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

Reply via email to