Ensure parameters in record ranges are computed

This commit is contained in:
Tobie Morgan Hitchcock 2022-11-03 10:55:32 +00:00
parent 7f953319ec
commit a4db0d8427
4 changed files with 58 additions and 12 deletions

View file

@ -1,4 +1,8 @@
use crate::cnf::ID_CHARS; use crate::cnf::ID_CHARS;
use crate::ctx::Context;
use crate::dbs::Options;
use crate::dbs::Transaction;
use crate::err::Error;
use crate::sql::array::{array, Array}; use crate::sql::array::{array, Array};
use crate::sql::error::IResult; use crate::sql::error::IResult;
use crate::sql::escape::escape_rid; use crate::sql::escape::escape_rid;
@ -109,6 +113,29 @@ impl Display for Id {
} }
} }
impl Id {
pub(crate) async fn compute(
&self,
ctx: &Context<'_>,
opt: &Options,
txn: &Transaction,
doc: Option<&Value>,
) -> Result<Id, Error> {
match self {
Id::Number(v) => Ok(Id::Number(*v)),
Id::String(v) => Ok(Id::String(v.clone())),
Id::Object(v) => match v.compute(ctx, opt, txn, doc).await? {
Value::Object(v) => Ok(Id::Object(v)),
_ => unreachable!(),
},
Id::Array(v) => match v.compute(ctx, opt, txn, doc).await? {
Value::Array(v) => Ok(Id::Array(v)),
_ => unreachable!(),
},
}
}
}
pub fn id(i: &str) -> IResult<&str, Id> { pub fn id(i: &str) -> IResult<&str, Id> {
alt(( alt((
map(integer, Id::Number), map(integer, Id::Number),

View file

@ -1,6 +1,11 @@
use crate::ctx::Context;
use crate::dbs::Options;
use crate::dbs::Transaction;
use crate::err::Error;
use crate::sql::error::IResult; use crate::sql::error::IResult;
use crate::sql::id::{id, Id}; use crate::sql::id::{id, Id};
use crate::sql::ident::ident_raw; use crate::sql::ident::ident_raw;
use crate::sql::value::Value;
use nom::branch::alt; use nom::branch::alt;
use nom::character::complete::char; use nom::character::complete::char;
use nom::combinator::map; use nom::combinator::map;
@ -19,6 +24,30 @@ pub struct Range {
pub end: Bound<Id>, pub end: Bound<Id>,
} }
impl Range {
pub(crate) async fn compute(
&self,
ctx: &Context<'_>,
opt: &Options,
txn: &Transaction,
doc: Option<&Value>,
) -> Result<Value, Error> {
Ok(Value::Range(Box::new(Range {
tb: self.tb.clone(),
beg: match &self.beg {
Bound::Included(id) => Bound::Included(id.compute(ctx, opt, txn, doc).await?),
Bound::Excluded(id) => Bound::Excluded(id.compute(ctx, opt, txn, doc).await?),
Bound::Unbounded => Bound::Unbounded,
},
end: match &self.end {
Bound::Included(id) => Bound::Included(id.compute(ctx, opt, txn, doc).await?),
Bound::Excluded(id) => Bound::Excluded(id.compute(ctx, opt, txn, doc).await?),
Bound::Unbounded => Bound::Unbounded,
},
})))
}
}
impl PartialOrd for Range { impl PartialOrd for Range {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> { fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
match self.tb.partial_cmp(&other.tb) { match self.tb.partial_cmp(&other.tb) {

View file

@ -66,18 +66,7 @@ impl Thing {
) -> Result<Value, Error> { ) -> Result<Value, Error> {
Ok(Value::Thing(Thing { Ok(Value::Thing(Thing {
tb: self.tb.clone(), tb: self.tb.clone(),
id: match &self.id { id: self.id.compute(ctx, opt, txn, doc).await?,
Id::Number(v) => Id::Number(*v),
Id::String(v) => Id::String(v.clone()),
Id::Object(v) => match v.compute(ctx, opt, txn, doc).await? {
Value::Object(v) => Id::Object(v),
_ => unreachable!(),
},
Id::Array(v) => match v.compute(ctx, opt, txn, doc).await? {
Value::Array(v) => Id::Array(v),
_ => unreachable!(),
},
},
})) }))
} }
} }

View file

@ -1278,6 +1278,7 @@ impl Value {
Value::True => Ok(Value::True), Value::True => Ok(Value::True),
Value::False => Ok(Value::False), Value::False => Ok(Value::False),
Value::Thing(v) => v.compute(ctx, opt, txn, doc).await, Value::Thing(v) => v.compute(ctx, opt, txn, doc).await,
Value::Range(v) => v.compute(ctx, opt, txn, doc).await,
Value::Param(v) => v.compute(ctx, opt, txn, doc).await, Value::Param(v) => v.compute(ctx, opt, txn, doc).await,
Value::Idiom(v) => v.compute(ctx, opt, txn, doc).await, Value::Idiom(v) => v.compute(ctx, opt, txn, doc).await,
Value::Array(v) => v.compute(ctx, opt, txn, doc).await, Value::Array(v) => v.compute(ctx, opt, txn, doc).await,