Skip to content

Commit

Permalink
Extend EvalContext to allow user context
Browse files Browse the repository at this point in the history
  • Loading branch information
jpschorr committed Mar 5, 2024
1 parent 00924f2 commit 6c5aa29
Show file tree
Hide file tree
Showing 20 changed files with 355 additions and 117 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ homepage = "https://github.com/partiql/partiql-lang-rust"
repository = "https://github.com/partiql/partiql-lang-rust"
version = "0.6.0"
edition = "2021"
resolver = 2

[workspace]
resolver = "2"

members = [
"partiql",
Expand Down
9 changes: 7 additions & 2 deletions extension/partiql-extension-ion-functions/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,9 +157,10 @@ mod tests {

use partiql_catalog::{Catalog, Extension, PartiqlCatalog};
use partiql_eval::env::basic::MapBindings;
use partiql_eval::eval::{BasicContext, SystemContext};
use partiql_eval::plan::EvaluationMode;
use partiql_parser::{Parsed, ParserResult};
use partiql_value::{bag, tuple, Value};
use partiql_value::{bag, tuple, DateTime, Value};

#[track_caller]
#[inline]
Expand Down Expand Up @@ -189,7 +190,11 @@ mod tests {

let mut plan = planner.compile(&logical).expect("Expect no plan error");

if let Ok(out) = plan.execute_mut(bindings) {
let sys = SystemContext {
now: DateTime::from_system_now_utc(),
};
let ctx = BasicContext::new(bindings, sys);
if let Ok(out) = plan.execute_mut(&ctx) {
out.result
} else {
Value::Missing
Expand Down
20 changes: 14 additions & 6 deletions partiql-conformance-tests/tests/mod.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
use partiql_ast_passes::error::AstTransformationError;
use partiql_catalog::{Catalog, PartiqlCatalog};
use partiql_eval as eval;
use partiql_eval::env::basic::MapBindings;

use partiql_eval::error::{EvalErr, PlanErr};
use partiql_eval::eval::{EvalPlan, EvalResult, Evaluated};
use partiql_eval::eval::{
BasicContext, EvalContext, EvalPlan, EvalResult, Evaluated, SystemContext,
};
use partiql_logical as logical;
use partiql_parser::{Parsed, ParserError, ParserResult};
use partiql_value::Value;
use partiql_value::DateTime;

use thiserror::Error;

Expand Down Expand Up @@ -58,8 +60,8 @@ pub(crate) fn compile(

#[track_caller]
#[inline]
pub(crate) fn evaluate(mut plan: EvalPlan, bindings: MapBindings<Value>) -> EvalResult {
plan.execute_mut(bindings)
pub(crate) fn evaluate<'a, 'c>(mut plan: EvalPlan, ctx: &'c dyn EvalContext<'c>) -> EvalResult {
plan.execute_mut(ctx)
}

#[track_caller]
Expand Down Expand Up @@ -161,9 +163,15 @@ pub(crate) fn eval<'a>(

let parsed = parse(statement)?;
let lowered = lower(&catalog, &parsed)?;

let bindings = env.as_ref().map(|e| (&e.value).into()).unwrap_or_default();
let sys = SystemContext {
now: DateTime::from_system_now_utc(),
};
let ctx = BasicContext::new(bindings, sys);
let plan = compile(mode, &catalog, lowered)?;
Ok(evaluate(plan, bindings)?)

Ok(evaluate(plan, &ctx)?)
}

#[track_caller]
Expand Down
1 change: 1 addition & 0 deletions partiql-eval/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ assert_matches = "1.5.*"
regex = "1.7"
regex-syntax = "0.6"
rustc-hash = "1"
delegate = "0.12"

[dev-dependencies]
criterion = "0.4"
Expand Down
11 changes: 9 additions & 2 deletions partiql-eval/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ impl ErrorNode {
}

impl Evaluable for ErrorNode {
fn evaluate(&mut self, _ctx: &dyn EvalContext) -> Value {
fn evaluate<'a, 'c>(&mut self, _ctx: &'c dyn EvalContext<'c>) -> Value {
panic!("ErrorNode will not be evaluated")
}

Expand All @@ -66,7 +66,14 @@ impl Evaluable for ErrorNode {
}

impl EvalExpr for ErrorNode {
fn evaluate<'a>(&'a self, _bindings: &'a Tuple, _ctx: &'a dyn EvalContext) -> Cow<'a, Value> {
fn evaluate<'a, 'c>(
&'a self,
_bindings: &'a Tuple,
_ctx: &'c dyn EvalContext<'c>,
) -> Cow<'a, Value>
where
'c: 'a,
{
panic!("ErrorNode will not be evaluated")
}
}
62 changes: 43 additions & 19 deletions partiql-eval/src/eval/eval_expr_wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,13 @@ pub(crate) fn unwrap_args<const N: usize>(
/// An expression that is evaluated over `N` input arguments
pub(crate) trait ExecuteEvalExpr<const N: usize>: Debug {
/// Evaluate the expression
fn evaluate<'a>(
fn evaluate<'a, 'c>(
&'a self,
args: [Cow<'a, Value>; N],
ctx: &'a dyn EvalContext,
) -> Cow<'a, Value>;
ctx: &'c dyn EvalContext<'c>,
) -> Cow<'a, Value>
where
'c: 'a;
}

/// Used to tell argument checking whether it should exit early or go on as usual.
Expand Down Expand Up @@ -249,11 +251,14 @@ impl<const STRICT: bool, const N: usize, E: ExecuteEvalExpr<N>, ArgC: ArgChecker
///
/// If type-checking fails, the appropriate failure case of [`ArgCheckControlFlow`] is returned,
/// else [`ArgCheckControlFlow::Continue`] is returned containing the `N` values.
pub fn evaluate_args<'a>(
pub fn evaluate_args<'a, 'c>(
&'a self,
bindings: &'a Tuple,
ctx: &'a dyn EvalContext,
) -> ControlFlow<Value, [Cow<Value>; N]> {
ctx: &'c dyn EvalContext<'c>,
) -> ControlFlow<Value, [Cow<Value>; N]>
where
'c: 'a,
{
let err_arg_count_mismatch = |args: Vec<_>| {
if STRICT {
ctx.add_error(EvaluationError::IllegalState(format!(
Expand Down Expand Up @@ -326,7 +331,14 @@ impl<const STRICT: bool, const N: usize, E: ExecuteEvalExpr<N>, ArgC: ArgChecker
impl<const STRICT: bool, const N: usize, E: ExecuteEvalExpr<N>, ArgC: ArgChecker> EvalExpr
for ArgCheckEvalExpr<STRICT, N, E, ArgC>
{
fn evaluate<'a>(&'a self, bindings: &'a Tuple, ctx: &'a dyn EvalContext) -> Cow<'a, Value> {
fn evaluate<'a, 'c>(
&'a self,
bindings: &'a Tuple,
ctx: &'c dyn EvalContext<'c>,
) -> Cow<'a, Value>
where
'c: 'a,
{
if STRICT && ctx.has_errors() {
return Cow::Owned(Missing);
}
Expand Down Expand Up @@ -379,11 +391,14 @@ where
F: Fn(&Value) -> Value,
{
#[inline]
fn evaluate<'a>(
fn evaluate<'a, 'c>(
&'a self,
args: [Cow<'a, Value>; 1],
_ctx: &'a dyn EvalContext,
) -> Cow<'a, Value> {
_ctx: &'c dyn EvalContext<'c>,
) -> Cow<'a, Value>
where
'c: 'a,
{
let [arg] = args;
Cow::Owned((self.f)(arg.borrow()))
}
Expand Down Expand Up @@ -440,11 +455,14 @@ where
F: Fn(&Value, &Value) -> Value,
{
#[inline]
fn evaluate<'a>(
fn evaluate<'a, 'c>(
&'a self,
args: [Cow<'a, Value>; 2],
_ctx: &'a dyn EvalContext,
) -> Cow<'a, Value> {
_ctx: &'c dyn EvalContext<'c>,
) -> Cow<'a, Value>
where
'c: 'a,
{
let [arg1, arg2] = args;
Cow::Owned((self.f)(arg1.borrow(), arg2.borrow()))
}
Expand Down Expand Up @@ -501,11 +519,14 @@ where
F: Fn(&Value, &Value, &Value) -> Value,
{
#[inline]
fn evaluate<'a>(
fn evaluate<'a, 'c>(
&'a self,
args: [Cow<'a, Value>; 3],
_ctx: &'a dyn EvalContext,
) -> Cow<'a, Value> {
_ctx: &'c dyn EvalContext<'c>,
) -> Cow<'a, Value>
where
'c: 'a,
{
let [arg1, arg2, arg3] = args;
Cow::Owned((self.f)(arg1.borrow(), arg2.borrow(), arg3.borrow()))
}
Expand Down Expand Up @@ -562,11 +583,14 @@ where
F: Fn(&Value, &Value, &Value, &Value) -> Value,
{
#[inline]
fn evaluate<'a>(
fn evaluate<'a, 'c>(
&'a self,
args: [Cow<'a, Value>; 4],
_ctx: &'a dyn EvalContext,
) -> Cow<'a, Value> {
_ctx: &'c dyn EvalContext<'c>,
) -> Cow<'a, Value>
where
'c: 'a,
{
let [arg1, arg2, arg3, arg4] = args;
Cow::Owned((self.f)(
arg1.borrow(),
Expand Down
Loading

0 comments on commit 6c5aa29

Please sign in to comment.