Changeset: 3f33e61182fa for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/3f33e61182fa
Modified Files:
sql/server/rel_optimizer.c
Branch: default
Log Message:
Merged with Jul2021
diffs (truncated from 373 to 300 lines):
diff --git a/sql/server/rel_dump.c b/sql/server/rel_dump.c
--- a/sql/server/rel_dump.c
+++ b/sql/server/rel_dump.c
@@ -2062,7 +2062,7 @@ rel_read(mvc *sql, char *r, int *pos, li
if (!(exps = read_exps(sql, NULL, NULL, NULL, r, pos, '[', 0,
1)))
return NULL;
rel = rel_setop(sql->sa, lrel, rrel, j);
- rel_setop_set_exps(sql, rel, exps);
+ rel_setop_set_exps(sql, rel, exps, false);
if (rel_set_types(sql, rel) < 0)
return sql_error(sql, -1, SQLSTATE(42000) "Setop:
number of expressions don't match\n");
set_processed(rel);
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
@@ -4296,7 +4296,7 @@ rel_push_aggr_down(visitor *v, sql_rel *
}
u = rel_setop(v->sql->sa, ul, ur, op_union);
- rel_setop_set_exps(v->sql, u, rel_projections(v->sql, ul, NULL,
1, 1));
+ rel_setop_set_exps(v->sql, u, rel_projections(v->sql, ul, NULL,
1, 1), false);
set_processed(u);
exps = new_exp_list(v->sql->sa);
@@ -5270,13 +5270,16 @@ rel_push_join_down_outer(visitor *v, sql
}
static int
-rel_is_empty( sql_rel *rel )
-{
- if ((is_join(rel->op) || is_semi(rel->op)) && !list_empty(rel->exps)) {
+rel_is_empty(mvc *sql, sql_rel *rel)
+{
+ if (mvc_highwater(sql))
+ return 0;
+ if ((is_innerjoin(rel->op) || is_left(rel->op) || is_right(rel->op) ||
is_semi(rel->op)) && !list_empty(rel->exps)) {
sql_rel *l = rel->l, *r = rel->r;
sql_exp *je;
- if (rel_is_empty(l) || rel_is_empty(r))
+ if (((is_innerjoin(rel->op) || is_left(rel->op) ||
is_semi(rel->op)) && rel_is_empty(sql, l)) ||
+ ((is_innerjoin(rel->op) || is_right(rel->op)) &&
rel_is_empty(sql, r)))
return 1;
/* check */
if ((je = rel_is_join_on_pkey(rel, true))) {
@@ -5287,12 +5290,13 @@ rel_is_empty( sql_rel *rel )
}
return 0;
}
- if (is_simple_project(rel->op) || is_groupby(rel->op) ||
is_select(rel->op) ||
- is_topn(rel->op) || is_sample(rel->op)) {
+ /* global aggregates always return 1 row */
+ if (is_simple_project(rel->op) || (is_groupby(rel->op) &&
!list_empty(rel->r)) || is_select(rel->op) ||
+ is_topn(rel->op) || is_sample(rel->op) || is_inter(rel->op) ||
is_except(rel->op)) {
if (rel->l)
- return rel_is_empty(rel->l);
- } else if (is_join(rel->op) || is_semi(rel->op) || is_inter(rel->op) ||
is_except(rel->op)) {
- return rel_is_empty(rel->l) && rel_is_empty(rel->r);
+ return rel_is_empty(sql, rel->l);
+ } else if (is_innerjoin(rel->op) && list_empty(rel->exps)) { /*
cartesian product */
+ return rel_is_empty(sql, rel->l) || rel_is_empty(sql, rel->r);
}
return 0;
}
@@ -5301,21 +5305,28 @@ rel_is_empty( sql_rel *rel )
static inline sql_rel *
rel_remove_empty_join(visitor *v, sql_rel *rel)
{
- if (!is_union(rel->op))
+ if (!is_union(rel->op) || rel_is_ref(rel))
return rel;
/* For half empty unions replace by projects */
- sql_rel *l = rel->l, *r = rel->r;
-
- if (rel_is_empty(l)) {
+ if (!rel_is_ref(rel->l) && rel_is_empty(v->sql, rel->l)) {
+ 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;
+ }
+ if (!rel_is_ref(rel->r) && rel_is_empty(v->sql, rel->r)) {
+ 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(l);
- return rel_inplace_project(v->sql->sa, rel, rel_dup(r),
rel->exps);
- } else if (rel_is_empty(r)) {
+ rel_destroy(rel);
v->changes++;
- rel->r = NULL;
- rel_destroy(r);
- return rel_inplace_project(v->sql->sa, rel, rel_dup(l),
rel->exps);
+ return l;
}
return rel;
}
@@ -8703,7 +8714,7 @@ rel_split_outerjoin(visitor *v, sql_rel
add_nulls( v->sql, nr, r);
exps = rel_projections(v->sql, nl, NULL, 1, 1);
nl = rel_setop(v->sql->sa, nl, nr, op_union);
- rel_setop_set_exps(v->sql, nl, exps);
+ rel_setop_set_exps(v->sql, nl, exps, false);
set_processed(nl);
}
if (rel->op == op_right || rel->op == op_full) {
@@ -8722,7 +8733,7 @@ rel_split_outerjoin(visitor *v, sql_rel
(fdup)NULL);
exps = rel_projections(v->sql, nl, NULL, 1, 1);
nl = rel_setop(v->sql->sa, nl, nr, op_union);
- rel_setop_set_exps(v->sql, nl, exps);
+ rel_setop_set_exps(v->sql, nl, exps, false);
set_processed(nl);
}
@@ -9140,7 +9151,7 @@ merge_table_prune_and_unionize(visitor *
if (nrel) {
nrel = rel_setop(v->sql->sa, nrel, next,
op_union);
- rel_setop_set_exps(v->sql, nrel,
rel_projections(v->sql, mt_rel, NULL, 1, 1));
+ rel_setop_set_exps(v->sql, nrel,
rel_projections(v->sql, mt_rel, NULL, 1, 1), true);
set_processed(nrel);
} else {
nrel = next;
@@ -9417,7 +9428,7 @@ static sql_rel*
exp_skip_output_parts(sql_rel *rel)
{
while ((is_topn(rel->op) || is_project(rel->op) || is_sample(rel->op))
&& rel->l) {
- if (is_groupby(rel->op) && list_empty(rel->r))
+ if (is_union(rel->op) || (is_groupby(rel->op) &&
list_empty(rel->r)))
return rel; /* a group-by with no
columns is a plain aggregate and hence always returns one row */
rel = rel->l;
}
@@ -9431,7 +9442,7 @@ exp_is_zero_rows(mvc *sql, sql_rel *rel,
sql_table *t;
node *n;
- if (!rel)
+ if (!rel || mvc_highwater(sql))
return 0;
rel = exp_skip_output_parts(rel);
if (is_select(rel->op) && rel->l) {
@@ -9494,9 +9505,9 @@ statistics, similarly to the merge table
static inline sql_rel *
rel_remove_union_partitions(visitor *v, sql_rel *rel)
{
- if (!is_union(rel->op))
+ if (!is_union(rel->op) || rel_is_ref(rel))
return rel;
- if (exp_is_zero_rows(v->sql, rel->l, NULL)) {
+ if (!rel_is_ref(rel->l) && exp_is_zero_rows(v->sql, rel->l, NULL)) {
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));
@@ -9506,7 +9517,7 @@ rel_remove_union_partitions(visitor *v,
v->changes++;
return r;
}
- if (exp_is_zero_rows(v->sql, rel->r, NULL)) {
+ if (!rel_is_ref(rel->r) && exp_is_zero_rows(v->sql, rel->r, NULL)) {
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));
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
@@ -421,7 +421,7 @@ rel_inplace_setop(mvc *sql, sql_rel *rel
rel->op = setop;
rel->card = CARD_MULTI;
rel->flag = 0;
- rel_setop_set_exps(sql, rel, exps);
+ rel_setop_set_exps(sql, rel, exps, false);
set_processed(rel);
return rel;
}
@@ -514,7 +514,7 @@ rel_setop_check_types(mvc *sql, sql_rel
}
void
-rel_setop_set_exps(mvc *sql, sql_rel *rel, list *exps)
+rel_setop_set_exps(mvc *sql, sql_rel *rel, list *exps, bool keep_props)
{
sql_rel *l = rel->l, *r = rel->r;
list *lexps = l->exps, *rexps = r->exps;
@@ -534,7 +534,8 @@ rel_setop_set_exps(mvc *sql, sql_rel *re
set_has_nil(e);
else
set_has_no_nil(e);
- e->p = NULL; /* remove all the properties on unions */
+ if (!keep_props)
+ e->p = NULL; /* remove all the properties on
unions on the general case */
}
e->card = CARD_MULTI; /* multi cardinality */
}
@@ -1344,7 +1345,7 @@ rel_or(mvc *sql, sql_rel *rel, sql_rel *
rel = rel_setop_check_types(sql, l, r, ls, rs, op_union);
if (!rel)
return NULL;
- rel_setop_set_exps(sql, rel, rel_projections(sql, rel, NULL, 1, 1));
+ rel_setop_set_exps(sql, rel, rel_projections(sql, rel, NULL, 1, 1),
false);
set_processed(rel);
rel->nrcols = list_length(rel->exps);
rel = rel_distinct(rel);
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
@@ -73,7 +73,7 @@ extern sql_rel *rel_inplace_groupby(sql_
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);
extern sql_rel *rel_setop_check_types(mvc *sql, sql_rel *l, sql_rel *r, list
*ls, list *rs, operator_type op);
-extern void rel_setop_set_exps(mvc *sql, sql_rel *rel, list *exps);
+extern void rel_setop_set_exps(mvc *sql, sql_rel *rel, list *exps, bool
keep_props);
extern sql_rel *rel_crossproduct(sql_allocator *sa, sql_rel *l, sql_rel *r,
operator_type join);
/* in case e is an constant and rel is a simple project of only e, free rel */
diff --git a/sql/server/rel_select.c b/sql/server/rel_select.c
--- a/sql/server/rel_select.c
+++ b/sql/server/rel_select.c
@@ -5815,7 +5815,7 @@ rel_setquery_(sql_query *query, sql_rel
rel = rel_setop(sql->sa, l, r, (operator_type)op);
}
if (rel) {
- rel_setop_set_exps(sql, rel, rel_projections(sql, rel, NULL, 0,
1));
+ rel_setop_set_exps(sql, rel, rel_projections(sql, rel, NULL, 0,
1), false);
set_processed(rel);
}
return rel;
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
@@ -2151,7 +2151,7 @@ rewrite_or_exp(visitor *v, sql_rel *rel)
return NULL;
if (!(rel =
rel_setop_check_types(v->sql, l, r, exps_copy(v->sql, exps), exps_copy(v->sql,
exps), op_union)))
return NULL;
- rel_setop_set_exps(v->sql, rel, exps);
+ rel_setop_set_exps(v->sql, rel, exps,
false);
set_processed(rel);
rel = rel_distinct(rel);
if (tids) /* restore TIDs with identity
function references */
@@ -2497,7 +2497,7 @@ rel_union_exps(mvc *sql, sql_exp **l, li
u = sq;
} else {
u = rel_setop(sql->sa, u, sq, op_union);
- rel_setop_set_exps(sql, u, exps);
+ rel_setop_set_exps(sql, u, exps, false);
set_processed(u);
}
exps = rel_projections(sql, sq, NULL, 1/*keep names */, 1);
@@ -3243,7 +3243,7 @@ rewrite_ifthenelse(visitor *v, sql_rel *
set_processed(rsq);
rsq = rel_select(v->sql->sa, rsq, exp_or(v->sql->sa,
list_append(new_exp_list(v->sql->sa), not_cond),
list_append(new_exp_list(v->sql->sa), cond_is_null), 0));
usq = rel_setop(v->sql->sa, lsq, rsq, op_union);
- rel_setop_set_exps(v->sql, usq,
append(sa_list(v->sql->sa), exp_ref(v->sql, e)));
+ rel_setop_set_exps(v->sql, usq,
append(sa_list(v->sql->sa), exp_ref(v->sql, e)), false);
if (single)
set_single(usq);
set_processed(usq);
@@ -3472,7 +3472,7 @@ rewrite_groupings(visitor *v, sql_rel *r
unions = nrel;
else {
unions = rel_setop(v->sql->sa, unions,
nrel, op_union);
- rel_setop_set_exps(v->sql, unions,
rel_projections(v->sql, rel, NULL, 1, 1));
+ rel_setop_set_exps(v->sql, unions,
rel_projections(v->sql, rel, NULL, 1, 1), false);
set_processed(unions);
}
if (!unions)
@@ -3551,7 +3551,7 @@ rewrite_outer2inner_union(visitor *v, sq
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));
+ rel_setop_set_exps(v->sql, except,
rel_projections(v->sql, rel->l, NULL, 1, 1), false);
set_processed(except);
sql_rel *nrel = rel_crossproduct(v->sql->sa, except,
rel_dup(rel->r), op_left);
rel_join_add_exp(v->sql->sa, nrel, f);
@@ -3560,7 +3560,7 @@ rewrite_outer2inner_union(visitor *v, sq
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));
+ rel_setop_set_exps(v->sql, nrel,
rel_projections(v->sql, rel, NULL, 1, 1), false);
set_processed(nrel);
v->changes++;
return nrel;
@@ -3569,7 +3569,7 @@ rewrite_outer2inner_union(visitor *v, sq
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));
+ rel_setop_set_exps(v->sql, except,
rel_projections(v->sql, rel->r, NULL, 1, 1), false);
set_processed(except);
sql_rel *nrel = rel_crossproduct(v->sql->sa,
rel_dup(rel->l), except, op_right);
rel_join_add_exp(v->sql->sa, nrel, f);
@@ -3578,7 +3578,7 @@ rewrite_outer2inner_union(visitor *v, sq
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list