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

Generated by: LCOV version 1.14