Changeset: 3ede5e9bb378 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/3ede5e9bb378
Modified Files:
        sql/backends/monet5/sql_execute.c
        sql/server/rel_rel.c
        sql/server/rel_unnest.c
        sql/server/sql_mvc.c
        sql/server/sql_partition.c
        sql/test/prepare/Tests/prepared-statement-with-udf.Bug-6650.stable.out
        sql/test/rel-optimizers/Tests/groupby-cse.test
Branch: default
Log Message:

rewrite simple (single return) table producing functions into inlined (view 
like) definitions.
Sofar only with constants as arguments (ie no unnesting yet).


diffs (212 lines):

diff --git a/sql/backends/monet5/sql_execute.c 
b/sql/backends/monet5/sql_execute.c
--- a/sql/backends/monet5/sql_execute.c
+++ b/sql/backends/monet5/sql_execute.c
@@ -676,7 +676,7 @@ RAstatement(Client c, MalBlkPtr mb, MalS
        refs = sa_list(m->sa);
        rel = rel_read(m, *expr, &pos, refs);
        if (*opt && rel)
-               rel = sql_processrelation(m, rel, 0, 0, 0, 0);
+               rel = sql_processrelation(m, rel, 0, 1, 0, 0);
        if (!rel) {
                if (strlen(m->errstr) > 6 && m->errstr[5] == '!')
                        msg = createException(SQL, "RAstatement", "%s", 
m->errstr);
@@ -892,7 +892,7 @@ RAstatement2(Client cntxt, MalBlkPtr mb,
        refs = sa_list(m->sa);
        rel = rel_read(m, expr, &pos, refs);
        if (rel)
-               rel = sql_processrelation(m, rel, 0, 0, 0, 0);
+               rel = sql_processrelation(m, rel, 0, 1, 0, 0);
        if (!rel) {
                if (strlen(m->errstr) > 6 && m->errstr[5] == '!')
                        msg = createException(SQL, "RAstatement2", "%s", 
m->errstr);
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
@@ -2180,9 +2180,13 @@ rel_exp_visitor(visitor *v, sql_rel *rel
                break;
        case op_table:
                if (IS_TABLE_PROD_FUNC(rel->flag) || rel->flag == 
TABLE_FROM_RELATION) {
+                       bool changed = false;
                        if (rel->l)
                                if ((rel->l = rel_exp_visitor(v, rel->l, 
exp_rewriter, topdown, relations_topdown)) == NULL)
                                        return NULL;
+                       if (rel->r)
+                               if ((rel->r = exp_visitor(v, rel, rel->r, 0, 
exp_rewriter, topdown, relations_topdown, &changed)) == NULL)
+                                       return NULL;
                }
                break;
        case op_ddl:
diff --git a/sql/server/rel_unnest.c b/sql/server/rel_unnest.c
--- a/sql/server/rel_unnest.c
+++ b/sql/server/rel_unnest.c
@@ -4197,11 +4197,97 @@ rewrite_rel(visitor *v, sql_rel *rel)
        return rel;
 }
 
+typedef struct sql_args {
+       list *args;
+       list *exps;
+} sql_args;
+
+static int
+var_name_cmp(sql_arg *v, char *name)
+{
+       return strcmp(v->name, name);
+}
+
+static sql_exp *
+exp_inline_arg(visitor *v, sql_rel *rel, sql_exp *e, int depth)
+{
+       (void)rel;
+       (void)depth;
+       sql_args *args = v->data;
+       if (e->type == e_atom && e->r) {
+               sql_arg *a = e->r;
+               int level = is_freevar(e);
+               node *n = list_find(args->args, a->name, (fcmp)&var_name_cmp);
+               if (n) {
+                       sql_exp *val = list_fetch(args->exps, 
list_position(args->args, n->data));
+                       val = exp_copy(v->sql, val);
+                       exp_setname(v->sql->sa, val, exp_relname(e), 
exp_name(e));
+                       if (level)
+                               set_freevar(val, level-1);
+                       return val;
+               }
+       }
+       return e;
+}
+
+static sql_rel *
+rel_inline_table_func(visitor *v, sql_rel *rel)
+{
+       if (!rel_is_ref(rel) && rel->op == op_table && !rel->l && rel->r) { /* 
TODO add input relation (rel->l) rewritting */
+               sql_exp *opf = rel->r;
+               if (opf->type == e_func) {
+                       sql_subfunc *f = opf->f;
+
+                       if (f->func->vararg || f->func->varres)
+                               return rel;
+
+                       if (f->func->lang == FUNC_LANG_SQL && f->func->type == 
F_UNION) {
+                               sql_rel *r = rel_parse(v->sql, f->func->s, 
f->func->query, m_instantiate);
+
+                               if (r && is_ddl(r->op) && list_length(r->exps) 
== 1) {
+                                       sql_exp *psm = r->exps->h->data;
+                                       if (psm && psm->type == e_psm && 
psm->flag == PSM_RETURN) {
+                                               sql_exp *ret = psm->l;
+                                               if (ret && ret->type == e_psm 
&& ret->flag == PSM_REL) {
+                                                       r = ret->l;
+                                                       list *exps = r->exps;
+                                                       r = 
rel_project(v->sql->sa, r, sa_list(v->sql->sa));
+                                                       for(node *n = 
rel->exps->h, *m = exps->h; n && m; n = n->next, m = m->next) {
+                                                               sql_exp *e = 
m->data;
+                                                               sql_exp *pe = 
n->data;
+
+                                                               e = 
exp_ref(v->sql, e);
+                                                               
exp_setname(v->sql->sa, e, exp_relname(pe), exp_name(pe));
+                                                               if 
(is_freevar(pe))
+                                                                       
set_freevar(e, is_freevar(pe)-1);
+                                                               append(r->exps, 
e);
+                                                       }
+                                                       sql_args a;
+                                                       if (f->func->ops) {
+                                                               a.args = 
f->func->ops;
+                                                               a.exps = opf->l;
+                                                               v->data = &a;
+                                                               r = 
rel_exp_visitor_topdown(v, r, &exp_inline_arg, true);
+                                                               v->data = NULL;
+                                                       }
+                                                       r = rel_unnest(v->sql, 
r);
+                                                       return r;
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+       return rel;
+}
+
 /* add an dummy true projection column */
 static sql_rel *
 rel_unnest_simplify(visitor *v, sql_rel *rel)
 {
        /* at rel_select.c explicit cross-products generate empty selects, if 
these are not used, they can be removed at rewrite_simplify */
+       if (rel && v->sql->emode != m_deps)
+               rel = rel_inline_table_func(v, rel);
        if (rel)
                rel = rewrite_basetable(v->sql, rel);   /* add proper exps 
lists */
        if (rel)
diff --git a/sql/server/sql_mvc.c b/sql/server/sql_mvc.c
--- a/sql/server/sql_mvc.c
+++ b/sql/server/sql_mvc.c
@@ -1558,8 +1558,12 @@ mvc_copy_trigger(mvc *m, sql_table *t, s
 sql_rel *
 sql_processrelation(mvc *sql, sql_rel *rel, int profile, int instantiate, int 
value_based_opt, int storage_based_opt)
 {
+       int emode = sql->emode;
+       if (!instantiate)
+               sql->emode = m_deps;
        if (rel)
                rel = rel_unnest(sql, rel);
+       sql->emode = emode;
        if (rel)
                rel = rel_optimizer(sql, rel, profile, instantiate, 
value_based_opt, storage_based_opt);
        return rel;
diff --git a/sql/server/sql_partition.c b/sql/server/sql_partition.c
--- a/sql/server/sql_partition.c
+++ b/sql/server/sql_partition.c
@@ -301,7 +301,7 @@ bootstrap_partition_expression(mvc *sql,
                r->l = NULL; /* omit table from list of dependencies */
                (void) rel_project_add_exp(sql, r, exp);
 
-               nr = sql_processrelation(sql, nr, 0, 0, 0, 0);
+               nr = sql_processrelation(sql, nr, 0, instantiate, 0, 0);
                if (nr) {
                        list *blist = rel_dependencies(sql, nr);
                        if (mvc_create_dependencies(sql, blist, mt->base.id, 
FUNC_DEPENDENCY))
diff --git 
a/sql/test/prepare/Tests/prepared-statement-with-udf.Bug-6650.stable.out 
b/sql/test/prepare/Tests/prepared-statement-with-udf.Bug-6650.stable.out
--- a/sql/test/prepare/Tests/prepared-statement-with-udf.Bug-6650.stable.out
+++ b/sql/test/prepare/Tests/prepared-statement-with-udf.Bug-6650.stable.out
@@ -79,7 +79,7 @@ stdout of test 'prepared-statement-with-
 [ "varchar",   0,      0,      "",     "%1",   "cc"    ]
 [ "varchar",   0,      0,      NULL,   NULL,   NULL    ]
 #exec  9('a');
-% .%1, .%1,    .%1 # table_name
+% sys.%1,      sys.%1, sys.%1 # table_name
 % aa,  bb,     cc # name
 % varchar,     varchar,        varchar # type
 % 1,   1,      1 # length
@@ -96,7 +96,7 @@ stdout of test 'prepared-statement-with-
 [ "varchar",   0,      0,      NULL,   NULL,   NULL    ]
 [ "varchar",   0,      0,      NULL,   NULL,   NULL    ]
 #exec 11('a', 'b');
-% .tt, .tt,    .tt # table_name
+% sys.tt,      sys.tt, sys.tt # table_name
 % aa,  bb,     cc # name
 % varchar,     varchar,        varchar # type
 % 0,   0,      0 # length
@@ -113,7 +113,7 @@ stdout of test 'prepared-statement-with-
 [ "varchar",   0,      0,      NULL,   NULL,   NULL    ]
 [ "varchar",   0,      0,      NULL,   NULL,   NULL    ]
 #exec 13('a', 'a');
-% .%1, .%1,    .%1,    sys.something # table_name
+% sys.%1,      sys.%1, sys.%1, sys.something # table_name
 % aa,  bb,     cc,     a # name
 % varchar,     varchar,        varchar,        varchar # type
 % 1,   1,      1,      1 # length
diff --git a/sql/test/rel-optimizers/Tests/groupby-cse.test 
b/sql/test/rel-optimizers/Tests/groupby-cse.test
--- a/sql/test/rel-optimizers/Tests/groupby-cse.test
+++ b/sql/test/rel-optimizers/Tests/groupby-cse.test
@@ -125,8 +125,9 @@ GROUP BY
 ----
 project (
 | group by (
-| | table ("sys"."tablereturnudf"(), 
-| | ) [ "%1"."a1", "%1"."a2", "%1"."a3" ]
+| | project (
+| | | table("sys"."foo") [ "foo"."c1", "foo"."c3" ]
+| | ) [ "foo"."c1" as "%1"."a1", "foo"."c3" as "%1"."a3" ]
 | ) [ "%1"."a1" ] [ "%1"."a1", "sys"."count" no nil ("%1"."a3") NOT NULL as 
"%2"."%2" ]
 ) [ "%1"."a1" UNIQUE, "%1"."a1" UNIQUE, "%2"."%2" NOT NULL ]
 
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to