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

Reply via email to