Changeset: 56e6d2d4b168 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/56e6d2d4b168
Modified Files:
gdk/gdk.h
gdk/gdk_utils.c
monetdb5/modules/mal/tablet.c
Branch: default
Log Message:
Merge with Dec2025 branch.
diffs (232 lines):
diff --git a/gdk/gdk.h b/gdk/gdk.h
--- a/gdk/gdk.h
+++ b/gdk/gdk.h
@@ -1101,10 +1101,14 @@ BATsettrivprop(BAT *b)
/* the only value is NIL */
b->tminpos = BUN_NONE;
b->tmaxpos = BUN_NONE;
+ b->tnil = true;
+ b->tnonil = false;
} else {
/* the only value is both min and max */
b->tminpos = 0;
b->tmaxpos = 0;
+ b->tnonil = true;
+ b->tnil = false;
}
} else {
b->tsorted = false;
diff --git a/gdk/gdk_utils.c b/gdk/gdk_utils.c
--- a/gdk/gdk_utils.c
+++ b/gdk/gdk_utils.c
@@ -2182,6 +2182,24 @@ ma_reset(allocator *sa)
void *
ma_realloc(allocator *sa, void *p, size_t sz, size_t oldsz)
{
+ size_t r_oldsz = round16(oldsz);
+ size_t r_sz = round16(sz);
+ if (r_oldsz <= sa->used &&
+ (char *) sa->blks[sa->nr - 1] + sa->used - r_oldsz == (char *) p) {
+ /* trying to realloc the last allocated buffer, we may
+ * be able to readjust it */
+ if (sz <= oldsz) {
+ /* size reduction */
+ sa->used = sa->used - r_oldsz + r_sz;
+ return p;
+ }
+ if (sa->used - r_oldsz + r_sz <= MA_BLOCK_SIZE) {
+ sa->used = sa->used - r_oldsz + r_sz;
+ return p;
+ }
+ } else if (r_sz <= r_oldsz)
+ return p;
+
void *r = ma_alloc(sa, sz);
if (r)
diff --git a/monetdb5/modules/mal/tablet.c b/monetdb5/modules/mal/tablet.c
--- a/monetdb5/modules/mal/tablet.c
+++ b/monetdb5/modules/mal/tablet.c
@@ -854,7 +854,8 @@ SQLinsert_val(READERtask *task, int col,
char *err = NULL;
int ret = 0;
allocator *ta = MT_thread_getallocator();
- allocator_state ta_state = ma_open(ta);
+ bool opened = false; /* whether ma_open was called */
+ allocator_state ta_state = {0};
allocator *ma = task->cntxt->curprg->def->ma;
/* include testing on the terminating null byte !! */
@@ -864,7 +865,14 @@ SQLinsert_val(READERtask *task, int col,
} else {
if (task->escape) {
size_t slen = strlen(s) + 1;
- char *data = slen <= sizeof(buf) ? buf : ma_alloc(ta,
strlen(s) + 1);
+ char *data;
+ if (slen <= sizeof(buf)) {
+ data = buf;
+ } else {
+ ta_state = ma_open(ta);
+ opened = true;
+ data = ma_alloc(ta, strlen(s) + 1);
+ }
if (data == NULL
|| GDKstrFromStr((unsigned char *) data,
(unsigned char *) s,
strlen(s),
'\0') < 0)
@@ -882,6 +890,10 @@ SQLinsert_val(READERtask *task, int col,
if (task->rowerror) {
err = SQLload_error(task, idx, task->as->nr_attrs);
if (s) {
+ if (!opened) {
+ ta_state = ma_open(ta);
+ opened = true;
+ }
size_t slen = mystrlen(s);
char *scpy = ma_alloc(ta, slen + 1);
if (scpy == NULL) {
@@ -898,7 +910,8 @@ SQLinsert_val(READERtask *task, int col,
s ? " in '" : "", s ? s : "", s ? "'"
: "");
tablet_error(task, idx, row, col, buf, err);
if (!task->besteffort) {
- ma_close(&ta_state);
+ if (opened)
+ ma_close(&ta_state);
return -1;
}
}
@@ -908,7 +921,8 @@ SQLinsert_val(READERtask *task, int col,
fmt->c->tnonil = false;
}
if (bunfastapp(fmt->c, adt) == GDK_SUCCEED) {
- ma_close(&ta_state);
+ if (opened)
+ ma_close(&ta_state);
return ret;
}
@@ -920,7 +934,8 @@ SQLinsert_val(READERtask *task, int col,
&& *msg ? msg : "insert failed", err);
}
task->besteffort = false; /* no longer best effort */
- ma_close(&ta_state);
+ if (opened)
+ ma_close(&ta_state);
return -1;
}
diff --git a/sql/backends/monet5/rel_bin.c b/sql/backends/monet5/rel_bin.c
--- a/sql/backends/monet5/rel_bin.c
+++ b/sql/backends/monet5/rel_bin.c
@@ -2856,7 +2856,7 @@ rel2bin_hash_lookup(backend *be, sql_rel
return stmt_join(be, h, idx, 0, cmp_equal, 0,
semantics, false);
}
} else {
- return stmt_uselect(be, idx, h, cmp_equal, NULL, 0, semantics);
+ return stmt_uselect(be, idx, h, cmp_equal, left->cand, 0,
semantics);
}
}
@@ -4939,6 +4939,10 @@ rel2bin_select(backend *be, sql_rel *rel
sql_idx *i = p->value.pval;
int oldvtop = be->mb->vtop, oldstop = be->mb->stop;
+ if (sel) {
+ sub->cand = sel;
+ sel = NULL;
+ }
if (!(sel = rel2bin_hash_lookup(be, rel, sub, NULL, i,
en))) {
/* hash lookup cannot be used, clean leftover
mal statements */
clean_mal_statements(be, oldstop, oldvtop);
diff --git a/sql/test/BugTracker-2026/Tests/7783-deleted-row.test
b/sql/test/BugTracker-2026/Tests/7783-deleted-row.test
new file mode 100644
--- /dev/null
+++ b/sql/test/BugTracker-2026/Tests/7783-deleted-row.test
@@ -0,0 +1,82 @@
+statement ok
+create table test (a int not null, b int not null, primary key (a, b))
+
+statement ok
+insert into test values (1, 1)
+
+statement ok
+delete from test where a = 1;
+
+statement ok
+insert into test values (1, 1)
+
+-- BUG: returns 2 identical rows (1, 1), this violates the constraint
+query II
+select * from test where a = 1 and b = 1
+----
+1
+1
+
+-- OK: returns 1 row
+query II
+select * from test where a = 1
+----
+1
+1
+
+query II
+select * from test where b = 1
+----
+1
+1
+
+query II
+select * from test
+----
+1
+1
+
+statement ok
+drop table test
+
+-- also happens with a composite unique constraint:
+statement ok
+create table test (a int, b int, unique (a, b))
+
+statement ok
+insert into test values (1, 1)
+
+statement ok
+delete from test where a = 1;
+
+statement ok
+insert into test values (1, 1)
+
+-- BUG: returns 2 identical rows (1, 1), this violates the constraint
+query II
+select * from test where a = 1 and b = 1
+----
+1
+1
+
+-- OK: returns 1 row
+query II
+select * from test where a = 1
+----
+1
+1
+
+query II
+select * from test where b = 1
+----
+1
+1
+
+query II
+select * from test
+----
+1
+1
+
+statement ok
+drop table test
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
@@ -1,1 +1,2 @@
7780-unnest-slow
+7783-deleted-row
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]