Changeset: 369967e06405 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=369967e06405 Added Files: sql/test/BugTracker-2019/Tests/sequences-defaults.Bug-6744.sql sql/test/BugTracker-2019/Tests/sequences-defaults.Bug-6744.stable.err sql/test/BugTracker-2019/Tests/sequences-defaults.Bug-6744.stable.out Modified Files: sql/server/rel_sequence.c sql/server/sql_parser.y sql/test/BugTracker-2019/Tests/All Branch: Apr2019 Log Message:
Added test and fix for bug 6744. diffs (truncated from 392 to 300 lines): diff --git a/sql/server/rel_sequence.c b/sql/server/rel_sequence.c --- a/sql/server/rel_sequence.c +++ b/sql/server/rel_sequence.c @@ -106,7 +106,7 @@ rel_create_seq( if (is_lng_nil(start)) start = 1; if (is_lng_nil(inc)) inc = 1; if (is_lng_nil(min)) min = 0; - if (cycle && is_lng_nil(max)) cycle = 0; + if (cycle && (!is_lng_nil(max) && max < 0)) cycle = 0; if (is_lng_nil(max)) max = 0; if (is_lng_nil(cache)) cache = 1; @@ -144,65 +144,67 @@ list_create_seq( unsigned int used = 0; bit cycle = 0; - /* check if no option is given twice */ - for (n = options->h; n; n = n->next) { - symbol *s = n->data.sym; + if (options) { + /* check if no option is given twice */ + for (n = options->h; n; n = n->next) { + symbol *s = n->data.sym; - switch(s->token) { - case SQL_TYPE: - if ((used&(1<<SEQ_TYPE))) - return sql_error(sql, 02, SQLSTATE(3F000) "CREATE SEQUENCE: AS type found should be used as most once"); - used |= (1<<SEQ_TYPE); - t = &s->data.lval->h->data.typeval; - break; - case SQL_START: - if ((used&(1<<SEQ_START))) - return sql_error(sql, 02, SQLSTATE(3F000) "CREATE SEQUENCE: START value should be passed as most once"); - used |= (1<<SEQ_START); - if (is_lng_nil(s->data.l_val)) - return sql_error(sql, 02, SQLSTATE(42000) "CREATE SEQUENCE: START must not be null"); - start = s->data.l_val; - break; - case SQL_INC: - if ((used&(1<<SEQ_INC))) - return sql_error(sql, 02, SQLSTATE(3F000) "CREATE SEQUENCE: INCREMENT value should be passed as most once"); - used |= (1<<SEQ_INC); - if (is_lng_nil(s->data.l_val)) - return sql_error(sql, 02, SQLSTATE(42000) "CREATE SEQUENCE: INCREMENT must not be null"); - inc = s->data.l_val; - break; - case SQL_MINVALUE: - if ((used&(1<<SEQ_MIN))) - return sql_error(sql, 02, SQLSTATE(3F000) "CREATE SEQUENCE: MINVALUE or NO MINVALUE should be passed as most once"); - used |= (1<<SEQ_MIN); - if (is_lng_nil(s->data.l_val)) - return sql_error(sql, 02, SQLSTATE(42000) "CREATE SEQUENCE: MINVALUE must not be null"); - min = s->data.l_val; - break; - case SQL_MAXVALUE: - if ((used&(1<<SEQ_MAX))) - return sql_error(sql, 02, SQLSTATE(3F000) "CREATE SEQUENCE: MAXVALUE or NO MAXVALUE should be passed as most once"); - used |= (1<<SEQ_MAX); - if (is_lng_nil(s->data.l_val)) - return sql_error(sql, 02, SQLSTATE(42000) "CREATE SEQUENCE: MAXVALUE must be non-NULL"); - max = s->data.l_val; - break; - case SQL_CYCLE: - if ((used&(1<<SEQ_CYCLE))) - return sql_error(sql, 02, SQLSTATE(3F000) "CREATE SEQUENCE: CYCLE or NO CYCLE should be passed as most once"); - used |= (1<<SEQ_CYCLE); - cycle = s->data.i_val != 0; - break; - case SQL_CACHE: - if ((used&(1<<SEQ_CACHE))) - return sql_error(sql, 02, SQLSTATE(3F000) "CREATE SEQUENCE: CACHE value should be passed as most once"); - used |= (1<<SEQ_CACHE); - if (is_lng_nil(s->data.l_val)) - return sql_error(sql, 02, SQLSTATE(42000) "CREATE SEQUENCE: CACHE must be non-NULL"); - cache = s->data.l_val; - break; - default: - assert(0); + switch(s->token) { + case SQL_TYPE: + if ((used&(1<<SEQ_TYPE))) + return sql_error(sql, 02, SQLSTATE(3F000) "CREATE SEQUENCE: AS type found should be used as most once"); + used |= (1<<SEQ_TYPE); + t = &s->data.lval->h->data.typeval; + break; + case SQL_START: + if ((used&(1<<SEQ_START))) + return sql_error(sql, 02, SQLSTATE(3F000) "CREATE SEQUENCE: START value should be passed as most once"); + used |= (1<<SEQ_START); + if (is_lng_nil(s->data.l_val)) + return sql_error(sql, 02, SQLSTATE(42000) "CREATE SEQUENCE: START must not be null"); + start = s->data.l_val; + break; + case SQL_INC: + if ((used&(1<<SEQ_INC))) + return sql_error(sql, 02, SQLSTATE(3F000) "CREATE SEQUENCE: INCREMENT value should be passed as most once"); + used |= (1<<SEQ_INC); + if (is_lng_nil(s->data.l_val)) + return sql_error(sql, 02, SQLSTATE(42000) "CREATE SEQUENCE: INCREMENT must not be null"); + inc = s->data.l_val; + break; + case SQL_MINVALUE: + if ((used&(1<<SEQ_MIN))) + return sql_error(sql, 02, SQLSTATE(3F000) "CREATE SEQUENCE: MINVALUE or NO MINVALUE should be passed as most once"); + used |= (1<<SEQ_MIN); + if (is_lng_nil(s->data.l_val)) + return sql_error(sql, 02, SQLSTATE(42000) "CREATE SEQUENCE: MINVALUE must not be null"); + min = s->data.l_val; + break; + case SQL_MAXVALUE: + if ((used&(1<<SEQ_MAX))) + return sql_error(sql, 02, SQLSTATE(3F000) "CREATE SEQUENCE: MAXVALUE or NO MAXVALUE should be passed as most once"); + used |= (1<<SEQ_MAX); + if (is_lng_nil(s->data.l_val)) + return sql_error(sql, 02, SQLSTATE(42000) "CREATE SEQUENCE: MAXVALUE must be non-NULL"); + max = s->data.l_val; + break; + case SQL_CYCLE: + if ((used&(1<<SEQ_CYCLE))) + return sql_error(sql, 02, SQLSTATE(3F000) "CREATE SEQUENCE: CYCLE or NO CYCLE should be passed as most once"); + used |= (1<<SEQ_CYCLE); + cycle = s->data.i_val != 0; + break; + case SQL_CACHE: + if ((used&(1<<SEQ_CACHE))) + return sql_error(sql, 02, SQLSTATE(3F000) "CREATE SEQUENCE: CACHE value should be passed as most once"); + used |= (1<<SEQ_CACHE); + if (is_lng_nil(s->data.l_val)) + return sql_error(sql, 02, SQLSTATE(42000) "CREATE SEQUENCE: CACHE must be non-NULL"); + cache = s->data.l_val; + break; + default: + assert(0); + } } } return rel_create_seq(sql, ss, qname, t, start, inc, min, max, cache, cycle, bedropped); diff --git a/sql/server/sql_parser.y b/sql/server/sql_parser.y --- a/sql/server/sql_parser.y +++ b/sql/server/sql_parser.y @@ -483,6 +483,7 @@ int yydebug=1; opt_paramlist opt_typelist typelist + params_list opt_seq_params opt_alt_seq_params serial_opt_params @@ -1369,7 +1370,7 @@ seq_def: * [ [ NO ] CYCLE ] * start may be a value or subquery */ - | ALTER SEQUENCE qname opt_alt_seq_params + | ALTER SEQUENCE qname opt_alt_seq_params { dlist *l = L(); append_list(l, $3); @@ -1379,8 +1380,12 @@ seq_def: ; opt_seq_params: - opt_seq_param { $$ = append_symbol(L(), $1); } - | opt_seq_params opt_seq_param { $$ = append_symbol($1, $2); } + params_list { $$ = $1; } + | { $$ = NULL; } + +params_list: + opt_seq_param { $$ = append_symbol(L(), $1); } + | params_list opt_seq_param { $$ = append_symbol($1, $2); } ; opt_alt_seq_params: @@ -1389,13 +1394,13 @@ opt_alt_seq_params: ; opt_seq_param: - AS data_type { $$ = _symbol_create_list(SQL_TYPE, append_type(L(),&$2)); } + AS data_type { $$ = _symbol_create_list(SQL_TYPE, append_type(L(),&$2)); } | START WITH opt_sign lngval { $$ = _symbol_create_lng(SQL_START, is_lng_nil($4) ? $4 : $3 * $4); } | opt_seq_common_param { $$ = $1; } ; opt_alt_seq_param: - AS data_type { $$ = _symbol_create_list(SQL_TYPE, append_type(L(),&$2)); } + AS data_type { $$ = _symbol_create_list(SQL_TYPE, append_type(L(),&$2)); } | RESTART { $$ = _symbol_create_list(SQL_START, append_int(L(),0)); /* plain restart now */ } | RESTART WITH opt_sign lngval { $$ = _symbol_create_list(SQL_START, append_lng(append_int(L(),2), is_lng_nil($4) ? $4 : $3 * $4)); } | RESTART WITH subquery { $$ = _symbol_create_list(SQL_START, append_symbol(append_int(L(),1), $3)); } @@ -1403,7 +1408,7 @@ opt_alt_seq_param: ; opt_seq_common_param: - INCREMENT BY opt_sign lngval { $$ = _symbol_create_lng(SQL_INC, is_lng_nil($4) ? $4 : $3 * $4); } + INCREMENT BY opt_sign lngval { $$ = _symbol_create_lng(SQL_INC, is_lng_nil($4) ? $4 : $3 * $4); } | MINVALUE opt_sign lngval { $$ = _symbol_create_lng(SQL_MINVALUE, is_lng_nil($3) ? $3 : $2 * $3); } | NO MINVALUE { $$ = _symbol_create_lng(SQL_MINVALUE, 0); } | MAXVALUE opt_sign lngval { $$ = _symbol_create_lng(SQL_MAXVALUE, is_lng_nil($3) ? $3 : $2 * $3); } @@ -1850,7 +1855,7 @@ generated_column: if (!$5) $5 = L(); sql_find_subtype(&it, "int", 32, 0); - append_symbol($5, _symbol_create_list(SQL_TYPE, append_type(L(),&it))); + append_symbol($5, _symbol_create_list(SQL_TYPE, append_type(L(),&it))); /* finally all the options */ append_list(l, $5); @@ -1904,7 +1909,7 @@ generated_column: serial_opt_params: /* empty: return the defaults */ { $$ = NULL; } - | '(' opt_seq_params ')' { $$ = $2; } + | '(' params_list ')' { $$ = $2; } ; diff --git a/sql/test/BugTracker-2019/Tests/All b/sql/test/BugTracker-2019/Tests/All --- a/sql/test/BugTracker-2019/Tests/All +++ b/sql/test/BugTracker-2019/Tests/All @@ -26,3 +26,4 @@ table-duplicate-column.Bug-6729 view-too-few-rows.Bug-6736 slow-inner-join.Bug-6737 sum-over-hge.Bug.6738 +sequences-defaults.Bug-6744 diff --git a/sql/test/BugTracker-2019/Tests/sequences-defaults.Bug-6744.sql b/sql/test/BugTracker-2019/Tests/sequences-defaults.Bug-6744.sql new file mode 100644 --- /dev/null +++ b/sql/test/BugTracker-2019/Tests/sequences-defaults.Bug-6744.sql @@ -0,0 +1,16 @@ +start transaction; +create sequence seq; +create sequence seq1 AS int; +create sequence seq2 START WITH 2; +create sequence seq3 INCREMENT BY 3; +create sequence seq4 MINVALUE 4; +create sequence seq5 NO MINVALUE; +create sequence seq6 MAXVALUE 6; +create sequence seq7 NO MAXVALUE; +create sequence seq8 CACHE 8; +create sequence seq9 NO CYCLE; +create sequence seq0 CYCLE; + +select name, start, minvalue, maxvalue, increment, cacheinc, cycle from sequences +where name in ('seq', 'seq1', 'seq2', 'seq3', 'seq4', 'seq5', 'seq6', 'seq7', 'seq8', 'seq9', 'seq0'); +rollback; diff --git a/sql/test/BugTracker-2019/Tests/sequences-defaults.Bug-6744.stable.err b/sql/test/BugTracker-2019/Tests/sequences-defaults.Bug-6744.stable.err new file mode 100644 --- /dev/null +++ b/sql/test/BugTracker-2019/Tests/sequences-defaults.Bug-6744.stable.err @@ -0,0 +1,35 @@ +stderr of test 'sequences-defaults.Bug-6744` in directory 'sql/test/BugTracker-2019` itself: + + +# 11:21:15 > +# 11:21:15 > "mserver5" "--debug=10" "--set" "gdk_nr_threads=0" "--set" "mapi_open=true" "--set" "mapi_port=34651" "--set" "mapi_usock=/var/tmp/mtest-1370/.s.monetdb.34651" "--set" "monet_prompt=" "--forcemito" "--dbpath=/home/ferreira/repositories/MonetDB-Apr2019/BUILD/var/MonetDB/mTests_sql_test_BugTracker-2019" "--set" "embedded_r=yes" "--set" "embedded_py=2" "--set" "embedded_c=true" +# 11:21:15 > + +# builtin opt gdk_dbpath = /home/ferreira/repositories/MonetDB-Apr2019/BUILD/var/monetdb5/dbfarm/demo +# builtin opt monet_prompt = > +# builtin opt monet_daemon = no +# builtin opt mapi_port = 50000 +# builtin opt mapi_open = false +# builtin opt mapi_autosense = false +# builtin opt sql_optimizer = default_pipe +# builtin opt sql_debug = 0 +# cmdline opt gdk_nr_threads = 0 +# cmdline opt mapi_open = true +# cmdline opt mapi_port = 34651 +# cmdline opt mapi_usock = /var/tmp/mtest-1370/.s.monetdb.34651 +# cmdline opt monet_prompt = +# cmdline opt gdk_dbpath = /home/ferreira/repositories/MonetDB-Apr2019/BUILD/var/MonetDB/mTests_sql_test_BugTracker-2019 +# cmdline opt embedded_r = yes +# cmdline opt embedded_py = 2 +# cmdline opt embedded_c = true +#main thread:!ERROR:MALException:client.quit:Server stopped + +# 11:21:16 > +# 11:21:16 > "mclient" "-lsql" "-ftest" "-tnone" "-Eutf-8" "-i" "-e" "--host=/var/tmp/mtest-1370" "--port=34651" +# 11:21:16 > + + +# 11:21:16 > +# 11:21:16 > "Done." +# 11:21:16 > + diff --git a/sql/test/BugTracker-2019/Tests/sequences-defaults.Bug-6744.stable.out b/sql/test/BugTracker-2019/Tests/sequences-defaults.Bug-6744.stable.out new file mode 100644 --- /dev/null +++ b/sql/test/BugTracker-2019/Tests/sequences-defaults.Bug-6744.stable.out @@ -0,0 +1,102 @@ +stdout of test 'sequences-defaults.Bug-6744` in directory 'sql/test/BugTracker-2019` itself: + + +# 11:21:15 > +# 11:21:15 > "mserver5" "--debug=10" "--set" "gdk_nr_threads=0" "--set" "mapi_open=true" "--set" "mapi_port=34651" "--set" "mapi_usock=/var/tmp/mtest-1370/.s.monetdb.34651" "--set" "monet_prompt=" "--forcemito" "--dbpath=/home/ferreira/repositories/MonetDB-Apr2019/BUILD/var/MonetDB/mTests_sql_test_BugTracker-2019" "--set" "embedded_r=yes" "--set" "embedded_py=2" "--set" "embedded_c=true" +# 11:21:15 > + +# MonetDB 5 server v11.33.4 (hg id: 101e6463524a+) +# This is an unreleased version +# Serving database 'mTests_sql_test_BugTracker-2019', using 8 threads _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list