Changeset: b72b05357cdd for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=b72b05357cdd Modified Files: sql/backends/monet5/rel_bin.c sql/server/rel_exp.c sql/server/rel_exp.h sql/server/rel_optimizer.c sql/server/rel_rel.c sql/server/rel_select.c sql/test/BugTracker-2015/Tests/crash.Bug-3736.stable.out sql/test/BugTracker-2016/Tests/case-column-when-null-Bug-6124.stable.out sql/test/BugTracker-2016/Tests/nested-subquery-in-select.Bug-6125.stable.out sql/test/BugTracker-2016/Tests/select-in-from.Bug-6121.stable.out Branch: Dec2016 Log Message:
fixes for bugs 6124, 6125 and 6121 The apply rename optimizer step has been rewriten. Apply optimizer now create new relational operators (doesn't steal the structures, ie safe against referenced subqueries). diffs (truncated from 1543 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 @@ -1898,8 +1898,10 @@ rel2bin_semijoin( mvc *sql, sql_rel *rel break; s = exp_bin(sql, en->data, left, right, NULL, NULL, NULL, NULL); - if (!s) + if (!s) { + assert(0); return NULL; + } if (join_idx != sql->opt_stats[0]) idx = 1; /* stop on first non equality join */ 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 @@ -631,6 +631,13 @@ exp_label(sql_allocator *sa, sql_exp *e, return e; } +sql_exp* +exp_label_table(sql_allocator *sa, sql_exp *e, int nr) +{ + e->rname = make_label(sa, nr); + return e; +} + void exp_swap( sql_exp *e ) { diff --git a/sql/server/rel_exp.h b/sql/server/rel_exp.h --- a/sql/server/rel_exp.h +++ b/sql/server/rel_exp.h @@ -86,6 +86,7 @@ extern void exp_setrelname(sql_allocator extern void noninternexp_setname(sql_allocator *sa, sql_exp *e, const char *rname, const char *name ); extern char* make_label(sql_allocator *sa, int nr); extern sql_exp* exp_label(sql_allocator *sa, sql_exp *e, int nr); +extern sql_exp* exp_label_table(sql_allocator *sa, sql_exp *e, int nr); extern sql_exp * exp_copy( sql_allocator *sa, sql_exp *e); extern list * exps_copy( sql_allocator *sa, list *exps); 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 @@ -4237,18 +4237,20 @@ rel_push_semijoin_down(int *changes, mvc if (!right && !left) return rel; } - nsexps = rel->exps; - njexps = l->exps; + nsexps = exps_copy(sql->sa, rel->exps); + njexps = exps_copy(sql->sa, l->exps); if (right) - l = rel_crossproduct(sql->sa, ll, r, op); + l = rel_crossproduct(sql->sa, rel_dup(ll), rel_dup(r), op); else - l = rel_crossproduct(sql->sa, lr, r, op); + l = rel_crossproduct(sql->sa, rel_dup(lr), rel_dup(r), op); l->exps = nsexps; if (right) - rel = rel_crossproduct(sql->sa, l, lr, lop); + l = rel_crossproduct(sql->sa, l, rel_dup(lr), lop); else - rel = rel_crossproduct(sql->sa, l, ll, lop); - rel->exps = njexps; + l = rel_crossproduct(sql->sa, l, rel_dup(ll), lop); + l->exps = njexps; + rel_destroy(rel); + rel = l; } return rel; } @@ -5908,34 +5910,46 @@ rel_remove_unused(mvc *sql, sql_rel *rel return rel; } -static void -rel_dce_refs(mvc *sql, sql_rel *rel, list *refs) -{ +static list * +merge_refs(list *l, list *r) +{ + node *n, *m, *np = l->h, *mp = r->h; + list *nl = sa_list(l->sa); + + for( n = np; n; n = n->next) { + sql_rel *lr = n->data; + for (m = mp; m; m = m->next) { + sql_rel *rr = m->data; + + if (lr == rr) { + for( ; np != n; np = np->next) + append(nl, np->data); + np = np->next; + for( ; mp != m; mp = mp->next) + append(nl, mp->data); + append(nl, mp->data); + mp = mp->next; + break; + } + } + } + for( ; np; np = np->next) + append(nl, np->data); + for( ; mp; mp = mp->next) + append(nl, mp->data); + return nl; +} + +static list * +rel_dce_refs(mvc *sql, sql_rel *rel) +{ + list *l = NULL, *r = NULL; + if (!rel) - return ; - - if (rel_is_ref(rel)) { - if (!list_find(refs, rel, NULL)) - list_append(refs, rel); - } + return NULL; switch(rel->op) { - case op_basetable: case op_table: - - if (rel->l && rel->op == op_table) - rel_dce_refs(sql, rel->l, refs); - case op_insert: - case op_ddl: - break; - - case op_update: - case op_delete: - - if (rel->r) - rel_dce_refs(sql, rel->r, refs); - break; - case op_topn: case op_sample: case op_project: @@ -5943,9 +5957,21 @@ rel_dce_refs(mvc *sql, sql_rel *rel, lis case op_select: if (rel->l) - rel_dce_refs(sql, rel->l, refs); + l = rel_dce_refs(sql, rel->l); + + case op_basetable: + case op_insert: + case op_ddl: break; + case op_update: + case op_delete: + + if (rel->r) + r = rel_dce_refs(sql, rel->r); + break; + + case op_union: case op_inter: case op_except: @@ -5957,14 +5983,25 @@ rel_dce_refs(mvc *sql, sql_rel *rel, lis case op_anti: if (rel->l) - rel_dce_refs(sql, rel->l, refs); + l = rel_dce_refs(sql, rel->l); if (rel->r) - rel_dce_refs(sql, rel->r, refs); + r = rel_dce_refs(sql, rel->r); break; case op_apply: assert(0); } + + if (l && r) + l = merge_refs(l, r); + if (!l) + l = r; + if (rel_is_ref(rel)) { + if (!l) + l = sa_list(sql->sa); + list_prepend(l, rel); + } + return l; } static sql_rel * @@ -6142,16 +6179,17 @@ rel_add_projects(mvc *sql, sql_rel *rel) sql_rel * rel_dce(mvc *sql, sql_rel *rel) { - list *refs = sa_list(sql->sa); + list *refs; node *n; - rel_dce_refs(sql, rel, refs); + refs = rel_dce_refs(sql, rel); rel = rel_add_projects(sql, rel); rel_used(rel); rel_dce_sub(sql, rel, refs); - for (n = refs->h; n; n = n->next) - rel_dce_sub(sql, n->data, refs); + if (refs) + for (n = refs->h; n; n = n->next) + rel_dce_sub(sql, n->data, refs); return rel; } @@ -7736,9 +7774,9 @@ exps_uses_exps(list *users, list *exps) static int rel_uses_exps(sql_rel *rel, list *exps ) { - if (!exps || !rel || !rel->l) + if (!exps || !rel) return 0; - if (rel->exps && exps_uses_exps(rel->exps, exps)) + if (rel->op == op_project && !rel->l && rel->exps && exps_uses_exps(rel->exps, exps)) return 1; switch(rel->op) { case op_basetable: @@ -7777,11 +7815,10 @@ rel_uses_exps(sql_rel *rel, list *exps ) return 0; } -/* exp_rename_up */ -static sql_exp * exp_rename_up(mvc *sql, sql_exp *e, list *aliases); +static sql_exp * exp_apply_rename(mvc *sql, sql_exp *e, list *aliases, int always); static list * -exps_rename_up(mvc *sql, list *l, list *aliases) +exps_apply_rename(mvc *sql, list *l, list *aliases, int always) { node *n; list *nl = new_exp_list(sql->sa); @@ -7791,33 +7828,34 @@ exps_rename_up(mvc *sql, list *l, list * for(n=l->h; n; n=n->next) { sql_exp *arg = n->data, *narg; - narg = exp_rename_up(sql, arg, aliases); + narg = exp_apply_rename(sql, arg, aliases, always); if (!narg) - return NULL; + narg = arg; narg->flag = arg->flag; append(nl, narg); } return nl; } -/* exp_rename_up, rename an expression to use an alias */ static sql_exp * -exp_rename_up(mvc *sql, sql_exp *e, list *aliases) -{ - sql_exp *ne = NULL, *l, *r, *r2; +exp_apply_rename(mvc *sql, sql_exp *e, list *aliases, int setname) +{ + sql_exp *ne = NULL, *l; switch(e->type) { case e_column: ne = exps_bind_alias(aliases, e->l, e->r); - if (ne) - ne = exp_column(sql->sa, exp_relname(ne), exp_name(ne), exp_subtype(ne), ne->card, has_nil(ne), is_intern(ne)); - else - return e; + if (ne && ne->used && !setname) { + ne = exp_column(sql->sa, exp_relname(ne), exp_name(ne), exp_subtype(e), e->card, has_nil(e), is_intern(e)); + if (e && e->rname && e->rname[0] == 'L') + exp_setname(sql->sa, ne, e->rname, e->name); + } else if (ne && !ne->used) + ne = NULL; break; case e_cmp: if (e->flag == cmp_or || get_cmp(e) == cmp_filter) { - list *l = exps_rename_up(sql, e->l, aliases); - list *r = exps_rename_up(sql, e->r, aliases); + list *l = exps_apply_rename(sql, e->l, aliases, setname); + list *r = exps_apply_rename(sql, e->r, aliases, setname); if (l && r) { if (get_cmp(e) == cmp_filter) ne = exp_filter(sql->sa, l, r, e->f, is_anti(e)); @@ -7825,15 +7863,25 @@ exp_rename_up(mvc *sql, sql_exp *e, list ne = exp_or(sql->sa, l,r); } } else if (e->flag == cmp_in || e->flag == cmp_notin) { - sql_exp *l = exp_rename_up(sql, e->l, aliases); - list *r = exps_rename_up(sql, e->r, aliases); + sql_exp *l = exp_apply_rename(sql, e->l, aliases, setname); + list *r = exps_apply_rename(sql, e->r, aliases, setname); + _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list