Changeset: cb92947332fa for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/cb92947332fa Modified Files: sql/backends/monet5/rel_bin.c sql/server/rel_updates.c sql/server/sql_parser.y Branch: returning Log Message:
UPDATE ... RETURNING ... diffs (146 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 @@ -6398,6 +6398,37 @@ rel2bin_update(backend *be, sql_rel *rel append(l, stmt_update_col(be, c, tids, updates[c->colnr])); } + stmt* returning = NULL; + if (rel->attr) { + sql_rel* b = rel->l; + int refcnt = b->ref.refcnt; // HACK: forces recalculation of base columns since they are assumed to be updated + b->ref.refcnt = 1; + returning = subrel_bin(be, b, refs); + b->ref.refcnt = refcnt; + returning->cand = tids; + returning = subrel_project(be, returning, refs, b); + list *pl = sa_list(sql->sa); + if (pl == NULL) + return NULL; + stmt *psub = stmt_list(be, pl); + if (psub == NULL) + return NULL; + for (node *en = rel->attr->h; en; en = en->next) { + sql_exp *exp = en->data; + stmt *s = exp_bin(be, exp, returning, NULL, NULL, NULL, NULL, NULL, 0, 0, 0); + + if (!exp_name(exp)) + exp_label(sql->sa, exp, ++sql->label); + s = stmt_rename(be, exp, s); + s->label = exp->alias.label; + list_append(pl, s); + } + stmt_set_nrcols(psub); + returning = psub; + returning = subrel_project(be, returning, refs, NULL); + sql->type = Q_TABLE; + } + if (cascade_updates(be, t, tids, updates)) { if (sql->cascade_action) sql->cascade_action = NULL; @@ -6426,7 +6457,7 @@ rel2bin_update(backend *be, sql_rel *rel sql->cascade_action = NULL; if (rel->r && !rel_predicates(be, rel->r)) return NULL; - return cnt; + return returning?returning:cnt; } static int @@ -6654,6 +6685,11 @@ rel2bin_delete(backend *be, sql_rel *rel assert(0/*ddl statement*/); if (rel->r) { /* first construct the deletes relation */ + if (rel->attr) { + sql_rel* sel = ((sql_rel*) rel->r)->l; + assert(is_select(sel->op)); + (void) rel_dup (sel); // required to prevent recalculating select in rel2bin_delete + } stmt *rows = subrel_bin(be, rel->r, refs); rows = subrel_project(be, rows, refs, rel->r); if (!rows) @@ -6663,7 +6699,8 @@ rel2bin_delete(backend *be, sql_rel *rel } if (rel->attr) { - sql_rel* ret = rel_project(sql->sa, ((sql_rel*) rel->r)->l, rel->attr); + sql_rel* sel = ((sql_rel*) rel->r)->l; + sql_rel* ret = rel_project(sql->sa, sel, rel->attr); s = subrel_bin(be, ret, refs); s = subrel_project(be, s, refs, rel); sql->type = Q_TABLE; @@ -7519,7 +7556,7 @@ subrel_bin(backend *be, sql_rel *rel, li break; case op_update: s = rel2bin_update(be, rel, refs); - if (sql->type == Q_TABLE) + if (!rel->attr && sql->type == Q_TABLE) sql->type = Q_UPDATE; break; case op_delete: 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 @@ -1194,7 +1194,7 @@ update_generate_assignments(sql_query *q } static sql_rel * -update_table(sql_query *query, dlist *qname, str alias, dlist *assignmentlist, symbol *opt_from, symbol *opt_where) +update_table(sql_query *query, dlist *qname, str alias, dlist *assignmentlist, symbol *opt_from, symbol *opt_where, dlist *opt_returning) { mvc *sql = query->sql; char *sname = qname_schema(qname); @@ -1245,7 +1245,21 @@ update_table(sql_query *query, dlist *qn } else { /* update all */ r = res; } - return update_generate_assignments(query, t, r, bt, assignmentlist, "UPDATE"); + r = update_generate_assignments(query, t, r, bt, assignmentlist, "UPDATE"); + if (opt_returning) { + sql->type = Q_TABLE; + list *pexps = sa_list(sql->sa); + for (dnode *n = opt_returning->h; n; n = n->next) { + sql_rel* inner = r->l; + sql_exp *ce = rel_column_exp(query, &inner, n->data.sym, sql_sel | sql_no_subquery | sql_update_set); + if (ce == NULL) + return sql_error(sql, 02, SQLSTATE(42000) "aggregate functions and subqueries are not allowed in RETURNING clause"); + pexps = append(pexps, ce); + } + r->attr = pexps; + } + + return r; } return NULL; } @@ -2204,8 +2218,8 @@ rel_updates(sql_query *query, symbol *s) dlist *l = s->data.lval; ret = update_table(query, l->h->data.lval, l->h->next->data.sval, l->h->next->next->data.lval, - l->h->next->next->next->data.sym, l->h->next->next->next->next->data.sym); - sql->type = Q_UPDATE; + l->h->next->next->next->data.sym, l->h->next->next->next->next->data.sym, l->h->next->next->next->next->next->data.lval); + if (ret && !ret->attr) sql->type = Q_UPDATE; } break; case SQL_DELETE: 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 @@ -3230,13 +3230,14 @@ truncate_stmt: ; update_stmt: - UPDATE qname opt_alias_name SET assignment_commalist opt_from_clause opt_where_clause + UPDATE qname opt_alias_name SET assignment_commalist opt_from_clause opt_where_clause opt_returning_clause { dlist *l = L(); append_list(l, $2); append_string(l, $3); append_list(l, $5); append_symbol(l, $6); append_symbol(l, $7); + append_list(l, $8); $$ = _symbol_create_list( SQL_UPDATE, l ); } ; _______________________________________________ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org