Skip to content

Commit 8d78905

Browse files
authored
Merge branch 'tursodatabase:main' into main
2 parents cd92cd7 + fa06fc2 commit 8d78905

File tree

10 files changed

+294
-81
lines changed

10 files changed

+294
-81
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3.c

Lines changed: 80 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -85652,7 +85652,7 @@ int vectorIdxParseColumnType(const char *, int *, int *, const char **);
8565285652
int vectorIndexCreate(Parse*, const Index*, const char *, const IdList*);
8565385653
int vectorIndexClear(sqlite3 *, const char *, const char *);
8565485654
int vectorIndexDrop(sqlite3 *, const char *, const char *);
85655-
int vectorIndexSearch(sqlite3 *, const char *, int, sqlite3_value **, VectorOutRows *, int *, int *, char **);
85655+
int vectorIndexSearch(sqlite3 *, int, sqlite3_value **, VectorOutRows *, int *, int *, char **);
8565685656
int vectorIndexCursorInit(sqlite3 *, const char *, const char *, VectorIdxCursor **);
8565785657
void vectorIndexCursorClose(sqlite3 *, VectorIdxCursor *, int *, int *);
8565885658
int vectorIndexInsert(VectorIdxCursor *, const UnpackedRecord *, char **);
@@ -215829,17 +215829,25 @@ int vectorIndexTryGetParametersFromBinFormat(sqlite3 *db, const char *zSql, cons
215829215829

215830215830
int vectorIndexGetParameters(
215831215831
sqlite3 *db,
215832+
const char *zDbSName,
215832215833
const char *zIdxName,
215833215834
VectorIdxParams *pParams
215834215835
) {
215835215836
int rc = SQLITE_OK;
215837+
assert( zDbSName != NULL );
215836215838

215837-
static const char* zSelectSql = "SELECT metadata FROM " VECTOR_INDEX_GLOBAL_META_TABLE " WHERE name = ?";
215839+
static const char *zSelectSqlTemplate = "SELECT metadata FROM \"%w\"." VECTOR_INDEX_GLOBAL_META_TABLE " WHERE name = ?";
215840+
char* zSelectSql;
215841+
zSelectSql = sqlite3_mprintf(zSelectSqlTemplate, zDbSName);
215842+
if( zSelectSql == NULL ){
215843+
return SQLITE_NOMEM_BKPT;
215844+
}
215838215845
// zSelectSqlPekkaLegacy handles the case when user created DB before 04 July 2024 (https://discord.com/channels/933071162680958986/1225560924526477322/1258367912402489397)
215839215846
// when instead of table with binary parameters rigid schema was used for index settings
215840215847
// we should drop this eventually - but for now we postponed this decision
215841215848
static const char* zSelectSqlPekkaLegacy = "SELECT vector_type, block_size, dims, distance_ops FROM libsql_vector_index WHERE name = ?";
215842215849
rc = vectorIndexTryGetParametersFromBinFormat(db, zSelectSql, zIdxName, pParams);
215850+
sqlite3_free(zSelectSql);
215843215851
if( rc == SQLITE_OK ){
215844215852
return SQLITE_OK;
215845215853
}
@@ -216022,19 +216030,46 @@ int vectorIndexCreate(Parse *pParse, const Index *pIdx, const char *zDbSName, co
216022216030
return CREATE_OK;
216023216031
}
216024216032

216033+
// extracts schema and index name part if full index name is composite (e.g. schema_name.index_name)
216034+
// if full index name has no schema part - function returns SQLITE_OK but leaves pzIdxDbSName and pzIdxName untouched
216035+
int getIndexNameParts(sqlite3 *db, const char *zIdxFullName, char **pzIdxDbSName, char **pzIdxName) {
216036+
int nFullName, nDbSName;
216037+
const char *pDot = zIdxFullName;
216038+
while( *pDot != '.' && *pDot != '\0' ){
216039+
pDot++;
216040+
}
216041+
if( *pDot == '\0' ){
216042+
return SQLITE_OK;
216043+
}
216044+
assert( *pDot == '.' );
216045+
nFullName = sqlite3Strlen30(zIdxFullName);
216046+
nDbSName = pDot - zIdxFullName;
216047+
*pzIdxDbSName = sqlite3DbStrNDup(db, zIdxFullName, nDbSName);
216048+
*pzIdxName = sqlite3DbStrNDup(db, pDot + 1, nFullName - nDbSName - 1);
216049+
if( pzIdxName == NULL || pzIdxDbSName == NULL ){
216050+
sqlite3DbFree(db, *pzIdxName);
216051+
sqlite3DbFree(db, *pzIdxDbSName);
216052+
return SQLITE_NOMEM_BKPT;
216053+
}
216054+
return SQLITE_OK;
216055+
}
216056+
216025216057
int vectorIndexSearch(
216026216058
sqlite3 *db,
216027-
const char* zDbSName,
216028216059
int argc,
216029216060
sqlite3_value **argv,
216030216061
VectorOutRows *pRows,
216031216062
int *nReads,
216032216063
int *nWrites,
216033216064
char **pzErrMsg
216034216065
) {
216035-
int type, dims, k, rc;
216066+
int type, dims, k, rc, iDb = -1;
216036216067
double kDouble;
216037-
const char *zIdxName;
216068+
const char *zIdxFullName;
216069+
char *zIdxDbSNameAlloc = NULL; // allocated managed schema name string - must be freed if not null
216070+
char *zIdxNameAlloc = NULL; // allocated managed index name string - must be freed if not null
216071+
const char *zIdxDbSName = NULL; // schema name of the index (can be static in cases where explicit schema is omitted - so must not be freed)
216072+
const char *zIdxName = NULL; // index name (can be extracted with sqlite3_value_text and managed by SQLite - so must not be freed)
216038216073
const char *zErrMsg;
216039216074
Vector *pVector = NULL;
216040216075
DiskAnnIndex *pDiskAnn = NULL;
@@ -216043,8 +216078,6 @@ int vectorIndexSearch(
216043216078
VectorIdxParams idxParams;
216044216079
vectorIdxParamsInit(&idxParams, NULL, 0);
216045216080

216046-
assert( zDbSName != NULL );
216047-
216048216081
if( argc != 3 ){
216049216082
*pzErrMsg = sqlite3_mprintf("vector index(search): got %d parameters, expected 3", argc);
216050216083
rc = SQLITE_ERROR;
@@ -216095,19 +216128,45 @@ int vectorIndexSearch(
216095216128
rc = SQLITE_ERROR;
216096216129
goto out;
216097216130
}
216098-
zIdxName = (const char*)sqlite3_value_text(argv[0]);
216099-
if( vectorIndexGetParameters(db, zIdxName, &idxParams) != 0 ){
216131+
zIdxFullName = (const char*)sqlite3_value_text(argv[0]);
216132+
rc = getIndexNameParts(db, zIdxFullName, &zIdxDbSNameAlloc, &zIdxNameAlloc);
216133+
if( rc != SQLITE_OK ){
216134+
*pzErrMsg = sqlite3_mprintf("vector index(search): failed to parse index name");
216135+
goto out;
216136+
}
216137+
assert( (zIdxDbSNameAlloc == NULL && zIdxNameAlloc == NULL) || (zIdxDbSNameAlloc != NULL && zIdxNameAlloc != NULL) );
216138+
if( zIdxDbSNameAlloc == NULL && zIdxNameAlloc == NULL ){
216139+
zIdxDbSName = "main";
216140+
zIdxName = zIdxFullName;
216141+
} else{
216142+
zIdxDbSName = zIdxDbSNameAlloc;
216143+
zIdxName = zIdxNameAlloc;
216144+
iDb = sqlite3FindDbName(db, zIdxDbSName);
216145+
if( iDb < 0 ){
216146+
*pzErrMsg = sqlite3_mprintf("vector index(search): unknown schema '%s'", zIdxDbSName);
216147+
rc = SQLITE_ERROR;
216148+
goto out;
216149+
}
216150+
// we need to hold mutex to protect schema against unwanted changes
216151+
// this code is necessary, otherwise sqlite3SchemaMutexHeld assert will fail
216152+
if( iDb !=1 ){
216153+
// not "main" DB which we already hold mutex for
216154+
sqlite3BtreeEnter(db->aDb[iDb].pBt);
216155+
}
216156+
}
216157+
216158+
if( vectorIndexGetParameters(db, zIdxDbSName, zIdxName, &idxParams) != 0 ){
216100216159
*pzErrMsg = sqlite3_mprintf("vector index(search): failed to parse vector index parameters");
216101216160
rc = SQLITE_ERROR;
216102216161
goto out;
216103216162
}
216104-
pIndex = sqlite3FindIndex(db, zIdxName, zDbSName);
216163+
pIndex = sqlite3FindIndex(db, zIdxName, zIdxDbSName);
216105216164
if( pIndex == NULL ){
216106216165
*pzErrMsg = sqlite3_mprintf("vector index(search): index not found");
216107216166
rc = SQLITE_ERROR;
216108216167
goto out;
216109216168
}
216110-
rc = diskAnnOpenIndex(db, zDbSName, zIdxName, &idxParams, &pDiskAnn);
216169+
rc = diskAnnOpenIndex(db, zIdxDbSName, zIdxName, &idxParams, &pDiskAnn);
216111216170
if( rc != SQLITE_OK ){
216112216171
*pzErrMsg = sqlite3_mprintf("vector index(search): failed to open diskann index");
216113216172
goto out;
@@ -216127,6 +216186,11 @@ int vectorIndexSearch(
216127216186
if( pVector != NULL ){
216128216187
vectorFree(pVector);
216129216188
}
216189+
sqlite3DbFree(db, zIdxNameAlloc);
216190+
sqlite3DbFree(db, zIdxDbSNameAlloc);
216191+
if( iDb >= 0 && iDb != 1 ){
216192+
sqlite3BtreeLeave(db->aDb[iDb].pBt);
216193+
}
216130216194
return rc;
216131216195
}
216132216196

@@ -216176,7 +216240,7 @@ int vectorIndexCursorInit(
216176216240

216177216241
assert( zDbSName != NULL );
216178216242

216179-
if( vectorIndexGetParameters(db, zIndexName, &params) != 0 ){
216243+
if( vectorIndexGetParameters(db, zDbSName, zIndexName, &params) != 0 ){
216180216244
return SQLITE_ERROR;
216181216245
}
216182216246
pCursor = sqlite3DbMallocZero(db, sizeof(VectorIdxCursor));
@@ -216240,7 +216304,6 @@ typedef struct vectorVtab vectorVtab;
216240216304
struct vectorVtab {
216241216305
sqlite3_vtab base; /* Base class - must be first */
216242216306
sqlite3 *db; /* Database connection */
216243-
char* zDbSName; /* Database schema name */
216244216307
};
216245216308

216246216309
typedef struct vectorVtab_cursor vectorVtab_cursor;
@@ -216266,7 +216329,6 @@ static int vectorVtabConnect(
216266216329
sqlite3_vtab **ppVtab,
216267216330
char **pzErr
216268216331
){
216269-
char *zDbSName = NULL;
216270216332
vectorVtab *pVtab = NULL;
216271216333
int rc;
216272216334
/*
@@ -216281,21 +216343,17 @@ static int vectorVtabConnect(
216281216343
if( pVtab == NULL ){
216282216344
return SQLITE_NOMEM_BKPT;
216283216345
}
216284-
zDbSName = sqlite3DbStrDup(db, argv[1]); // argv[1] is the database schema name by spec (see https://www.sqlite.org/vtab.html#the_xcreate_method)
216285-
if( zDbSName == NULL ){
216286-
sqlite3_free(pVtab);
216287-
return SQLITE_NOMEM_BKPT;
216288-
}
216346+
// > Eponymous virtual tables exist in the "main" schema only, so they will not work if prefixed with a different schema name.
216347+
// so, argv[1] always equal to "main" and we can safely ignore it
216348+
// (see https://www.sqlite.org/vtab.html#epovtab)
216289216349
memset(pVtab, 0, sizeof(*pVtab));
216290216350
pVtab->db = db;
216291-
pVtab->zDbSName = zDbSName;
216292216351
*ppVtab = (sqlite3_vtab*)pVtab;
216293216352
return SQLITE_OK;
216294216353
}
216295216354

216296216355
static int vectorVtabDisconnect(sqlite3_vtab *pVtab){
216297216356
vectorVtab *pVTab = (vectorVtab*)pVtab;
216298-
sqlite3DbFree(pVTab->db, pVTab->zDbSName);
216299216357
sqlite3_free(pVtab);
216300216358
return SQLITE_OK;
216301216359
}
@@ -216362,7 +216420,7 @@ static int vectorVtabFilter(
216362216420
pCur->rows.aIntValues = NULL;
216363216421
pCur->rows.ppValues = NULL;
216364216422

216365-
if( vectorIndexSearch(pVTab->db, pVTab->zDbSName, argc, argv, &pCur->rows, &pCur->nReads, &pCur->nWrites, &pVTab->base.zErrMsg) != 0 ){
216423+
if( vectorIndexSearch(pVTab->db, argc, argv, &pCur->rows, &pCur->nReads, &pCur->nWrites, &pVTab->base.zErrMsg) != 0 ){
216366216424
return SQLITE_ERROR;
216367216425
}
216368216426

0 commit comments

Comments
 (0)