Changeset: c79d6b49e80c for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=c79d6b49e80c Modified Files: monetdb5/modules/kernel/batstr.c tools/monetdbe/monetdbe.c tools/monetdbe/monetdbe_mapi.c Branch: default Log Message:
Merged with octbugs diffs (truncated from 477 to 300 lines): diff --git a/sql/backends/monet5/sql_fround_impl.h b/sql/backends/monet5/sql_fround_impl.h --- a/sql/backends/monet5/sql_fround_impl.h +++ b/sql/backends/monet5/sql_fround_impl.h @@ -41,6 +41,8 @@ dec_round_wrap(TYPE *res, const TYPE *v, /* basic sanity checks */ assert(res && v && r); + if (*r <= 0) + throw(MAL, "round", SQLSTATE(42000) "Argument 2 to round function must be positive"); *res = dec_round_body(*v, *r); return MAL_SUCCEED; } @@ -56,6 +58,8 @@ bat_dec_round_wrap(bat *_res, const bat /* basic sanity checks */ assert(_res && _v && r); + if (*r <= 0) + throw(MAL, "round", SQLSTATE(42000) "Argument 2 to round function must be positive"); /* get argument BAT descriptor */ if ((v = BATdescriptor(*_v)) == NULL) throw(MAL, "round", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING); diff --git a/sql/common/sql_types.c b/sql/common/sql_types.c --- a/sql/common/sql_types.c +++ b/sql/common/sql_types.c @@ -1880,7 +1880,7 @@ sqltypeinit( sql_allocator *sa) sql_create_func(sa, "patindex", "pcre", "patindex", FALSE, FALSE, SCALE_NONE, 0, INT, 2, *t, *t); sql_create_func(sa, "truncate", "str", "stringleft", FALSE, FALSE, SCALE_NONE, 0, *t, 2, *t, INT); sql_create_func(sa, "concat", "calc", "+", FALSE, FALSE, DIGITS_ADD, 0, *t, 2, *t, *t); - sql_create_func(sa, "ascii", "str", "ascii", FALSE, FALSE, SCALE_NONE, 0, INT, 1, *t); + sql_create_func(sa, "ascii", "str", "ascii", TRUE, FALSE, SCALE_NONE, 0, INT, 1, *t); /* ascii of empty string is null */ sql_create_func(sa, "code", "str", "unicode", FALSE, FALSE, SCALE_NONE, 0, *t, 1, INT); sql_create_func(sa, "length", "str", "length", FALSE, FALSE, SCALE_NONE, 0, INT, 1, *t); sql_create_func(sa, "right", "str", "stringright", FALSE, FALSE, SCALE_NONE, 0, *t, 2, *t, INT); @@ -1903,8 +1903,8 @@ sqltypeinit( sql_allocator *sa) sql_create_func(sa, "insert", "str", "insert", FALSE, FALSE, SCALE_NONE, 0, *t, 4, *t, INT, INT, *t); sql_create_func(sa, "replace", "str", "replace", FALSE, FALSE, SCALE_NONE, 0, *t, 3, *t, *t, *t); - sql_create_func(sa, "repeat", "str", "repeat", FALSE, FALSE, SCALE_NONE, 0, *t, 2, *t, INT); - sql_create_func(sa, "space", "str", "space", FALSE, FALSE, SCALE_NONE, 0, *t, 1, INT); + sql_create_func(sa, "repeat", "str", "repeat", TRUE, FALSE, SCALE_NONE, 0, *t, 2, *t, INT); /* repeat -1 times is null */ + sql_create_func(sa, "space", "str", "space", TRUE, FALSE, SCALE_NONE, 0, *t, 1, INT); /* space -1 times is null */ sql_create_func(sa, "char_length", "str", "length", FALSE, FALSE, SCALE_NONE, 0, INT, 1, *t); sql_create_func(sa, "character_length", "str", "length", FALSE, FALSE, SCALE_NONE, 0, INT, 1, *t); sql_create_func(sa, "octet_length", "str", "nbytes", FALSE, FALSE, SCALE_NONE, 0, INT, 1, *t); diff --git a/sql/server/rel_exp.c b/sql/server/rel_exp.c --- a/sql/server/rel_exp.c +++ b/sql/server/rel_exp.c @@ -2282,30 +2282,45 @@ exp_has_sideeffect( sql_exp *e ) return 0; } -int -exp_unsafe( sql_exp *e, int allow_identity) +static int +exps_have_unsafe(list *exps, int allow_identity) { - if (!e) - return 0; - - if (e->type != e_func && e->type != e_convert) + int unsafe = 0; + + if (list_empty(exps)) return 0; - - if (e->type == e_convert && e->l) + for (node *n = exps->h; n && !unsafe; n = n->next) + unsafe |= exp_unsafe(n->data, allow_identity); + return unsafe; +} + +int +exp_unsafe(sql_exp *e, int allow_identity) +{ + switch (e->type) { + case e_convert: return exp_unsafe(e->l, allow_identity); - if ((e->type == e_func || e->type == e_aggr) && e->l) { + case e_aggr: + case e_func: { sql_subfunc *f = e->f; - list *args = e->l; - node *n; if (IS_ANALYTIC(f->func) || (!allow_identity && is_identity(e, NULL))) return 1; - for(n = args->h; n; n = n->next) { - sql_exp *e = n->data; - - if (exp_unsafe(e, allow_identity)) - return 1; + return exps_have_unsafe(e->l, allow_identity); + } break; + case e_cmp: { + if (e->flag == cmp_in || e->flag == cmp_notin) { + return exp_unsafe(e->l, allow_identity) || exps_have_unsafe(e->r, allow_identity); + } else if (e->flag == cmp_or || e->flag == cmp_filter) { + return exps_have_unsafe(e->l, allow_identity) || exps_have_unsafe(e->r, allow_identity); + } else { + return exp_unsafe(e->l, allow_identity) || exp_unsafe(e->r, allow_identity) || (e->f && exp_unsafe(e->f, allow_identity)); } + } break; + case e_column: + case e_atom: + case e_psm: + return 0; } return 0; } diff --git a/sql/server/rel_optimizer.c b/sql/server/rel_optimizer.c --- a/sql/server/rel_optimizer.c +++ b/sql/server/rel_optimizer.c @@ -1337,19 +1337,16 @@ can_push_func(sql_exp *e, sql_rel *rel, { switch(e->type) { case e_cmp: { - int mustl = 0, mustr = 0, mustf = 0; sql_exp *l = e->l, *r = e->r, *f = e->f; + int res = 1, lmust = 0; if (e->flag == cmp_or || e->flag == cmp_in || e->flag == cmp_notin || e->flag == cmp_filter) return 0; - if (!f) { - return ((l->type == e_column || can_push_func(l, rel, &mustl)) && (*must = mustl)) || - ((r->type == e_column || can_push_func(r, rel, &mustr)) && (*must = mustr)); - } else { - return (l->type == e_column || can_push_func(l, rel, &mustl)) && - (r->type == e_column || can_push_func(r, rel, &mustr)) && - (f->type == e_column || can_push_func(f, rel, &mustf)) && (*must = (mustl || mustr || mustf)); - } + res = can_push_func(l, rel, &lmust) && can_push_func(r, rel, &lmust) && (!f || can_push_func(f, rel, &lmust)); + if (res && !lmust) + return 1; + (*must) |= lmust; + return res; } case e_convert: return can_push_func(e->l, rel, must); diff --git a/sql/test/SQLancer/Tests/sqlancer08.sql b/sql/test/SQLancer/Tests/sqlancer08.sql --- a/sql/test/SQLancer/Tests/sqlancer08.sql +++ b/sql/test/SQLancer/Tests/sqlancer08.sql @@ -15,3 +15,58 @@ ALTER TABLE t0 ALTER tc0 SET NOT NULL; INSERT INTO t0(tc0) VALUES(INTERVAL '-625288924' MONTH); UPDATE t0 SET tc0 = (t0.tc0) WHERE TRUE; DROP TABLE t0; + +START TRANSACTION; +CREATE TABLE "t1" ("tc0" DOUBLE NOT NULL,"tc1" CHARACTER LARGE OBJECT); +COPY 7 RECORDS INTO "sys"."t1" FROM stdin USING DELIMITERS E'\t',E'\n','"'; +-1823648899 "" +929994438 "0.0" +1388143804 "" +-1060683114 NULL +0.6102056577219861 NULL +0.5788611308131733 NULL +0.36061345372160747 NULL + +SELECT t1.tc0 FROM t1 WHERE "isauuid"(lower(lower("truncate"(t1.tc1, NULL)))); +ROLLBACK; + +START TRANSACTION; +CREATE TABLE "sys"."t0" ("tc0" CHARACTER LARGE OBJECT NOT NULL); +CREATE TABLE "sys"."t1" ("tc0" CHARACTER LARGE OBJECT NOT NULL); + +select t0.tc0 from t0 cross join t1 where "isauuid"(cast(trim(t1.tc0) between t0.tc0 and 'a' as clob)); + -- empty +select t0.tc0 from t0 cross join t1 where "isauuid"(cast((substr(rtrim(t1.tc0, t1.tc0), abs(-32767), 0.27)) between asymmetric (t0.tc0) and (cast(time '01:09:03' as string)) as string(19))); + -- empty +ROLLBACK; + +START TRANSACTION; +CREATE TABLE "sys"."t2" ("tc0" BIGINT NOT NULL,CONSTRAINT "t2_tc0_pkey" PRIMARY KEY ("tc0"),CONSTRAINT "t2_tc0_unique" UNIQUE ("tc0")); +COPY 4 RECORDS INTO "sys"."t2" FROM stdin USING DELIMITERS E'\t',E'\n','"'; +1611702516 +0 +-803413833 +921740890 + +select t2.tc0, scale_down(0.87735366430185102171179778451914899051189422607421875, t2.tc0) from t2; +ROLLBACK; + +START TRANSACTION; +CREATE TABLE "sys"."t0" ("tc0" BIGINT NOT NULL,CONSTRAINT "t0_tc0_pkey" PRIMARY KEY ("tc0"),CONSTRAINT "t0_tc0_unique" UNIQUE ("tc0")); +COPY 3 RECORDS INTO "sys"."t0" FROM stdin USING DELIMITERS E'\t',E'\n','"'; +34818777 +-2089543687 +0 + +CREATE TABLE "sys"."t1" ("tc0" TIMESTAMP NOT NULL,CONSTRAINT "t1_tc0_pkey" PRIMARY KEY ("tc0"),CONSTRAINT "t1_tc0_unique" UNIQUE ("tc0")); +CREATE TABLE "sys"."t2" ("tc1" INTERVAL DAY NOT NULL,CONSTRAINT "t2_tc1_pkey" PRIMARY KEY ("tc1"),CONSTRAINT "t2_tc1_unique" UNIQUE ("tc1"),CONSTRAINT "t2_tc1_unique" UNIQUE ("tc1")); +COPY 3 RECORDS INTO "sys"."t2" FROM stdin USING DELIMITERS E'\t',E'\n','"'; +133611486249600.000 +48909174537600.000 +55100204380800.000 + +SELECT ALL t1.tc0 FROM t2, t1 FULL OUTER JOIN t0 ON TRUE WHERE (ascii(ltrim(replace(r'', r'l/', r'(')))) IS NOT NULL; + -- empty +SELECT CAST(SUM(count) AS BIGINT) FROM (SELECT CAST((ascii(ltrim(replace(r'', r'l/', r'(')))) IS NOT NULL AS INT) as count FROM t2, t1 FULL OUTER JOIN t0 ON TRUE) as res; + -- 0 +ROLLBACK; diff --git a/sql/test/SQLancer/Tests/sqlancer08.stable.err b/sql/test/SQLancer/Tests/sqlancer08.stable.err --- a/sql/test/SQLancer/Tests/sqlancer08.stable.err +++ b/sql/test/SQLancer/Tests/sqlancer08.stable.err @@ -5,6 +5,10 @@ stderr of test 'sqlancer08` in directory # 11:38:36 > "mclient" "-lsql" "-ftest" "-tnone" "-Eutf-8" "-i" "-e" "--host=/var/tmp/mtest-68619" "--port=38834" # 11:38:36 > +MAPI = (monetdb) /var/tmp/mtest-456083/.s.monetdb.34034 +QUERY = select t2.tc0, scale_down(0.87735366430185102171179778451914899051189422607421875, t2.tc0) from t2; +ERROR = !Argument 2 to round function must be positive +CODE = 42000 # 11:38:36 > # 11:38:36 > "Done." diff --git a/sql/test/SQLancer/Tests/sqlancer08.stable.out b/sql/test/SQLancer/Tests/sqlancer08.stable.out --- a/sql/test/SQLancer/Tests/sqlancer08.stable.out +++ b/sql/test/SQLancer/Tests/sqlancer08.stable.out @@ -27,6 +27,81 @@ stdout of test 'sqlancer08` in directory [ NULL ] [ NULL ] #ROLLBACK; +#CREATE TABLE t0(tc0 INTERVAL MONTH DEFAULT (INTERVAL '1997904243' MONTH), tc1 TIME UNIQUE); +#INSERT INTO t0(tc0) VALUES(INTERVAL '444375026' MONTH); +[ 1 ] +#DELETE FROM t0 WHERE TRUE; +[ 1 ] +#ALTER TABLE t0 ALTER tc0 SET NOT NULL; +#INSERT INTO t0(tc0) VALUES(INTERVAL '-625288924' MONTH); +[ 1 ] +#DROP TABLE t0; +#START TRANSACTION; +#CREATE TABLE "t1" ("tc0" DOUBLE NOT NULL,"tc1" CHARACTER LARGE OBJECT); +#COPY 7 RECORDS INTO "sys"."t1" FROM stdin USING DELIMITERS E'\t',E'\n','"'; +#-1823648899 "" +#929994438 "0.0" +#1388143804 "" +#-1060683114 NULL +#0.6102056577219861 NULL +#0.5788611308131733 NULL +#0.36061345372160747 NULL +[ 7 ] +#SELECT t1.tc0 FROM t1 WHERE "isauuid"(lower(lower("truncate"(t1.tc1, NULL)))); +% sys.t1 # table_name +% tc0 # name +% double # type +% 24 # length +#ROLLBACK; +#START TRANSACTION; +#CREATE TABLE "sys"."t0" ("tc0" CHARACTER LARGE OBJECT NOT NULL); +#CREATE TABLE "sys"."t1" ("tc0" CHARACTER LARGE OBJECT NOT NULL); +#select t0.tc0 from t0 cross join t1 where "isauuid"(cast(trim(t1.tc0) between t0.tc0 and 'a' as clob)); +% sys.t0 # table_name +% tc0 # name +% clob # type +% 0 # length +#select t0.tc0 from t0 cross join t1 where "isauuid"(cast((substr(rtrim(t1.tc0, t1.tc0), abs(-32767), 0.27)) between asymmetric (t0.tc0) and (cast(time '01:09:03' as string)) as string(19))); +% sys.t0 # table_name +% tc0 # name +% clob # type +% 0 # length +#ROLLBACK; +#START TRANSACTION; +#CREATE TABLE "sys"."t2" ("tc0" BIGINT NOT NULL,CONSTRAINT "t2_tc0_pkey" PRIMARY KEY ("tc0"),CONSTRAINT "t2_tc0_unique" UNIQUE ("tc0")); +#COPY 4 RECORDS INTO "sys"."t2" FROM stdin USING DELIMITERS E'\t',E'\n','"'; +#1611702516 +#0 +#-803413833 +#921740890 +[ 4 ] +#ROLLBACK; +#START TRANSACTION; +#CREATE TABLE "sys"."t0" ("tc0" BIGINT NOT NULL,CONSTRAINT "t0_tc0_pkey" PRIMARY KEY ("tc0"),CONSTRAINT "t0_tc0_unique" UNIQUE ("tc0")); +#COPY 3 RECORDS INTO "sys"."t0" FROM stdin USING DELIMITERS E'\t',E'\n','"'; +#34818777 +#-2089543687 +#0 +[ 3 ] +#CREATE TABLE "sys"."t1" ("tc0" TIMESTAMP NOT NULL,CONSTRAINT "t1_tc0_pkey" PRIMARY KEY ("tc0"),CONSTRAINT "t1_tc0_unique" UNIQUE ("tc0")); +#CREATE TABLE "sys"."t2" ("tc1" INTERVAL DAY NOT NULL,CONSTRAINT "t2_tc1_pkey" PRIMARY KEY ("tc1"),CONSTRAINT "t2_tc1_unique" UNIQUE ("tc1"),CONSTRAINT "t2_tc1_unique" UNIQUE ("tc1")); +#COPY 3 RECORDS INTO "sys"."t2" FROM stdin USING DELIMITERS E'\t',E'\n','"'; +#133611486249600.000 +#48909174537600.000 +#55100204380800.000 +[ 3 ] +#SELECT ALL t1.tc0 FROM t2, t1 FULL OUTER JOIN t0 ON TRUE WHERE (ascii(ltrim(replace(r'', r'l/', r'(')))) IS NOT NULL; +% .t1 # table_name +% tc0 # name +% timestamp # type +% 26 # length +#SELECT CAST(SUM(count) AS BIGINT) FROM (SELECT CAST((ascii(ltrim(replace(r'', r'l/', r'(')))) IS NOT NULL AS INT) as count FROM t2, t1 FULL OUTER JOIN t0 ON TRUE) as res; +% .%3 # table_name +% %3 # name +% bigint # type +% 1 # length +[ 0 ] +#ROLLBACK; # 11:38:36 > # 11:38:36 > "Done." diff --git a/tools/monetdbe/monetdbe.c b/tools/monetdbe/monetdbe.c _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list