Changeset: b8017bcbe66b for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=b8017bcbe66b
Modified Files:
monetdb5/modules/kernel/batstr.c
sql/common/sql_types.c
Branch: clean-candidates
Log Message:
Merged with default
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
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list