Changeset: 42daf1d9f892 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=42daf1d9f892
Modified Files:
sql/server/rel_exp.c
sql/server/rel_exp.h
sql/server/rel_optimizer.c
sql/server/rel_select.c
sql/test/BugTracker-2012/Tests/scalar_subquery_with_alias.Bug-3093.stable.out
sql/test/BugTracker-2013/Tests/correlated_select.Bug-3250.stable.out
sql/test/BugTracker-2013/Tests/correlated_subquery.Bug-3317.stable.out
sql/test/BugTracker-2013/Tests/syntaxerror.Bug-3399.stable.err
sql/test/BugTracker-2013/Tests/syntaxerror.Bug-3399.stable.out
sql/test/BugTracker-2014/Tests/order_by_incorrect_error.Bug-3630.stable.err
sql/test/BugTracker-2014/Tests/order_by_incorrect_error.Bug-3630.stable.out
Branch: subquery
Log Message:
push more join expressions down
cleanup some more code
approved some more tests
diffs (truncated from 416 to 300 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
@@ -1201,6 +1201,20 @@ rel_has_exps(sql_rel *rel, list *exps)
return -1;
}
+int
+rel_has_all_exps(sql_rel *rel, list *exps)
+{
+ node *n;
+
+ if (!exps)
+ return -1;
+ for (n = exps->h; n; n = n->next)
+ if (rel_has_exp(rel, n->data) < 0)
+ return 0;
+ return 1;
+}
+
+
sql_rel *
find_rel(list *rels, 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
@@ -136,6 +136,8 @@ extern int exp_has_sideeffect(sql_exp *e
extern int rel_has_exp(sql_rel *rel, sql_exp *e);
/* return 0 when the relation contain atleast one of the passed expressions
else < 0 */
extern int rel_has_exps(sql_rel *rel, list *e);
+/* return 1 when the relation contains all of the passed expressions else 0 */
+extern int rel_has_all_exps(sql_rel *rel, list *e);
extern sql_rel *find_rel(list *rels, sql_exp *e);
extern sql_rel *find_one_rel(list *rels, sql_exp *e);
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
@@ -4720,6 +4720,69 @@ rel_uses_part_nr( sql_rel *rel, sql_exp
return 0;
}
+static int
+rel_has_cmp_exp(sql_rel *rel, sql_exp *e)
+{
+ if (get_cmp(e) == cmp_or) {
+ return rel_has_exp(rel, e->l) == 0 &&
+ rel_has_all_exps(rel, e->r);
+ } else if (e->flag == cmp_in || e->flag == cmp_notin || get_cmp(e) ==
cmp_filter) {
+ return rel_has_all_exps(rel, e->l) &&
+ rel_has_all_exps(rel, e->r);
+ } else {
+ return rel_has_exp(rel, e->l) == 0 &&
+ rel_has_exp(rel, e->r) == 0 &&
+ (!e->f || rel_has_exp(rel, e->f) == 0);
+ }
+ return 0;
+}
+
+static sql_rel *
+rel_join_push_exps_down(int *changes, mvc *sql, sql_rel *rel)
+{
+ if ((is_join(rel->op) && !is_outerjoin(rel->op)) || is_semi(rel->op)) {
+ sql_rel *l = rel->l, *r = rel->r;
+ list *jexps = NULL, *lexps = NULL, *rexps = NULL;
+ node *n;
+
+ if (list_empty(rel->exps))
+ return rel;
+
+ for(n=rel->exps->h; n; n=n->next) {
+ sql_exp *e = n->data;
+ int le = rel_has_cmp_exp(l, e);
+ int re = rel_has_cmp_exp(r, e);
+
+ if (le && !re) {
+ if (!lexps)
+ lexps=sa_list(sql->sa);
+ append(lexps, e);
+ } else if (!le && re) {
+ if (!rexps)
+ rexps=sa_list(sql->sa);
+ append(rexps, e);
+ } else {
+ if (!jexps)
+ jexps=sa_list(sql->sa);
+ append(jexps, e);
+ }
+ }
+ if (lexps || rexps)
+ rel->exps = jexps;
+ if (lexps) {
+ l = rel->l = rel_select(sql->sa, rel->l, NULL);
+ l->exps = lexps;
+ (*changes) = 1;
+ }
+ if (rexps) {
+ r = rel->r = rel_select(sql->sa, rel->r, NULL);
+ r->exps = rexps;
+ (*changes) = 1;
+ }
+ }
+ return rel;
+}
+
/*
* Push (semi)joins down unions, this is basically for merge tables, where
* we know that the fk-indices are split over two clustered merge tables.
@@ -9697,6 +9760,9 @@ optimize_rel(mvc *sql, sql_rel *rel, int
rel = rewrite(sql, rel, &rel_push_join_down_union, &changes);
/* rel_join_order may introduce empty selects */
rel = rewrite(sql, rel, &rel_remove_empty_select, &e_changes);
+
+ if (level <= 0)
+ rel = rewrite(sql, rel, &rel_join_push_exps_down,
&changes);
}
if (gp.cnt[op_join] || gp.cnt[op_left] || gp.cnt[op_right] ||
gp.cnt[op_full]) {
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
@@ -1621,20 +1621,6 @@ rel_filter_exp_(mvc *sql, sql_rel *rel,
return rel_filter(sql, rel, l, r, "sys", filter_op, anti);
}
-static int
-exp_is_subquery( mvc *sql, sql_exp *e)
-{
- if (e->type == e_column) {
- if (e->card == CARD_ATOM) /* free variable? */
- return 1;
- if (mvc_find_subquery(sql, e->l?e->l:e->r, e->r))
- return 1;
- }
- if (e->type == e_convert)
- return exp_is_subquery( sql, e->l);
- return 0;
-}
-
static sql_rel *
rel_compare_exp_(sql_query *query, sql_rel *rel, sql_exp *ls, sql_exp *rs,
sql_exp *rs2, int type, int anti, int quantifier)
{
@@ -1693,8 +1679,8 @@ rel_compare_exp_(sql_query *query, sql_r
else
return sql_error(sql, 02, SQLSTATE(42000) "SELECT:
cannot use non GROUP BY column in query results without an aggregate function");
}
- if (rs->card <= CARD_ATOM && (exp_is_atom(rs) || exp_has_freevar(rs))
&&
- (!rs2 || (rs2->card <= CARD_ATOM && (exp_is_atom(rs2) ||
exp_is_subquery(sql, rs2))))) {
+ if (rs->card <= CARD_ATOM && (exp_is_atom(rs) || exp_has_freevar(rs)) &&
+ (!rs2 || (rs2->card <= CARD_ATOM && (exp_is_atom(rs2) ||
exp_has_freevar(rs2))))) {
if ((ls->card == rs->card && !rs2) || rel->processed) /* bin
compare op */
return rel_select(sql->sa, rel, e);
@@ -4015,8 +4001,14 @@ static sql_exp *
return e;
}
#endif
- if (!(groupby = rel_bind_groupby(sql, rel)))
- return NULL;
+ if (!(groupby = rel_bind_groupby(sql, rel))) {
+ char *uaname = GDKmalloc(strlen(aname) + 1);
+ sql_exp *e = sql_error(sql, 02, SQLSTATE(42000) "%s: missing
group by",
+ uaname ? toUpperCopy(uaname,
aname) : aname);
+ if (uaname)
+ GDKfree(uaname);
+ return e;
+ }
if (!args->data.sym) { /* count(*) case */
sql_exp *e;
@@ -4854,7 +4846,7 @@ simple_selection(symbol *sq)
sn = (SelectNode *) sq;
- if (!sn->from && !sn->where && !sn->distinct)
+ if (!sn->from && !sn->where && !sn->distinct &&
dlist_length(sn->selection) == 1)
return sn->selection;
}
return NULL;
diff --git
a/sql/test/BugTracker-2012/Tests/scalar_subquery_with_alias.Bug-3093.stable.out
b/sql/test/BugTracker-2012/Tests/scalar_subquery_with_alias.Bug-3093.stable.out
---
a/sql/test/BugTracker-2012/Tests/scalar_subquery_with_alias.Bug-3093.stable.out
+++
b/sql/test/BugTracker-2012/Tests/scalar_subquery_with_alias.Bug-3093.stable.out
@@ -57,7 +57,7 @@ Ready.
# ) AS c2
# FROM test1 a
#;
-% .L6, .L17 # table_name
+% .L6, .L14 # table_name
% c1, c2 # name
% bigint, bigint # type
% 1, 1 # length
@@ -70,8 +70,8 @@ Ready.
# )
# FROM test1 a
#;
-% .L5, .L15 # table_name
-% cnt1, L15 # name
+% .L5, .L12 # table_name
+% cnt1, cnt2 # name
% bigint, bigint # type
% 1, 1 # length
#SELECT (SELECT COUNT(id) AS cnt1
@@ -83,7 +83,7 @@ Ready.
# ) AS c2
# FROM test1 a
#;
-% .L5, .L16 # table_name
+% .L5, .L13 # table_name
% cnt1, c2 # name
% bigint, bigint # type
% 1, 1 # length
@@ -96,7 +96,7 @@ Ready.
# ) AS c1
# FROM test1 a
#;
-% .L10, sys.L16 # table_name
+% .L6, .L14 # table_name
% c2, c1 # name
% bigint, bigint # type
% 1, 1 # length
@@ -109,7 +109,7 @@ Ready.
# ) AS c2
# FROM test1 a
#;
-% .L6, .L17 # table_name
+% .L6, .L14 # table_name
% c1, c2 # name
% bigint, bigint # type
% 1, 1 # length
@@ -130,13 +130,13 @@ Ready.
# ) AS c2
# FROM test1 a
#;
-% .L6, .L17 # table_name
+% .L6, .L14 # table_name
% c1, c2 # name
% bigint, bigint # type
% 1, 1 # length
-[ 3, 1 ]
[ 3, 0 ]
[ 3, 0 ]
+[ 3, 1 ]
#SELECT (SELECT COUNT(id) AS cnt1
# FROM test1
# )
@@ -146,13 +146,13 @@ Ready.
# )
# FROM test1 a
#;
-% .L5, .L15 # table_name
-% cnt1, L15 # name
+% .L5, .L12 # table_name
+% cnt1, cnt2 # name
% bigint, bigint # type
% 1, 1 # length
-[ 3, 1 ]
[ 3, 0 ]
[ 3, 0 ]
+[ 3, 1 ]
#SELECT (SELECT COUNT(id) AS cnt1
# FROM test1
# )
@@ -162,13 +162,13 @@ Ready.
# ) AS c2
# FROM test1 a
#;
-% .L5, .L16 # table_name
+% .L5, .L13 # table_name
% cnt1, c2 # name
% bigint, bigint # type
% 1, 1 # length
-[ 3, 1 ]
[ 3, 0 ]
[ 3, 0 ]
+[ 3, 1 ]
#SELECT (SELECT COUNT(b.id) AS cnt2
# FROM test2 b
# WHERE a.id = b.id
@@ -178,13 +178,13 @@ Ready.
# ) AS c1
# FROM test1 a
#;
-% .L10, sys.L16 # table_name
+% .L6, .L14 # table_name
% c2, c1 # name
% bigint, bigint # type
% 1, 1 # length
-[ 1, 3 ]
[ 0, 3 ]
[ 0, 3 ]
+[ 1, 3 ]
#SELECT (SELECT COUNT(id) AS cnt1
# FROM test1
# ) AS c1
@@ -194,13 +194,13 @@ Ready.
# ) AS c2
# FROM test1 a
#;
-% .L6, .L17 # table_name
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list