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 356699 : destroy_sql_var(void *gdata, void *data)
25 : {
26 356699 : (void)gdata;
27 356699 : sql_var *svar = (sql_var*) data;
28 356699 : VALclear(&(svar->var.data));
29 356699 : svar->var.data.vtype = 0;
30 356699 : _DELETE(svar->sname);
31 356699 : _DELETE(svar->name);
32 356699 : _DELETE(svar);
33 356699 : }
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 347292 : var_key(sql_var *v)
41 : {
42 347292 : return hash_key(v->name);
43 : }
44 :
45 : int
46 38588 : init_global_variables(mvc *sql)
47 : {
48 38588 : sql_subtype ctype;
49 38588 : lng sec = 0;
50 38588 : ValRecord src;
51 38588 : const char *opt, *sname = "sys";
52 38588 : sql_var *var;
53 :
54 38588 : if (!(sql->global_vars = list_create(destroy_sql_var)))
55 : return -1;
56 : /* Use hash lookup for global variables */
57 38588 : if (!(sql->global_vars->ht = hash_new(NULL, 16, (fkeyvalue)&var_key)))
58 : return -1;
59 :
60 38588 : sql_find_subtype(&ctype, "int", 0, 0);
61 38588 : SQLglobal(sname, "debug", &sql->debug);
62 38588 : SQLglobal(sname, "sql_optimizer", &sql->sql_optimizer);
63 :
64 38588 : sql_find_subtype(&ctype, "varchar", 1024, 0);
65 38588 : SQLglobal(sname, "current_schema", sname);
66 38588 : SQLglobal(sname, "current_user", "monetdb");
67 38588 : SQLglobal(sname, "current_role", "monetdb");
68 :
69 : /* inherit the optimizer from the server */
70 38588 : opt = GDKgetenv("sql_optimizer");
71 38588 : if (!opt)
72 0 : opt = "default_pipe";
73 38588 : SQLglobal(sname, "optimizer", opt);
74 :
75 38588 : sql_find_subtype(&ctype, "sec_interval", inttype2digits(ihour, isec), 0);
76 38588 : SQLglobal(sname, "current_timezone", &sec);
77 :
78 38588 : sql_find_subtype(&ctype, "bigint", 0, 0);
79 38588 : SQLglobal(sname, "last_id", &sec);
80 38588 : SQLglobal(sname, "rowcnt", &sec);
81 : return 0;
82 : }
83 :
84 : sql_var*
85 347292 : push_global_var(mvc *sql, const char *sname, const char *name, sql_subtype *type)
86 : {
87 347292 : sql_var *svar = ZNEW(sql_var);
88 :
89 347292 : if (!svar)
90 : return NULL;
91 347292 : if (!(svar->name = _STRDUP(name))) {
92 0 : _DELETE(svar);
93 0 : return NULL;
94 : }
95 347292 : if (!(svar->sname = _STRDUP(sname))) {
96 0 : _DELETE(svar->name);
97 0 : _DELETE(svar);
98 0 : return NULL;
99 : }
100 347292 : atom_init(&(svar->var));
101 347292 : if (type) {
102 347292 : int tpe = type->type->localtype;
103 347292 : VALset(&(svar->var.data), tpe, (ptr) ATOMnilptr(tpe));
104 347292 : svar->var.tpe = *type;
105 : }
106 347292 : 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 9407 : frame_push_var(mvc *sql, const char *name, sql_subtype *type)
130 : {
131 9407 : assert(sql->topframes > 0);
132 9407 : sql_frame *f = sql->frames[sql->topframes - 1];
133 9407 : sql_var *svar = ZNEW(sql_var);
134 :
135 9407 : if (!svar)
136 : return NULL;
137 9407 : if (!(svar->name = _STRDUP(name))) {
138 0 : _DELETE(svar);
139 0 : return NULL;
140 : }
141 9407 : atom_init(&(svar->var));
142 9407 : if (type) {
143 9407 : int tpe = type->type->localtype;
144 9407 : VALset(&(svar->var.data), tpe, (ptr) ATOMnilptr(tpe));
145 9407 : svar->var.tpe = *type;
146 : }
147 9407 : 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 9407 : 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 105 : destroy_sql_local_table(void *gdata, void *data)
162 : {
163 105 : (void)gdata;
164 105 : sql_local_table *slt = (sql_local_table*) data;
165 105 : _DELETE(slt);
166 105 : }
167 :
168 : sql_local_table*
169 105 : frame_push_table(mvc *sql, sql_table *t)
170 : {
171 105 : assert(sql->topframes > 0);
172 105 : sql_frame *f = sql->frames[sql->topframes - 1];
173 105 : sql_local_table *slt = ZNEW(sql_local_table);
174 :
175 105 : if (!slt)
176 : return NULL;
177 105 : slt->table = t;
178 105 : t->s = NULL;
179 105 : if (!f->tables && !(f->tables = list_create(destroy_sql_local_table))) {
180 0 : _DELETE(slt);
181 0 : return NULL;
182 : }
183 105 : if (!list_append(f->tables, slt)) {
184 0 : _DELETE(slt);
185 0 : return NULL;
186 : }
187 : return slt;
188 : }
189 :
190 : static void
191 17817 : destroy_sql_rel_view(void *gdata, void *data)
192 : {
193 17817 : (void)gdata;
194 17817 : sql_rel_view *srv = (sql_rel_view*) data;
195 17817 : rel_destroy(srv->rel_view);
196 17817 : _DELETE(srv->name);
197 17817 : _DELETE(srv);
198 17817 : }
199 :
200 : sql_rel_view*
201 17817 : stack_push_rel_view(mvc *sql, const char *name, sql_rel *var)
202 : {
203 17817 : assert(sql->topframes > 0);
204 17817 : sql_frame *f = sql->frames[sql->topframes - 1];
205 17817 : sql_rel_view *srv = ZNEW(sql_rel_view);
206 :
207 17817 : if (!srv)
208 : return NULL;
209 17817 : if (!(srv->name = _STRDUP(name))) {
210 0 : _DELETE(srv);
211 0 : return NULL;
212 : }
213 17817 : srv->rel_view = var;
214 17817 : 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 17817 : 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 29 : destroy_sql_window_definition(void *gdata, void *data)
229 : {
230 29 : (void)gdata;
231 29 : sql_window_definition *swd = (sql_window_definition*) data;
232 29 : _DELETE(swd->name);
233 29 : _DELETE(swd);
234 29 : }
235 :
236 : sql_window_definition*
237 29 : frame_push_window_def(mvc *sql, const char *name, dlist *wdef)
238 : {
239 29 : assert(sql->topframes > 0);
240 29 : sql_frame *f = sql->frames[sql->topframes - 1];
241 29 : sql_window_definition *swd = ZNEW(sql_window_definition);
242 :
243 29 : if (!swd)
244 : return NULL;
245 29 : if (!(swd->name = _STRDUP(name))) {
246 0 : _DELETE(swd);
247 0 : return NULL;
248 : }
249 29 : swd->wdef = wdef;
250 29 : swd->visited = false;
251 29 : 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 29 : 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 283 : destroy_sql_groupby_expression(void *gdata, void *data)
266 : {
267 283 : (void)gdata;
268 283 : sql_groupby_expression *sge = (sql_groupby_expression*) data;
269 283 : _DELETE(sge);
270 283 : }
271 :
272 : sql_groupby_expression*
273 283 : frame_push_groupby_expression(mvc *sql, symbol *def, sql_exp *exp)
274 : {
275 283 : assert(sql->topframes > 0);
276 283 : sql_frame *f = sql->frames[sql->topframes - 1];
277 283 : sql_groupby_expression *sge = ZNEW(sql_groupby_expression);
278 :
279 283 : if (!sge)
280 : return NULL;
281 283 : sge->sdef = def;
282 283 : sge->token = def->token;
283 283 : sge->exp = exp;
284 283 : if (!f->group_expressions && !(f->group_expressions = list_create(destroy_sql_groupby_expression))) {
285 0 : _DELETE(sge);
286 0 : return NULL;
287 : }
288 283 : if (!list_append(f->group_expressions, sge)) {
289 0 : _DELETE(sge);
290 0 : return NULL;
291 : }
292 : return sge;
293 : }
294 :
295 : dlist *
296 60 : frame_get_window_def(mvc *sql, const char *name, int *pos)
297 : {
298 60 : if (sql->topframes > 0) {
299 60 : sql_frame *f = sql->frames[sql->topframes - 1];
300 60 : if (f->windows) {
301 40 : int i = 0;
302 67 : for (node *n = f->windows->h; n ; n = n->next, i++) {
303 56 : sql_window_definition *var = (sql_window_definition*) n->data;
304 56 : if (var->name && !strcmp(var->name, name)) {
305 29 : if (pos)
306 28 : *pos = i;
307 29 : return var->wdef;
308 : }
309 : }
310 : }
311 : }
312 : return NULL;
313 : }
314 :
315 : sql_exp*
316 102108 : frame_get_groupby_expression(mvc *sql, symbol *def)
317 : {
318 102108 : if (sql->topframes > 0) {
319 102108 : sql_frame *f = sql->frames[sql->topframes - 1];
320 102108 : if (f->group_expressions) {
321 1552 : for (node *n = f->group_expressions->h; n ; n = n->next) {
322 1018 : sql_groupby_expression *var = (sql_groupby_expression*) n->data;
323 1018 : if (var->token == def->token && !symbol_cmp(sql, var->sdef, def))
324 115 : 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 27 : frame_set_var_visited(mvc *sql, int i)
351 : {
352 27 : if (sql->topframes > 0) {
353 27 : sql_frame *f = sql->frames[sql->topframes - 1];
354 27 : sql_window_definition *win;
355 :
356 27 : if (i < 0 || i >= list_length(f->windows))
357 0 : return;
358 :
359 27 : win = (sql_window_definition*) list_fetch(f->windows, i);
360 27 : win->visited = true;
361 : }
362 : }
363 :
364 : void
365 17569 : frame_clear_visited_flag(mvc *sql)
366 : {
367 17569 : if (sql->topframes > 0) {
368 17562 : sql_frame *f = sql->frames[sql->topframes - 1];
369 17562 : if (f->windows) {
370 58 : for (node *n = f->windows->h; n ; n = n->next) {
371 37 : sql_window_definition *var = (sql_window_definition*) n->data;
372 37 : var->visited = false;
373 : }
374 : }
375 : }
376 17569 : }
377 :
378 : atom *
379 385344 : sqlvar_set(sql_var *var, ValRecord *v)
380 : {
381 385344 : VALclear(&(var->var.data));
382 385328 : if (VALcopy(&(var->var.data), v) == NULL)
383 : return NULL;
384 385337 : var->var.isnull = VALisnil(v);
385 385322 : return &(var->var);
386 : }
387 :
388 : sql_frame*
389 407568 : stack_push_frame(mvc *sql, const char *name)
390 : {
391 407568 : sql_frame *v, **nvars;
392 407568 : int osize = sql->sizeframes, nextsize = osize;
393 :
394 407568 : 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 407568 : if (!(v = ZNEW(sql_frame)))
402 : return NULL;
403 407568 : if (name && !(v->name = _STRDUP(name))) {
404 0 : _DELETE(v);
405 0 : return NULL;
406 : }
407 407568 : v->frame_number = ++sql->frame; /* The frame number for varialbes on the stack start on level 1 */
408 407568 : sql->frames[sql->topframes++] = v;
409 407568 : return v;
410 : }
411 :
412 : void
413 407564 : clear_frame(mvc *sql, sql_frame *frame)
414 : {
415 407564 : list_destroy(frame->group_expressions);
416 407563 : list_destroy(frame->windows);
417 407561 : list_destroy(frame->tables);
418 407559 : list_destroy(frame->rel_views);
419 407559 : list_destroy(frame->vars);
420 407560 : _DELETE(frame->name);
421 407559 : _DELETE(frame);
422 407568 : sql->frame--;
423 407568 : }
424 :
425 : void
426 38588 : stack_pop_until(mvc *sql, int frame)
427 : {
428 38588 : 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 38588 : }
434 :
435 : void
436 407566 : stack_pop_frame(mvc *sql)
437 : {
438 407566 : sql_frame *f = sql->frames[--sql->topframes];
439 407566 : assert(sql->topframes >= 0);
440 407566 : clear_frame(sql, f);
441 407568 : }
442 :
443 : sql_table *
444 107 : frame_find_table(mvc *sql, const char *name)
445 : {
446 107 : if (sql->topframes > 0) {
447 107 : sql_frame *f = sql->frames[sql->topframes - 1];
448 107 : 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 209813 : stack_find_table(mvc *sql, const char *name)
461 : {
462 3807559 : for (int i = sql->topframes-1; i >= 0; i--) {
463 3597927 : sql_frame *f = sql->frames[i];
464 3597927 : if (f->tables) {
465 271 : for (node *n = f->tables->h; n ; n = n->next) {
466 226 : sql_local_table *var = (sql_local_table*) n->data;
467 226 : if (!strcmp(var->table->base.name, name))
468 181 : return var->table;
469 : }
470 : }
471 : }
472 : return NULL;
473 : }
474 :
475 : sql_rel *
476 113921 : stack_find_rel_view(mvc *sql, const char *name)
477 : {
478 255150 : for (int i = sql->topframes-1; i >= 0; i--) {
479 157921 : sql_frame *f = sql->frames[i];
480 157921 : if (f->rel_views) {
481 34637 : for (node *n = f->rel_views->h; n ; n = n->next) {
482 32910 : sql_rel_view *var = (sql_rel_view*) n->data;
483 32910 : assert(var->name);
484 32910 : if (!strcmp(var->name, name))
485 16692 : 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 12435 : frame_find_rel_view(mvc *sql, const char *name)
518 : {
519 12435 : assert(sql->topframes > 0);
520 12435 : sql_frame *f = sql->frames[sql->topframes - 1];
521 12435 : if (f->rel_views) {
522 17864 : for (node *n = f->rel_views->h; n ; n = n->next) {
523 12208 : sql_rel_view *var = (sql_rel_view*) n->data;
524 12208 : assert(var->name);
525 12208 : 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 1213861 : find_global_var(mvc *sql, sql_schema *s, const char *name)
553 : {
554 1213861 : const char *sname = s->base.name;
555 1213861 : int key = hash_key(name); /* Using hash lookup */
556 1213861 : sql_hash_e *he = sql->global_vars->ht->buckets[key&(sql->global_vars->ht->size-1)];
557 :
558 1347047 : for (; he; he = he->chain) {
559 1343121 : sql_var *var = (sql_var*) he->value;
560 :
561 1343121 : assert(var->sname && var->name);
562 1343121 : if (!strcmp(var->sname, sname) && !strcmp(var->name, name))
563 1209935 : return var;
564 : }
565 : return NULL;
566 : }
567 :
568 : int
569 9382 : frame_find_var(mvc *sql, const char *name)
570 : {
571 9382 : assert(sql->topframes > 0);
572 9382 : sql_frame *f = sql->frames[sql->topframes - 1];
573 9382 : if (f->vars) {
574 14198 : for (node *n = f->vars->h; n ; n = n->next) {
575 8903 : sql_var *var = (sql_var*) n->data;
576 8903 : assert(var->name);
577 8903 : if (!strcmp(var->name, name))
578 : return 1;
579 : }
580 : }
581 : return 0;
582 : }
583 :
584 : sql_var*
585 160598 : stack_find_var_frame(mvc *sql, const char *name, int *level)
586 : {
587 160598 : *level = 1; /* Level 0 is for globals */
588 355358 : for (int i = sql->topframes-1; i >= 0; i--) {
589 236934 : sql_frame *f = sql->frames[i];
590 236934 : if (f->vars) {
591 199111 : for (node *n = f->vars->h; n ; n = n->next) {
592 163428 : sql_var *var = (sql_var*) n->data;
593 163428 : assert(var->name);
594 163428 : if (!strcmp(var->name, name)) {
595 42174 : *level = f->frame_number;
596 42174 : return var;
597 : }
598 : }
599 : }
600 : }
601 : return NULL;
602 : }
603 :
604 : sql_var*
605 50 : stack_find_var_at_level(mvc *sql, const char *name, int level)
606 : {
607 50 : 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 311 : stack_has_frame(mvc *sql, const char *name)
623 : {
624 311 : for (int i = sql->topframes-1; i >= 0; i--) {
625 196 : sql_frame *f = sql->frames[i];
626 196 : if (f->name && !strcmp(f->name, name))
627 : return 1;
628 : }
629 : return 0;
630 : }
631 :
632 : int
633 22675 : stack_nr_of_declared_tables(mvc *sql)
634 : {
635 22675 : int dt = 0;
636 :
637 55950 : for (int i = sql->topframes-1; i >= 0; i--) {
638 33275 : sql_frame *f = sql->frames[i];
639 33275 : dt += list_length(f->tables);
640 : }
641 22675 : return dt;
642 : }
643 :
644 : str
645 113780 : sqlvar_set_string(sql_var *var, const char *val)
646 : {
647 113780 : atom *a = &var->var;
648 113780 : str new_val = _STRDUP(val);
649 :
650 113779 : if (a != NULL && new_val != NULL) {
651 113779 : ValRecord *v = &a->data;
652 :
653 113779 : if (v->val.sval)
654 113779 : _DELETE(v->val.sval);
655 113780 : v->val.sval = new_val;
656 113780 : return new_val;
657 : } else if (new_val) {
658 : _DELETE(new_val);
659 : }
660 : return NULL;
661 : }
662 :
663 : str
664 798811 : sqlvar_get_string(sql_var *var)
665 : {
666 798811 : atom *a = &var->var;
667 :
668 798811 : if (!a || a->data.vtype != TYPE_str)
669 : return NULL;
670 798811 : return a->data.val.sval;
671 : }
672 :
673 : void
674 : #ifdef HAVE_HGE
675 253082 : sqlvar_set_number(sql_var *var, hge val)
676 : #else
677 : sqlvar_set_number(sql_var *var, lng val)
678 : #endif
679 : {
680 253082 : atom *a = &var->var;
681 :
682 253082 : if (a != NULL) {
683 253082 : ValRecord *v = &a->data;
684 : #ifdef HAVE_HGE
685 253082 : if (v->vtype == TYPE_hge)
686 0 : v->val.hval = val;
687 : #endif
688 253082 : if (v->vtype == TYPE_lng)
689 253082 : v->val.lval = val;
690 253082 : if (v->vtype == TYPE_int)
691 0 : v->val.lval = (int) val;
692 253082 : if (v->vtype == TYPE_sht)
693 0 : v->val.lval = (sht) val;
694 253082 : if (v->vtype == TYPE_bte)
695 0 : v->val.lval = (bte) val;
696 253082 : 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 253082 : }
704 :
705 : #ifdef HAVE_HGE
706 : hge
707 : #else
708 : lng
709 : #endif
710 37914 : val_get_number(ValRecord *v)
711 : {
712 37914 : if (v != NULL) {
713 : #ifdef HAVE_HGE
714 37914 : if (v->vtype == TYPE_hge)
715 0 : return v->val.hval;
716 : #endif
717 : if (v->vtype == TYPE_lng)
718 37910 : 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 : }
|