5050/// ```
5151use partiql_value:: { BindingsName , Value } ;
5252use std:: collections:: HashMap ;
53+ use std:: fmt:: { Debug , Display , Formatter } ;
5354
5455#[ cfg( feature = "serde" ) ]
5556use 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 ) ) ]
168187pub 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 ) ) ]
190210pub 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 ) ) ]
201222pub 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 ) ) ]
208230pub 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 ) ) ]
216239pub 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 ) ) ]
223247pub 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 ) ) ]
232257pub 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 ) ) ]
242268pub 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 ) ) ]
249276pub 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 ) ) ]
255283pub 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 ) ) ]
262291pub 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 ) ) ]
286316pub 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 ) ) ]
295326pub 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.
319351pub 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 ) ) ]
330363pub 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 ) ) ]
344378pub 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 ) ) ]
357392pub 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 ) ) ]
370406pub 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 ) ) ]
378415pub 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 ) ) ]
384422pub 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 ) ) ]
392431pub 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 ) ) ]
400440pub 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 ) ) ]
408449pub 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 ) ) ]
415457pub 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 ) ) ]
424467pub 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 ) ) ]
431475pub 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 ) ) ]
439484pub 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 ) ) ]
471517pub 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 ) ) ]
479526pub 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 ) ) ]
485533pub 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 ) ) ]
492541pub enum CallName {
493542 Lower ,
494543 Upper ,
0 commit comments