diff --git a/sqlite-vec.c b/sqlite-vec.c index d63ce53..64e5442 100644 --- a/sqlite-vec.c +++ b/sqlite-vec.c @@ -613,7 +613,8 @@ static int fvec_from_value(sqlite3_value *value, f32 **vector, } *pzErr = sqlite3_mprintf( - "Input must have type BLOB (compact format) or TEXT (JSON), found %s", type_name(value_type)); + "Input must have type BLOB (compact format) or TEXT (JSON), found %s", + type_name(value_type)); return SQLITE_ERROR; } @@ -639,7 +640,7 @@ static int bitvec_from_value(sqlite3_value *value, u8 **vector, static int int8_vec_from_value(sqlite3_value *value, i8 **vector, size_t *dimensions, vector_cleanup *cleanup, - char **pzErr) { + char **pzErr) { int value_type = sqlite3_value_type(value); if (value_type == SQLITE_BLOB) { const void *blob = sqlite3_value_blob(value); @@ -799,7 +800,6 @@ int vector_from_value(sqlite3_value *value, void **vector, size_t *dimensions, return SQLITE_ERROR; } - int ensure_vector_match(sqlite3_value *aValue, sqlite3_value *bValue, void **a, void **b, enum VectorElementType *element_type, size_t *dimensions, vector_cleanup *outACleanup, @@ -3044,10 +3044,10 @@ int vec0_get_id_value_from_rowid(vec0_vtab *pVtab, i64 rowid, *out = sqlite3_value_dup(value); rc = SQLITE_OK; - cleanup: - sqlite3_reset(pVtab->stmtRowidsGetChunkPosition); - sqlite3_clear_bindings(pVtab->stmtRowidsGetChunkPosition); - return rc; +cleanup: + sqlite3_reset(pVtab->stmtRowidsGetChunkPosition); + sqlite3_clear_bindings(pVtab->stmtRowidsGetChunkPosition); + return rc; } // TODO make sure callees use the return value of this function @@ -4471,7 +4471,7 @@ static int vec0Column_point(vec0_vtab *pVtab, vec0_cursor *pCur, } // TODO only have 1st vector data if (vec0_column_idx_is_vector(pVtab, i)) { - if(sqlite3_vtab_nochange(context)) { + if (sqlite3_vtab_nochange(context)) { sqlite3_result_null(context); return SQLITE_OK; } @@ -5220,7 +5220,7 @@ cleanup: int vec0Update_Delete_DeleteRowids(vec0_vtab *p, i64 rowid) { int rc; - sqlite3_stmt *stmt = NULL; + sqlite3_stmt *stmt = NULL; char *zSql = sqlite3_mprintf("DELETE FROM " VEC0_SHADOW_ROWIDS_NAME " WHERE rowid = ?", @@ -5231,17 +5231,17 @@ int vec0Update_Delete_DeleteRowids(vec0_vtab *p, i64 rowid) { rc = sqlite3_prepare_v2(p->db, zSql, -1, &stmt, NULL); sqlite3_free(zSql); - if(rc != SQLITE_OK ) { + if (rc != SQLITE_OK) { goto cleanup; } sqlite3_bind_int64(stmt, 1, rowid); rc = sqlite3_step(stmt); - if(rc != SQLITE_DONE) { + if (rc != SQLITE_DONE) { goto cleanup; } rc = SQLITE_OK; - cleanup: +cleanup: sqlite3_finalize(stmt); return rc; } @@ -5374,7 +5374,7 @@ int vec0Update_UpdateOnRowid(sqlite3_vtab *pVTab, int argc, // 1. get chunk_id and chunk_offset from _rowids rc = vec0_get_chunk_position(p, rowid, &chunk_id, &chunk_offset); - if(rc != SQLITE_OK) { + if (rc != SQLITE_OK) { return rc; } @@ -5392,13 +5392,13 @@ int vec0Update_UpdateOnRowid(sqlite3_vtab *pVTab, int argc, // but subtypes don't appear to survive xColumn -> xUpdate, it's always 0. // So for now, we'll just use NULL and warn people to not SET X = NULL // in the docs. - if(sqlite3_value_type(valueVector) == SQLITE_NULL) { + if (sqlite3_value_type(valueVector) == SQLITE_NULL) { continue; } rc = vec0Update_UpdateVectorColumn(p, chunk_id, chunk_offset, i, valueVector); - if(rc != SQLITE_OK){ + if (rc != SQLITE_OK) { return SQLITE_ERROR; } } @@ -5488,7 +5488,7 @@ static void vec_static_blob_from_raw(sqlite3_context *context, int argc, sqlite3_value **argv) { struct static_blob_definition *p; p = sqlite3_malloc(sizeof(*p)); - if(!p) { + if (!p) { sqlite3_result_error_nomem(context); return; } @@ -6179,7 +6179,7 @@ int sqlite3_vec_init(sqlite3 *db, char **pzErrMsg, #ifdef SQLITE_VEC_ENABLE_EXPERIMENTAL vec_static_blob_data *static_blob_data; static_blob_data = sqlite3_malloc(sizeof(*static_blob_data)); - if(!static_blob_data) { + if (!static_blob_data) { return SQLITE_NOMEM; } memset(static_blob_data, 0, sizeof(*static_blob_data)); diff --git a/tests/test-loadable.py b/tests/test-loadable.py index 1e2d306..60b44b5 100644 --- a/tests/test-loadable.py +++ b/tests/test-loadable.py @@ -538,18 +538,18 @@ def test_vec0_inserts(): "ccc": bitmap_full(128), } ] - #db.execute( + # db.execute( # "update t set aaa = ? where rowid = ?", # [np.full((128,), 0.00011, dtype="float32"), 1], - #) - #assert execute_all(db, "select * from t") == [ + # ) + # assert execute_all(db, "select * from t") == [ # { # "rowid": 1, # "aaa": _f32([0.00011] * 128), # "bbb": _int8([4] * 128), # "ccc": bitmap_full(128), # } - #] + # ] db.execute("create virtual table t1 using vec0(aaa float[4], chunk_size=8)") db.execute( @@ -996,9 +996,9 @@ def test_vec0_updates(): (3, :z, vec_quantize_i8(:z, 'unit') ,vec_quantize_binary(:z)); """, { - "x": "[.1, .1, .1, .1, -.1, -.1, -.1, -.1]", + "x": "[.1, .1, .1, .1, -.1, -.1, -.1, -.1]", "y": "[-.2, .2, .2, .2, .2, .2, -.2, .2]", - "z": "[.3, .3, .3, .3, .3, .3, .3, .3]" + "z": "[.3, .3, .3, .3, .3, .3, .3, .3]", }, ) assert execute_all(db, "select * from t3") == [ @@ -1011,18 +1011,29 @@ def test_vec0_updates(): { "rowid": 2, "aaa": _f32([-0.2, 0.2, 0.2, 0.2, 0.2, 0.2, -0.2, 0.2]), - "bbb": _int8([-26, 24, 24, 24, 24, 24, -26, 24]), + "bbb": _int8([-26, 24, 24, 24, 24, 24, -26, 24]), "ccc": bitmap("10111110"), }, { "rowid": 3, "aaa": _f32([0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3]), - "bbb": _int8([37, 37, 37, 37, 37, 37, 37, 37, ]), + "bbb": _int8( + [ + 37, + 37, + 37, + 37, + 37, + 37, + 37, + 37, + ] + ), "ccc": bitmap("11111111"), }, ] - db.execute("UPDATE t3 SET aaa = ? WHERE rowid = 1", ['[.9,.9,.9,.9,.9,.9,.9,.9]']) + db.execute("UPDATE t3 SET aaa = ? WHERE rowid = 1", ["[.9,.9,.9,.9,.9,.9,.9,.9]"]) assert execute_all(db, "select * from t3") == [ { "rowid": 1, @@ -1033,45 +1044,70 @@ def test_vec0_updates(): { "rowid": 2, "aaa": _f32([-0.2, 0.2, 0.2, 0.2, 0.2, 0.2, -0.2, 0.2]), - "bbb": _int8([-26, 24, 24, 24, 24, 24, -26, 24]), + "bbb": _int8([-26, 24, 24, 24, 24, 24, -26, 24]), "ccc": bitmap("10111110"), }, { "rowid": 3, "aaa": _f32([0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3]), - "bbb": _int8([37, 37, 37, 37, 37, 37, 37, 37, ]), + "bbb": _int8( + [ + 37, + 37, + 37, + 37, + 37, + 37, + 37, + 37, + ] + ), "ccc": bitmap("11111111"), }, ] # EVIDENCE-OF: V15203_32042 vec0 UPDATE validates vector - with _raises('Updated vector for the "aaa" column is invalid: invalid float32 vector BLOB length. Must be divisible by 4, found 1'): + with _raises( + 'Updated vector for the "aaa" column is invalid: invalid float32 vector BLOB length. Must be divisible by 4, found 1' + ): db.execute("UPDATE t3 SET aaa = X'AB' WHERE rowid = 1") # EVIDENCE-OF: V25739_09810 vec0 UPDATE validates dimension length - with _raises('Dimension mismatch for new updated vector for the "aaa" column. Expected 8 dimensions but received 1.'): + with _raises( + 'Dimension mismatch for new updated vector for the "aaa" column. Expected 8 dimensions but received 1.' + ): db.execute("UPDATE t3 SET aaa = vec_bit(X'AABBCCDD') WHERE rowid = 1") # EVIDENCE-OF: V03643_20481 vec0 UPDATE validates vector column type - with _raises('Updated vector for the "bbb" column is expected to be of type int8, but a float32 vector was provided.'): + with _raises( + 'Updated vector for the "bbb" column is expected to be of type int8, but a float32 vector was provided.' + ): db.execute("UPDATE t3 SET bbb = X'ABABABAB' WHERE rowid = 1") db.execute("CREATE VIRTUAL TABLE t2 USING vec0(a float[2], b float[2])") db.execute("INSERT INTO t2(rowid, a, b) VALUES (1, '[.1, .1]', '[.2, .2]')") - assert execute_all(db, "select * from t2") == [{ - 'rowid': 1, - 'a': _f32([.1, .1]), - 'b': _f32([.2, .2]), - }] + assert execute_all(db, "select * from t2") == [ + { + "rowid": 1, + "a": _f32([0.1, 0.1]), + "b": _f32([0.2, 0.2]), + } + ] # sanity check: the 1st column UPDATE "works", but since the 2nd one fails, # then aaa should remain unchanged. - with _raises('Dimension mismatch for new updated vector for the "b" column. Expected 2 dimensions but received 3.'): - db.execute("UPDATE t2 SET a = '[.11, .11]', b = '[.22, .22, .22]' WHERE rowid = 1") - assert execute_all(db, "select * from t2") == [{ - 'rowid': 1, - 'a': _f32([.1, .1]), - 'b': _f32([.2, .2]), - }] + with _raises( + 'Dimension mismatch for new updated vector for the "b" column. Expected 2 dimensions but received 3.' + ): + db.execute( + "UPDATE t2 SET a = '[.11, .11]', b = '[.22, .22, .22]' WHERE rowid = 1" + ) + assert execute_all(db, "select * from t2") == [ + { + "rowid": 1, + "a": _f32([0.1, 0.1]), + "b": _f32([0.2, 0.2]), + } + ] # TODO: set UPDATEs on int8/bit columns # db.execute("UPDATE t3 SET ccc = vec_bit(?) WHERE rowid = 3", [bitmap('01010101')]) @@ -1108,27 +1144,29 @@ def test_vec0_text_pk(): ); """ ) - db.executemany("INSERT INTO t VALUES (:t_id, :aaa, :bbb)", + db.executemany( + "INSERT INTO t VALUES (:t_id, :aaa, :bbb)", [ { - "t_id": "t_1", - "aaa": "[.1, .1, .1, .1, -.1, -.1, -.1, -.1]", - "bbb": "[.1, .1, .1, .1, -.1, -.1, -.1, -.1]", + "t_id": "t_1", + "aaa": "[.1, .1, .1, .1, -.1, -.1, -.1, -.1]", + "bbb": "[.1, .1, .1, .1, -.1, -.1, -.1, -.1]", }, { - "t_id": "t_2", - "aaa": "[.1, .1, .1, .1, -.1, -.1, -.1, -.1]", - "bbb": "[.1, .1, .1, .1, -.1, -.1, -.1, -.1]", + "t_id": "t_2", + "aaa": "[.1, .1, .1, .1, -.1, -.1, -.1, -.1]", + "bbb": "[.1, .1, .1, .1, -.1, -.1, -.1, -.1]", }, { - "t_id": "t_3", - "aaa": "[.1, .1, .1, .1, -.1, -.1, -.1, -.1]", - "bbb": "[.1, .1, .1, .1, -.1, -.1, -.1, -.1]", + "t_id": "t_3", + "aaa": "[.1, .1, .1, .1, -.1, -.1, -.1, -.1]", + "bbb": "[.1, .1, .1, .1, -.1, -.1, -.1, -.1]", }, ], ) assert execute_all(db, "select * from t") == [] + def authorizer_deny_on(operation, x1, x2=None): def _auth(op, p1, p2, p3, p4): if op == operation and p1 == x1 and p2 == x2: