Changeset: ea0b21aeaf5b for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/ea0b21aeaf5b
Modified Files:
        sql/server/rel_updates.c
Branch: Jan2022
Log Message:

when inserting complex rows, convert into a union of rows.


diffs (66 lines):

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
@@ -322,6 +322,7 @@ rel_inserts(mvc *sql, sql_table *t, sql_
        sql_exp **inserts = insert_exp_array(sql, t, &len);
        list *exps = NULL;
        node *n, *m;
+       bool has_rel = false, all_values = true;
 
        if (r->exps) {
                if (!copy) {
@@ -333,6 +334,8 @@ rel_inserts(mvc *sql, sql_table *t, sql_
                                        return sql_error(sql, 02, 
SQLSTATE(42000) "%s: column '%s' specified more than once", action, 
c->base.name);
                                if (!(inserts[c->colnr] = exp_check_type(sql, 
&c->type, r, e, type_equal)))
                                        return NULL;
+                               has_rel = (has_rel || exp_has_rel(e));
+                               all_values &= is_values(e);
                        }
                } else {
                        for (m = collist->h; m; m = m->next) {
@@ -344,6 +347,8 @@ rel_inserts(mvc *sql, sql_table *t, sql_
                                        if (inserts[c->colnr])
                                                return sql_error(sql, 02, 
SQLSTATE(42000) "%s: column '%s' specified more than once", action, 
c->base.name);
                                        inserts[c->colnr] = exp_ref(sql, e);
+                                       has_rel = has_rel || exp_has_rel(e);
+                                       all_values &= is_values(e);
                                }
                        }
                }
@@ -384,10 +389,32 @@ rel_inserts(mvc *sql, sql_table *t, sql_
                        assert(inserts[c->colnr]);
                }
        }
-       /* now rewrite project exps in proper table order */
-       exps = new_exp_list(sql->sa);
-       for (i = 0; i<len; i++)
-               list_append(exps, inserts[i]);
+       /* rewrite into unions */
+       if (has_rel && rowcount && all_values) {
+               sql_rel *c = NULL;
+               for (size_t j = 0; j < rowcount; j++) {
+                       sql_rel *p = rel_project(sql->sa, NULL, 
sa_list(sql->sa));
+                       for (m = ol_first_node(t->columns); m; m = m->next) {
+                               sql_column *c = m->data;
+                               sql_exp *e = inserts[c->colnr];
+                               assert(is_values(e));
+                               list *vals = e->f;
+                               append(p->exps, list_fetch(vals, j));
+                       }
+                       if (c) {
+                               c = rel_setop(sql->sa, c, p, op_union);
+                               rel_setop_set_exps(sql, c, rel_projections(sql, 
c->l, NULL, 1, 1), false);
+                       } else
+                               c = p;
+               }
+               r->l = c;
+               exps = rel_projections(sql, r->l, NULL, 1, 1);
+       } else {
+               /* now rewrite project exps in proper table order */
+               exps = new_exp_list(sql->sa);
+               for (i = 0; i<len; i++)
+                       list_append(exps, inserts[i]);
+       }
        return exps;
 }
 
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to