Line data Source code
1 : /*
2 : * SPDX-License-Identifier: MPL-2.0
3 : *
4 : * This Source Code Form is subject to the terms of the Mozilla Public
5 : * License, v. 2.0. If a copy of the MPL was not distributed with this
6 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 : *
8 : * Copyright 2024 MonetDB Foundation;
9 : * Copyright August 2008 - 2023 MonetDB B.V.;
10 : * Copyright 1997 - July 2008 CWI.
11 : */
12 :
13 : #include "monetdb_config.h"
14 : #include "sql_mvc.h"
15 : #include "sql_scan.h"
16 : #include "sql_list.h"
17 : #include "sql_types.h"
18 : #include "sql_catalog.h"
19 : #include "sql_datetime.h"
20 : #include "sql_atom.h"
21 : #include "rel_rel.h"
22 :
23 : static void
24 349135 : destroy_sql_var(void *gdata, void *data)
25 : {
26 349135 : (void)gdata;
27 349135 : sql_var *svar = (sql_var*) data;
28 349135 : VALclear(&(svar->var.data));
29 349135 : svar->var.data.vtype = 0;
30 349135 : _DELETE(svar->sname);
31 349135 : _DELETE(svar->name);
32 349135 : _DELETE(svar);
33 349135 : }
34 :
35 : #define SQLglobal(sname, name, val) \
36 : if (!(var = push_global_var(sql, sname, name, &ctype)) || !sqlvar_set(var, VALset(&src, ctype.type->localtype, (char*)(val)))) \
37 : return -1;
38 :
39 : static int
40 339615 : var_key(sql_var *v)
41 : {
42 339615 : return hash_key(v->name);
43 : }
44 :
45 : int
46 37735 : init_global_variables(mvc *sql)
47 : {
48 37735 : sql_subtype ctype;
49 37735 : lng sec = 0;
50 37735 : ValRecord src;
51 37735 : const char *opt, *sname = "sys";
52 37735 : sql_var *var;
53 :
54 37735 : if (!(sql->global_vars = list_create(destroy_sql_var)))
55 : return -1;
56 : /* Use hash lookup for global variables */
57 37735 : if (!(sql->global_vars->ht = hash_new(NULL, 16, (fkeyvalue)&var_key)))
58 : return -1;
59 :
60 37735 : sql_find_subtype(&ctype, "int", 0, 0);
61 37735 : SQLglobal(sname, "debug", &sql->debug);
62 37735 : SQLglobal(sname, "sql_optimizer", &sql->sql_optimizer);
63 :
64 37735 : sql_find_subtype(&ctype, "varchar", 1024, 0);
65 37735 : SQLglobal(sname, "current_schema", sname);
66 37735 : SQLglobal(sname, "current_user", "monetdb");
67 37735 : SQLglobal(sname, "current_role", "monetdb");
68 :
69 : /* inherit the optimizer from the server */
70 37735 : opt = GDKgetenv("sql_optimizer");
71 37735 : if (!opt)
72 0 : opt = "default_pipe";
73 37735 : SQLglobal(sname, "optimizer", opt);
74 :
75 37735 : sql_find_subtype(&ctype, "sec_interval", inttype2digits(ihour, isec), 0);
76 37735 : SQLglobal(sname, "current_timezone", &sec);
77 :
78 37735 : sql_find_subtype(&ctype, "bigint", 0, 0);
79 37735 : SQLglobal(sname, "last_id", &sec);
80 37735 : SQLglobal(sname, "rowcnt", &sec);
81 : return 0;
82 : }
83 :
84 : sql_var*
85 339615 : push_global_var(mvc *sql, const char *sname, const char *name, sql_subtype *type)
86 : {
87 339615 : sql_var *svar = ZNEW(sql_var);
88 :
89 339615 : if (!svar)
90 : return NULL;
91 339615 : if (!(svar->name = _STRDUP(name))) {
92 0 : _DELETE(svar);
93 0 : return NULL;
94 : }
95 339615 : if (!(svar->sname = _STRDUP(sname))) {
96 0 : _DELETE(svar->name);
97 0 : _DELETE(svar);
98 0 : return NULL;
99 : }
100 339615 : atom_init(&(svar->var));
101 339615 : if (type) {
102 339615 : int tpe = type->type->localtype;
103 339615 : VALset(&(svar->var.data), tpe, (ptr) ATOMnilptr(tpe));
104 339615 : svar->var.tpe = *type;
105 : }
106 339615 : if (!list_append(sql->global_vars, svar)) {
107 0 : _DELETE(svar->name);
108 0 : _DELETE(svar->sname);
109 0 : _DELETE(svar);
110 0 : return NULL;
111 : }
112 : return svar;
113 : }
114 :
115 : int
116 0 : remove_global_var(mvc *sql, sql_schema *s, const char *name)
117 : {
118 0 : sql_var *v = find_global_var(sql, s, name);
119 :
120 0 : if (v) {
121 0 : list_remove_data(sql->global_vars, NULL, v);
122 0 : return 0;
123 : } else {
124 : return -1;
125 : }
126 : }
127 :
128 : sql_var*
129 9520 : frame_push_var(mvc *sql, const char *name, sql_subtype *type)
130 : {
131 9520 : assert(sql->topframes > 0);
132 9520 : sql_frame *f = sql->frames[sql->topframes - 1];
133 9520 : sql_var *svar = ZNEW(sql_var);
134 :
135 9520 : if (!svar)
136 : return NULL;
137 9520 : if (!(svar->name = _STRDUP(name))) {
138 0 : _DELETE(svar);
139 0 : return NULL;
140 : }
141 9520 : atom_init(&(svar->var));
142 9520 : if (type) {
143 9520 : int tpe = type->type->localtype;
144 9520 : VALset(&(svar->var.data), tpe, (ptr) ATOMnilptr(tpe));
145 9520 : svar->var.tpe = *type;
146 : }
147 9520 : if (!f->vars && !(f->vars = list_create(destroy_sql_var))) {
148 0 : _DELETE(svar->name);
149 0 : _DELETE(svar);
150 0 : return NULL;
151 : }
152 9520 : if (!list_append(f->vars, svar)) {
153 0 : _DELETE(svar->name);
154 0 : _DELETE(svar);
155 0 : return NULL;
156 : }
157 : return svar;
158 : }
159 :
160 : static void
161 119 : destroy_sql_local_table(void *gdata, void *data)
162 : {
163 119 : (void)gdata;
164 119 : sql_local_table *slt = (sql_local_table*) data;
165 119 : _DELETE(slt);
166 119 : }
167 :
168 : sql_local_table*
169 119 : frame_push_table(mvc *sql, sql_table *t)
170 : {
171 119 : assert(sql->topframes > 0);
172 119 : sql_frame *f = sql->frames[sql->topframes - 1];
173 119 : sql_local_table *slt = ZNEW(sql_local_table);
174 :
175 119 : if (!slt)
176 : return NULL;
177 119 : slt->table = t;
178 119 : t->s = NULL;
179 119 : if (!f->tables && !(f->tables = list_create(destroy_sql_local_table))) {
180 0 : _DELETE(slt);
181 0 : return NULL;
182 : }
183 119 : if (!list_append(f->tables, slt)) {
184 0 : _DELETE(slt);
185 0 : return NULL;
186 : }
187 : return slt;
188 : }
189 :
190 : static void
191 18391 : destroy_sql_rel_view(void *gdata, void *data)
192 : {
193 18391 : (void)gdata;
194 18391 : sql_rel_view *srv = (sql_rel_view*) data;
195 18391 : rel_destroy(srv->rel_view);
196 18391 : _DELETE(srv->name);
197 18391 : _DELETE(srv);
198 18391 : }
199 :
200 : sql_rel_view*
201 18391 : stack_push_rel_view(mvc *sql, const char *name, sql_rel *var)
202 : {
203 18391 : assert(sql->topframes > 0);
204 18391 : sql_frame *f = sql->frames[sql->topframes - 1];
205 18391 : sql_rel_view *srv = ZNEW(sql_rel_view);
206 :
207 18391 : if (!srv)
208 : return NULL;
209 18391 : if (!(srv->name = _STRDUP(name))) {
210 0 : _DELETE(srv);
211 0 : return NULL;
212 : }
213 18391 : srv->rel_view = var;
214 18391 : if (!f->rel_views && !(f->rel_views = list_create(destroy_sql_rel_view))) {
215 0 : _DELETE(srv->name);
216 0 : _DELETE(srv);
217 0 : return NULL;
218 : }
219 18391 : if (!list_append(f->rel_views, srv)) {
220 0 : _DELETE(srv->name);
221 0 : _DELETE(srv);
222 0 : return NULL;
223 : }
224 : return srv;
225 : }
226 :
227 : static void
228 31 : destroy_sql_window_definition(void *gdata, void *data)
229 : {
230 31 : (void)gdata;
231 31 : sql_window_definition *swd = (sql_window_definition*) data;
232 31 : _DELETE(swd->name);
233 31 : _DELETE(swd);
234 31 : }
235 :
236 : sql_window_definition*
237 31 : frame_push_window_def(mvc *sql, const char *name, dlist *wdef)
238 : {
239 31 : assert(sql->topframes > 0);
240 31 : sql_frame *f = sql->frames[sql->topframes - 1];
241 31 : sql_window_definition *swd = ZNEW(sql_window_definition);
242 :
243 31 : if (!swd)
244 : return NULL;
245 31 : if (!(swd->name = _STRDUP(name))) {
246 0 : _DELETE(swd);
247 0 : return NULL;
248 : }
249 31 : swd->wdef = wdef;
250 31 : swd->visited = false;
251 31 : if (!f->windows && !(f->windows = list_create(destroy_sql_window_definition))) {
252 0 : _DELETE(swd->name);
253 0 : _DELETE(swd);
254 0 : return NULL;
255 : }
256 31 : if (!list_append(f->windows, swd)) {
257 0 : _DELETE(swd->name);
258 0 : _DELETE(swd);
259 0 : return NULL;
260 : }
261 : return swd;
262 : }
263 :
264 : static void
265 150 : destroy_sql_groupby_expression(void *gdata, void *data)
266 : {
267 150 : (void)gdata;
268 150 : sql_groupby_expression *sge = (sql_groupby_expression*) data;
269 150 : _DELETE(sge);
270 150 : }
271 :
272 : sql_groupby_expression*
273 150 : frame_push_groupby_expression(mvc *sql, symbol *def, sql_exp *exp)
274 : {
275 150 : assert(sql->topframes > 0);
276 150 : sql_frame *f = sql->frames[sql->topframes - 1];
277 150 : sql_groupby_expression *sge = ZNEW(sql_groupby_expression);
278 :
279 150 : if (!sge)
280 : return NULL;
281 150 : sge->sdef = def;
282 150 : sge->token = def->token;
283 150 : sge->exp = exp;
284 150 : if (!f->group_expressions && !(f->group_expressions = list_create(destroy_sql_groupby_expression))) {
285 0 : _DELETE(sge);
286 0 : return NULL;
287 : }
288 150 : if (!list_append(f->group_expressions, sge)) {
289 0 : _DELETE(sge);
290 0 : return NULL;
291 : }
292 : return sge;
293 : }
294 :
295 : dlist *
296 64 : frame_get_window_def(mvc *sql, const char *name, int *pos)
297 : {
298 64 : if (sql->topframes > 0) {
299 64 : sql_frame *f = sql->frames[sql->topframes - 1];
300 64 : if (f->windows) {
301 42 : int i = 0;
302 69 : for (node *n = f->windows->h; n ; n = n->next, i++) {
303 58 : sql_window_definition *var = (sql_window_definition*) n->data;
304 58 : if (var->name && !strcmp(var->name, name)) {
305 31 : if (pos)
306 30 : *pos = i;
307 31 : return var->wdef;
308 : }
309 : }
310 : }
311 : }
312 : return NULL;
313 : }
314 :
315 : sql_exp*
316 105111 : frame_get_groupby_expression(mvc *sql, symbol *def)
317 : {
318 105111 : if (sql->topframes > 0) {
319 105111 : sql_frame *f = sql->frames[sql->topframes - 1];
320 105111 : if (f->group_expressions) {
321 670 : for (node *n = f->group_expressions->h; n ; n = n->next) {
322 398 : sql_groupby_expression *var = (sql_groupby_expression*) n->data;
323 398 : if (var->token == def->token && !symbol_cmp(sql, var->sdef, def))
324 78 : return var->exp;
325 : }
326 : }
327 : }
328 : return NULL;
329 : }
330 :
331 : /* There could a possibility that this is vulnerable to a time-of-check, time-of-use race condition.
332 : * However this should never happen in the SQL compiler */
333 : bool
334 15 : frame_check_var_visited(mvc *sql, int i)
335 : {
336 15 : if (sql->topframes > 0) {
337 15 : sql_frame *f = sql->frames[sql->topframes - 1];
338 15 : sql_window_definition *win;
339 :
340 15 : if (i < 0 || i >= list_length(f->windows))
341 0 : return false;
342 :
343 15 : win = (sql_window_definition*) list_fetch(f->windows, i);
344 15 : return win->visited;
345 : }
346 : return false;
347 : }
348 :
349 : void
350 29 : frame_set_var_visited(mvc *sql, int i)
351 : {
352 29 : if (sql->topframes > 0) {
353 29 : sql_frame *f = sql->frames[sql->topframes - 1];
354 29 : sql_window_definition *win;
355 :
356 29 : if (i < 0 || i >= list_length(f->windows))
357 0 : return;
358 :
359 29 : win = (sql_window_definition*) list_fetch(f->windows, i);
360 29 : win->visited = true;
361 : }
362 : }
363 :
364 : void
365 17947 : frame_clear_visited_flag(mvc *sql)
366 : {
367 17947 : if (sql->topframes > 0) {
368 17940 : sql_frame *f = sql->frames[sql->topframes - 1];
369 17940 : if (f->windows) {
370 62 : for (node *n = f->windows->h; n ; n = n->next) {
371 39 : sql_window_definition *var = (sql_window_definition*) n->data;
372 39 : var->visited = false;
373 : }
374 : }
375 : }
376 17947 : }
377 :
378 : atom *
379 376848 : sqlvar_set(sql_var *var, ValRecord *v)
380 : {
381 376848 : VALclear(&(var->var.data));
382 376838 : if (VALcopy(&(var->var.data), v) == NULL)
383 : return NULL;
384 376840 : var->var.isnull = VALisnil(v);
385 376831 : return &(var->var);
386 : }
387 :
388 : sql_frame*
389 419202 : stack_push_frame(mvc *sql, const char *name)
390 : {
391 419202 : sql_frame *v, **nvars;
392 419202 : int osize = sql->sizeframes, nextsize = osize;
393 :
394 419202 : if (sql->topframes == nextsize) {
395 12 : nextsize <<= 1;
396 24 : if (!(nvars = SA_RENEW_ARRAY(sql->pa, sql_frame*, sql->frames, nextsize, osize)))
397 : return NULL;
398 12 : sql->frames = nvars;
399 12 : sql->sizeframes = nextsize;
400 : }
401 419202 : if (!(v = ZNEW(sql_frame)))
402 : return NULL;
403 419203 : if (name && !(v->name = _STRDUP(name))) {
404 0 : _DELETE(v);
405 0 : return NULL;
406 : }
407 419203 : v->frame_number = ++sql->frame; /* The frame number for variables on the stack start on level 1 */
408 419203 : sql->frames[sql->topframes++] = v;
409 419203 : return v;
410 : }
411 :
412 : void
413 419202 : clear_frame(mvc *sql, sql_frame *frame)
414 : {
415 419202 : list_destroy(frame->group_expressions);
416 419193 : list_destroy(frame->windows);
417 419190 : list_destroy(frame->tables);
418 419188 : list_destroy(frame->rel_views);
419 419187 : list_destroy(frame->vars);
420 419186 : _DELETE(frame->name);
421 419185 : _DELETE(frame);
422 419201 : sql->frame--;
423 419201 : }
424 :
425 : void
426 37735 : stack_pop_until(mvc *sql, int frame)
427 : {
428 37735 : while (sql->topframes > frame) {
429 0 : assert(sql->topframes >= 0);
430 0 : sql_frame *f = sql->frames[--sql->topframes];
431 0 : clear_frame(sql, f);
432 : }
433 37735 : }
434 :
435 : void
436 419200 : stack_pop_frame(mvc *sql)
437 : {
438 419200 : sql_frame *f = sql->frames[--sql->topframes];
439 419200 : assert(sql->topframes >= 0);
440 419200 : clear_frame(sql, f);
441 419201 : }
442 :
443 : sql_table *
444 121 : frame_find_table(mvc *sql, const char *name)
445 : {
446 121 : if (sql->topframes > 0) {
447 121 : sql_frame *f = sql->frames[sql->topframes - 1];
448 121 : if (f->tables) {
449 5 : for (node *n = f->tables->h; n ; n = n->next) {
450 3 : sql_local_table *var = (sql_local_table*) n->data;
451 3 : if (!strcmp(var->table->base.name, name))
452 1 : return var->table;
453 : }
454 : }
455 : }
456 : return NULL;
457 : }
458 :
459 : sql_table *
460 211776 : stack_find_table(mvc *sql, const char *name)
461 : {
462 4219268 : for (int i = sql->topframes-1; i >= 0; i--) {
463 4007702 : sql_frame *f = sql->frames[i];
464 4007702 : if (f->tables) {
465 306 : for (node *n = f->tables->h; n ; n = n->next) {
466 258 : sql_local_table *var = (sql_local_table*) n->data;
467 258 : if (!strcmp(var->table->base.name, name))
468 210 : return var->table;
469 : }
470 : }
471 : }
472 : return NULL;
473 : }
474 :
475 : sql_rel *
476 115070 : stack_find_rel_view(mvc *sql, const char *name)
477 : {
478 257689 : for (int i = sql->topframes-1; i >= 0; i--) {
479 159680 : sql_frame *f = sql->frames[i];
480 159680 : if (f->rel_views) {
481 35268 : for (node *n = f->rel_views->h; n ; n = n->next) {
482 33541 : sql_rel_view *var = (sql_rel_view*) n->data;
483 33541 : assert(var->name);
484 33541 : if (!strcmp(var->name, name))
485 17061 : return rel_dup(var->rel_view);
486 : }
487 : }
488 : }
489 : return NULL;
490 : }
491 :
492 : int
493 13 : stack_find_rel_view_projection_columns(mvc *sql, const char *name, sql_rel **res)
494 : {
495 13 : *res = NULL;
496 :
497 43 : for (int i = sql->topframes-1; i >= 0; i--) {
498 31 : sql_frame *f = sql->frames[i];
499 31 : if (f->rel_views) {
500 18 : for (node *n = f->rel_views->h; n ; n = n->next) {
501 10 : sql_rel_view *var = (sql_rel_view*) n->data;
502 :
503 10 : assert(var->name);
504 : /* trigger views are basetables relations, so those may conflict */
505 10 : if (is_base(var->rel_view->op) && rel_bind_column(sql, var->rel_view, name, 0, 0)) {
506 10 : if (*res)
507 : return -1;
508 9 : *res = var->rel_view;
509 : }
510 : }
511 : }
512 : }
513 : return 0;
514 : }
515 :
516 : sql_rel *
517 12740 : frame_find_rel_view(mvc *sql, const char *name)
518 : {
519 12740 : assert(sql->topframes > 0);
520 12740 : sql_frame *f = sql->frames[sql->topframes - 1];
521 12740 : if (f->rel_views) {
522 18276 : for (node *n = f->rel_views->h; n ; n = n->next) {
523 12470 : sql_rel_view *var = (sql_rel_view*) n->data;
524 12470 : assert(var->name);
525 12470 : if (!strcmp(var->name, name))
526 1 : return var->rel_view;
527 : }
528 : }
529 : return NULL;
530 : }
531 :
532 : void
533 6 : stack_update_rel_view(mvc *sql, const char *name, sql_rel *view)
534 : {
535 6 : for (int i = sql->topframes-1; i >= 0; i--) {
536 6 : sql_frame *f = sql->frames[i];
537 6 : if (f->rel_views) {
538 9 : for (node *n = f->rel_views->h; n ; n = n->next) {
539 9 : sql_rel_view *var = (sql_rel_view*) n->data;
540 9 : assert(var->name);
541 9 : if (!strcmp(var->name, name)) {
542 6 : rel_destroy(var->rel_view);
543 6 : var->rel_view = view;
544 6 : return;
545 : }
546 : }
547 : }
548 : }
549 : }
550 :
551 : sql_var*
552 1231326 : find_global_var(mvc *sql, sql_schema *s, const char *name)
553 : {
554 1231326 : const char *sname = s->base.name;
555 1231326 : int key = hash_key(name); /* Using hash lookup */
556 1231326 : sql_hash_e *he = sql->global_vars->ht->buckets[key&(sql->global_vars->ht->size-1)];
557 :
558 1362887 : for (; he; he = he->chain) {
559 1358824 : sql_var *var = (sql_var*) he->value;
560 :
561 1358824 : assert(var->sname && var->name);
562 1358824 : if (!strcmp(var->sname, sname) && !strcmp(var->name, name))
563 1227263 : return var;
564 : }
565 : return NULL;
566 : }
567 :
568 : int
569 9495 : frame_find_var(mvc *sql, const char *name)
570 : {
571 9495 : assert(sql->topframes > 0);
572 9495 : sql_frame *f = sql->frames[sql->topframes - 1];
573 9495 : if (f->vars) {
574 14383 : for (node *n = f->vars->h; n ; n = n->next) {
575 9022 : sql_var *var = (sql_var*) n->data;
576 9022 : assert(var->name);
577 9022 : if (!strcmp(var->name, name))
578 : return 1;
579 : }
580 : }
581 : return 0;
582 : }
583 :
584 : sql_var*
585 133344 : stack_find_var_frame(mvc *sql, const char *name, int *level)
586 : {
587 133344 : *level = 1; /* Level 0 is for globals */
588 301410 : for (int i = sql->topframes-1; i >= 0; i--) {
589 210703 : sql_frame *f = sql->frames[i];
590 210703 : if (f->vars) {
591 201593 : for (node *n = f->vars->h; n ; n = n->next) {
592 165506 : sql_var *var = (sql_var*) n->data;
593 165506 : assert(var->name);
594 165506 : if (!strcmp(var->name, name)) {
595 42637 : *level = f->frame_number;
596 42637 : return var;
597 : }
598 : }
599 : }
600 : }
601 : return NULL;
602 : }
603 :
604 : sql_var*
605 0 : stack_find_var_at_level(mvc *sql, const char *name, int level)
606 : {
607 0 : for (int i = sql->topframes-1; i >= 0; i--) {
608 0 : sql_frame *f = sql->frames[i];
609 0 : if (f->frame_number == level && f->vars) {
610 0 : for (node *n = f->vars->h; n ; n = n->next) {
611 0 : sql_var *var = (sql_var*) n->data;
612 0 : assert(var->name);
613 0 : if (!strcmp(var->name, name))
614 0 : return var;
615 : }
616 : }
617 : }
618 : return NULL;
619 : }
620 :
621 : int
622 510 : stack_has_frame(mvc *sql, const char *name)
623 : {
624 526 : for (int i = sql->topframes-1; i >= 0; i--) {
625 212 : sql_frame *f = sql->frames[i];
626 212 : if (f->name && !strcmp(f->name, name))
627 : return 1;
628 : }
629 : return 0;
630 : }
631 :
632 : int
633 23157 : stack_nr_of_declared_tables(mvc *sql)
634 : {
635 23157 : int dt = 0;
636 :
637 57070 : for (int i = sql->topframes-1; i >= 0; i--) {
638 33913 : sql_frame *f = sql->frames[i];
639 33913 : dt += list_length(f->tables);
640 : }
641 23157 : return dt;
642 : }
643 :
644 : str
645 111261 : sqlvar_set_string(sql_var *var, const char *val)
646 : {
647 111261 : atom *a = &var->var;
648 111261 : str new_val = _STRDUP(val);
649 :
650 111261 : if (a != NULL && new_val != NULL) {
651 111261 : ValRecord *v = &a->data;
652 :
653 111261 : if (v->val.sval)
654 111261 : _DELETE(v->val.sval);
655 111259 : v->val.sval = new_val;
656 111259 : return new_val;
657 : } else if (new_val) {
658 : _DELETE(new_val);
659 : }
660 : return NULL;
661 : }
662 :
663 : str
664 820159 : sqlvar_get_string(sql_var *var)
665 : {
666 820159 : atom *a = &var->var;
667 :
668 820159 : if (!a || a->data.vtype != TYPE_str)
669 : return NULL;
670 820159 : return a->data.val.sval;
671 : }
672 :
673 : void
674 : #ifdef HAVE_HGE
675 252133 : sqlvar_set_number(sql_var *var, hge val)
676 : #else
677 : sqlvar_set_number(sql_var *var, lng val)
678 : #endif
679 : {
680 252133 : atom *a = &var->var;
681 :
682 252133 : if (a != NULL) {
683 252133 : ValRecord *v = &a->data;
684 : #ifdef HAVE_HGE
685 252133 : if (v->vtype == TYPE_hge)
686 0 : v->val.hval = val;
687 : #endif
688 252133 : if (v->vtype == TYPE_lng)
689 252133 : v->val.lval = val;
690 252133 : if (v->vtype == TYPE_int)
691 0 : v->val.lval = (int) val;
692 252133 : if (v->vtype == TYPE_sht)
693 0 : v->val.lval = (sht) val;
694 252133 : if (v->vtype == TYPE_bte)
695 0 : v->val.lval = (bte) val;
696 252133 : if (v->vtype == TYPE_bit) {
697 0 : if (val)
698 0 : v->val.btval = 1;
699 : else
700 0 : v->val.btval = 0;
701 : }
702 : }
703 252133 : }
704 :
705 : #ifdef HAVE_HGE
706 : hge
707 : #else
708 : lng
709 : #endif
710 37083 : val_get_number(const ValRecord *v)
711 : {
712 37083 : if (v != NULL) {
713 : #ifdef HAVE_HGE
714 37083 : if (v->vtype == TYPE_hge)
715 0 : return v->val.hval;
716 : #endif
717 : if (v->vtype == TYPE_lng)
718 37079 : return v->val.lval;
719 : if (v->vtype == TYPE_int)
720 4 : return v->val.ival;
721 : if (v->vtype == TYPE_sht)
722 0 : return v->val.shval;
723 : if (v->vtype == TYPE_bte)
724 0 : return v->val.btval;
725 : if (v->vtype == TYPE_bit)
726 0 : if (v->val.btval)
727 : return 1;
728 0 : return 0;
729 : }
730 : return 0;
731 : }
|