Skip to content

Commit

Permalink
Merge pull request tursodatabase#1637 from tursodatabase/vector-searc…
Browse files Browse the repository at this point in the history
…h-fix-error-handling

Vector search fix error handling
  • Loading branch information
sivukhin authored Aug 6, 2024
2 parents 56330c8 + 32d72e5 commit a4af6c6
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 6 deletions.
7 changes: 5 additions & 2 deletions libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3.c
Original file line number Diff line number Diff line change
Expand Up @@ -214238,7 +214238,7 @@ int insertIndexParameters(sqlite3* db, const char *zDbSName, const char *zName,
goto clear_and_exit;
}
rc = sqlite3_step(pStatement);
if( rc == SQLITE_CONSTRAINT ){
if( (rc&0xff) == SQLITE_CONSTRAINT ){
rc = SQLITE_CONSTRAINT;
}else if( rc != SQLITE_DONE ){
rc = SQLITE_ERROR;
Expand Down Expand Up @@ -214546,7 +214546,10 @@ int vectorIndexCreate(Parse *pParse, const Index *pIdx, const char *zDbSName, co
return CREATE_FAIL;
}
rc = insertIndexParameters(db, zDbSName, pIdx->zName, &idxParams);
if( rc == SQLITE_CONSTRAINT ){

// we must consider only lower bits because with sqlite3_extended_result_codes on
// we can recieve different subtypes of CONSTRAINT error
if( (rc&0xff) == SQLITE_CONSTRAINT ){
// we are violating unique constraint here which means that someone inserted parameters in the table before us
// taking aside corruption scenarios, this can be in case of loading dump (because tables and data are loaded before indices)
// this case is valid and we must proceed with index creating but avoid index-refill step as it is already filled
Expand Down
7 changes: 5 additions & 2 deletions libsql-ffi/bundled/src/sqlite3.c
Original file line number Diff line number Diff line change
Expand Up @@ -214238,7 +214238,7 @@ int insertIndexParameters(sqlite3* db, const char *zDbSName, const char *zName,
goto clear_and_exit;
}
rc = sqlite3_step(pStatement);
if( rc == SQLITE_CONSTRAINT ){
if( (rc&0xff) == SQLITE_CONSTRAINT ){
rc = SQLITE_CONSTRAINT;
}else if( rc != SQLITE_DONE ){
rc = SQLITE_ERROR;
Expand Down Expand Up @@ -214546,7 +214546,10 @@ int vectorIndexCreate(Parse *pParse, const Index *pIdx, const char *zDbSName, co
return CREATE_FAIL;
}
rc = insertIndexParameters(db, zDbSName, pIdx->zName, &idxParams);
if( rc == SQLITE_CONSTRAINT ){

// we must consider only lower bits because with sqlite3_extended_result_codes on
// we can recieve different subtypes of CONSTRAINT error
if( (rc&0xff) == SQLITE_CONSTRAINT ){
// we are violating unique constraint here which means that someone inserted parameters in the table before us
// taking aside corruption scenarios, this can be in case of loading dump (because tables and data are loaded before indices)
// this case is valid and we must proceed with index creating but avoid index-refill step as it is already filled
Expand Down
23 changes: 23 additions & 0 deletions libsql-server/tests/hrana/batch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -379,3 +379,26 @@ fn reindex_statement() {

sim.run().unwrap();
}

#[test]
fn test_simulate_vector_index_load_from_dump() {
let mut sim = turmoil::Builder::new()
.simulation_duration(Duration::from_secs(1000))
.build();
sim.host("primary", super::make_standalone_server);
sim.client("client", async {
let db = Database::open_remote_with_connector("http://primary:8080", "", TurmoilConnector)?;
let conn = db.connect()?;

conn.execute("CREATE TABLE t ( v FLOAT32(2) );", ()).await?;
conn.execute("CREATE TABLE t_idx_shadow(index_key INTEGER , data BLOB, PRIMARY KEY (index_key));", ()).await?;
conn.execute("CREATE TABLE libsql_vector_meta_shadow ( name TEXT PRIMARY KEY, metadata BLOB ) WITHOUT ROWID", ()).await?;
conn.execute("INSERT INTO libsql_vector_meta_shadow VALUES ('t_idx', x'');", ()).await?;
conn.execute("INSERT INTO t VALUES (vector('[1,2]')), (vector('[2,3]'));", ()).await?;
conn.execute("CREATE INDEX t_idx ON t (libsql_vector_idx(v));", ()).await?;

Ok(())
});

sim.run().unwrap();
}
7 changes: 5 additions & 2 deletions libsql-sqlite3/src/vectorIndex.c
Original file line number Diff line number Diff line change
Expand Up @@ -629,7 +629,7 @@ int insertIndexParameters(sqlite3* db, const char *zDbSName, const char *zName,
goto clear_and_exit;
}
rc = sqlite3_step(pStatement);
if( rc == SQLITE_CONSTRAINT ){
if( (rc&0xff) == SQLITE_CONSTRAINT ){
rc = SQLITE_CONSTRAINT;
}else if( rc != SQLITE_DONE ){
rc = SQLITE_ERROR;
Expand Down Expand Up @@ -937,7 +937,10 @@ int vectorIndexCreate(Parse *pParse, const Index *pIdx, const char *zDbSName, co
return CREATE_FAIL;
}
rc = insertIndexParameters(db, zDbSName, pIdx->zName, &idxParams);
if( rc == SQLITE_CONSTRAINT ){

// we must consider only lower bits because with sqlite3_extended_result_codes on
// we can recieve different subtypes of CONSTRAINT error
if( (rc&0xff) == SQLITE_CONSTRAINT ){
// we are violating unique constraint here which means that someone inserted parameters in the table before us
// taking aside corruption scenarios, this can be in case of loading dump (because tables and data are loaded before indices)
// this case is valid and we must proceed with index creating but avoid index-refill step as it is already filled
Expand Down

0 comments on commit a4af6c6

Please sign in to comment.