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
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list