@@ -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
937937int vectorIndexSearch (sqlite3 * db , const char * zDbSName , int argc , sqlite3_value * * argv , VectorOutRows * pRows , char * * pzErrMsg ) {
0 commit comments