Skip to content

Commit bb3ef78

Browse files
asg017claude
andcommitted
Hide IVF behind SQLITE_VEC_EXPERIMENTAL_IVF_ENABLE, default off
Rename SQLITE_VEC_ENABLE_IVF to SQLITE_VEC_EXPERIMENTAL_IVF_ENABLE and flip the default from 1 to 0. IVF tests are automatically skipped when the build flag is not set. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 3e26925 commit bb3ef78

File tree

2 files changed

+45
-21
lines changed

2 files changed

+45
-21
lines changed

sqlite-vec.c

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,8 @@ typedef size_t usize;
9393
#define COMPILER_SUPPORTS_VTAB_IN 1
9494
#endif
9595

96-
#ifndef SQLITE_VEC_ENABLE_IVF
97-
#define SQLITE_VEC_ENABLE_IVF 1
96+
#ifndef SQLITE_VEC_EXPERIMENTAL_IVF_ENABLE
97+
#define SQLITE_VEC_EXPERIMENTAL_IVF_ENABLE 0
9898
#endif
9999

100100
#ifndef SQLITE_SUBTYPE
@@ -2558,7 +2558,7 @@ struct Vec0RescoreConfig {
25582558
};
25592559
#endif
25602560

2561-
#if SQLITE_VEC_ENABLE_IVF
2561+
#if SQLITE_VEC_EXPERIMENTAL_IVF_ENABLE
25622562
enum Vec0IvfQuantizer {
25632563
VEC0_IVF_QUANTIZER_NONE = 0,
25642564
VEC0_IVF_QUANTIZER_INT8 = 1,
@@ -2737,7 +2737,7 @@ static int vec0_parse_rescore_options(struct Vec0Scanner *scanner,
27372737
* @return int SQLITE_OK on success, SQLITE_EMPTY is it's not a vector column
27382738
* definition, SQLITE_ERROR on error.
27392739
*/
2740-
#if SQLITE_VEC_ENABLE_IVF
2740+
#if SQLITE_VEC_EXPERIMENTAL_IVF_ENABLE
27412741
// Forward declaration — defined in sqlite-vec-ivf.c
27422742
static int vec0_parse_ivf_options(struct Vec0Scanner *scanner,
27432743
struct Vec0IvfConfig *config);
@@ -2922,7 +2922,7 @@ int vec0_parse_vector_column(const char *source, int source_length,
29222922
}
29232923
#endif
29242924
else if (sqlite3_strnicmp(token.start, "ivf", indexNameLen) == 0) {
2925-
#if SQLITE_VEC_ENABLE_IVF
2925+
#if SQLITE_VEC_EXPERIMENTAL_IVF_ENABLE
29262926
indexType = VEC0_INDEX_TYPE_IVF;
29272927
memset(&ivfConfig, 0, sizeof(ivfConfig));
29282928
rc = vec0_parse_ivf_options(&scanner, &ivfConfig);
@@ -3321,7 +3321,7 @@ struct vec0_vtab {
33213321

33223322
int chunk_size;
33233323

3324-
#if SQLITE_VEC_ENABLE_IVF
3324+
#if SQLITE_VEC_EXPERIMENTAL_IVF_ENABLE
33253325
// IVF cached state per vector column
33263326
char *shadowIvfCellsNames[VEC0_MAX_VECTOR_COLUMNS]; // table name for blob_open
33273327
int ivfTrainedCache[VEC0_MAX_VECTOR_COLUMNS]; // -1=unknown, 0=no, 1=yes
@@ -3419,7 +3419,7 @@ void vec0_free_resources(vec0_vtab *p) {
34193419
sqlite3_finalize(p->stmtRowidsGetChunkPosition);
34203420
p->stmtRowidsGetChunkPosition = NULL;
34213421

3422-
#if SQLITE_VEC_ENABLE_IVF
3422+
#if SQLITE_VEC_EXPERIMENTAL_IVF_ENABLE
34233423
for (int i = 0; i < VEC0_MAX_VECTOR_COLUMNS; i++) {
34243424
sqlite3_finalize(p->stmtIvfCellMeta[i]); p->stmtIvfCellMeta[i] = NULL;
34253425
sqlite3_finalize(p->stmtIvfCellUpdateN[i]); p->stmtIvfCellUpdateN[i] = NULL;
@@ -3451,7 +3451,7 @@ void vec0_free(vec0_vtab *p) {
34513451
for (int i = 0; i < p->numVectorColumns; i++) {
34523452
sqlite3_free(p->shadowVectorChunksNames[i]);
34533453
p->shadowVectorChunksNames[i] = NULL;
3454-
#if SQLITE_VEC_ENABLE_IVF
3454+
#if SQLITE_VEC_EXPERIMENTAL_IVF_ENABLE
34553455
sqlite3_free(p->shadowIvfCellsNames[i]);
34563456
p->shadowIvfCellsNames[i] = NULL;
34573457
#endif
@@ -3743,7 +3743,7 @@ int vec0_result_id(vec0_vtab *p, sqlite3_context *context, i64 rowid) {
37433743
* will be stored.
37443744
* @return int SQLITE_OK on success.
37453745
*/
3746-
#if SQLITE_VEC_ENABLE_IVF
3746+
#if SQLITE_VEC_EXPERIMENTAL_IVF_ENABLE
37473747
// Forward declaration — defined in sqlite-vec-ivf.c (included later)
37483748
static int ivf_get_vector_data(vec0_vtab *p, i64 rowid, int col_idx,
37493749
void **outVector, int *outVectorSize);
@@ -3756,7 +3756,7 @@ int vec0_get_vector_data(vec0_vtab *pVtab, i64 rowid, int vector_column_idx,
37563756
i64 chunk_id;
37573757
i64 chunk_offset;
37583758

3759-
#if SQLITE_VEC_ENABLE_IVF
3759+
#if SQLITE_VEC_EXPERIMENTAL_IVF_ENABLE
37603760
// IVF-indexed columns store vectors in _ivf_cells, not _vector_chunks
37613761
if (p->vector_columns[vector_column_idx].index_type == VEC0_INDEX_TYPE_IVF) {
37623762
return ivf_get_vector_data(p, rowid, vector_column_idx, outVector, outVectorSize);
@@ -4411,7 +4411,7 @@ int vec0_new_chunk(vec0_vtab *p, sqlite3_value ** partitionKeyValues, i64 *chunk
44114411
#if SQLITE_VEC_ENABLE_RESCORE
44124412
// Rescore and IVF columns don't use _vector_chunks for float storage
44134413
if (p->vector_columns[vector_column_idx].index_type == VEC0_INDEX_TYPE_RESCORE
4414-
#if SQLITE_VEC_ENABLE_IVF
4414+
#if SQLITE_VEC_EXPERIMENTAL_IVF_ENABLE
44154415
|| p->vector_columns[vector_column_idx].index_type == VEC0_INDEX_TYPE_IVF
44164416
#endif
44174417
) {
@@ -4587,7 +4587,7 @@ void vec0_cursor_clear(vec0_cursor *pCur) {
45874587
}
45884588

45894589
// IVF index implementation — #include'd here after all struct/helper definitions
4590-
#if SQLITE_VEC_ENABLE_IVF
4590+
#if SQLITE_VEC_EXPERIMENTAL_IVF_ENABLE
45914591
#include "sqlite-vec-ivf-kmeans.c"
45924592
#include "sqlite-vec-ivf.c"
45934593
#endif
@@ -4986,7 +4986,7 @@ static int vec0_init(sqlite3 *db, void *pAux, int argc, const char *const *argv,
49864986
}
49874987
#endif
49884988
}
4989-
#if SQLITE_VEC_ENABLE_IVF
4989+
#if SQLITE_VEC_EXPERIMENTAL_IVF_ENABLE
49904990
for (int i = 0; i < pNew->numVectorColumns; i++) {
49914991
if (pNew->vector_columns[i].index_type != VEC0_INDEX_TYPE_IVF) continue;
49924992
pNew->shadowIvfCellsNames[i] =
@@ -5147,7 +5147,7 @@ static int vec0_init(sqlite3 *db, void *pAux, int argc, const char *const *argv,
51475147
}
51485148
#endif
51495149

5150-
#if SQLITE_VEC_ENABLE_IVF
5150+
#if SQLITE_VEC_EXPERIMENTAL_IVF_ENABLE
51515151
// Create IVF shadow tables for IVF-indexed vector columns
51525152
for (int i = 0; i < pNew->numVectorColumns; i++) {
51535153
if (pNew->vector_columns[i].index_type != VEC0_INDEX_TYPE_IVF) continue;
@@ -5315,7 +5315,7 @@ static int vec0Destroy(sqlite3_vtab *pVtab) {
53155315
}
53165316
#endif
53175317

5318-
#if SQLITE_VEC_ENABLE_IVF
5318+
#if SQLITE_VEC_EXPERIMENTAL_IVF_ENABLE
53195319
// Drop IVF shadow tables
53205320
for (int i = 0; i < p->numVectorColumns; i++) {
53215321
if (p->vector_columns[i].index_type != VEC0_INDEX_TYPE_IVF) continue;
@@ -7335,7 +7335,7 @@ int vec0Filter_knn(vec0_cursor *pCur, vec0_vtab *p, int idxNum,
73357335
}
73367336
#endif
73377337

7338-
#if SQLITE_VEC_ENABLE_IVF
7338+
#if SQLITE_VEC_EXPERIMENTAL_IVF_ENABLE
73397339
// IVF dispatch: if vector column has IVF, use IVF query instead of chunk scan
73407340
if (vector_column->index_type == VEC0_INDEX_TYPE_IVF) {
73417341
rc = ivf_query_knn(p, vectorColumnIdx, queryVector,
@@ -8177,7 +8177,7 @@ int vec0Update_InsertWriteFinalStep(vec0_vtab *p, i64 chunk_rowid,
81778177
#if SQLITE_VEC_ENABLE_RESCORE
81788178
// Rescore and IVF columns don't use _vector_chunks
81798179
if (p->vector_columns[i].index_type == VEC0_INDEX_TYPE_RESCORE
8180-
#if SQLITE_VEC_ENABLE_IVF
8180+
#if SQLITE_VEC_EXPERIMENTAL_IVF_ENABLE
81818181
|| p->vector_columns[i].index_type == VEC0_INDEX_TYPE_IVF
81828182
#endif
81838183
)
@@ -8593,7 +8593,7 @@ int vec0Update_Insert(sqlite3_vtab *pVTab, int argc, sqlite3_value **argv,
85938593
}
85948594
#endif
85958595

8596-
#if SQLITE_VEC_ENABLE_IVF
8596+
#if SQLITE_VEC_EXPERIMENTAL_IVF_ENABLE
85978597
// Step #4: IVF index insert (if any vector column uses IVF)
85988598
for (int i = 0; i < p->numVectorColumns; i++) {
85998599
if (p->vector_columns[i].index_type != VEC0_INDEX_TYPE_IVF) continue;
@@ -9189,7 +9189,7 @@ int vec0Update_Delete(sqlite3_vtab *pVTab, sqlite3_value *idValue) {
91899189
}
91909190
}
91919191

9192-
#if SQLITE_VEC_ENABLE_IVF
9192+
#if SQLITE_VEC_EXPERIMENTAL_IVF_ENABLE
91939193
// 7. delete from IVF index
91949194
for (int i = 0; i < p->numVectorColumns; i++) {
91959195
if (p->vector_columns[i].index_type != VEC0_INDEX_TYPE_IVF) continue;
@@ -9473,7 +9473,7 @@ static int vec0Update(sqlite3_vtab *pVTab, int argc, sqlite3_value **argv,
94739473
}
94749474
// INSERT operation
94759475
else if (argc > 1 && sqlite3_value_type(argv[0]) == SQLITE_NULL) {
9476-
#if SQLITE_VEC_ENABLE_IVF
9476+
#if SQLITE_VEC_EXPERIMENTAL_IVF_ENABLE
94779477
// Check for IVF command inserts: INSERT INTO t(rowid) VALUES ('compute-centroids')
94789478
// The id column holds the command string.
94799479
sqlite3_value *idVal = argv[2 + VEC0_COLUMN_ID];
@@ -9632,7 +9632,7 @@ static sqlite3_module vec0Module = {
96329632
#define SQLITE_VEC_DEBUG_BUILD_RESCORE ""
96339633
#endif
96349634

9635-
#if SQLITE_VEC_ENABLE_IVF
9635+
#if SQLITE_VEC_EXPERIMENTAL_IVF_ENABLE
96369636
#define SQLITE_VEC_DEBUG_BUILD_IVF "ivf"
96379637
#else
96389638
#define SQLITE_VEC_DEBUG_BUILD_IVF ""

tests/conftest.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,29 @@
11
import pytest
22
import sqlite3
3+
import os
4+
5+
6+
def _vec_debug():
7+
db = sqlite3.connect(":memory:")
8+
db.enable_load_extension(True)
9+
db.load_extension("dist/vec0")
10+
db.enable_load_extension(False)
11+
return db.execute("SELECT vec_debug()").fetchone()[0]
12+
13+
14+
def _has_build_flag(flag):
15+
return flag in _vec_debug().split("Build flags:")[-1]
16+
17+
18+
def pytest_collection_modifyitems(config, items):
19+
has_ivf = _has_build_flag("ivf")
20+
if has_ivf:
21+
return
22+
skip_ivf = pytest.mark.skip(reason="IVF not enabled (compile with -DSQLITE_VEC_EXPERIMENTAL_IVF_ENABLE=1)")
23+
ivf_prefixes = ("test-ivf",)
24+
for item in items:
25+
if any(item.fspath.basename.startswith(p) for p in ivf_prefixes):
26+
item.add_marker(skip_ivf)
327

428

529
@pytest.fixture()

0 commit comments

Comments
 (0)