Skip to content

Commit

Permalink
Add session context to evaluation (#446)
Browse files Browse the repository at this point in the history
  • Loading branch information
jpschorr authored Mar 7, 2024
1 parent 00924f2 commit 4d9ae54
Show file tree
Hide file tree
Showing 29 changed files with 660 additions and 151 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci_build_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ jobs:
- name: Rust Toolchain
uses: dtolnay/rust-toolchain@master
with:
toolchain: nightly-2023-03-09
toolchain: nightly-2023-06-09
- uses: actions/cache@v3
id: restore-build
with:
Expand Down Expand Up @@ -132,7 +132,7 @@ jobs:
- name: Rust Toolchain
uses: dtolnay/rust-toolchain@master
with:
toolchain: nightly-2023-03-09
toolchain: nightly-2023-06-09
- uses: actions/cache@v3
id: restore-build-and-conformance
with:
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
### Changed
- Adds quotes to the attributes of PartiQL tuple's debug output so it can be read and transformed using Kotlin `partiql-cli`
- [breaking] Changes the interface to `EvalPlan` to accept an `EvalContext`

### Added
- Add `partiql-extension-visualize` for visualizing AST and logical plan
- Add a `SessionContext` containing both a system-level and a user-level context object usable by expression evaluation

### Fixed
- Fixed `ORDER BY`'s ability to see into projection aliases
Expand Down
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
17 changes: 14 additions & 3 deletions extension/partiql-extension-ion-functions/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use partiql_logical as logical;
use partiql_value::Value;
use std::borrow::Cow;

use partiql_catalog::context::SessionContext;
use std::error::Error;
use std::fmt::Debug;
use std::fs::File;
Expand Down Expand Up @@ -98,7 +99,11 @@ impl BaseTableFunctionInfo for ReadIonFunction {
pub(crate) struct EvalFnReadIon {}

impl BaseTableExpr for EvalFnReadIon {
fn evaluate(&self, args: &[Cow<Value>]) -> BaseTableExprResult {
fn evaluate<'c>(
&self,
args: &[Cow<Value>],
_ctx: &'c dyn SessionContext<'c>,
) -> BaseTableExprResult<'c> {
if let Some(arg1) = args.first() {
match arg1.as_ref() {
Value::String(path) => parse_ion_file(path),
Expand Down Expand Up @@ -155,11 +160,13 @@ fn parse_ion_buff<'a, I: 'a + ToIonDataSource>(input: I) -> BaseTableExprResult<
mod tests {
use super::*;

use partiql_catalog::context::SystemContext;
use partiql_catalog::{Catalog, Extension, PartiqlCatalog};
use partiql_eval::env::basic::MapBindings;
use partiql_eval::eval::BasicContext;
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 +196,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
27 changes: 27 additions & 0 deletions partiql-catalog/src/context.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use partiql_value::{BindingsName, DateTime, Tuple, Value};
use std::any::Any;
use std::fmt::Debug;

pub trait Bindings<T>: Debug {
fn get(&self, name: &BindingsName) -> Option<&T>;
}

impl Bindings<Value> for Tuple {
fn get(&self, name: &BindingsName) -> Option<&Value> {
self.get(name)
}
}

#[derive(Debug)]
pub struct SystemContext {
pub now: DateTime,
}

/// Represents a session context that is used during evaluation of a plan.
pub trait SessionContext<'a>: Debug {
fn bindings(&self) -> &dyn Bindings<Value>;

fn system_context(&self) -> &SystemContext;

fn user_context(&self, name: &str) -> Option<&(dyn Any)>;
}
9 changes: 8 additions & 1 deletion partiql-catalog/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use partiql_types::PartiqlType;
use partiql_value::Value;
use std::borrow::Cow;

use crate::context::SessionContext;
use std::collections::HashMap;
use std::error::Error;
use std::fmt::Debug;
Expand All @@ -13,6 +14,8 @@ use unicase::UniCase;

pub mod call_defs;

pub mod context;

pub trait Extension: Debug {
fn name(&self) -> String;
fn load(&self, catalog: &mut dyn Catalog) -> Result<(), Box<dyn Error>>;
Expand Down Expand Up @@ -49,7 +52,11 @@ pub type BaseTableExprResult<'a> =
Result<BaseTableExprResultValueIter<'a>, BaseTableExprResultError>;

pub trait BaseTableExpr: Debug {
fn evaluate(&self, args: &[Cow<Value>]) -> BaseTableExprResult;
fn evaluate<'c>(
&self,
args: &[Cow<Value>],
ctx: &'c dyn SessionContext<'c>,
) -> BaseTableExprResult<'c>;
}

pub trait BaseTableFunctionInfo: Debug {
Expand Down
19 changes: 13 additions & 6 deletions partiql-conformance-tests/tests/mod.rs
Original file line number Diff line number Diff line change
@@ -1,13 +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};
use partiql_logical as logical;
use partiql_parser::{Parsed, ParserError, ParserResult};
use partiql_value::Value;
use partiql_value::DateTime;

use partiql_catalog::context::SystemContext;
use thiserror::Error;

mod test_value;
Expand Down Expand Up @@ -58,8 +59,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<'c>(mut plan: EvalPlan, ctx: &'c dyn EvalContext<'c>) -> EvalResult {
plan.execute_mut(ctx)
}

#[track_caller]
Expand Down Expand Up @@ -161,9 +162,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: 8 additions & 3 deletions partiql-eval/benches/bench_eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,19 @@ use std::borrow::Cow;
use std::time::Duration;

use criterion::{black_box, criterion_group, criterion_main, Criterion};
use partiql_catalog::context::SystemContext;
use partiql_catalog::PartiqlCatalog;

use partiql_eval::env::basic::MapBindings;
use partiql_eval::eval::EvalPlan;
use partiql_eval::eval::{BasicContext, EvalPlan};
use partiql_eval::plan;
use partiql_eval::plan::EvaluationMode;
use partiql_logical as logical;
use partiql_logical::BindingsOp::{Project, ProjectAll};
use partiql_logical::{
BinaryOp, BindingsOp, JoinKind, LogicalPlan, PathComponent, ValueExpr, VarRefType,
};
use partiql_value::{bag, list, tuple, BindingsName, Value};
use partiql_value::{bag, list, tuple, BindingsName, DateTime, Value};

fn data() -> MapBindings<Value> {
let hr = tuple![(
Expand Down Expand Up @@ -134,7 +135,11 @@ fn eval_plan(logical: &LogicalPlan<BindingsOp>) -> EvalPlan {
}

fn evaluate(mut plan: EvalPlan, bindings: MapBindings<Value>) -> Value {
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
11 changes: 1 addition & 10 deletions partiql-eval/src/env.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,8 @@
use partiql_catalog::context::Bindings;
use partiql_value::{BindingsName, Tuple, Value};
use std::fmt::Debug;
use unicase::UniCase;

pub trait Bindings<T>: Debug {
fn get(&self, name: &BindingsName) -> Option<&T>;
}

impl Bindings<Value> for Tuple {
fn get(&self, name: &BindingsName) -> Option<&Value> {
self.get(name)
}
}

pub mod basic {
use super::*;
use std::collections::HashMap;
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")
}
}
Loading

1 comment on commit 4d9ae54

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PartiQL (rust) Benchmark

Benchmark suite Current: 4d9ae54 Previous: 00924f2 Ratio
arith_agg-avg 750597 ns/iter (± 7488) 754554 ns/iter (± 4322) 0.99
arith_agg-avg_distinct 836315 ns/iter (± 3793) 844531 ns/iter (± 2241) 0.99
arith_agg-count 793759 ns/iter (± 19048) 797390 ns/iter (± 13786) 1.00
arith_agg-count_distinct 826980 ns/iter (± 4937) 829564 ns/iter (± 6228) 1.00
arith_agg-min 796934 ns/iter (± 3103) 804063 ns/iter (± 2274) 0.99
arith_agg-min_distinct 832026 ns/iter (± 9211) 839403 ns/iter (± 2762) 0.99
arith_agg-max 803358 ns/iter (± 2992) 810532 ns/iter (± 3029) 0.99
arith_agg-max_distinct 843917 ns/iter (± 2002) 846513 ns/iter (± 2781) 1.00
arith_agg-sum 799575 ns/iter (± 23513) 808493 ns/iter (± 2023) 0.99
arith_agg-sum_distinct 832584 ns/iter (± 13265) 838090 ns/iter (± 2608) 0.99
arith_agg-avg-count-min-max-sum 935970 ns/iter (± 2693) 952146 ns/iter (± 5957) 0.98
arith_agg-avg-count-min-max-sum-group_by 1166138 ns/iter (± 17416) 1193797 ns/iter (± 14549) 0.98
arith_agg-avg-count-min-max-sum-group_by-group_as 1757688 ns/iter (± 17890) 1780324 ns/iter (± 17197) 0.99
arith_agg-avg_distinct-count_distinct-min_distinct-max_distinct-sum_distinct 1267440 ns/iter (± 16676) 1234325 ns/iter (± 21454) 1.03
arith_agg-avg_distinct-count_distinct-min_distinct-max_distinct-sum_distinct-group_by 1532572 ns/iter (± 102361) 1509448 ns/iter (± 19471) 1.02
arith_agg-avg_distinct-count_distinct-min_distinct-max_distinct-sum_distinct-group_by-group_as 2101194 ns/iter (± 18999) 2093994 ns/iter (± 19080) 1.00
parse-1 4189 ns/iter (± 17) 4277 ns/iter (± 18) 0.98
parse-15 39717 ns/iter (± 169) 39387 ns/iter (± 147) 1.01
parse-30 79927 ns/iter (± 1192) 77794 ns/iter (± 231) 1.03
compile-1 4182 ns/iter (± 16) 4404 ns/iter (± 13) 0.95
compile-15 30759 ns/iter (± 181) 32097 ns/iter (± 165) 0.96
compile-30 62767 ns/iter (± 193) 65060 ns/iter (± 486) 0.96
plan-1 67023 ns/iter (± 672) 65323 ns/iter (± 523) 1.03
plan-15 1044691 ns/iter (± 28724) 1023202 ns/iter (± 23909) 1.02
plan-30 2085981 ns/iter (± 15790) 2038989 ns/iter (± 5575) 1.02
eval-1 12576519 ns/iter (± 152058) 12530654 ns/iter (± 145755) 1.00
eval-15 85195131 ns/iter (± 1406453) 86425714 ns/iter (± 1706273) 0.99
eval-30 164167304 ns/iter (± 410291) 165648119 ns/iter (± 775470) 0.99
join 9793 ns/iter (± 144) 9722 ns/iter (± 64) 1.01
simple 2513 ns/iter (± 3) 2432 ns/iter (± 5) 1.03
simple-no 442 ns/iter (± 2) 434 ns/iter (± 3) 1.02
numbers 59 ns/iter (± 0) 57 ns/iter (± 0) 1.04
parse-simple 567 ns/iter (± 1) 577 ns/iter (± 3) 0.98
parse-ion 1755 ns/iter (± 6) 1776 ns/iter (± 20) 0.99
parse-group 6093 ns/iter (± 12) 5726 ns/iter (± 84) 1.06
parse-complex 15229 ns/iter (± 905) 14529 ns/iter (± 42) 1.05
parse-complex-fexpr 21704 ns/iter (± 729) 21178 ns/iter (± 656) 1.02

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.