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