Changeset: 56e77337f207 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=56e77337f207
Modified Files:
        clients/Tests/MAL-signatures.stable.out
        clients/Tests/MAL-signatures.stable.out.int128
        sql/backends/monet5/rel_bin.c
        sql/backends/monet5/sql.c
        sql/backends/monet5/sql.h
        sql/backends/monet5/sql.mal
        sql/backends/monet5/sql_statement.c
        sql/backends/monet5/sql_statement.h
        sql/server/rel_optimizer.c
        sql/server/rel_rel.c
        sql/server/rel_rel.h
        sql/server/rel_select.c
        sql/server/rel_unnest.c
        sql/test/subquery/Tests/subquery3.stable.err
        sql/test/subquery/Tests/subquery3.stable.out
        sql/test/subquery/Tests/subquery4.sql
        sql/test/subquery/Tests/subquery4.stable.err
        sql/test/subquery/Tests/subquery4.stable.out
Branch: pushdown
Log Message:

merged with default


diffs (truncated from 859 to 300 lines):

diff --git a/clients/Tests/MAL-signatures.stable.out 
b/clients/Tests/MAL-signatures.stable.out
--- a/clients/Tests/MAL-signatures.stable.out
+++ b/clients/Tests/MAL-signatures.stable.out
@@ -18886,6 +18886,7 @@ stdout of test 'MAL-signatures` in direc
 [ "sql",       "transaction_commit",   "pattern 
sql.transaction_commit(chain:int, name:str):void ",    
"SQLtransaction_commit;",       "A transaction statement (type can be 
commit,release,rollback or start)"        ]
 [ "sql",       "transaction_release",  "pattern 
sql.transaction_release(chain:int, name:str):void ",   
"SQLtransaction_release;",      "A transaction statement (type can be 
commit,release,rollback or start)"        ]
 [ "sql",       "transaction_rollback", "pattern 
sql.transaction_rollback(chain:int, name:str):void ",  
"SQLtransaction_rollback;",     "A transaction statement (type can be 
commit,release,rollback or start)"        ]
+[ "sql",       "unionfunc",    "pattern sql.unionfunc(mod:str, fcn:str, 
X_0:any...):any... ",  "SQLunionfunc;",        ""      ]
 [ "sql",       "update",       "pattern sql.update(mvc:int, sname:str, 
tname:str, cname:str, rids:any, upd:any):int ", "mvc_update_wrap;",     "Update 
the values of the column tname.cname. Returns sequence number for order 
dependence)"    ]
 [ "sql",       "update_schemas",       "pattern sql.update_schemas():void ",   
"SYSupdate_schemas;",   "Procedure triggered on update of the sys.schemas 
table"        ]
 [ "sql",       "update_tables",        "pattern sql.update_tables():void ",    
"SYSupdate_tables;",    "Procedure triggered on update of the sys._tables 
table"        ]
diff --git a/clients/Tests/MAL-signatures.stable.out.int128 
b/clients/Tests/MAL-signatures.stable.out.int128
--- a/clients/Tests/MAL-signatures.stable.out.int128
+++ b/clients/Tests/MAL-signatures.stable.out.int128
@@ -26900,6 +26900,7 @@ stdout of test 'MAL-signatures` in direc
 [ "sql",       "transaction_commit",   "pattern 
sql.transaction_commit(chain:int, name:str):void ",    
"SQLtransaction_commit;",       "A transaction statement (type can be 
commit,release,rollback or start)"        ]
 [ "sql",       "transaction_release",  "pattern 
sql.transaction_release(chain:int, name:str):void ",   
"SQLtransaction_release;",      "A transaction statement (type can be 
commit,release,rollback or start)"        ]
 [ "sql",       "transaction_rollback", "pattern 
sql.transaction_rollback(chain:int, name:str):void ",  
"SQLtransaction_rollback;",     "A transaction statement (type can be 
commit,release,rollback or start)"        ]
+[ "sql",       "unionfunc",    "pattern sql.unionfunc(mod:str, fcn:str, 
X_0:any...):any... ",  "SQLunionfunc;",        ""      ]
 [ "sql",       "update",       "pattern sql.update(mvc:int, sname:str, 
tname:str, cname:str, rids:any, upd:any):int ", "mvc_update_wrap;",     "Update 
the values of the column tname.cname. Returns sequence number for order 
dependence)"    ]
 [ "sql",       "update_schemas",       "pattern sql.update_schemas():void ",   
"SYSupdate_schemas;",   "Procedure triggered on update of the sys.schemas 
table"        ]
 [ "sql",       "update_tables",        "pattern sql.update_tables():void ",    
"SYSupdate_tables;",    "Procedure triggered on update of the sys._tables 
table"        ]
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
@@ -19,6 +19,8 @@
 #include "rel_optimizer.h"
 #include "sql_env.h"
 #include "sql_optimizer.h"
+#include "sql_gencode.h"
+#include "mal_builder.h"
 
 #define OUTER_ZERO 64
 
@@ -538,6 +540,10 @@ exp_bin(backend *be, sql_exp *e, stmt *l
                                        for(n=lst->op4.lval->h; n; n = n->next)
                                                list_append(l, const_column(be, 
(stmt*)n->data));
                                        r = stmt_list(be, l);
+                               } else if (r->type == st_table && e->card == 
CARD_ATOM) { /* fetch value */
+                                       r = lst->op4.lval->h->data;
+                                       if (!r->aggr)
+                                               r = stmt_fetch(be, r);
                                }
                                if (r->type == st_list)
                                        r = stmt_table(be, r, 1);
@@ -1550,7 +1556,7 @@ exp2bin_args(backend *be, sql_exp *e, li
        if (THRhighwater())
                return sql_error(sql, 10, SQLSTATE(42000) "Query too complex: 
running out of stack space");
 
-       if (!e)
+       if (!e || !args)
                return args;
        switch(e->type){
        case e_column:
@@ -1587,7 +1593,7 @@ exp2bin_args(backend *be, sql_exp *e, li
                } else if (e->r) {
                        char nme[64];
 
-                       snprintf(nme, 64, "A%s", (char*)e->r);
+                       snprintf(nme, sizeof(nme), "A%s", (char*)e->r);
                        if (!list_find(args, nme, (fcmp)&alias_cmp)) {
                                stmt *s = stmt_var(be, e->r, &e->tpe, 0, 0);
 
@@ -1597,7 +1603,7 @@ exp2bin_args(backend *be, sql_exp *e, li
                } else {
                        char nme[16];
 
-                       snprintf(nme, 16, "A%u", e->flag);
+                       snprintf(nme, sizeof(nme), "A%u", e->flag);
                        if (!list_find(args, nme, (fcmp)&alias_cmp)) {
                                atom *a = sql->args[e->flag];
                                stmt *s = stmt_varnr(be, e->flag, &a->tpe);
@@ -1628,7 +1634,7 @@ rel2bin_args(backend *be, sql_rel *rel, 
        if (THRhighwater())
                return sql_error(be->mvc, 10, SQLSTATE(42000) "Query too 
complex: running out of stack space");
 
-       if (!rel)
+       if (!rel || !args)
                return args;
        switch(rel->op) {
        case op_basetable:
@@ -1718,6 +1724,8 @@ rel2bin_table(backend *be, sql_rel *rel,
                int i;
                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;
@@ -1735,10 +1743,30 @@ rel2bin_table(backend *be, sql_rel *rel,
                }
 
                assert(f);
-               psub = exp_bin(be, op, sub, NULL, NULL, NULL, NULL, NULL); /* 
table function */
-               if (!psub) { 
-                       assert(sql->session->status == -10); /* Stack overflow 
errors shouldn't terminate the server */
-                       return NULL;
+               if (f->func->res && list_length(f->func->res) + 1 == 
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;
+                       ops = sa_list(be->mvc->sa);
+                       if (exps) {
+                               for (node *en = exps->h; en; en = en->next) {
+                                       sql_exp *e = en->data;
+
+                                       /* find column */
+                                       stmt *s = exp_bin(be, e, sub, NULL, 
NULL, NULL, NULL, NULL);
+                                       if (!s)
+                                               return NULL;
+                                       if (en->next)
+                                               append(ops, s);
+                                       else /* last added exp is the ids (todo 
use name base lookup !!) */
+                                               ids = s;
+                               }
+                       }
+               } else {
+                       psub = exp_bin(be, op, sub, NULL, NULL, NULL, NULL, 
NULL); /* table function */
+                       if (!psub) { 
+                               assert(sql->session->status == -10); /* Stack 
overflow errors shouldn't terminate the server */
+                               return NULL;
+                       }
                }
                l = sa_list(sql->sa);
                if (f->func->res) {
@@ -1753,9 +1781,58 @@ rel2bin_table(backend *be, sql_rel *rel,
                                        list_append(l, s);
                                }
                        } else {
-                               assert(list_length(f->func->res) == 
list_length(rel->exps));
-                               node *m;
-                               for(i = 0, n = f->func->res->h, m = 
rel->exps->h; n && m; n = n->next, m = m->next, i++ ) {
+                               node *m = rel->exps->h;
+                               int i = 0;
+
+                               /* correlated table returning function */
+                               if (list_length(f->func->res) + 1 == 
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 
+                                        */
+                                       InstrPtr q = newStmt(be->mb, "sql", 
"unionfunc");
+                                       /* Generate output rowid column and 
output of function f */
+                                       for(i=0; m; m = m->next, i++) {
+                                               sql_exp *e = m->data;
+                                               int type = 
exp_subtype(e)->type->localtype;
+
+                                               type = newBatType(type);
+                                               if (i)
+                                                       q = pushReturn(be->mb, 
q, newTmpVariable(be->mb, type));
+                                               else
+                                                       getArg(q, 0) = 
newTmpVariable(be->mb, type);
+                                       }
+                                       str mod = sql_func_mod(f->func);
+                                       str fcn = sql_func_imp(f->func);
+                                       q = pushStr(be->mb, q, mod);
+                                       q = pushStr(be->mb, q, fcn);
+                                       if (backend_create_func(be, f->func, 
NULL, ops) < 0)
+                                               return NULL;
+                                       psub = stmt_direct_func(be, q);
+
+                                       if (ids) /* push input rowids column */
+                                               q = pushArgument(be->mb, q, 
ids->nr);
+
+                                       /* add inputs in correct order ie loop 
through args of f and pass column */
+                                       if (ops) {
+                                               for (node *en = ops->h; en; en 
= en->next) {
+                                                       stmt *op = en->data;
+
+                                                       q = 
pushArgument(be->mb, q, op->nr);
+                                               }
+                                       }
+
+                                       /* 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++ ) {
+                                               sql_exp *exp = m->data;
+                                               stmt *s = stmt_rs_column(be, 
psub, i, exp_subtype(exp)); 
+                               
+                                               s = stmt_alias(be, s, exp->l, 
exp->r);
+                                               list_append(l, s);
+                                       }
+                               }
+                               for(n = f->func->res->h; n && m; n = n->next, m 
= m->next, i++ ) {
                                        sql_arg *a = n->data;
                                        sql_exp *exp = m->data;
                                        stmt *s = stmt_rs_column(be, psub, i, 
&a->type); 
@@ -1764,7 +1841,9 @@ rel2bin_table(backend *be, sql_rel *rel,
                                        s = stmt_alias(be, s, rnme, a->name);
                                        list_append(l, s);
                                }
+#if 0
                                if (list_length(f->res) == 
list_length(f->func->res) + 1) {
+                                       assert(0);
                                        /* add missing %TID% column */
                                        sql_subtype *t = f->res->t->data;
                                        stmt *s = stmt_rs_column(be, psub, i, 
t); 
@@ -1773,6 +1852,7 @@ rel2bin_table(backend *be, sql_rel *rel,
                                        s = stmt_alias(be, s, rnme, TID);
                                        list_append(l, s);
                                }
+#endif
                        }
                }
                assert(rel->flag != TABLE_PROD_FUNC || !sub || !(sub->nrcols));
@@ -2605,6 +2685,7 @@ rel_rename(backend *be, sql_rel *rel, st
 {
        mvc *sql = be->mvc;
 
+       (void) sql;
        if (rel->exps) {
                node *en, *n;
                list *l = sa_list(be->mvc->sa);
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
@@ -5553,3 +5553,169 @@ 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
+ */
+str
+SQLunionfunc(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
+{
+       int arg = pci->retc;
+       str mod, fcn, ret = MAL_SUCCEED;
+       InstrPtr npci;
+
+       mod = *getArgReference_str(stk, pci, arg++);
+       fcn = *getArgReference_str(stk, pci, arg++);
+       npci = newStmt(mb, mod, fcn);
+
+       for (int i = 1; i < pci->retc; i++) {
+               int type = getArgType(mb, pci, i);
+
+               if (i==1)
+                       getArg(npci, 0) = newTmpVariable(mb, type);
+               else
+                       npci = pushReturn(mb, npci, newTmpVariable(mb, type));
+       }
+       for (int i = pci->retc+2+1; i < pci->argc; i++) {
+               int type = getBatType(getArgType(mb, pci, i));
+
+               npci = pushNil(mb, npci, type);
+       }
+       /* check program to get the proper malblk */
+       if (chkInstruction(cntxt->usermodule, mb, npci)) {
+               freeInstruction(npci);
+               return createException(MAL, "sql.unionfunc", SQLSTATE(42000) 
PROGRAM_GENERAL);
+       }
+
+       if (npci) {
+               BAT **res = NULL, **input = NULL;
+               BATiter *bi = NULL;
+               BUN cnt = 0;
+               int nrinput = pci->argc - 2 - pci->retc;
+               MalBlkPtr nmb = NULL;
+               MalStkPtr env = NULL;
+               InstrPtr q = NULL;
+
+               if (!(input = GDKzalloc(sizeof(BAT*) * nrinput))) {
+                       ret = createException(MAL, "sql.unionfunc", 
SQLSTATE(HY013) MAL_MALLOC_FAIL);
+                       goto finalize;
+               }
+               if (!(bi = GDKmalloc(sizeof(BATiter) * nrinput))) {
+                       ret = createException(MAL, "sql.unionfunc", 
SQLSTATE(HY013) MAL_MALLOC_FAIL);
+                       goto finalize;
+               }
+               assert(nrinput == pci->retc);
+               for (int i = 0, j = pci->retc+2; 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");
+                               goto finalize;
+                       }
+                       bi[i] = bat_iterator(input[i]);
+                       cnt = BATcount(input[i]); 
+               }
+
+               /* create result bats */
+               if (!(res = GDKzalloc(sizeof(BAT*) * pci->retc))) {
+                       ret = createException(MAL, "sql.unionfunc", 
SQLSTATE(HY013) MAL_MALLOC_FAIL);
+                       goto finalize;
+               }
+               for (int i = 0; i<pci->retc; i++) {
+                       int type = getArgType(mb, pci, i);
+
+                       if (!(res[i] = COLnew(0, getBatType(type), cnt, 
TRANSIENT))) {
+                               ret = createException(MAL, "sql.unionfunc", 
SQLSTATE(HY013) MAL_MALLOC_FAIL);
+                               goto finalize;
+                       }
+               }
+
+               if (!(nmb = copyMalBlk(npci->blk))) {
+                       ret = createException(MAL, "sql.unionfunc", 
SQLSTATE(HY013) MAL_MALLOC_FAIL);
+                       goto finalize;
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to