Changeset: ed47c5d014b3 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/ed47c5d014b3
Modified Files:
sql/server/rel_exp.c
sql/server/rel_optimize_others.c
sql/server/rel_optimize_proj.c
sql/server/rel_select.c
sql/server/rel_unnest.c
sql/test/BugTracker-2023/Tests/misc-crashes-7390.test
sql/test/BugTracker-2026/Tests/7833-assertion-failure.test
sql/test/BugTracker-2026/Tests/7843-assertion-failure.test
sql/test/BugTracker-2026/Tests/7845-assertion-failure.test
sql/test/BugTracker-2026/Tests/7846-do_covariance_and_correlation-crash.test
sql/test/BugTracker-2026/Tests/7847-assertion-failure.test
sql/test/BugTracker-2026/Tests/7849-assertion-failure.test
sql/test/BugTracker-2026/Tests/All
sql/test/Dependencies/Tests/dependency_DBobjects.test
sql/test/Dependencies/Tests/dependency_owner_schema_3.test
sql/test/emptydb/Tests/check.stable.out
sql/test/emptydb/Tests/check.stable.out.32bit
sql/test/emptydb/Tests/check.stable.out.int128
sql/test/sql_dump/Tests/dump.test
sql/test/subquery/Tests/subquery5.test
Branch: Dec2025
Log Message:
fixed exp_has_aggr, properly detect aggr function in compare expression
fixed exp_push_down_prj, properly find expression in group by list (not
projection list)
fixed simplify_groupby_columns, properly add (simplified) expression to the
projection list
of a lower projection when needed (skipping over selects inbetween)
fixed rel_order_by, make copy of expression, don't directly reuse expression
(would later lead to use after free)
fixed push_up_project_exp, when replacing an expression with an inner one, keep
the freevar st
atus.
fixed push_up_join, in case of push up of group joins, directly reorder the
joins.
fixed rel_unnest_dependent, removed blind reorder of op_right into op_left
fixed rewrite_ifthenelse, no longer needed, handled by later rewrites.
Solving issues #7781, #7791, #7793, #7794, #7795, #7797, #7800, #7801, #7833,
#7843, #7845, #7
846, #7847, #7848, #7849, #7850 and #7851
diffs (truncated from 550 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
@@ -2296,8 +2296,6 @@ exp_has_aggr(sql_rel *r, sql_exp *e )
case e_aggr:
return true;
case e_cmp:
- if (e->card != CARD_ATOM)
- return false;
if (e->flag == cmp_filter)
return exps_have_aggr(r, e->l) && exps_have_aggr(r,
e->r);
if (e->flag == cmp_con || e->flag == cmp_dis)
diff --git a/sql/server/rel_optimize_others.c b/sql/server/rel_optimize_others.c
--- a/sql/server/rel_optimize_others.c
+++ b/sql/server/rel_optimize_others.c
@@ -117,7 +117,7 @@ exp_push_down_prj(mvc *sql, sql_exp *e,
if (is_groupby(f->op) && !list_empty(f->r) && ne->type ==
e_column) {
sql_exp *gbe = NULL;
if (ne->nid)
- gbe = exps_bind_nid(f->exps, ne->nid);
+ gbe = exps_bind_nid(f->r, ne->nid);
ne = gbe;
if (!ne || (ne->type != e_column && (ne->type != e_atom
|| ne->f)))
return NULL;
diff --git a/sql/server/rel_optimize_proj.c b/sql/server/rel_optimize_proj.c
--- a/sql/server/rel_optimize_proj.c
+++ b/sql/server/rel_optimize_proj.c
@@ -1523,8 +1523,12 @@ static inline sql_rel *
rel_simplify_groupby_columns(visitor *v, sql_rel *rel)
{
if (is_groupby(rel->op) && !list_empty(rel->r)) {
- sql_rel *l = rel->l;
-
+ sql_rel *l = rel->l, *p = rel;
+
+ if (l && is_select(l->op)) {
+ p = l;
+ l = l->l;
+ }
for (node *n=((list*)rel->r)->h; n ; n = n->next) {
sql_exp *e = n->data;
e->used = 0; /* we need to use this flag, clean it
first */
@@ -1597,7 +1601,7 @@ rel_simplify_groupby_columns(visitor *v,
if (!has_label(e)) /* dangerous
to merge, skip it */
continue;
if (!is_simple_project(l->op)
|| !list_empty(l->r) || rel_is_ref(l) || need_distinct(l))
- rel->l = l =
rel_project(v->sql->sa, l, rel_projections(v->sql, l, NULL, 1, 1));
+ p->l = l =
rel_project(v->sql->sa, l, rel_projections(v->sql, l, NULL, 1, 1));
list_append(l->exps, e);
n->data = e = exp_ref(v->sql,
e);
list_hash_clear(rel->r);
@@ -1628,7 +1632,7 @@ rel_simplify_groupby_columns(visitor *v,
if (colf) /* a col
reference is already there, add a new label */
exp_label(v->sql->sa, ne, ++v->sql->label);
if
(!is_simple_project(l->op) || !list_empty(l->r) || rel_is_ref(l) ||
need_distinct(l))
- rel->l = l =
rel_project(v->sql->sa, l, rel_projections(v->sql, l, NULL, 1, 1));
+ p->l = l =
rel_project(v->sql->sa, l, rel_projections(v->sql, l, NULL, 1, 1));
list_append(l->exps,
ne);
n->data =
exp_ref(v->sql, ne);
}
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
@@ -4742,6 +4742,8 @@ rel_order_by(sql_query *query, sql_rel *
}
if (!is_freevar(e) &&
!(is_sql_window(f) && exp_is_atom(e)))
e = exp_ref(sql, e);
+ else
+ e = exp_copy(sql, e);
}
}
@@ -5980,6 +5982,8 @@ rel_select_exp(sql_query *query, sql_rel
atom *a = e->l;
int nr =
(int)atom_get_int(a);
if (nr ==
(list_length(pexps) + 1)) {
+ if
(exp_has_aggr(inner, ce))
+ return
sql_error(sql, 02, SQLSTATE(42000) "SELECT: aggregate functions are not allowed
in GROUP BY");
n->data = ce;
ce =
exp_ref(sql, ce);
ce->card =
CARD_AGGR;
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
@@ -599,6 +599,7 @@ push_up_project_exp(mvc *sql, sql_rel *r
e->l = ne->l;
e->r = ne->r;
e->nid = ne->nid;
+ e->freevar = ne->freevar;
} else {
ne = exp_copy(sql, ne);
return push_up_project_exp(sql, rel,
ne);
@@ -1428,6 +1429,8 @@ bind_join_vars(mvc *sql, sql_rel *rel)
}
}
+static sql_rel * rel_unnest_dependent(mvc *sql, sql_rel *rel);
+
static sql_rel * rewrite_outer2inner_union(visitor *v, sql_rel *rel);
static sql_rel *
@@ -1471,6 +1474,19 @@ push_up_join(mvc *sql, sql_rel *rel, lis
list *attr = j->attr?exps_copy(sql,
j->attr):NULL;
int single = is_single(j);
+ if (attr && exps_uses_exp(rel->exps,
attr->h->data)) {
+ if (!rel_is_ref(rel) && !rel_is_ref(j)
&&
+ rel->op == op_left && j->op ==
op_left) {
+
+ j->l = rel->l;
+ rel->l = jl;
+ set_dependent(j);
+ rel->r =
rel_unnest_dependent(sql, j);
+ return rel;
+ }
+ assert(0);
+ }
+
rel->r = rel_dup(jl);
rel->exps = sa_list(sql->sa);
nj = rel_crossproduct(sql->sa, rel_dup(d),
rel_dup(jr), j->op);
@@ -1654,8 +1670,6 @@ push_up_set(mvc *sql, sql_rel *rel, list
return rel;
}
-static sql_rel * rel_unnest_dependent(mvc *sql, sql_rel *rel);
-
static sql_rel *
push_up_munion(mvc *sql, sql_rel *rel, list *ad)
{
@@ -1874,14 +1888,8 @@ rel_unnest_dependent(mvc *sql, sql_rel *
if (rel_has_freevar(sql, l)) {
rel->l = rel_unnest_dependent(sql, rel->l);
if (rel_has_freevar(sql, rel->l)) {
- if (rel->op == op_right) {
- sql_rel *l = rel->l;
-
- rel->l = rel->r;
- rel->r = l;
- rel->op = op_left;
- return rel_unnest_dependent(sql, rel);
- } else if (rel->op == op_left &&
list_empty(rel->attr) && !rel_has_freevar(sql, rel->r) &&
rel_dependent_var(sql, rel->r, rel->l)) {
+ if (rel->op == op_left && list_empty(rel->attr)
&& !rel_has_freevar(sql, rel->r) && rel_dependent_var(sql, rel->r, rel->l)) {
+assert(0);
sql_rel *l = rel->l;
rel->l = rel->r;
@@ -3926,90 +3934,6 @@ rewrite_ifthenelse(visitor *v, sql_rel *
v->changes++;
return exp_ref(v->sql, e);
}
-
- sql_subfunc *sf;
- if (e->type != e_func)
- return e;
-
- sf = e->f;
- /* TODO also handle ifthenelse with more than 3 arguments */
- if (is_case_func(sf) && !list_empty(e->l) && list_length(e->l) == 3) {
- list *l = e->l;
-
- /* remove unnecessary = true expressions under ifthenelse */
- for (node *n = l->h ; n ; n = n->next) {
- sql_exp *e = n->data;
-
- if (e->type == e_cmp && e->flag == cmp_equal &&
exp_is_true(e) && exp_is_true(e->r)) {
- sql_subtype *t = exp_subtype(e->r);
- if (t->type->localtype == TYPE_bit)
- n->data = e->l;
- }
- }
-
- sql_exp *cond = l->h->data;
- sql_exp *then_exp = l->h->next->data;
- sql_exp *else_exp = l->h->next->next->data;
- sql_exp *not_cond;
-
- if (!exp_has_rel(cond) && (exp_has_rel(then_exp) ||
exp_has_rel(else_exp))) {
- if (!rel_has_freevar(v->sql, rel))
- return e;
- bool single = false;
- /* return sql_error(v->sql, 10, SQLSTATE(42000) "time
to rewrite into union\n");
- union(
- select(
- project [then]
- )[cond]
- select(
- project [else]
- )[not(cond) or cond is null]
- ) [ cols ] */
- sql_rel *lsq = NULL, *rsq = NULL, *usq = NULL;
- list *urs = sa_list(v->sql->sa);
-
- if (exp_has_rel(then_exp)) {
- lsq = exp_rel_get_rel(v->sql->sa, then_exp);
- then_exp = exp_rel_update_exp(v->sql, then_exp,
false);
- if (is_single(lsq))
- single = true;
- reset_single(lsq);
- }
- exp_set_freevar(v->sql, then_exp, lsq);
- exp_label(v->sql->sa, then_exp, ++v->sql->label);
- lsq = rel_project(v->sql->sa, lsq,
append(sa_list(v->sql->sa), then_exp));
- exp_set_freevar(v->sql, cond, lsq);
- set_processed(lsq);
- lsq = rel_select(v->sql->sa, lsq,
exp_compare(v->sql->sa, cond, exp_atom_bool(v->sql->sa, 1), cmp_equal));
- set_processed(lsq);
- if (exp_has_rel(else_exp)) {
- rsq = exp_rel_get_rel(v->sql->sa, else_exp);
- else_exp = exp_rel_update_exp(v->sql, else_exp,
false);
- if (is_single(rsq))
- single = true;
- reset_single(rsq);
- }
- exp_set_freevar(v->sql, else_exp, rsq);
- exp_label(v->sql->sa, else_exp, ++v->sql->label);
- rsq = rel_project(v->sql->sa, rsq,
append(sa_list(v->sql->sa), else_exp));
- cond = exp_copy(v->sql, cond);
- exp_set_freevar(v->sql, cond, rsq);
- not_cond = exp_compare(v->sql->sa, cond,
exp_atom_bool(v->sql->sa, 1), cmp_notequal);
- set_semantics(not_cond); /* also compare nulls */
- set_processed(rsq);
- rsq = rel_select(v->sql->sa, rsq, not_cond);
- set_processed(rsq);
- urs = append(urs, lsq);
- urs = append(urs, rsq);
- usq = rel_setop_n_ary(v->sql->sa, urs, op_munion);
- rel_setop_n_ary_set_exps(v->sql, usq,
append(sa_list(v->sql->sa), exp_ref(v->sql, e)), false);
- if (single)
- set_single(usq);
- set_processed(usq);
- e = exp_rel(v->sql, usq);
- v->changes++;
- }
- }
return e;
}
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
@@ -400,7 +400,7 @@ INSERT INTO v0 VALUES (-1),(127),(4),(-1
statement error 42000!SELECT: identifier 'v1' ambiguous
WITH v0 AS (SELECT -1, * FROM v0) INSERT INTO v0 SELECT v1 * 29 FROM v0 AS v3,
v0, v0 AS v2, v0 AS v4, v0 ORDER BY v1 * 0 ^ 83
-statement ok
+statement error 42000!row frame bound must be non negative and non null.
UPDATE v0 SET v1 = -1 WHERE CASE WHEN v1 > -1 THEN (SELECT STDDEV_SAMP((18 *
v1 + (v1 IN (21 , -1)))) OVER (ROWS BETWEEN CURRENT ROW AND v1 - NULL
FOLLOWING) * 17) > v1 / (SELECT -1 WHERE (88 IN (96))) ELSE 82 END ^ -128 ^ v1
statement ok
diff --git a/sql/test/BugTracker-2026/Tests/7833-assertion-failure.test
b/sql/test/BugTracker-2026/Tests/7833-assertion-failure.test
--- a/sql/test/BugTracker-2026/Tests/7833-assertion-failure.test
+++ b/sql/test/BugTracker-2026/Tests/7833-assertion-failure.test
@@ -1,4 +1,3 @@
-query II
+statement error Illegal argument
SELECT 301 AS x , 5 IN ( SELECT 5 FROM ( SELECT 5 UNION SELECT RANK ( ) OVER (
) FROM generate_series ( 285 , 298 ) AS x GROUP BY x HAVING NOT x < ANY ( NOT
MAX ( 561 ) < x * AVG ( x + x ) * x ) ) AS x ) AND 6 IN ( SELECT MAX ( x ) ,
MIN ( x ) , MAX ( x ) , MIN ( x ) , MAX ( x ) , MIN ( x ) LIMIT 0 OFFSET 0 )
GROUP BY x , x HAVING x = 1
-----
diff --git a/sql/test/BugTracker-2026/Tests/7843-assertion-failure.test
b/sql/test/BugTracker-2026/Tests/7843-assertion-failure.test
--- a/sql/test/BugTracker-2026/Tests/7843-assertion-failure.test
+++ b/sql/test/BugTracker-2026/Tests/7843-assertion-failure.test
@@ -68,4 +68,4 @@ SELECT x , CASE WHEN x > 12 THEN 1 ELSE
13
1
NULL
-0
+NULL
diff --git a/sql/test/BugTracker-2026/Tests/7845-assertion-failure.test
b/sql/test/BugTracker-2026/Tests/7845-assertion-failure.test
--- a/sql/test/BugTracker-2026/Tests/7845-assertion-failure.test
+++ b/sql/test/BugTracker-2026/Tests/7845-assertion-failure.test
@@ -5,7 +5,7 @@ a
b
-- assertion failure in exp_bin (be=0x7f96b81a61b0, e=0x7f96b81b5760,
left=0x7f96b821d130, right=0x7f96b821d310, grp=0x0, ext=0x0, cnt=0x0, sel=0x0,
depth=1, reduce=0, push=0) at sql/backends/monet5/rel_bin.c:1899
-query I rowsort
+statement error 42000!SELECT: aggregate functions are not allowed in GROUP BY
SELECT * FROM ( SELECT 11 AS x )
JOIN ( SELECT * FROM ( SELECT * FROM ( SELECT 10 AS x ) ) UNION SELECT * FROM
generate_series ( CAST( 0.000000 AS REAL ) , CAST( 123.999496 AS REAL ) , CAST(
1.600000 AS REAL ) ) ORDER BY COALESCE ( x , 0 ) + COALESCE ( x , 0 ) ) USING (
x )
WHERE x BETWEEN ( SELECT 1 AS x WHERE ( SELECT x AS x WHERE x IN ( SELECT x
FROM ( WITH RECURSIVE x ( x ) AS ( SELECT count ( * ) = - 36 * - 33 * - 49 *
CASE 50 WHEN - 21 + 0 + - COUNT ( * ) THEN NULL WHEN 99 * - 43 + - - 35 THEN -
75 ELSE NULL END * - - 51 * 0 GROUP BY 1 ) SELECT x FROM x WHERE x = 2 UNION
SELECT x FROM x WHERE x = 3 ORDER BY x , x LIMIT 4 ) ) ) ) AND x
diff --git
a/sql/test/BugTracker-2026/Tests/7846-do_covariance_and_correlation-crash.test
b/sql/test/BugTracker-2026/Tests/7846-do_covariance_and_correlation-crash.test
---
a/sql/test/BugTracker-2026/Tests/7846-do_covariance_and_correlation-crash.test
+++
b/sql/test/BugTracker-2026/Tests/7846-do_covariance_and_correlation-crash.test
@@ -1,7 +1,7 @@
query I nosort
-SELECT count(*) FROM ( SELECT 1 AS x UNION SELECT 0 AS x UNION SELECT DISTINCT
* FROM generate_series ( CAST( 65536 AS REAL ) , CAST( 1.900000 AS REAL ) ) AS
x WHERE 625 )
+SELECT count(*) FROM ( SELECT 1 AS x UNION SELECT 0 AS x UNION SELECT DISTINCT
* FROM generate_series ( CAST( 200 AS REAL ) , CAST( 1.900000 AS REAL ) ) AS x
WHERE 625 )
----
-65536
+200
query RRIRR rowsort
SELECT DISTINCT covar_pop ( 1 , 1 ) OVER ( ) ,
@@ -9,7 +9,7 @@ SELECT DISTINCT covar_pop ( 1 , 1 ) OVER
MAX ( CASE x WHEN 1 THEN x END ) OVER ( ) ,
covar_samp ( 1 , NULL ) OVER ( ) ,
corr ( 1 , NULL ) OVER ( )
-FROM ( SELECT 1 AS x UNION SELECT 0 AS x UNION SELECT DISTINCT * FROM
generate_series ( CAST( 65536 AS REAL ) , CAST( 1.900000 AS REAL ) ) AS x WHERE
625 )
+FROM ( SELECT 1 AS x UNION SELECT 0 AS x UNION SELECT DISTINCT * FROM
generate_series ( CAST( 200 AS REAL ) , CAST( 1.900000 AS REAL ) ) AS x WHERE
625 )
----
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]