Skip to content

Commit 76558e8

Browse files
committed
fix behaviour of VACUUM for vector indices to make rowid consistent
between shadow tables and base table
1 parent 778a13a commit 76558e8

File tree

3 files changed

+34
-29
lines changed

3 files changed

+34
-29
lines changed

libsql-sqlite3/src/vacuum.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717
#include "sqliteInt.h"
1818
#include "vdbeInt.h"
1919

20+
#ifndef SQLITE_OMIT_VECTOR
21+
#include "vectorIndexInt.h"
22+
#endif
23+
2024
#if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH)
2125

2226
/*
@@ -294,6 +298,27 @@ SQLITE_NOINLINE int sqlite3RunVacuum(
294298
if( rc!=SQLITE_OK ) goto end_of_vacuum;
295299
db->init.iDb = 0;
296300

301+
#ifndef SQLITE_OMIT_VECTOR
302+
// shadow tables for vector index will be populated automatically during CREATE INDEX command
303+
// so we must skip them at this step
304+
if( sqlite3FindTable(db, VECTOR_INDEX_GLOBAL_META_TABLE, zDbMain) != NULL ){
305+
rc = execSqlF(db, pzErrMsg,
306+
"SELECT'INSERT INTO vacuum_db.'||quote(name)"
307+
"||' SELECT*FROM\"%w\".'||quote(name)"
308+
"FROM vacuum_db.sqlite_schema "
309+
"WHERE type='table'AND coalesce(rootpage,1)>0 AND name NOT IN (SELECT name||'_shadow' FROM " VECTOR_INDEX_GLOBAL_META_TABLE ")",
310+
zDbMain
311+
);
312+
}else{
313+
rc = execSqlF(db, pzErrMsg,
314+
"SELECT'INSERT INTO vacuum_db.'||quote(name)"
315+
"||' SELECT*FROM\"%w\".'||quote(name)"
316+
"FROM vacuum_db.sqlite_schema "
317+
"WHERE type='table'AND coalesce(rootpage,1)>0 AND name",
318+
zDbMain
319+
);
320+
}
321+
#else
297322
/* Loop through the tables in the main database. For each, do
298323
** an "INSERT INTO vacuum_db.xxx SELECT * FROM main.xxx;" to copy
299324
** the contents to the temporary database.
@@ -305,6 +330,7 @@ SQLITE_NOINLINE int sqlite3RunVacuum(
305330
"WHERE type='table'AND coalesce(rootpage,1)>0",
306331
zDbMain
307332
);
333+
#endif
308334
assert( (db->mDbFlags & DBFLAG_Vacuum)!=0 );
309335
db->mDbFlags &= ~DBFLAG_Vacuum;
310336
if( rc!=SQLITE_OK ) goto end_of_vacuum;

libsql-sqlite3/src/vectorIndex.c

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,6 @@
4949
** VectorIdxParams utilities
5050
****************************************************************************/
5151

52-
// VACUUM creates tables and indices first and only then populate data
53-
// we need to ignore inserts from 'INSERT INTO vacuum.t SELECT * FROM t' statements because
54-
// all shadow tables will be populated by VACUUM process during regular process of table copy
55-
#define IsVacuum(db) ((db->mDbFlags&DBFLAG_Vacuum)!=0)
56-
5752
void vectorIdxParamsInit(VectorIdxParams *pParams, u8 *pBinBuf, int nBinSize) {
5853
assert( nBinSize <= VECTOR_INDEX_PARAMS_BUF_SIZE );
5954

@@ -772,10 +767,6 @@ int vectorIndexDrop(sqlite3 *db, const char *zDbSName, const char *zIdxName) {
772767
// this is done to prevent unrecoverable situations where index were dropped but index parameters deletion failed and second attempt will fail on first step
773768
int rcIdx, rcParams;
774769

775-
if( IsVacuum(db) ){
776-
return SQLITE_OK;
777-
}
778-
779770
assert( zDbSName != NULL );
780771

781772
rcIdx = diskAnnDropIndex(db, zDbSName, zIdxName);
@@ -786,10 +777,6 @@ int vectorIndexDrop(sqlite3 *db, const char *zDbSName, const char *zIdxName) {
786777
int vectorIndexClear(sqlite3 *db, const char *zDbSName, const char *zIdxName) {
787778
assert( zDbSName != NULL );
788779

789-
if( IsVacuum(db) ){
790-
return SQLITE_OK;
791-
}
792-
793780
return diskAnnClearIndex(db, zDbSName, zIdxName);
794781
}
795782

@@ -799,7 +786,7 @@ int vectorIndexClear(sqlite3 *db, const char *zDbSName, const char *zIdxName) {
799786
* this made intentionally in order to natively support upload of SQLite dumps
800787
*
801788
* dump populates tables first and create indices after
802-
* so we must omit them because shadow tables already filled
789+
* so we must omit index refill setp because shadow tables already filled
803790
*
804791
* 1. in case of any error :-1 returned (and pParse errMsg is populated with some error message)
805792
* 2. if vector index must not be created : 0 returned
@@ -817,10 +804,6 @@ int vectorIndexCreate(Parse *pParse, const Index *pIdx, const char *zDbSName, co
817804
int hasLibsqlVectorIdxFn = 0, hasCollation = 0;
818805
const char *pzErrMsg;
819806

820-
if( IsVacuum(pParse->db) ){
821-
return CREATE_IGNORE;
822-
}
823-
824807
assert( zDbSName != NULL );
825808

826809
sqlite3 *db = pParse->db;
@@ -970,7 +953,6 @@ int vectorIndexSearch(
970953
VectorIdxParams idxParams;
971954
vectorIdxParamsInit(&idxParams, NULL, 0);
972955

973-
assert( !IsVacuum(db) );
974956
assert( zDbSName != NULL );
975957

976958
if( argc != 3 ){
@@ -1055,10 +1037,6 @@ int vectorIndexInsert(
10551037
int rc;
10561038
VectorInRow vectorInRow;
10571039

1058-
if( IsVacuum(pCur->db) ){
1059-
return SQLITE_OK;
1060-
}
1061-
10621040
rc = vectorInRowAlloc(pCur->db, pRecord, &vectorInRow, pzErrMsg);
10631041
if( rc != SQLITE_OK ){
10641042
return rc;
@@ -1078,10 +1056,6 @@ int vectorIndexDelete(
10781056
){
10791057
VectorInRow payload;
10801058

1081-
if( IsVacuum(pCur->db) ){
1082-
return SQLITE_OK;
1083-
}
1084-
10851059
payload.pVector = NULL;
10861060
payload.nKeys = r->nField - 1;
10871061
payload.pKeyValues = r->aMem + 1;

libsql-sqlite3/test/libsql_vector_index.test

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,12 +236,17 @@ do_execsql_test vector-attach {
236236

237237
do_execsql_test vector-vacuum {
238238
CREATE TABLE t_vacuum ( emb FLOAT32(2) );
239-
INSERT INTO t_vacuum VALUES (vector('[1,2]')), (vector('[3,4]'));
239+
INSERT INTO t_vacuum VALUES (vector('[1,2]')), (vector('[3,4]')), (vector('[5,6]'));
240240
CREATE INDEX t_vacuum_idx ON t_vacuum(libsql_vector_idx(emb));
241241
VACUUM;
242242
SELECT COUNT(*) FROM t_vacuum;
243243
SELECT COUNT(*) FROM t_vacuum_idx_shadow;
244-
} {2 2}
244+
DELETE FROM t_vacuum WHERE rowid = 2;
245+
VACUUM;
246+
SELECT * FROM vector_top_k('t_vacuum_idx', vector('[1,2]'), 3);
247+
SELECT * FROM vector_top_k('t_vacuum_idx', vector('[5,6]'), 3);
248+
SELECT * FROM vector_top_k('t_vacuum_idx', vector('[3,4]'), 3);
249+
} {3 3 1 2 2 1 2 1}
245250

246251
do_execsql_test vector-many-columns {
247252
CREATE TABLE t_many ( i INTEGER PRIMARY KEY, e1 FLOAT32(2), e2 FLOAT32(2) );

0 commit comments

Comments
 (0)