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