LCOV - code coverage report
Current view: top level - sql/server - rel_sequence.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 239 295 81.0 %
Date: 2024-04-25 20:03:45 Functions: 8 8 100.0 %

          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 "rel_select.h"
      15             : #include "rel_rel.h"
      16             : #include "rel_sequence.h"
      17             : #include "rel_exp.h"
      18             : #include "sql_privileges.h"
      19             : 
      20             : char*
      21         196 : sql_next_seq_name(mvc *m)
      22             : {
      23         196 :         sqlid id = store_next_oid(m->session->tr->store);
      24         196 :         size_t len = 5 + 10;    /* max nr of digits of (4 bytes) int is 10 */
      25         196 :         char *msg = sa_alloc(m->sa, len);
      26             : 
      27         196 :         snprintf(msg, len, "seq_%d", id);
      28         196 :         return msg;
      29             : }
      30             : 
      31             : static sql_rel *
      32          32 : rel_drop_seq(sql_allocator *sa, char *sname, char *seqname)
      33             : {
      34          32 :         sql_rel *rel = rel_create(sa);
      35          32 :         list *exps = new_exp_list(sa);
      36          32 :         if(!rel || !exps)
      37             :                 return NULL;
      38             : 
      39          32 :         append(exps, exp_atom_clob(sa, sname));
      40          32 :         append(exps, exp_atom_clob(sa, seqname));
      41          32 :         append(exps, exp_atom_int(sa, 0));
      42          32 :         rel->l = NULL;
      43          32 :         rel->r = NULL;
      44          32 :         rel->op = op_ddl;
      45          32 :         rel->flag = ddl_drop_seq;
      46          32 :         rel->exps = exps;
      47          32 :         rel->card = 0;
      48          32 :         rel->nrcols = 0;
      49          32 :         return rel;
      50             : }
      51             : 
      52             : static sql_rel *
      53         355 : rel_seq(sql_allocator *sa, int cat_type, char *sname, sql_sequence *s, sql_rel *r, sql_exp *val)
      54             : {
      55         355 :         sql_rel *rel = rel_create(sa);
      56         355 :         list *exps = new_exp_list(sa);
      57         355 :         if(!rel || !exps)
      58             :                 return NULL;
      59             : 
      60         355 :         if (val)
      61          44 :                 append(exps, val);
      62             :         else
      63         311 :                 append(exps, exp_atom_int(sa, 0));
      64         355 :         append(exps, exp_atom_str(sa, sname, sql_bind_localtype("str") ));
      65         355 :         append(exps, exp_atom_str(sa, s->base.name, sql_bind_localtype("str") ));
      66         355 :         append(exps, exp_atom_ptr(sa, s));
      67         355 :         rel->l = r;
      68         355 :         rel->r = NULL;
      69         355 :         rel->op = op_ddl;
      70         355 :         rel->flag = cat_type;
      71         355 :         rel->exps = exps;
      72         355 :         rel->card = CARD_MULTI;
      73         355 :         rel->nrcols = 0;
      74         355 :         return rel;
      75             : }
      76             : 
      77             : static sql_rel *
      78         314 : rel_create_seq(
      79             :         mvc *sql,
      80             :         dlist *qname,
      81             :         sql_subtype *tpe,
      82             :         lng start,
      83             :         lng inc,
      84             :         symbol* s_min,
      85             :         symbol* s_max,
      86             :         lng cache,
      87             :         bit cycle,
      88             :         bit bedropped)
      89             : {
      90         314 :         bit nomin = s_min && s_min ->type == type_int ? 1: 0;
      91         314 :         bit nomax = s_max && s_max ->type == type_int ? 1: 0;
      92         314 :         lng min = s_min ? s_min->data.l_val : lng_nil;
      93         314 :         lng max = s_max ? s_max->data.l_val : lng_nil;
      94         314 :         sql_rel *res = NULL;
      95         314 :         sql_sequence *seq = NULL;
      96         314 :         char *sname = qname_schema(qname);
      97         314 :         char *name = qname_schema_object(qname);
      98         314 :         sql_schema *s = cur_schema(sql);
      99             : 
     100         314 :         if (sname && !(s = mvc_bind_schema(sql, sname)))
     101           0 :                 return sql_error(sql, ERR_NOTFOUND, SQLSTATE(3F000) "CREATE SEQUENCE: no such schema '%s'", sname);
     102         314 :         if (!mvc_schema_privs(sql, s))
     103           0 :                 return sql_error(sql, 02, SQLSTATE(42000) "CREATE SEQUENCE: access denied for %s to schema '%s'", get_string_global_var(sql, "current_user"), s->base.name);
     104         314 :         (void) tpe;
     105         314 :         if (find_sql_sequence(sql->session->tr, s, name))
     106           0 :                 return sql_error(sql, 02, SQLSTATE(42000) "CREATE SEQUENCE: name '%s' already in use", name);
     107         314 :         if (!mvc_schema_privs(sql, s))
     108           0 :                 return sql_error(sql, 02, SQLSTATE(42000) "CREATE SEQUENCE: insufficient privileges "
     109             :                                 "for '%s' in schema '%s'", get_string_global_var(sql, "current_user"), s->base.name);
     110             : 
     111             :         /* generate defaults */
     112         314 :         if (is_lng_nil(inc)) inc = 1;
     113         314 :         if (nomin) min = GDK_lng_min;
     114         314 :         if (nomax) max = GDK_lng_max;
     115         314 :         if (is_lng_nil(min)) min = inc > 0 ? 0 : GDK_lng_min;
     116         314 :         if (is_lng_nil(max)) max = inc > 0 ? GDK_lng_max : 0;
     117         314 :         if (is_lng_nil(start)) {if (inc > 0) start = nomin ? 1 : min ? min : 1; else if (inc < 0) start = nomax ? -1 : max ? max : -1;}
     118         314 :         if (is_lng_nil(cache)) cache = 1;
     119         314 :         if (is_bit_nil(cycle)) cycle = 0;
     120             : 
     121         314 :         if (inc == 0)
     122           0 :                 return sql_error(sql, 02, SQLSTATE(42000) "CREATE SEQUENCE: INCREMENT cannot be 0");
     123         314 :         if (cache <= 0)
     124           0 :                 return sql_error(sql, 02, SQLSTATE(42000) "CREATE SEQUENCE: CACHE must be positive");
     125         314 :         lng calc = llabs(inc) * cache;
     126         314 :         if (calc < llabs(inc) || calc < cache)
     127           0 :                 return sql_error(sql, 02, SQLSTATE(42000) "CREATE SEQUENCE: The specified range of cached values cannot be set. Either reduce increment or cache value");
     128         314 :         if (max < min)
     129           1 :                 return sql_error(sql, 02, SQLSTATE(42000) "CREATE SEQUENCE: MAXVALUE value is less than MINVALUE ("LLFMT" < "LLFMT")", max, min);
     130         313 :         if (start < min)
     131           1 :                 return sql_error(sql, 02, SQLSTATE(42000) "CREATE SEQUENCE: START value is less than MINVALUE ("LLFMT" < "LLFMT")", start, min);
     132         312 :         if (start > max)
     133           1 :                 return sql_error(sql, 02, SQLSTATE(42000) "CREATE SEQUENCE: START value is higher than MAXVALUE ("LLFMT" > "LLFMT")", start, max);
     134             : 
     135         311 :         seq = create_sql_sequence(sql->store, sql->sa, s, name, start, min, max, inc, cache, cycle);
     136         311 :         seq->bedropped = bedropped;
     137         311 :         res = rel_seq(sql->sa, ddl_create_seq, s->base.name, seq, NULL, NULL);
     138             :         /* for multi statements we keep the sequence around */
     139         311 :         if (res && stack_has_frame(sql, "%MUL") != 0) {
     140         196 :                 if (!stack_push_rel_view(sql, name, rel_dup(res)))
     141           0 :                         return sql_error(sql, 02, SQLSTATE(HY013) MAL_MALLOC_FAIL);
     142             :         }
     143             : 
     144             :         return res;
     145             : }
     146             : 
     147             : #define SEQ_TYPE        0
     148             : #define SEQ_START       1
     149             : #define SEQ_INC         2
     150             : #define SEQ_MIN         3
     151             : #define SEQ_MAX         4
     152             : #define SEQ_CYCLE       5
     153             : #define SEQ_CACHE       6
     154             : 
     155             : static sql_rel *
     156         322 : list_create_seq(
     157             :         mvc *sql,
     158             :         dlist *qname,
     159             :         dlist *options,
     160             :         bit bedropped)
     161             : {
     162         322 :         dnode *n;
     163         322 :         sql_subtype *t = NULL;
     164         322 :         lng start = lng_nil, inc = lng_nil, cache = lng_nil;
     165         322 :         symbol* min = NULL,* max = NULL;
     166         322 :         unsigned int used = 0;
     167         322 :         bit cycle = 0;
     168             : 
     169         322 :         if (options) {
     170             :                 /* check if no option is given twice */
     171         756 :                 for (n = options->h; n; n = n->next) {
     172         447 :                         symbol *s = n->data.sym;
     173             : 
     174         447 :                         switch(s->token) {
     175         298 :                         case SQL_TYPE: {
     176         298 :                                 bool found = false;
     177         298 :                                 const char *valid_types[4] = {"tinyint", "smallint", "int", "bigint"};
     178         298 :                                 size_t number_valid_types = sizeof(valid_types) / sizeof(valid_types[0]);
     179             : 
     180         298 :                                 if ((used&(1<<SEQ_TYPE)))
     181           8 :                                         return sql_error(sql, 02, SQLSTATE(3F000) "CREATE SEQUENCE: AS type found should be used as most once");
     182         298 :                                 used |= (1<<SEQ_TYPE);
     183         298 :                                 t = &s->data.lval->h->data.typeval;
     184         923 :                                 for (size_t i = 0; i < number_valid_types; i++) {
     185         915 :                                         if (strcasecmp(valid_types[i], t->type->base.name) == 0) {
     186             :                                                 found = true;
     187             :                                                 break;
     188             :                                         }
     189             :                                 }
     190         298 :                                 if (!found)
     191           8 :                                         return sql_error(sql, 02, SQLSTATE(42000) "CREATE SEQUENCE: The type of the sequence must be either tinyint, smallint, int or bigint");
     192         290 :                         } break;
     193          52 :                         case SQL_START:
     194          52 :                                 if ((used&(1<<SEQ_START)))
     195           0 :                                         return sql_error(sql, 02, SQLSTATE(3F000) "CREATE SEQUENCE: START value should be passed as most once");
     196          52 :                                 used |= (1<<SEQ_START);
     197          52 :                                 if (is_lng_nil(s->data.l_val))
     198           0 :                                         return sql_error(sql, 02, SQLSTATE(42000) "CREATE SEQUENCE: START must not be null");
     199             :                                 start = s->data.l_val;
     200             :                                 break;
     201          22 :                         case SQL_INC:
     202          22 :                                 if ((used&(1<<SEQ_INC)))
     203           0 :                                         return sql_error(sql, 02, SQLSTATE(3F000) "CREATE SEQUENCE: INCREMENT value should be passed as most once");
     204          22 :                                 used |= (1<<SEQ_INC);
     205          22 :                                 if (is_lng_nil(s->data.l_val))
     206           0 :                                         return sql_error(sql, 02, SQLSTATE(42000) "CREATE SEQUENCE: INCREMENT must not be null");
     207             :                                 inc = s->data.l_val;
     208             :                                 break;
     209          20 :                         case SQL_MINVALUE:
     210          20 :                                 if ((used&(1<<SEQ_MIN)))
     211           0 :                                         return sql_error(sql, 02, SQLSTATE(3F000) "CREATE SEQUENCE: MINVALUE or NO MINVALUE should be passed as most once");
     212          20 :                                 used |= (1<<SEQ_MIN);
     213          20 :                                 if (s->type == type_lng) {
     214          18 :                                          if (is_lng_nil(s->data.l_val))
     215           0 :                                                 return sql_error(sql, 02, SQLSTATE(42000) "CREATE SEQUENCE: MINVALUE must not be null");
     216             :                                 }
     217          20 :                                 assert(s->type == type_lng || (s->type == type_int && is_int_nil(s->data.i_val)));
     218             :                                 // int_nil signals NO MINVALUE
     219             :                                 min = s;
     220             :                                 break;
     221          23 :                         case SQL_MAXVALUE:
     222          23 :                                 if ((used&(1<<SEQ_MAX)))
     223           0 :                                         return sql_error(sql, 02, SQLSTATE(3F000) "CREATE SEQUENCE: MAXVALUE or NO MAXVALUE should be passed as most once");
     224          23 :                                 used |= (1<<SEQ_MAX);
     225          23 :                                 if (s->type == type_lng) {
     226          22 :                                          if (is_lng_nil(s->data.l_val))
     227           0 :                                                 return sql_error(sql, 02, SQLSTATE(42000) "CREATE SEQUENCE: MAXVALUE must not be null");
     228             :                                 }
     229          23 :                                 assert(s->type == type_lng || (s->type == type_int && is_int_nil(s->data.i_val)));
     230             :                                 // int_nil signals NO MAXVALUE
     231             :                                 max = s;
     232             :                                 break;
     233          22 :                         case SQL_CYCLE:
     234          22 :                                 if ((used&(1<<SEQ_CYCLE)))
     235           0 :                                         return sql_error(sql, 02, SQLSTATE(3F000) "CREATE SEQUENCE: CYCLE or NO CYCLE should be passed as most once");
     236          22 :                                 used |= (1<<SEQ_CYCLE);
     237          22 :                                 cycle = s->data.i_val != 0;
     238          22 :                                 break;
     239          10 :                         case SQL_CACHE:
     240          10 :                                 if ((used&(1<<SEQ_CACHE)))
     241           0 :                                         return sql_error(sql, 02, SQLSTATE(3F000) "CREATE SEQUENCE: CACHE value should be passed as most once");
     242          10 :                                 used |= (1<<SEQ_CACHE);
     243          10 :                                 if (is_lng_nil(s->data.l_val))
     244           0 :                                         return sql_error(sql, 02, SQLSTATE(42000) "CREATE SEQUENCE: CACHE must be non-NULL");
     245             :                                 cache = s->data.l_val;
     246             :                                 break;
     247             :                         default:
     248           0 :                                 assert(0);
     249             :                         }
     250             :                 }
     251             :         }
     252         314 :         return rel_create_seq(sql, qname, t, start, inc, min, max, cache, cycle, bedropped);
     253             : }
     254             : 
     255             : static sql_rel *
     256          45 : rel_alter_seq(
     257             :                 sql_query *query,
     258             :                 dlist *qname,
     259             :                 sql_subtype *tpe,
     260             :                 dlist* start_list,
     261             :                 lng inc,
     262             :                 symbol* s_min,
     263             :                 symbol* s_max,
     264             :                 lng cache,
     265             :                 bit cycle)
     266             : {
     267          45 :         bit nomin = s_min && s_min ->type == type_int ? 1: 0;
     268          45 :         bit nomax = s_max && s_max ->type == type_int ? 1: 0;
     269          45 :         lng min = s_min ? s_min->data.l_val : lng_nil;
     270          45 :         lng max = s_max ? s_max->data.l_val : lng_nil;
     271          45 :         mvc *sql = query->sql;
     272          45 :         char *sname = qname_schema(qname);
     273          45 :         char *name = qname_schema_object(qname);
     274          45 :         sql_sequence *seq;
     275          45 :         int start_type = start_list?start_list->h->data.i_val:0;
     276          45 :         sql_rel *r = NULL;
     277          45 :         sql_exp *val = NULL;
     278             : 
     279          45 :         assert(!start_list || start_list->h->type == type_int);
     280          45 :         (void) tpe;
     281          45 :         if (!(seq = find_sequence_on_scope(sql, sname, name, "ALTER SEQUENCE")))
     282             :                 return NULL;
     283          44 :         if (!mvc_schema_privs(sql, seq->s))
     284           0 :                 return sql_error(sql, 02, SQLSTATE(42000) "ALTER SEQUENCE: insufficient privileges "
     285           0 :                                 "for '%s' in schema '%s'", get_string_global_var(sql, "current_user"), seq->s->base.name);
     286             : 
     287             :         /* if not being modified, use existing values */
     288          44 :         if (is_lng_nil(inc)) inc = seq->increment;
     289          44 :         if (nomin) min = GDK_lng_min;
     290          44 :         if (nomax) max = GDK_lng_max;
     291          44 :         if (is_lng_nil(min)) min = seq->minvalue;
     292          44 :         if (is_lng_nil(max)) max = seq->maxvalue;
     293          44 :         if (is_lng_nil(cache)) cache = seq->cacheinc;
     294          44 :         if (is_bit_nil(cycle)) cycle = seq->cycle;
     295             : 
     296          44 :         if (inc == 0)
     297           0 :                 return sql_error(sql, 02, SQLSTATE(42000) "ALTER SEQUENCE: INCREMENT cannot be 0");
     298          44 :         if (cache <= 0)
     299           0 :                 return sql_error(sql, 02, SQLSTATE(42000) "ALTER SEQUENCE: CACHE must be positive");
     300          44 :         lng calc = llabs(inc) * cache;
     301          44 :         if (calc < llabs(inc) || calc < cache)
     302           0 :                 return sql_error(sql, 02, SQLSTATE(42000) "ALTER SEQUENCE: The specified range of cached values cannot be set. Either reduce increment or cache value");
     303          44 :         if (max < min)
     304           0 :                 return sql_error(sql, 02, SQLSTATE(42000) "ALTER SEQUENCE: MAXVALUE value is less than MINVALUE ("LLFMT" < "LLFMT")", max, min);
     305             :         /* first alter the known values */
     306          44 :         seq = create_sql_sequence(sql->store, sql->sa, seq->s, name, seq->start, min, max, inc, cache, cycle);
     307             : 
     308             :         /* restart may be a query, i.e. we create a statement
     309             :            restart(ssname,seqname,value) */
     310             : 
     311          44 :         if (start_type == 0) {
     312           0 :                 val = exp_atom_lng(sql->sa, seq->start);
     313          44 :         } else if (start_type == 1) { /* value (exp) */
     314           7 :                 exp_kind ek = {type_value, card_value, FALSE};
     315           7 :                 sql_subtype *lng_t = sql_bind_localtype("lng");
     316             : 
     317           7 :                 val = rel_value_exp2(query, &r, start_list->h->next->data.sym, sql_sel, ek);
     318           7 :                 if (!val || !(val = exp_check_type(sql, lng_t, r, val, type_equal)))
     319           0 :                         return NULL;
     320           7 :                 if (r && r->op == op_project) {
     321           0 :                         exp_label(sql->sa, val, ++sql->label);
     322           0 :                         val = rel_project_add_exp(sql, r, val);
     323             :                 }
     324          37 :         } else if (start_type == 2) {
     325          37 :                 assert (start_list->h->next->type == type_lng);
     326          37 :                 val = exp_atom_lng(sql->sa, start_list->h->next->data.l_val);
     327             :         }
     328          44 :         if (val && val->card > CARD_ATOM) {
     329           0 :                 sql_subfunc *zero_or_one = sql_bind_func(sql, "sys", "zero_or_one", exp_subtype(val), NULL, F_AGGR, true);
     330           0 :                 val = exp_aggr1(sql->sa, val, zero_or_one, 0, 0, CARD_ATOM, has_nil(val));
     331             :         }
     332          44 :         return rel_seq(sql->sa, ddl_alter_seq, seq->s->base.name, seq, r, val);
     333             : }
     334             : 
     335             : static sql_rel *
     336          45 : list_alter_seq(
     337             :         sql_query *query,
     338             :         dlist *qname,
     339             :         dlist *options)
     340             : {
     341          45 :         mvc *sql = query->sql;
     342          45 :         dnode *n;
     343          45 :         sql_subtype* t = NULL;
     344          45 :         lng inc = lng_nil, cache = lng_nil;
     345          45 :         symbol* min = NULL,* max = NULL;
     346          45 :         dlist *start = NULL;
     347          45 :         unsigned int used = 0;
     348          45 :         bit cycle = 0;
     349             : 
     350             :         /* check if no option is given twice */
     351         164 :         for (n = options->h; n; n = n->next) {
     352         119 :                 symbol *s = n->data.sym;
     353             : 
     354         119 :                 switch(s->token) {
     355           0 :                 case SQL_TYPE:
     356           0 :                         if ((used&(1<<SEQ_TYPE)))
     357           0 :                                 return sql_error(sql, 02, SQLSTATE(3F000) "ALTER SEQUENCE: AS type found should be used as most once");
     358           0 :                         used |= (1<<SEQ_TYPE);
     359           0 :                         t = &s->data.lval->h->data.typeval;
     360           0 :                         break;
     361          44 :                 case SQL_START:
     362          44 :                         if ((used&(1<<SEQ_START)))
     363           0 :                                 return sql_error(sql, 02, SQLSTATE(3F000) "ALTER SEQUENCE: START value should be passed as most once");
     364          44 :                         used |= (1<<SEQ_START);
     365          44 :                         if (is_lng_nil(s->data.l_val))
     366           0 :                                 return sql_error(sql, 02, SQLSTATE(42000) "ALTER SEQUENCE: START must be non-NULL");
     367          44 :                         start = s->data.lval;
     368          44 :                         break;
     369           6 :                 case SQL_INC:
     370           6 :                         if ((used&(1<<SEQ_INC)))
     371           0 :                                 return sql_error(sql, 02, SQLSTATE(3F000) "ALTER SEQUENCE: INCREMENT value should be passed as most once");
     372           6 :                         used |= (1<<SEQ_INC);
     373           6 :                         if (is_lng_nil(s->data.l_val))
     374           0 :                                 return sql_error(sql, 02, SQLSTATE(42000) "ALTER SEQUENCE: INCREMENT must be non-NULL");
     375             :                         inc = s->data.l_val;
     376             :                         break;
     377          31 :                 case SQL_MINVALUE:
     378          31 :                         if ((used&(1<<SEQ_MIN)))
     379           0 :                                 return sql_error(sql, 02, SQLSTATE(3F000) "ALTER SEQUENCE: MINVALUE or NO MINVALUE should be passed as most once");
     380          31 :                         used |= (1<<SEQ_MIN);
     381          31 :                         if (s->type == type_lng) {
     382          31 :                                 if (is_lng_nil(s->data.l_val))
     383           0 :                                         return sql_error(sql, 02, SQLSTATE(42000) "ALTER SEQUENCE: MINVALUE must not be null");
     384             :                         }
     385          31 :                         assert(s->type == type_lng || (s->type == type_int && is_int_nil(s->data.i_val)));
     386             :                         min = s;
     387             :                         // int_nil signals NO MINVALUE
     388             :                         break;
     389           5 :                 case SQL_MAXVALUE:
     390           5 :                         if ((used&(1<<SEQ_MAX)))
     391           0 :                                 return sql_error(sql, 02, SQLSTATE(3F000) "ALTER SEQUENCE: MAXVALUE or NO MAXVALUE should be passed as most once");
     392           5 :                         used |= (1<<SEQ_MAX);
     393           5 :                         if (s->type == type_lng) {
     394           5 :                                 if (is_lng_nil(s->data.l_val))
     395           0 :                                         return sql_error(sql, 02, SQLSTATE(42000) "ALTER SEQUENCE: MAXVALUE must not be null");
     396             :                         }
     397           5 :                         assert(s->type == type_lng || (s->type == type_int && is_int_nil(s->data.i_val)));
     398             :                         // int_nil signals NO MAXVALUE
     399             :                         max = s;
     400             :                         break;
     401          33 :                 case SQL_CYCLE:
     402          33 :                         if ((used&(1<<SEQ_CYCLE)))
     403           0 :                                 return sql_error(sql, 02, SQLSTATE(3F000) "ALTER SEQUENCE: CYCLE or NO CYCLE should be passed as most once");
     404          33 :                         used |= (1<<SEQ_CYCLE);
     405          33 :                         cycle = s->data.i_val != 0;
     406          33 :                         break;
     407           0 :                 case SQL_CACHE:
     408           0 :                         if ((used&(1<<SEQ_CACHE)))
     409           0 :                                 return sql_error(sql, 02, SQLSTATE(3F000) "ALTER SEQUENCE: CACHE value should be passed as most once");
     410           0 :                         used |= (1<<SEQ_CACHE);
     411           0 :                         if (is_lng_nil(s->data.l_val))
     412           0 :                                 return sql_error(sql, 02, SQLSTATE(42000) "ALTER SEQUENCE: CACHE must be non-NULL");
     413             :                         cache = s->data.l_val;
     414             :                         break;
     415             :                 default:
     416           0 :                         assert(0);
     417             :                 }
     418             :         }
     419          45 :         return rel_alter_seq(query, qname, t, start, inc, min, max, cache, cycle);
     420             : }
     421             : 
     422             : sql_rel *
     423         399 : rel_sequences(sql_query *query, symbol *s)
     424             : {
     425         399 :         mvc *sql = query->sql;
     426         399 :         sql_rel *res = NULL;
     427             : 
     428         399 :         switch (s->token) {
     429         322 :                 case SQL_CREATE_SEQ:
     430             :                 {
     431         322 :                         dlist *l = s->data.lval;
     432             : 
     433         322 :                         res = list_create_seq(
     434             : /* mvc* sql */          sql,
     435         322 : /* dlist* qname */      l->h->data.lval,
     436         322 : /* dlist* options */    l->h->next->data.lval,
     437         322 : /* bit bedropped */     (bit) (l->h->next->next->data.i_val != 0));
     438             :                 }
     439         322 :                 break;
     440          45 :                 case SQL_ALTER_SEQ:
     441             :                 {
     442          45 :                         dlist* l = s->data.lval;
     443             : 
     444          45 :                         res = list_alter_seq(
     445             : /* mvc* sql */          query,
     446          45 : /* dlist* qname */      l->h->data.lval,
     447          45 : /* dlist* options */    l->h->next->data.lval);
     448             :                 }
     449          45 :                 break;
     450          32 :                 case SQL_DROP_SEQ:
     451             :                 {
     452          32 :                         dlist *l = s->data.lval;
     453          32 :                         char *sname = qname_schema(l->h->data.lval);
     454          32 :                         char *seqname = qname_schema_object(l->h->data.lval);
     455          32 :                         sql_sequence *seq = NULL;
     456             : 
     457          32 :                         if (!(seq = find_sequence_on_scope(sql, sname, seqname, "DROP SEQUENCE")))
     458             :                                 return NULL;
     459          32 :                         res = rel_drop_seq(sql->sa, seq->s->base.name, seqname);
     460             :                 }
     461          32 :                 break;
     462           0 :                 default:
     463           0 :                         return sql_error(sql, 01, SQLSTATE(42000) "sql_stmt Symbol(%p)->token = %s", s, token2string(s->token));
     464             :         }
     465         399 :         sql->type = Q_SCHEMA;
     466         399 :         return res;
     467             : }

Generated by: LCOV version 1.14