Changeset: 321c6716c5f7 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/321c6716c5f7
Modified Files:
        monetdb5/optimizer/opt_emptybind.c
        monetdb5/optimizer/opt_support.c
        sql/backends/monet5/rel_bin.c
        sql/backends/monet5/sql_gencode.c
        sql/backends/monet5/sql_gencode.h
        sql/backends/monet5/sql_statement.c
        sql/backends/monet5/sql_statement.h
        sql/server/rel_basetable.c
        sql/server/rel_prop.c
        sql/server/rel_prop.h
        sql/server/rel_select.c
        sql/test/BugTracker-2024/Tests/7439-exps-cards-crash.test
Branch: nested
Log Message:

handle unnset by passing the column via NESTED property
handle left join with unnest better


diffs (truncated from 482 to 300 lines):

diff --git a/monetdb5/optimizer/opt_emptybind.c 
b/monetdb5/optimizer/opt_emptybind.c
--- a/monetdb5/optimizer/opt_emptybind.c
+++ b/monetdb5/optimizer/opt_emptybind.c
@@ -230,7 +230,7 @@ OPTemptybindImplementation(Client cntxt,
                        continue;
                }
                if (getModuleId(p) == algebraRef && getFunctionId(p) == 
projectionRef) {
-                       if (empty[getArg(p, 1)] || empty[getArg(p, 2)]) {
+                       if (empty[getArg(p, 1)] /*|| empty[getArg(p, 2)]*/) {
                                actions++;
                                emptyresult(0);
                        }
diff --git a/monetdb5/optimizer/opt_support.c b/monetdb5/optimizer/opt_support.c
--- a/monetdb5/optimizer/opt_support.c
+++ b/monetdb5/optimizer/opt_support.c
@@ -546,6 +546,8 @@ isDelta(InstrPtr p)
 int
 isFragmentGroup2(InstrPtr p)
 {
+       if (getModuleId(p) == batRef && getFunctionId(p) == appendRef)
+               return TRUE;
        if (getModuleId(p) == batRef && getFunctionId(p) == replaceRef)
                return TRUE;
        return (getModuleId(p) == algebraRef && (getFunctionId(p) == 
projectionRef))
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
@@ -301,10 +301,13 @@ column(backend *be, stmt *val)
 }
 
 static stmt *
-create_const_column(backend *be, stmt *val)
-{
+create_const_column(backend *be, stmt *val, stmt *d1)
+{
+       (void)d1;
        if (val->nrcols == 0)
                val = const_column(be, val);
+       if (val->nested)
+               return stmt_nest(be, val, NULL, &create_const_column);
        return stmt_append(be, stmt_temp(be, tail_type(val)), val);
 }
 
@@ -2160,8 +2163,8 @@ exp_bin(backend *be, sql_exp *e, stmt *l
                        }
                }
                s = stmt_aggr(be, as, grp, ext, a, 1, need_no_nil(e) /* ignore 
nil*/, !zero_if_empty(e));
-               if (find_prop(e->p, PROP_COUNT)) /* propagate count == 0 ipv 
NULL in outer joins */
-                       s->flag |= OUTER_ZERO;
+               //if (find_prop(e->p, PROP_COUNT)) /* propagate count == 0 ipv 
NULL in outer joins */
+                       //s->flag |= OUTER_ZERO;
        }       break;
        case e_column: {
                if (right) /* check relation names */
@@ -3697,6 +3700,14 @@ get_equi_joins_first(mvc *sql, list *exp
 }
 
 static stmt *
+stmt_append_nil(backend *be, stmt *s, stmt *rows)
+{
+       if (s->nested)
+               return stmt_nest(be, s, rows, &stmt_append_nil);
+       return stmt_append(be, s, stmt_const(be, rows, 
(s->flag&OUTER_ZERO)?stmt_atom_lng(be, 0):stmt_atom(be, 
atom_general(be->mvc->sa, tail_type(s), NULL, 0))));
+}
+
+static stmt *
 rel2bin_join(backend *be, sql_rel *rel, list *refs)
 {
        mvc *sql = be->mvc;
@@ -3886,6 +3897,18 @@ rel2bin_join(backend *be, sql_rel *rel, 
                list_append(l2, ld);
        }
 
+       int op = rel->op;
+       if (0 && (op == op_right || op == op_full || op == op_left)) {
+               if (op == op_left || op == op_full) {
+                       jl = stmt_append(be, jl, ld);
+                       jr = stmt_append(be, jr, stmt_const(be, ld, 
stmt_atom(be, atom_general(sql->sa, tail_type(ld), NULL, 0))));
+               }
+               if (op == op_right || op == op_full) {
+                       jl = stmt_append(be, jl, stmt_const(be, rd, 
stmt_atom(be, atom_general(sql->sa, tail_type(rd), NULL, 0))));
+                       jr = stmt_append(be, jr, rd);
+               }
+               op = op_join;
+       }
        for (n = left->op4.lval->h; n; n = n->next) {
                stmt *c = n->data;
                sql_alias *rnme = table_name(sql->sa, c);
@@ -3893,13 +3916,14 @@ rel2bin_join(backend *be, sql_rel *rel, 
                stmt *s = stmt_project(be, jl, column(be, c));
 
                /* as append isn't save, we append to a new copy */
-               if (rel->op == op_left || rel->op == op_full || rel->op == 
op_right)
-                       s = create_const_column(be, s);
-               if (rel->op == op_left || rel->op == op_full)
+               if (op == op_left || op == op_full || op == op_right)
+                       s = create_const_column(be, s, NULL);
+               if (op == op_left || op == op_full)
                        s = stmt_append(be, s, stmt_project(be, ld, c));
-               if (rel->op == op_right || rel->op == op_full)
-                       s = stmt_append(be, s, stmt_const(be, rd, 
(c->flag&OUTER_ZERO)?stmt_atom_lng(be, 0):stmt_atom(be, atom_general(sql->sa, 
tail_type(c), NULL, 0))));
-
+               if (op == op_right || op == op_full) {
+                       s->flag = c->flag; /* push OUTER_ZERO */
+                       s = stmt_append_nil(be, s, rd);
+               }
                s = stmt_alias(be, s, c->label, rnme, nme);
                list_append(l, s);
        }
@@ -3910,11 +3934,13 @@ rel2bin_join(backend *be, sql_rel *rel, 
                stmt *s = stmt_project(be, jr, column(be, c));
 
                /* as append isn't save, we append to a new copy */
-               if (rel->op == op_left || rel->op == op_full || rel->op == 
op_right)
-                       s = create_const_column(be, s);
-               if (rel->op == op_left || rel->op == op_full)
-                       s = stmt_append(be, s, stmt_const(be, ld, 
(c->flag&OUTER_ZERO)?stmt_atom_lng(be, 0):stmt_atom(be, atom_general(sql->sa, 
tail_type(c), NULL, 0))));
-               if (rel->op == op_right || rel->op == op_full)
+               if (op == op_left || op == op_full || op == op_right)
+                       s = create_const_column(be, s, NULL);
+               if (op == op_left || op == op_full) {
+                       s->flag = c->flag; /* push OUTER_ZERO */
+                       s = stmt_append_nil(be, s, ld);
+               }
+               if (op == op_right || op == op_full)
                        s = stmt_append(be, s, stmt_project(be, rd, c));
 
                s = stmt_alias(be, s, c->label, rnme, nme);
@@ -4801,7 +4827,7 @@ rel2bin_union(backend *be, sql_rel *rel,
                const char *nme = column_name(sql->sa, c1);
                stmt *s;
 
-               s = stmt_append(be, create_const_column(be, c1), c2);
+               s = stmt_append(be, create_const_column(be, c1, NULL), c2);
                if (s == NULL)
                        return NULL;
                s = stmt_alias(be, s, c1->label, rnme, nme);
diff --git a/sql/backends/monet5/sql_gencode.c 
b/sql/backends/monet5/sql_gencode.c
--- a/sql/backends/monet5/sql_gencode.c
+++ b/sql/backends/monet5/sql_gencode.c
@@ -1754,8 +1754,8 @@ static void
     char *node_prefix = last?tg[TG_END]:tg[TG_BIF];
     switch (s->type) {
         case st_list:
-            mnstr_printf(GDKstdout, "%s%sst_list (X_%d)\n",
-                         node_prefix, tg[TG_DOT], s->nr);
+            mnstr_printf(GDKstdout, "%s%s%sst_list (X_%d)\n",
+                         node_prefix, tg[TG_DOT], s->nested?"* ":"", s->nr);
             for (node *n = s->op4.lval->h; n; n = n->next)
                 _stmt_print_list_(n->data, depth+1, lvls, (n == 
s->op4.lval->t));
             break;
@@ -1764,9 +1764,21 @@ static void
                          node_prefix, tg[TG_DOT], s->nr);
             break;
         case st_alias:
-            mnstr_printf(GDKstdout, "%s%sst_alias (X_%d)\n",
-                         node_prefix, tg[TG_DOT], s->nr);
+            mnstr_printf(GDKstdout, "%s%s%sst_alias (X_%d) (%d, %s, %s)\n",
+                         node_prefix, tg[TG_DOT], s->nested?"* ":"", s->nr, 
s->label, s->tname?s->tname->name:"", s->cname);
+            _stmt_print_list_(s->op1, depth+1, lvls, true);
+            break;
+        case st_append:
+            mnstr_printf(GDKstdout, "%s%sst_append (X_%d) label: %d\n",
+                         node_prefix, tg[TG_DOT], s->nr, s->label);
             _stmt_print_list_(s->op1, depth+1, lvls, true);
+            _stmt_print_list_(s->op2, depth+1, lvls, true);
+            break;
+        case st_join:
+            mnstr_printf(GDKstdout, "%s%sst_%s (X_%d) label: %d\n",
+                         node_prefix, tg[TG_DOT], s->flag == 
cmp_project?"project":"join", s->nr, s->label);
+            _stmt_print_list_(s->op1, depth+1, lvls, true);
+            _stmt_print_list_(s->op2, depth+1, lvls, true);
             break;
         default:
             mnstr_printf(GDKstdout, "%s%sUNKNOWN stmt type=%d (X_%d)\n",
@@ -1793,6 +1805,15 @@ void
 }
 
 void
+_stmt_print(stmt *sl)
+{
+       if (sl->type == st_list)
+               return _stmt_print_list(sl);
+    size_t lvls = 1;
+    _stmt_print_list_(sl, 0, &lvls, true);
+}
+
+void
 rel_print(mvc *sql, sql_rel *rel, int depth)
 {
        list *refs = sa_list(sql->sa);
diff --git a/sql/backends/monet5/sql_gencode.h 
b/sql/backends/monet5/sql_gencode.h
--- a/sql/backends/monet5/sql_gencode.h
+++ b/sql/backends/monet5/sql_gencode.h
@@ -37,6 +37,7 @@ extern void _rel_print(mvc *sql, sql_rel
 extern void _exp_print(mvc *sql, sql_exp *e);
 extern void _exps_print(mvc *sql, list *l);
 extern void _stmt_print_list(stmt *sl);
+extern void _stmt_print(stmt *sl);
 
 extern int constantAtom(backend *be, MalBlkPtr mb, atom *a);
 extern InstrPtr table_func_create_result(MalBlkPtr mb, InstrPtr q, sql_func 
*f, list *restypes);
diff --git a/sql/backends/monet5/sql_statement.c 
b/sql/backends/monet5/sql_statement.c
--- a/sql/backends/monet5/sql_statement.c
+++ b/sql/backends/monet5/sql_statement.c
@@ -2618,6 +2618,116 @@ unnest_stmt(stmt *o)
        return o->op4.lval;
 }
 
+static stmt *
+stmt_nest2(backend *be, stmt *op1, stmt *op2, fstmt call)
+{
+       list *ops1 = unnest_stmt(op1);
+       list *ops2 = unnest_stmt(op2);
+       list *nops = sa_list(be->mvc->sa);
+       sql_subtype *st = tail_type(op2);
+       bool propagate = !st->multiset && st->type->composite;
+       for(node *n = ops1->h, *m = ops2->h; n && m; n = n->next, m = m->next) {
+               stmt *i1 = n->data;
+               stmt *i2 = m->data;
+               stmt *i = i2;
+               if (propagate || (st->multiset && n == ops1->t)) {
+                       stmt *oi = i;
+                       i = call(be, i1, oi);
+                       i->nested = oi->nested;
+                       i->subtype = *tail_type(oi);
+                       i->tname = oi->tname;
+                       i->cname = oi->cname;
+                       i->label = oi->label;
+               }
+               append(nops, i);
+       }
+       stmt *s = stmt_list(be, nops);
+       if (s == NULL)
+               return NULL;
+       s->nested = true;
+       s->subtype = *st;
+       s->tname = op2->tname;
+       s->cname = op2->cname;
+       s->label = op2->label;
+       if (op2->type == st_alias)
+               return stmt_alias(be, s, op2->label, op2->tname, op2->cname);
+       return s;
+}
+
+static stmt *
+stmt_nest1(backend *be, stmt *op1, stmt *op2, fstmt call)
+{
+       assert(op1->nested);
+       list *ops = unnest_stmt(op1);
+       list *nops = sa_list(be->mvc->sa);
+       sql_subtype *st = tail_type(op1);
+       bool propagate = !st->multiset && st->type->composite;
+       for(node *n = ops->h; n; n = n->next) {
+               stmt *i = n->data;
+               if (propagate || (st->multiset && n == ops->t)) {
+                       stmt *oi = i;
+                       i = call(be, oi, op2);
+                       i->nested = oi->nested;
+                       i->subtype = *tail_type(oi);
+                       i->tname = oi->tname;
+                       i->cname = oi->cname;
+                       i->label = oi->label;
+               }
+               append(nops, i);
+       }
+       stmt *s = stmt_list(be, nops);
+       if (s == NULL)
+               return NULL;
+       s->nested = true;
+       s->subtype = *st;
+       s->tname = op1->tname;
+       s->cname = op1->cname;
+       s->label = op1->label;
+       if (op1->type == st_alias)
+               return stmt_alias(be, s, op1->label, op1->tname, op1->cname);
+       return s;
+}
+
+stmt *
+stmt_nest(backend *be, stmt *op1, stmt *op2, fstmt call)
+{
+       if (!op2)
+               op2 = op1;
+       if (op1->nested && op2->nested)
+               return stmt_nest2(be, op1, op2, call);
+       if (op1->nested && !op2->nested)
+               return stmt_nest1(be, op1, op2, call);
+       assert(op2->nested);
+       list *ops = unnest_stmt(op2);
+       list *nops = sa_list(be->mvc->sa);
+       sql_subtype *st = tail_type(op2);
+       bool propagate = !st->multiset && st->type->composite;
+       for(node *n = ops->h; n; n = n->next) {
+               stmt *i = n->data;
+               if (propagate || (st->multiset && n == ops->t)) {
+                       stmt *oi = i;
+                       i = call(be, op1, oi);
+                       i->nested = oi->nested;
+                       i->subtype = *tail_type(oi);
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to