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 388906 : destroy_sql_var(void *gdata, void *data)
25 : {
26 388906 : (void)gdata;
27 388906 : sql_var *svar = (sql_var*) data;
28 388906 : VALclear(&(svar->var.data));
29 388906 : svar->var.data.vtype = 0;
30 388906 : _DELETE(svar->sname);
31 388906 : _DELETE(svar->name);
32 388906 : _DELETE(svar);
33 388906 : }
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 379350 : var_key(sql_var *v)
42 : {
43 379350 : return hash_key(v->name);
44 : }
45 :
46 : int
47 37935 : init_global_variables(mvc *sql)
48 : {
49 37935 : sql_subtype ctype;
50 37935 : lng sec = 0;
51 37935 : ValRecord src;
52 37935 : const char *mal_optimizer, *sname = "sys";
53 37935 : sql_var *var;
54 :
55 37935 : if (!(sql->global_vars = list_create(destroy_sql_var)))
56 : return -1;
57 37935 : if (!(sql->global_vars->ht = hash_new(NULL, 16, (fkeyvalue)&var_key)))
58 : return -1;
59 :
60 37935 : sql_find_subtype(&ctype, "int", 0, 0);
61 37935 : SQL_GLOBAL(sname, "debug", &sql->debug);
62 37935 : SQL_GLOBAL(sname, "sql_optimizer", &sql->sql_optimizer);
63 37935 : SQL_GLOBAL(sname, "division_min_scale", &sql->div_min_scale);
64 :
65 37935 : sql_find_subtype(&ctype, "varchar", 1024, 0);
66 37935 : SQL_GLOBAL(sname, "current_schema", sname);
67 37935 : SQL_GLOBAL(sname, "current_user", "monetdb");
68 37935 : SQL_GLOBAL(sname, "current_role", "monetdb");
69 :
70 : /* TODO: GDKenv var sql_optimizer change to mal_optimizer */
71 37935 : mal_optimizer = GDKgetenv("sql_optimizer");
72 37935 : if (!mal_optimizer)
73 0 : mal_optimizer = "default_pipe";
74 : /* TODO: Change optmizer to mal_optimizer */
75 37935 : SQL_GLOBAL(sname, "optimizer", mal_optimizer);
76 :
77 37935 : sql_find_subtype(&ctype, "sec_interval", inttype2digits(ihour, isec), 0);
78 37935 : SQL_GLOBAL(sname, "current_timezone", &sec);
79 :
80 37935 : sql_find_subtype(&ctype, "bigint", 0, 0);
81 37935 : SQL_GLOBAL(sname, "last_id", &sec);
82 37935 : SQL_GLOBAL(sname, "rowcnt", &sec);
83 :
84 : return 0;
85 : }
86 :
87 : sql_var*
88 379350 : push_global_var(mvc *sql, const char *sname, const char *name, sql_subtype *type)
89 : {
90 379350 : sql_var *svar = ZNEW(sql_var);
91 :
92 379350 : if (!svar)
93 : return NULL;
94 379350 : if (!(svar->name = _STRDUP(name))) {
95 0 : _DELETE(svar);
96 0 : return NULL;
97 : }
98 379350 : if (!(svar->sname = _STRDUP(sname))) {
99 0 : _DELETE(svar->name);
100 0 : _DELETE(svar);
101 0 : return NULL;
102 : }
103 379350 : atom_init(&(svar->var));
104 379350 : if (type) {
105 379350 : int tpe = type->type->localtype;
106 379350 : VALset(&(svar->var.data), tpe, (ptr) ATOMnilptr(tpe));
107 379350 : svar->var.tpe = *type;
108 : }
109 379350 : 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 9556 : frame_push_var(mvc *sql, const char *name, sql_subtype *type)
133 : {
134 9556 : assert(sql->topframes > 0);
135 9556 : sql_frame *f = sql->frames[sql->topframes - 1];
136 9556 : sql_var *svar = ZNEW(sql_var);
137 :
138 9556 : if (!svar)
139 : return NULL;
140 9556 : if (!(svar->name = _STRDUP(name))) {
141 0 : _DELETE(svar);
142 0 : return NULL;
143 : }
144 9556 : atom_init(&(svar->var));
145 9556 : if (type) {
146 9556 : int tpe = type->type->localtype;
147 9556 : VALset(&(svar->var.data), tpe, (ptr) ATOMnilptr(tpe));
148 9556 : svar->var.tpe = *type;
149 : }
150 9556 : 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 9556 : 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 15449 : destroy_sql_rel_view(void *gdata, void *data)
195 : {
196 15449 : (void)gdata;
197 15449 : sql_rel_view *srv = (sql_rel_view*) data;
198 15449 : rel_destroy(srv->rel_view);
199 15449 : _DELETE(srv->name);
200 15449 : _DELETE(srv);
201 15449 : }
202 :
203 : sql_rel_view*
204 15449 : stack_push_rel_view(mvc *sql, const char *name, sql_rel *var)
205 : {
206 15449 : assert(sql->topframes > 0);
207 15449 : sql_frame *f = sql->frames[sql->topframes - 1];
208 15449 : sql_rel_view *srv = ZNEW(sql_rel_view);
209 :
210 15449 : if (!srv)
211 : return NULL;
212 15449 : if (!(srv->name = _STRDUP(name))) {
213 0 : _DELETE(srv);
214 0 : return NULL;
215 : }
216 15449 : srv->rel_view = var;
217 15449 : 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 15449 : 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 158 : destroy_sql_groupby_expression(void *gdata, void *data)
269 : {
270 158 : (void)gdata;
271 158 : sql_groupby_expression *sge = (sql_groupby_expression*) data;
272 158 : _DELETE(sge);
273 158 : }
274 :
275 : sql_groupby_expression*
276 158 : frame_push_groupby_expression(mvc *sql, symbol *def, sql_exp *exp)
277 : {
278 158 : assert(sql->topframes > 0);
279 158 : sql_frame *f = sql->frames[sql->topframes - 1];
280 158 : sql_groupby_expression *sge = ZNEW(sql_groupby_expression);
281 :
282 158 : if (!sge)
283 : return NULL;
284 158 : sge->sdef = def;
285 158 : sge->token = def->token;
286 158 : sge->exp = exp;
287 158 : if (!f->group_expressions && !(f->group_expressions = list_create(destroy_sql_groupby_expression))) {
288 0 : _DELETE(sge);
289 0 : return NULL;
290 : }
291 158 : 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 135801 : frame_get_groupby_expression(mvc *sql, symbol *def)
320 : {
321 135801 : if (sql->topframes > 0) {
322 135801 : sql_frame *f = sql->frames[sql->topframes - 1];
323 135801 : if (f->group_expressions) {
324 712 : for (node *n = f->group_expressions->h; n ; n = n->next) {
325 420 : sql_groupby_expression *var = (sql_groupby_expression*) n->data;
326 420 : if (var->token == def->token && !symbol_cmp(sql, var->sdef, def))
327 80 : 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 12707 : frame_clear_visited_flag(mvc *sql)
369 : {
370 12707 : if (sql->topframes > 0) {
371 12700 : sql_frame *f = sql->frames[sql->topframes - 1];
372 12700 : 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 12707 : }
380 :
381 : atom *
382 416684 : sqlvar_set(sql_var *var, ValRecord *v)
383 : {
384 416684 : VALclear(&(var->var.data));
385 416653 : if (VALcopy(&(var->var.data), v) == NULL)
386 : return NULL;
387 416673 : var->var.isnull = VALisnil(v);
388 416657 : return &(var->var);
389 : }
390 :
391 : sql_frame*
392 425059 : stack_push_frame(mvc *sql, const char *name)
393 : {
394 425059 : sql_frame *v, **nvars;
395 425059 : int osize = sql->sizeframes, nextsize = osize;
396 :
397 425059 : 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 425059 : if (!(v = ZNEW(sql_frame)))
405 : return NULL;
406 425139 : if (name && !(v->name = _STRDUP(name))) {
407 0 : _DELETE(v);
408 0 : return NULL;
409 : }
410 425139 : v->frame_number = ++sql->frame; /* The frame number for variables on the stack start on level 1 */
411 425139 : sql->frames[sql->topframes++] = v;
412 425139 : return v;
413 : }
414 :
415 : void
416 425045 : clear_frame(mvc *sql, sql_frame *frame)
417 : {
418 425045 : list_destroy(frame->group_expressions);
419 425052 : list_destroy(frame->windows);
420 425120 : list_destroy(frame->tables);
421 425128 : list_destroy(frame->rel_views);
422 425133 : list_destroy(frame->vars);
423 425128 : _DELETE(frame->name);
424 425035 : _DELETE(frame);
425 425144 : sql->frame--;
426 425144 : }
427 :
428 : void
429 37935 : stack_pop_until(mvc *sql, int frame)
430 : {
431 37935 : 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 37935 : }
437 :
438 : void
439 425041 : stack_pop_frame(mvc *sql)
440 : {
441 425041 : sql_frame *f = sql->frames[--sql->topframes];
442 425041 : assert(sql->topframes >= 0);
443 425041 : clear_frame(sql, f);
444 425143 : }
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 211437 : stack_find_table(mvc *sql, const char *name)
464 : {
465 3907383 : for (int i = sql->topframes-1; i >= 0; i--) {
466 3696156 : sql_frame *f = sql->frames[i];
467 3696156 : 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 111574 : stack_find_rel_view(mvc *sql, const char *name)
480 : {
481 249474 : for (int i = sql->topframes-1; i >= 0; i--) {
482 150962 : sql_frame *f = sql->frames[i];
483 150962 : if (f->rel_views) {
484 26920 : for (node *n = f->rel_views->h; n ; n = n->next) {
485 25178 : sql_rel_view *var = (sql_rel_view*) n->data;
486 25178 : assert(var->name);
487 25178 : if (!strcmp(var->name, name))
488 13062 : 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 10008 : frame_find_rel_view(mvc *sql, const char *name)
521 : {
522 10008 : assert(sql->topframes > 0);
523 10008 : sql_frame *f = sql->frames[sql->topframes - 1];
524 10008 : if (f->rel_views) {
525 12222 : for (node *n = f->rel_views->h; n ; n = n->next) {
526 8088 : sql_rel_view *var = (sql_rel_view*) n->data;
527 8088 : assert(var->name);
528 8088 : if (!strcmp(var->name, name))
529 3 : 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 1258584 : find_global_var(mvc *sql, sql_schema *s, const char *name)
556 : {
557 1258584 : const char *sname = s->base.name;
558 1258584 : int key = hash_key(name); /* Using hash lookup */
559 1258584 : sql_hash_e *he = sql->global_vars->ht->buckets[key&(sql->global_vars->ht->size-1)];
560 :
561 1390838 : for (; he; he = he->chain) {
562 1388216 : sql_var *var = (sql_var*) he->value;
563 :
564 1388216 : assert(var->sname && var->name);
565 1388216 : if (!strcmp(var->sname, sname) && !strcmp(var->name, name))
566 1255962 : return var;
567 : }
568 : return NULL;
569 : }
570 :
571 : int
572 9531 : frame_find_var(mvc *sql, const char *name)
573 : {
574 9531 : assert(sql->topframes > 0);
575 9531 : sql_frame *f = sql->frames[sql->topframes - 1];
576 9531 : if (f->vars) {
577 14431 : for (node *n = f->vars->h; n ; n = n->next) {
578 9050 : sql_var *var = (sql_var*) n->data;
579 9050 : assert(var->name);
580 9050 : if (!strcmp(var->name, name))
581 : return 1;
582 : }
583 : }
584 : return 0;
585 : }
586 :
587 : sql_var*
588 134933 : stack_find_var_frame(mvc *sql, const char *name, int *level)
589 : {
590 134933 : *level = 1; /* Level 0 is for globals */
591 304741 : for (int i = sql->topframes-1; i >= 0; i--) {
592 212611 : sql_frame *f = sql->frames[i];
593 212611 : if (f->vars) {
594 202375 : for (node *n = f->vars->h; n ; n = n->next) {
595 166136 : sql_var *var = (sql_var*) n->data;
596 166136 : assert(var->name);
597 166136 : if (!strcmp(var->name, name)) {
598 42803 : *level = f->frame_number;
599 42803 : 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 24255 : stack_nr_of_declared_tables(mvc *sql)
637 : {
638 24255 : int dt = 0;
639 :
640 59312 : for (int i = sql->topframes-1; i >= 0; i--) {
641 35057 : sql_frame *f = sql->frames[i];
642 35057 : dt += list_length(f->tables);
643 : }
644 24255 : return dt;
645 : }
646 :
647 : str
648 111713 : sqlvar_set_string(sql_var *var, const char *val)
649 : {
650 111713 : atom *a = &var->var;
651 111713 : str new_val = _STRDUP(val);
652 :
653 111714 : if (a != NULL && new_val != NULL) {
654 111714 : ValRecord *v = &a->data;
655 :
656 111714 : if (v->val.sval)
657 111714 : _DELETE(v->val.sval);
658 111714 : v->val.sval = new_val;
659 111714 : return new_val;
660 : } else if (new_val) {
661 : _DELETE(new_val);
662 : }
663 : return NULL;
664 : }
665 :
666 : str
667 836587 : sqlvar_get_string(sql_var *var)
668 : {
669 836587 : atom *a = &var->var;
670 :
671 836587 : if (!a || a->data.vtype != TYPE_str)
672 : return NULL;
673 836587 : return a->data.val.sval;
674 : }
675 :
676 : void
677 : #ifdef HAVE_HGE
678 263603 : sqlvar_set_number(sql_var *var, hge val)
679 : #else
680 : sqlvar_set_number(sql_var *var, lng val)
681 : #endif
682 : {
683 263603 : atom *a = &var->var;
684 :
685 263603 : if (a != NULL) {
686 263603 : ValRecord *v = &a->data;
687 : #ifdef HAVE_HGE
688 263603 : if (v->vtype == TYPE_hge)
689 0 : v->val.hval = val;
690 : #endif
691 263603 : if (v->vtype == TYPE_lng)
692 263621 : v->val.lval = val;
693 263603 : if (v->vtype == TYPE_int)
694 0 : v->val.lval = (int) val;
695 263603 : if (v->vtype == TYPE_sht)
696 0 : v->val.lval = (sht) val;
697 263603 : if (v->vtype == TYPE_bte)
698 0 : v->val.lval = (bte) val;
699 263603 : 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 263603 : }
707 :
708 : #ifdef HAVE_HGE
709 : hge
710 : #else
711 : lng
712 : #endif
713 37229 : val_get_number(const ValRecord *v)
714 : {
715 37229 : if (v != NULL) {
716 : #ifdef HAVE_HGE
717 37229 : if (v->vtype == TYPE_hge)
718 0 : return v->val.hval;
719 : #endif
720 : if (v->vtype == TYPE_lng)
721 37225 : 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 : }
|