Changeset: 79badf93261a for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=79badf93261a
Modified Files:
        sql/backends/monet5/rel_bin.c
        sql/test/SQLancer/Tests/sqlancer14.test
Branch: default
Log Message:

Two sqlancer bugs killed in one shot. 1. Always clean 'cascade_action' list 
before returning on updates code generation 2. Converting between the same type 
during code generation should be always allowed


diffs (147 lines):

diff --git a/sql/backends/monet5/rel_bin.c b/sql/backends/monet5/rel_bin.c
--- a/sql/backends/monet5/rel_bin.c
+++ b/sql/backends/monet5/rel_bin.c
@@ -30,7 +30,7 @@ static stmt * exp_bin(backend *be, sql_e
 static stmt * rel_bin(backend *be, sql_rel *rel);
 static stmt * subrel_bin(backend *be, sql_rel *rel, list *refs);
 
-static stmt *check_types(backend *be, sql_subtype *ct, stmt *s, check_type 
tpe);
+static stmt *check_types(backend *be, sql_subtype *fromtype, stmt *s, 
check_type tpe);
 
 static void
 clean_mal_statements(backend *be, int oldstop, int oldvtop, int oldvid)
@@ -1603,52 +1603,43 @@ stmt_set_type_param(mvc *sql, sql_subtyp
        return -1;
 }
 
-/* check_types tries to match the ct type with the type of s if they don't
+/* check_types tries to match the t type with the type of s if they don't
  * match s is converted. Returns NULL on failure.
  */
 static stmt *
-check_types(backend *be, sql_subtype *ct, stmt *s, check_type tpe)
+check_types(backend *be, sql_subtype *t, stmt *s, check_type tpe)
 {
        mvc *sql = be->mvc;
-       int c = 0;
-       sql_subtype *t = NULL, *st = NULL;
-
-       st = tail_type(s);
-       if ((!st || !st->type) && stmt_set_type_param(sql, ct, s) == 0) {
+       int c, err = 0;
+       sql_subtype *fromtype = tail_type(s);
+
+       if ((!fromtype || !fromtype->type) && stmt_set_type_param(sql, t, s) == 
0)
                return s;
-       } else if (!st) {
+       if (!fromtype)
                return sql_error(sql, 02, SQLSTATE(42000) "statement has no 
type information");
-       }
-
-       /* check if the types are the same */
-       if (t && subtype_cmp(t, ct) != 0) {
-               t = NULL;
-       }
-
-       if (!t) {       /* try to convert if needed */
-               if (EC_INTERVAL(st->type->eclass) && (ct->type->eclass == 
EC_NUM || ct->type->eclass == EC_POS) && ct->digits < st->digits) {
-                       s = NULL; /* conversion from interval to num depends on 
the number of digits */
+
+       if (fromtype && subtype_cmp(t, fromtype) != 0) {
+               if (EC_INTERVAL(fromtype->type->eclass) && (t->type->eclass == 
EC_NUM || t->type->eclass == EC_POS) && t->digits < fromtype->digits) {
+                       err = 1; /* conversion from interval to num depends on 
the number of digits */
                } else {
-                       c = sql_type_convert(st->type->eclass, 
ct->type->eclass);
+                       c = sql_type_convert(fromtype->type->eclass, 
t->type->eclass);
                        if (!c || (c == 2 && tpe == type_set) || (c == 3 && tpe 
!= type_cast)) {
-                               s = NULL;
+                               err = 1;
                        } else {
-                               s = stmt_convert(be, s, NULL, st, ct);
+                               s = stmt_convert(be, s, NULL, fromtype, t);
                        }
                }
        }
-       if (!s) {
-               stmt *res = sql_error(
-                       sql, 03,
-                       SQLSTATE(42000) "types %s(%u,%u) (%s) and %s(%u,%u) 
(%s) are not equal",
-                       st->type->sqlname,
-                       st->digits,
-                       st->scale,
-                       st->type->base.name,
-                       ct->type->sqlname,
-                       ct->digits,
-                       ct->scale,
-                       ct->type->base.name
+       if (err) {
+               stmt *res = sql_error(sql, 03, SQLSTATE(42000) "types %s(%u,%u) 
(%s) and %s(%u,%u) (%s) are not equal",
+                       fromtype->type->sqlname,
+                       fromtype->digits,
+                       fromtype->scale,
+                       fromtype->type->base.name,
+                       t->type->sqlname,
+                       t->digits,
+                       t->scale,
+                       t->type->base.name
                );
                return res;
        }
@@ -5309,8 +5300,11 @@ rel2bin_update(backend *be, sql_rel *rel
                }
        }
 #endif
-       if (!sql_update_triggers(be, t, tids, updates, 0))
+       if (!sql_update_triggers(be, t, tids, updates, 0)) {
+               if (sql->cascade_action)
+                       sql->cascade_action = NULL;
                return sql_error(sql, 02, SQLSTATE(27000) "UPDATE: triggers 
failed for table '%s'", t->base.name);
+       }
 
 /* apply the update */
        for (m = rel->exps->h; m; m = m->next) {
@@ -5321,8 +5315,11 @@ rel2bin_update(backend *be, sql_rel *rel
                        append(l, stmt_update_col(be,  c, tids, 
updates[c->colnr]));
        }
 
-       if (cascade_updates(be, t, tids, updates))
+       if (cascade_updates(be, t, tids, updates)) {
+               if (sql->cascade_action)
+                       sql->cascade_action = NULL;
                return sql_error(sql, 02, SQLSTATE(42000) "UPDATE: cascade 
failed for table '%s'", t->base.name);
+       }
 
 /* after */
 #if 0
@@ -5333,8 +5330,11 @@ rel2bin_update(backend *be, sql_rel *rel
                }
        }
 #endif
-       if (!sql_update_triggers(be, t, tids, updates, 1))
+       if (!sql_update_triggers(be, t, tids, updates, 1)) {
+               if (sql->cascade_action)
+                       sql->cascade_action = NULL;
                return sql_error(sql, 02, SQLSTATE(27000) "UPDATE: triggers 
failed for table '%s'", t->base.name);
+       }
 
        if (ddl) {
                list_prepend(l, ddl);
diff --git a/sql/test/SQLancer/Tests/sqlancer14.test 
b/sql/test/SQLancer/Tests/sqlancer14.test
--- a/sql/test/SQLancer/Tests/sqlancer14.test
+++ b/sql/test/SQLancer/Tests/sqlancer14.test
@@ -81,3 +81,15 @@ DROP TABLE t0
 
 statement ok
 DROP TABLE t1
+
+statement ok
+CREATE TABLE "sys"."t2" ("c0" UUID, CONSTRAINT "t2_c0_pkey" PRIMARY KEY 
("c0"),CONSTRAINT "t2_c0_fkey" FOREIGN KEY ("c0") REFERENCES "sys"."t2" ("c0"))
+
+statement ok
+update t2 set c0 = uuid 'ABeCdDdd-80Cd-D26A-2a77-aAabE4C2caeA' where least(9 
in (2, 3), case false when true then false end)
+
+statement ok
+update t2 set c0 = uuid 'ABeCdDdd-80Cd-D26A-2a77-aAabE4C2caeA' where least(9 
in (2, 3), case false when true then false end)
+
+statement ok
+DROP TABLE t2
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to