mirror of
https://github.com/asg017/sqlite-vec.git
synced 2026-04-26 01:06:27 +02:00
block WHERE constraints on auxiliary columns in KNN queries
This commit is contained in:
parent
7d4c023928
commit
743511af55
3 changed files with 81 additions and 1 deletions
13
sqlite-vec.c
13
sqlite-vec.c
|
|
@ -4923,6 +4923,7 @@ static int vec0BestIndex(sqlite3_vtab *pVTab, sqlite3_index_info *pIdxInfo) {
|
|||
int iRowidTerm = -1;
|
||||
int iKTerm = -1;
|
||||
int iRowidInTerm = -1;
|
||||
int hasAuxConstraint = 0;
|
||||
|
||||
#ifdef SQLITE_VEC_DEBUG
|
||||
printf("pIdxInfo->nOrderBy=%d, pIdxInfo->nConstraint=%d\n", pIdxInfo->nOrderBy, pIdxInfo->nConstraint);
|
||||
|
|
@ -4977,6 +4978,11 @@ static int vec0BestIndex(sqlite3_vtab *pVTab, sqlite3_index_info *pIdxInfo) {
|
|||
if (op == SQLITE_INDEX_CONSTRAINT_EQ && iColumn == vec0_column_k_idx(p)) {
|
||||
iKTerm = i;
|
||||
}
|
||||
if(
|
||||
(op != SQLITE_INDEX_CONSTRAINT_LIMIT && op != SQLITE_INDEX_CONSTRAINT_OFFSET)
|
||||
&& vec0_column_idx_is_auxiliary(p, iColumn)) {
|
||||
hasAuxConstraint = 1;
|
||||
}
|
||||
}
|
||||
|
||||
sqlite3_str *idxStr = sqlite3_str_new(NULL);
|
||||
|
|
@ -5019,6 +5025,13 @@ static int vec0BestIndex(sqlite3_vtab *pVTab, sqlite3_index_info *pIdxInfo) {
|
|||
}
|
||||
}
|
||||
|
||||
if(hasAuxConstraint) {
|
||||
// IMP: V25623_09693
|
||||
vtab_set_error(pVTab, "An illegal WHERE constraint was provided on a vec0 auxiliary column in a KNN query.");
|
||||
rc = SQLITE_ERROR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
sqlite3_str_appendchar(idxStr, 1, VEC0_QUERY_PLAN_KNN);
|
||||
|
||||
int argvIndex = 1;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,59 @@
|
|||
'message': 'vec0 constructor error: More than 16 auxiliary columns were provided',
|
||||
})
|
||||
# ---
|
||||
# name: test_knn
|
||||
OrderedDict({
|
||||
'sql': 'select * from v',
|
||||
'rows': list([
|
||||
OrderedDict({
|
||||
'rowid': 1,
|
||||
'vector': b'\x00\x00\x80?',
|
||||
'name': 'alex',
|
||||
}),
|
||||
OrderedDict({
|
||||
'rowid': 2,
|
||||
'vector': b'\x00\x00\x00@',
|
||||
'name': 'brian',
|
||||
}),
|
||||
OrderedDict({
|
||||
'rowid': 3,
|
||||
'vector': b'\x00\x00@@',
|
||||
'name': 'craig',
|
||||
}),
|
||||
]),
|
||||
})
|
||||
# ---
|
||||
# name: test_knn[illegal KNN w/ aux]
|
||||
dict({
|
||||
'error': 'OperationalError',
|
||||
'message': 'An illegal WHERE constraint was provided on a vec0 auxiliary column in a KNN query.',
|
||||
})
|
||||
# ---
|
||||
# name: test_knn[legal KNN w/ aux]
|
||||
OrderedDict({
|
||||
'sql': "select *, distance from v where vector match '[5]' and k = 10",
|
||||
'rows': list([
|
||||
OrderedDict({
|
||||
'rowid': 3,
|
||||
'vector': b'\x00\x00@@',
|
||||
'name': 'craig',
|
||||
'distance': 2.0,
|
||||
}),
|
||||
OrderedDict({
|
||||
'rowid': 2,
|
||||
'vector': b'\x00\x00\x00@',
|
||||
'name': 'brian',
|
||||
'distance': 3.0,
|
||||
}),
|
||||
OrderedDict({
|
||||
'rowid': 1,
|
||||
'vector': b'\x00\x00\x80?',
|
||||
'name': 'alex',
|
||||
'distance': 4.0,
|
||||
}),
|
||||
]),
|
||||
})
|
||||
# ---
|
||||
# name: test_normal.1
|
||||
OrderedDict({
|
||||
'sql': 'select * from v',
|
||||
|
|
|
|||
|
|
@ -81,7 +81,21 @@ def test_deletes(db, snapshot):
|
|||
|
||||
|
||||
def test_knn(db, snapshot):
|
||||
pass
|
||||
db.execute("create virtual table v using vec0(vector float[1], +name text)")
|
||||
db.executemany(
|
||||
"insert into v(vector, name) values (?, ?)",
|
||||
[("[1]", "alex"), ("[2]", "brian"), ("[3]", "craig")],
|
||||
)
|
||||
assert exec(db, "select * from v") == snapshot()
|
||||
assert exec(
|
||||
db, "select *, distance from v where vector match '[5]' and k = 10"
|
||||
) == snapshot(name="legal KNN w/ aux")
|
||||
|
||||
# EVIDENCE-OF: V25623_09693 No aux constraint allowed on KNN queries
|
||||
assert exec(
|
||||
db,
|
||||
"select *, distance from v where vector match '[5]' and k = 10 and name = 'alex'",
|
||||
) == snapshot(name="illegal KNN w/ aux")
|
||||
|
||||
|
||||
def exec(db, sql, parameters=[]):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue