mirror of
https://github.com/asg017/sqlite-vec.git
synced 2026-04-26 01:06:27 +02:00
fix aux column error when using non-default rowid values, needs test
This commit is contained in:
parent
da29ace630
commit
1a216a684d
3 changed files with 84 additions and 62 deletions
1
TODO
1
TODO
|
|
@ -17,6 +17,7 @@
|
||||||
- skip invalid validity entries in knn filter?
|
- skip invalid validity entries in knn filter?
|
||||||
- null!
|
- null!
|
||||||
- date/datetime
|
- date/datetime
|
||||||
|
- [ ] test accessing aux values when rowid is different than 1,2,3 etc.
|
||||||
- later
|
- later
|
||||||
- `v in (...)` handling
|
- `v in (...)` handling
|
||||||
- remaining TODO items
|
- remaining TODO items
|
||||||
|
|
|
||||||
117
sqlite-vec.c
117
sqlite-vec.c
|
|
@ -7680,67 +7680,6 @@ int vec0Update_Insert(sqlite3_vtab *pVTab, int argc, sqlite3_value **argv,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(p->numAuxiliaryColumns > 0) {
|
|
||||||
sqlite3_stmt *stmt;
|
|
||||||
sqlite3_str * s = sqlite3_str_new(NULL);
|
|
||||||
sqlite3_str_appendf(s, "INSERT INTO " VEC0_SHADOW_AUXILIARY_NAME "(", p->schemaName, p->tableName);
|
|
||||||
for(int i = 0; i < p->numAuxiliaryColumns; i++) {
|
|
||||||
if(i!=0) {
|
|
||||||
sqlite3_str_appendchar(s, 1, ',');
|
|
||||||
}
|
|
||||||
sqlite3_str_appendf(s, "value%02d", i);
|
|
||||||
}
|
|
||||||
sqlite3_str_appendall(s, ") VALUES (");
|
|
||||||
for(int i = 0; i < p->numAuxiliaryColumns; i++) {
|
|
||||||
if(i!=0) {
|
|
||||||
sqlite3_str_appendchar(s, 1, ',');
|
|
||||||
}
|
|
||||||
sqlite3_str_appendchar(s, 1, '?');
|
|
||||||
}
|
|
||||||
sqlite3_str_appendall(s, ")");
|
|
||||||
char * zSql = sqlite3_str_finish(s);
|
|
||||||
// TODO double check error handling ehre
|
|
||||||
if(!zSql) {
|
|
||||||
rc = SQLITE_NOMEM;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
rc = sqlite3_prepare_v2(p->db, zSql, -1, &stmt, NULL);
|
|
||||||
if(rc != SQLITE_OK) {
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < vec0_num_defined_user_columns(p); i++) {
|
|
||||||
if(p->user_column_kinds[i] != SQLITE_VEC0_USER_COLUMN_KIND_AUXILIARY) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
int auxiliary_key_idx = p->user_column_idxs[i];
|
|
||||||
sqlite3_value * v = argv[2+VEC0_COLUMN_USERN_START + i];
|
|
||||||
int v_type = sqlite3_value_type(v);
|
|
||||||
if(v_type != SQLITE_NULL && (v_type != p->auxiliary_columns[auxiliary_key_idx].type)) {
|
|
||||||
sqlite3_finalize(stmt);
|
|
||||||
rc = SQLITE_ERROR;
|
|
||||||
vtab_set_error(
|
|
||||||
pVTab,
|
|
||||||
"Auxiliary column type mismatch: The auxiliary column %.*s has type %s, but %s was provided.",
|
|
||||||
p->auxiliary_columns[auxiliary_key_idx].name_length,
|
|
||||||
p->auxiliary_columns[auxiliary_key_idx].name,
|
|
||||||
type_name(p->auxiliary_columns[auxiliary_key_idx].type),
|
|
||||||
type_name(v_type)
|
|
||||||
);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
sqlite3_bind_value(stmt, 1 + auxiliary_key_idx, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = sqlite3_step(stmt);
|
|
||||||
if(rc != SQLITE_DONE) {
|
|
||||||
sqlite3_finalize(stmt);
|
|
||||||
rc = SQLITE_ERROR;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
sqlite3_finalize(stmt);
|
|
||||||
}
|
|
||||||
|
|
||||||
// read all the inserted vectors into vectorDatas, validate their lengths.
|
// read all the inserted vectors into vectorDatas, validate their lengths.
|
||||||
for (int i = 0; i < vec0_num_defined_user_columns(p); i++) {
|
for (int i = 0; i < vec0_num_defined_user_columns(p); i++) {
|
||||||
if(p->user_column_kinds[i] != SQLITE_VEC0_USER_COLUMN_KIND_VECTOR) {
|
if(p->user_column_kinds[i] != SQLITE_VEC0_USER_COLUMN_KIND_VECTOR) {
|
||||||
|
|
@ -7832,6 +7771,62 @@ int vec0Update_Insert(sqlite3_vtab *pVTab, int argc, sqlite3_value **argv,
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(p->numAuxiliaryColumns > 0) {
|
||||||
|
sqlite3_stmt *stmt;
|
||||||
|
sqlite3_str * s = sqlite3_str_new(NULL);
|
||||||
|
sqlite3_str_appendf(s, "INSERT INTO " VEC0_SHADOW_AUXILIARY_NAME "(rowid ", p->schemaName, p->tableName);
|
||||||
|
for(int i = 0; i < p->numAuxiliaryColumns; i++) {
|
||||||
|
sqlite3_str_appendf(s, ", value%02d", i);
|
||||||
|
}
|
||||||
|
sqlite3_str_appendall(s, ") VALUES (? ");
|
||||||
|
for(int i = 0; i < p->numAuxiliaryColumns; i++) {
|
||||||
|
sqlite3_str_appendall(s, ", ?");
|
||||||
|
}
|
||||||
|
sqlite3_str_appendall(s, ")");
|
||||||
|
char * zSql = sqlite3_str_finish(s);
|
||||||
|
// TODO double check error handling ehre
|
||||||
|
if(!zSql) {
|
||||||
|
rc = SQLITE_NOMEM;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
rc = sqlite3_prepare_v2(p->db, zSql, -1, &stmt, NULL);
|
||||||
|
if(rc != SQLITE_OK) {
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
sqlite3_bind_int64(stmt, 1, rowid);
|
||||||
|
|
||||||
|
for (int i = 0; i < vec0_num_defined_user_columns(p); i++) {
|
||||||
|
if(p->user_column_kinds[i] != SQLITE_VEC0_USER_COLUMN_KIND_AUXILIARY) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int auxiliary_key_idx = p->user_column_idxs[i];
|
||||||
|
sqlite3_value * v = argv[2+VEC0_COLUMN_USERN_START + i];
|
||||||
|
int v_type = sqlite3_value_type(v);
|
||||||
|
if(v_type != SQLITE_NULL && (v_type != p->auxiliary_columns[auxiliary_key_idx].type)) {
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
rc = SQLITE_ERROR;
|
||||||
|
vtab_set_error(
|
||||||
|
pVTab,
|
||||||
|
"Auxiliary column type mismatch: The auxiliary column %.*s has type %s, but %s was provided.",
|
||||||
|
p->auxiliary_columns[auxiliary_key_idx].name_length,
|
||||||
|
p->auxiliary_columns[auxiliary_key_idx].name,
|
||||||
|
type_name(p->auxiliary_columns[auxiliary_key_idx].type),
|
||||||
|
type_name(v_type)
|
||||||
|
);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
sqlite3_bind_value(stmt, 1 + 1 + auxiliary_key_idx, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = sqlite3_step(stmt);
|
||||||
|
if(rc != SQLITE_DONE) {
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
rc = SQLITE_ERROR;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
for(int i = 0; i < vec0_num_defined_user_columns(p); i++) {
|
for(int i = 0; i < vec0_num_defined_user_columns(p); i++) {
|
||||||
if(p->user_column_kinds[i] != SQLITE_VEC0_USER_COLUMN_KIND_METADATA) {
|
if(p->user_column_kinds[i] != SQLITE_VEC0_USER_COLUMN_KIND_METADATA) {
|
||||||
|
|
|
||||||
28
test.sql
28
test.sql
|
|
@ -1,10 +1,36 @@
|
||||||
|
|
||||||
.load dist/vec0
|
.load dist/vec0
|
||||||
.echo on
|
|
||||||
.bail on
|
.bail on
|
||||||
|
|
||||||
.mode qbox
|
.mode qbox
|
||||||
|
|
||||||
|
create virtual table v using vec0(
|
||||||
|
vector float[1],
|
||||||
|
+description text
|
||||||
|
);
|
||||||
|
insert into v(rowid, vector, description) values (1, '[1]', 'aaa');
|
||||||
|
select * from v;
|
||||||
|
|
||||||
|
.exit
|
||||||
|
|
||||||
|
create virtual table vec_articles using vec0(
|
||||||
|
article_id integer primary key,
|
||||||
|
year integer partition key,
|
||||||
|
headline_embedding float[1],
|
||||||
|
+headline text,
|
||||||
|
+url text,
|
||||||
|
word_count integer,
|
||||||
|
print_section text,
|
||||||
|
print_page integer,
|
||||||
|
pub_date text,
|
||||||
|
);
|
||||||
|
|
||||||
|
insert into vec_articles values (1111, 2020, '[1]', 'headline', 'https://...', 200, 'A', 1, '2020-01-01');
|
||||||
|
|
||||||
|
select * from vec_articles;
|
||||||
|
|
||||||
|
.exit
|
||||||
|
|
||||||
|
|
||||||
create table movies(movie_id integer primary key, synopsis text);
|
create table movies(movie_id integer primary key, synopsis text);
|
||||||
INSERT INTO movies(movie_id, synopsis)
|
INSERT INTO movies(movie_id, synopsis)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue