Fix #if SQLITE_VEC_ENABLE_RESCORE guards wrapping non-rescore logic

Six sites used #if SQLITE_VEC_ENABLE_RESCORE to guard _vector_chunks
skip logic that applies to ALL non-flat index types. When RESCORE was
compiled out, DiskANN and IVF columns would incorrectly access flat
chunk tables. Two sites also missed DiskANN in the skip enumeration,
which would break mixed flat+DiskANN tables.

Fix: replace all six compile-time guards with unconditional runtime
`!= VEC0_INDEX_TYPE_FLAT` checks. Also move rescore_on_delete inside
the !vec0_all_columns_diskann guard to prevent use of uninitialized
chunk_id/chunk_offset, and initialize those variables to 0.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Alex Garcia 2026-03-31 13:51:08 -07:00
parent 3cfc2e0c1f
commit 07f56e3cbe

View file

@ -4625,16 +4625,10 @@ int vec0_new_chunk(vec0_vtab *p, sqlite3_value ** partitionKeyValues, i64 *chunk
} }
int vector_column_idx = p->user_column_idxs[i]; int vector_column_idx = p->user_column_idxs[i];
#if SQLITE_VEC_ENABLE_RESCORE // Non-FLAT columns (rescore, IVF, DiskANN) don't use _vector_chunks
// Rescore and IVF columns don't use _vector_chunks for float storage if (p->vector_columns[vector_column_idx].index_type != VEC0_INDEX_TYPE_FLAT) {
if (p->vector_columns[vector_column_idx].index_type == VEC0_INDEX_TYPE_RESCORE
#if SQLITE_VEC_EXPERIMENTAL_IVF_ENABLE
|| p->vector_columns[vector_column_idx].index_type == VEC0_INDEX_TYPE_IVF
#endif
) {
continue; continue;
} }
#endif
i64 vectorsSize = i64 vectorsSize =
p->chunk_size * vector_column_byte_size(p->vector_columns[vector_column_idx]); p->chunk_size * vector_column_byte_size(p->vector_columns[vector_column_idx]);
@ -5418,11 +5412,9 @@ static int vec0_init(sqlite3 *db, void *pAux, int argc, const char *const *argv,
sqlite3_finalize(stmt); sqlite3_finalize(stmt);
for (int i = 0; i < pNew->numVectorColumns; i++) { for (int i = 0; i < pNew->numVectorColumns; i++) {
#if SQLITE_VEC_ENABLE_RESCORE // Non-FLAT columns (rescore, IVF, DiskANN) don't use _vector_chunks
// Non-FLAT columns don't use _vector_chunks
if (pNew->vector_columns[i].index_type != VEC0_INDEX_TYPE_FLAT) if (pNew->vector_columns[i].index_type != VEC0_INDEX_TYPE_FLAT)
continue; continue;
#endif
char *zSql = sqlite3_mprintf(VEC0_SHADOW_VECTOR_N_CREATE, char *zSql = sqlite3_mprintf(VEC0_SHADOW_VECTOR_N_CREATE,
pNew->schemaName, pNew->tableName, i); pNew->schemaName, pNew->tableName, i);
if (!zSql) { if (!zSql) {
@ -5711,10 +5703,9 @@ static int vec0Destroy(sqlite3_vtab *pVtab) {
continue; continue;
} }
#endif #endif
#if SQLITE_VEC_ENABLE_RESCORE // Non-FLAT columns (rescore, IVF, DiskANN) don't use _vector_chunks
if (p->vector_columns[i].index_type != VEC0_INDEX_TYPE_FLAT) if (p->vector_columns[i].index_type != VEC0_INDEX_TYPE_FLAT)
continue; continue;
#endif
zSql = sqlite3_mprintf("DROP TABLE \"%w\".\"%w\"", p->schemaName, zSql = sqlite3_mprintf("DROP TABLE \"%w\".\"%w\"", p->schemaName,
p->shadowVectorChunksNames[i]); p->shadowVectorChunksNames[i]);
rc = sqlite3_prepare_v2(p->db, zSql, -1, &stmt, 0); rc = sqlite3_prepare_v2(p->db, zSql, -1, &stmt, 0);
@ -8764,15 +8755,9 @@ int vec0Update_InsertWriteFinalStep(vec0_vtab *p, i64 chunk_rowid,
// Go insert the vector data into the vector chunk shadow tables // Go insert the vector data into the vector chunk shadow tables
for (int i = 0; i < p->numVectorColumns; i++) { for (int i = 0; i < p->numVectorColumns; i++) {
#if SQLITE_VEC_ENABLE_RESCORE // Non-FLAT columns (rescore, IVF, DiskANN) don't use _vector_chunks
// Rescore and IVF columns don't use _vector_chunks if (p->vector_columns[i].index_type != VEC0_INDEX_TYPE_FLAT)
if (p->vector_columns[i].index_type == VEC0_INDEX_TYPE_RESCORE
#if SQLITE_VEC_EXPERIMENTAL_IVF_ENABLE
|| p->vector_columns[i].index_type == VEC0_INDEX_TYPE_IVF
#endif
)
continue; continue;
#endif
sqlite3_blob *blobVectors; sqlite3_blob *blobVectors;
rc = sqlite3_blob_open(p->db, p->schemaName, p->shadowVectorChunksNames[i], rc = sqlite3_blob_open(p->db, p->schemaName, p->shadowVectorChunksNames[i],
@ -9398,11 +9383,9 @@ int vec0Update_Delete_ClearVectors(vec0_vtab *p, i64 chunk_id,
u64 chunk_offset) { u64 chunk_offset) {
int rc, brc; int rc, brc;
for (int i = 0; i < p->numVectorColumns; i++) { for (int i = 0; i < p->numVectorColumns; i++) {
#if SQLITE_VEC_ENABLE_RESCORE // Non-FLAT columns (rescore, IVF, DiskANN) don't use _vector_chunks
// Non-FLAT columns don't use _vector_chunks
if (p->vector_columns[i].index_type != VEC0_INDEX_TYPE_FLAT) if (p->vector_columns[i].index_type != VEC0_INDEX_TYPE_FLAT)
continue; continue;
#endif
sqlite3_blob *blobVectors = NULL; sqlite3_blob *blobVectors = NULL;
size_t n = vector_column_byte_size(p->vector_columns[i]); size_t n = vector_column_byte_size(p->vector_columns[i]);
@ -9514,10 +9497,9 @@ int vec0Update_Delete_DeleteChunkIfEmpty(vec0_vtab *p, i64 chunk_id,
// Delete from each _vector_chunksNN // Delete from each _vector_chunksNN
for (int i = 0; i < p->numVectorColumns; i++) { for (int i = 0; i < p->numVectorColumns; i++) {
#if SQLITE_VEC_ENABLE_RESCORE // Non-FLAT columns (rescore, IVF, DiskANN) don't use _vector_chunks
if (p->vector_columns[i].index_type != VEC0_INDEX_TYPE_FLAT) if (p->vector_columns[i].index_type != VEC0_INDEX_TYPE_FLAT)
continue; continue;
#endif
zSql = sqlite3_mprintf( zSql = sqlite3_mprintf(
"DELETE FROM " VEC0_SHADOW_VECTOR_N_NAME " WHERE rowid = ?", "DELETE FROM " VEC0_SHADOW_VECTOR_N_NAME " WHERE rowid = ?",
p->schemaName, p->tableName, i); p->schemaName, p->tableName, i);
@ -9711,8 +9693,8 @@ int vec0Update_Delete(sqlite3_vtab *pVTab, sqlite3_value *idValue) {
vec0_vtab *p = (vec0_vtab *)pVTab; vec0_vtab *p = (vec0_vtab *)pVTab;
int rc; int rc;
i64 rowid; i64 rowid;
i64 chunk_id; i64 chunk_id = 0;
i64 chunk_offset; i64 chunk_offset = 0;
if (p->pkIsText) { if (p->pkIsText) {
rc = vec0_rowid_from_id(p, idValue, &rowid); rc = vec0_rowid_from_id(p, idValue, &rowid);
@ -9764,8 +9746,6 @@ int vec0Update_Delete(sqlite3_vtab *pVTab, sqlite3_value *idValue) {
if (rc != SQLITE_OK) { if (rc != SQLITE_OK) {
return rc; return rc;
} }
}
#if SQLITE_VEC_ENABLE_RESCORE #if SQLITE_VEC_ENABLE_RESCORE
// 4b. zero out quantized data in rescore chunk tables, delete from rescore vectors // 4b. zero out quantized data in rescore chunk tables, delete from rescore vectors
@ -9774,6 +9754,7 @@ int vec0Update_Delete(sqlite3_vtab *pVTab, sqlite3_value *idValue) {
return rc; return rc;
} }
#endif #endif
}
// 5. delete from _rowids table // 5. delete from _rowids table
rc = vec0Update_Delete_DeleteRowids(p, rowid); rc = vec0Update_Delete_DeleteRowids(p, rowid);