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::idx::planner::plan::{IndexOperator, IndexOption};
|
||||||
use crate::sql::index::Index;
|
use crate::sql::index::Index;
|
||||||
use crate::sql::statements::DefineIndexStatement;
|
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 async_recursion::async_recursion;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
@ -126,6 +126,13 @@ impl<'a> TreeBuilder<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn eval_idiom(&mut self, i: &Idiom) -> Result<Node, Error> {
|
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 let Some(irs) = self.find_indexes(i).await? {
|
||||||
if !irs.is_empty() {
|
if !irs.is_empty() {
|
||||||
return Ok(Node::IndexedField(i.to_owned(), irs));
|
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
|
/// Check if this Value is a Geometry of a specific type
|
||||||
pub fn is_geometry_type(&self, types: &[String]) -> bool {
|
pub fn is_geometry_type(&self, types: &[String]) -> bool {
|
||||||
match self {
|
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> {
|
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
|
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