Changeset: 5d46ef638df2 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=5d46ef638df2
Modified Files:
sql/server/rel_unnest.c
sql/test/SQLancer/Tests/sqlancer07.stable.out
sql/test/SQLancer/Tests/sqlancer07.stable.out.int128
Branch: octbugs
Log Message:
rewrite outer-join when we have a outer ref (freevar) or subquery (exp_is_rel)
into union( innerjoin/ except (x, innerjoin)) ..
added expra projection around innerjoin to make sure, unnesting can savely
happen
diffs (146 lines):
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
@@ -898,8 +898,10 @@ push_up_project(mvc *sql, sql_rel *rel,
}
}
/* remove old project */
- rel->r = r->l;
- r->l = NULL;
+ if (r->l) {
+ rel->r = r->l;
+ r->l = NULL;
+ }
rel_destroy(r);
return n;
}
@@ -3122,7 +3124,7 @@ static sql_rel *
rewrite_outer2inner_union(visitor *v, sql_rel *rel)
{
if (is_outerjoin(rel->op) && !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)*/)) {
+ ((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))) {
sql_exp *f = exp_atom_bool(v->sql->sa, 0);
int nrcols = rel->nrcols;
@@ -3130,44 +3132,47 @@ rewrite_outer2inner_union(visitor *v, sq
nrcols += include_tid(rel->r);
rel->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 *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(rel),
rel_projections(v->sql, rel->l, NULL, 1, 1)), op_except);
+ 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));
sql_rel *nrel = rel_crossproduct(v->sql->sa, except,
rel_dup(rel->r), op_left);
rel_join_add_exp(v->sql->sa, nrel, f);
rel->op = op_join;
nrel = rel_setop(v->sql->sa,
- rel_project(v->sql->sa, rel,
rel_projections(v->sql, rel, NULL, 1, 1)),
+ prel,
rel_project(v->sql->sa, nrel,
rel_projections(v->sql, nrel, NULL, 1, 1)),
op_union);
rel_set_exps(nrel, rel_projections(v->sql, rel, NULL,
1, 1));
return nrel;
} 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 *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(rel),
rel_projections(v->sql, rel->r, NULL, 1, 1)), op_except);
+ 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));
sql_rel *nrel = rel_crossproduct(v->sql->sa,
rel_dup(rel->l), except, op_right);
rel_join_add_exp(v->sql->sa, nrel, f);
rel->op = op_join;
nrel = rel_setop(v->sql->sa,
- rel_project(v->sql->sa, rel,
rel_projections(v->sql, rel, NULL, 1, 1)),
+ prel,
rel_project(v->sql->sa, nrel,
rel_projections(v->sql, nrel, NULL, 1, 1)),
op_union);
rel_set_exps(nrel, rel_projections(v->sql, rel, NULL,
1, 1));
return nrel;
} 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 *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(rel),
rel_projections(v->sql, rel->l, NULL, 1, 1)), op_except);
+ 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));
sql_rel *lrel = rel_crossproduct(v->sql->sa, except,
rel_dup(rel->r), op_left);
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(rel),
rel_projections(v->sql, rel->r, NULL, 1, 1)), op_except);
+ 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));
sql_rel *rrel = rel_crossproduct(v->sql->sa,
rel_dup(rel->l), except, op_right);
rel_join_add_exp(v->sql->sa, rrel, f);
@@ -3178,7 +3183,7 @@ rewrite_outer2inner_union(visitor *v, sq
rel_setop_set_exps(v->sql, lrel,
rel_projections(v->sql, rel, NULL, 1, 1));
rel->op = op_join;
lrel = rel_setop(v->sql->sa,
- rel_project(v->sql->sa, rel,
rel_projections(v->sql, rel, NULL, 1, 1)),
+ 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));
@@ -3278,10 +3283,9 @@ rel_unnest(mvc *sql, sql_rel *rel)
rel = rel_visitor_bottomup(&v, rel, &rewrite_aggregates);
rel = rel_exp_visitor_bottomup(&v, rel, &rewrite_rank, false);
+ rel = rel_visitor_bottomup(&v, rel, &rewrite_values);
rel = rel_visitor_bottomup(&v, rel, &rewrite_outer2inner_union);
- rel = rel_visitor_bottomup(&v, rel, &rewrite_values); /* must come
before rewrite_exp_rel */
-
// remove empty project/groupby !
rel = rel_visitor_bottomup(&v, rel, &rewrite_empty_project);
rel = rel_exp_visitor_bottomup(&v, rel, &rewrite_complex, true);
diff --git a/sql/test/SQLancer/Tests/sqlancer07.stable.out
b/sql/test/SQLancer/Tests/sqlancer07.stable.out
--- a/sql/test/SQLancer/Tests/sqlancer07.stable.out
+++ b/sql/test/SQLancer/Tests/sqlancer07.stable.out
@@ -73,7 +73,7 @@ stdout of test 'sqlancer07` in directory
#CREATE TABLE "t1" ("c0" INTERVAL MONTH,"c1" BOOLEAN);
#CREATE TABLE "t2" ("c0" INTERVAL MONTH);
#SELECT CAST(t1.c1 AS INT) FROM t1, t0 RIGHT OUTER JOIN t2 ON ((SELECT
DISTINCT t1.c0 FROM t1, t0 WHERE FALSE)) NOT IN (t0.c0);
-% sys.%4 # table_name
+% .%4 # table_name
% %4 # name
% int # type
% 1 # length
@@ -467,8 +467,8 @@ stdout of test 'sqlancer07` in directory
% 1, 1 # length
[ 1, 2 ]
#SELECT FALSE FROM v3, v0 FULL OUTER JOIN v4 ON sql_max(FALSE, (0.6902854) NOT
IN (0.5854332103580835, CASE WHEN v4.vc0 THEN (SELECT 0.023816515 WHERE TRUE)
END));
-% .%16 # table_name
-% %16 # name
+% .%15 # table_name
+% %15 # name
% boolean # type
% 5 # length
[ false ]
diff --git a/sql/test/SQLancer/Tests/sqlancer07.stable.out.int128
b/sql/test/SQLancer/Tests/sqlancer07.stable.out.int128
--- a/sql/test/SQLancer/Tests/sqlancer07.stable.out.int128
+++ b/sql/test/SQLancer/Tests/sqlancer07.stable.out.int128
@@ -73,7 +73,7 @@ stdout of test 'sqlancer07` in directory
#CREATE TABLE "t1" ("c0" INTERVAL MONTH,"c1" BOOLEAN);
#CREATE TABLE "t2" ("c0" INTERVAL MONTH);
#SELECT CAST(t1.c1 AS INT) FROM t1, t0 RIGHT OUTER JOIN t2 ON ((SELECT
DISTINCT t1.c0 FROM t1, t0 WHERE FALSE)) NOT IN (t0.c0);
-% sys.%4 # table_name
+% .%4 # table_name
% %4 # name
% int # type
% 1 # length
@@ -467,8 +467,8 @@ stdout of test 'sqlancer07` in directory
% 1, 1 # length
[ 1, 2 ]
#SELECT FALSE FROM v3, v0 FULL OUTER JOIN v4 ON sql_max(FALSE, (0.6902854) NOT
IN (0.5854332103580835, CASE WHEN v4.vc0 THEN (SELECT 0.023816515 WHERE TRUE)
END));
-% .%16 # table_name
-% %16 # name
+% .%15 # table_name
+% %15 # name
% boolean # type
% 5 # length
[ false ]
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list