Skip to content

Commit 57b5f72

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

File tree

27 files changed

+119
-71
lines changed

27 files changed

+119
-71
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: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use partiql_logical as logical;
77
use partiql_parser::{Parsed, ParserError, ParserResult};
88
use partiql_value::DateTime;
99

10-
use partiql_catalog::catalog::{Catalog, PartiqlCatalog};
10+
use partiql_catalog::catalog::{PartiqlCatalog, SharedCatalog};
1111
use partiql_catalog::context::SystemContext;
1212
use thiserror::Error;
1313

@@ -52,7 +52,7 @@ pub(crate) fn parse(statement: &str) -> ParserResult {
5252
#[track_caller]
5353
#[inline]
5454
pub(crate) fn lower(
55-
catalog: &dyn Catalog,
55+
catalog: &dyn SharedCatalog,
5656
parsed: &Parsed<'_>,
5757
) -> Result<logical::LogicalPlan<logical::BindingsOp>, AstTransformationError> {
5858
let planner = partiql_logical_planner::LogicalPlanner::new(catalog);
@@ -63,7 +63,7 @@ pub(crate) fn lower(
6363
#[inline]
6464
pub(crate) fn compile(
6565
mode: EvaluationMode,
66-
catalog: &dyn Catalog,
66+
catalog: &dyn SharedCatalog,
6767
logical: logical::LogicalPlan<logical::BindingsOp>,
6868
) -> Result<EvalPlan, PlanErr> {
6969
let mut planner = eval::plan::EvaluatorPlanner::new(mode.into(), catalog);
@@ -103,7 +103,7 @@ pub(crate) fn pass_syntax(statement: &str) -> Parsed {
103103
#[inline]
104104
#[allow(dead_code)]
105105
pub(crate) fn fail_semantics(statement: &str) {
106-
let catalog = PartiqlCatalog::default();
106+
let catalog = PartiqlCatalog::default().to_shared_catalog();
107107
if let Ok(parsed) = parse(statement) {
108108
let lowered = lower(&catalog, &parsed);
109109

@@ -118,7 +118,7 @@ pub(crate) fn fail_semantics(statement: &str) {
118118
#[inline]
119119
#[allow(dead_code)]
120120
pub(crate) fn pass_semantics(statement: &str) {
121-
let catalog = PartiqlCatalog::default();
121+
let catalog = PartiqlCatalog::default().to_shared_catalog();
122122
let parsed = pass_syntax(statement);
123123
let lowered = lower(&catalog, &parsed);
124124
assert!(
@@ -171,7 +171,7 @@ pub(crate) fn eval<'a>(
171171
mode: EvaluationMode,
172172
env: &Option<TestValue>,
173173
) -> Result<Evaluated, TestError<'a>> {
174-
let catalog = PartiqlCatalog::default();
174+
let catalog = PartiqlCatalog::default().to_shared_catalog();
175175

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

partiql-eval/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ mod tests {
3131
use partiql_value::{bag, list, tuple, Bag, BindingsName, DateTime, List, Tuple, Value};
3232

3333
fn evaluate(logical: LogicalPlan<BindingsOp>, bindings: MapBindings<Value>) -> Value {
34-
let catalog = PartiqlCatalog::default();
34+
let catalog = PartiqlCatalog::default().to_shared_catalog();
3535
let mut planner = plan::EvaluatorPlanner::new(EvaluationMode::Permissive, &catalog);
3636
let plan = planner.compile(&logical).expect("Expect no plan error");
3737
let sys = SystemContext {

0 commit comments

Comments
 (0)