Skip to content

Commit aacd3e4

Browse files
committed
review fixes
1 parent 0917d7b commit aacd3e4

File tree

3 files changed

+42
-39
lines changed

3 files changed

+42
-39
lines changed

libsql-sqlite3/src/build.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4314,10 +4314,13 @@ void sqlite3CreateIndex(
43144314
if( vectorIdxRc < 0 ){
43154315
goto exit_create_index;
43164316
}
4317+
if( vectorIdxRc >= 1 ){
4318+
idxType = SQLITE_IDXTYPE_VECTOR;
4319+
pIndex->idxType = idxType;
4320+
}
43174321
if( vectorIdxRc == 1 ){
43184322
skipRefill = 1;
43194323
}
4320-
idxType = pIndex->idxType; // vectorIndexCreate can update idxType to 4 (VECTOR INDEX)
43214324
#endif
43224325

43234326
/* Append the table key to the end of the index. For WITHOUT ROWID

libsql-sqlite3/src/vectorIndex.c

Lines changed: 37 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -735,6 +735,9 @@ int vectorIndexGetParameters(
735735
int rc = SQLITE_OK;
736736

737737
static const char* zSelectSql = "SELECT metadata FROM " VECTOR_INDEX_GLOBAL_META_TABLE " WHERE name = ?";
738+
// zSelectSqlPekkaLegacy handles the case when user created DB before 04 July 2024 (https://discord.com/channels/933071162680958986/1225560924526477322/1258367912402489397)
739+
// when instead of table with binary parameters rigid schema was used for index settings
740+
// we should drop this eventually - but for now we postponed this decision
738741
static const char* zSelectSqlPekkaLegacy = "SELECT vector_type, block_size, dims, distance_ops FROM libsql_vector_index WHERE name = ?";
739742
rc = vectorIndexTryGetParametersFromBinFormat(db, zSelectSql, zIdxName, pParams);
740743
if( rc == SQLITE_OK ){
@@ -781,19 +784,24 @@ int vectorIndexClear(sqlite3 *db, const char *zDbSName, const char *zIdxName) {
781784
* dump populates tables first and create indices after
782785
* so we must omit them because shadow tables already filled
783786
*
784-
* 1. if vector index must not be created : 0 returned and pIdx is unchanged
785-
* 2. if vector index must be created and refilled from base table: 0 returned and pIdx->idxType set to SQLITE_IDXTYPE_VECTOR
786-
* 3. if vector index must be created but refill must be skipped : 1 returned and pIdx->idxType set to SQLITE_IDXTYPE_VECTOR
787-
* 4. in case of any error :-1 returned (and pParse errMsg is populated with some error message)
787+
* 1. in case of any error :-1 returned (and pParse errMsg is populated with some error message)
788+
* 2. if vector index must not be created : 0 returned
789+
* 3. if vector index must be created but refill must be skipped : 1 returned
790+
* 4. if vector index must be created and refilled from base table: 2 returned
788791
*/
789-
int vectorIndexCreate(Parse *pParse, Index *pIdx, const char *zDbSName, const IdList *pUsing) {
792+
int vectorIndexCreate(Parse *pParse, const Index *pIdx, const char *zDbSName, const IdList *pUsing) {
793+
static const int CREATE_FAIL = -1;
794+
static const int CREATE_IGNORE = 0;
795+
static const int CREATE_OK_SKIP_REFILL = 1;
796+
static const int CREATE_OK = 2;
797+
790798
int i, rc = SQLITE_OK;
791799
int dims, type;
792800
int hasLibsqlVectorIdxFn = 0, hasCollation = 0;
793801
const char *pzErrMsg;
794802

795803
if( IsVacuum(pParse->db) ){
796-
return SQLITE_OK;
804+
return CREATE_IGNORE;
797805
}
798806

799807
assert( zDbSName != NULL );
@@ -811,7 +819,7 @@ int vectorIndexCreate(Parse *pParse, Index *pIdx, const char *zDbSName, const Id
811819
if( pParse->eParseMode ){
812820
// scheme can be re-parsed by SQLite for different reasons (for example, to check schema after
813821
// ALTER COLUMN statements) - so we must skip creation in such cases
814-
goto ignore;
822+
return CREATE_IGNORE;
815823
}
816824

817825
// backward compatibility: preserve old indices with deprecated syntax but forbid creation of new indices with this syntax
@@ -821,15 +829,15 @@ int vectorIndexCreate(Parse *pParse, Index *pIdx, const char *zDbSName, const Id
821829
} else {
822830
sqlite3ErrorMsg(pParse, "USING syntax is deprecated, please use plain CREATE INDEX: CREATE INDEX xxx ON yyy ( " VECTOR_INDEX_MARKER_FUNCTION "(zzz) )");
823831
}
824-
goto fail;
832+
return CREATE_FAIL;
825833
}
826834
if( db->init.busy == 1 && pUsing != NULL ){
827-
goto ok;
835+
return CREATE_OK;
828836
}
829837

830838
// vector index must have expressions over column
831839
if( pIdx->aColExpr == NULL ) {
832-
goto ignore;
840+
return CREATE_IGNORE;
833841
}
834842

835843
pListItem = pIdx->aColExpr->a;
@@ -844,94 +852,86 @@ int vectorIndexCreate(Parse *pParse, Index *pIdx, const char *zDbSName, const Id
844852
}
845853
}
846854
if( !hasLibsqlVectorIdxFn ) {
847-
goto ignore;
855+
return CREATE_IGNORE;
848856
}
849857
if( hasCollation ){
850858
sqlite3ErrorMsg(pParse, "vector index can't have collation");
851-
goto fail;
859+
return CREATE_FAIL;
852860
}
853861
if( pIdx->aColExpr->nExpr != 1 ) {
854862
sqlite3ErrorMsg(pParse, "vector index must contain exactly one column wrapped into the " VECTOR_INDEX_MARKER_FUNCTION " function");
855-
goto fail;
863+
return CREATE_FAIL;
856864
}
857865
// we are able to support this but I doubt this works for now - more polishing required to make this work
858866
if( pIdx->pPartIdxWhere != NULL ) {
859867
sqlite3ErrorMsg(pParse, "partial vector index is not supported");
860-
goto fail;
868+
return CREATE_FAIL;
861869
}
862870

863871
pArgsList = pIdx->aColExpr->a[0].pExpr->x.pList;
864872
pListItem = pArgsList->a;
865873

866874
if( pArgsList->nExpr < 1 ){
867875
sqlite3ErrorMsg(pParse, VECTOR_INDEX_MARKER_FUNCTION " must contain at least one argument");
868-
goto fail;
876+
return CREATE_FAIL;
869877
}
870878
if( pListItem[0].pExpr->op != TK_COLUMN ) {
871879
sqlite3ErrorMsg(pParse, VECTOR_INDEX_MARKER_FUNCTION " first argument must be a column token");
872-
goto fail;
880+
return CREATE_FAIL;
873881
}
874882
iEmbeddingColumn = pListItem[0].pExpr->iColumn;
875883
if( iEmbeddingColumn < 0 ) {
876884
sqlite3ErrorMsg(pParse, VECTOR_INDEX_MARKER_FUNCTION " first argument must be column with vector type");
877-
goto fail;
885+
return CREATE_FAIL;
878886
}
879887
assert( iEmbeddingColumn >= 0 && iEmbeddingColumn < pTable->nCol );
880888

881889
zEmbeddingColumnTypeName = sqlite3ColumnType(&pTable->aCol[iEmbeddingColumn], "");
882890
if( vectorIdxParseColumnType(zEmbeddingColumnTypeName, &type, &dims, &pzErrMsg) != 0 ){
883891
sqlite3ErrorMsg(pParse, "%s: %s", pzErrMsg, zEmbeddingColumnTypeName);
884-
goto fail;
892+
return CREATE_FAIL;
885893
}
886894

887895
// schema is locked while db is initializing and we need to just proceed here
888896
if( db->init.busy == 1 ){
889-
goto ok;
897+
return CREATE_OK;
890898
}
891899

892900
rc = initVectorIndexMetaTable(db, zDbSName);
893901
if( rc != SQLITE_OK ){
894902
sqlite3ErrorMsg(pParse, "failed to init vector index meta table: %s", sqlite3_errmsg(db));
895-
goto fail;
903+
return CREATE_FAIL;
896904
}
897905
rc = parseVectorIdxParams(pParse, &idxParams, type, dims, pListItem + 1, pArgsList->nExpr - 1);
898906
if( rc != SQLITE_OK ){
899907
sqlite3ErrorMsg(pParse, "failed to parse vector idx params");
900-
goto fail;
908+
return CREATE_FAIL;
901909
}
902910
if( vectorIdxKeyGet(pTable, &idxKey, &pzErrMsg) != 0 ){
903911
sqlite3ErrorMsg(pParse, "failed to detect underlying table key: %s", pzErrMsg);
904-
goto fail;
912+
return CREATE_FAIL;
905913
}
906914
if( idxKey.nKeyColumns != 1 ){
907915
sqlite3ErrorMsg(pParse, "vector index for tables without ROWID and composite primary key are not supported");
908-
goto fail;
916+
return CREATE_FAIL;
909917
}
910918
rc = diskAnnCreateIndex(db, zDbSName, pIdx->zName, &idxKey, &idxParams);
911919
if( rc != SQLITE_OK ){
912920
sqlite3ErrorMsg(pParse, "unable to initialize diskann vector index");
913-
goto fail;
921+
return CREATE_FAIL;
914922
}
915923
rc = insertIndexParameters(db, zDbSName, pIdx->zName, &idxParams);
916924
if( rc == SQLITE_CONSTRAINT ){
917925
// we are violating unique constraint here which means that someone inserted parameters in the table before us
918-
// taking aside corruption scenarios, this can be in case of loading dump (because tables are loaded before indices) or vacuum-ing DB
919-
// both these cases are valid and we must proceed with index creating but avoid index-refill step as it is already filled
920-
goto skip_refill;
926+
// taking aside corruption scenarios, this can be in case of loading dump (because tables and data are loaded before indices)
927+
// this case is valid and we must proceed with index creating but avoid index-refill step as it is already filled
928+
return CREATE_OK_SKIP_REFILL;
921929
}
922930
if( rc != SQLITE_OK ){
923931
sqlite3ErrorMsg(pParse, "unable to update global metadata table");
924-
goto fail;
932+
return CREATE_FAIL;
925933
}
926-
ok:
927-
pIdx->idxType = SQLITE_IDXTYPE_VECTOR;
928-
ignore:
929-
return 0;
930-
skip_refill:
931-
pIdx->idxType = SQLITE_IDXTYPE_VECTOR;
932-
return 1;
933-
fail:
934-
return -1;
934+
return CREATE_OK;
935935
}
936936

937937
int vectorIndexSearch(sqlite3 *db, const char* zDbSName, int argc, sqlite3_value **argv, VectorOutRows *pRows, char **pzErrMsg) {

libsql-sqlite3/src/vectorIndexInt.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ typedef struct VectorIdxCursor VectorIdxCursor;
224224

225225
int vectorIdxParseColumnType(const char *, int *, int *, const char **);
226226

227-
int vectorIndexCreate(Parse*, Index*, const char *, const IdList*);
227+
int vectorIndexCreate(Parse*, const Index*, const char *, const IdList*);
228228
int vectorIndexClear(sqlite3 *, const char *, const char *);
229229
int vectorIndexDrop(sqlite3 *, const char *, const char *);
230230
int vectorIndexSearch(sqlite3 *, const char *, int, sqlite3_value **, VectorOutRows *, char **);

0 commit comments

Comments
 (0)