Fix index plan for idiom param value (#2865)
This commit is contained in:
parent
bc2f7fdafa
commit
cfdd7c195c
3 changed files with 53 additions and 1 deletions
|
@ -4,7 +4,7 @@ use crate::err::Error;
|
|||
use crate::idx::planner::plan::{IndexOperator, IndexOption};
|
||||
use crate::sql::index::Index;
|
||||
use crate::sql::statements::DefineIndexStatement;
|
||||
use crate::sql::{Array, Cond, Expression, Idiom, Operator, Subquery, Table, Value, With};
|
||||
use crate::sql::{Array, Cond, Expression, Idiom, Operator, Part, Subquery, Table, Value, With};
|
||||
use async_recursion::async_recursion;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
|
@ -126,6 +126,13 @@ impl<'a> TreeBuilder<'a> {
|
|||
}
|
||||
|
||||
async fn eval_idiom(&mut self, i: &Idiom) -> Result<Node, Error> {
|
||||
// Compute the idiom value if it is a param
|
||||
if let Some(Part::Start(x)) = i.0.first() {
|
||||
if x.is_param() {
|
||||
let v = i.compute(self.ctx, self.opt, self.txn, None).await?;
|
||||
return self.eval_value(&v).await;
|
||||
}
|
||||
}
|
||||
if let Some(irs) = self.find_indexes(i).await? {
|
||||
if !irs.is_empty() {
|
||||
return Ok(Node::IndexedField(i.to_owned(), irs));
|
||||
|
|
|
@ -991,6 +991,11 @@ impl Value {
|
|||
}
|
||||
}
|
||||
|
||||
/// Check if this Value is a Param
|
||||
pub fn is_param(&self) -> bool {
|
||||
matches!(self, Value::Param(_))
|
||||
}
|
||||
|
||||
/// Check if this Value is a Geometry of a specific type
|
||||
pub fn is_geometry_type(&self, types: &[String]) -> bool {
|
||||
match self {
|
||||
|
|
|
@ -846,3 +846,43 @@ async fn select_index_single_range_operator_more_or_equal() -> Result<(), Error>
|
|||
async fn select_unique_single_range_operator_more_or_equal() -> Result<(), Error> {
|
||||
select_single_range_operator(true, ">=", EXPLAIN_MORE_OR_EQUAL, RESULT_MORE_OR_EQUAL).await
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn select_with_idiom_param_value() -> Result<(), Error> {
|
||||
let dbs = new_ds().await?;
|
||||
let ses = Session::owner().with_ns("test").with_db("test");
|
||||
let sql = format!(
|
||||
"
|
||||
CREATE person:tobie SET name = 'Tobie', genre='m', company='SurrealDB';
|
||||
CREATE person:jaime SET name = 'Jaime', genre='m', company='SurrealDB';
|
||||
DEFINE INDEX name ON TABLE person COLUMNS name UNIQUE;
|
||||
LET $name = 'Tobie';
|
||||
LET $nameObj = {{name:'Tobie'}};
|
||||
SELECT name FROM person WHERE name = $nameObj.name EXPLAIN;"
|
||||
);
|
||||
let mut res = dbs.execute(&sql, &ses, None).await?;
|
||||
assert_eq!(res.len(), 6);
|
||||
res.remove(0).result?;
|
||||
res.remove(0).result?;
|
||||
res.remove(0).result?;
|
||||
res.remove(0).result?;
|
||||
res.remove(0).result?;
|
||||
let tmp = res.remove(0).result?;
|
||||
let val = Value::parse(
|
||||
r#"[
|
||||
{
|
||||
detail: {
|
||||
plan: {
|
||||
index: 'name',
|
||||
operator: '=',
|
||||
value: 'Tobie'
|
||||
},
|
||||
table: 'person'
|
||||
},
|
||||
operation: 'Iterate Index'
|
||||
}
|
||||
]"#,
|
||||
);
|
||||
assert_eq!(format!("{:#}", tmp), format!("{:#}", val));
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue