Changeset: da9db530cfe2 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/da9db530cfe2 Branch: Aug2024 Log Message:
merged diffs (truncated from 730 to 300 lines): diff --git a/MonetDB.spec b/MonetDB.spec --- a/MonetDB.spec +++ b/MonetDB.spec @@ -417,6 +417,7 @@ developer. %{_bindir}/arraytest %{_bindir}/bincopydata %{_bindir}/murltest +%{_bindir}/odbcconnect %{_bindir}/odbcsample1 %{_bindir}/sample0 %{_bindir}/sample1 diff --git a/debian/monetdb-client-testing.install b/debian/monetdb-client-testing.install --- a/debian/monetdb-client-testing.install +++ b/debian/monetdb-client-testing.install @@ -5,6 +5,7 @@ debian/tmp/usr/bin/ODBCtester usr/bin debian/tmp/usr/bin/arraytest usr/bin debian/tmp/usr/bin/bincopydata usr/bin debian/tmp/usr/bin/murltest usr/bin +debian/tmp/usr/bin/odbcconnect usr/bin debian/tmp/usr/bin/odbcsample1 usr/bin debian/tmp/usr/bin/sample0 usr/bin debian/tmp/usr/bin/sample1 usr/bin diff --git a/sql/server/rel_optimize_proj.c b/sql/server/rel_optimize_proj.c --- a/sql/server/rel_optimize_proj.c +++ b/sql/server/rel_optimize_proj.c @@ -977,7 +977,7 @@ bind_project_reduce_casts(visitor *v, gl return gp->cnt[op_project] && (flag & project_reduce_casts) ? rel_project_reduce_casts : NULL; } - +#if 0 static sql_rel * exp_skip_output_parts(sql_rel *rel) { @@ -988,6 +988,7 @@ exp_skip_output_parts(sql_rel *rel) } return rel; } +#endif static sql_column * exp_find_column_( sql_rel *rel, sql_exp *exp, int pnr, sql_rel **bt ) @@ -1085,6 +1086,7 @@ rel_is_join_on_pkey(sql_rel *rel, bool p return NULL; } +#if 0 /* return true if the given expression is guaranteed to have no rows */ static int exp_is_zero_rows(visitor *v, sql_rel *rel, sql_rel *sel) @@ -1160,56 +1162,6 @@ exp_is_zero_rows(visitor *v, sql_rel *re return 0; } -/* discard sides of UNION or UNION ALL which cannot produce any rows, as per -statistics, similarly to the merge table optimizer, e.g. - select * from a where x between 1 and 2 union all select * from b where x between 1 and 2 --> select * from b where x between 1 and 2 [assuming a has no rows with 1<=x<=2] -*/ -static inline sql_rel * -rel_remove_union_partitions(visitor *v, sql_rel *rel) -{ - if (!is_union(rel->op) || rel_is_ref(rel)) - return rel; - int left_zero_rows = !rel_is_ref(rel->l) && exp_is_zero_rows(v, rel->l, NULL); - int right_zero_rows = !rel_is_ref(rel->r) && exp_is_zero_rows(v, rel->r, NULL); - - if (left_zero_rows && right_zero_rows) { - /* generate dummy relation */ - list *converted = sa_list(v->sql->sa); - sql_rel *nrel = rel_project_exp(v->sql, exp_atom_bool(v->sql->sa, 1)); - nrel = rel_select(v->sql->sa, nrel, exp_atom_bool(v->sql->sa, 0)); - set_processed(nrel); - - for (node *n = rel->exps->h ; n ; n = n->next) { - sql_exp *e = n->data, *a = exp_atom(v->sql->sa, atom_general(v->sql->sa, exp_subtype(e), NULL, 0)); - exp_prop_alias(v->sql->sa, a, e); - list_append(converted, a); - } - rel_destroy(rel); - v->changes++; - return rel_project(v->sql->sa, nrel, converted); - } else if (left_zero_rows) { - sql_rel *r = rel->r; - if (!is_project(r->op)) - r = rel_project(v->sql->sa, r, rel_projections(v->sql, r, NULL, 1, 1)); - rel_rename_exps(v->sql, rel->exps, r->exps); - rel->r = NULL; - rel_destroy(rel); - v->changes++; - return r; - } else if (right_zero_rows) { - sql_rel *l = rel->l; - if (!is_project(l->op)) - l = rel_project(v->sql->sa, l, rel_projections(v->sql, l, NULL, 1, 1)); - rel_rename_exps(v->sql, rel->exps, l->exps); - rel->l = NULL; - rel_destroy(rel); - v->changes++; - return l; - } - return rel; -} - static int rel_match_projections(sql_rel *l, sql_rel *r) { @@ -1227,6 +1179,7 @@ rel_match_projections(sql_rel *l, sql_re return 0; return 1; } +#endif static int exps_has_predicate( list *l ) @@ -1252,55 +1205,6 @@ rel_find_select( sql_rel *r) return NULL; } -static inline sql_rel * -rel_merge_union(visitor *v, sql_rel *rel) -{ - sql_rel *l = rel->l; - sql_rel *r = rel->r; - sql_rel *ref = NULL; - - if (is_union(rel->op) && - l && is_project(l->op) && !project_unsafe(l,0) && - r && is_project(r->op) && !project_unsafe(r,0) && - (ref = rel_find_ref(l)) != NULL && ref == rel_find_ref(r)) { - /* Find selects and try to merge */ - sql_rel *ls = rel_find_select(l); - sql_rel *rs = rel_find_select(r); - - /* can we merge ? */ - if (!ls || !rs) - return rel; - - /* merge any extra projects */ - if (l->l != ls) - rel->l = l = rel_merge_projects_(v, l); - if (r->l != rs) - rel->r = r = rel_merge_projects_(v, r); - - if (!rel_match_projections(l,r)) - return rel; - - /* for now only union(project*(select(R),project*(select(R))) */ - if (ls != l->l || rs != r->l || - ls->l != rs->l || !rel_is_ref(ls->l)) - return rel; - - if (!ls->exps || !rs->exps || - exps_has_predicate(ls->exps) || - exps_has_predicate(rs->exps)) - return rel; - - /* merge, ie. add 'or exp' */ - v->changes++; - ls->exps = append(new_exp_list(v->sql->sa), exp_or(v->sql->sa, ls->exps, rs->exps, 0)); - rs->exps = NULL; - rel = rel_inplace_project(v->sql->sa, rel, rel_dup(rel->l), rel->exps); - set_processed(rel); - return rel; - } - return rel; -} - static bool rels_share_rel(list *l) { @@ -1323,10 +1227,6 @@ rel_merge_munion(visitor *v, sql_rel *re if (is_munion(rel->op) && rels_share_rel(rel->l)) { list *rels = rel->l, *nrels = NULL; sql_rel *cur = NULL, *curs = NULL; - /* - l && is_project(l->op) && !project_unsafe(l,0) && - r && is_project(r->op) && !project_unsafe(r,0) && - */ /* Find selects and try to merge */ for(node *n = rels->h; n; n = n->next) { @@ -1372,26 +1272,9 @@ rel_merge_munion(visitor *v, sql_rel *re return rel; } - -static sql_rel * -rel_optimize_unions_bottomup_(visitor *v, sql_rel *rel) -{ - rel = rel_remove_union_partitions(v, rel); - rel = rel_merge_union(v, rel); - return rel; -} - -static sql_rel * -rel_optimize_unions_bottomup(visitor *v, global_props *gp, sql_rel *rel) -{ - (void) gp; - return rel_visitor_bottomup(v, rel, &rel_optimize_unions_bottomup_); -} - static sql_rel * rel_optimize_munions_bottomup_(visitor *v, sql_rel *rel) { - // TODO: implement rel_remove_munion_partitions rel = rel_merge_munion(v, rel); return rel; } @@ -1409,8 +1292,6 @@ bind_optimize_unions_bottomup(visitor *v int flag = v->sql->sql_optimizer; return gp->opt_level == 1 && gp->cnt[op_munion] && (flag & optimize_unions_bottomup) ? rel_optimize_munions_bottomup : NULL; - // TODO: remove the next return - return rel_optimize_unions_bottomup; } @@ -3313,126 +3194,75 @@ rel_push_project_down_union(visitor *v, int need_distinct = need_distinct(rel); sql_rel *u = rel->l; sql_rel *p = rel; - sql_rel *ul = u->l; - sql_rel *ur = u->r; if (!u || !(is_union(u->op) || is_munion(u->op)) || need_distinct(u) || !u->exps || rel_is_ref(u) || project_unsafe(rel,0)) return rel; - // TODO: for now we have to differentiate between union and munion - if (is_union(u->op)) { - /* don't push project down union of single values */ - if ((is_project(ul->op) && !ul->l) || (is_project(ur->op) && !ur->l)) + sql_rel *r; + + /* don't push project down union of single values */ + for (node *n = ((list*)u->l)->h; n; n = n->next) { + r = n->data; + // TODO: does this check make sense? + if (is_project(r->op) && !r->l) return rel; - - ul = rel_dup(ul); - ur = rel_dup(ur); - - if (!is_project(ul->op)) - ul = rel_project(v->sql->sa, ul, - rel_projections(v->sql, ul, NULL, 1, 1)); - if (!is_project(ur->op)) - ur = rel_project(v->sql->sa, ur, - rel_projections(v->sql, ur, NULL, 1, 1)); - need_distinct = (need_distinct && - (!exps_unique(v->sql, ul, ul->exps) || have_nil(ul->exps) || - !exps_unique(v->sql, ur, ur->exps) || have_nil(ur->exps))); - rel_rename_exps(v->sql, u->exps, ul->exps); - rel_rename_exps(v->sql, u->exps, ur->exps); - - /* introduce projects under the set */ - ul = rel_project(v->sql->sa, ul, NULL); - if (need_distinct) - set_distinct(ul); - ur = rel_project(v->sql->sa, ur, NULL); - if (need_distinct) - set_distinct(ur); - - ul->exps = exps_copy(v->sql, p->exps); - set_processed(ul); - ur->exps = exps_copy(v->sql, p->exps); - set_processed(ur); - - rel = rel_inplace_setop(v->sql, rel, ul, ur, op_union, - rel_projections(v->sql, rel, NULL, 1, 1)); + } + + for (node *n = ((list*)u->l)->h; n; n = n->next) { + r = rel_dup(n->data); + + /* introduce projection around each operand if needed */ + if (!is_project(r->op)) + r = rel_project(v->sql->sa, r, + rel_projections(v->sql, r, NULL, 1, 1)); + /* check if we need distinct */ + need_distinct &= + (!exps_unique(v->sql, r, r->exps) || have_nil(r->exps)); + rel_rename_exps(v->sql, u->exps, r->exps); + + rel_destroy(n->data); + n->data = r; + } + + /* once we have checked for need_distinct in every rel we can + * introduce the projects under the munion which are gonna be + * copies of the single project above munion */ + for (node *n = ((list*)u->l)->h; n; n = n->next) { + r = rel_dup(n->data); + + r = rel_project(v->sql->sa, r, NULL); if (need_distinct) - set_distinct(rel); - if (is_single(u)) - set_single(rel); _______________________________________________ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org