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