Changeset: 0711f13f3fc4 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/0711f13f3fc4
Modified Files:
sql/backends/monet5/rel_bin.c
sql/include/sql_relation.h
sql/server/rel_optimize_others.c
sql/server/rel_updates.c
sql/test/2024/Tests/returning.test
Branch: returning
Log Message:
nest modify relations instead using attr list
diffs (truncated from 331 to 300 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
@@ -5352,7 +5352,7 @@ rel2bin_insert(backend *be, sql_rel *rel
if (!insert)
return NULL;
- if (rel->attr) {
+ if (rel->returning) {
list* il = sa_list(sql->sa);
sql_rel* inner = rel->l;
assert(inner->op == op_basetable);
@@ -5362,21 +5362,7 @@ rel2bin_insert(backend *be, sql_rel *rel
stmt* s = stmt_rename(be, ce, ins);// label
each insert statement with the corresponding col exp label
append(il, s);
}
- stmt* inserts2 = stmt_list(be, il);
-
- list* rl = sa_list(sql->sa);
- for (n = rel->attr->h; n; n = n->next) {
- sql_exp *exp = n->data;
- stmt *s = exp_bin(be, exp, inserts2, NULL, NULL, NULL,
NULL, NULL, 0, 0, 0);
- if (!exp_name(exp))
- exp_label(sql->sa, exp, ++sql->label);
- if (exp_name(exp)) {
- s = stmt_rename(be, exp, s);
- s->label = exp->alias.label;
- }
- append(rl, s);
- }
- returning = stmt_list(be, rl);
+ returning = stmt_list(be, il);
sql->type = Q_TABLE;
}
@@ -6427,7 +6413,7 @@ rel2bin_update(backend *be, sql_rel *rel
}
stmt* returning = NULL;
- if (rel->attr) {
+ if (rel->returning) {
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;
@@ -6435,25 +6421,6 @@ rel2bin_update(backend *be, sql_rel *rel
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;
}
@@ -6703,7 +6670,7 @@ static stmt *
rel2bin_delete(backend *be, sql_rel *rel, list *refs)
{
mvc *sql = be->mvc;
- stmt *stdelete = NULL, *tids = NULL, *s = NULL;
+ stmt *stdelete = NULL, *tids = NULL, *returning = NULL;
sql_rel *tr = rel->l;
sql_table *t = NULL;
@@ -6721,19 +6688,13 @@ rel2bin_delete(backend *be, sql_rel *rel
tids = rows->op4.lval->h->data; /* TODO this should be the
candidate list instead */
}
- if (rel->attr) {
- sql_rel* inner = rel->l;
- if (rel_is_ref(inner)) {
- s = refs_find_rel(refs, inner);
- if (s)
- s->cand = tids;
- }
-
- sql_rel* ret = rel_project(sql->sa, inner, rel->attr);
- s = subrel_bin(be, ret, refs);
- s = subrel_project(be, s, refs, rel);
+ if (rel->returning) {
+ returning = subrel_bin(be, rel->l, refs);
+ returning->cand = tids;
+ returning = subrel_project(be, returning, refs, rel->l);
sql->type = Q_TABLE;
}
+
stdelete = sql_delete(be, t, tids);
if (sql->cascade_action)
sql->cascade_action = NULL;
@@ -6742,7 +6703,7 @@ rel2bin_delete(backend *be, sql_rel *rel
if (rel->r && !rel_predicates(be, rel->r))
return NULL;
- return s?s:stdelete;
+ return returning?returning:stdelete;
}
struct tablelist {
@@ -7580,17 +7541,17 @@ subrel_bin(backend *be, sql_rel *rel, li
break;
case op_insert:
s = rel2bin_insert(be, rel, refs);
- if (!rel->attr && sql->type == Q_TABLE)
+ if (!(rel->returning) && sql->type == Q_TABLE)
sql->type = Q_UPDATE;
break;
case op_update:
s = rel2bin_update(be, rel, refs);
- if (!rel->attr && sql->type == Q_TABLE)
+ if (!(rel->returning) && sql->type == Q_TABLE)
sql->type = Q_UPDATE;
break;
case op_delete:
s = rel2bin_delete(be, rel, refs);
- if (!rel->attr && sql->type == Q_TABLE)
+ if (!(rel->returning) && sql->type == Q_TABLE)
sql->type = Q_UPDATE;
break;
case op_truncate:
diff --git a/sql/include/sql_relation.h b/sql/include/sql_relation.h
--- a/sql/include/sql_relation.h
+++ b/sql/include/sql_relation.h
@@ -312,7 +312,8 @@ typedef struct relation {
processed:1, /* fully processed or still in the process of building
*/
outer:1, /* used as outer (ungrouped) */
grouped:1, /* groupby processed all the group by exps */
- single:1;
+ single:1,
+ returning:1; /*update|delete|insert relations return modified records*/
/*
* Used by rewriters at rel_unnest, rel_optimizer and rel_distribute so
a relation is not modified twice
* The list is kept at rel_optimizer_private.h Please update it
accordingly
diff --git a/sql/server/rel_optimize_others.c b/sql/server/rel_optimize_others.c
--- a/sql/server/rel_optimize_others.c
+++ b/sql/server/rel_optimize_others.c
@@ -532,6 +532,7 @@ rel_mark_used(mvc *sql, sql_rel *rel, in
case op_update:
case op_delete:
if (proj && rel->r) {
+ rel_used(rel);
sql_rel *r = rel->r;
if (!list_empty(r->exps)) {
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
@@ -695,7 +695,6 @@ insert_into(sql_query *query, dlist *qna
if (opt_returning) {
mvc *sql = query->sql;
- sql->type = Q_TABLE;
list *pexps = sa_list(sql->sa);
sql_rel* inner = ins->l;
for (dnode *n = opt_returning->h; n; n = n->next) {
@@ -704,7 +703,14 @@ insert_into(sql_query *query, dlist *qna
return NULL;
pexps = append(pexps, ce);
}
- ins->attr = is_groupby(inner->op) ? inner->exps : pexps;
+ ins->returning = 1;
+
+ if (is_groupby(inner->op)) {
+ inner->l = ins;
+ ins = rel_project(sql->sa, inner, pexps);
+ }
+ else
+ ins = rel_project(sql->sa, ins, pexps);
}
return ins;
@@ -1250,6 +1256,7 @@ update_table(sql_query *query, dlist *qn
res = rel_crossproduct(sql->sa, res, tables, op_join);
set_single(res);
}
+ query_push_outer(query, res, sql_where);
if (opt_where) {
if (!(r = rel_logical_exp(query, res, opt_where,
sql_where)))
return NULL;
@@ -1262,8 +1269,9 @@ update_table(sql_query *query, dlist *qn
r = res;
}
r = update_generate_assignments(query, t, r, bt,
assignmentlist, "UPDATE");
+ query_pop_outer(query);
if (opt_returning) {
- sql->type = Q_TABLE;
+ r->returning = 1;
list *pexps = sa_list(sql->sa);
sql_rel* inner = r->l;
for (dnode *n = opt_returning->h; n; n = n->next) {
@@ -1272,7 +1280,12 @@ update_table(sql_query *query, dlist *qn
return NULL;
pexps = append(pexps, ce);
}
- r->attr = is_groupby(inner->op) ? inner->exps : pexps;
+ if (is_groupby(inner->op)) {
+ inner->l = r;
+ r = rel_project(sql->sa, inner, pexps);
+ }
+ else
+ r = rel_project(sql->sa, r, pexps);
}
return r;
@@ -1332,8 +1345,11 @@ delete_table(sql_query *query, dlist *qn
get_string_global_var(sql, "current_user"), tname);
}
rel_base_use_tid(sql, r);
+
+ query_push_outer(query, r, sql_where);
if (!(r = rel_logical_exp(query, r, opt_where,
sql_where)))
return NULL;
+ query_pop_outer(query);
e = exp_column(sql->sa, rel_name(r), TID,
sql_bind_localtype("oid"), CARD_MULTI, 0, 1, 1);
e->nid = rel_base_nid(bt, NULL);
e->alias.label = e->nid;
@@ -1343,16 +1359,21 @@ delete_table(sql_query *query, dlist *qn
r = rel_delete(sql->sa, r, NULL);
}
if (opt_returning) {
- sql->type = Q_TABLE;
+ r->returning = 1;
list *pexps = sa_list(sql->sa);
sql_rel* inner = r->l;
for (dnode *n = opt_returning->h; n; n = n->next) {
- sql_exp *ce = rel_column_exp(query, &inner,
n->data.sym, sql_sel | sql_no_subquery | sql_update_set);
+ sql_exp *ce = rel_column_exp(query, &inner,
n->data.sym, sql_sel | sql_no_subquery);
if (ce == NULL)
return NULL;
pexps = append(pexps, ce);
}
- r->attr = is_groupby(inner->op) ? inner->exps : pexps;
+ if (is_groupby(inner->op)) {
+ inner->l = r;
+ r = rel_project(sql->sa, inner, pexps);
+ }
+ else
+ r = rel_project(sql->sa, r, pexps);
}
return r;
}
diff --git a/sql/test/2024/Tests/returning.test
b/sql/test/2024/Tests/returning.test
--- a/sql/test/2024/Tests/returning.test
+++ b/sql/test/2024/Tests/returning.test
@@ -57,6 +57,31 @@ update foo set i = -i returning sum(j)
----
-60
+query II nosort
+update foo set i = -i where i >0 returning sum(j), count(j)
+----
+-60
+3
+
+statement error 42000!SELECT: cannot use non GROUP BY column 'i' in query
results without an aggregate function
+update foo set i = -i returning sum(j), i
+
+statement error 42000!SELECT: cannot use non GROUP BY column 'foo.i' in query
results without an aggregate function
+update foo set i = -i returning i, sum(j)
+
+statement error 42000!SELECT: cannot use non GROUP BY column 'i' in query
results without an aggregate function
+delete from foo where i > 0 returning sum(j), i
+
+statement error 42000!SELECT: cannot use non GROUP BY column 'foo.i' in query
results without an aggregate function
+delete from foo where i > 0 returning i, sum(j)
+
+statement error 42000!SELECT: cannot use non GROUP BY column 'i' in query
results without an aggregate function
+insert into foo select * from foo returning sum(j), i
+
+statement error 42000!SELECT: cannot use non GROUP BY column 'foo.i' in query
results without an aggregate function
+insert into foo select * from foo returning i, sum(j)
+
+
statement error 42000!SELECT: identifier 'k' unknown
update foo set i = -i returning k
@@ -77,6 +102,23 @@ 4
9
statement ok
+insert into foo values (1, 10), (2, 20), (3, 30);
+
+query I nosort
+delete from foo returning sum(j)
+----
+60
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]