Changeset: b6deb3a36ebb for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=b6deb3a36ebb
Added Files:
sql/test/BugTracker-2015/Tests/schema-trigger.Bug-3710.stable.err
sql/test/BugTracker-2015/Tests/schema-trigger.Bug-3710.stable.out
Modified Files:
sql/backends/monet5/UDF/pyapi/pyapi.c
sql/backends/monet5/rel_bin.c
sql/backends/monet5/sql.c
sql/backends/monet5/sql_cat.c
sql/rel.txt
sql/server/rel_psm.c
sql/server/rel_select.c
sql/server/sql_mvc.c
sql/server/sql_mvc.h
sql/server/sql_parser.y
sql/test/BugTracker-2012/Tests/conditions_when_for_triggers_do_not_work.Bug-2073.sql
sql/test/BugTracker-2012/Tests/conditions_when_for_triggers_do_not_work.Bug-2073.stable.out
sql/test/BugTracker-2015/Tests/schema-trigger.Bug-3710.sql
sql/test/Triggers/trigger_action.sql
Branch: oltp
Log Message:
merged with default
diffs (truncated from 830 to 300 lines):
diff --git a/sql/backends/monet5/UDF/pyapi/pyapi.c
b/sql/backends/monet5/UDF/pyapi/pyapi.c
--- a/sql/backends/monet5/UDF/pyapi/pyapi.c
+++ b/sql/backends/monet5/UDF/pyapi/pyapi.c
@@ -509,7 +509,7 @@ str PyAPIeval(Client cntxt, MalBlkPtr mb
if (GDKinitmmap(query_ptr->mmapid + 0, size,
(void**) &result_ptr, NULL, &msg) != GDK_SUCCEED) {
_connection_cleanup_result(output);
GDKchangesemval(query_sem, 1, 1, &msg);
- msg = createException(MAL, "pyapi.eval",
"nothin");
+ msg = createException(MAL, "pyapi.eval", "eval
failed");
GDKfree(result_columns);
goto wrapup;
}
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
@@ -1333,6 +1333,15 @@ rel2bin_args(backend *be, sql_rel *rel,
return args;
}
+typedef struct trigger_input {
+ sql_table *t;
+ stmt *tids;
+ stmt **updates;
+ int type; /* insert 1, update 2, delete 3 */
+ const char *on;
+ const char *nn;
+} trigger_input;
+
static stmt *
rel2bin_table(backend *be, sql_rel *rel, list *refs)
{
@@ -1342,7 +1351,28 @@ rel2bin_table(backend *be, sql_rel *rel,
node *en, *n;
sql_exp *op = rel->r;
- if (op) {
+ if (rel->flag == 2) {
+ trigger_input *ti = rel->l;
+ l = sa_list(sql->sa);
+
+ for(n = ti->t->columns.set->h; n; n = n->next) {
+ sql_column *c = n->data;
+
+ if (ti->type == 2) { /* updates */
+ stmt *s = stmt_col(be, c, ti->tids);
+ append(l, stmt_alias(be, s, ti->on,
c->base.name));
+ }
+ if (ti->updates[c->colnr]) {
+ append(l, stmt_alias(be, ti->updates[c->colnr],
ti->nn, c->base.name));
+ } else {
+ stmt *s = stmt_col(be, c, ti->tids);
+ append(l, stmt_alias(be, s, ti->nn,
c->base.name));
+ assert(ti->type != 1);
+ }
+ }
+ sub = stmt_list(be, l);
+ return sub;
+ } else if (op) {
int i;
sql_subfunc *f = op->f;
stmt *psub = NULL;
@@ -3065,15 +3095,33 @@ sql_insert_key(backend *be, list *insert
}
static void
-sql_stack_add_inserted( mvc *sql, const char *name, sql_table *t)
+sql_stack_add_inserted( mvc *sql, const char *name, sql_table *t, stmt
**updates)
{
- sql_rel *r = rel_basetable(sql, t, name );
-
+ /* Put single relation of updates and old values on to the stack */
+ sql_rel *r = NULL;
+ node *n;
+ list *exps = sa_list(sql->sa);
+ trigger_input *ti = SA_NEW(sql->sa, trigger_input);
+
+ ti->t = t;
+ ti->tids = NULL;
+ ti->updates = updates;
+ ti->type = 1;
+ ti->nn = name;
+ for (n = t->columns.set->h; n; n = n->next) {
+ sql_column *c = n->data;
+ sql_exp *ne = exp_column(sql->sa, name, c->base.name, &c->type,
CARD_MULTI, c->null, 0);
+
+ append(exps, ne);
+ }
+ r = rel_table_func(sql->sa, NULL, NULL, exps, 2);
+ r->l = ti;
+
stack_push_rel_view(sql, name, r);
}
static int
-sql_insert_triggers(backend *be, sql_table *t, list *l, int time)
+sql_insert_triggers(backend *be, sql_table *t, stmt **updates, int time)
{
mvc *sql = be->mvc;
node *n;
@@ -3093,12 +3141,11 @@ sql_insert_triggers(backend *be, sql_tab
/* add name for the 'inserted' to the stack */
if (!n) n = "new";
- sql_stack_add_inserted(sql, n, t);
+ sql_stack_add_inserted(sql, n, t, updates);
s = sql_parse(be, sql->sa, trigger->statement,
m_instantiate);
if (!s)
return 0;
- list_append(l, s);
}
stack_pop_frame(sql);
}
@@ -3135,13 +3182,32 @@ sql_insert_check_null(backend *be, sql_t
}
}
+static stmt **
+table_update_stmts(mvc *sql, sql_table *t, int *Len)
+{
+ stmt **updates;
+ int i, len = list_length(t->columns.set);
+ node *m;
+
+ *Len = len;
+ updates = SA_NEW_ARRAY(sql->sa, stmt *, len);
+ for (m = t->columns.set->h, i = 0; m; m = m->next, i++) {
+ sql_column *c = m->data;
+
+ /* update the column number, for correct array access */
+ c->colnr = i;
+ updates[i] = NULL;
+ }
+ return updates;
+}
+
static stmt *
rel2bin_insert(backend *be, sql_rel *rel, list *refs)
{
mvc *sql = be->mvc;
list *l;
- stmt *inserts = NULL, *insert = NULL, *s, *ddl = NULL, *pin = NULL;
- int idx_ins = 0, constraint = 1;
+ stmt *inserts = NULL, *insert = NULL, *s, *ddl = NULL, *pin = NULL,
**updates;
+ int idx_ins = 0, constraint = 1, len = 0;
node *n, *m;
sql_rel *tr = rel->l, *prel = rel->r;
sql_table *t = NULL;
@@ -3177,13 +3243,17 @@ rel2bin_insert(backend *be, sql_rel *rel
l = sa_list(sql->sa);
+ updates = table_update_stmts(sql, t, &len);
+ for (n = t->columns.set->h, m = inserts->op4.lval->h; n && m; n =
n->next, m = m->next) {
+ sql_column *c = n->data;
+
+ updates[c->colnr] = m->data;
+ }
+
/* before */
- if (!sql_insert_triggers(be, t, inserts->op4.lval, 0))
+ if (!sql_insert_triggers(be, t, updates, 0))
return sql_error(sql, 02, "INSERT INTO: triggers failed for
table '%s'", t->base.name);
- /* skip over column inserts */
- for (n = t->columns.set->h, m = inserts->op4.lval->h; n && m; n =
n->next, m = m->next)
- ;
if (t->idxs.set)
for (n = t->idxs.set->h; n && m; n = n->next, m = m->next) {
stmt *is = m->data;
@@ -3215,7 +3285,7 @@ rel2bin_insert(backend *be, sql_rel *rel
if (!insert)
return NULL;
- if (!sql_insert_triggers(be, t, l, 1))
+ if (!sql_insert_triggers(be, t, updates, 1))
return sql_error(sql, 02, "INSERT INTO: triggers failed for
table '%s'", t->base.name);
if (ddl) {
list_prepend(l, ddl);
@@ -3259,25 +3329,6 @@ first_updated_col(stmt **updates, int cn
return -1;
}
-static stmt **
-table_update_stmts(mvc *sql, sql_table *t, int *Len)
-{
- stmt **updates;
- int i, len = list_length(t->columns.set);
- node *m;
-
- *Len = len;
- updates = SA_NEW_ARRAY(sql->sa, stmt *, len);
- for (m = t->columns.set->h, i = 0; m; m = m->next, i++) {
- sql_column *c = m->data;
-
- /* update the column number, for correct array access */
- c->colnr = i;
- updates[i] = NULL;
- }
- return updates;
-}
-
static stmt *
update_check_ukey(backend *be, stmt **updates, sql_key *k, stmt *tids, stmt
*idx_updates, int updcol)
{
@@ -3959,17 +4010,47 @@ update_idxs_and_check_keys(backend *be,
}
static void
-sql_stack_add_updated(mvc *sql, const char *on, const char *nn, sql_table *t)
+sql_stack_add_updated(mvc *sql, const char *on, const char *nn, sql_table *t,
stmt *tids, stmt **updates)
{
- sql_rel *or = rel_basetable(sql, t, on );
- sql_rel *nr = rel_basetable(sql, t, nn );
+ /* Put single relation of updates and old values on to the stack */
+ sql_rel *r = NULL;
+ node *n;
+ list *exps = sa_list(sql->sa);
+ trigger_input *ti = SA_NEW(sql->sa, trigger_input);
+
+ ti->t = t;
+ ti->tids = tids;
+ ti->updates = updates;
+ ti->type = 2;
+ ti->on = on;
+ ti->nn = nn;
+ for (n = t->columns.set->h; n; n = n->next) {
+ sql_column *c = n->data;
+
+ if (updates[c->colnr]) {
+ sql_exp *oe = exp_column(sql->sa, on, c->base.name,
&c->type, CARD_MULTI, c->null, 0);
+ sql_exp *ne = exp_column(sql->sa, nn, c->base.name,
&c->type, CARD_MULTI, c->null, 0);
+
+ append(exps, oe);
+ append(exps, ne);
+ } else { /* later select correct updated rows only ? */
+ sql_exp *oe = exp_column(sql->sa, on, c->base.name,
&c->type, CARD_MULTI, c->null, 0);
+ sql_exp *ne = exp_column(sql->sa, nn, c->base.name,
&c->type, CARD_MULTI, c->null, 0);
+
+ append(exps, oe);
+ append(exps, ne);
+ }
+ }
+ r = rel_table_func(sql->sa, NULL, NULL, exps, 2);
+ r->l = ti;
- stack_push_rel_view(sql, on, or);
- stack_push_rel_view(sql, nn, nr);
+ /* put single table into the stack with 2 names, needed for the psm
code */
+ stack_push_rel_view(sql, on, r);
+ stack_push_rel_view(sql, nn, rel_dup(r));
}
static int
-sql_update_triggers(backend *be, sql_table *t, list *l, int time )
+sql_update_triggers(backend *be, sql_table *t, stmt *tids, stmt **updates, int
time )
{
mvc *sql = be->mvc;
node *n;
@@ -3992,11 +4073,10 @@ sql_update_triggers(backend *be, sql_tab
if (!n) n = "new";
if (!o) o = "old";
- sql_stack_add_updated(sql, o, n, t);
+ sql_stack_add_updated(sql, o, n, t, tids, updates);
s = sql_parse(be, sql->sa, trigger->statement,
m_instantiate);
if (!s)
return 0;
- list_append(l, s);
}
stack_pop_frame(sql);
}
@@ -4052,7 +4132,7 @@ sql_update(backend *be, sql_table *t, st
}
/* before */
- if (!sql_update_triggers(be, t, l, 0))
+ if (!sql_update_triggers(be, t, rows, updates, 0))
return sql_error(sql, 02, "UPDATE: triggers failed for table
'%s'", t->base.name);
/* apply updates */
@@ -4066,7 +4146,7 @@ sql_update(backend *be, sql_table *t, st
return sql_error(sql, 02, "UPDATE: cascade failed for table
'%s'", t->base.name);
/* after */
- if (!sql_update_triggers(be, t, l, 1))
+ if (!sql_update_triggers(be, t, rows, updates, 1))
return sql_error(sql, 02, "UPDATE: triggers failed for table
'%s'", t->base.name);
/* cascade ?? */
@@ -4149,7 +4229,7 @@ rel2bin_update(backend *be, sql_rel *rel
}
/* before */
- if (!sql_update_triggers(be, t, l, 0))
+ if (!sql_update_triggers(be, t, tids, updates, 0))
return sql_error(sql, 02, "UPDATE: triggers failed for table
'%s'", t->base.name);
/* apply the update */
@@ -4165,7 +4245,7 @@ rel2bin_update(backend *be, sql_rel *rel
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list