Changeset: 70dc41c10f28 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=70dc41c10f28
Modified Files:
sql/server/rel_select.c
sql/server/rel_unnest.c
sql/test/BugTracker-2015/Tests/crash.Bug-3736.stable.out
sql/test/subquery/Tests/subquery3.stable.out
Branch: default
Log Message:
fixed one more subquery problem (limit general unnest)
diffs (truncated from 309 to 300 lines):
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
@@ -3070,7 +3070,7 @@ rel_binop(sql_query *query, sql_rel **re
if (!l || !r)
return NULL;
- if (rel_check_card(*rel, l, r))
+ if (0 && rel_check_card(*rel, l, r))
return NULL;
return rel_binop_(sql, rel ? *rel : NULL, l, r, s, fname, ek.card);
}
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
@@ -562,6 +562,77 @@ rel_bound_exp(mvc *sql, sql_rel *rel )
return NULL;
}
+/*
+ * join j was just rewriten, but some join expressions may now
+ * be too low in de relation rel. These need to move up.
+ * */
+static void
+move_join_exps(mvc *sql, sql_rel *j, sql_rel *rel)
+{
+ node *n;
+ list *exps = rel->exps;
+
+ if (!exps)
+ return;
+ rel->exps = sa_list(sql->sa);
+ if (!j->exps)
+ j->exps = sa_list(sql->sa);
+ for(n = exps->h; n; n = n->next){
+ sql_exp *e = n->data;
+
+ if (rel_find_exp(rel, e)) {
+ if (exp_has_freevar(sql, e))
+ rel_bind_var(sql, rel->l, e);
+ append(rel->exps, e);
+ } else {
+ if (exp_has_freevar(sql, e))
+ rel_bind_var(sql, j->l, e);
+ append(j->exps, e);
+ }
+ }
+}
+
+static sql_rel *
+rel_general_unnest(mvc *sql, sql_rel *rel, list *ad)
+{
+ /* current unnest only possible for equality joins, <, <> etc needs
more work */
+ if (rel && (is_join(rel->op) || is_semi(rel->op)) && is_dependent(rel)
&& ad) {
+ list *fd;
+ node *n, *m;
+ int nr;
+
+ sql_rel *l = rel->l, *r = rel->r;
+ /* rewrite T1 dependent join T2 -> T1 join D dependent join T2,
where the T1/D join adds (equality) predicates (for the Domain (ad)) and D is
are the distinct(projected(ad) from T1) */
+ sql_rel *D = rel_project(sql->sa, rel_dup(l), exps_copy(sql,
ad));
+ set_distinct(D);
+
+ r = rel_crossproduct(sql->sa, D, r, rel->op);
+ r->op = /*is_semi(rel->op)?op_left:*/op_join;
+ move_join_exps(sql, rel, r);
+ set_dependent(r);
+ r = rel_project(sql->sa, r,
(is_semi(r->op))?sa_list(sql->sa):rel_projections(sql, r->r, NULL, 1, 1));
+ /* append ad + rename */
+ nr = sql->label+1;
+ sql->label += list_length(ad);
+ fd = exps_label(sql->sa, exps_copy(sql, ad), nr);
+ for (n = ad->h, m = fd->h; n && m; n = n->next, m = m->next) {
+ sql_exp *l = n->data, *r = m->data, *e;
+
+ l = exp_ref(sql->sa, l);
+ r = exp_ref(sql->sa, r);
+ e = exp_compare(sql->sa, l, r,
(is_outerjoin(rel->op)|is_semi(rel->op))?cmp_equal_nil:cmp_equal);
+ if (!rel->exps)
+ rel->exps = sa_list(sql->sa);
+ append(rel->exps, e);
+ }
+ list_merge(r->exps, fd, (fdup)NULL);
+ rel->r = r;
+ reset_dependent(rel);
+ return rel;
+ }
+ return rel;
+}
+
static sql_rel *
push_up_project(mvc *sql, sql_rel *rel, list *ad)
{
@@ -734,10 +805,25 @@ push_up_topn(mvc *sql, sql_rel *rel)
}
static sql_rel *
-push_up_select(mvc *sql, sql_rel *rel)
+push_up_select(mvc *sql, sql_rel *rel, list *ad)
{
- /* input rel is dependent join with on the right a project */
- if (rel && /*(is_join(rel->op) ||*/( is_semi(rel->op)) &&
is_dependent(rel)) {
+ sql_rel *d = rel->l;
+ sql_rel *r = rel->r;
+ int inner = 0;
+
+ if (rel && is_dependent(rel) && r && r->op == op_select) {
+ sql_rel *rl = r->l;
+
+ if (rl && rel_has_freevar(sql, rl)) {
+ list *inner_ad = rel_dependent_var(sql, d, rl);
+
+ inner = !list_empty(inner_ad);
+ }
+ }
+ if (inner && is_left(rel->op) && !need_distinct(d))
+ return rel_general_unnest(sql, rel, ad);
+ /* input rel is dependent join with on the right a select */
+ if ((!inner || is_semi(rel->op)) && rel && is_dependent(rel)) {
sql_rel *r = rel->r;
if (r && r->op == op_select) { /* move into join */
@@ -754,9 +840,10 @@ push_up_select(mvc *sql, sql_rel *rel)
/* remove select */
rel->r = rel_dup(r->l);
rel_destroy(r);
+ if (!inner)
+ reset_dependent(rel);
}
- }
- if (rel && is_join(rel->op) && is_dependent(rel)) {
+ } else if (rel && is_join(rel->op) && is_dependent(rel)) {
sql_rel *r = rel->r;
list *exps = r->exps;
@@ -920,36 +1007,6 @@ push_up_groupby(mvc *sql, sql_rel *rel,
return rel;
}
-/*
- * join j was just rewriten, but some join expressions may now
- * be too low in de relation rel. These need to move up.
- * */
-static void
-move_join_exps(mvc *sql, sql_rel *j, sql_rel *rel)
-{
- node *n;
- list *exps = rel->exps;
-
- if (!exps)
- return;
- rel->exps = sa_list(sql->sa);
- if (!j->exps)
- j->exps = sa_list(sql->sa);
- for(n = exps->h; n; n = n->next){
- sql_exp *e = n->data;
-
- if (rel_find_exp(rel, e)) {
- if (exp_has_freevar(sql, e))
- rel_bind_var(sql, rel->l, e);
- append(rel->exps, e);
- } else {
- if (exp_has_freevar(sql, e))
- rel_bind_var(sql, j->l, e);
- append(j->exps, e);
- }
- }
-}
-
static sql_rel *
push_up_select_l(mvc *sql, sql_rel *rel)
{
@@ -1131,47 +1188,6 @@ push_up_table(mvc *sql, sql_rel *rel, li
return rel;
}
-static sql_rel *
-rel_general_unnest(mvc *sql, sql_rel *rel, list *ad)
-{
- /* current unnest only possible for equality joins, <, <> etc needs
more work */
- if (rel && (is_join(rel->op) || is_semi(rel->op)) && is_dependent(rel)
&& ad) {
- list *fd;
- node *n, *m;
- int nr;
-
- sql_rel *l = rel->l, *r = rel->r;
- /* rewrite T1 dependent join T2 -> T1 join D dependent join T2,
where the T1/D join adds (equality) predicates (for the Domain (ad)) and D is
are the distinct(projected(ad) from T1) */
- sql_rel *D = rel_project(sql->sa, rel_dup(l), exps_copy(sql,
ad));
- set_distinct(D);
-
- r = rel_crossproduct(sql->sa, D, r, rel->op);
- r->op = /*is_semi(rel->op)?op_left:*/op_join;
- move_join_exps(sql, rel, r);
- set_dependent(r);
- r = rel_project(sql->sa, r,
(is_semi(r->op))?sa_list(sql->sa):rel_projections(sql, r->r, NULL, 1, 1));
- /* append ad + rename */
- nr = sql->label+1;
- sql->label += list_length(ad);
- fd = exps_label(sql->sa, exps_copy(sql, ad), nr);
- for (n = ad->h, m = fd->h; n && m; n = n->next, m = m->next) {
- sql_exp *l = n->data, *r = m->data, *e;
-
- l = exp_ref(sql->sa, l);
- r = exp_ref(sql->sa, r);
- e = exp_compare(sql->sa, l, r,
(is_outerjoin(rel->op)|is_semi(rel->op))?cmp_equal_nil:cmp_equal);
- if (!rel->exps)
- rel->exps = sa_list(sql->sa);
- append(rel->exps, e);
- }
- list_merge(r->exps, fd, (fdup)NULL);
- rel->r = r;
- reset_dependent(rel);
- return rel;
- }
- return rel;
-}
-
/* reintroduce selects, for freevar's of other dependent joins */
static sql_rel *
push_down_select(mvc *sql, sql_rel *rel)
@@ -1251,8 +1267,8 @@ rel_unnest_dependent(mvc *sql, sql_rel *
return rel_unnest_dependent(sql, rel);
}
- if (r && is_select(r->op)) {
- rel = push_up_select(sql, rel);
+ if (r && is_select(r->op) && ad) {
+ rel = push_up_select(sql, rel, ad);
return rel_unnest_dependent(sql, rel);
}
@@ -1456,6 +1472,7 @@ rewrite_exp_rel(mvc *sql, sql_rel *rel,
}
#define is_not_func(sf) (strcmp(sf->func->base.name, "not") == 0)
+#define is_not_anyequal(sf) (strcmp(sf->func->base.name, "sql_not_anyequal")
== 0)
/* simplify expressions, such as not(not(x)) */
/* exp visitor */
@@ -1484,6 +1501,17 @@ rewrite_simplify_exp(mvc *sql, sql_rel *
exp_prop_alias(sql->sa, ie, e);
return ie;
}
+ if (is_func(ie->type) && list_length(ie->l) == 2 &&
is_not_anyequal(sf)) {
+ args = ie->l;
+
+ sql_exp *l = args->h->data;
+ sql_exp *vals = args->h->next->data;
+
+ ie = exp_in_func(sql, l, vals, 1, 0);
+ if (exp_name(e))
+ exp_prop_alias(sql->sa, ie, e);
+ return ie;
+ }
}
return e;
}
diff --git a/sql/test/BugTracker-2015/Tests/crash.Bug-3736.stable.out
b/sql/test/BugTracker-2015/Tests/crash.Bug-3736.stable.out
--- a/sql/test/BugTracker-2015/Tests/crash.Bug-3736.stable.out
+++ b/sql/test/BugTracker-2015/Tests/crash.Bug-3736.stable.out
@@ -90,7 +90,7 @@ join (
| | | | | | | | | | & REF 1
| | | | | | | | | ) [ "o"."open_auction_id" NOT NULL ]
| | | | | | | | ) [ "o"."open_auction_id" NOT NULL ] [ "o"."open_auction_id"
NOT NULL ]
-| | | | | | | ) [ "b3a"."open_auction_id" NOT NULL = !!!FREE!!!
"o"."open_auction_id" NOT NULL ]
+| | | | | | | ) [ "b3a"."open_auction_id" NOT NULL = "o"."open_auction_id" NOT
NULL ]
| | | | | | ) [ "o"."open_auction_id" NOT NULL ] [ sys.min no nil ("b3a"."id"
NOT NULL HASHCOL ) NOT NULL as "%1"."%1", "o"."open_auction_id" NOT NULL ]
| | | | | ) [ "o"."open_auction_id" NOT NULL, "%1"."%1" NOT NULL ]
| | | | ) [ "b3"."id" NOT NULL HASHCOL = "%1"."%1" NOT NULL ]
@@ -116,14 +116,14 @@ project (
| | | | | | | | | | | | & REF 2
| | | | | | | | | | | ) [ "o"."open_auction_id" NOT NULL ]
| | | | | | | | | | ) [ "o"."open_auction_id" NOT NULL ] [
"o"."open_auction_id" NOT NULL ]
-| | | | | | | | | ) [ "b2a"."open_auction_id" NOT NULL = !!!FREE!!!
"o"."open_auction_id" NOT NULL ]
+| | | | | | | | | ) [ "b2a"."open_auction_id" NOT NULL = "o"."open_auction_id"
NOT NULL ]
| | | | | | | | ) [ "o"."open_auction_id" NOT NULL ] [ sys.max no nil
("b2a"."id" NOT NULL HASHCOL ) NOT NULL as "%4"."%4", "o"."open_auction_id" NOT
NULL ]
| | | | | | | ) [ "o"."open_auction_id" NOT NULL, "%4"."%4" NOT NULL ]
| | | | | | ) [ "b2"."id" NOT NULL HASHCOL = "%4"."%4" NOT NULL ]
| | | | | ) [ "o"."open_auction_id" NOT NULL, "b2"."increase" NOT NULL as
"%5"."%5" ]
| | | | ) [ "o"."open_auction_id" NOT NULL ] [ sys.zero_or_one("%5"."%5" NOT
NULL) NOT NULL as "%6"."%6", "o"."open_auction_id" NOT NULL ]
-| | | ) [ "%6"."%6" NOT NULL, "o"."open_auction_id" NOT NULL as "%46"."%46" ]
-| | ) [ "o"."open_auction_id" NOT NULL = "%46"."%46" NOT NULL ]
+| | | ) [ "%6"."%6" NOT NULL, "o"."open_auction_id" NOT NULL as "%47"."%47" ]
+| | ) [ "o"."open_auction_id" NOT NULL = "%47"."%47" NOT NULL ]
| ) [ sys.sql_mul("%3"."%3" NOT NULL, double "2") <= "%6"."%6" NOT NULL ]
) [ "b"."id" NOT NULL HASHCOL , "b"."open_auction_id" NOT NULL, "b"."date" NOT
NULL, "b"."time" NOT NULL, "b"."personref" NOT NULL, "b"."increase" NOT NULL ]
#Select b.* FROM open_auctions o, bidder b WHERE (select b3.INCREASE from
bidder b3 where b3.id = (select min(b3a.id) from bidder b3a where
b3a.open_auction_id = o.open_auction_id)) * 2 <= (Select b2.INCREASE from
bidder b2 where b2.id = (SELECT MAX(b2a.id) from bidder b2a where
b2a.open_auction_id = o.open_auction_id)) AND o.open_auction_id =
b.open_auction_id order by date, time;
diff --git a/sql/test/subquery/Tests/subquery3.stable.out
b/sql/test/subquery/Tests/subquery3.stable.out
--- a/sql/test/subquery/Tests/subquery3.stable.out
+++ b/sql/test/subquery/Tests/subquery3.stable.out
@@ -186,6 +186,18 @@ stdout of test 'subquery3` in directory
[ true ]
[ true ]
[ true ]
+#SELECT
+# NOT SUM(t1.col2) * MIN(t1.col6 + t1.col6 - t1.col6 * t1.col6) NOT IN
(SELECT MAX(t2.col6) FROM another_T t2 GROUP BY t1.col6 HAVING t1.col7 +
MIN(t2.col8) < MAX(t2.col7 - t1.col6))
+#FROM another_T t1
+#GROUP BY t1.col7, t1.col6;
+% .%53 # table_name
+% %53 # name
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list