feat: the query planner should support params (#2200)
This commit is contained in:
parent
699880f155
commit
1b73d3e4e4
4 changed files with 16 additions and 8 deletions
|
@ -30,18 +30,17 @@ impl<'a> QueryPlanner<'a> {
|
|||
pub(crate) async fn get_iterable(
|
||||
&mut self,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
t: Table,
|
||||
) -> Result<Iterable, Error> {
|
||||
let txn = ctx.try_clone_transaction()?;
|
||||
let res = Tree::build(self.opt, &txn, &t, self.cond).await?;
|
||||
let res = Tree::build(ctx, self.opt, &txn, &t, self.cond).await?;
|
||||
if let Some((node, im)) = res {
|
||||
if let Some(plan) = AllAndStrategy::build(&node)? {
|
||||
let e = QueryExecutor::new(opt, &txn, &t, im, Some(plan.e.clone())).await?;
|
||||
let e = QueryExecutor::new(self.opt, &txn, &t, im, Some(plan.e.clone())).await?;
|
||||
self.executors.insert(t.0.clone(), e);
|
||||
return Ok(Iterable::Index(t, plan));
|
||||
}
|
||||
let e = QueryExecutor::new(opt, &txn, &t, im, None).await?;
|
||||
let e = QueryExecutor::new(self.opt, &txn, &t, im, None).await?;
|
||||
self.executors.insert(t.0.clone(), e);
|
||||
}
|
||||
Ok(Iterable::Table(t))
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::err::Error;
|
||||
use crate::idx::planner::plan::IndexOption;
|
||||
|
@ -14,12 +15,14 @@ impl Tree {
|
|||
/// Traverse the all the conditions and extract every expression
|
||||
/// that can be resolved by an index.
|
||||
pub(super) async fn build<'a>(
|
||||
ctx: &'a Context<'_>,
|
||||
opt: &'a Options,
|
||||
txn: &'a Transaction,
|
||||
table: &'a Table,
|
||||
cond: &Option<Cond>,
|
||||
) -> Result<Option<(Node, IndexMap)>, Error> {
|
||||
let mut b = TreeBuilder {
|
||||
ctx,
|
||||
opt,
|
||||
txn,
|
||||
table,
|
||||
|
@ -35,6 +38,7 @@ impl Tree {
|
|||
}
|
||||
|
||||
struct TreeBuilder<'a> {
|
||||
ctx: &'a Context<'a>,
|
||||
opt: &'a Options,
|
||||
txn: &'a Transaction,
|
||||
table: &'a Table,
|
||||
|
@ -74,6 +78,10 @@ impl<'a> TreeBuilder<'a> {
|
|||
Value::Number(_) => Node::Scalar(v.to_owned()),
|
||||
Value::Bool(_) => Node::Scalar(v.to_owned()),
|
||||
Value::Subquery(s) => self.eval_subquery(s).await?,
|
||||
Value::Param(p) => {
|
||||
let v = p.compute(self.ctx, self.opt).await?;
|
||||
self.eval_value(&v).await?
|
||||
}
|
||||
_ => Node::Unsupported,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -89,7 +89,7 @@ impl SelectStatement {
|
|||
let v = w.compute(ctx, opt).await?;
|
||||
match v {
|
||||
Value::Table(t) => {
|
||||
i.ingest(planner.get_iterable(ctx, opt, t).await?);
|
||||
i.ingest(planner.get_iterable(ctx, t).await?);
|
||||
}
|
||||
Value::Thing(v) => i.ingest(Iterable::Thing(v)),
|
||||
Value::Range(v) => i.ingest(Iterable::Range(*v)),
|
||||
|
|
|
@ -234,15 +234,16 @@ async fn select_where_matches_without_using_index_and_score() -> Result<(), Erro
|
|||
CREATE blog:4 SET title = 'the dog sat there and did nothing';
|
||||
DEFINE ANALYZER simple TOKENIZERS blank,class;
|
||||
DEFINE INDEX blog_title ON blog FIELDS title SEARCH ANALYZER simple BM25 HIGHLIGHTS;
|
||||
SELECT id,search::score(1) AS score FROM blog WHERE (title @1@ 'animals' AND id>0) OR (title @1@ 'animals' AND id<99);
|
||||
LET $keywords = 'animals';
|
||||
SELECT id,search::score(1) AS score FROM blog WHERE (title @1@ $keywords AND id>0) OR (title @1@ $keywords AND id<99);
|
||||
SELECT id,search::score(1) + search::score(2) AS score FROM blog WHERE title @1@ 'dummy1' OR title @2@ 'dummy2';
|
||||
";
|
||||
let dbs = Datastore::new("memory").await?;
|
||||
let ses = Session::for_kv().with_ns("test").with_db("test");
|
||||
let res = &mut dbs.execute(&sql, &ses, None, false).await?;
|
||||
assert_eq!(res.len(), 8);
|
||||
assert_eq!(res.len(), 9);
|
||||
//
|
||||
for _ in 0..6 {
|
||||
for _ in 0..7 {
|
||||
let _ = res.remove(0).result?;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue