[Bug fix] Iterator not found on unique indexes with == (#4108)

This commit is contained in:
Emmanuel Keller 2024-05-28 16:30:24 +01:00 committed by GitHub
parent 9962c56961
commit f79a946cbe
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 95 additions and 37 deletions

View file

@ -578,7 +578,7 @@ impl<'a> Processor<'a> {
return Ok(());
} else {
return Err(Error::QueryNotExecutedDetail {
message: "No Iterator has been found.".to_string(),
message: "No iterator has been found.".to_string(),
});
}
}

View file

@ -450,9 +450,16 @@ impl QueryExecutor {
io: IndexOption,
) -> Result<Option<ThingIterator>, Error> {
Ok(match io.op() {
IndexOperator::Equality(value) => Some(ThingIterator::UniqueEqual(
UniqueEqualThingIterator::new(irf, opt.ns(), opt.db(), &ix.what, &ix.name, value),
)),
IndexOperator::Equality(value) | IndexOperator::Exactness(value) => {
Some(ThingIterator::UniqueEqual(UniqueEqualThingIterator::new(
irf,
opt.ns(),
opt.db(),
&ix.what,
&ix.name,
value,
)))
}
IndexOperator::Union(value) => {
Some(ThingIterator::UniqueUnion(UniqueUnionThingIterator::new(irf, opt, ix, value)))
}

View file

@ -1,6 +1,7 @@
mod parse;
use parse::Parse;
mod helpers;
use crate::helpers::skip_ok;
use helpers::new_ds;
use surrealdb::dbs::Session;
use surrealdb::err::Error;
@ -20,9 +21,8 @@ async fn select_where_matches_using_index() -> Result<(), Error> {
let res = &mut dbs.execute(sql, &ses, None).await?;
assert_eq!(res.len(), 5);
//
let _ = res.remove(0).result?;
let _ = res.remove(0).result?;
let _ = res.remove(0).result?;
skip_ok(res, 3)?;
//
let tmp = res.remove(0).result?;
let val = Value::parse(
"[
@ -74,10 +74,8 @@ async fn select_where_matches_without_using_index_iterator() -> Result<(), Error
let res = &mut dbs.execute(sql, &ses, None).await?;
assert_eq!(res.len(), 6);
//
let _ = res.remove(0).result?;
let _ = res.remove(0).result?;
let _ = res.remove(0).result?;
let _ = res.remove(0).result?;
skip_ok(res, 4)?;
//
let tmp = res.remove(0).result?;
let val = Value::parse(
"[
@ -135,9 +133,7 @@ async fn select_where_matches_using_index_and_arrays(parallel: bool) -> Result<(
let res = &mut dbs.execute(&sql, &ses, None).await?;
assert_eq!(res.len(), 5);
//
let _ = res.remove(0).result?;
let _ = res.remove(0).result?;
let _ = res.remove(0).result?;
skip_ok(res, 3)?;
//
let tmp = res.remove(0).result?;
let val = Value::parse(
@ -208,9 +204,7 @@ async fn select_where_matches_partial_highlight() -> Result<(), Error> {
let res = &mut dbs.execute(sql, &ses, None).await?;
assert_eq!(res.len(), 9);
//
for _ in 0..3 {
let _ = res.remove(0).result?;
}
skip_ok(res, 3)?;
//
for i in 0..2 {
let tmp = res.remove(0).result?;
@ -295,9 +289,7 @@ async fn select_where_matches_partial_highlight_ngram() -> Result<(), Error> {
let res = &mut dbs.execute(sql, &ses, None).await?;
assert_eq!(res.len(), 10);
//
for _ in 0..3 {
let _ = res.remove(0).result?;
}
skip_ok(res, 3)?;
//
for i in 0..3 {
let tmp = res.remove(0).result?;
@ -383,9 +375,7 @@ async fn select_where_matches_using_index_and_objects(parallel: bool) -> Result<
let res = &mut dbs.execute(&sql, &ses, None).await?;
assert_eq!(res.len(), 5);
//
let _ = res.remove(0).result?;
let _ = res.remove(0).result?;
let _ = res.remove(0).result?;
skip_ok(res, 3)?;
//
let tmp = res.remove(0).result?;
let val = Value::parse(
@ -453,9 +443,8 @@ async fn select_where_matches_using_index_offsets() -> Result<(), Error> {
let res = &mut dbs.execute(sql, &ses, None).await?;
assert_eq!(res.len(), 5);
//
for _ in 0..4 {
let _ = res.remove(0).result?;
}
skip_ok(res, 4)?;
//
let tmp = res.remove(0).result?;
let val = Value::parse(
"[
@ -491,9 +480,8 @@ async fn select_where_matches_using_index_and_score() -> Result<(), Error> {
let res = &mut dbs.execute(sql, &ses, None).await?;
assert_eq!(res.len(), 7);
//
for _ in 0..6 {
let _ = res.remove(0).result?;
}
skip_ok(res, 6)?;
//
let tmp = res.remove(0).result?;
let val = Value::parse(
"[
@ -529,10 +517,8 @@ async fn select_where_matches_without_using_index_and_score() -> Result<(), Erro
let res = &mut dbs.execute(sql, &ses, None).await?;
assert_eq!(res.len(), 9);
//
for _ in 0..7 {
let _ = res.remove(0).result?;
}
skip_ok(res, 7)?;
//
let tmp = res.remove(0).result?;
let val = Value::parse(
"[
@ -579,10 +565,8 @@ async fn select_where_matches_without_complex_query() -> Result<(), Error> {
let res = &mut dbs.execute(sql, &ses, None).await?;
assert_eq!(res.len(), 10);
//
for _ in 0..6 {
let _ = res.remove(0).result?;
}
skip_ok(res, 6)?;
//
let tmp = res.remove(0).result?;
let val_docs = Value::parse(
"[
@ -653,3 +637,70 @@ async fn select_where_matches_without_complex_query() -> Result<(), Error> {
assert_eq!(format!("{:#}", tmp), format!("{:#}", val_docs));
Ok(())
}
#[tokio::test]
async fn select_where_matches_mixing_indexes() -> Result<(), Error> {
let sql = r"
DEFINE ANALYZER edgeNgram TOKENIZERS class FILTERS lowercase,ascii,edgeNgram(1,10);
DEFINE INDEX idxPersonName ON TABLE person COLUMNS name SEARCH ANALYZER edgeNgram BM25;
DEFINE INDEX idxSecurityNumber ON TABLE person COLUMNS securityNumber UNIQUE;
CREATE person:1 content {name: 'Tobie', securityNumber: '123456'};
CREATE person:2 content {name: 'Jaime', securityNumber: 'ABCDEF'};
SELECT * FROM person WHERE name @@ 'Tobie' || securityNumber == '123456' EXPLAIN;
SELECT * FROM person WHERE name @@ 'Tobie' || securityNumber == '123456';
";
let dbs = new_ds().await?;
let ses = Session::owner().with_ns("test").with_db("test");
let res = &mut dbs.execute(sql, &ses, None).await?;
assert_eq!(res.len(), 7);
//
skip_ok(res, 5)?;
//
let tmp = res.remove(0).result?;
let val = Value::parse(
"[
{
detail: {
plan: {
index: 'idxPersonName',
operator: '@@',
value: 'Tobie'
},
table: 'person'
},
operation: 'Iterate Index'
},
{
detail: {
plan: {
index: 'idxSecurityNumber',
operator: '==',
value: '123456'
},
table: 'person'
},
operation: 'Iterate Index'
},
{
detail: {
type: 'Memory'
},
operation: 'Collector'
}
]",
);
assert_eq!(format!("{:#}", tmp), format!("{:#}", val));
//
let tmp = res.remove(0).result?;
let val = Value::parse(
"[
{
id: person:1,
name: 'Tobie',
securityNumber: '123456'
}
]",
);
assert_eq!(format!("{:#}", tmp), format!("{:#}", val));
Ok(())
}