Changeset: 4869d170e82c for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/4869d170e82c
Modified Files:
sql/include/sql_relation.h
sql/server/rel_unnest.c
Branch: nested
Log Message:
merged with default
diffs (truncated from 353 to 300 lines):
diff --git a/sql/common/sql_list.c b/sql/common/sql_list.c
--- a/sql/common/sql_list.c
+++ b/sql/common/sql_list.c
@@ -715,6 +715,8 @@ list_join(list *l, list *data)
{
if (!l)
return data;
+ if (!data)
+ return l;
assert(data->sa);
assert(data->sa == l->sa);
assert(!l->ht);
diff --git a/sql/include/sql_relation.h b/sql/include/sql_relation.h
--- a/sql/include/sql_relation.h
+++ b/sql/include/sql_relation.h
@@ -313,6 +313,7 @@ typedef struct relation {
card:2, /* 0, 1 (row), 2 aggr, 3 */
dependent:1, /* dependent join */
distinct:1,
+ fv_distinct:1, /* set during general unnest */
processed:1, /* fully processed or still in the process of building
*/
outer:1, /* used as outer (ungrouped) */
grouped:1, /* groupby processed all the group by exps */
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
@@ -79,16 +79,18 @@ exps_set_freevar(mvc *sql, list *exps, s
/* check if the set is distinct (ie we did a domain reduction for the general
unnest) for the set of free variables */
static int
-is_distinct_set(mvc *sql, sql_rel *rel, list *ad)
+is_distinct_set(mvc *sql, sql_rel *rel, list *ad, bool need_join)
{
int distinct = 0;
if (ad && is_groupby(rel->op) && (list_empty(rel->r) ||
exp_match_list(rel->r, ad)))
return 1;
distinct = need_distinct(rel);
+ if (need_join)
+ distinct &= rel->fv_distinct;
if (is_project(rel->op) && rel->l && !distinct)
- distinct = is_distinct_set(sql, rel->l, ad);
+ distinct = is_distinct_set(sql, rel->l, ad, need_join);
if (is_semi(rel->op))
- distinct = is_distinct_set(sql, rel->l, ad);
+ distinct = is_distinct_set(sql, rel->l, ad, need_join);
prop *p = NULL;
if (is_base(rel->op) && (p = find_prop(rel->p, PROP_UKEY)) != NULL)
return exp_match_list(p->value.pval, ad);
@@ -925,6 +927,7 @@ rel_general_unnest(mvc *sql, sql_rel *re
/* 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);
+ D->fv_distinct = true;
int single = is_single(r);
reset_single(r);
@@ -1245,7 +1248,14 @@ push_up_topn_and_sample(mvc *sql, sql_re
if (r && (is_topn(r->op) || is_sample(r->op))) {
/* remove old topn/sample */
sql_rel *(*func) (allocator *, sql_rel *, list *) =
is_topn(r->op) ? rel_topn : rel_sample;
+ sql_rel *l = r->l;
rel->r = rel_dup(r->l);
+ list *obes = (l->op == op_project)?l->r:NULL;
+ if (obes) {
+ obes = exps_copy(sql, obes);
+ list_join(l->exps, l->r);
+ l->r = NULL;
+ }
rel = func(sql->sa, rel, r->exps);
if (r->op == op_topn && !list_empty(ad)) { /* topn per
freevar */
/* add rel_project(), ordering on freevar */
@@ -1255,7 +1265,7 @@ push_up_topn_and_sample(mvc *sql, sql_re
sql_exp *e = n->data;
set_partitioning(e);
}
- p->r = ad;
+ p->r = list_join(ad, obes);
rel->grouped = 1;
}
set_processed(rel);
@@ -1389,7 +1399,7 @@ push_up_groupby(mvc *sql, sql_rel *rel,
sql_rel *l = rel->l, *r = rel->r;
/* left of rel should be a set */
- if (l && is_distinct_set(sql, l, ad) && r && is_groupby(r->op))
{
+ if (l && is_distinct_set(sql, l, ad, false) && r &&
is_groupby(r->op)) {
list *sexps, *jexps, *a = rel_projections(sql, rel->l,
NULL, 1, 1);
node *n;
sql_exp *id = NULL;
@@ -1570,6 +1580,45 @@ static sql_rel * rel_unnest_dependent(mv
static sql_rel * rewrite_outer2inner_union(visitor *v, sql_rel *rel);
+static void
+add_natural_exps(mvc *sql, sql_rel *d, sql_rel *n, bool labelleft)
+{
+ /* add nr->l exps with labels */
+ if (!n->exps)
+ n->exps = sa_list(sql->sa);
+ if (!list_empty(d->exps)) {
+ sql_rel *nl = n->l = rel_project(sql->sa, n->l,
rel_projections(sql, n->l, NULL, 1, 1));
+ sql_rel *nr = n->r;
+ nr = n->r = rel_project(sql->sa, n->r,
is_semi(nr->op)?sa_list(sql->sa):rel_projections(sql, nr->r, NULL, 1, 1));
+ for (node *m = d->exps->h; m; m = m->next) {
+ sql_exp *e = m->data, *le, *re, *je;
+
+ le = exp_ref(sql, e);
+ re = exp_ref(sql, e);
+
+ if (labelleft) {
+ sql_exp *f = NULL;
+ if ((f=rel_find_exp(nl, le)) != NULL)
+ le = f;
+ if (!has_label(le))
+ le = exp_label(sql->sa, le,
++sql->label);
+ if (!f)
+ append(nl->exps, le);
+ le = exp_ref(sql, le);
+ }
+
+ if (!labelleft)
+ re = exp_label(sql->sa, re, ++sql->label);
+ append(nr->exps, re);
+ re = exp_ref(sql, re);
+ je = exp_compare(sql->sa, le, re, cmp_equal);
+ set_semantics(je);
+ append(n->exps, je);
+ }
+ list_hash_clear(nl->exps);
+ }
+}
+
static sql_rel *
push_up_join(mvc *sql, sql_rel *rel, list *ad)
{
@@ -1578,7 +1627,7 @@ push_up_join(mvc *sql, sql_rel *rel, lis
sql_rel *d = rel->l, *j = rel->r;
/* left of rel should be a set */
- if (d && is_distinct_set(sql, d, ad) && j && (is_join(j->op) ||
is_semi(j->op))) {
+ if (d && is_distinct_set(sql, d, ad, is_outerjoin(j->op)) && j
&& (is_join(j->op) || is_semi(j->op))) {
sql_rel *jl = j->l, *jr = j->r;
/* op_join if F(jl) intersect A(D) = empty -> jl join
(D djoin jr)
* F(jr) intersect A(D) = empty -> (D djoin
jl) join jr
@@ -1616,8 +1665,7 @@ push_up_join(mvc *sql, sql_rel *rel, lis
}
if (ld && rd) {
- node *m;
- sql_rel *n, *nr, *nj, *nl;
+ sql_rel *n;
list *inner_exps = exps_copy(sql, j->exps);
list *outer_exps = exps_copy(sql, rel->exps);
list *attr = j->attr?exps_copy(sql,
j->attr):NULL;
@@ -1637,12 +1685,13 @@ push_up_join(mvc *sql, sql_rel *rel, lis
rel->r = rel_dup(jl);
rel->exps = sa_list(sql->sa);
- nj = rel_crossproduct(sql->sa, rel_dup(d),
rel_dup(jr), j->op);
+ sql_rel *nj = rel_crossproduct(sql->sa,
rel_dup(d), rel_dup(jr), rel->op);
set_processed(nj);
+ int op = j->op;
rel_destroy(sql, j);
j = nj;
set_dependent(j);
- n = rel_crossproduct(sql->sa, rel, j, j->op);
+ n = rel_crossproduct(sql->sa, rel, j, op);
n->exps = outer_exps;
if (single)
set_single(n);
@@ -1655,41 +1704,7 @@ push_up_join(mvc *sql, sql_rel *rel, lis
j->op = op_left;
rel->op = op_left;
}
- nl = n->l = rel_project(sql->sa, n->l,
rel_projections(sql, n->l, NULL, 1, 1));
- nr = n->r;
- nr = n->r = rel_project(sql->sa, n->r,
is_semi(nr->op)?sa_list(sql->sa):rel_projections(sql, nr->r, NULL, 1, 1));
- /* add nr->l exps with labels */
- /* create jexps */
- if (!n->exps)
- n->exps = sa_list(sql->sa);
- if (!list_empty(d->exps)) {
- for (m = d->exps->h; m; m = m->next) {
- sql_exp *e = m->data, *le, *re,
*je;
-
- le = exp_ref(sql, e);
- re = exp_ref(sql, e);
-
- if (labelleft) {
- sql_exp *f = NULL;
- if ((f=rel_find_exp(nl,
le)) != NULL)
- le = f;
- if (!has_label(le))
- le =
exp_label(sql->sa, le, ++sql->label);
- if (!f)
-
append(nl->exps, le);
- le = exp_ref(sql, le);
- }
-
- if (!labelleft)
- re = exp_label(sql->sa,
re, ++sql->label);
- append(nr->exps, re);
- re = exp_ref(sql, re);
- je = exp_compare(sql->sa, le,
re, cmp_equal);
- set_semantics(je);
- append(n->exps, je);
- }
- }
- list_hash_clear(nl->exps);
+ add_natural_exps(sql, d, n, labelleft); /*
create jexps */
n->attr = attr;
set_processed(n);
rel_bind_vars(sql, n, n->exps);
@@ -1744,7 +1759,7 @@ push_up_set(mvc *sql, sql_rel *rel, list
int need_distinct = is_semi(rel->op) && need_distinct(d);
/* left of rel should be a set */
- if (d && is_distinct_set(sql, d, ad) && s && is_set(s->op)) {
+ if (d && is_distinct_set(sql, d, ad, false) && s &&
is_set(s->op)) {
sql_rel *sl = s->l, *sr = s->r, *ns;
sl = rel_project(sql->sa, rel_dup(sl),
rel_projections(sql, sl, NULL, 1, 1));
@@ -1829,7 +1844,7 @@ push_up_munion(mvc *sql, sql_rel *rel, l
/* left of rel should be a set */
list *rlist = sa_list(sql->sa);
- if (d && is_distinct_set(sql, d, ad) && s && is_munion(s->op)) {
+ if (d && is_distinct_set(sql, d, ad, false) && s &&
is_munion(s->op)) {
list *iu = s->l;
if (rec) {
sql_rel *r = iu->h->data;
@@ -2099,12 +2114,12 @@ rel_unnest_dependent(mvc *sql, sql_rel *
}
}
- if (r && is_simple_project(r->op) && ((!r->r &&
!exps_have_rank(r->exps)) || (!exps_have_freevar(sql, r->exps) &&
!exps_have_unsafe(r->exps, true, false)) || is_distinct_set(sql, l, ad))) {
+ if (r && is_simple_project(r->op) && ((!r->r &&
!exps_have_rank(r->exps)) || (!exps_have_freevar(sql, r->exps) &&
!exps_have_unsafe(r->exps, true, false)) || is_distinct_set(sql, l, ad,
false))) {
rel = push_up_project(sql, rel, ad);
return rel_unnest_dependent(sql, rel);
}
- if (r && (is_topn(r->op) || is_sample(r->op)) &&
is_distinct_set(sql, l, ad)) {
+ if (r && (is_topn(r->op) || is_sample(r->op)) &&
is_distinct_set(sql, l, ad, false)) {
sql_rel *l = r->l;
if (is_left(rel->op) && l && is_project(l->op)
&& !l->r && !project_unsafe(l, 1)) {
rel = push_down_topn_and_sample(sql,
rel);
@@ -2120,22 +2135,22 @@ rel_unnest_dependent(mvc *sql, sql_rel *
return rel_unnest_dependent(sql, rel);
}
- if (r && is_groupby(r->op) && !is_left(rel->op) &&
is_distinct_set(sql, l, ad)) {
+ if (r && is_groupby(r->op) && !is_left(rel->op) &&
is_distinct_set(sql, l, ad, false)) {
rel = push_up_groupby(sql, rel, ad);
return rel_unnest_dependent(sql, rel);
}
- if (r && (is_join(r->op) || is_semi(r->op)) &&
is_distinct_set(sql, l, ad)) {
+ if (r && (is_join(r->op) || is_semi(r->op)) &&
is_distinct_set(sql, l, ad, is_outerjoin(r->op))) {
rel = push_up_join(sql, rel, ad);
return rel_unnest_dependent(sql, rel);
}
- if (r && is_set(r->op) && !is_left(rel->op) && rel->op
!= op_anti && is_distinct_set(sql, l, ad)) {
+ if (r && is_set(r->op) && !is_left(rel->op) && rel->op
!= op_anti && is_distinct_set(sql, l, ad, false)) {
rel = push_up_set(sql, rel, ad);
return rel_unnest_dependent(sql, rel);
}
- if (r && is_munion(r->op) && !is_left(rel->op) &&
is_distinct_set(sql, l, ad)) {
+ if (r && is_munion(r->op) && !is_left(rel->op) &&
is_distinct_set(sql, l, ad, false)) {
rel = push_up_munion(sql, rel, ad);
return rel_unnest_dependent(sql, rel);
}
diff --git a/sql/test/BugTracker-2023/Tests/misc-crashes-7390.test
b/sql/test/BugTracker-2023/Tests/misc-crashes-7390.test
--- a/sql/test/BugTracker-2023/Tests/misc-crashes-7390.test
+++ b/sql/test/BugTracker-2023/Tests/misc-crashes-7390.test
@@ -459,7 +459,7 @@ DROP TABLE v0
-- 31.sql
onlyif has-hugeint
query I nosort
-SELECT ALL ( SELECT - - - - - - - - - - - 1 - - - - - - 16 FROM ( SELECT NULL
- - - - - - - - - - - - - - - - 1 FROM ( SELECT - - - - 1 * - - - - - -
2147483648 * - - - 43 * 77745222.000000 ) AS v1 ( v1 ) GROUP BY GROUPING SETS (
GROUPING SETS ( CUBE ( v1 ) ) ) ORDER BY v1 , - - - 86 + - - power(93 , v1) ,
v1 LIMIT 21 ) AS v1 UNION SELECT - - - - - - - - - - - - 93 WHERE - v1 < -
63226945.000000 - - - - - - - - - - 68 ) FROM ( VALUES ( - - - - - - - - - 40 /
- ( SELECT - - - - - - - - 0 WHERE - - - - - - - 40 = - - - - - 0 ) ) , ( - -
88 ) ) v1 ( v1 )
+SELECT ALL ( SELECT - - - - - - - - - - - 1 - - - - - - 16 FROM ( SELECT NULL
- - - - - - - - - - - - - - - - 1 FROM ( SELECT - - - - 1 * - - - - - -
2147483648 * - - - 43 * 77745222.000000 ) AS v1 ( v1 ) GROUP BY GROUPING SETS (
GROUPING SETS ( CUBE ( v1 ) ) ) ORDER BY v1 , - - - 86 + - - 93 ^ 2 , v1 LIMIT
21 ) AS v1 UNION SELECT - - - - - - - - - - - - 93 WHERE - v1 < -
63226945.000000 - - - - - - - - - - 68 ) FROM ( VALUES ( - - - - - - - - - 40 /
- ( SELECT - - - - - - - - 0 WHERE - - - - - - - 40 = - - - - - 0 ) ) , ( - -
88 ) ) v1 ( v1 )
----
15
15
diff --git
a/sql/test/BugTracker-2026/Tests/7834-BATsubcross-more-than-one-match.test
b/sql/test/BugTracker-2026/Tests/7834-BATsubcross-more-than-one-match.test
--- a/sql/test/BugTracker-2026/Tests/7834-BATsubcross-more-than-one-match.test
+++ b/sql/test/BugTracker-2026/Tests/7834-BATsubcross-more-than-one-match.test
@@ -1,4 +1,4 @@
-statement error GDK reported error: BATsubcross: more than one match
+statement error 42000!row frame bound must be non negative and non null.
SELECT x , x , STDDEV_POP ( NULLIF ( ( WITH RECURSIVE x ( x ) AS ( WITH
RECURSIVE x ( x ) AS ( SELECT 440 UNION SELECT 1 - x FROM x ) SELECT * FROM
generate_series ( 0 , 10 ) WHERE x < 5 ) SELECT - COUNT ( * ) OVER ( ROWS
BETWEEN 2 PRECEDING AND 3 >= ( SELECT CASE WHEN x = 12 THEN 1 ELSE CASE WHEN
length ( 'abcdefg' ) >= 1 THEN substr ( ( SELECT SUM ( 0 ) OVER ( ) ) , locate
( RPAD ( 'abc' , 1 , ( SELECT 1 ) > ANY ( 1 ) ) , 'joeuser@mydatabase@test' , 9
) , 1 ) ELSE 'nil' END END FROM ( SELECT 1 x HAVING COUNT ( * ) > ( SELECT -
CASE - ( 0 ) WHEN 18 + - 60 THEN NULL WHEN - CASE - 67 WHEN - 79 * ROW_NUMBER (
) OVER ( ORDER BY ( SELECT * FROM ( SELECT 1 AS x ) WHERE x IN ( SELECT (
row_number ( ) OVER ( ) ) ) ) ) <= -5.500000 / 30 - 32 * 69 THEN sign ( CAST(
'-9223372036854775808.5' AS FLOAT ) ) + 0 ELSE NULL END * ( 45 ) + 19 * 17 THEN
20 WHEN SUM ( 78 ) + 69 THEN 1234567954432.000000 % 119070 % '' * 74 ELSE
NULLIF ( 82 , 72 + 26 ) * 7 END * - 92 WHERE FALSE ) UNION SELECT 1 + 1 AS x
INTERSECT SELECT 3 ) AS x ) FOLLOWING ) FROM x AS x WHERE NOT ( - x ) BETWEEN
- x AND NULL ) , NULL ) ) OVER ( ORDER BY CASE WHEN x % 2 = 0 THEN 0 ELSE 1 END
RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) AS x FROM ( SELECT rank ( )
OVER ( PARTITION BY 'x' , 1 , 1 , 'x' ) AS x UNION SELECT 0 AS x UNION SELECT 3
AS x ) ORDER BY 1 , 2 , 3
onlyif has-hugeintxs
diff --git a/sql/test/BugTracker-2026/Tests/7859-getModule-crash.test
b/sql/test/BugTracker-2026/Tests/7859-getModule-crash.test
--- a/sql/test/BugTracker-2026/Tests/7859-getModule-crash.test
+++ b/sql/test/BugTracker-2026/Tests/7859-getModule-crash.test
@@ -7,7 +7,7 @@ SELECT x NOT IN (
query II rowsort
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]