Skip to content

Commit ed3a181

Browse files
committed
Add PartiqlSharedCatalog for Send+Sync catalog usage.
1 parent 2ae6c4e commit ed3a181

File tree

29 files changed

+202
-113
lines changed

29 files changed

+202
-113
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99
## [Unreleased]
1010
### Changed
1111
- Changed many internal `HashMap`s to use `rustc-hash`'s `FxHash`
12+
- *BREAKING* Refactors `Catalog` to allow `Send`+`Sync` for re-use.
1213

1314
### Added
1415

extension/partiql-extension-csv/tests/scan.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use partiql_catalog::catalog::{Catalog, PartiqlCatalog};
1+
use partiql_catalog::catalog::{PartiqlCatalog, SharedCatalog};
22
use partiql_catalog::context::SystemContext;
33
use partiql_catalog::extension::Extension;
44
use partiql_eval::env::basic::MapBindings;
@@ -19,7 +19,7 @@ pub(crate) fn parse(statement: &str) -> ParserResult<'_> {
1919
#[track_caller]
2020
#[inline]
2121
pub(crate) fn lower(
22-
catalog: &dyn Catalog,
22+
catalog: &dyn SharedCatalog,
2323
parsed: &Parsed<'_>,
2424
) -> partiql_logical::LogicalPlan<partiql_logical::BindingsOp> {
2525
let planner = partiql_logical_planner::LogicalPlanner::new(catalog);
@@ -29,7 +29,7 @@ pub(crate) fn lower(
2929
#[track_caller]
3030
#[inline]
3131
pub(crate) fn evaluate(
32-
catalog: &dyn Catalog,
32+
catalog: &dyn SharedCatalog,
3333
logical: partiql_logical::LogicalPlan<partiql_logical::BindingsOp>,
3434
bindings: MapBindings<Value>,
3535
) -> (Value, Vec<EvaluationError>) {
@@ -61,6 +61,7 @@ pub(crate) fn evaluate_with_csv_scan(
6161
let ext = CsvExtension {};
6262
ext.load(&mut catalog)
6363
.expect("ion extension load to succeed");
64+
let catalog = catalog.to_shared_catalog();
6465

6566
let parsed = parse(statement);
6667
let lowered = lower(&catalog, &parsed.expect("parse"));

extension/partiql-extension-ion-functions/tests/scan.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use partiql_catalog::catalog::{Catalog, PartiqlCatalog};
1+
use partiql_catalog::catalog::{PartiqlCatalog, SharedCatalog};
22
use partiql_catalog::context::SystemContext;
33
use partiql_catalog::extension::Extension;
44
use partiql_eval::env::basic::MapBindings;
@@ -19,7 +19,7 @@ pub(crate) fn parse(statement: &str) -> ParserResult<'_> {
1919
#[track_caller]
2020
#[inline]
2121
pub(crate) fn lower(
22-
catalog: &dyn Catalog,
22+
catalog: &dyn SharedCatalog,
2323
parsed: &Parsed<'_>,
2424
) -> partiql_logical::LogicalPlan<partiql_logical::BindingsOp> {
2525
let planner = partiql_logical_planner::LogicalPlanner::new(catalog);
@@ -29,7 +29,7 @@ pub(crate) fn lower(
2929
#[track_caller]
3030
#[inline]
3131
pub(crate) fn evaluate(
32-
catalog: &dyn Catalog,
32+
catalog: &dyn SharedCatalog,
3333
logical: partiql_logical::LogicalPlan<partiql_logical::BindingsOp>,
3434
bindings: MapBindings<Value>,
3535
) -> (Value, Vec<EvaluationError>) {
@@ -61,6 +61,7 @@ pub(crate) fn evaluate_with_ion_scan(
6161
let ext = IonExtension {};
6262
ext.load(&mut catalog)
6363
.expect("ion extension load to succeed");
64+
let catalog = catalog.to_shared_catalog();
6465

6566
let parsed = parse(statement);
6667
let lowered = lower(&catalog, &parsed.expect("parse"));

partiql-ast-passes/src/name_resolver.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use indexmap::{IndexMap, IndexSet};
44
use partiql_ast::ast;
55
use partiql_ast::ast::{GraphPattern, GroupByExpr, GroupKey};
66
use partiql_ast::visit::{Traverse, Visit, Visitor};
7-
use partiql_catalog::catalog::Catalog;
7+
use partiql_catalog::catalog::SharedCatalog;
88
use partiql_common::node::NodeId;
99
use std::sync::atomic::{AtomicU32, Ordering};
1010

@@ -102,11 +102,11 @@ pub struct NameResolver<'c> {
102102

103103
// errors that occur during name resolution
104104
errors: Vec<AstTransformError>,
105-
catalog: &'c dyn Catalog,
105+
catalog: &'c dyn SharedCatalog,
106106
}
107107

108108
impl<'c> NameResolver<'c> {
109-
pub fn new(catalog: &'c dyn Catalog) -> Self {
109+
pub fn new(catalog: &'c dyn SharedCatalog) -> Self {
110110
NameResolver {
111111
// environment stack tracking
112112
id_path_to_root: Default::default(),

partiql-catalog/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,5 @@ ordered-float = "5"
3131
itertools = "0.14"
3232
unicase = "2.7"
3333
rustc-hash = "2"
34-
34+
delegate = "0.13"
3535
dyn-clone = "1"

partiql-catalog/src/catalog.rs

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::call_defs::ScalarFnCallSpecs;
22
use crate::scalar_fn::ScalarFunction;
33
use crate::table_fn::TableFunction;
4+
use delegate::delegate;
45
use partiql_common::catalog::{CatalogId, EntryId, ObjectId};
56
use partiql_types::PartiqlShape;
67
use rustc_hash::FxHashMap;
@@ -42,19 +43,22 @@ pub enum CatalogErrorKind {
4243
Unknown,
4344
}
4445

45-
pub trait Catalog: Debug {
46+
pub trait MutableCatalog: Debug {
4647
fn add_table_function(&mut self, info: TableFunction) -> Result<ObjectId, CatalogError>;
4748
fn add_scalar_function(&mut self, info: ScalarFunction) -> Result<ObjectId, CatalogError>;
48-
4949
fn add_type_entry(&mut self, entry: TypeEnvEntry<'_>) -> Result<ObjectId, CatalogError>;
50+
}
5051

52+
pub trait ReadOnlyCatalog: Debug {
5153
fn get_function(&self, name: &str) -> Option<FunctionEntry<'_>>;
52-
5354
fn get_function_by_id(&self, id: ObjectId) -> Option<FunctionEntry<'_>>;
54-
5555
fn resolve_type(&self, name: &str) -> Option<TypeEntry>;
5656
}
5757

58+
pub trait SharedCatalog: ReadOnlyCatalog + Send + Sync {}
59+
60+
pub trait Catalog: MutableCatalog + ReadOnlyCatalog {}
61+
5862
#[derive(Debug)]
5963
pub struct TypeEnvEntry<'a> {
6064
name: UniCase<String>,
@@ -123,6 +127,9 @@ pub struct PartiqlCatalog {
123127
id: CatalogId,
124128
}
125129

130+
#[derive(Debug)]
131+
pub struct PartiqlSharedCatalog(PartiqlCatalog);
132+
126133
impl Default for PartiqlCatalog {
127134
fn default() -> Self {
128135
PartiqlCatalog {
@@ -133,9 +140,15 @@ impl Default for PartiqlCatalog {
133140
}
134141
}
135142

136-
impl PartiqlCatalog {}
143+
impl PartiqlCatalog {
144+
pub fn to_shared_catalog(self) -> PartiqlSharedCatalog {
145+
PartiqlSharedCatalog(self)
146+
}
147+
}
148+
149+
impl Catalog for PartiqlCatalog {}
137150

138-
impl Catalog for PartiqlCatalog {
151+
impl MutableCatalog for PartiqlCatalog {
139152
fn add_table_function(&mut self, info: TableFunction) -> Result<ObjectId, CatalogError> {
140153
let call_def = info.call_def();
141154
let names = call_def.names.clone();
@@ -180,7 +193,9 @@ impl Catalog for PartiqlCatalog {
180193
Err(e) => Err(e),
181194
}
182195
}
196+
}
183197

198+
impl ReadOnlyCatalog for PartiqlCatalog {
184199
fn get_function(&self, name: &str) -> Option<FunctionEntry<'_>> {
185200
self.functions
186201
.find_by_name(name)
@@ -202,6 +217,18 @@ impl Catalog for PartiqlCatalog {
202217
}
203218
}
204219

220+
impl ReadOnlyCatalog for PartiqlSharedCatalog {
221+
delegate! {
222+
to self.0 {
223+
fn get_function(&self, name: &str) -> Option<FunctionEntry<'_>>;
224+
fn get_function_by_id(&self, id: ObjectId) -> Option<FunctionEntry<'_>>;
225+
fn resolve_type(&self, name: &str) -> Option<TypeEntry>;
226+
}
227+
}
228+
}
229+
230+
impl SharedCatalog for PartiqlSharedCatalog {}
231+
205232
impl PartiqlCatalog {
206233
fn to_function_entry<'a>(
207234
&'a self,

partiql-catalog/src/scalar_fn.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use std::fmt::{Debug, Formatter};
1111
pub type ScalarFnExprResultValue<'a> = Cow<'a, Value>;
1212
pub type ScalarFnExprResult<'a> = Result<ScalarFnExprResultValue<'a>, ExtensionResultError>;
1313

14-
pub trait ScalarFnExpr: DynClone + Debug {
14+
pub trait ScalarFnExpr: DynClone + Debug + Send + Sync {
1515
fn evaluate<'c>(
1616
&self,
1717
args: &[Cow<'_, Value>],

partiql-catalog/src/table_fn.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ pub trait BaseTableExpr: Debug {
1717
) -> BaseTableExprResult<'c>;
1818
}
1919

20-
pub trait BaseTableFunctionInfo: Debug {
20+
pub trait BaseTableFunctionInfo: Debug + Send + Sync {
2121
fn call_def(&self) -> &CallDef;
2222
fn plan_eval(&self) -> Box<dyn BaseTableExpr>;
2323
}

partiql-conformance-tests/tests/mod.rs

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,27 @@
11
use partiql_ast_passes::error::AstTransformationError;
22
use partiql_eval as eval;
3+
use std::ops::Deref;
34

45
use partiql_eval::error::{EvalErr, PlanErr};
56
use partiql_eval::eval::{BasicContext, EvalContext, EvalPlan, EvalResult, Evaluated};
67
use partiql_logical as logical;
78
use partiql_parser::{Parsed, ParserError, ParserResult};
89
use partiql_value::DateTime;
910

10-
use partiql_catalog::catalog::{Catalog, PartiqlCatalog};
11+
use partiql_catalog::catalog::{PartiqlCatalog, PartiqlSharedCatalog, SharedCatalog};
1112
use partiql_catalog::context::SystemContext;
1213
use thiserror::Error;
1314

1415
mod test_value;
1516
pub(crate) use test_value::TestValue;
1617

18+
use once_cell::sync::Lazy;
19+
pub(crate) static SHARED_CATALOG: Lazy<PartiqlSharedCatalog> = Lazy::new(init_shared_catalog);
20+
21+
fn init_shared_catalog() -> PartiqlSharedCatalog {
22+
PartiqlCatalog::default().to_shared_catalog()
23+
}
24+
1725
#[derive(Debug, Copy, Clone)]
1826
#[allow(dead_code)]
1927
pub(crate) enum EvaluationMode {
@@ -52,7 +60,7 @@ pub(crate) fn parse(statement: &str) -> ParserResult {
5260
#[track_caller]
5361
#[inline]
5462
pub(crate) fn lower(
55-
catalog: &dyn Catalog,
63+
catalog: &dyn SharedCatalog,
5664
parsed: &Parsed<'_>,
5765
) -> Result<logical::LogicalPlan<logical::BindingsOp>, AstTransformationError> {
5866
let planner = partiql_logical_planner::LogicalPlanner::new(catalog);
@@ -63,7 +71,7 @@ pub(crate) fn lower(
6371
#[inline]
6472
pub(crate) fn compile(
6573
mode: EvaluationMode,
66-
catalog: &dyn Catalog,
74+
catalog: &dyn SharedCatalog,
6775
logical: logical::LogicalPlan<logical::BindingsOp>,
6876
) -> Result<EvalPlan, PlanErr> {
6977
let mut planner = eval::plan::EvaluatorPlanner::new(mode.into(), catalog);
@@ -103,9 +111,9 @@ pub(crate) fn pass_syntax(statement: &str) -> Parsed {
103111
#[inline]
104112
#[allow(dead_code)]
105113
pub(crate) fn fail_semantics(statement: &str) {
106-
let catalog = PartiqlCatalog::default();
114+
let catalog: &PartiqlSharedCatalog = SHARED_CATALOG.deref();
107115
if let Ok(parsed) = parse(statement) {
108-
let lowered = lower(&catalog, &parsed);
116+
let lowered = lower(catalog, &parsed);
109117

110118
assert!(
111119
lowered.is_err(),
@@ -118,9 +126,9 @@ pub(crate) fn fail_semantics(statement: &str) {
118126
#[inline]
119127
#[allow(dead_code)]
120128
pub(crate) fn pass_semantics(statement: &str) {
121-
let catalog = PartiqlCatalog::default();
129+
let catalog: &PartiqlSharedCatalog = SHARED_CATALOG.deref();
122130
let parsed = pass_syntax(statement);
123-
let lowered = lower(&catalog, &parsed);
131+
let lowered = lower(catalog, &parsed);
124132
assert!(
125133
lowered.is_ok(),
126134
"When semantically verifying `{statement}`, expected `Ok(_)`, but was `{lowered:#?}`"
@@ -171,17 +179,17 @@ pub(crate) fn eval<'a>(
171179
mode: EvaluationMode,
172180
env: &Option<TestValue>,
173181
) -> Result<Evaluated, TestError<'a>> {
174-
let catalog = PartiqlCatalog::default();
182+
let catalog: &PartiqlSharedCatalog = SHARED_CATALOG.deref();
175183

176184
let parsed = parse(statement)?;
177-
let lowered = lower(&catalog, &parsed)?;
185+
let lowered = lower(catalog, &parsed)?;
178186

179187
let bindings = env.as_ref().map(|e| (&e.value).into()).unwrap_or_default();
180188
let sys = SystemContext {
181189
now: DateTime::from_system_now_utc(),
182190
};
183191
let ctx = BasicContext::new(bindings, sys);
184-
let plan = compile(mode, &catalog, lowered)?;
192+
let plan = compile(mode, catalog, lowered)?;
185193

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

partiql-eval/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ rustc-hash = "2"
4444
delegate = "0.13"
4545

4646
serde = { version = "1", features = ["derive"], optional = true }
47+
once_cell = "1"
4748

4849
[dev-dependencies]
4950
criterion = "0.5"

0 commit comments

Comments
 (0)