Changeset: f43f1b79f22a for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=f43f1b79f22a
Added Files:
        sql/test/lateral/Tests/All
        sql/test/lateral/Tests/lateral.sql
        sql/test/lateral/Tests/lateral.stable.err
        sql/test/lateral/Tests/lateral.stable.out
Modified Files:
        sql/backends/monet5/rel_bin.c
        sql/backends/monet5/sql_gencode.c
        sql/backends/monet5/sql_statement.c
        sql/backends/monet5/sql_statement.h
        sql/include/sql_catalog.h
        sql/include/sql_relation.h
        sql/server/Makefile.ag
        sql/server/rel_exp.c
        sql/server/rel_optimizer.c
        sql/server/rel_psm.c
        sql/server/rel_psm.h
        sql/server/rel_rel.c
        sql/server/rel_rel.h
        sql/server/rel_select.c
        sql/server/rel_select.h
        sql/server/rel_updates.c
        sql/server/sql_parser.y
        sql/server/sql_scan.c
        sql/server/sql_symbol.c
        sql/server/sql_symbol.h
Branch: default
Log Message:

add first support for new sql table level keyword lateral
It allows looking left, into the tables (relations)


diffs (truncated from 1524 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
@@ -479,6 +479,9 @@ exp_bin(mvc *sql, sql_exp *e, stmt *left
                        s = stmt_mirror(sql->sa, l->h->data);
                else
                */
+               if (f->func->rel) 
+                       s = stmt_func(sql->sa, stmt_list(sql->sa, l), 
sa_strdup(sql->sa, f->func->base.name), f->func->rel, (f->func->type == 
F_UNION));
+               else
                        s = stmt_Nop(sql->sa, stmt_list(sql->sa, l), e->f); 
        }       break;
        case e_aggr: {
@@ -1425,8 +1428,18 @@ rel2bin_table( mvc *sql, sql_rel *rel, l
                                s = stmt_alias(sql->sa, s, rnme, a->name);
                                list_append(l, s);
                        }
+                       if (list_length(f->res) == list_length(f->func->res) + 
1) {
+                               /* add missing %TID% column */
+                               sql_subtype *t = f->res->t->data;
+                               stmt *s = stmt_rs_column(sql->sa, psub, i, t); 
+                               const char *rnme = exp_find_rel_name(op);
+       
+                               s = stmt_alias(sql->sa, s, rnme, TID);
+                               list_append(l, s);
+                       }
                }
-               if (!rel->flag && sub && sub->nrcols) { /* add sub, table func 
with table input, we expect alignment */
+               if (!rel->flag && sub && sub->nrcols) { 
+                       assert(0);
                        list_merge(l, sub->op4.lval, NULL);
                        osub = sub;
                }
@@ -1439,7 +1452,7 @@ rel2bin_table( mvc *sql, sql_rel *rel, l
 
                l = rel2bin_args(sql, rel->l, sa_list(sql->sa));
                sub = stmt_list(sql->sa, l);
-               sub = stmt_func(sql->sa, sub, sa_strdup(sql->sa, nme), rel->l);
+               sub = stmt_func(sql->sa, sub, sa_strdup(sql->sa, nme), rel->l, 
0);
                l = sa_list(sql->sa);
                for(i = 0, n = rel->exps->h; n; n = n->next, i++ ) {
                        sql_exp *c = n->data;
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
@@ -466,8 +466,10 @@ static int
                        int type = t->type->localtype;
                        int varid = 0;
                        const char *nme = 
(op->op3)?op->op3->op4.aval->data.val.sval:op->cname;
-
-                       varid = newVariable(curBlk, (char *)nme, strlen(nme), 
type);
+                       char buf[64];
+
+                       snprintf(buf,64,"A%s",nme);
+                       varid = newVariable(curBlk, (char *)buf, strlen(buf), 
type);
                        curInstr = pushArgument(curBlk, curInstr, varid);
                        setVarType(curBlk, varid, type);
                        setVarUDFtype(curBlk, varid);
@@ -557,8 +559,10 @@ static int
                        int type = t->type->localtype;
                        int varid = 0;
                        const char *nme = 
(op->op3)?op->op3->op4.aval->data.val.sval:op->cname;
-
-                       varid = newVariable(curBlk, (char*) nme,strlen(nme), 
type);
+                       char buf[64];
+
+                       snprintf(buf,64,"A%s",nme);
+                       varid = newVariable(curBlk, (char*) buf,strlen(buf), 
type);
                        curInstr = pushArgument(curBlk, curInstr, varid);
                        setVarType(curBlk, varid, type);
                        setVarUDFtype(curBlk, varid);
@@ -2178,8 +2182,15 @@ static int
                        if (monet5_create_relational_function(sql->mvc, mod, 
fimp, rel, s, 1) < 0)
                                 return -1;
 
-                       q = newStmt(mb, mod, fimp);
+                       if (s->flag) 
+                               q = newStmt(mb, batmalRef, multiplexRef);
+                       else
+                               q = newStmt(mb, mod, fimp);
                        q = relational_func_create_result(sql->mvc, mb, q, rel);
+                       if (s->flag) {
+                               q = pushStr(mb, q, mod);
+                               q = pushStr(mb, q, fimp);
+                       }
                        if (s->op1)
                                for (n = s->op1->op4.lval->h; n; n = n->next) {
                                        stmt *op = n->data;
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
@@ -1124,7 +1124,7 @@ stmt_Nop(sql_allocator *sa, stmt *ops, s
 }
 
 stmt *
-stmt_func(sql_allocator *sa, stmt *ops, const char *name, sql_rel *rel)
+stmt_func(sql_allocator *sa, stmt *ops, const char *name, sql_rel *rel, int 
f_union)
 {
        node *n;
        stmt *o = NULL, *s = stmt_create(sa, st_func);
@@ -1132,6 +1132,7 @@ stmt_func(sql_allocator *sa, stmt *ops, 
        s->op1 = ops;
        s->op2 = stmt_atom_string(sa, name);
        s->op4.rel = rel;
+       s->flag = f_union;
        if (ops && list_length(ops->op4.lval)) {
                for (n = ops->op4.lval->h, o = n->data; n; n = n->next) {
                        stmt *c = n->data;
diff --git a/sql/backends/monet5/sql_statement.h 
b/sql/backends/monet5/sql_statement.h
--- a/sql/backends/monet5/sql_statement.h
+++ b/sql/backends/monet5/sql_statement.h
@@ -224,7 +224,7 @@ extern stmt *stmt_convert(sql_allocator 
 extern stmt *stmt_unop(sql_allocator *sa, stmt *op1, sql_subfunc *op);
 extern stmt *stmt_binop(sql_allocator *sa, stmt *op1, stmt *op2, sql_subfunc 
*op);
 extern stmt *stmt_Nop(sql_allocator *sa, stmt *ops, sql_subfunc *op);
-extern stmt *stmt_func(sql_allocator *sa, stmt *ops, const char *name, sql_rel 
*imp);
+extern stmt *stmt_func(sql_allocator *sa, stmt *ops, const char *name, sql_rel 
*imp, int f_union);
 extern stmt *stmt_aggr(sql_allocator *sa, stmt *op1, stmt *grp, stmt *ext, 
sql_subaggr *op, int reduce, int no_nil);
 
 extern stmt *stmt_alias(sql_allocator *sa, stmt *op1, const char *tname, const 
char *name);
diff --git a/sql/include/sql_catalog.h b/sql/include/sql_catalog.h
--- a/sql/include/sql_catalog.h
+++ b/sql/include/sql_catalog.h
@@ -334,6 +334,7 @@ typedef struct sql_func {
                        */
        sql_schema *s;
        sql_allocator *sa;
+       void *rel;      /* implementation */
 } sql_func;
 
 typedef struct sql_subfunc {
diff --git a/sql/include/sql_relation.h b/sql/include/sql_relation.h
--- a/sql/include/sql_relation.h
+++ b/sql/include/sql_relation.h
@@ -282,10 +282,11 @@ typedef struct relation {
        void *r;
        list *exps; 
        int nrcols;     /* nr of cols */        
-       char flag;      /* EXP_DISTINCT */ 
-       char card;      /* 0, 1 (row), 2 aggr, 3 */
-       char processed; /* fully processed or still in the process of building 
*/
-       char subquery;  /* is this part a subquery, this is needed for proper 
name binding */
+       unsigned int
+        flag:8,        /* EXP_DISTINCT */ 
+        card:4,        /* 0, 1 (row), 2 aggr, 3 */
+        processed:1, /* fully processed or still in the process of building */
+        subquery:1;    /* is this part a subquery, this is needed for proper 
name binding */
        void *p;        /* properties for the optimizer, distribution */
 } sql_rel;
 
diff --git a/sql/server/Makefile.ag b/sql/server/Makefile.ag
--- a/sql/server/Makefile.ag
+++ b/sql/server/Makefile.ag
@@ -15,7 +15,7 @@ INCLUDES = ../include ../common ../stora
                   ../../common/stream \
                   ../../gdk
 
-AM_YFLAGS = -d -p sql
+AM_YFLAGS = -d -p sql -r all
 
 lib_sqlserver = {
        NOINST
diff --git a/sql/server/rel_exp.c b/sql/server/rel_exp.c
--- a/sql/server/rel_exp.c
+++ b/sql/server/rel_exp.c
@@ -567,8 +567,10 @@ exp_rel(mvc *sql, sql_rel *rel)
 {
        sql_exp *e = exp_create(sql->sa, e_psm);
 
+       /*
        rel = rel_optimizer(sql, rel);
        rel = rel_distribute(sql, rel);
+       */
        e->l = rel;
        e->flag = PSM_REL;
        return e;
diff --git a/sql/server/rel_optimizer.c b/sql/server/rel_optimizer.c
--- a/sql/server/rel_optimizer.c
+++ b/sql/server/rel_optimizer.c
@@ -591,34 +591,6 @@ order_join_expressions(mvc *sql, list *d
        return res;
 }
 
-static sql_exp *
-rel_find_column( sql_allocator *sa, sql_rel *rel, const char *tname, const 
char *cname )
-{
-       if (!rel)
-               return NULL;
-
-       if (rel->exps && (is_project(rel->op) || is_base(rel->op))) {
-               sql_exp *e = exps_bind_column2(rel->exps, tname, cname);
-               if (e)
-                       return exp_alias(sa, e->rname, exp_name(e), tname, 
cname, exp_subtype(e), e->card, has_nil(e), is_intern(e));
-       }
-       if (is_project(rel->op) && rel->l) {
-               return rel_find_column(sa, rel->l, tname, cname);
-       } else if (is_join(rel->op)) {
-               sql_exp *e = rel_find_column(sa, rel->l, tname, cname);
-               if (!e)
-                       e = rel_find_column(sa, rel->r, tname, cname);
-               return e;
-       } else if (is_set(rel->op) ||
-                  is_sort(rel) ||
-                  is_semi(rel->op) ||
-                  is_select(rel->op)) {
-               if (rel->l)
-                       return rel_find_column(sa, rel->l, tname, cname);
-       }
-       return NULL;
-}
-
 static int
 find_join_rels(list **L, list **R, list *exps, list *rels)
 {
diff --git a/sql/server/rel_psm.c b/sql/server/rel_psm.c
--- a/sql/server/rel_psm.c
+++ b/sql/server/rel_psm.c
@@ -32,7 +32,7 @@ rel_psm_block(sql_allocator *sa, list *l
        return NULL;
 }
 
-static sql_rel *
+sql_rel *
 rel_psm_stmt(sql_allocator *sa, sql_exp *e)
 {
        if (e) {
diff --git a/sql/server/rel_psm.h b/sql/server/rel_psm.h
--- a/sql/server/rel_psm.h
+++ b/sql/server/rel_psm.h
@@ -20,4 +20,6 @@ extern sql_func *resolve_func( mvc *sql,
 extern sql_rel *rel_psm(mvc *sql, symbol *sym);
 extern sql_rel *rel_select_with_into( mvc *sql, symbol *sq);
 
+extern sql_rel *rel_psm_stmt(sql_allocator *sa, sql_exp *e);
+
 #endif /*_REL_PSM_H_*/
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
@@ -1145,3 +1145,32 @@ rel_add_identity(mvc *sql, sql_rel *rel,
                return rel;
        return _rel_add_identity(sql, rel, exp);
 }
+
+sql_exp *
+rel_find_column( sql_allocator *sa, sql_rel *rel, const char *tname, const 
char *cname )
+{
+       if (!rel)
+               return NULL;
+
+       if (rel->exps && (is_project(rel->op) || is_base(rel->op))) {
+               sql_exp *e = exps_bind_column2(rel->exps, tname, cname);
+               if (e)
+                       return exp_alias(sa, e->rname, exp_name(e), tname, 
cname, exp_subtype(e), e->card, has_nil(e), is_intern(e));
+       }
+       if (is_project(rel->op) && rel->l) {
+               return rel_find_column(sa, rel->l, tname, cname);
+       } else if (is_join(rel->op)) {
+               sql_exp *e = rel_find_column(sa, rel->l, tname, cname);
+               if (!e)
+                       e = rel_find_column(sa, rel->r, tname, cname);
+               return e;
+       } else if (is_set(rel->op) ||
+                  is_sort(rel) ||
+                  is_semi(rel->op) ||
+                  is_select(rel->op)) {
+               if (rel->l)
+                       return rel_find_column(sa, rel->l, tname, cname);
+       }
+       return NULL;
+}
+
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
@@ -73,4 +73,5 @@ extern sql_rel *rel_or(mvc *sql, sql_rel
 extern sql_table *rel_ddl_table_get(sql_rel *r);
 
 extern sql_rel *rel_add_identity(mvc *sql, sql_rel *rel, sql_exp **exp);
+extern sql_exp * rel_find_column( sql_allocator *sa, sql_rel *rel, const char 
*tname, const char *cname );
 #endif /* _REL_REL_H_ */
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
@@ -411,154 +411,229 @@ find_func(mvc *sql, sql_schema *s, char 
        return NULL;
 }
 
+static sql_exp *
+find_table_function(mvc *sql, sql_schema *s, char *fname, list *exps, list *tl)
+{
+       sql_exp *e = NULL;
+       sql_subfunc * sf = bind_func_(sql, s, fname, tl, F_UNION);
+
+       if (sf) {
+               e = exp_op(sql->sa, exps, sf);
+       } else if (list_length(tl)) { 
+               sql_subfunc * prev = NULL;
+
+               while(!e && (sf = bind_member_func(sql, s, fname, tl->h->data, 
list_length(tl), prev)) != NULL) {
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to