From 77dd26bbed8ddf55cd29a9cfcbf50ef15a95eb93 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 6 Oct 2026 10:30:12 +0000 Subject: [PATCH] Fix a case causing infinitely recursive calls to vec1.xSavepoint. FossilOrigin-Name: a6f0843000e537a68be9e65693e8da276a4f66302a9a3c72f3a3417b6d275272 --- ext/vec1/test/vec1overflow.test | 55 +++++++++++++++++++++++++++++++++ ext/vec1/vec1.c | 18 +++++++++-- manifest | 15 ++++----- manifest.uuid | 2 +- 4 files changed, 79 insertions(+), 11 deletions(-) create mode 100644 ext/vec1/test/vec1overflow.test diff --git a/ext/vec1/test/vec1overflow.test b/ext/vec1/test/vec1overflow.test new file mode 100644 index 0000000000..d88b2fc238 --- /dev/null +++ b/ext/vec1/test/vec1overflow.test @@ -0,0 +1,55 @@ +# 2026-10-06 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# Test cases where a %_idx list is flushed to disk mid-transaction. +# + +source [file join [file dirname [info script]] vec1_common.tcl] +set testprefix vec1overflow +vec1_load db + +do_execsql_test 1.0 { + CREATE VIRTUAL TABLE v1 USING vec1(v); + CREATE TABLE t1(x); + WITH s(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<100) + INSERT INTO t1 SELECT random_vector(8) FROM s; + INSERT INTO v1(cmd, arg) VALUES('rebuild', ( + SELECT vec1_train(x, '{nbucket:1}') FROM t1 + )); + INSERT INTO v1(rowid, v) SELECT rowid, x FROM t1; +} + +do_execsql_test 1.1 { + INSERT INTO v1(rowid, v) VALUES(4294967296, random_vector(8)); + PRAGMA integrity_check; +} {ok} + +reset_db +vec1_load db +do_execsql_test 2.0 { + CREATE VIRTUAL TABLE v1 USING vec1(v); + CREATE TABLE t1(x); + WITH s(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<100) + INSERT INTO t1 SELECT random_vector(8) FROM s; + INSERT INTO v1(cmd, arg) VALUES('rebuild', ( + SELECT vec1_train(x, '{nbucket:1}') FROM t1 + )); + INSERT INTO v1(cmd, arg) VALUES('blocksize', 1024); +} + +do_execsql_test 2.1 { + WITH s(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<200) + INSERT INTO v1(rowid, v) SELECT i, random_vector(8) FROM s; + SELECT count(*)>1 FROM v1_idx; + PRAGMA integrity_check; +} {1 ok} + +finish_test diff --git a/ext/vec1/vec1.c b/ext/vec1/vec1.c index 47fe15c97e..ba07d080fd 100644 --- a/ext/vec1/vec1.c +++ b/ext/vec1/vec1.c @@ -5870,7 +5870,7 @@ static int vec1PrepareSql( } #define VEC1_SQL_SCAN_BASE 1 -#define VEC1_SQL_REPLACE_IDX 2 +#define VEC1_SQL_INSERT_IDX 2 #define VEC1_SQL_SCAN_IDX 3 #define VEC1_SQL_CNT_IDX 4 @@ -5889,7 +5889,7 @@ static int vec1GetSql(Vec1Tab *pTab, int eSql, sqlite3_stmt **ppStmt){ #define VEC1_SQL_INSERT_BASE 0 "INSERT INTO %Q.'%q_base' VALUES(?, ?%s)", "SELECT * FROM %Q.'%q_base' ORDER BY 1", - "REPLACE INTO %Q.'%q_idx'(id, bucket, first, last, val)VALUES(?,?,?,?,?)", + "INSERT INTO %Q.'%q_idx'(id, bucket, first, last, val)VALUES(?,?,?,?,?)", "SELECT val, bucket, rowid FROM %Q.'%q_idx'", "SELECT sum( length(val) / ? ) FROM %Q.'%q_idx'", @@ -9983,7 +9983,19 @@ static int vec1ListBuilderFlush(Vec1ListBuilder *p){ memcpy(&aBlob[VEC1_LIST_SZHDR], p->bufRowid.a, p->bufRowid.n); memcpy(&aBlob[VEC1_LIST_SZHDR+p->bufRowid.n], p->bufData.a, p->bufData.n); - rc = vec1GetSql(p->pTab, VEC1_SQL_REPLACE_IDX, &pStmt); + if( p->iId>0 ){ + /* If there is an existing entry, remove it */ + rc = vec1GetSql(p->pTab, VEC1_SQL_DELETE_FROM_IDX, &pStmt); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pStmt, 1, p->iId); + sqlite3_step(pStmt); + vec1StmtReset(&rc, pStmt); + } + } + + if( rc==SQLITE_OK ){ + rc = vec1GetSql(p->pTab, VEC1_SQL_INSERT_IDX, &pStmt); + } if( rc==SQLITE_OK ){ if( p->iId==0 ){ sqlite3_bind_null(pStmt, 1); diff --git a/manifest b/manifest index 1bd25f033a..b6d82c68ac 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sbuild\sfor\sSQLITE_OMIT_WSD. -D 2026-10-06T09:30:23.599 +C Fix\sa\scase\scausing\sinfinitely\srecursive\scalls\sto\svec1.xSavepoint. +D 2026-10-06T10:30:12.845 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -623,6 +623,7 @@ F ext/vec1/test/vec1meta.test 5a3ae0338a6168bab4a381817b13425028b6ab04dff2700650 F ext/vec1/test/vec1meta2.test 4997a26728d24aaf8219b3c168209df00f8174eec521415ff94dfdd2d7db5da0 F ext/vec1/test/vec1meta3.test 91907adb451e17b777f526dd39c8cdfd2c5928a47b3a864eb2df6b812a8ce461 F ext/vec1/test/vec1nan.test 3ff3fe4b0f33a5c1f4129ba318443e7d927fd9dd6fc339349fea3c57fe140a8c +F ext/vec1/test/vec1overflow.test f007c6b149b434bc6593501c48214535151cb989620e18d48dbca51e7d9c98c7 F ext/vec1/test/vec1pq.test 81d74f516971a3883782d2d443efe3f6a7501d4c9f980a758e1c2eb8b5f22885 F ext/vec1/test/vec1query.test 7120a2824b9f6563f7986c436204870c9d6e4af2bff3a39d38ef277188ef9189 F ext/vec1/test/vec1rollback.test 41565f526e153b24615ed38edda835fbb185f2f07f5e72f5c947add810b33d71 @@ -640,7 +641,7 @@ F ext/vec1/tool/vec1_algo_test.c c62b828a3e46a39a8656f26b74804906cc3160758f8afc6 F ext/vec1/tool/vec1bench.tcl a117caee3cb99712f0477fe2fa85c94c260866951d3a9d667b62631b480c2d2d F ext/vec1/tool/vec1bench_addcols.tcl 8c509253d07b179928f2ee32e3591a2c70d13c914217e1328c01afa148717051 F ext/vec1/tool/vec1bench_vibe2db.py 84ddb0236bc3d02a0393abce41986a1b7dad7f0d83884576f8318c2883e3aed3 -F ext/vec1/vec1.c 08cd74248dd2707e8a59943007e1dbcac2946e60b9d55c261f4810d1689b17fa +F ext/vec1/vec1.c 80a28a4914a0abea720372d9ae36f6855aa664edfa0709542a0abce5945fe440 F ext/wasm/GNUmakefile cc28e65dec12f1b992957152d8395484f4fcf7f94e6b6736a09ee4f48e7ec048 F ext/wasm/README-dist.txt f01081a850ce38a56706af6b481e3a7878e24e42b314cfcd4b129f0f8427066a F ext/wasm/README.md 2e87804e12c98f1d194b7a06162a88441d33bb443efcfe00dc6565a780d2f259 @@ -2279,8 +2280,8 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee F tool/warnings.sh a554d13f6e5cf3760f041b87939e3d616ec6961859c3245e8ef701d1eafc2ca2 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c -P a61987887a942abc4bdd10691455211b9b93028dd8c6cd5302bbd406f6474cc7 -R e0073611c3c3666a5d43429d53f9b682 -U drh -Z 09a82a3497a92b71660982af068e85b0 +P 4bf968095f427e87ae3afe498f74e00e9058b154e12e2d261f317640f4b49cc4 +R 45397a61da4ae3f4271291969ad517da +U dan +Z 51feb3211d73fd62480d652a105feaad # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index faed779184..146fbb5650 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4bf968095f427e87ae3afe498f74e00e9058b154e12e2d261f317640f4b49cc4 +a6f0843000e537a68be9e65693e8da276a4f66302a9a3c72f3a3417b6d275272