Changeset: ce3dc71b7633 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=ce3dc71b7633
Modified Files:
        sql/server/rel_exp.c
        sql/server/rel_exp.h
        sql/server/rel_optimizer.c
Branch: Jun2020
Log Message:

merged


diffs (160 lines):

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
@@ -1525,7 +1525,7 @@ exp_is_eqjoin(sql_exp *e)
 }
 
 static sql_exp *
-rel_find_exp_( sql_rel *rel, sql_exp *e) 
+rel_find_exp_and_corresponding_rel_( sql_rel *rel, sql_exp *e, sql_rel **res) 
 {
        sql_exp *ne = NULL;
 
@@ -1540,9 +1540,11 @@ rel_find_exp_( sql_rel *rel, sql_exp *e)
                                ne = exps_bind_column(rel->exps, e->r, NULL, 1);
                        }
                }
+               if (ne && res)
+                       *res = rel;
                return ne;
        case e_convert:
-               return rel_find_exp_(rel, e->l);
+               return rel_find_exp_and_corresponding_rel_(rel, e->l, res);
        case e_aggr:
        case e_func: 
                if (e->l) {
@@ -1551,7 +1553,7 @@ rel_find_exp_( sql_rel *rel, sql_exp *e)
        
                        ne = n->data;
                        while (ne != NULL && n != NULL) {
-                               ne = rel_find_exp_(rel, n->data);
+                               ne = rel_find_exp_and_corresponding_rel_(rel, 
n->data, res);
                                n = n->next;
                        }
                        return ne;
@@ -1568,7 +1570,7 @@ rel_find_exp_( sql_rel *rel, sql_exp *e)
        
                        ne = n->data;
                        while (ne != NULL && n != NULL) {
-                               ne = rel_find_exp_(rel, n->data);
+                               ne = rel_find_exp_and_corresponding_rel_(rel, 
n->data, res);
                                n = n->next;
                        }
                        return ne;
@@ -1579,9 +1581,9 @@ rel_find_exp_( sql_rel *rel, sql_exp *e)
 }
 
 sql_exp *
-rel_find_exp( sql_rel *rel, sql_exp *e)
+rel_find_exp_and_corresponding_rel(sql_rel *rel, sql_exp *e, sql_rel **res)
 {
-       sql_exp *ne = rel_find_exp_(rel, e);
+       sql_exp *ne = rel_find_exp_and_corresponding_rel_(rel, e, res);
 
        if (rel && !ne) {
                switch(rel->op) {
@@ -1589,38 +1591,53 @@ rel_find_exp( sql_rel *rel, sql_exp *e)
                case op_right:
                case op_full:
                case op_join:
-                       ne = rel_find_exp(rel->l, e);
+                       ne = rel_find_exp_and_corresponding_rel(rel->l, e, res);
                        if (!ne) 
-                               ne = rel_find_exp(rel->r, e);
+                               ne = rel_find_exp_and_corresponding_rel(rel->r, 
e, res);
                        break;
                case op_table:
                        if (rel->exps && e->type == e_column && e->l && 
exps_bind_column2(rel->exps, e->l, e->r)) 
                                ne = e;
+                       if (ne && res)
+                               *res = rel;
                        break;
                case op_union:
                case op_except:
                case op_inter:
                {
                        if (rel->l)
-                               ne = rel_find_exp(rel->l, e);
-                       else if (rel->exps && e->l)
+                               ne = rel_find_exp_and_corresponding_rel(rel->l, 
e, res);
+                       else if (rel->exps && e->l) {
                                ne = exps_bind_column2(rel->exps, e->l, e->r);
-                       else if (rel->exps)
+                               if (ne && res)
+                                       *res = rel;
+                       } else if (rel->exps) {
                                ne = exps_bind_column(rel->exps, e->r, NULL, 1);
+                               if (ne && res)
+                                       *res = rel;
+                       }
                }
                break;
                case op_basetable: 
                        if (rel->exps && e->type == e_column && e->l) 
                                ne = exps_bind_column2(rel->exps, e->l, e->r);
+                       if (ne && res)
+                               *res = rel;
                        break;
                default:
                        if (!is_project(rel->op) && rel->l)
-                               ne = rel_find_exp(rel->l, e);
+                               ne = rel_find_exp_and_corresponding_rel(rel->l, 
e, res);
                }
        }
        return ne;
 }
 
+sql_exp *
+rel_find_exp( sql_rel *rel, sql_exp *e)
+{
+       return rel_find_exp_and_corresponding_rel(rel, e, NULL);
+}
+
 int
 exp_is_true(mvc *sql, 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
@@ -123,6 +123,7 @@ extern unsigned int exp_card(sql_exp *e)
 extern const char *exp_find_rel_name(sql_exp *e);
 
 extern sql_exp *rel_find_exp( sql_rel *rel, sql_exp *e);
+extern sql_exp *rel_find_exp_and_corresponding_rel(sql_rel *rel, sql_exp *e, 
sql_rel **res);
 
 extern int exp_cmp( sql_exp *e1, sql_exp *e2);
 extern int exp_equal( sql_exp *e1, sql_exp *e2);
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
@@ -5454,11 +5454,27 @@ find_simple_projection_for_join2semi(sql
                        return true;
                /* a single group by column in the projection list from a group 
by relation is guaranteed to be unique, but not an aggregate */
                if (e->type == e_column) {
+                       sql_rel *res = NULL;
+                       sql_exp *found = NULL;
+
                        if (is_groupby(rel->op) || find_prop(e->p, 
PROP_HASHCOL))
                                return true;
-                       sql_exp *found = rel_find_exp(rel->l, e); /* grouping 
column on inner relation */
-                       if (found && ((found->type == e_column && found->card 
<= CARD_AGGR) || find_prop(found->p, PROP_HASHCOL)))
-                               return true;
+
+                       found = rel_find_exp_and_corresponding_rel(rel->l, e, 
&res); /* grouping column on inner relation */
+                       if (found) {
+                               if (find_prop(found->p, PROP_HASHCOL)) /* 
primary key always unique */
+                                       return true;
+                               if (found->type == e_column && found->card <= 
CARD_AGGR) {
+                                       if (!is_groupby(res->op) && 
list_length(res->exps) != 1)
+                                               return false;
+                                       for (node *n = res->exps->h ; n ; n = 
n->next) { /* must be the single column in the group by expression list */
+                                               sql_exp *e = n->data;
+                                               if (e != found && e->type == 
e_column)
+                                                       return false;
+                                       }
+                                       return true;
+                               }
+                       }
                }
        }
        return false;
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to