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]