Changeset: c5fa877c43fa for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/c5fa877c43fa
Modified Files:
        sql/server/rel_optimizer.c
        sql/server/rel_rel.c
        sql/server/rel_rel.h
        sql/server/rel_unnest.c
Branch: default
Log Message:

Use relation inplacement at outer2inner_union, so it will be safe to rewrite 
when the input relation has more than 1 reference


diffs (243 lines):

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
@@ -9839,14 +9839,7 @@ rel_setjoins_2_joingroupby(visitor *v, s
                        list *lexps = rel_projections(v->sql, l, NULL, 1, 1);
                        aexps = list_merge(aexps, lexps, (fdup)NULL);
                        if (rel_is_ref(rel)) {
-                               sql_rel *l = rel_create(v->sql->sa);
-                               if (!l)
-                                       return NULL;
-                               *l = *rel;
-                               /* properly increment the ref counts */
-                               rel_dup(rel->l);
-                               rel_dup(rel->r);
-                               l->ref.refcnt = 1;
+                               sql_rel *l = rel_dup_copy(v->sql->sa, rel);
                                rel = rel_inplace_groupby(rel, l, 
list_append(sa_list(v->sql->sa), exp_ref(v->sql, lid)), aexps);
                        } else {
                                rel = rel_groupby(v->sql, rel, 
list_append(sa_list(v->sql->sa), exp_ref(v->sql, lid)));
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
@@ -556,6 +556,55 @@ rel_inplace_groupby(sql_rel *rel, sql_re
        return rel;
 }
 
+/* this function is to be used with the above rel_inplace_* functions */
+sql_rel *
+rel_dup_copy(sql_allocator *sa, sql_rel *rel)
+{
+       sql_rel *nrel = rel_create(sa);
+
+       if (!nrel)
+               return NULL;
+       *nrel = *rel;
+       nrel->ref.refcnt = 1;
+       switch(nrel->op){
+       case op_basetable:
+       case op_ddl:
+               break;
+       case op_table:
+               if ((IS_TABLE_PROD_FUNC(nrel->flag) || nrel->flag == 
TABLE_FROM_RELATION) && nrel->l)
+                       rel_dup(nrel->l);
+               break;
+       case op_join:
+       case op_left:
+       case op_right:
+       case op_full:
+       case op_semi:
+       case op_anti:
+       case op_union:
+       case op_inter:
+       case op_except:
+       case op_insert:
+       case op_update:
+       case op_delete:
+       case op_merge:
+               if (nrel->l)
+                       rel_dup(nrel->l);
+               if (nrel->r)
+                       rel_dup(nrel->r);
+               break;
+       case op_project:
+       case op_groupby:
+       case op_select:
+       case op_topn:
+       case op_sample:
+       case op_truncate:
+               if (nrel->l)
+                       rel_dup(nrel->l);
+               break;
+       }
+       return nrel;
+}
+
 sql_rel *
 rel_setop(sql_allocator *sa, sql_rel *l, sql_rel *r, operator_type setop)
 {
diff --git a/sql/server/rel_rel.h b/sql/server/rel_rel.h
--- a/sql/server/rel_rel.h
+++ b/sql/server/rel_rel.h
@@ -74,6 +74,7 @@ extern sql_rel *rel_inplace_setop(mvc *s
 extern sql_rel *rel_inplace_project(sql_allocator *sa, sql_rel *rel, sql_rel 
*l, list *e);
 extern sql_rel *rel_inplace_select(sql_rel *rel, sql_rel *l, list *exps);
 extern sql_rel *rel_inplace_groupby(sql_rel *rel, sql_rel *l, list 
*groupbyexps, list *exps );
+extern sql_rel *rel_dup_copy(sql_allocator *sa, sql_rel *rel);
 
 extern int rel_convert_types(mvc *sql, sql_rel *ll, sql_rel *rr, sql_exp **L, 
sql_exp **R, int scale_fixing, check_type tpe);
 extern sql_rel *rel_setop(sql_allocator *sa, sql_rel *l, sql_rel *r, 
operator_type setop);
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
@@ -2192,13 +2192,7 @@ aggrs_split_funcs(mvc *sql, sql_rel *rel
                }
                if (!list_empty(projs)) {
                        /* the grouping relation may have more than 1 
reference, a replacement is needed */
-                       sql_rel *l = rel_create(sql->sa);
-                       if (!l)
-                               return NULL;
-                       *l = *rel;
-                       /* increment the refcount of the left relation */
-                       rel_dup(rel->l);
-                       l->ref.refcnt = 1;
+                       sql_rel *l = rel_dup_copy(sql->sa, rel);
                        list *nexps = list_merge(rel_projections(sql, l, NULL, 
1, 1), projs, NULL);
                        rel = rel_inplace_project(sql->sa, rel, l, nexps);
                        rel->card = exps_card(nexps);
@@ -3722,70 +3716,68 @@ rewrite_outer2inner_union(visitor *v, sq
 {
        if (is_outerjoin(rel->op) && !is_rewrite_outer_used(rel->used) && 
!list_empty(rel->exps) && (((/*is_left(rel->op) ||*/ is_full(rel->op)) && 
rel_has_freevar(v->sql,rel->l)) ||
                ((/*is_right(rel->op) ||*/ is_full(rel->op)) && 
rel_has_freevar(v->sql,rel->r)) || exps_have_freevar(v->sql, rel->exps) || 
exps_have_rel_exp(rel->exps))) {
+               /* the join relation may have more than 1 reference, a 
replacement is needed */
+               sql_rel *nr = rel_dup_copy(v->sql->sa, rel);
                sql_exp *f = exp_atom_bool(v->sql->sa, 0);
-               int nrcols = rel->nrcols;
-
-               nrcols = include_tid(rel->l);
-               nrcols += include_tid(rel->r);
-               rel->nrcols = nrcols;
+               int nrcols = nr->nrcols;
+
+               nrcols = include_tid(nr->l);
+               nrcols += include_tid(nr->r);
+               nr->nrcols = nrcols;
                if (is_left(rel->op)) {
-                       sql_rel *prel = rel_project(v->sql->sa, rel, 
rel_projections(v->sql, rel, NULL, 1, 1));
+                       sql_rel *prel = rel_project(v->sql->sa, nr, 
rel_projections(v->sql, nr, NULL, 1, 1));
                        sql_rel *except = rel_setop(v->sql->sa,
-                                       rel_project(v->sql->sa, 
rel_dup(rel->l), rel_projections(v->sql, rel->l, NULL, 1, 1)),
-                                       rel_project(v->sql->sa, rel_dup(prel), 
rel_projections(v->sql, rel->l, NULL, 1, 1)), op_except);
-                       rel_setop_set_exps(v->sql, except, 
rel_projections(v->sql, rel->l, NULL, 1, 1), false);
+                                       rel_project(v->sql->sa, rel_dup(nr->l), 
rel_projections(v->sql, nr->l, NULL, 1, 1)),
+                                       rel_project(v->sql->sa, rel_dup(prel), 
rel_projections(v->sql, nr->l, NULL, 1, 1)), op_except);
+                       rel_setop_set_exps(v->sql, except, 
rel_projections(v->sql, nr->l, NULL, 1, 1), false);
                        set_processed(except);
-                       sql_rel *nrel = rel_crossproduct(v->sql->sa, except, 
rel_dup(rel->r),  op_left);
+                       sql_rel *nrel = rel_crossproduct(v->sql->sa, except, 
rel_dup(nr->r),  op_left);
                        set_processed(nrel);
                        nrel->used |= rewrite_outer_used;
                        rel_join_add_exp(v->sql->sa, nrel, f);
-                       rel->op = op_join;
-                       nrel = rel_setop(v->sql->sa,
-                                       prel,
-                                       rel_project(v->sql->sa, nrel, 
rel_projections(v->sql, nrel, NULL, 1, 1)),
-                                       op_union);
-                       rel_setop_set_exps(v->sql, nrel, 
rel_projections(v->sql, rel, NULL, 1, 1), false);
-                       set_processed(nrel);
+                       nr->op = op_join;
+                       rel = rel_inplace_setop(v->sql, rel,
+                               prel,
+                               rel_project(v->sql->sa, nrel, 
rel_projections(v->sql, nrel, NULL, 1, 1)),
+                               op_union, rel_projections(v->sql, nr, NULL, 1, 
1));
                        v->changes++;
-                       return nrel;
+                       return rel;
                } else if (is_right(rel->op)) {
-                       sql_rel *prel = rel_project(v->sql->sa, rel, 
rel_projections(v->sql, rel, NULL, 1, 1));
+                       sql_rel *prel = rel_project(v->sql->sa, nr, 
rel_projections(v->sql, nr, NULL, 1, 1));
                        sql_rel *except = rel_setop(v->sql->sa,
-                                       rel_project(v->sql->sa, 
rel_dup(rel->r), rel_projections(v->sql, rel->r, NULL, 1, 1)),
-                                       rel_project(v->sql->sa, rel_dup(prel), 
rel_projections(v->sql, rel->r, NULL, 1, 1)), op_except);
-                       rel_setop_set_exps(v->sql, except, 
rel_projections(v->sql, rel->r, NULL, 1, 1), false);
+                                       rel_project(v->sql->sa, rel_dup(nr->r), 
rel_projections(v->sql, nr->r, NULL, 1, 1)),
+                                       rel_project(v->sql->sa, rel_dup(prel), 
rel_projections(v->sql, nr->r, NULL, 1, 1)), op_except);
+                       rel_setop_set_exps(v->sql, except, 
rel_projections(v->sql, nr->r, NULL, 1, 1), false);
                        set_processed(except);
-                       sql_rel *nrel = rel_crossproduct(v->sql->sa, 
rel_dup(rel->l), except, op_right);
+                       sql_rel *nrel = rel_crossproduct(v->sql->sa, 
rel_dup(nr->l), except, op_right);
                        set_processed(nrel);
                        nrel->used |= rewrite_outer_used;
                        rel_join_add_exp(v->sql->sa, nrel, f);
-                       rel->op = op_join;
-                       nrel = rel_setop(v->sql->sa,
-                                       prel,
-                                       rel_project(v->sql->sa, nrel, 
rel_projections(v->sql, nrel, NULL, 1, 1)),
-                                       op_union);
-                       rel_setop_set_exps(v->sql, nrel, 
rel_projections(v->sql, rel, NULL, 1, 1), false);
-                       set_processed(nrel);
+                       nr->op = op_join;
+                       rel = rel_inplace_setop(v->sql, rel,
+                               prel,
+                               rel_project(v->sql->sa, nrel, 
rel_projections(v->sql, nrel, NULL, 1, 1)),
+                               op_union, rel_projections(v->sql, nr, NULL, 1, 
1));
                        v->changes++;
-                       return nrel;
+                       return rel;
                } else if (is_full(rel->op)) {
-                       sql_rel *prel = rel_project(v->sql->sa, rel, 
rel_projections(v->sql, rel, NULL, 1, 1));
+                       sql_rel *prel = rel_project(v->sql->sa, nr, 
rel_projections(v->sql, nr, NULL, 1, 1));
                        sql_rel *except = rel_setop(v->sql->sa,
-                                       rel_project(v->sql->sa, 
rel_dup(rel->l), rel_projections(v->sql, rel->l, NULL, 1, 1)),
-                                       rel_project(v->sql->sa, rel_dup(prel), 
rel_projections(v->sql, rel->l, NULL, 1, 1)), op_except);
-                       rel_setop_set_exps(v->sql, except, 
rel_projections(v->sql, rel->l, NULL, 1, 1), false);
+                                       rel_project(v->sql->sa, rel_dup(nr->l), 
rel_projections(v->sql, nr->l, NULL, 1, 1)),
+                                       rel_project(v->sql->sa, rel_dup(prel), 
rel_projections(v->sql, nr->l, NULL, 1, 1)), op_except);
+                       rel_setop_set_exps(v->sql, except, 
rel_projections(v->sql, nr->l, NULL, 1, 1), false);
                        set_processed(except);
-                       sql_rel *lrel = rel_crossproduct(v->sql->sa, except, 
rel_dup(rel->r),  op_left);
+                       sql_rel *lrel = rel_crossproduct(v->sql->sa, except, 
rel_dup(nr->r),  op_left);
                        set_processed(lrel);
                        lrel->used |= rewrite_outer_used;
                        rel_join_add_exp(v->sql->sa, lrel, f);
 
                        except = rel_setop(v->sql->sa,
-                                       rel_project(v->sql->sa, 
rel_dup(rel->r), rel_projections(v->sql, rel->r, NULL, 1, 1)),
-                                       rel_project(v->sql->sa, rel_dup(prel), 
rel_projections(v->sql, rel->r, NULL, 1, 1)), op_except);
-                       rel_setop_set_exps(v->sql, except, 
rel_projections(v->sql, rel->r, NULL, 1, 1), false);
+                                       rel_project(v->sql->sa, rel_dup(nr->r), 
rel_projections(v->sql, nr->r, NULL, 1, 1)),
+                                       rel_project(v->sql->sa, rel_dup(prel), 
rel_projections(v->sql, nr->r, NULL, 1, 1)), op_except);
+                       rel_setop_set_exps(v->sql, except, 
rel_projections(v->sql, nr->r, NULL, 1, 1), false);
                        set_processed(except);
-                       sql_rel *rrel = rel_crossproduct(v->sql->sa, 
rel_dup(rel->l), except, op_right);
+                       sql_rel *rrel = rel_crossproduct(v->sql->sa, 
rel_dup(nr->l), except, op_right);
                        set_processed(rrel);
                        rrel->used |= rewrite_outer_used;
                        rel_join_add_exp(v->sql->sa, rrel, f);
@@ -3793,17 +3785,17 @@ rewrite_outer2inner_union(visitor *v, sq
                                        rel_project(v->sql->sa, lrel,  
rel_projections(v->sql, lrel, NULL, 1, 1)),
                                        rel_project(v->sql->sa, rrel, 
rel_projections(v->sql, rrel, NULL, 1, 1)),
                                        op_union);
-                       rel_setop_set_exps(v->sql, lrel, 
rel_projections(v->sql, rel, NULL, 1, 1), false);
+                       rel_setop_set_exps(v->sql, lrel, 
rel_projections(v->sql, nr, NULL, 1, 1), false);
                        set_processed(lrel);
-                       rel->op = op_join;
-                       lrel = rel_setop(v->sql->sa,
-                                       rel_project(v->sql->sa, prel,  
rel_projections(v->sql, rel, NULL, 1, 1)),
-                                       rel_project(v->sql->sa, lrel, 
rel_projections(v->sql, lrel, NULL, 1, 1)),
-                                       op_union);
-                       rel_setop_set_exps(v->sql, lrel, 
rel_projections(v->sql, rel, NULL, 1, 1), false);
-                       set_processed(lrel);
+                       nr->op = op_join;
+                       rel = rel_inplace_setop(v->sql, rel,
+                               rel_project(v->sql->sa, prel, 
rel_projections(v->sql, nr, NULL, 1, 1)),
+                               rel_project(v->sql->sa, lrel, 
rel_projections(v->sql, lrel, NULL, 1, 1)),
+                               op_union, rel_projections(v->sql, nr, NULL, 1, 
1));
                        v->changes++;
-                       return lrel;
+                       return rel;
+               } else {
+                       assert(0);
                }
        }
        return rel;
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to