Changeset: 5033a4523f7b for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/5033a4523f7b
Modified Files:
sql/backends/monet5/rel_bin.c
sql/test/2024/Tests/check.test
Branch: check
Log Message:
implement check constraint for partial row update
diffs (99 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
@@ -5917,17 +5917,42 @@ sql_update_triggers(backend *be, sql_tab
}
static void
-sql_update_check(backend *be, sql_key * key, sql_rel *rupdates, list *refs)
+sql_update_check(backend *be, sql_key * key, sql_rel *updates, list *refs)
{
- /* TODO: this won't work for general table check constraints involving
updates to a strict subset of check columns*/
mvc *sql = be->mvc;
+ int pos = 0;
+ sql_rel* rel = rel_read(sql, sa_strdup(sql->sa, key->check), &pos,
sa_list(sql->sa));
+ sql_rel* base = rel->l;
+ assert(strcmp(((sql_exp*) updates->exps->h->data)->alias.name, TID) ==
0);
+ list_append(base->exps, exp_copy(sql, updates->exps->h->data));
+
+ bool need_join = 0;
+ list* pexps = sa_list(sql->sa);
+ sql_exp* tid_exp = exp_copy(sql, updates->exps->h->data);
+ unsigned label = ++sql->label;
+ exp_setrelname(sql->sa, tid_exp, label);
+ list_append(pexps, tid_exp);
+ for (node* m = base->exps->h; m; m = m->next) {
+ if (exps_find_exp( updates->exps, m->data) == NULL) {
+ pexps = list_append(pexps, exp_copy(sql, m->data));
+ need_join = 1;
+ }
+ }
+
+ if (need_join) {
+ base = rel_project(sql->sa, base, pexps);
+ sql_rel* join = rel_crossproduct(sql->sa, base, updates,
op_join);
+ sql_exp* join_cond = exp_compare(sql->sa, exp_ref(sql,
base->exps->h->data), exp_ref(sql, updates->exps->h->data), cmp_equal);
+ join->exps = sa_list(sql->sa);
+ join->exps = list_append(join->exps, join_cond);
+ rel->l = join;
+ }
+ else {
+ rel->l = updates;
+ }
+
sql_subfunc *cnt = sql_bind_func(sql, "sys", "count",
sql_bind_localtype("void"), NULL, F_AGGR, true, true);
sql_subtype *bt = sql_bind_localtype("bit");
-
-
- int pos = 0;
- sql_rel* rel = rel_read(sql, sa_strdup(sql->sa, key->check), &pos,
sa_list(sql->sa));
- rel->l = rupdates;
stmt* s = subrel_bin(be, rel, refs);
s = stmt_uselect(be, column(be, s), stmt_atom(be,
atom_zero_value(sql->sa, bt)), cmp_equal, NULL, 0, 1);
s = stmt_aggr(be, s, NULL, NULL, cnt, 1, 0, 1);
diff --git a/sql/test/2024/Tests/check.test b/sql/test/2024/Tests/check.test
--- a/sql/test/2024/Tests/check.test
+++ b/sql/test/2024/Tests/check.test
@@ -1,20 +1,35 @@
statement ok
-create table bar (i int, j int CHECK (j > 0));
+create table foo (i int CHECK (i > 0), j int CHECK (j > 0))
statement ok
-insert into bar values (1,10), (2, 20), (3, 30);
+insert into foo values (1,10), (2, 20), (3, 30)
statement error
-update bar set j = -30 where i = 3;
+update foo set j = -30 where i = 3
+
+statement error
+update foo set j = -j
statement error
-update bar set j = -j;
+insert into foo values (4, -40)
+
+statement ok
+insert into foo select * from foo
statement error
-insert into bar values (4, -40);
+insert into foo select 4, -40
statement ok
-insert into bar select * from bar
+create table bar (i int, j int, constraint check_i_j CHECK (i < j))
statement error
-insert into bar select 4, -40;
+insert into bar values (30, 20)
+
+statement ok
+insert into bar values (10,20), (20, 30), (30, 40)
+
+statement error
+update bar set i = 50 where i = 30
+
+statement error
+update bar set i = 50, j = 40 where i = 30
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]