@@ -747,17 +747,25 @@ int vectorIndexTryGetParametersFromBinFormat(sqlite3 *db, const char *zSql, cons
747
747
748
748
int vectorIndexGetParameters (
749
749
sqlite3 * db ,
750
+ const char * zDbSName ,
750
751
const char * zIdxName ,
751
752
VectorIdxParams * pParams
752
753
) {
753
754
int rc = SQLITE_OK ;
755
+ assert ( zDbSName != NULL );
754
756
755
- static const char * zSelectSql = "SELECT metadata FROM " VECTOR_INDEX_GLOBAL_META_TABLE " WHERE name = ?" ;
757
+ static const char * zSelectSqlTemplate = "SELECT metadata FROM \"%w\"." VECTOR_INDEX_GLOBAL_META_TABLE " WHERE name = ?" ;
758
+ char * zSelectSql ;
759
+ zSelectSql = sqlite3_mprintf (zSelectSqlTemplate , zDbSName );
760
+ if ( zSelectSql == NULL ){
761
+ return SQLITE_NOMEM_BKPT ;
762
+ }
756
763
// zSelectSqlPekkaLegacy handles the case when user created DB before 04 July 2024 (https://discord.com/channels/933071162680958986/1225560924526477322/1258367912402489397)
757
764
// when instead of table with binary parameters rigid schema was used for index settings
758
765
// we should drop this eventually - but for now we postponed this decision
759
766
static const char * zSelectSqlPekkaLegacy = "SELECT vector_type, block_size, dims, distance_ops FROM libsql_vector_index WHERE name = ?" ;
760
767
rc = vectorIndexTryGetParametersFromBinFormat (db , zSelectSql , zIdxName , pParams );
768
+ sqlite3_free (zSelectSql );
761
769
if ( rc == SQLITE_OK ){
762
770
return SQLITE_OK ;
763
771
}
@@ -940,9 +948,32 @@ int vectorIndexCreate(Parse *pParse, const Index *pIdx, const char *zDbSName, co
940
948
return CREATE_OK ;
941
949
}
942
950
951
+ // extracts schema and index name part if full index name is composite (e.g. schema_name.index_name)
952
+ // if full index name has no schema part - function returns SQLITE_OK but leaves pzIdxDbSName and pzIdxName untouched
953
+ int getIndexNameParts (sqlite3 * db , const char * zIdxFullName , char * * pzIdxDbSName , char * * pzIdxName ) {
954
+ int nFullName , nDbSName ;
955
+ const char * pDot = zIdxFullName ;
956
+ while ( * pDot != '.' && * pDot != '\0' ){
957
+ pDot ++ ;
958
+ }
959
+ if ( * pDot == '\0' ){
960
+ return SQLITE_OK ;
961
+ }
962
+ assert ( * pDot == '.' );
963
+ nFullName = sqlite3Strlen30 (zIdxFullName );
964
+ nDbSName = pDot - zIdxFullName ;
965
+ * pzIdxDbSName = sqlite3DbStrNDup (db , zIdxFullName , nDbSName );
966
+ * pzIdxName = sqlite3DbStrNDup (db , pDot + 1 , nFullName - nDbSName - 1 );
967
+ if ( pzIdxName == NULL || pzIdxDbSName == NULL ){
968
+ sqlite3DbFree (db , * pzIdxName );
969
+ sqlite3DbFree (db , * pzIdxDbSName );
970
+ return SQLITE_NOMEM_BKPT ;
971
+ }
972
+ return SQLITE_OK ;
973
+ }
974
+
943
975
int vectorIndexSearch (
944
976
sqlite3 * db ,
945
- const char * zDbSName ,
946
977
int argc ,
947
978
sqlite3_value * * argv ,
948
979
VectorOutRows * pRows ,
@@ -952,7 +983,11 @@ int vectorIndexSearch(
952
983
) {
953
984
int type , dims , k , rc ;
954
985
double kDouble ;
955
- const char * zIdxName ;
986
+ const char * zIdxFullName ;
987
+ char * zIdxDbSNameAlloc = NULL ; // allocated managed schema name string - must be freed if not null
988
+ char * zIdxNameAlloc = NULL ; // allocated managed index name string - must be freed if not null
989
+ const char * zIdxDbSName = NULL ; // schema name of the index (can be static in cases where explicit schema is omitted - so must not be freed)
990
+ const char * zIdxName = NULL ; // index name (can be extracted with sqlite3_value_text and managed by SQLite - so must not be freed)
956
991
const char * zErrMsg ;
957
992
Vector * pVector = NULL ;
958
993
DiskAnnIndex * pDiskAnn = NULL ;
@@ -961,8 +996,6 @@ int vectorIndexSearch(
961
996
VectorIdxParams idxParams ;
962
997
vectorIdxParamsInit (& idxParams , NULL , 0 );
963
998
964
- assert ( zDbSName != NULL );
965
-
966
999
if ( argc != 3 ){
967
1000
* pzErrMsg = sqlite3_mprintf ("vector index(search): got %d parameters, expected 3" , argc );
968
1001
rc = SQLITE_ERROR ;
@@ -1013,19 +1046,33 @@ int vectorIndexSearch(
1013
1046
rc = SQLITE_ERROR ;
1014
1047
goto out ;
1015
1048
}
1016
- zIdxName = (const char * )sqlite3_value_text (argv [0 ]);
1017
- if ( vectorIndexGetParameters (db , zIdxName , & idxParams ) != 0 ){
1049
+ zIdxFullName = (const char * )sqlite3_value_text (argv [0 ]);
1050
+ rc = getIndexNameParts (db , zIdxFullName , & zIdxDbSNameAlloc , & zIdxNameAlloc );
1051
+ if ( rc != SQLITE_OK ){
1052
+ * pzErrMsg = sqlite3_mprintf ("vector index(search): failed to parse index name" );
1053
+ goto out ;
1054
+ }
1055
+ assert ( (zIdxDbSNameAlloc == NULL && zIdxNameAlloc == NULL ) || (zIdxDbSNameAlloc != NULL && zIdxNameAlloc != NULL ) );
1056
+ if ( zIdxDbSNameAlloc == NULL && zIdxNameAlloc == NULL ){
1057
+ zIdxDbSName = "main" ;
1058
+ zIdxName = zIdxFullName ;
1059
+ } else {
1060
+ zIdxDbSName = zIdxDbSNameAlloc ;
1061
+ zIdxName = zIdxNameAlloc ;
1062
+ }
1063
+
1064
+ if ( vectorIndexGetParameters (db , zIdxDbSName , zIdxName , & idxParams ) != 0 ){
1018
1065
* pzErrMsg = sqlite3_mprintf ("vector index(search): failed to parse vector index parameters" );
1019
1066
rc = SQLITE_ERROR ;
1020
1067
goto out ;
1021
1068
}
1022
- pIndex = sqlite3FindIndex (db , zIdxName , zDbSName );
1069
+ pIndex = sqlite3FindIndex (db , zIdxName , zIdxDbSName );
1023
1070
if ( pIndex == NULL ){
1024
1071
* pzErrMsg = sqlite3_mprintf ("vector index(search): index not found" );
1025
1072
rc = SQLITE_ERROR ;
1026
1073
goto out ;
1027
1074
}
1028
- rc = diskAnnOpenIndex (db , zDbSName , zIdxName , & idxParams , & pDiskAnn );
1075
+ rc = diskAnnOpenIndex (db , zIdxDbSName , zIdxName , & idxParams , & pDiskAnn );
1029
1076
if ( rc != SQLITE_OK ){
1030
1077
* pzErrMsg = sqlite3_mprintf ("vector index(search): failed to open diskann index" );
1031
1078
goto out ;
@@ -1045,6 +1092,8 @@ int vectorIndexSearch(
1045
1092
if ( pVector != NULL ){
1046
1093
vectorFree (pVector );
1047
1094
}
1095
+ sqlite3DbFree (db , zIdxNameAlloc );
1096
+ sqlite3DbFree (db , zIdxDbSNameAlloc );
1048
1097
return rc ;
1049
1098
}
1050
1099
@@ -1094,7 +1143,7 @@ int vectorIndexCursorInit(
1094
1143
1095
1144
assert ( zDbSName != NULL );
1096
1145
1097
- if ( vectorIndexGetParameters (db , zIndexName , & params ) != 0 ){
1146
+ if ( vectorIndexGetParameters (db , zDbSName , zIndexName , & params ) != 0 ){
1098
1147
return SQLITE_ERROR ;
1099
1148
}
1100
1149
pCursor = sqlite3DbMallocZero (db , sizeof (VectorIdxCursor ));
0 commit comments