Update of /cvsroot/monetdb/sql/src/server
In directory sc8-pr-cvs16:/tmp/cvs-serv9707
Modified Files:
sql_updates.mx
Log Message:
changes to implement UPDATE/DELETE cascade.
The implementation of UPDATE/DELETE cascade operations is covered by the tests:
sql/src/test/Update_Delete_Action/
Note: Only some of these tests should be green after this checkin. There are
still some issues to resolve.
Index: sql_updates.mx
===================================================================
RCS file: /cvsroot/monetdb/sql/src/server/sql_updates.mx,v
retrieving revision 1.112
retrieving revision 1.113
diff -u -d -r1.112 -r1.113
--- sql_updates.mx 1 Apr 2007 23:35:41 -0000 1.112
+++ sql_updates.mx 17 Apr 2007 10:33:54 -0000 1.113
@@ -737,106 +737,67 @@
}
static stmt*
-sql_update_cascade_Fkeys(mvc *sql, sql_schema *schema, stmt **updates, list
*l, sql_key *fk)
+sql_update_cascade_Fkeys(mvc *sql, sql_schema *schema, sql_key *k, int updcol,
stmt **updates, list *l)
{
- sql_table *t = NULL;
+ int len = 0, i;
+ node *m, *o;
+ sql_idx *ri = ((sql_fkey*)k)->rkey->k.idx;
+ stmt *ts = stmt_basetable(ri->t, ri->t->base.name), *fts,
**new_updates, *s;
+ stmt *rows;
+ sql_table *t = mvc_bind_table(sql, schema, k->t->base.name);
- t = mvc_bind_table(sql, schema, fk->t->base.name);
-
- return sql_update(sql, schema, t, updates, l);
-}
+ fts = stmt_basetable(k->idx->t, k->idx->t->base.name);
+ rows = stmt_idxbat(k->idx, RDONLY);
+ rows = stmt_semijoin(stmt_reverse(rows), stmt_dup(updates[updcol]));
+
+ len = list_length(t->columns.set);
+ new_updates = NEW_ARRAY(stmt *, len);
-static stmt*
-sql_update_cascade_Fkeys_set(mvc *sql, sql_schema *schema, sql_key *fk, int
set_type)
-{
- sql_table *t = NULL;
- int len = 0, i = 0;
- stmt *s = NULL;
- node *n = NULL;
- stmt **updates;
- scope *scp = NULL;
- tvar *tv = NULL;
- list * l = NULL;
-
- l = create_stmt_list();
- len = list_length(fk->columns);
- updates = NEW_ARRAY(stmt *, len);
-
for (i = 0; i < len; i++)
- updates[i] = NULL;
+ new_updates[i] = NULL;
+ for (m = k->idx->columns->h, o = ri->columns->h; m && o; m = m->next, o
= o->next) {
+ sql_kc *fc = m->data;
+ sql_kc *c = o->data;
+ stmt *upd;
- t = mvc_bind_table(sql, schema, fk->t->base.name);
- scp = scope_open(scp);
- tv = scope_add_table_columns(sql, scp, t, t->base.name, RDONLY);
+ if (updates[c->c->colnr]) {
+ upd = stmt_dup(updates[fc->c->colnr]->op2.stval);
+ } else
+ upd = stmt_atom(atom_general(&fc->c->type, NULL, 0));
- for (n = fk->columns->h, i = 0; n; n = n->next, i++) {
- stmt *v = NULL;
- sql_column *c = (sql_column *) n->data;
-
- if ((set_type == ACT_SET_DEFAULT) && c->def) {
- stmt *sq;
- char buf[BUFSIZ];
-
- snprintf(buf, BUFSIZ, "select %s;", c->def);
- sq = scope_sqlparse(sql, NULL, buf, sql->mode);
-
- if (!sq || sq->type != st_list ||
list_length(sq->op1.lval) != 1) {
- cond_stmt_destroy(sq);
- cleanup_stmts(updates, 1);
+ if (!upd || (upd = check_types(sql, &fc->c->type, upd,
type_equal)) == NULL) {
+ stmt_destroy(rows);
+ list_destroy(l);
+ cleanup_stmts(new_updates, len);
return NULL;
- }
-
- v = stmt_dup(sq->op1.lval->h->data);
- v = check_types(sql, &c->type, v, type_equal);
-
- stmt_destroy(sq);
-
- }
- else
- v = stmt_atom(atom_general(&c->type, NULL, 0));
-
- if (!v || (v = check_types(sql, &c->type, v, type_equal)) ==
NULL) {
- stmt_destroy(v);
- list_destroy(l);
- cleanup_stmts(updates, 1);
- return NULL;
- }
-
- if (v->nrcols <= 0) {
- v = stmt_const(stmt_reverse(v ? first_subset(s) :
stmt_bat(c, stmt_dup(tv->s), RDONLY)), v);
- } else {
- /* s is a table result ie new oid, original oid
- * v is a result based on subset s, new oid, val
- * So a join is needed to get original oid, val
- */
- v = stmt_join(stmt_reverse(first_subset(s)), v,
cmp_equal);
}
+ if (upd->nrcols <= 0)
+ upd = stmt_const(stmt_reverse(rows ? first_subset(rows)
: stmt_bat(fc->c, stmt_dup(fts), RDONLY)), upd);
+
/* new bats need values replaced */
- if (c->base.flag == TR_NEW)
- updates[c->colnr] = stmt_replace(stmt_bat(c,
stmt_dup(tv->s), INS), stmt_dup(v));
- else
- updates[c->colnr] = stmt_insert(stmt_bat(c,
stmt_dup(tv->s), UPD), stmt_dup(v));
-
- list_append(l, stmt_dup(updates[c->colnr]));
+ if (c->c->base.flag == TR_NEW)
+ new_updates[c->c->colnr] = stmt_replace(stmt_bat(fc->c,
stmt_dup(fts), INS), stmt_dup(upd));
+ else
+ updates[c->c->colnr] = stmt_insert(stmt_bat(fc->c,
stmt_dup(fts), UPD), stmt_dup(upd));
+ list_append(l, stmt_dup(new_updates[fc->c->colnr]));
}
- list_append(l, stmt_affected_rows(stmt_aggr(first_subset(s), NULL,
sql_bind_aggr(sql->session->schema, "count", NULL), 1)));
- stmt_destroy(s);
-
- if ((s = sql_update(sql, schema, t, updates, l)) == NULL) {
- list_destroy(l);
- cleanup_stmts(updates, len);
- return NULL;
+ stmt_destroy(ts);
+ stmt_destroy(fts);
+
+ if ((s = sql_update(sql, schema, t, new_updates, l)) == NULL) {
+ list_destroy(l);
+ cleanup_stmts(new_updates, len);
+ return NULL;
}
-
- scp = scope_close(scp);
- cleanup_stmts(updates, len);
+ cleanup_stmts(new_updates, len);
return s;
}
+
static void
sql_update_ukey(mvc *sql, sql_schema *schema, stmt **updates, sql_key *k, int
updcol, list *l)
{
@@ -856,15 +817,11 @@
case ACT_NO_ACTION:
break;
case ACT_SET_NULL:
- s = sql_update_cascade_Fkeys_set(sql,
schema, fk, ACT_SET_NULL);
- list_prepend(l, s);
break;
case ACT_SET_DEFAULT:
- s = sql_update_cascade_Fkeys_set(sql,
schema, fk, ACT_SET_DEFAULT);
- list_prepend(l, s);
break;
case ACT_CASCADE:
- s = sql_update_cascade_Fkeys(sql,
schema, updates, l, fk);
+ s = sql_update_cascade_Fkeys(sql,
schema, fk, updcol, updates, l);
list_prepend(l, s);
break;
default: /*RESTRICT*/
@@ -983,7 +940,6 @@
int res = 1;
node *n;
int updcol;
- list * keys = NULL;
if (!t->idxs.set)
return res;
@@ -1004,25 +960,20 @@
} else if (i->type == join_idx) {
is = join_idx_update(i, updates, updcol);
}
- if (i->key && !list_find_id(sql->cascade_action,
i->key->base.id)){
- int id = i->key->base.id;
-
- if ( sql->cascade_action) {
- list_append(sql->cascade_action, &id);
- }
- else {
- keys = list_create((fdestroy) NULL);
- keys = list_append(keys, &id);
- sql->cascade_action = keys;
+ if (i->key) {
+ if (!sql->cascade_action) {
+ sql->cascade_action = list_create((fdestroy)
NULL);
+ } else {
+ if (sql->cascade_action &&
!list_find_id(sql->cascade_action, i->key->base.id))
+ continue;
+ else {
+ int id = i->key->base.id;
+ list_append(sql->cascade_action, &id);
+ }
}
sql_update_key(sql, schema, updates, i->key, is,
updcol, l);
- if (keys) {
- sql->cascade_action = NULL;
- list_destroy(keys);
- }
- keys = NULL;
}
if (is)
list_append(l, stmt_insert(stmt_idxbat(i, UPD), is));
@@ -1666,9 +1617,17 @@
if ((s = sql_update(sql, schema, t, updates, l)) == NULL) {
list_destroy(l);
+ if (sql->cascade_action) {
+ list_destroy(sql->cascade_action);
+ sql->cascade_action = NULL;
+ }
cleanup_stmts(updates, len);
return NULL;
}
+ if (sql->cascade_action) {
+ list_destroy(sql->cascade_action);
+ sql->cascade_action = NULL;
+ }
scp = scope_close(scp);
cleanup_stmts(updates, len);
return s;
@@ -1805,12 +1764,8 @@
case ACT_NO_ACTION:
break;
case ACT_SET_NULL:
- s = sql_update_cascade_Fkeys_set(sql,
schema, fk, ACT_SET_NULL);
- list_prepend(l, s);
break;
case ACT_SET_DEFAULT:
- s = sql_update_cascade_Fkeys_set(sql,
schema, fk, ACT_SET_NULL);
- list_prepend(l, s);
break;
case ACT_CASCADE:
s = sql_delete_cascade_Fkeys(sql,
schema, s, fk, k);
@@ -1833,7 +1788,6 @@
{
int res = 1;
node *n;
- list *keys = NULL;
if (!t->keys.set)
return res;
@@ -1841,26 +1795,19 @@
for (n = t->keys.set->h; n; n = n->next) {
sql_key *k = n->data;
- if ((k->type == pkey || k->type == ukey) &&
!list_find_id(sql->cascade_action, k->base.id)) {
+ if ((k->type == pkey || k->type == ukey) &&
(!sql->cascade_action || !list_find_id(sql->cascade_action, k->base.id))) {
int id = k->base.id;
if ( sql->cascade_action) {
list_append(sql->cascade_action, &id);
}
else {
- keys = list_create((fdestroy) NULL);
- keys = list_append(keys, &id);
- sql->cascade_action = keys;
+ sql->cascade_action = list_create((fdestroy)
NULL);
+ list_append(sql->cascade_action, &id);
}
sql_delete_ukey(sql, schema, deletes, k, l);
- if (keys) {
- sql->cascade_action = NULL;
- list_destroy(keys);
- }
- keys = NULL;
-
}
}
return res;
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Monetdb-sql-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/monetdb-sql-checkins