Changeset: 84f723edadae for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=84f723edadae Modified Files: sql/server/rel_select.c sql/server/rel_select.h sql/server/rel_updates.c sql/server/sql_parser.y Branch: default Log Message:
allow advanced update statements, ie including from part within the update statement. diffs (129 lines): diff --git a/sql/server/rel_select.c b/sql/server/rel_select.c --- a/sql/server/rel_select.c +++ b/sql/server/rel_select.c @@ -721,13 +721,12 @@ rel_values( mvc *sql, symbol *tableref) return r; } -static sql_rel * +sql_rel * table_ref(mvc *sql, sql_rel *rel, symbol *tableref) { char *tname = NULL; sql_table *t = NULL; - (void)rel; if (tableref->token == SQL_NAME) { dlist *name = tableref->data.lval->h->data.lval; sql_rel *temp_table = NULL; diff --git a/sql/server/rel_select.h b/sql/server/rel_select.h --- a/sql/server/rel_select.h +++ b/sql/server/rel_select.h @@ -33,5 +33,6 @@ extern sql_exp *rel_binop_(mvc *sql, sql extern sql_exp *rel_nop_(mvc *sql, sql_exp *l, sql_exp *r, sql_exp *r2, sql_exp *r3, sql_schema *s, char *fname, int card); extern sql_rel *rel_with_query(mvc *sql, symbol *q); +extern sql_rel *table_ref(mvc *sql, sql_rel *rel, symbol *tableref); #endif /*_REL_SELECT_H_*/ diff --git a/sql/server/rel_updates.c b/sql/server/rel_updates.c --- a/sql/server/rel_updates.c +++ b/sql/server/rel_updates.c @@ -837,13 +837,12 @@ update_check_column(mvc *sql, sql_table } static sql_rel * -update_table(mvc *sql, dlist *qname, dlist *assignmentlist, symbol *opt_where) +update_table(mvc *sql, dlist *qname, dlist *assignmentlist, symbol *opt_from, symbol *opt_where) { char *sname = qname_schema(qname); char *tname = qname_table(qname); sql_schema *s = NULL; sql_table *t = NULL; - sql_rel *bt = NULL; if (sname && !(s=mvc_bind_schema(sql,sname))) { (void) sql_error(sql, 02, "3F000!UPDATE: no such schema '%s'", sname); @@ -866,7 +865,9 @@ update_table(mvc *sql, dlist *qname, dli list *exps; dnode *n; const char *rname = NULL; + sql_rel *res = NULL, *bt = rel_basetable(sql, t, t->base.name); + res = bt; #if 0 dlist *selection = dlist_create(sql->sa); dlist *from_list = dlist_create(sql->sa); @@ -912,6 +913,19 @@ update_table(mvc *sql, dlist *qname, dli } #endif + if (opt_from) { + dlist *fl = opt_from->data.lval; + dnode *n = NULL; + sql_rel *fnd = NULL; + + for (n = fl->h; n && res; n = n->next) { + fnd = table_ref(sql, NULL, n->data.sym); + if (fnd) + res = rel_crossproduct(sql->sa, res, fnd, op_join); + } + if (!res) + return NULL; + } if (opt_where) { int status = sql->session->status; @@ -920,21 +934,18 @@ update_table(mvc *sql, dlist *qname, dli r = rel_logical_exp(sql, NULL, opt_where, sql_where); if (r) { /* simple predicate which is not using the to be updated table. We add a select all */ - - sql_rel *l = bt = rel_basetable(sql, t, t->base.name ); - r = rel_crossproduct(sql->sa, l, r, op_semi); + r = rel_crossproduct(sql->sa, res, r, op_semi); } else { sql->errstr[0] = 0; sql->session->status = status; - bt = r = rel_basetable(sql, t, t->base.name ); - r = rel_logical_exp(sql, r, opt_where, sql_where); - if (r && is_join(r->op)) + r = rel_logical_exp(sql, res, opt_where, sql_where); + if (!opt_from && r && is_join(r->op)) r->op = op_semi; } if (!r) return NULL; } else { /* update all */ - bt = r = rel_basetable(sql, t, t->base.name ); + r = res; } /* first create the project */ @@ -1634,7 +1645,7 @@ rel_updates(mvc *sql, symbol *s) { dlist *l = s->data.lval; - ret = update_table(sql, l->h->data.lval, l->h->next->data.lval, l->h->next->next->data.sym); + ret = update_table(sql, l->h->data.lval, l->h->next->data.lval, l->h->next->next->data.sym, l->h->next->next->next->data.sym); sql->type = Q_UPDATE; } break; diff --git a/sql/server/sql_parser.y b/sql/server/sql_parser.y --- a/sql/server/sql_parser.y +++ b/sql/server/sql_parser.y @@ -2654,12 +2654,13 @@ delete_stmt: ; update_stmt: - UPDATE qname SET assignment_commalist opt_where_clause + UPDATE qname SET assignment_commalist opt_from_clause opt_where_clause { dlist *l = L(); append_list(l, $2); append_list(l, $4); append_symbol(l, $5); + append_symbol(l, $6); $$ = _symbol_create_list( SQL_UPDATE, l ); } ; _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list