Changeset: b4eaa11e6900 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/b4eaa11e6900
Modified Files:
        sql/server/rel_select.c
        sql/server/rel_unnest.c
        sql/test/BugTracker-2026/Tests/All
Branch: default
Log Message:

Merge with Dec2025 branch.


diffs (200 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
@@ -4354,10 +4354,9 @@ symbol_get_identifier(symbol *sym)
 static sql_exp*
 rel_group_column(sql_query *query, sql_rel **rel, symbol *grp, dlist 
*selection, list *exps, int f)
 {
-       sql_query *lquery = query_create(query->sql);
        mvc *sql = query->sql;
        exp_kind ek = {type_value, card_value, TRUE};
-       sql_exp *e = rel_value_exp2(lquery, rel, grp, f, ek);
+       sql_exp *e = rel_value_exp2(query, rel, grp, f, ek);
 
        if (e && exp_is_atom(e)) {
                sql_subtype *tpe = exp_subtype(e);
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
@@ -330,7 +330,7 @@ merge_freevar(list *l, list *r, bool all
 }
 
 static list * exps_freevar(mvc *sql, list *exps, bool all);
-static list * rel_freevar(mvc *sql, sql_rel *rel);
+static list * rel_freevar(mvc *sql, sql_rel *rel, sql_rel *ref);
 
 static list *
 exp_freevar(mvc *sql, sql_exp *e, bool all)
@@ -375,7 +375,7 @@ exp_freevar(mvc *sql, sql_exp *e, bool a
        case e_psm:
                if (exp_is_rel(e))
                        if (rel_has_freevar(sql, e->l))
-                               return rel_freevar(sql, e->l);
+                               return rel_freevar(sql, e->l, NULL);
                return NULL;
        case e_atom:
                if (e->f)
@@ -407,13 +407,13 @@ exps_freevar(mvc *sql, list *exps, bool 
 }
 
 static list *
-rel_freevar(mvc *sql, sql_rel *rel)
+rel_freevar(mvc *sql, sql_rel *rel, sql_rel *ref)
 {
        list *lexps = NULL, *rexps = NULL, *exps = NULL;
 
        if (mvc_highwater(sql))
                return sql_error(sql, 10, SQLSTATE(42000) "Query too complex: 
running out of stack space");
-       if (!rel)
+       if (!rel || rel == ref)
                return NULL;
        if (is_independent(rel->used))
                return NULL;
@@ -423,8 +423,8 @@ rel_freevar(mvc *sql, sql_rel *rel)
        case op_right:
        case op_full:
                exps = exps_freevar(sql, rel->exps, false);
-               lexps = rel_freevar(sql, rel->l);
-               rexps = rel_freevar(sql, rel->r);
+               lexps = rel_freevar(sql, rel->l, ref);
+               rexps = rel_freevar(sql, rel->r, ref);
                lexps = merge_freevar(lexps, rexps, false);
                exps = merge_freevar(exps, lexps, false);
                return exps;
@@ -434,22 +434,22 @@ rel_freevar(mvc *sql, sql_rel *rel)
        case op_table: {
                sql_exp *call = rel->r;
                if (rel->flag != TRIGGER_WRAPPER && rel->l)
-                       lexps = rel_freevar(sql, rel->l);
+                       lexps = rel_freevar(sql, rel->l, ref);
                exps = (rel->flag != TRIGGER_WRAPPER && call)?exps_freevar(sql, 
call->l, false):NULL;
                return merge_freevar(exps, lexps, false);
        }
        case op_except:
        case op_inter:
                exps = exps_freevar(sql, rel->exps, false);
-               lexps = rel_freevar(sql, rel->l);
-               rexps = rel_freevar(sql, rel->r);
+               lexps = rel_freevar(sql, rel->l, ref);
+               rexps = rel_freevar(sql, rel->r, ref);
                lexps = merge_freevar(lexps, rexps, false);
                exps = merge_freevar(exps, lexps, false);
                return exps;
        case op_munion:
                exps = exps_freevar(sql, rel->exps, false);
                for (node *n = ((list*)rel->l)->h; n; n = n->next) {
-                       lexps = rel_freevar(sql, n->data);
+                       lexps = rel_freevar(sql, n->data, ref);
                        exps = merge_freevar(exps, lexps, false);
                }
                return exps;
@@ -464,12 +464,12 @@ rel_freevar(mvc *sql, sql_rel *rel)
        case op_groupby:
        case op_project:
                exps = exps_freevar(sql, rel->exps, false);
-               lexps = rel_freevar(sql, rel->l);
+               lexps = rel_freevar(sql, rel->l, ref);
                if (rel->r) {
                        if (is_groupby(rel->op) || is_simple_project(rel->op))
                                rexps = exps_freevar(sql, rel->r, false);
                        else
-                               rexps = rel_freevar(sql, rel->r);
+                               rexps = rel_freevar(sql, rel->r, ref);
                        lexps = merge_freevar(lexps, rexps, false);
                }
                exps = merge_freevar(exps, lexps, false);
@@ -486,7 +486,7 @@ rel_dependent_var(mvc *sql, sql_rel *l, 
        list *res = NULL;
 
        if (rel_has_freevar(sql, r)){
-               list *freevar = rel_freevar(sql, r);
+               list *freevar = rel_freevar(sql, r, l);
                if (freevar) {
                        node *n;
                        list *boundvar = rel_projections(sql, l, NULL, 1, 0);
@@ -1739,7 +1739,8 @@ push_up_munion(mvc *sql, sql_rel *rel, l
                                set_has_freevar(sl);
                                if (!is_simple_project(sl->op))
                                        sl = rel_inplace_project(sql->sa, sl, 
NULL, rel_projections(sql, sl, NULL, 1, 1));
-                               list *exps = exps_copy(sql, ad);
+                               list *exps = NULL;
+                               exps = rel_projections(sql, d, NULL, 1, 1);
                                for(node *n = exps->h; n; n = n->next) {
                                        sql_exp *e = n->data;
                                        set_freevar(e, 0);
@@ -1889,11 +1890,11 @@ rel_unnest_dependent(mvc *sql, sql_rel *
                l = rel->l;
                r = rel->r;
 
+               /*
                if (rel_has_freevar(sql, l)) {
-                       rel->l = rel_unnest_dependent(sql, rel->l);
+                        rel->l = rel_unnest_dependent(sql, rel->l);
                        if (rel_has_freevar(sql, 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;
@@ -1903,6 +1904,7 @@ assert(0);
                                }
                        }
                }
+               */
 
                if (!rel_has_freevar(sql, r)) {
                        if (rel_has_freevar(sql, l) && is_innerjoin(rel->op) && 
!rel->exps) {
@@ -1912,6 +1914,8 @@ assert(0);
                                r = rel->r;
                        } else {
                                reset_dependent(rel);
+                               if (is_join(rel->op))
+                                       rel_bind_vars(sql, rel->l, rel->exps);
                                return rel;
                        }
                }
@@ -2334,7 +2338,7 @@ rewrite_inner(mvc *sql, sql_rel *rel, sq
        assert(d);
        if (rel_has_freevar(sql, inner)) {
                list *dv = rel_dependent_var(sql, d, inner);
-               list *fv = rel_freevar(sql, inner);
+               list *fv = rel_freevar(sql, inner, d);
                /* check if the inner depends on the new join (d) or one level 
up */
                if (list_length(dv))
                        set_dependent(d);
diff --git a/sql/test/BugTracker-2026/Tests/7862-rel_has_freevar-crash.test 
b/sql/test/BugTracker-2026/Tests/7862-rel_has_freevar-crash.test
--- a/sql/test/BugTracker-2026/Tests/7862-rel_has_freevar-crash.test
+++ b/sql/test/BugTracker-2026/Tests/7862-rel_has_freevar-crash.test
@@ -14,8 +14,18 @@ NULL
 0
 
 -- Segmentation fault. in rel_has_freevar (sql=0x7f0a081844e0, rel=0x0) at 
sql/server/rel_unnest.c:170    if (is_basetable(rel->op)) {  -- cause of seg 
fault: rel=0x0
-statement error 42000!Query too complex: running out of stack space
+query II rowsort
 SELECT x , CASE WHEN x > 12 THEN 1 ELSE 0 END AS x
   FROM ( SELECT 10 AS x UNION SELECT 11 AS x GROUP BY CUBE ( x , x ) UNION 
SELECT 12 AS x UNION SELECT 13 AS x )
  WHERE x IN ( WITH RECURSIVE x ( row_number ) AS ( SELECT 1 UNION SELECT x + 1 
FROM x WHERE x < 20 ) SELECT x AS x FROM x WHERE x NOT IN ( 8 , 12 , CAST( 
0.000000 AS FLOAT ) , 24 , 32 ) OR x = 512 GROUP BY x HAVING NOT x < ANY ( CASE 
WHEN NULLIF ( ( WITH RECURSIVE x ( x ) AS ( SELECT 1 UNION SELECT x + 1 FROM ( 
WITH RECURSIVE x ( x ) AS ( SELECT CASE WHEN x < - 13 * - ( 0 ) + 39 * - ( 
SELECT '1' ) + 0.100000 + 0.100000 THEN CAST( '-0' AS DOUBLE ) END UNION SELECT 
ROUND ( 70 , 2 ) FROM x ) SELECT * FROM ( SELECT 'b' AS x FROM x ) WHERE x NOT 
IN ( 'a' ) ) WHERE x < 8 ) SELECT - COUNT ( * ) FROM x AS x WHERE NOT ( - x ) 
BETWEEN - x AND NULL ) , NULL ) IS NULL THEN 1 ELSE 0 END AND 6 IN ( SELECT MAX 
( x ) , x < -1234567 , MAX ( x ) , MIN ( x ) , MAX ( x ) , MIN ( x ) ORDER BY 1 
, 2 LIMIT 0 OFFSET 0 ) ) )
-
+----
+10
+0
+11
+0
+12
+0
+13
+1
+NULL
+0
diff --git a/sql/test/BugTracker-2026/Tests/All 
b/sql/test/BugTracker-2026/Tests/All
--- a/sql/test/BugTracker-2026/Tests/All
+++ b/sql/test/BugTracker-2026/Tests/All
@@ -59,7 +59,7 @@ KNOWNFAIL?7774-insert-into-renamed-table
 7855-ntile
 7856-crash-exp-match
 7857-rollup-crash
-KNOWNFAIL?7862-rel_has_freevar-crash
+7862-rel_has_freevar-crash
 7865-unnest-cte-crash
 7867-push-groupby-down
 7872-exp-type-check-failed
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to