Changeset: defe80d85934 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/defe80d85934
Modified Files:
        gdk/gdk_bbp.c
        sql/backends/monet5/sql_gencode.c
        sql/test/BugTracker-2026/Tests/All
Branch: default
Log Message:

Merge with Dec2025 branch.


diffs (truncated from 471 to 300 lines):

diff --git a/gdk/gdk_bbp.c b/gdk/gdk_bbp.c
--- a/gdk/gdk_bbp.c
+++ b/gdk/gdk_bbp.c
@@ -2073,8 +2073,10 @@ BBPexit(void)
                                        if (b->oldtail) {
                                                Heap *h = b->oldtail;
                                                b->oldtail = NULL;
-                                               ATOMIC_AND(&h->refs, 
~DELAYEDREMOVE);
-                                               HEAPdecref(h, false);
+                                               if (h != (Heap *) 1) {
+                                                       ATOMIC_AND(&h->refs, 
~DELAYEDREMOVE);
+                                                       HEAPdecref(h, false);
+                                               }
                                        }
                                        PROPdestroy_nolock(b);
                                        MT_lock_unset(&b->theaplock);
diff --git a/sql/backends/monet5/sql_gencode.c 
b/sql/backends/monet5/sql_gencode.c
--- a/sql/backends/monet5/sql_gencode.c
+++ b/sql/backends/monet5/sql_gencode.c
@@ -1131,6 +1131,7 @@ backend_dumpproc_body(backend *be, Clien
                c->curprg->def->errors = SQLoptimizeFunction(c,c->curprg->def);
        if (c->curprg->def->errors) {
                sql_error(m, 10, SQLSTATE(42000) "Internal error while 
compiling statement: %s", c->curprg->def->errors);
+               res = -1;
        } else {
                res = 0;                                /* success */
        }
@@ -1585,7 +1586,8 @@ backend_create_sql_func_body(backend *be
                        res = -1;
                        goto cleanup;
                }
-               f->imp = fimp;
+               if (fimp)
+                       f->imp = fimp;
                f->instantiated = TRUE; /* make sure 'instantiated' gets set 
after 'imp' */
        }
        MT_lock_unset(&sql_gencodeLock);
@@ -1618,18 +1620,22 @@ backend_create_sql_func(backend *be, sql
        exception_buffer ebsave = *ma_get_eb(m->sa);
        char befname[IDLENGTH];
        int nargs;
-       char *fimp;
+       char *fimp = NULL;
 
        /* already instantiated or instantiating a recursive function */
        if (f->instantiated || (m->forward && m->forward->base.id == 
f->base.id))
                return 0;
 
-       (void) snprintf(befname, sizeof(befname), "f_" ULLFMT, 
store_function_counter(m->store));
-       TRC_INFO(SQL_PARSER, "Mapping SQL name '%s' to MAL name '%s'\n", 
f->base.name, befname);
+       if (!prepare || !f->imp) {
+               (void) snprintf(befname, sizeof(befname), "f_" ULLFMT, 
store_function_counter(m->store));
+               TRC_INFO(SQL_PARSER, "Mapping SQL name '%s' to MAL name 
'%s'\n", f->base.name, befname);
+       }
        nargs = (f->res && f->type == F_UNION ? list_length(f->res) : 1) + 
(f->vararg && ops ? list_length(ops) : f->ops ? list_length(f->ops) : 0);
-       c->curprg = newFunctionArgs(modname, putName(befname), FUNCTIONsymbol, 
nargs);
+       c->curprg = newFunctionArgs(modname, putName(prepare ? f->imp : 
befname), FUNCTIONsymbol, nargs);
 
-       if ((fimp = _STRDUP(befname)) == NULL) {
+       if (prepare)
+               fimp = f->imp;
+       if (!fimp && (fimp = _STRDUP(befname)) == NULL) {
                sql_error(m, 10, SQLSTATE(HY013) MAL_MALLOC_FAIL);
                goto bailout;
        } else if (c->curprg == NULL) {
@@ -1647,7 +1653,8 @@ backend_create_sql_func(backend *be, sql
        *ma_get_eb(m->sa) = ebsave;
        return 0;
   bailout:
-       _DELETE(fimp);
+       if (!prepare)
+               _DELETE(fimp);
        *be = bebackup;
        c->curprg = symbackup;
        *ma_get_eb(m->sa) = ebsave;
diff --git 
a/sql/test/BugTracker-2026/Tests/7972-orderby-limit-subquery-bug.test 
b/sql/test/BugTracker-2026/Tests/7972-orderby-limit-subquery-bug.test
new file mode 100644
--- /dev/null
+++ b/sql/test/BugTracker-2026/Tests/7972-orderby-limit-subquery-bug.test
@@ -0,0 +1,65 @@
+statement ok
+CREATE TABLE r0 (id INT PRIMARY KEY, c0 INT)
+
+statement ok
+INSERT INTO r0 VALUES (1,10)
+
+statement ok
+CREATE TABLE r1 (id INT PRIMARY KEY, c0 INT, c1 INT)
+
+statement ok
+INSERT INTO r1 VALUES (1,10,111),(2,10,222)
+
+statement ok
+CREATE TABLE r2 (id INT PRIMARY KEY, c0 INT, c1 INT)
+
+statement ok
+INSERT INTO r2 VALUES (1,10,999),(2,10,111)
+
+-- (A) Direction ignored: expect 222, get 111
+-- observed: 111 (WRONG — same as ASC)
+query I rowsort
+SELECT (SELECT r1.c1 FROM r1 WHERE r1.c0 = r0.c0 ORDER BY r1.id DESC LIMIT 1) 
AS sq FROM r0
+----
+222
+
+query I rowsort
+SELECT (SELECT r1.c1 FROM r1 WHERE r1.c0 = r0.c0 ORDER BY r1.id ASC LIMIT 1) 
AS sq FROM r0
+----
+111
+
+-- (B) Non-correlated control: correct
+-- observed: 222 (correct)
+query I rowsort
+SELECT (SELECT r1.c1 FROM r1 WHERE r1.c0 = 10 ORDER BY r1.id DESC LIMIT 1) 
FROM r0
+----
+222
+
+-- (C) Column ignored: expect 111 (smallest c1), get 999 (insertion-first row)
+-- observed: 999 (WRONG)
+query I rowsort
+SELECT (SELECT r2.c1 FROM r2 WHERE r2.c0 = r0.c0 ORDER BY r2.c1 LIMIT 1) AS sq 
FROM r0
+----
+111
+
+query I rowsort
+SELECT (SELECT r2.c1 FROM r2 WHERE r2.c0 = r0.c0 ORDER BY r2.c1 DESC LIMIT 1) 
AS sq FROM r0
+----
+999
+
+-- (D) Non-correlated control: correct
+-- observed: 111 (correct)
+query I rowsort
+SELECT (SELECT r2.c1 FROM r2 WHERE r2.c0 = 10 ORDER BY r2.c1 LIMIT 1) FROM r0
+----
+111
+
+statement ok
+DROP TABLE IF EXISTS r0
+
+statement ok
+DROP TABLE IF EXISTS r1
+
+statement ok
+DROP TABLE IF EXISTS r2
+
diff --git a/sql/test/BugTracker-2026/Tests/7973-groupby-list-null-row-bug.test 
b/sql/test/BugTracker-2026/Tests/7973-groupby-list-null-row-bug.test
new file mode 100644
--- /dev/null
+++ b/sql/test/BugTracker-2026/Tests/7973-groupby-list-null-row-bug.test
@@ -0,0 +1,135 @@
+statement ok
+CREATE TABLE br_rollup_t (id INT PRIMARY KEY, c0 INT)
+
+statement ok
+INSERT INTO br_rollup_t VALUES (1,10),(2,20)        -- note: no NULL in c0
+
+-- (1) bare ROLLUP: the super-aggregate row's c0 is projected as NULL -- 
correct
+-- observed: (10,1) (20,1) (NULL,2)                                    correct
+query II rowsort
+SELECT c0, COUNT(*) AS n FROM br_rollup_t GROUP BY ROLLUP(c0)
+----
+10
+1
+20
+1
+
+-- (2) the same row, four ways of asking "is c0 null?" -- they disagree
+-- observed: (10,10,0,'IS NULL -> FALSE',1)
+--           (20,20,0,'IS NULL -> FALSE',1)
+--           (NULL,-1,1,'IS NULL -> FALSE',2)   <-- WRONG: value is NULL, 
GROUPING says 1,
+--                                                  COALESCE says NULL, IS 
NULL says FALSE
+query IIITI rowsort
+SELECT c0, COALESCE(c0,-1) AS coalesced, GROUPING(c0) AS grp,
+       CASE WHEN c0 IS NULL THEN 'IS NULL -> TRUE' ELSE 'IS NULL -> FALSE' END 
AS pred,
+       COUNT(*) AS n
+FROM br_rollup_t GROUP BY ROLLUP(c0)
+----
+10
+10
+0
+IS NULL -> FALSE
+1
+20
+20
+0
+IS NULL -> FALSE
+1
+NULL
+-1
+1
+IS NULL -> TRUE
+2
+
+-- (3) filter the super-aggregate row out: it is not removed
+-- observed: (10,1) (20,1) (NULL,2)   <-- WRONG      expected: (10,1) (20,1)
+query II rowsort
+SELECT c0, n FROM (SELECT c0, COUNT(*) AS n FROM br_rollup_t GROUP BY 
ROLLUP(c0)) x
+WHERE x.c0 IS NOT NULL
+----
+10
+1
+20
+1
+
+-- (4) dual form: select only the super-aggregate row -- nothing comes back
+-- observed: <empty>                  <-- WRONG      expected: (NULL,2)
+query II rowsort
+SELECT c0, n FROM (SELECT c0, COUNT(*) AS n FROM br_rollup_t GROUP BY 
ROLLUP(c0)) x
+WHERE x.c0 IS NULL
+----
+NULL
+2
+
+-- (5) HAVING form
+-- observed: (10,1) (20,1) (NULL,2)   <-- WRONG      expected: (10,1) (20,1)
+query II rowsort
+SELECT c0, COUNT(*) AS n FROM br_rollup_t GROUP BY ROLLUP(c0) HAVING c0 IS NOT 
NULL
+----
+10
+1
+20
+1
+
+-- (6) GROUPING() consistency criterion: a row with GROUPING(c0)=1 must have 
c0 NULL,
+--     so this count must be 0 in every conforming implementation
+-- observed: 1                        <-- WRONG      expected: 0
+query I rowsort
+SELECT COUNT(*) AS should_be_zero
+FROM (SELECT c0 AS k, GROUPING(c0) AS g, COUNT(*) AS n FROM br_rollup_t GROUP 
BY ROLLUP(c0)) x
+WHERE x.g = 1 AND x.k IS NOT NULL
+----
+0
+
+-- (7) CONTROL: same query, one NULL added to c0 -- everything becomes correct
+statement ok
+CREATE TABLE br_rollup_n (id INT PRIMARY KEY, c0 INT)
+
+statement ok
+INSERT INTO br_rollup_n VALUES (1,10),(2,20),(3,NULL)
+
+-- observed: (10,1) (20,1)            correct
+query II rowsort
+SELECT c0, n FROM (SELECT c0, COUNT(*) AS n FROM br_rollup_n GROUP BY 
ROLLUP(c0)) x
+WHERE x.c0 IS NOT NULL
+----
+10
+1
+20
+1
+
+-- observed: 0                        correct
+query I rowsort
+SELECT COUNT(*) AS should_be_zero
+FROM (SELECT c0 AS k, GROUPING(c0) AS g, COUNT(*) AS n FROM br_rollup_n GROUP 
BY ROLLUP(c0)) x
+WHERE x.g = 1 AND x.k IS NOT NULL
+----
+0
+
+-- (8) CUBE and GROUPING SETS are affected identically
+-- observed: (10,1) (20,1) (NULL,2)   <-- WRONG      expected: (10,1) (20,1)
+query II rowsort
+SELECT c0, n FROM (SELECT c0, COUNT(*) AS n FROM br_rollup_t GROUP BY 
CUBE(c0)) x
+WHERE x.c0 IS NOT NULL
+----
+10
+1
+20
+1
+
+-- observed: (10,1) (20,1) (NULL,2)   <-- WRONG      expected: (10,1) (20,1)
+query II rowsort
+SELECT c0, n FROM (SELECT c0, COUNT(*) AS n FROM br_rollup_t GROUP BY GROUPING 
SETS ((c0),())) x
+WHERE x.c0 IS NOT NULL
+----
+10
+1
+20
+1
+
+statement ok
+DROP TABLE IF EXISTS br_rollup_n
+
+statement ok
+DROP TABLE IF EXISTS br_rollup_t
+
diff --git 
a/sql/test/BugTracker-2026/Tests/7974-muli-column-not-in-subquery-bug.test 
b/sql/test/BugTracker-2026/Tests/7974-muli-column-not-in-subquery-bug.test
new file mode 100644
--- /dev/null
+++ b/sql/test/BugTracker-2026/Tests/7974-muli-column-not-in-subquery-bug.test
@@ -0,0 +1,137 @@
+statement ok
+CREATE TABLE br_o_null     (id INT, a INT, b INT)
+
+statement ok
+CREATE TABLE br_o_nonull   (id INT, a INT, b INT)
+
+statement ok
+CREATE TABLE br_o_bothcols (id INT, a INT, b INT)
+
+statement ok
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to