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 -- [email protected]
To unsubscribe send an email to [email protected]