From ed3a1810dcdee96ff45d6875fd4e1a1245ade052 Mon Sep 17 00:00:00 2001 From: Josh Pschorr Date: Mon, 30 Jun 2025 16:19:22 -0700 Subject: [PATCH] Add `PartiqlSharedCatalog` for `Send`+`Sync` catalog usage. --- CHANGELOG.md | 1 + extension/partiql-extension-csv/tests/scan.rs | 7 +- .../tests/scan.rs | 7 +- partiql-ast-passes/src/name_resolver.rs | 6 +- partiql-catalog/Cargo.toml | 2 +- partiql-catalog/src/catalog.rs | 39 +++++++++-- partiql-catalog/src/scalar_fn.rs | 2 +- partiql-catalog/src/table_fn.rs | 2 +- partiql-conformance-tests/tests/mod.rs | 28 +++++--- partiql-eval/Cargo.toml | 1 + partiql-eval/benches/bench_eval.rs | 13 +++- partiql-eval/src/lib.rs | 2 +- partiql-eval/src/plan.rs | 8 +-- partiql-eval/src/test_value.rs | 2 +- partiql-logical-planner/src/lib.rs | 9 ++- partiql-logical-planner/src/lower.rs | 13 ++-- partiql-logical-planner/src/typer.rs | 13 ++-- partiql/benches/bench_agg.rs | 23 +++++-- partiql/benches/bench_eval_multi_like.rs | 65 +++++++++++-------- partiql/benches/bench_join.rs | 28 +++++--- partiql/src/lib.rs | 8 +-- partiql/src/subquery_tests.rs | 8 +-- partiql/tests/common.rs | 10 +-- partiql/tests/extension_error.rs | 8 ++- partiql/tests/graph.rs | 2 +- partiql/tests/ion.rs | 1 + partiql/tests/queries.rs | 1 + partiql/tests/tuple_ops.rs | 1 + partiql/tests/user_context.rs | 5 +- 29 files changed, 202 insertions(+), 113 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 30a79c9a..1a46f5fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Changed - Changed many internal `HashMap`s to use `rustc-hash`'s `FxHash` +- *BREAKING* Refactors `Catalog` to allow `Send`+`Sync` for re-use. ### Added diff --git a/extension/partiql-extension-csv/tests/scan.rs b/extension/partiql-extension-csv/tests/scan.rs index d57e5cd7..ed294523 100644 --- a/extension/partiql-extension-csv/tests/scan.rs +++ b/extension/partiql-extension-csv/tests/scan.rs @@ -1,4 +1,4 @@ -use partiql_catalog::catalog::{Catalog, PartiqlCatalog}; +use partiql_catalog::catalog::{PartiqlCatalog, SharedCatalog}; use partiql_catalog::context::SystemContext; use partiql_catalog::extension::Extension; use partiql_eval::env::basic::MapBindings; @@ -19,7 +19,7 @@ pub(crate) fn parse(statement: &str) -> ParserResult<'_> { #[track_caller] #[inline] pub(crate) fn lower( - catalog: &dyn Catalog, + catalog: &dyn SharedCatalog, parsed: &Parsed<'_>, ) -> partiql_logical::LogicalPlan { let planner = partiql_logical_planner::LogicalPlanner::new(catalog); @@ -29,7 +29,7 @@ pub(crate) fn lower( #[track_caller] #[inline] pub(crate) fn evaluate( - catalog: &dyn Catalog, + catalog: &dyn SharedCatalog, logical: partiql_logical::LogicalPlan, bindings: MapBindings, ) -> (Value, Vec) { @@ -61,6 +61,7 @@ pub(crate) fn evaluate_with_csv_scan( let ext = CsvExtension {}; ext.load(&mut catalog) .expect("ion extension load to succeed"); + let catalog = catalog.to_shared_catalog(); let parsed = parse(statement); let lowered = lower(&catalog, &parsed.expect("parse")); diff --git a/extension/partiql-extension-ion-functions/tests/scan.rs b/extension/partiql-extension-ion-functions/tests/scan.rs index cb9cccbd..07427889 100644 --- a/extension/partiql-extension-ion-functions/tests/scan.rs +++ b/extension/partiql-extension-ion-functions/tests/scan.rs @@ -1,4 +1,4 @@ -use partiql_catalog::catalog::{Catalog, PartiqlCatalog}; +use partiql_catalog::catalog::{PartiqlCatalog, SharedCatalog}; use partiql_catalog::context::SystemContext; use partiql_catalog::extension::Extension; use partiql_eval::env::basic::MapBindings; @@ -19,7 +19,7 @@ pub(crate) fn parse(statement: &str) -> ParserResult<'_> { #[track_caller] #[inline] pub(crate) fn lower( - catalog: &dyn Catalog, + catalog: &dyn SharedCatalog, parsed: &Parsed<'_>, ) -> partiql_logical::LogicalPlan { let planner = partiql_logical_planner::LogicalPlanner::new(catalog); @@ -29,7 +29,7 @@ pub(crate) fn lower( #[track_caller] #[inline] pub(crate) fn evaluate( - catalog: &dyn Catalog, + catalog: &dyn SharedCatalog, logical: partiql_logical::LogicalPlan, bindings: MapBindings, ) -> (Value, Vec) { @@ -61,6 +61,7 @@ pub(crate) fn evaluate_with_ion_scan( let ext = IonExtension {}; ext.load(&mut catalog) .expect("ion extension load to succeed"); + let catalog = catalog.to_shared_catalog(); let parsed = parse(statement); let lowered = lower(&catalog, &parsed.expect("parse")); diff --git a/partiql-ast-passes/src/name_resolver.rs b/partiql-ast-passes/src/name_resolver.rs index 61118c3f..18142824 100644 --- a/partiql-ast-passes/src/name_resolver.rs +++ b/partiql-ast-passes/src/name_resolver.rs @@ -4,7 +4,7 @@ use indexmap::{IndexMap, IndexSet}; use partiql_ast::ast; use partiql_ast::ast::{GraphPattern, GroupByExpr, GroupKey}; use partiql_ast::visit::{Traverse, Visit, Visitor}; -use partiql_catalog::catalog::Catalog; +use partiql_catalog::catalog::SharedCatalog; use partiql_common::node::NodeId; use std::sync::atomic::{AtomicU32, Ordering}; @@ -102,11 +102,11 @@ pub struct NameResolver<'c> { // errors that occur during name resolution errors: Vec, - catalog: &'c dyn Catalog, + catalog: &'c dyn SharedCatalog, } impl<'c> NameResolver<'c> { - pub fn new(catalog: &'c dyn Catalog) -> Self { + pub fn new(catalog: &'c dyn SharedCatalog) -> Self { NameResolver { // environment stack tracking id_path_to_root: Default::default(), diff --git a/partiql-catalog/Cargo.toml b/partiql-catalog/Cargo.toml index f9a298b4..37f8361e 100644 --- a/partiql-catalog/Cargo.toml +++ b/partiql-catalog/Cargo.toml @@ -31,5 +31,5 @@ ordered-float = "5" itertools = "0.14" unicase = "2.7" rustc-hash = "2" - +delegate = "0.13" dyn-clone = "1" diff --git a/partiql-catalog/src/catalog.rs b/partiql-catalog/src/catalog.rs index 78360dd2..e536ae36 100644 --- a/partiql-catalog/src/catalog.rs +++ b/partiql-catalog/src/catalog.rs @@ -1,6 +1,7 @@ use crate::call_defs::ScalarFnCallSpecs; use crate::scalar_fn::ScalarFunction; use crate::table_fn::TableFunction; +use delegate::delegate; use partiql_common::catalog::{CatalogId, EntryId, ObjectId}; use partiql_types::PartiqlShape; use rustc_hash::FxHashMap; @@ -42,19 +43,22 @@ pub enum CatalogErrorKind { Unknown, } -pub trait Catalog: Debug { +pub trait MutableCatalog: Debug { fn add_table_function(&mut self, info: TableFunction) -> Result; fn add_scalar_function(&mut self, info: ScalarFunction) -> Result; - fn add_type_entry(&mut self, entry: TypeEnvEntry<'_>) -> Result; +} +pub trait ReadOnlyCatalog: Debug { fn get_function(&self, name: &str) -> Option>; - fn get_function_by_id(&self, id: ObjectId) -> Option>; - fn resolve_type(&self, name: &str) -> Option; } +pub trait SharedCatalog: ReadOnlyCatalog + Send + Sync {} + +pub trait Catalog: MutableCatalog + ReadOnlyCatalog {} + #[derive(Debug)] pub struct TypeEnvEntry<'a> { name: UniCase, @@ -123,6 +127,9 @@ pub struct PartiqlCatalog { id: CatalogId, } +#[derive(Debug)] +pub struct PartiqlSharedCatalog(PartiqlCatalog); + impl Default for PartiqlCatalog { fn default() -> Self { PartiqlCatalog { @@ -133,9 +140,15 @@ impl Default for PartiqlCatalog { } } -impl PartiqlCatalog {} +impl PartiqlCatalog { + pub fn to_shared_catalog(self) -> PartiqlSharedCatalog { + PartiqlSharedCatalog(self) + } +} + +impl Catalog for PartiqlCatalog {} -impl Catalog for PartiqlCatalog { +impl MutableCatalog for PartiqlCatalog { fn add_table_function(&mut self, info: TableFunction) -> Result { let call_def = info.call_def(); let names = call_def.names.clone(); @@ -180,7 +193,9 @@ impl Catalog for PartiqlCatalog { Err(e) => Err(e), } } +} +impl ReadOnlyCatalog for PartiqlCatalog { fn get_function(&self, name: &str) -> Option> { self.functions .find_by_name(name) @@ -202,6 +217,18 @@ impl Catalog for PartiqlCatalog { } } +impl ReadOnlyCatalog for PartiqlSharedCatalog { + delegate! { + to self.0 { + fn get_function(&self, name: &str) -> Option>; + fn get_function_by_id(&self, id: ObjectId) -> Option>; + fn resolve_type(&self, name: &str) -> Option; + } + } +} + +impl SharedCatalog for PartiqlSharedCatalog {} + impl PartiqlCatalog { fn to_function_entry<'a>( &'a self, diff --git a/partiql-catalog/src/scalar_fn.rs b/partiql-catalog/src/scalar_fn.rs index 5d5b28d3..84374c42 100644 --- a/partiql-catalog/src/scalar_fn.rs +++ b/partiql-catalog/src/scalar_fn.rs @@ -11,7 +11,7 @@ use std::fmt::{Debug, Formatter}; pub type ScalarFnExprResultValue<'a> = Cow<'a, Value>; pub type ScalarFnExprResult<'a> = Result, ExtensionResultError>; -pub trait ScalarFnExpr: DynClone + Debug { +pub trait ScalarFnExpr: DynClone + Debug + Send + Sync { fn evaluate<'c>( &self, args: &[Cow<'_, Value>], diff --git a/partiql-catalog/src/table_fn.rs b/partiql-catalog/src/table_fn.rs index 27d788f0..26bab6da 100644 --- a/partiql-catalog/src/table_fn.rs +++ b/partiql-catalog/src/table_fn.rs @@ -17,7 +17,7 @@ pub trait BaseTableExpr: Debug { ) -> BaseTableExprResult<'c>; } -pub trait BaseTableFunctionInfo: Debug { +pub trait BaseTableFunctionInfo: Debug + Send + Sync { fn call_def(&self) -> &CallDef; fn plan_eval(&self) -> Box; } diff --git a/partiql-conformance-tests/tests/mod.rs b/partiql-conformance-tests/tests/mod.rs index 032a25b8..9b0278ab 100644 --- a/partiql-conformance-tests/tests/mod.rs +++ b/partiql-conformance-tests/tests/mod.rs @@ -1,5 +1,6 @@ use partiql_ast_passes::error::AstTransformationError; use partiql_eval as eval; +use std::ops::Deref; use partiql_eval::error::{EvalErr, PlanErr}; use partiql_eval::eval::{BasicContext, EvalContext, EvalPlan, EvalResult, Evaluated}; @@ -7,13 +8,20 @@ use partiql_logical as logical; use partiql_parser::{Parsed, ParserError, ParserResult}; use partiql_value::DateTime; -use partiql_catalog::catalog::{Catalog, PartiqlCatalog}; +use partiql_catalog::catalog::{PartiqlCatalog, PartiqlSharedCatalog, SharedCatalog}; use partiql_catalog::context::SystemContext; use thiserror::Error; mod test_value; pub(crate) use test_value::TestValue; +use once_cell::sync::Lazy; +pub(crate) static SHARED_CATALOG: Lazy = Lazy::new(init_shared_catalog); + +fn init_shared_catalog() -> PartiqlSharedCatalog { + PartiqlCatalog::default().to_shared_catalog() +} + #[derive(Debug, Copy, Clone)] #[allow(dead_code)] pub(crate) enum EvaluationMode { @@ -52,7 +60,7 @@ pub(crate) fn parse(statement: &str) -> ParserResult { #[track_caller] #[inline] pub(crate) fn lower( - catalog: &dyn Catalog, + catalog: &dyn SharedCatalog, parsed: &Parsed<'_>, ) -> Result, AstTransformationError> { let planner = partiql_logical_planner::LogicalPlanner::new(catalog); @@ -63,7 +71,7 @@ pub(crate) fn lower( #[inline] pub(crate) fn compile( mode: EvaluationMode, - catalog: &dyn Catalog, + catalog: &dyn SharedCatalog, logical: logical::LogicalPlan, ) -> Result { let mut planner = eval::plan::EvaluatorPlanner::new(mode.into(), catalog); @@ -103,9 +111,9 @@ pub(crate) fn pass_syntax(statement: &str) -> Parsed { #[inline] #[allow(dead_code)] pub(crate) fn fail_semantics(statement: &str) { - let catalog = PartiqlCatalog::default(); + let catalog: &PartiqlSharedCatalog = SHARED_CATALOG.deref(); if let Ok(parsed) = parse(statement) { - let lowered = lower(&catalog, &parsed); + let lowered = lower(catalog, &parsed); assert!( lowered.is_err(), @@ -118,9 +126,9 @@ pub(crate) fn fail_semantics(statement: &str) { #[inline] #[allow(dead_code)] pub(crate) fn pass_semantics(statement: &str) { - let catalog = PartiqlCatalog::default(); + let catalog: &PartiqlSharedCatalog = SHARED_CATALOG.deref(); let parsed = pass_syntax(statement); - let lowered = lower(&catalog, &parsed); + let lowered = lower(catalog, &parsed); assert!( lowered.is_ok(), "When semantically verifying `{statement}`, expected `Ok(_)`, but was `{lowered:#?}`" @@ -171,17 +179,17 @@ pub(crate) fn eval<'a>( mode: EvaluationMode, env: &Option, ) -> Result> { - let catalog = PartiqlCatalog::default(); + let catalog: &PartiqlSharedCatalog = SHARED_CATALOG.deref(); let parsed = parse(statement)?; - let lowered = lower(&catalog, &parsed)?; + 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)?; + let plan = compile(mode, catalog, lowered)?; Ok(evaluate(plan, &ctx)?) } diff --git a/partiql-eval/Cargo.toml b/partiql-eval/Cargo.toml index 8aeb0d4e..6cdecca2 100644 --- a/partiql-eval/Cargo.toml +++ b/partiql-eval/Cargo.toml @@ -44,6 +44,7 @@ rustc-hash = "2" delegate = "0.13" serde = { version = "1", features = ["derive"], optional = true } +once_cell = "1" [dev-dependencies] criterion = "0.5" diff --git a/partiql-eval/benches/bench_eval.rs b/partiql-eval/benches/bench_eval.rs index 5999f9fc..63e2d06a 100644 --- a/partiql-eval/benches/bench_eval.rs +++ b/partiql-eval/benches/bench_eval.rs @@ -1,10 +1,12 @@ use std::borrow::Cow; +use std::ops::Deref; use std::time::Duration; use criterion::{black_box, criterion_group, criterion_main, Criterion}; -use partiql_catalog::catalog::PartiqlCatalog; +use partiql_catalog::catalog::{PartiqlCatalog, PartiqlSharedCatalog}; use partiql_catalog::context::SystemContext; +use once_cell::sync::Lazy; use partiql_eval::env::basic::MapBindings; use partiql_eval::eval::{BasicContext, EvalPlan}; use partiql_eval::plan; @@ -16,6 +18,11 @@ use partiql_logical::{ VarRefType, }; use partiql_value::{bag, list, tuple, BindingsName, DateTime, Value}; +pub(crate) static SHARED_CATALOG: Lazy = Lazy::new(init_shared_catalog); + +fn init_shared_catalog() -> PartiqlSharedCatalog { + PartiqlCatalog::default().to_shared_catalog() +} fn data() -> MapBindings { let hr = tuple![( @@ -130,8 +137,8 @@ fn logical_plan() -> LogicalPlan { } fn eval_plan(logical: &LogicalPlan) -> EvalPlan { - let catalog = PartiqlCatalog::default(); - let mut planner = plan::EvaluatorPlanner::new(EvaluationMode::Permissive, &catalog); + let catalog: &PartiqlSharedCatalog = SHARED_CATALOG.deref(); + let mut planner = plan::EvaluatorPlanner::new(EvaluationMode::Permissive, catalog); planner.compile(logical).expect("Expect no plan error") } diff --git a/partiql-eval/src/lib.rs b/partiql-eval/src/lib.rs index 08d17c50..7aa45b36 100644 --- a/partiql-eval/src/lib.rs +++ b/partiql-eval/src/lib.rs @@ -31,7 +31,7 @@ mod tests { use partiql_value::{bag, list, tuple, Bag, BindingsName, DateTime, List, Tuple, Value}; fn evaluate(logical: LogicalPlan, bindings: MapBindings) -> Value { - let catalog = PartiqlCatalog::default(); + let catalog = PartiqlCatalog::default().to_shared_catalog(); let mut planner = plan::EvaluatorPlanner::new(EvaluationMode::Permissive, &catalog); let plan = planner.compile(&logical).expect("Expect no plan error"); let sys = SystemContext { diff --git a/partiql-eval/src/plan.rs b/partiql-eval/src/plan.rs index da39e0bc..40ba1318 100644 --- a/partiql-eval/src/plan.rs +++ b/partiql-eval/src/plan.rs @@ -17,7 +17,7 @@ use crate::eval::graph::string_graph::StringGraphTypes; use crate::eval::EvalPlan; use eval::graph::plan as physical; use itertools::{Either, Itertools}; -use partiql_catalog::catalog::{Catalog, FunctionEntryFunction}; +use partiql_catalog::catalog::{FunctionEntryFunction, SharedCatalog}; use partiql_extension_ion::boxed_ion::BoxedIonType; use partiql_logical as logical; use partiql_logical::{ @@ -61,7 +61,7 @@ pub enum EvaluationMode { pub struct EvaluatorPlanner<'c> { mode: EvaluationMode, - catalog: &'c dyn Catalog, + catalog: &'c dyn SharedCatalog, errors: Vec, } @@ -126,7 +126,7 @@ impl From<&BinaryOp> for EvalOpBinary { } impl<'c> EvaluatorPlanner<'c> { - pub fn new(mode: EvaluationMode, catalog: &'c dyn Catalog) -> Self { + pub fn new(mode: EvaluationMode, catalog: &'c dyn SharedCatalog) -> Self { EvaluatorPlanner { mode, catalog, @@ -1056,7 +1056,7 @@ mod tests { let sink = logical.add_operator(BindingsOp::Sink); logical.add_flow(expq, sink); - let catalog = PartiqlCatalog::default(); + let catalog = PartiqlCatalog::default().to_shared_catalog(); let mut planner = EvaluatorPlanner::new(EvaluationMode::Permissive, &catalog); let plan = planner.compile(&logical); diff --git a/partiql-eval/src/test_value.rs b/partiql-eval/src/test_value.rs index b5fd6ee2..c76537c2 100644 --- a/partiql-eval/src/test_value.rs +++ b/partiql-eval/src/test_value.rs @@ -62,7 +62,7 @@ pub(crate) fn parse_partiql_value_str(contents: &str) -> Value { use partiql_catalog::catalog::PartiqlCatalog; use partiql_catalog::context::SystemContext; use partiql_value::DateTime; - let catalog = PartiqlCatalog::default(); + let catalog = PartiqlCatalog::default().to_shared_catalog(); let parsed = partiql_parser::Parser::default() .parse(contents) .expect("Expect successful parse"); diff --git a/partiql-logical-planner/src/lib.rs b/partiql-logical-planner/src/lib.rs index 089117a5..5f240557 100644 --- a/partiql-logical-planner/src/lib.rs +++ b/partiql-logical-planner/src/lib.rs @@ -8,7 +8,7 @@ use partiql_ast_passes::name_resolver::NameResolver; use partiql_logical as logical; use partiql_parser::Parsed; -use partiql_catalog::catalog::{Catalog, PartiqlCatalog}; +use partiql_catalog::catalog::SharedCatalog; mod builtins; mod functions; @@ -17,11 +17,11 @@ mod lower; mod typer; pub struct LogicalPlanner<'c> { - catalog: &'c dyn Catalog, + catalog: &'c dyn SharedCatalog, } impl<'c> LogicalPlanner<'c> { - pub fn new(catalog: &'c dyn Catalog) -> Self { + pub fn new(catalog: &'c dyn SharedCatalog) -> Self { LogicalPlanner { catalog } } @@ -31,8 +31,7 @@ impl<'c> LogicalPlanner<'c> { parsed: &Parsed<'_>, ) -> Result, AstTransformationError> { let q = &parsed.ast; - let catalog = PartiqlCatalog::default(); - let mut resolver = NameResolver::new(&catalog); + let mut resolver = NameResolver::new(self.catalog); let registry = resolver.resolve(q)?; let planner = AstToLogical::new(self.catalog, registry); planner.lower_query(q) diff --git a/partiql-logical-planner/src/lower.rs b/partiql-logical-planner/src/lower.rs index 8770ef1a..b009dab1 100644 --- a/partiql-logical-planner/src/lower.rs +++ b/partiql-logical-planner/src/lower.rs @@ -32,7 +32,7 @@ use partiql_ast_passes::error::{AstTransformError, AstTransformationError}; use crate::functions::Function; use partiql_ast_passes::name_resolver::NameRef; -use partiql_catalog::catalog::Catalog; +use partiql_catalog::catalog::SharedCatalog; use partiql_common::node::{IdAnnotated, NodeId}; use partiql_logical::AggFunc::{AggAny, AggAvg, AggCount, AggEvery, AggMax, AggMin, AggSum}; @@ -191,7 +191,7 @@ pub struct AstToLogical<'a> { // catalog & data flow data key_registry: name_resolver::KeyRegistry, fnsym_tab: &'static FnSymTab, - catalog: &'a dyn Catalog, + catalog: &'a dyn SharedCatalog, // list of errors encountered during AST lowering errors: Vec, @@ -232,7 +232,7 @@ fn infer_id(expr: &ValueExpr) -> Option { } impl<'a> AstToLogical<'a> { - pub fn new(catalog: &'a dyn Catalog, registry: name_resolver::KeyRegistry) -> Self { + pub fn new(catalog: &'a dyn SharedCatalog, registry: name_resolver::KeyRegistry) -> Self { let fnsym_tab: &FnSymTab = &FN_SYM_TAB; AstToLogical { id_stack: Default::default(), @@ -2068,14 +2068,14 @@ mod tests { use super::*; use crate::LogicalPlanner; use assert_matches::assert_matches; - use partiql_catalog::catalog::{PartiqlCatalog, TypeEnvEntry}; + use partiql_catalog::catalog::{MutableCatalog, PartiqlCatalog, TypeEnvEntry}; use partiql_logical::BindingsOp::Project; use partiql_logical::ValueExpr; use partiql_types::PartiqlShape; #[test] fn test_plan_non_existent_fns() { - let catalog = PartiqlCatalog::default(); + let catalog = PartiqlCatalog::default().to_shared_catalog(); let statement = "foo(1, 2) + bar(3)"; let parsed = partiql_parser::Parser::default() .parse(statement) @@ -2097,7 +2097,7 @@ mod tests { #[test] fn test_plan_bad_num_arguments() { - let catalog = PartiqlCatalog::default(); + let catalog = PartiqlCatalog::default().to_shared_catalog(); let statement = "abs(1, 2) + mod(3)"; let parsed = partiql_parser::Parser::default() .parse(statement) @@ -2169,6 +2169,7 @@ mod tests { let mut catalog = PartiqlCatalog::default(); let _oid = catalog.add_type_entry(TypeEnvEntry::new("customers", &[], PartiqlShape::Dynamic)); + let catalog = catalog.to_shared_catalog(); let statement = "SELECT c.id AS my_id, customers.name AS my_name FROM customers AS c"; let parsed = partiql_parser::Parser::default() .parse(statement) diff --git a/partiql-logical-planner/src/typer.rs b/partiql-logical-planner/src/typer.rs index c3a6ed29..06937270 100644 --- a/partiql-logical-planner/src/typer.rs +++ b/partiql-logical-planner/src/typer.rs @@ -1,7 +1,7 @@ use crate::typer::LookupOrder::{GlobalLocal, LocalGlobal}; use indexmap::{IndexMap, IndexSet}; use partiql_ast::ast::{CaseSensitivity, SymbolPrimitive}; -use partiql_catalog::catalog::Catalog; +use partiql_catalog::catalog::SharedCatalog; use partiql_logical::{BindingsOp, Lit, LogicalPlan, OpId, PathComponent, ValueExpr, VarRefType}; use partiql_types::{ type_array, type_bag, type_bool, type_decimal, type_dynamic, type_float64, type_int, @@ -128,7 +128,7 @@ type LocalTypeEnv = IndexMap; #[derive(Debug)] pub struct PlanTyper<'c> { typing_mode: TypingMode, - catalog: &'c dyn Catalog, + catalog: &'c dyn SharedCatalog, logical_plan: LogicalPlan, errors: Vec, type_env_stack: Vec, @@ -140,7 +140,7 @@ pub struct PlanTyper<'c> { #[allow(dead_code)] impl<'c> PlanTyper<'c> { /// Creates a new [`PlanTyper`] for the given Catalog and Intermediate Representation with `Strict` Typing Mode. - pub fn new_strict(catalog: &'c dyn Catalog, ir: &LogicalPlan) -> Self { + pub fn new_strict(catalog: &'c dyn SharedCatalog, ir: &LogicalPlan) -> Self { PlanTyper { typing_mode: TypingMode::Strict, catalog, @@ -154,7 +154,7 @@ impl<'c> PlanTyper<'c> { } /// Creates a new [`PlanTyper`] for the given Catalog and Intermediate Representation with `Permissive` Typing Mode. - pub fn new_permissive(catalog: &'c dyn Catalog, lg: &LogicalPlan) -> Self { + pub fn new_permissive(catalog: &'c dyn SharedCatalog, lg: &LogicalPlan) -> Self { PlanTyper { typing_mode: TypingMode::Permissive, catalog, @@ -605,7 +605,7 @@ mod tests { use super::*; use crate::{logical, LogicalPlanner}; use partiql_ast_passes::error::AstTransformationError; - use partiql_catalog::catalog::{PartiqlCatalog, TypeEnvEntry}; + use partiql_catalog::catalog::{MutableCatalog, PartiqlCatalog, SharedCatalog, TypeEnvEntry}; use partiql_parser::{Parsed, Parser}; use partiql_types::{ struct_fields, PartiqlNoIdShapeBuilder, ShapeBuilderExtensions, StructType, @@ -920,6 +920,7 @@ mod tests { ) -> Result { let mut catalog = PartiqlCatalog::default(); let _oid = catalog.add_type_entry(type_env_entry); + let catalog = catalog.to_shared_catalog(); let parsed = parse(query); let lg = lower(&parsed, &catalog).expect("Logical plan"); @@ -940,7 +941,7 @@ mod tests { #[track_caller] fn lower( parsed: &Parsed<'_>, - catalog: &dyn Catalog, + catalog: &dyn SharedCatalog, ) -> Result, AstTransformationError> { let planner = LogicalPlanner::new(catalog); planner.lower(parsed) diff --git a/partiql/benches/bench_agg.rs b/partiql/benches/bench_agg.rs index 2b549aa0..04eef201 100644 --- a/partiql/benches/bench_agg.rs +++ b/partiql/benches/bench_agg.rs @@ -1,8 +1,9 @@ +use std::ops::Deref; use std::time::Duration; use criterion::{black_box, criterion_group, criterion_main, Criterion}; use itertools::Itertools; -use partiql_catalog::catalog::{Catalog, PartiqlCatalog}; +use partiql_catalog::catalog::{Catalog, PartiqlCatalog, PartiqlSharedCatalog, SharedCatalog}; use partiql_catalog::context::SystemContext; use partiql_eval::env::basic::MapBindings; use partiql_eval::eval::{BasicContext, EvalPlan}; @@ -13,6 +14,13 @@ use partiql_logical_planner::LogicalPlanner; use partiql_parser::{Parser, ParserResult}; use partiql_value::{tuple, Bag, DateTime, Value}; +use once_cell::sync::Lazy; +pub(crate) static SHARED_CATALOG: Lazy = Lazy::new(init_shared_catalog); + +fn init_shared_catalog() -> PartiqlSharedCatalog { + PartiqlCatalog::default().to_shared_catalog() +} + fn numbers() -> impl Iterator { (0..1000i64).map(Value::from) } @@ -37,12 +45,15 @@ fn parse(text: &str) -> ParserResult { Parser::default().parse(text) } #[inline] -fn compile(catalog: &dyn Catalog, parsed: &partiql_parser::Parsed) -> LogicalPlan { +fn compile( + catalog: &dyn SharedCatalog, + parsed: &partiql_parser::Parsed, +) -> LogicalPlan { let planner = LogicalPlanner::new(catalog); planner.lower(parsed).expect("Expect no lower error") } #[inline] -fn plan(catalog: &dyn Catalog, logical: &LogicalPlan) -> EvalPlan { +fn plan(catalog: &dyn SharedCatalog, logical: &LogicalPlan) -> EvalPlan { EvaluatorPlanner::new(EvaluationMode::Permissive, catalog) .compile(logical) .expect("Expect no plan error") @@ -134,14 +145,14 @@ fn create_tests() -> Vec<(String, String)> { } fn bench_agg(c: &mut Criterion) { - let catalog = PartiqlCatalog::default(); + let catalog: &PartiqlSharedCatalog = SHARED_CATALOG.deref(); let bindings = data(); for (name, query) in create_tests() { - let compiled = compile(&catalog, &parse(query.as_str()).unwrap()); + let compiled = compile(catalog, &parse(query.as_str()).unwrap()); c.bench_function(name.as_str(), |b| { b.iter(|| { - let plan = plan(&catalog, &compiled); + let plan = plan(catalog, &compiled); let bindings = bindings.clone(); evaluate(black_box(plan), black_box(bindings)) }) diff --git a/partiql/benches/bench_eval_multi_like.rs b/partiql/benches/bench_eval_multi_like.rs index c38d6923..127cff1a 100644 --- a/partiql/benches/bench_eval_multi_like.rs +++ b/partiql/benches/bench_eval_multi_like.rs @@ -1,8 +1,9 @@ +use std::ops::Deref; use std::time::Duration; use criterion::{black_box, criterion_group, criterion_main, Criterion}; use itertools::Itertools; -use partiql_catalog::catalog::{Catalog, PartiqlCatalog}; +use partiql_catalog::catalog::{Catalog, PartiqlCatalog, PartiqlSharedCatalog, SharedCatalog}; use partiql_catalog::context::SystemContext; use partiql_eval::env::basic::MapBindings; use partiql_eval::eval::{BasicContext, EvalPlan}; @@ -263,6 +264,13 @@ fn employee_data() -> Vec { employee_data } +use once_cell::sync::Lazy; +pub(crate) static SHARED_CATALOG: Lazy = Lazy::new(init_shared_catalog); + +fn init_shared_catalog() -> PartiqlSharedCatalog { + PartiqlCatalog::default().to_shared_catalog() +} + fn data() -> MapBindings { let data = tuple![("hr", tuple![("employees", Bag::from(employee_data()))])]; @@ -335,12 +343,15 @@ fn parse(text: &str) -> ParserResult { Parser::default().parse(text) } #[inline] -fn compile(catalog: &dyn Catalog, parsed: &partiql_parser::Parsed) -> LogicalPlan { +fn compile( + catalog: &dyn SharedCatalog, + parsed: &partiql_parser::Parsed, +) -> LogicalPlan { let planner = LogicalPlanner::new(catalog); planner.lower(parsed).expect("Expect no lower error") } #[inline] -fn plan(catalog: &dyn Catalog, logical: &LogicalPlan) -> EvalPlan { +fn plan(catalog: &dyn SharedCatalog, logical: &LogicalPlan) -> EvalPlan { EvaluatorPlanner::new(EvaluationMode::Permissive, catalog) .compile(logical) .expect("Expect no plan error") @@ -378,27 +389,27 @@ fn bench_parse(c: &mut Criterion) { /// filter against 1, 15, or 30 `OR`ed `LIKE` expressions /// over 10201 rows of tuples containing an id and a string fn bench_compile(c: &mut Criterion) { - let catalog = PartiqlCatalog::default(); + let catalog: &PartiqlSharedCatalog = SHARED_CATALOG.deref(); let parsed_1 = parse(QUERY_1).unwrap(); let parsed_15 = parse(QUERY_15).unwrap(); let parsed_30 = parse(QUERY_30).unwrap(); - let compiled_1 = compile(&catalog, &parsed_1); + let compiled_1 = compile(catalog, &parsed_1); assert_eq!(compiled_1.operator_count(), 4); - let compiled_15 = compile(&catalog, &parsed_15); + let compiled_15 = compile(catalog, &parsed_15); assert_eq!(compiled_15.operator_count(), 4); - let compiled_30 = compile(&catalog, &parsed_30); + let compiled_30 = compile(catalog, &parsed_30); assert_eq!(compiled_30.operator_count(), 4); c.bench_function("compile-1", |b| { - b.iter(|| compile(&catalog, black_box(&parsed_1))) + b.iter(|| compile(catalog, black_box(&parsed_1))) }); c.bench_function("compile-15", |b| { - b.iter(|| compile(&catalog, black_box(&parsed_15))) + b.iter(|| compile(catalog, black_box(&parsed_15))) }); c.bench_function("compile-30", |b| { - b.iter(|| compile(&catalog, black_box(&parsed_30))) + b.iter(|| compile(catalog, black_box(&parsed_30))) }); } @@ -406,24 +417,24 @@ fn bench_compile(c: &mut Criterion) { /// filter against 1, 15, or 30 `OR`ed `LIKE` expressions /// over 10201 rows of tuples containing an id and a string fn bench_plan(c: &mut Criterion) { - let catalog = PartiqlCatalog::default(); + let catalog: &PartiqlSharedCatalog = SHARED_CATALOG.deref(); - let compiled_1 = compile(&catalog, &parse(QUERY_1).unwrap()); - let compiled_15 = compile(&catalog, &parse(QUERY_15).unwrap()); - let compiled_30 = compile(&catalog, &parse(QUERY_30).unwrap()); + let compiled_1 = compile(catalog, &parse(QUERY_1).unwrap()); + let compiled_15 = compile(catalog, &parse(QUERY_15).unwrap()); + let compiled_30 = compile(catalog, &parse(QUERY_30).unwrap()); - let _planned_1 = plan(&catalog, &compiled_1); - let _planned_15 = plan(&catalog, &compiled_15); - let _planned_30 = plan(&catalog, &compiled_30); + let _planned_1 = plan(catalog, &compiled_1); + let _planned_15 = plan(catalog, &compiled_15); + let _planned_30 = plan(catalog, &compiled_30); c.bench_function("plan-1", |b| { - b.iter(|| plan(&catalog, black_box(&compiled_1))) + b.iter(|| plan(catalog, black_box(&compiled_1))) }); c.bench_function("plan-15", |b| { - b.iter(|| plan(&catalog, black_box(&compiled_15))) + b.iter(|| plan(catalog, black_box(&compiled_15))) }); c.bench_function("plan-30", |b| { - b.iter(|| plan(&catalog, black_box(&compiled_30))) + b.iter(|| plan(catalog, black_box(&compiled_30))) }); } @@ -431,31 +442,31 @@ fn bench_plan(c: &mut Criterion) { /// filter against 1, 15, or 30 `OR`ed `LIKE` expressions /// over 10201 rows of tuples containing an id and a string fn bench_eval(c: &mut Criterion) { - let catalog = PartiqlCatalog::default(); + let catalog: &PartiqlSharedCatalog = SHARED_CATALOG.deref(); - let compiled_1 = compile(&catalog, &parse(QUERY_1).unwrap()); - let compiled_15 = compile(&catalog, &parse(QUERY_15).unwrap()); - let compiled_30 = compile(&catalog, &parse(QUERY_30).unwrap()); + let compiled_1 = compile(catalog, &parse(QUERY_1).unwrap()); + let compiled_15 = compile(catalog, &parse(QUERY_15).unwrap()); + let compiled_30 = compile(catalog, &parse(QUERY_30).unwrap()); let bindings = data(); c.bench_function("eval-1", |b| { b.iter(|| { - let plan = plan(&catalog, &compiled_1); + let plan = plan(catalog, &compiled_1); let bindings = bindings.clone(); evaluate(black_box(plan), black_box(bindings)) }) }); c.bench_function("eval-15", |b| { b.iter(|| { - let plan = plan(&catalog, &compiled_15); + let plan = plan(catalog, &compiled_15); let bindings = bindings.clone(); evaluate(black_box(plan), black_box(bindings)) }) }); c.bench_function("eval-30", |b| { b.iter(|| { - let plan = plan(&catalog, &compiled_30); + let plan = plan(catalog, &compiled_30); let bindings = bindings.clone(); evaluate(black_box(plan), black_box(bindings)) }) diff --git a/partiql/benches/bench_join.rs b/partiql/benches/bench_join.rs index 30faad66..3f9873a7 100644 --- a/partiql/benches/bench_join.rs +++ b/partiql/benches/bench_join.rs @@ -1,7 +1,8 @@ +use std::ops::Deref; use std::time::Duration; use criterion::{black_box, criterion_group, criterion_main, Criterion}; -use partiql_catalog::catalog::{Catalog, PartiqlCatalog}; +use partiql_catalog::catalog::{Catalog, PartiqlCatalog, PartiqlSharedCatalog, SharedCatalog}; use partiql_catalog::context::SystemContext; use partiql_eval::env::basic::MapBindings; use partiql_eval::eval::{BasicContext, EvalPlan}; @@ -11,6 +12,14 @@ use partiql_logical_planner::LogicalPlanner; use partiql_parser::{Parser, ParserResult}; use partiql_value::{tuple, Bag, DateTime, Value}; + +use once_cell::sync::Lazy; +pub(crate) static SHARED_CATALOG: Lazy = Lazy::new(init_shared_catalog); + +fn init_shared_catalog() -> PartiqlSharedCatalog { + PartiqlCatalog::default().to_shared_catalog() +} + fn tables() -> MapBindings { let mut txt = ["foo", "bar", "baz", "qux", "etc"].into_iter().cycle(); let mut names = ["bob", "fido", "foo"].into_iter().cycle(); @@ -34,12 +43,15 @@ fn parse(text: &str) -> ParserResult { Parser::default().parse(text) } #[inline] -fn compile(catalog: &dyn Catalog, parsed: &partiql_parser::Parsed) -> LogicalPlan { +fn compile( + catalog: &dyn SharedCatalog, + parsed: &partiql_parser::Parsed, +) -> LogicalPlan { let planner = LogicalPlanner::new(catalog); planner.lower(parsed).expect("Expect no lower error") } #[inline] -fn plan(catalog: &dyn Catalog, logical: &LogicalPlan) -> EvalPlan { +fn plan(catalog: &dyn SharedCatalog, logical: &LogicalPlan) -> EvalPlan { EvaluatorPlanner::new(EvaluationMode::Permissive, catalog) .compile(logical) .expect("Expect no plan error") @@ -58,24 +70,24 @@ pub(crate) fn evaluate(eval: EvalPlan, bindings: MapBindings) -> Value { } fn bench_join(c: &mut Criterion) { - let catalog = PartiqlCatalog::default(); + let catalog: &PartiqlSharedCatalog = SHARED_CATALOG.deref(); let bindings = tables(); let query = "SELECT * FROM table1, table2"; - let compiled = compile(&catalog, &parse(query).unwrap()); + let compiled = compile(catalog, &parse(query).unwrap()); c.bench_function("cartesian join", |b| { b.iter(|| { - let plan = plan(&catalog, &compiled); + let plan = plan(catalog, &compiled); let bindings = bindings.clone(); evaluate(black_box(plan), black_box(bindings)) }) }); let query = "SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.id"; - let compiled = compile(&catalog, &parse(query).unwrap()); + let compiled = compile(catalog, &parse(query).unwrap()); c.bench_function("inner equi join", |b| { b.iter(|| { - let plan = plan(&catalog, &compiled); + let plan = plan(catalog, &compiled); let bindings = bindings.clone(); evaluate(black_box(plan), black_box(bindings)) }) diff --git a/partiql/src/lib.rs b/partiql/src/lib.rs index 269afe2e..28822d97 100644 --- a/partiql/src/lib.rs +++ b/partiql/src/lib.rs @@ -6,7 +6,7 @@ mod subquery_tests; #[cfg(test)] mod tests { use partiql_ast_passes::error::AstTransformationError; - use partiql_catalog::catalog::{Catalog, PartiqlCatalog}; + use partiql_catalog::catalog::{PartiqlCatalog, SharedCatalog}; use partiql_catalog::context::SystemContext; use partiql_eval as eval; use partiql_eval::env::basic::MapBindings; @@ -63,7 +63,7 @@ mod tests { #[track_caller] #[inline] fn lower( - catalog: &dyn Catalog, + catalog: &dyn SharedCatalog, parsed: &Parsed<'_>, ) -> Result, AstTransformationError> { let planner = partiql_logical_planner::LogicalPlanner::new(catalog); @@ -74,7 +74,7 @@ mod tests { #[inline] fn compile( mode: EvaluationMode, - catalog: &dyn Catalog, + catalog: &dyn SharedCatalog, logical: logical::LogicalPlan, ) -> Result { let mut planner = eval::plan::EvaluatorPlanner::new(mode, catalog); @@ -94,7 +94,7 @@ mod tests { #[track_caller] #[inline] fn eval(statement: &str, mode: EvaluationMode) -> Result> { - let catalog = PartiqlCatalog::default(); + let catalog = PartiqlCatalog::default().to_shared_catalog(); let parsed = parse(statement)?; let lowered = lower(&catalog, &parsed)?; diff --git a/partiql/src/subquery_tests.rs b/partiql/src/subquery_tests.rs index fa4ca630..7b6fd279 100644 --- a/partiql/src/subquery_tests.rs +++ b/partiql/src/subquery_tests.rs @@ -3,7 +3,7 @@ #[cfg(test)] mod tests { - use partiql_catalog::catalog::{Catalog, PartiqlCatalog}; + use partiql_catalog::catalog::{PartiqlCatalog, SharedCatalog}; use partiql_catalog::context::SystemContext; use partiql_eval::env::basic::MapBindings; use partiql_eval::error::EvalErr; @@ -16,7 +16,7 @@ mod tests { #[track_caller] #[inline] pub(crate) fn evaluate( - catalog: &dyn Catalog, + catalog: &dyn SharedCatalog, logical: &LogicalPlan, bindings: MapBindings, ctx_vals: &[(String, &(dyn Any))], @@ -88,7 +88,7 @@ mod tests { let sink_op_id = plan.add_operator(partiql_logical::BindingsOp::Sink); plan.add_flow(project_value_op_id, sink_op_id); - let catalog = PartiqlCatalog::default(); + let catalog = PartiqlCatalog::default().to_shared_catalog(); let bindings = MapBindings::default(); let res = evaluate(&catalog, &plan, bindings, &[]).expect("should eval correctly"); dbg!(&res); @@ -145,7 +145,7 @@ mod tests { let sink_op_id = plan.add_operator(partiql_logical::BindingsOp::Sink); plan.add_flow(project_value_op_id, sink_op_id); - let catalog = PartiqlCatalog::default(); + let catalog = PartiqlCatalog::default().to_shared_catalog(); let mut bindings = MapBindings::default(); bindings.insert( "foo", diff --git a/partiql/tests/common.rs b/partiql/tests/common.rs index 4ce2e53f..dc859ee7 100644 --- a/partiql/tests/common.rs +++ b/partiql/tests/common.rs @@ -1,5 +1,5 @@ use partiql_ast_passes::error::AstTransformationError; -use partiql_catalog::catalog::{Catalog, PartiqlCatalog}; +use partiql_catalog::catalog::{PartiqlCatalog, SharedCatalog}; use partiql_catalog::context::SystemContext; use partiql_catalog::extension::ExtensionResultError; use partiql_eval as eval; @@ -76,7 +76,7 @@ pub fn parse(statement: &str) -> ParserResult<'_> { #[track_caller] #[inline] pub fn lower( - catalog: &dyn Catalog, + catalog: &dyn SharedCatalog, parsed: &Parsed<'_>, ) -> Result, AstTransformationError> { let planner = partiql_logical_planner::LogicalPlanner::new(catalog); @@ -88,7 +88,7 @@ pub fn lower( #[inline] pub fn compile( mode: EvaluationMode, - catalog: &dyn Catalog, + catalog: &dyn SharedCatalog, logical: logical::LogicalPlan, ) -> Result { let mut planner = eval::plan::EvaluatorPlanner::new(mode, catalog); @@ -111,7 +111,7 @@ pub fn evaluate(plan: EvalPlan, bindings: MapBindings) -> EvalResult { #[inline] pub fn eval_query_with_catalog<'a>( statement: &'a str, - catalog: &dyn Catalog, + catalog: &dyn SharedCatalog, mode: EvaluationMode, ) -> Result> { let parsed = parse(statement)?; @@ -125,6 +125,6 @@ pub fn eval_query_with_catalog<'a>( #[track_caller] #[inline] pub fn eval_query(statement: &str, mode: EvaluationMode) -> Result> { - let catalog = PartiqlCatalog::default(); + let catalog = PartiqlCatalog::default().to_shared_catalog(); eval_query_with_catalog(statement, &catalog, mode) } diff --git a/partiql/tests/extension_error.rs b/partiql/tests/extension_error.rs index 3fa81b7a..34a562ea 100644 --- a/partiql/tests/extension_error.rs +++ b/partiql/tests/extension_error.rs @@ -4,7 +4,7 @@ use std::borrow::Cow; use thiserror::Error; use partiql_catalog::call_defs::{CallDef, CallSpec, CallSpecArg}; -use partiql_catalog::catalog::{Catalog, PartiqlCatalog}; +use partiql_catalog::catalog::{Catalog, PartiqlCatalog, SharedCatalog}; use partiql_catalog::context::{SessionContext, SystemContext}; use partiql_catalog::extension::{Extension, ExtensionResultError}; use partiql_catalog::table_fn::{ @@ -122,7 +122,7 @@ impl Iterator for TestDataGen { #[inline] pub(crate) fn evaluate( mode: EvaluationMode, - catalog: &dyn Catalog, + catalog: &dyn SharedCatalog, logical: partiql_logical::LogicalPlan, bindings: MapBindings, ctx_vals: &[(String, &(dyn Any))], @@ -149,6 +149,7 @@ fn test_context_bad_args_permissive() -> Result<(), TestError<'static>> { let mut catalog = PartiqlCatalog::default(); let ext = UserCtxTestExtension {}; ext.load(&mut catalog).expect("extension load to succeed"); + let catalog = catalog.to_shared_catalog(); let parsed = parse(query); let lowered = lower(&catalog, &parsed.expect("parse"))?; @@ -176,6 +177,7 @@ fn test_context_bad_args_strict() -> Result<(), TestError<'static>> { let mut catalog = PartiqlCatalog::default(); let ext = UserCtxTestExtension {}; ext.load(&mut catalog).expect("extension load to succeed"); + let catalog = catalog.to_shared_catalog(); let parsed = parse(query); let lowered = lower(&catalog, &parsed.expect("parse"))?; @@ -202,6 +204,7 @@ fn test_context_runtime_permissive() -> Result<(), TestError<'static>> { let mut catalog = PartiqlCatalog::default(); let ext = UserCtxTestExtension {}; ext.load(&mut catalog).expect("extension load to succeed"); + let catalog = catalog.to_shared_catalog(); let parsed = parse(query); let lowered = lower(&catalog, &parsed.expect("parse"))?; @@ -229,6 +232,7 @@ fn test_context_runtime_strict() -> Result<(), TestError<'static>> { let mut catalog = PartiqlCatalog::default(); let ext = UserCtxTestExtension {}; ext.load(&mut catalog).expect("extension load to succeed"); + let catalog = catalog.to_shared_catalog(); let parsed = parse(query); let lowered = lower(&catalog, &parsed.expect("parse"))?; diff --git a/partiql/tests/graph.rs b/partiql/tests/graph.rs index c93a159c..80e08d16 100644 --- a/partiql/tests/graph.rs +++ b/partiql/tests/graph.rs @@ -168,7 +168,7 @@ fn snapshot_test_graph_eval(name: &'static str, contents: &'static str, query: & let bindings = tuple![("g", graph)]; let parsed = parse(query).expect("parse"); - let catalog = PartiqlCatalog::default(); + let catalog = PartiqlCatalog::default().to_shared_catalog(); let lowered = lower(&catalog, &parsed).expect("lower"); let plan = compile(EvaluationMode::Permissive, &catalog, lowered).expect("compile"); let res = evaluate(plan, bindings.into()); diff --git a/partiql/tests/ion.rs b/partiql/tests/ion.rs index 4c584805..8bbb91aa 100644 --- a/partiql/tests/ion.rs +++ b/partiql/tests/ion.rs @@ -18,6 +18,7 @@ pub fn eval(statement: &str, mode: EvaluationMode) -> Result Result Result, bindings: MapBindings, ctx_vals: &[(String, &(dyn Any))], @@ -183,6 +183,7 @@ fn test_context() -> Result<(), TestError<'static>> { let mut catalog = PartiqlCatalog::default(); let ext = UserCtxTestExtension {}; ext.load(&mut catalog).expect("extension load to succeed"); + let catalog = catalog.to_shared_catalog(); let parsed = parse(query); let lowered = lower(&catalog, &parsed.expect("parse"))?;