Changeset: da2d87168785 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/da2d87168785
Modified Files:
sql/backends/monet5/rel_bin.c
sql/backends/monet5/sql.c
sql/server/rel_rel.c
sql/server/rel_rel.h
sql/server/rel_select.c
sql/server/rel_statistics.c
sql/server/rel_unnest.c
sql/test/BugTracker-2024/Tests/7473-SQLunionfunc.test
sql/test/SQLancer/Tests/sqlancer11.test
Branch: unnest2
Log Message:
handle table returning functions with correlation, cleanup old code
diffs (truncated from 2346 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
@@ -2603,7 +2603,6 @@ rel2bin_table(backend *be, sql_rel *rel,
sql_subfunc *f = op->f;
stmt *psub = NULL;
list *ops = NULL;
- stmt *ids = NULL;
if (rel->l) { /* first construct the sub relation */
sql_rel *l = rel->l;
@@ -2621,22 +2620,31 @@ rel2bin_table(backend *be, sql_rel *rel,
}
assert(f);
- if (f->func->res && list_length(f->func->res) + 1 ==
list_length(rel->exps) && !f->func->varres) {
+ list *outers = NULL;
+ if (f->func->res && rel->nr_outers && list_length(f->func->res)
+ rel->nr_outers == list_length(rel->exps) && !f->func->varres) {
/* add inputs in correct order ie loop through args of
f and pass column */
list *exps = op->l;
+ outers = sa_list(be->mvc->sa);
ops = sa_list(be->mvc->sa);
if (exps) {
- for (node *en = exps->h; en; en = en->next) {
+ node *en = exps->h;
+ for (int c = 0; en && c < rel->nr_outers; en =
en->next, c++) {
sql_exp *e = en->data;
/* find column */
stmt *s = exp_bin(be, e, sub, NULL,
NULL, NULL, NULL, NULL, 0, 0, 0);
if (!s)
return NULL;
- if (en->next)
- append(ops, s);
- else /* last added exp is the ids (todo
use name base lookup !!) */
- ids = s;
+ append(outers, s);
+ }
+ for (; en; en = en->next) {
+ sql_exp *e = en->data;
+
+ /* find column */
+ stmt *s = exp_bin(be, e, sub, NULL,
NULL, NULL, NULL, NULL, 0, 0, 0);
+ if (!s)
+ return NULL;
+ append(ops, s);
}
}
} else {
@@ -2663,18 +2671,21 @@ rel2bin_table(backend *be, sql_rel *rel,
int i = 0;
/* correlated table returning function */
- if (list_length(f->func->res) + 1 ==
list_length(rel->exps)) {
+ if (rel->nr_outers &&
(list_length(f->func->res) + rel->nr_outers) == list_length(rel->exps)) {
/* use a simple nested loop solution
for this case, ie
- * output a table of (input) row-ids,
the output of the table producing function
+ * output a table of (input) row, the
output of the table producing function
*/
/* make sure the input for
sql.unionfunc are bats */
- if (ids)
- ids = column(be, ids);
+ if (outers)
+ for(node *n = outers->h; n; n =
n->next)
+ n->data = column(be,
n->data);
if (ops)
for (node *en = ops->h; en; en
= en->next)
en->data = column(be,
(stmt *) en->data);
- int narg = 3 + list_length(rel->exps);
+ int narg = 2 + list_length(rel->exps);
+ if (outers)
+ narg += list_length(outers);
if (ops)
narg += list_length(ops);
InstrPtr q = newStmtArgs(be->mb,
sqlRef, "unionfunc", narg);
@@ -2702,14 +2713,18 @@ rel2bin_table(backend *be, sql_rel *rel,
str fcn = backend_function_imp(be,
f->func);
q = pushStr(be->mb, q, mod);
q = pushStr(be->mb, q, fcn);
+ q = pushInt(be->mb, q, rel->nr_outers);
psub = stmt_direct_func(be, q);
if (psub == NULL) {
freeInstruction(be->mb, q);
return NULL;
}
- if (ids) /* push input rowids column */
- q = pushArgument(be->mb, q,
ids->nr);
+ if (outers) /* push input row column */
+ for (node *n = outers->h; n; n
= n->next) {
+ stmt *outer = n->data;
+ q =
pushArgument(be->mb, q, outer->nr);
+ }
/* add inputs in correct order ie loop
through args of f and pass column */
if (ops) {
@@ -2722,9 +2737,8 @@ rel2bin_table(backend *be, sql_rel *rel,
pushInstruction(be->mb, q);
/* name output of dependent columns,
output of function is handled the same as without correlation */
- int len =
list_length(rel->exps)-list_length(f->func->res);
- assert(len== 1);
- for (i=0, m=rel->exps->h; m && i<len; m
= m->next, i++) {
+ //int len =
list_length(rel->exps)-list_length(f->func->res);
+ for (i=0, m=rel->exps->h; m; m =
m->next, i++) {
sql_exp *exp = m->data;
stmt *s = stmt_rs_column(be,
psub, i, exp_subtype(exp));
diff --git a/sql/backends/monet5/sql.c b/sql/backends/monet5/sql.c
--- a/sql/backends/monet5/sql.c
+++ b/sql/backends/monet5/sql.c
@@ -4981,9 +4981,9 @@ bailout:
return msg;
}
-/* input id, row-input-values
- * for each id call function(with row-input-values) return table
- * return for each id the table, ie id (*length of table) and table results
+/*
+ * for each input row call function(with row-input-values) return table
+ * return for each input row the table, ie input-row (*length of table) and
table results
*/
str
SQLunionfunc(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
@@ -4997,21 +4997,22 @@ SQLunionfunc(Client cntxt, MalBlkPtr mb,
return createException(MAL, "sql.unionfunc", SQLSTATE(HY013)
MAL_MALLOC_FAIL);
mod = *getArgReference_str(stk, pci, arg++);
fcn = *getArgReference_str(stk, pci, arg++);
+ int nr_outers = *getArgReference_int(stk, pci, arg++);
npci = newStmtArgs(nmb, mod, fcn, pci->argc);
if (npci == NULL) {
freeMalBlk(nmb);
return createException(MAL, "sql.unionfunc", SQLSTATE(HY013)
MAL_MALLOC_FAIL);
}
- for (int i = 1; i < pci->retc; i++) {
+ for (int i = nr_outers; i < pci->retc; i++) {
int type = getArgType(mb, pci, i);
- if (i==1)
+ if (i==nr_outers)
getArg(npci, 0) = newTmpVariable(nmb, type);
else
npci = pushReturn(nmb, npci, newTmpVariable(nmb, type));
}
- for (int i = pci->retc+2+1; i < pci->argc; i++) {
+ for (int i = pci->retc+3+nr_outers; i < pci->argc; i++) {
int type = getBatType(getArgType(mb, pci, i));
npci = pushNil(nmb, npci, type);
@@ -5027,7 +5028,7 @@ SQLunionfunc(Client cntxt, MalBlkPtr mb,
BAT **res = NULL, **input = NULL;
BATiter *bi = NULL;
BUN cnt = 0;
- int nrinput = pci->argc - 2 - pci->retc;
+ int nrinput = pci->argc - 3 - pci->retc;
MalStkPtr env = NULL;
InstrPtr q = NULL;
@@ -5039,8 +5040,8 @@ SQLunionfunc(Client cntxt, MalBlkPtr mb,
ret = createException(MAL, "sql.unionfunc",
SQLSTATE(HY013) MAL_MALLOC_FAIL);
goto finalize;
}
- assert(pci->retc + 2 + nrinput == pci->argc);
- for (int i = 0, j = pci->retc+2; j < pci->argc; i++, j++) {
+ assert(pci->retc + 3 + nrinput == pci->argc);
+ for (int i = 0, j = pci->retc+3; j < pci->argc; i++, j++) {
bat *b = getArgReference_bat(stk, pci, j);
if (!(input[i] = BATdescriptor(*b))) {
ret = createException(MAL, "sql.unionfunc",
SQLSTATE(HY005) "Cannot access column descriptor");
@@ -5100,8 +5101,8 @@ SQLunionfunc(Client cntxt, MalBlkPtr mb,
if (!nstk) { /* needed for result */
ret = createException(MAL, "sql.unionfunc",
SQLSTATE(HY013) MAL_MALLOC_FAIL);
} else {
- /* copy (input) arguments onto destination
stack, skipping rowid col */
- for (i = 1, ii = q->retc; ii < q->argc && !ret;
ii++, i++) {
+ /* copy (input) arguments onto destination
stack, skipping input row value columns */
+ for (i = nr_outers, ii = q->retc; ii < q->argc
&& !ret; ii++, i++) {
ValPtr lhs = &nstk->stk[q->argv[ii]];
ptr rhs = (ptr)BUNtail(&bi[i], cur);
@@ -5116,21 +5117,24 @@ SQLunionfunc(Client cntxt, MalBlkPtr mb,
ret = runMALsequence(cntxt,
nmb, start, nmb->stop, nstk, env /* copy result in nstk first instruction*/, q);
if (!ret) {
- /* insert into result */
- if (!(fres =
BBPquickdesc(omb?env->stk[q->argv[0]].val.bval:nstk->stk[q->argv[0]].val.bval)))
{
- ret =
createException(MAL, "sql.unionfunc", SQLSTATE(HY005) "Cannot access column
descriptor");
- } else {
- BAT *p =
BATconstant(fres->hseqbase, res[0]->ttype, (ptr)BUNtail(&bi[0], cur),
BATcount(fres), TRANSIENT);
-
- if (p) {
- if
(BATappend(res[0], p, NULL, FALSE) != GDK_SUCCEED)
+ /* insert into result, input
column values */
+ for (int i = 0; i<nr_outers;
i++) {
+ if (!(fres =
BBPquickdesc(omb?env->stk[q->argv[0]].val.bval:nstk->stk[q->argv[0]].val.bval)))
{
+ ret =
createException(MAL, "sql.unionfunc", SQLSTATE(HY005) "Cannot access column
descriptor");
+ } else {
+ BAT *p =
BATconstant(fres->hseqbase, res[i]->ttype, (ptr)BUNtail(&bi[i], cur),
BATcount(fres), TRANSIENT);
+
+ if (p) {
+ if
(BATappend(res[i], p, NULL, FALSE) != GDK_SUCCEED)
+
ret = createException(MAL, "sql.unionfunc", GDK_EXCEPTION);
+
BBPunfix(p->batCacheid);
+ } else {
ret =
createException(MAL, "sql.unionfunc", GDK_EXCEPTION);
-
BBPunfix(p->batCacheid);
- } else {
- ret =
createException(MAL, "sql.unionfunc", GDK_EXCEPTION);
+ }
}
}
- i=1;
+ i=nr_outers;
+ /* insert into result */
for (ii = 0; i < pci->retc &&
!ret; ii++, i++) {
BAT *b;
ValPtr vp = omb ?
env->stk + q->argv[ii] : nstk->stk + q->argv[ii];
diff --git a/sql/server/rel_rel.c b/sql/server/rel_rel.c
--- a/sql/server/rel_rel.c
+++ b/sql/server/rel_rel.c
@@ -1026,7 +1026,7 @@ rel_select_add_exp(allocator *sa, sql_re
return l;
}
-void
+sql_rel *
rel_join_add_exp( allocator *sa, sql_rel *rel, sql_exp *e)
{
assert(is_join(rel->op) || is_semi(rel->op) || is_select(rel->op));
@@ -1036,6 +1036,7 @@ rel_join_add_exp( allocator *sa, sql_rel
append(rel->exps, e);
if (e->card > rel->card)
rel->card = e->card;
+ return rel;
}
sql_exp *
@@ -1548,6 +1549,8 @@ rel_select_push_exp_down(mvc *sql, sql_r
sql_rel *
rel_push_select(mvc *sql, sql_rel *rel, sql_exp *ls, sql_exp *e, int f)
{
+ if (rel && rel->op == op_select)
+ return rel_select_add_exp(sql->sa, rel, e);
list *l = rel_bind_path(sql, rel, ls, sa_list(sql->sa));
node *n;
sql_rel *lrel = NULL, *p = NULL;
@@ -1686,7 +1689,7 @@ rel_push_join(mvc *sql, sql_rel *rel, sq
return rel;
}
- rel_join_add_exp( sql->sa, p, e);
+ (void) rel_join_add_exp( sql->sa, p, e);
return rel;
}
diff --git a/sql/server/rel_rel.h b/sql/server/rel_rel.h
--- a/sql/server/rel_rel.h
+++ b/sql/server/rel_rel.h
@@ -109,7 +109,7 @@ extern sql_rel *rel_sample(allocator *sa
extern sql_rel *rel_label( mvc *sql, sql_rel *r, int all);
extern sql_exp *rel_project_add_exp( mvc *sql, sql_rel *rel, sql_exp *e);
extern sql_rel *rel_select_add_exp(allocator *sa, sql_rel *l, sql_exp *e);
-extern void rel_join_add_exp(allocator *sa, sql_rel *rel, sql_exp *e);
+extern sql_rel *rel_join_add_exp(allocator *sa, sql_rel *rel, sql_exp *e);
extern sql_exp *rel_groupby_add_aggr(mvc *sql, sql_rel *rel, sql_exp *e);
extern sql_rel *rel_select(allocator *sa, sql_rel *l, sql_exp *e);
diff --git a/sql/server/rel_select.c b/sql/server/rel_select.c
--- a/sql/server/rel_select.c
+++ b/sql/server/rel_select.c
@@ -1895,11 +1895,9 @@ push_select_exp(mvc *sql, sql_rel *rel,
{
if (is_outerjoin(rel->op)) {
if ((is_left(rel->op) || is_full(rel->op)) &&
rel_find_exp(rel->l, ls)) {
- rel_join_add_exp(sql->sa, rel, e);
- return rel;
+ return rel_join_add_exp(sql->sa, rel, e);
} else if ((is_right(rel->op) || is_full(rel->op)) &&
rel_find_exp(rel->r, ls)) {
- rel_join_add_exp(sql->sa, rel, e);
- return rel;
+ return rel_join_add_exp(sql->sa, rel, e);
}
if (is_left(rel->op) && rel_find_exp(rel->r, ls)) {
rel->r = rel_push_select(sql, rel->r, ls, e, f);
@@ -1918,14 +1916,12 @@ push_join_exp(mvc *sql, sql_rel *rel, sq
{
sql_rel *r;
if (/*is_semi(rel->op) ||*/ (is_outerjoin(rel->op) &&
!is_processed((rel)))) {
- rel_join_add_exp(sql->sa, rel, e);
- return rel;
+ return rel_join_add_exp(sql->sa, rel, e);
}
/* push join into the given relation */
if ((r = rel_push_join(sql, rel, L, R, R2, e, f)) != NULL)
return r;
- rel_join_add_exp(sql->sa, rel, e);
- return rel;
+ return rel_join_add_exp(sql->sa, rel, e);
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]