Changeset: 8e99c6d33c7f for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/8e99c6d33c7f
Modified Files:
gdk/gdk_string.c
sql/test/BugTracker-2026/Tests/All
Branch: default
Log Message:
Merge with Dec2025 branch.
diffs (truncated from 410 to 300 lines):
diff --git a/gdk/gdk_calc_private.h b/gdk/gdk_calc_private.h
--- a/gdk/gdk_calc_private.h
+++ b/gdk/gdk_calc_private.h
@@ -31,11 +31,11 @@
#define GT(a, b) ((bit) ((a) > (b)))
-#if !defined(__clang__) || __clang_major__ >= 21
-/* compiling with clang on Ubuntu 24.04 fails when using
- * __builtin_mul_overflow, so we avoid using it when using the version
- * of clang that is installed on said system (clang on Ubuntu 26.04 does
- * work) */
+#if defined(__aarch64__) && (!defined(__clang__) || __clang_major__ >= 21)
+/* compiling with clang on Ubuntu 24.04 on aarch64 (aka arm64) fails
+ * when using __builtin_mul_overflow, so we avoid using it when using
+ * the version of clang that is installed on said system (clang on
+ * Ubuntu 26.04 does work) */
#ifdef __has_builtin
#if __has_builtin(__builtin_add_overflow)
#define OP_WITH_CHECK(lft, rgt, TYPE3, dst, op, max, on_overflow) \
diff --git a/gdk/gdk_string.c b/gdk/gdk_string.c
--- a/gdk/gdk_string.c
+++ b/gdk/gdk_string.c
@@ -1099,6 +1099,7 @@ concat_strings(allocator *ma, BAT **bnp,
assert((bnp == NULL) != (pt == NULL));
/* if pt not NULL, only a single group allowed */
assert(pt == NULL || ngrp == 1);
+ assert(separator == NULL || !strNil(separator));
if (bnp) {
if ((bn = COLnew(min, TYPE_str, ngrp, TRANSIENT)) == NULL) {
@@ -1147,15 +1148,8 @@ concat_strings(allocator *ma, BAT **bnp,
}
} else {
single_length += strlen(s);
- if (!empty) {
- if (strNil(sl)) {
- if (!skip_nils) {
- nils = 1;
- break;
- }
- } else
- single_length +=
strlen(sl);
- }
+ if (!empty && !strNil(sl))
+ single_length += strlen(sl);
empty = false;
}
}
@@ -1285,13 +1279,11 @@ concat_strings(allocator *ma, BAT **bnp,
if (lengths[gid] == (size_t) -1)
continue;
const char *s = BUNtvar(&bi, i);
- const char *sl = BUNtvar(&bis, i);
if (!strNil(s)) {
+ const char *sl = BUNtvar(&bis,
i);
lengths[gid] += strlen(s);
- if (!strNil(sl)) {
- next_length =
strlen(sl);
- lengths[gid] +=
next_length;
- }
+ next_length = strNil(sl) ? 0 :
strlen(sl);
+ lengths[gid] += next_length;
astrings[gid] = NULL;
} else if (!skip_nils) {
nils++;
@@ -1357,13 +1349,15 @@ concat_strings(allocator *ma, BAT **bnp,
gid = gids[i] - min;
if (astrings[gid]) {
const char *s = BUNtvar(&bi, i);
- const char *sl = BUNtvar(&bis,
i);
if (strNil(s))
continue;
- if (astrings[gid][lengths[gid]]
&& !strNil(sl)) {
- next_length =
strlen(sl);
- memcpy(astrings[gid] +
lengths[gid], sl, next_length);
- lengths[gid] +=
next_length;
+ if
(astrings[gid][lengths[gid]]) {
+ const char *sl =
BUNtvar(&bis, i);
+ if (!strNil(sl)) {
+ next_length =
strlen(sl);
+
memcpy(astrings[gid] + lengths[gid], sl, next_length);
+ lengths[gid] +=
next_length;
+ }
}
next_length = strlen(s);
memcpy(astrings[gid] +
lengths[gid], s, next_length);
@@ -1413,20 +1407,21 @@ BATstr_group_concat(allocator *ma, ValPt
{
struct canditer ci;
gdk_return r = GDK_SUCCEED;
- const char *nseparator = separator;
-
- assert((nseparator && !sep) || (!nseparator && sep)); /* only one of
them must be set */
+
+ assert((separator && !sep) || (!separator && sep)); /* only one of them
must be set */
*res = (ValRecord) {.vtype = TYPE_str};
canditer_init(&ci, b, s);
BATiter bi = bat_iterator(sep);
if (sep && BATcount(sep) == 1) { /* Only one element in sep */
- nseparator = BUNtvar(&bi, 0);
+ separator = BUNtvar(&bi, 0);
sep = NULL;
}
-
- if (ci.ncand == 0 || (nseparator && strNil(nseparator))) {
+ if (separator && strNil(separator))
+ separator = "";
+
+ if (ci.ncand == 0) {
if (VALinit(ma, res, TYPE_str, nil_if_empty ? str_nil : "") ==
NULL)
r = GDK_FAIL;
bat_iterator_end(&bi);
@@ -1434,7 +1429,7 @@ BATstr_group_concat(allocator *ma, ValPt
}
r = concat_strings(ma, NULL, res, b, b->hseqbase, 1, &ci, NULL, 0, 0,
- skip_nils, sep, nseparator, NULL);
+ skip_nils, sep, separator, NULL);
bat_iterator_end(&bi);
return r;
}
@@ -1449,9 +1444,8 @@ BATgroupstr_group_concat(BAT *b, BAT *g,
struct canditer ci;
const char *err;
gdk_return res;
- const char *nseparator = separator;
-
- assert((nseparator && !sep) || (!nseparator && sep)); /* only one of
them must be set */
+
+ assert((separator && !sep) || (!separator && sep)); /* only one of them
must be set */
(void) skip_nils;
if ((err = BATgroupaggrinit(b, g, e, s, &min, &max, &ngrp,
@@ -1466,11 +1460,13 @@ BATgroupstr_group_concat(BAT *b, BAT *g,
BATiter bi = bat_iterator(sep);
if (sep && BATcount(sep) == 1) { /* Only one element in sep */
- nseparator = BUNtvar(&bi, 0);
+ separator = BUNtvar(&bi, 0);
sep = NULL;
}
-
- if (ci.ncand == 0 || ngrp == 0 || (nseparator && strNil(nseparator))) {
+ if (separator && strNil(separator))
+ separator = "";
+
+ if (ci.ncand == 0 || ngrp == 0) {
/* trivial: no strings to concat, so return bat
* aligned with g with nil in the tail */
bn = BATconstant(ngrp == 0 ? 0 : min, TYPE_str, str_nil, ngrp,
TRANSIENT);
@@ -1488,7 +1484,7 @@ BATgroupstr_group_concat(BAT *b, BAT *g,
res = concat_strings(NULL, &bn, NULL, b, b->hseqbase, ngrp, &ci,
(const oid *) Tloc(g, 0), min, max, skip_nils, sep,
- nseparator, &nils);
+ separator, &nils);
if (res != GDK_SUCCEED)
bn = NULL;
@@ -1513,6 +1509,7 @@ compute_next_single_str(size_t *mglp, ch
size_t next_length = 0;
size_t offset = 0;
bool empty = true;
+ assert(separator == NULL || !strNil(separator));
for (oid m = start; m < end; m++) {
const char *sb = BUNtvar(bi, m);
@@ -1623,9 +1620,11 @@ GDKanalytical_str_group_concat(BAT *b, B
separator = BUNtvar(&sepi, 0);
sep = NULL;
}
-
- if (sep == NULL)
+ if (separator) {
+ if (strNil(separator))
+ separator = "";
separator_length = strlen(separator);
+ }
if ((bn = COLnew(b->hseqbase, TYPE_str, bi.count, TRANSIENT)) == NULL)
goto bailout;
diff --git
a/sql/test/BugTracker-2026/Tests/7976-dump_database-composite-key-order-bug.test
b/sql/test/BugTracker-2026/Tests/7976-dump_database-composite-key-order-bug.test
new file mode 100644
--- /dev/null
+++
b/sql/test/BugTracker-2026/Tests/7976-dump_database-composite-key-order-bug.test
@@ -0,0 +1,108 @@
+statement ok
+CREATE SCHEMA demo
+
+statement ok
+SET SCHEMA demo
+
+statement ok
+CREATE TABLE parent (
+ a INT NOT NULL,
+ b INT NOT NULL,
+ CONSTRAINT parent_ab UNIQUE (a, b)
+)
+
+statement ok
+CREATE TABLE child (
+ a INT NOT NULL,
+ b INT NOT NULL,
+ CONSTRAINT child_fk
+ FOREIGN KEY (a, b) REFERENCES parent (a, b)
+)
+
+query IT rowsort
+SELECT o.nr, o.name
+FROM sys.objects o
+JOIN sys.keys k ON o.id = k.id
+JOIN sys._tables t ON k.table_id = t.id
+JOIN sys.schemas s ON t.schema_id = s.id
+WHERE s.name = 'demo'
+ AND t.name = 'parent'
+ AND k.type = 1
+ORDER BY o.nr
+----
+0
+a
+1
+b
+
+query T nosort
+SELECT stmt
+FROM sys.dump_table_constraint_type
+WHERE schema_name = 'demo'
+ AND table_name = 'parent'
+----
+ALTER TABLE "demo"."parent" ADD CONSTRAINT "parent_ab" UNIQUE ("a", "b");
+
+statement ok
+CREATE SCHEMA noise
+
+statement ok
+CREATE TABLE noise.unrelated (
+ a INT NOT NULL,
+ b INT NOT NULL,
+ UNIQUE (a, b)
+)
+
+-- The catalogue query still returns 0, a and 1, b
+query IT rowsort
+SELECT o.nr, o.name
+FROM sys.objects o
+JOIN sys.keys k ON o.id = k.id
+JOIN sys._tables t ON k.table_id = t.id
+JOIN sys.schemas s ON t.schema_id = s.id
+WHERE s.name = 'demo'
+ AND t.name = 'parent'
+ AND k.type = 1
+ORDER BY o.nr
+----
+0
+a
+1
+b
+
+-- but the dump query now returns: ALTER TABLE "demo"."parent" ADD CONSTRAINT
"parent_ab" UNIQUE ("b", "a"); -- key columns are reversed
+query T nosort
+SELECT stmt
+FROM sys.dump_table_constraint_type
+WHERE schema_name = 'demo'
+ AND table_name = 'parent'
+----
+ALTER TABLE "demo"."parent" ADD CONSTRAINT "parent_ab" UNIQUE ("a", "b");
+
+query T nosort
+SELECT stmt
+FROM sys.dump_database(TRUE)
+WHERE stmt LIKE 'ALTER TABLE "demo".%'
+ORDER BY o
+----
+ALTER TABLE "demo"."parent" ADD CONSTRAINT "parent_ab" UNIQUE ("a", "b");
+ALTER TABLE "demo"."child" ADD CONSTRAINT "child_fk" FOREIGN KEY("a","b")
REFERENCES "demo"."parent"("a","b") ON DELETE RESTRICT ON UPDATE RESTRICT;
+
+statement ok
+DROP SCHEMA noise CASCADE
+
+-- the dump query now returns: ALTER TABLE "demo"."parent" ADD CONSTRAINT
"parent_ab" UNIQUE ("a", "b");
+query T nosort
+SELECT stmt
+FROM sys.dump_table_constraint_type
+WHERE schema_name = 'demo'
+ AND table_name = 'parent'
+----
+ALTER TABLE "demo"."parent" ADD CONSTRAINT "parent_ab" UNIQUE ("a", "b");
+
+statement ok
+SET SCHEMA sys
+
+statement ok
+DROP SCHEMA demo CASCADE
+
diff --git
a/sql/test/BugTracker-2026/Tests/7985-qualify-row_number-over-bug.test
b/sql/test/BugTracker-2026/Tests/7985-qualify-row_number-over-bug.test
new file mode 100644
--- /dev/null
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]