Skip to content

Commit 7e54311

Browse files
authored
Add serde and Display for partiql-logical and serde for partiql-value (#293)
1- Adds the remaining serde features. 2- Adds an initial Display for LogicalPlan.
1 parent 9e2dbf7 commit 7e54311

File tree

2 files changed

+50
-0
lines changed

2 files changed

+50
-0
lines changed

partiql-logical/src/lib.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
/// ```
5151
use partiql_value::{BindingsName, Value};
5252
use std::collections::HashMap;
53+
use std::fmt::{Debug, Display, Formatter};
5354

5455
#[cfg(feature = "serde")]
5556
use serde::{Deserialize, Serialize};
@@ -162,9 +163,27 @@ impl OpId {
162163
}
163164
}
164165

166+
impl<T> Display for LogicalPlan<T>
167+
where
168+
T: Default + Debug,
169+
{
170+
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
171+
let flows = self.flows();
172+
writeln!(f, "LogicalPlan")?;
173+
writeln!(f, "---")?;
174+
for (s, d, _w) in flows {
175+
let src_node = self.operator(*s).expect("Unable to get the src operator");
176+
let dst_node = self.operator(*d).expect("Unable to get the dst operator");
177+
writeln!(f, ">>> [{src_node:?}] -> [{dst_node:?}]")?;
178+
}
179+
writeln!(f)
180+
}
181+
}
182+
165183
/// Represents PartiQL binding operators; A `BindingOp` is an operator that operates on
166184
/// binding tuples as specified by [PartiQL Specification 2019](https://partiql.org/assets/PartiQL-Specification.pdf).
167185
#[derive(Debug, Clone, Default, Eq, PartialEq)]
186+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
168187
pub enum BindingsOp {
169188
Scan(Scan),
170189
Pivot(Pivot),
@@ -187,6 +206,7 @@ pub enum BindingsOp {
187206

188207
/// [`Scan`] bridges from [`ValueExpr`]s to [`BindingsOp`]s.
189208
#[derive(Debug, Clone, Eq, PartialEq)]
209+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
190210
pub struct Scan {
191211
pub expr: ValueExpr,
192212
pub as_key: String,
@@ -198,13 +218,15 @@ pub struct Scan {
198218
/// see section `6.2` of
199219
/// [PartiQL Specification — August 1, 2019](https://partiql.org/assets/PartiQL-Specification.pdf).
200220
#[derive(Debug, Clone, Eq, PartialEq)]
221+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
201222
pub struct Pivot {
202223
pub key: ValueExpr,
203224
pub value: ValueExpr,
204225
}
205226

206227
/// [`Unpivot`] bridges from [`ValueExpr`]s to [`BindingsOp`]s.
207228
#[derive(Debug, Clone, Eq, PartialEq)]
229+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
208230
pub struct Unpivot {
209231
pub expr: ValueExpr,
210232
pub as_key: String,
@@ -213,13 +235,15 @@ pub struct Unpivot {
213235

214236
/// [`Filter`] represents a filter operator, e.g. `WHERE a = 10` in `SELECT a FROM t WHERE a = 10`.
215237
#[derive(Debug, Clone, Eq, PartialEq)]
238+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
216239
pub struct Filter {
217240
pub expr: ValueExpr,
218241
}
219242

220243
/// ['Join`] represents a join operator, e.g. implicit `CROSS JOIN` specified by comma in `FROM`
221244
/// clause in `SELECT t1.a, t2.b FROM tbl1 AS t1, tbl2 AS t2`.
222245
#[derive(Debug, Clone, Eq, PartialEq)]
246+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
223247
pub struct Join {
224248
pub kind: JoinKind,
225249
pub left: Box<BindingsOp>,
@@ -229,6 +253,7 @@ pub struct Join {
229253

230254
/// Represents join types.
231255
#[derive(Debug, Clone, Eq, PartialEq)]
256+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
232257
pub enum JoinKind {
233258
Inner,
234259
Left,
@@ -239,26 +264,30 @@ pub enum JoinKind {
239264

240265
/// Represents a projection, e.g. `SELECT a` in `SELECT a FROM t`.
241266
#[derive(Debug, Clone, Eq, PartialEq)]
267+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
242268
pub struct Project {
243269
pub exprs: HashMap<String, ValueExpr>,
244270
}
245271

246272
/// Represents a value projection (SELECT VALUE) e.g. `SELECT VALUE t.a * 2` in
247273
///`SELECT VALUE t.a * 2 IN tbl AS t`.
248274
#[derive(Debug, Clone, Eq, PartialEq)]
275+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
249276
pub struct ProjectValue {
250277
pub expr: ValueExpr,
251278
}
252279

253280
/// Represents an expression query e.g. `a * 2` in `a * 2` or an expression like `2+2`.
254281
#[derive(Debug, Clone, Eq, PartialEq)]
282+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
255283
pub struct ExprQuery {
256284
pub expr: ValueExpr,
257285
}
258286

259287
/// Represents a PartiQL value expression. Evaluation of a [`ValueExpr`] leads to a PartiQL value as
260288
/// specified by [PartiQL Specification 2019](https://partiql.org/assets/PartiQL-Specification.pdf).
261289
#[derive(Debug, Clone, Eq, PartialEq)]
290+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
262291
pub enum ValueExpr {
263292
UnExpr(UnaryOp, Box<ValueExpr>),
264293
BinaryExpr(BinaryOp, Box<ValueExpr>, Box<ValueExpr>),
@@ -283,6 +312,7 @@ pub enum ValueExpr {
283312
// TODO we should replace this enum with some identifier that can be looked up in a symtab/funcregistry?
284313
/// Represents logical plan's unary operators.
285314
#[derive(Debug, Clone, Eq, PartialEq)]
315+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
286316
pub enum UnaryOp {
287317
Pos,
288318
Neg,
@@ -292,6 +322,7 @@ pub enum UnaryOp {
292322
// TODO we should replace this enum with some identifier that can be looked up in a symtab/funcregistry?
293323
/// Represents logical plan's binary operators.
294324
#[derive(Debug, Clone, Eq, PartialEq)]
325+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
295326
pub enum BinaryOp {
296327
And,
297328
Or,
@@ -315,6 +346,7 @@ pub enum BinaryOp {
315346
}
316347

317348
#[derive(Debug, Clone, Eq, PartialEq)]
349+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
318350
/// Represents a path component in a plan.
319351
pub enum PathComponent {
320352
/// E.g. `b` in `a.b`
@@ -327,6 +359,7 @@ pub enum PathComponent {
327359

328360
/// Represents a PartiQL tuple expression, e.g: `{ a.b: a.c * 2, 'count': a.c + 10}`.
329361
#[derive(Clone, Debug, Default, Eq, PartialEq)]
362+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
330363
pub struct TupleExpr {
331364
pub attrs: Vec<ValueExpr>,
332365
pub values: Vec<ValueExpr>,
@@ -341,6 +374,7 @@ impl TupleExpr {
341374

342375
/// Represents a PartiQL list expression, e.g. `[a.c * 2, 5]`.
343376
#[derive(Clone, Debug, Default, Eq, PartialEq)]
377+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
344378
pub struct ListExpr {
345379
pub elements: Vec<ValueExpr>,
346380
}
@@ -354,6 +388,7 @@ impl ListExpr {
354388

355389
/// Represents a PartiQL bag expression, e.g. `<<a.c * 2, 5>>`.
356390
#[derive(Clone, Debug, Default, Eq, PartialEq)]
391+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
357392
pub struct BagExpr {
358393
pub elements: Vec<ValueExpr>,
359394
}
@@ -367,6 +402,7 @@ impl BagExpr {
367402

368403
/// Represents a PartiQL `BETWEEN` expression, e.g. `BETWEEN 500 AND 600`.
369404
#[derive(Debug, Clone, Eq, PartialEq)]
405+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
370406
pub struct BetweenExpr {
371407
pub value: Box<ValueExpr>,
372408
pub from: Box<ValueExpr>,
@@ -375,12 +411,14 @@ pub struct BetweenExpr {
375411

376412
/// Represents a PartiQL Pattern Match expression, e.g. `'foo' LIKE 'foo'`.
377413
#[derive(Debug, Clone, Eq, PartialEq)]
414+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
378415
pub struct PatternMatchExpr {
379416
pub value: Box<ValueExpr>,
380417
pub pattern: Pattern,
381418
}
382419

383420
#[derive(Debug, Clone, Eq, PartialEq)]
421+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
384422
pub enum Pattern {
385423
Like(LikeMatch), // TODO other e.g., SIMILAR_TO, or regex match
386424
LikeNonStringNonLiteral(LikeNonStringNonLiteralMatch),
@@ -389,6 +427,7 @@ pub enum Pattern {
389427
/// Represents a LIKE expression where both the `pattern` and `escape` are string literals,
390428
/// e.g. `'foo%' ESCAPE '/'`
391429
#[derive(Debug, Clone, Eq, PartialEq)]
430+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
392431
pub struct LikeMatch {
393432
pub pattern: String,
394433
pub escape: String,
@@ -397,6 +436,7 @@ pub struct LikeMatch {
397436
/// Represents a LIKE expression where one of `pattern` and `escape` is not a string literal,
398437
/// e.g. `some_pattern ESCAPE '/'`
399438
#[derive(Debug, Clone, Eq, PartialEq)]
439+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
400440
pub struct LikeNonStringNonLiteralMatch {
401441
pub pattern: Box<ValueExpr>,
402442
pub escape: Box<ValueExpr>,
@@ -405,13 +445,15 @@ pub struct LikeNonStringNonLiteralMatch {
405445
/// Represents a sub-query expression, e.g. `SELECT v.a*2 AS u FROM t AS v` in
406446
/// `SELECT t.a, s FROM data AS t, (SELECT v.a*2 AS u FROM t AS v) AS s`
407447
#[derive(Debug, Clone, Eq, PartialEq)]
448+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
408449
pub struct SubQueryExpr {
409450
pub plan: LogicalPlan<BindingsOp>,
410451
}
411452

412453
/// Represents a PartiQL's simple case expressions,
413454
/// e.g.`CASE <expr> [ WHEN <expr> THEN <expr> ]... [ ELSE <expr> ] END`.
414455
#[derive(Debug, Clone, Eq, PartialEq)]
456+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
415457
pub struct SimpleCase {
416458
pub expr: Box<ValueExpr>,
417459
pub cases: Vec<(Box<ValueExpr>, Box<ValueExpr>)>,
@@ -421,13 +463,15 @@ pub struct SimpleCase {
421463
/// Represents a PartiQL's searched case expressions,
422464
/// e.g.`CASE [ WHEN <expr> THEN <expr> ]... [ ELSE <expr> ] END`.
423465
#[derive(Debug, Clone, Eq, PartialEq)]
466+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
424467
pub struct SearchedCase {
425468
pub cases: Vec<(Box<ValueExpr>, Box<ValueExpr>)>,
426469
pub default: Option<Box<ValueExpr>>,
427470
}
428471

429472
/// Represents an `IS` expression, e.g. `IS TRUE`.
430473
#[derive(Debug, Clone, Eq, PartialEq)]
474+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
431475
pub struct IsTypeExpr {
432476
pub not: bool,
433477
pub expr: Box<ValueExpr>,
@@ -436,6 +480,7 @@ pub struct IsTypeExpr {
436480

437481
/// Represents a PartiQL Type.
438482
#[derive(Clone, Debug, PartialEq, Eq)]
483+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
439484
pub enum Type {
440485
NullType,
441486
BooleanType,
@@ -468,6 +513,7 @@ pub enum Type {
468513

469514
/// Represents a `NULLIF` expression, e.g. `NULLIF(v1, v2)` in `SELECT NULLIF(v1, v2) FROM data`.
470515
#[derive(Debug, Clone, Eq, PartialEq)]
516+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
471517
pub struct NullIfExpr {
472518
pub lhs: Box<ValueExpr>,
473519
pub rhs: Box<ValueExpr>,
@@ -476,19 +522,22 @@ pub struct NullIfExpr {
476522
/// Represents a `COALESCE` expression, e.g.
477523
/// `COALESCE(NULL, 10)` in `SELECT COALESCE(NULL, 10) FROM data`.
478524
#[derive(Debug, Clone, Eq, PartialEq)]
525+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
479526
pub struct CoalesceExpr {
480527
pub elements: Vec<ValueExpr>,
481528
}
482529

483530
/// Represents a `CALL` expression (i.e., a function call), e.g. `LOWER("ALL CAPS")`.
484531
#[derive(Debug, Clone, Eq, PartialEq)]
532+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
485533
pub struct CallExpr {
486534
pub name: CallName,
487535
pub arguments: Vec<ValueExpr>,
488536
}
489537

490538
/// Represents a known function.
491539
#[derive(Debug, Clone, Eq, PartialEq)]
540+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
492541
pub enum CallName {
493542
Lower,
494543
Upper,

partiql-value/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ mod ion;
1919
use serde::{Deserialize, Serialize};
2020

2121
#[derive(Clone, Hash, Debug, Eq, PartialEq)]
22+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2223
pub enum BindingsName {
2324
CaseSensitive(String),
2425
CaseInsensitive(String),

0 commit comments

Comments
 (0)