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 -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to