LCOV - code coverage report
Current view: top level - sql/server - sql_var.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 296 366 80.9 %
Date: 2021-10-13 02:24:04 Functions: 38 39 97.4 %

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

Generated by: LCOV version 1.14