Changeset: 45cf0d08f2a7 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/45cf0d08f2a7
Modified Files:
sql/server/rel_optimizer.c
sql/test/SQLancer/Tests/sqlancer17.test
Branch: Jan2022
Log Message:
rel_push_topn_and_sample_down optimizer ignoring ordering expressions. Also do
a better check for ordered/grouping list existence
diffs (179 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
@@ -149,7 +149,7 @@ name_find_column( sql_rel *rel, const ch
alias = exps_bind_column2(rel->exps, rname, name, NULL);
else
alias = exps_bind_column(rel->exps, name, NULL, NULL,
1);
- if (is_groupby(rel->op) && alias && alias->type == e_column &&
rel->r) {
+ if (is_groupby(rel->op) && alias && alias->type == e_column &&
!list_empty(rel->r)) {
if (alias->l)
alias = exps_bind_column2(rel->r, alias->l,
alias->r, NULL);
else
@@ -1917,10 +1917,10 @@ rel_push_topn_and_sample_down(visitor *v
return rel;
/* push topn/sample under projections */
- if (!rel_is_ref(rel) && r && is_simple_project(r->op) &&
!need_distinct(r) && !rel_is_ref(r) && r->l && !r->r) {
+ if (!rel_is_ref(rel) && r && is_simple_project(r->op) &&
!need_distinct(r) && !rel_is_ref(r) && r->l && list_empty(r->r)) {
sql_rel *x = r, *px = x;
- while (is_simple_project(x->op) && !need_distinct(x) &&
!rel_is_ref(x) && x->l && !x->r) {
+ while (is_simple_project(x->op) && !need_distinct(x) &&
!rel_is_ref(x) && x->l && list_empty(x->r)) {
px = x;
x = x->l;
}
@@ -1943,7 +1943,7 @@ rel_push_topn_and_sample_down(visitor *v
bool changed = false;
x = ul;
- while (is_simple_project(x->op) && !need_distinct(x) &&
!rel_is_ref(x) && x->l && !x->r)
+ while (is_simple_project(x->op) && !need_distinct(x) &&
!rel_is_ref(x) && x->l && list_empty(x->r))
x = x->l;
if (x && x->op != rel->op) { /* only push topn once */
ul = func(v->sql->sa, ul,
sum_limit_offset(v->sql, rel));
@@ -1952,7 +1952,7 @@ rel_push_topn_and_sample_down(visitor *v
}
x = ur;
- while (is_simple_project(x->op) && !need_distinct(x) &&
!rel_is_ref(x) && x->l && !x->r)
+ while (is_simple_project(x->op) && !need_distinct(x) &&
!rel_is_ref(x) && x->l && list_empty(x->r))
x = x->l;
if (x && x->op != rel->op) { /* only push topn once */
ur = func(v->sql->sa, ur,
sum_limit_offset(v->sql, rel));
@@ -1968,7 +1968,7 @@ rel_push_topn_and_sample_down(visitor *v
/* duplicate topn/sample + [ project-order ] under union */
if (r)
rp = r->l;
- if (r && r->exps && is_simple_project(r->op) && !rel_is_ref(r)
&& r->r && r->l && is_union(rp->op)) {
+ if (r && r->exps && is_simple_project(r->op) && !rel_is_ref(r)
&& !list_empty(r->r) && r->l && is_union(rp->op)) {
sql_rel *u = rp, *ou = u, *x;
sql_rel *ul = u->l;
sql_rel *ur = u->r;
@@ -1977,12 +1977,12 @@ rel_push_topn_and_sample_down(visitor *v
/* only push topn/sample once */
x = ul;
- while (is_simple_project(x->op) && !need_distinct(x) &&
!rel_is_ref(x) && x->l && !x->r)
+ while (is_simple_project(x->op) && !need_distinct(x) &&
!rel_is_ref(x) && x->l && list_empty(x->r))
x = x->l;
if (x && x->op == rel->op)
return rel;
x = ur;
- while (is_simple_project(x->op) && !need_distinct(x) &&
!rel_is_ref(x) && x->l && !x->r)
+ while (is_simple_project(x->op) && !need_distinct(x) &&
!rel_is_ref(x) && x->l && list_empty(x->r))
x = x->l;
if (x && x->op == rel->op)
return rel;
@@ -2119,7 +2119,7 @@ exp_push_down_prj(mvc *sql, sql_exp *e,
return NULL;
}
/* possibly a groupby/project column is renamed */
- if (is_groupby(f->op) && f->r) {
+ if (is_groupby(f->op) && !list_empty(f->r)) {
sql_exp *gbe = NULL;
if (ne->l)
gbe = exps_bind_column2(f->r, ne->l, ne->r,
NULL);
@@ -2753,7 +2753,7 @@ rel_merge_projects(visitor *v, sql_rel *
node *n;
if (rel->op == op_project &&
- prj && prj->op == op_project && !(rel_is_ref(prj)) && !prj->r) {
+ prj && prj->op == op_project && !(rel_is_ref(prj)) &&
list_empty(prj->r)) {
int all = 1;
if (project_unsafe(rel,0) || project_unsafe(prj,0) ||
exps_share_expensive_exp(rel->exps, prj->exps))
@@ -2788,7 +2788,7 @@ rel_merge_projects(visitor *v, sql_rel *
if (all) {
/* we can now remove the intermediate project */
/* push order by expressions */
- if (rel->r) {
+ if (!list_empty(rel->r)) {
list *nr = new_exp_list(v->sql->sa), *res =
rel->r;
for (n = res->h; n; n = n->next) {
sql_exp *e = n->data, *ne = NULL;
@@ -4177,7 +4177,7 @@ rel_push_aggr_down(visitor *v, sql_rel *
}
}
- if (rel->r) {
+ if (!list_empty(rel->r)) {
list *ogbe = rel->r;
gbe = new_exp_list(v->sql->sa);
@@ -5506,7 +5506,7 @@ rel_push_project_down_union(visitor *v,
v->changes++;
}
- if (rel->op == op_project && rel->l && rel->exps && !rel->r) {
+ if (rel->op == op_project && rel->l && rel->exps && list_empty(rel->r))
{
int need_distinct = need_distinct(rel);
sql_rel *u = rel->l;
sql_rel *p = rel;
@@ -7851,7 +7851,7 @@ rel_split_project(visitor *v, sql_rel *r
if (nrel->l && !(nrel->l = rel_split_project(v,
nrel->l, (is_topn(rel->op)||is_sample(rel->op))?top:0)))
return NULL;
return rel;
- } else if (funcs && !top && !rel->r) {
+ } else if (funcs && !top && list_empty(rel->r)) {
/* projects can have columns point back into the
expression list, ie
* create a new list including the split expressions */
node *n;
@@ -7860,7 +7860,7 @@ rel_split_project(visitor *v, sql_rel *r
rel->exps = sa_list(v->sql->sa);
for (n=exps->h; n; n = n->next)
append(rel->exps, split_exp(v->sql, n->data,
rel));
- } else if (funcs && top && rel_is_ref(rel) && !rel->r) {
+ } else if (funcs && top && rel_is_ref(rel) &&
list_empty(rel->r)) {
/* inplace */
list *exps = rel_projections(v->sql, rel, NULL, 1, 1);
sql_rel *l = rel_project(v->sql->sa, rel->l, NULL);
@@ -7969,7 +7969,7 @@ rel_split_select(visitor *v, sql_rel *re
if (nrel->l && !(nrel->l = rel_split_project(v,
nrel->l, (is_topn(rel->op)||is_sample(rel->op))?top:0)))
return NULL;
return rel;
- } else if (funcs && !top && !rel->r) {
+ } else if (funcs && !top && list_empty(rel->r)) {
/* projects can have columns point back into the
expression list, ie
* create a new list including the split expressions */
node *n;
@@ -7978,7 +7978,7 @@ rel_split_select(visitor *v, sql_rel *re
rel->exps = sa_list(v->sql->sa);
for (n=exps->h; n; n = n->next)
append(rel->exps, select_split_exp(v->sql,
n->data, rel));
- } else if (funcs && top && rel_is_ref(rel) && !rel->r) {
+ } else if (funcs && top && rel_is_ref(rel) &&
list_empty(rel->r)) {
/* inplace */
list *exps = rel_projections(v->sql, rel, NULL, 1, 1);
sql_rel *l = rel_project(v->sql->sa, rel->l, NULL);
diff --git a/sql/test/SQLancer/Tests/sqlancer17.test
b/sql/test/SQLancer/Tests/sqlancer17.test
--- a/sql/test/SQLancer/Tests/sqlancer17.test
+++ b/sql/test/SQLancer/Tests/sqlancer17.test
@@ -537,3 +537,27 @@ 1
statement ok
DROP TABLE t3
+
+statement ok
+START TRANSACTION
+
+statement ok
+CREATE TABLE rt0 ("c0" INET, "c1" TINYINT)
+
+statement ok
+CREATE TABLE tz(c1 BLOB)
+
+statement ok
+create or replace view va(vc0) as ((select 4 from tz) union all (select 2 from
rt0))
+
+statement ok
+create or replace view vb(vc0) as (select (select 4 from rt0) from rt0)
+
+statement ok
+create or replace view vx(vc0) as (select 9 = vb.vc0 from vb, rt0, va order by
rt0.c0)
+
+statement ok rowcount 1
+INSERT INTO tz(c1) VALUES(CASE WHEN EXISTS (SELECT DISTINCT 3, vc0 FROM vx
WHERE vc0) THEN BLOB 'AD' END)
+
+statement ok
+ROLLBACK
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list