Changeset: 0ca2fb7cf7c6 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/0ca2fb7cf7c6 Modified Files: gdk/gdk_logger.c sql/test/BugTracker-2023/Tests/misc-crashes-7390.test Branch: default Log Message:
Merge with Dec2023 branch. diffs (234 lines): diff --git a/gdk/ChangeLog.Dec2023 b/gdk/ChangeLog.Dec2023 --- a/gdk/ChangeLog.Dec2023 +++ b/gdk/ChangeLog.Dec2023 @@ -1,3 +1,10 @@ # ChangeLog file for GDK # This file is updated with Maddlog +* Fri Mar 1 2024 Sjoerd Mullender <sjo...@acm.org> +- Fixed a regression where bats weren't always cleaned up when they + weren't needed anymore. In particular, after a DELETE FROM table query + without a WHERE clause (which deletes all rows from the table), the + bats for the table get replaced by new ones, and the old, now unused, + bats weren't removed from the database. + diff --git a/gdk/gdk_logger.c b/gdk/gdk_logger.c --- a/gdk/gdk_logger.c +++ b/gdk/gdk_logger.c @@ -1224,6 +1224,8 @@ log_read_transaction(logger *lg, uint32_ bool ok = true; ATOMIC_BASE_TYPE dbg = ATOMIC_GET(&GDKdebug); + (void) maxupdated; /* only used inside assert() */ + if (!lg->flushing) ATOMIC_AND(&GDKdebug, ~CHECKMASK); @@ -1251,16 +1253,40 @@ log_read_transaction(logger *lg, uint32_ if (updated && BAThash(lg->catalog_id) == GDK_SUCCEED) { BATiter cni = bat_iterator(lg->catalog_id); BUN p; + BUN posnew = BUN_NONE; + BUN posold = BUN_NONE; MT_rwlock_rdlock(&cni.b->thashlock); HASHloop_int(cni, cni.b->thash, p, &l.id) { - (void)maxupdated; - assert(p < maxupdated); - updated[p / 32] |= 1U << (p % 32); - /* there should only be one hit */ - break; + lng lid = *(lng *) Tloc(lg->catalog_lid, p); + if (lid == lng_nil || lid > tr->tid) + posnew = p; + else if (lid == tr->tid) + posold = p; } MT_rwlock_rdunlock(&cni.b->thashlock); bat_iterator_end(&cni); + /* Normally at this point, posnew is the + * location of the bat that this + * transaction is working on, and posold + * is the location of the previous + * version of the bat. If LOG_CREATE, + * both are relevant, since the latter + * is the new bat, and the former is the + * to-be-destroyed bat. For + * LOG_DESTROY, only posnew should be + * relevant, but for the other types, if + * the table is destroyed later in the + * same transaction, we need posold, and + * else (the normal case) we need + * posnew. */ + if (posnew != BUN_NONE) { + assert(posnew < maxupdated); + updated[posnew / 32] |= 1U << (posnew % 32); + } + if ((l.flag == LOG_CREATE || posnew == BUN_NONE) && posold != BUN_NONE) { + assert(posold < maxupdated); + updated[posold / 32] |= 1U << (posold % 32); + } } break; default: @@ -2643,8 +2669,7 @@ log_flush(logger *lg, ulng ts) TRC_CRITICAL(GDK, "log_id filename is too large\n"); return GDK_FAIL; } - if ((filename = - GDKfilepath(BBPselectfarm(PERSISTENT, 0, offheap), lg->dir, LOGFILE, id)) == NULL) { + if ((filename = GDKfilepath(BBPselectfarm(PERSISTENT, 0, offheap), lg->dir, LOGFILE, id)) == NULL) { GDKfree(updated); return GDK_FAIL; } @@ -3386,8 +3411,9 @@ log_add_bat(logger *lg, BAT *b, log_id i bid = b->batCacheid; TRC_DEBUG(WAL, "create %d\n", id); assert(log_find(lg->catalog_bid, lg->dcatalog, bid) == BUN_NONE); - if (BUNappend(lg->catalog_bid, &bid, true) != GDK_SUCCEED || BUNappend(lg->catalog_id, &id, true) != GDK_SUCCEED - || BUNappend(lg->catalog_cnt, &cnt, false) != GDK_SUCCEED || + if (BUNappend(lg->catalog_bid, &bid, true) != GDK_SUCCEED || + BUNappend(lg->catalog_id, &id, true) != GDK_SUCCEED || + BUNappend(lg->catalog_cnt, &cnt, false) != GDK_SUCCEED || BUNappend(lg->catalog_lid, &lid, false) != GDK_SUCCEED) return GDK_FAIL; if (lg->current) 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 @@ -319,49 +319,66 @@ UPDATE v0 SET v1 = (SELECT LAG(v1 * v1) statement ok DROP TABLE v0 --- -- 23.sql --- statement ok --- CREATE TABLE v0 (v1 INTEGER PRIMARY KEY) +-- 23.sql +statement ok +CREATE TABLE v0 (v1 INTEGER PRIMARY KEY) + +query I nosort +SELECT 67 + 0 + -1 + 96 + 46463082.000000 + 30 AS v2 FROM v0 WHERE 255 = v1 LIMIT 66 OFFSET 16 +---- --- statement ok --- UPDATE v0 SET v1 = -128 WHERE v1 = 1 AND v1 IN (WITH v0 AS (SELECT v1 * (95 - v1) FROM v0 ORDER BY v1, v1 DESC, ('x' < v1 AND v1 = 24)) SELECT 67 + 0 + -1 + 96 + 46463082.000000 + 30 AS v2 FROM v0 WHERE 255 = v1 LIMIT 66 OFFSET 16) OR (69 AND 30) OR ('x' >= 9) +query I nosort +SELECT v1 * (95 - v1) FROM v0 ORDER BY v1, v1 DESC, ('x' < v1 AND v1 = 24) +---- --- statement ok --- DROP TABLE v0 +statement error 42000!SELECT: identifier 'v1' unknown +WITH v0 AS (SELECT v1 * (95 - v1) FROM v0 ORDER BY v1, v1 DESC, ('x' < v1 AND v1 = 24)) SELECT 67 + 0 + -1 + 96 + 46463082.000000 + 30 AS v2 FROM v0 WHERE 255 = v1 LIMIT 66 OFFSET 16 +---- + +skipif knownfail +statement ok +UPDATE v0 SET v1 = -128 WHERE v1 = 1 AND v1 IN (WITH v0 AS (SELECT v1 * (95 - v1) FROM v0 ORDER BY v1, v1 DESC, ('x' < v1 AND v1 = 24)) SELECT 67 + 0 + -1 + 96 + 46463082.000000 + 30 AS v2 FROM v0 WHERE 255 = v1 LIMIT 66 OFFSET 16) OR (69 AND 30) OR ('x' >= 9) + +statement ok +DROP TABLE v0 -- 24.sql --- statement ok --- CREATE TABLE v0(v1 FLOAT) +statement ok +CREATE TABLE v0(v1 FLOAT) --- statement ok --- INSERT INTO v0 VALUES (0),(67),(127),(-1),(NULL),(NULL),(NULL),(NULL) +statement ok +INSERT INTO v0 VALUES (0),(67),(127),(-1),(NULL),(NULL),(NULL),(NULL) --- query IT nosort --- SELECT * , 'x' FROM v0 WHERE (SELECT 39 WHERE (v1 + -32768 NOT IN (14, 255))) * 87 + 2147483647 --- ---- --- 0 --- x --- 67 --- x --- 127 --- x --- -1 --- x +query IT nosort +SELECT * , 'x' FROM v0 WHERE (SELECT 39 WHERE (v1 + -32768 NOT IN (14, 255))) * 87 + 2147483647 +---- +0 +x +67 +x +127 +x +-1 +x --- statement ok --- WITH v0 AS (SELECT 14, * FROM v0) INSERT INTO v0 SELECT v1 * 0 FROM v0 NATURAL JOIN v0, v0, v0 AS v2, v0, v0 AS v3 ORDER BY v1 * 0 / 77 +statement ok +WITH v0 AS (SELECT 14, * FROM v0) INSERT INTO v0 SELECT v1 * 0 FROM v0 NATURAL JOIN v0, v0, v0 AS v2, v0, v0 AS v3 ORDER BY v1 * 0 / 77 --- query I nosort --- SELECT count(*) FROM v0 --- ---- --- 131080 +query I nosort +SELECT count(*) FROM v0 +---- +131080 --- statement crashes server --- SELECT * , 'x' FROM v0 WHERE (SELECT 39 WHERE (v1 + -32768 NOT IN (14, 255))) * 87 + 2147483647 +-- after the second insert, rerun same query as above, now it crashes server +skipif knownfail +query IT nosort +SELECT * , 'x' FROM v0 WHERE (SELECT 39 WHERE (v1 + -32768 NOT IN (14, 255))) * 87 + 2147483647 +---- + -- mul_bte_bte_bte: ERROR: 22003!overflow in calculation 87*39. --- statement ok --- DROP TABLE v0 +statement ok +DROP TABLE v0 -- 25.sql statement ok @@ -424,10 +441,11 @@ 0.000 statement ok DROP TABLE v0 --- -- 29.sql --- statement error --- SELECT ALL ( SELECT - - - - - - - - - - 48 FROM ( SELECT NULL - - - - - - - - 89 FROM ( VALUES ( - - - - - - - - - - 74 ) , ( - - - - - 128 ) , ( - - - - - - 8 ) , ( - - - - 61 ) ) AS v1 ( v1 ) GROUP BY ( ) , GROUPING SETS ( GROUPING SETS ( GROUPING SETS ( ( ) ) ) ) , ( ) ORDER BY - - - - - - - - - - 255 LIKE v1 / CASE WHEN v1 IS NULL THEN - - 75 END DESC , v1 , v1 LIMIT 63 ) AS v1 UNION SELECT - - - - - - - - - - - - - 74 WHERE - v1 < - 89088397.000000 ) FROM ( SELECT * FROM ( VALUES ( - - - - - - - 61 ) , ( - - - 42 ) ) AS v1 ( v1 ) ) AS v1 ( v1 ) --- sql/server/rel_select.c:4614: rel_groupings: Assertion `next_set' failed. +-- 29.sql +skipif knownfail +statement error +SELECT ALL ( SELECT - - - - - - - - - - 48 FROM ( SELECT NULL - - - - - - - - 89 FROM ( VALUES ( - - - - - - - - - - 74 ) , ( - - - - - 128 ) , ( - - - - - - 8 ) , ( - - - - 61 ) ) AS v1 ( v1 ) GROUP BY ( ) , GROUPING SETS ( GROUPING SETS ( GROUPING SETS ( ( ) ) ) ) , ( ) ORDER BY - - - - - - - - - - 255 LIKE v1 / CASE WHEN v1 IS NULL THEN - - 75 END DESC , v1 , v1 LIMIT 63 ) AS v1 UNION SELECT - - - - - - - - - - - - - 74 WHERE - v1 < - 89088397.000000 ) FROM ( SELECT * FROM ( VALUES ( - - - - - - - 61 ) , ( - - - 42 ) ) AS v1 ( v1 ) ) AS v1 ( v1 ) +-- sql/server/rel_select.c:4616: rel_groupings: Assertion `next_set' failed. -- 30.sql statement ok @@ -541,11 +559,15 @@ statement ok DROP TABLE v0 -- 40.sql --- statement ok --- CREATE TABLE v0(v2 DOUBLE, v1 REAL) +statement ok +CREATE TABLE v0(v2 DOUBLE, v1 REAL) + +statement error 42S22!SELECT: no such column 'v0.v2' +SELECT 2 FROM v0 AS WHERE v0 . v2 = ( SELECT v2 WHERE v2 = 2 ) + v0 . v1 --- statement ok --- DELETE FROM v0 WHERE EXISTS (SELECT 2 FROM v0 AS WHERE v0.v2 = (SELECT v2 WHERE v2 = 2) + v0.v1) +skipif knownfail +statement error 42S22!SELECT: no such column 'v0.v2' +DELETE FROM v0 WHERE EXISTS ( SELECT 2 FROM v0 AS WHERE v0 . v2 = ( SELECT v2 WHERE v2 = 2 ) + v0 . v1 ) --- statement ok --- DROP TABLE v0 +statement ok +DROP TABLE v0 _______________________________________________ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org