feat: the query planner should support params (#2200)

This commit is contained in:
Emmanuel Keller 2023-06-30 17:51:03 +01:00 committed by GitHub
parent 699880f155
commit 1b73d3e4e4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 16 additions and 8 deletions

View file

@ -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))

View file

@ -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,
})
}

View file

@ -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)),

View file

@ -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?;
}