@@ -2,6 +2,7 @@ use partiql_ast::ast;
2
2
use std:: fmt:: Display ;
3
3
4
4
use dot_writer:: { Attributes , DotWriter , Node , NodeId , Scope , Shape } ;
5
+ use partiql_ast:: ast:: { CallArg , CustomTypeParam , CustomTypePart , Lit , Type } ;
5
6
6
7
/*
7
8
subgraph cluster_legend {
@@ -184,37 +185,82 @@ impl ToDot<ast::Expr> for AstToDot {
184
185
}
185
186
}
186
187
188
+ #[ inline]
189
+ fn lit_to_str ( ast : & Lit ) -> String {
190
+ match ast {
191
+ Lit :: Null => "NULL" . to_string ( ) ,
192
+ Lit :: Missing => "MISSING" . to_string ( ) ,
193
+ Lit :: Int8Lit ( l) => l. to_string ( ) ,
194
+ Lit :: Int16Lit ( l) => l. to_string ( ) ,
195
+ Lit :: Int32Lit ( l) => l. to_string ( ) ,
196
+ Lit :: Int64Lit ( l) => l. to_string ( ) ,
197
+ Lit :: DecimalLit ( l) => l. to_string ( ) ,
198
+ Lit :: NumericLit ( l) => l. to_string ( ) ,
199
+ Lit :: RealLit ( l) => l. to_string ( ) ,
200
+ Lit :: FloatLit ( l) => l. to_string ( ) ,
201
+ Lit :: DoubleLit ( l) => l. to_string ( ) ,
202
+ Lit :: BoolLit ( l) => ( if * l { "TRUE" } else { "FALSE" } ) . to_string ( ) ,
203
+ Lit :: IonStringLit ( l) => format ! ( "`{}`" , l) ,
204
+ Lit :: CharStringLit ( l) => format ! ( "'{}'" , l) ,
205
+ Lit :: NationalCharStringLit ( l) => format ! ( "'{}'" , l) ,
206
+ Lit :: BitStringLit ( l) => format ! ( "b'{}'" , l) ,
207
+ Lit :: HexStringLit ( l) => format ! ( "x'{}'" , l) ,
208
+ Lit :: DateTimeLit ( l) => match l {
209
+ ast:: DateTimeLit :: DateLit ( d) => format ! ( "DATE '{}'" , d) ,
210
+ ast:: DateTimeLit :: TimeLit ( t) => format ! ( "TIME '{}'" , t) ,
211
+ ast:: DateTimeLit :: TimestampLit ( ts) => format ! ( "TIMESTAMP '{}'" , ts) ,
212
+ } ,
213
+ Lit :: CollectionLit ( l) => match l {
214
+ ast:: CollectionLit :: ArrayLit ( al) => format ! ( "[{}]" , al) ,
215
+ ast:: CollectionLit :: BagLit ( bl) => format ! ( "<<{}>>" , bl) ,
216
+ } ,
217
+ Lit :: TypedLit ( val_str, ty) => {
218
+ format ! ( "{} '{}'" , type_to_str( ty) , val_str)
219
+ }
220
+ }
221
+ }
222
+
223
+ #[ inline]
224
+ fn custom_type_param_to_str ( param : & ast:: CustomTypeParam ) -> String {
225
+ match param {
226
+ CustomTypeParam :: Lit ( lit) => lit_to_str ( lit) ,
227
+ CustomTypeParam :: Type ( ty) => type_to_str ( ty) ,
228
+ }
229
+ }
230
+
231
+ #[ inline]
232
+ fn custom_type_part_to_str ( part : & ast:: CustomTypePart ) -> String {
233
+ match part {
234
+ CustomTypePart :: Name ( name) => symbol_primitive_to_label ( name) ,
235
+ CustomTypePart :: Parameterized ( name, args) => {
236
+ let name = symbol_primitive_to_label ( name) ;
237
+ let args = args
238
+ . iter ( )
239
+ . map ( custom_type_param_to_str)
240
+ . collect :: < Vec < _ > > ( )
241
+ . join ( "," ) ;
242
+ format ! ( "{}({})" , name, args)
243
+ }
244
+ }
245
+ }
246
+
247
+ #[ inline]
248
+ fn type_to_str ( ty : & ast:: Type ) -> String {
249
+ match ty {
250
+ Type :: CustomType ( cty) => cty
251
+ . parts
252
+ . iter ( )
253
+ . map ( custom_type_part_to_str)
254
+ . collect :: < Vec < _ > > ( )
255
+ . join ( " " ) ,
256
+ _ => format ! ( "{:?}" , ty) ,
257
+ }
258
+ }
259
+
187
260
impl ToDot < ast:: Lit > for AstToDot {
188
261
fn to_dot ( & mut self , out : & mut Scope , ast : & ast:: Lit ) -> Targets {
189
262
use ast:: Lit ;
190
- let lbl = match ast {
191
- Lit :: Null => "NULL" . to_string ( ) ,
192
- Lit :: Missing => "MISSING" . to_string ( ) ,
193
- Lit :: Int8Lit ( l) => l. to_string ( ) ,
194
- Lit :: Int16Lit ( l) => l. to_string ( ) ,
195
- Lit :: Int32Lit ( l) => l. to_string ( ) ,
196
- Lit :: Int64Lit ( l) => l. to_string ( ) ,
197
- Lit :: DecimalLit ( l) => l. to_string ( ) ,
198
- Lit :: NumericLit ( l) => l. to_string ( ) ,
199
- Lit :: RealLit ( l) => l. to_string ( ) ,
200
- Lit :: FloatLit ( l) => l. to_string ( ) ,
201
- Lit :: DoubleLit ( l) => l. to_string ( ) ,
202
- Lit :: BoolLit ( l) => ( if * l { "TRUE" } else { "FALSE" } ) . to_string ( ) ,
203
- Lit :: IonStringLit ( l) => format ! ( "`{}`" , l) ,
204
- Lit :: CharStringLit ( l) => format ! ( "'{}'" , l) ,
205
- Lit :: NationalCharStringLit ( l) => format ! ( "'{}'" , l) ,
206
- Lit :: BitStringLit ( l) => format ! ( "b'{}'" , l) ,
207
- Lit :: HexStringLit ( l) => format ! ( "x'{}'" , l) ,
208
- Lit :: DateTimeLit ( l) => match l {
209
- ast:: DateTimeLit :: DateLit ( d) => format ! ( "DATE '{}'" , d) ,
210
- ast:: DateTimeLit :: TimeLit ( t) => format ! ( "TIME '{}'" , t) ,
211
- ast:: DateTimeLit :: TimestampLit ( ts) => format ! ( "TIMESTAMP '{}'" , ts) ,
212
- } ,
213
- Lit :: CollectionLit ( l) => match l {
214
- ast:: CollectionLit :: ArrayLit ( al) => format ! ( "[{}]" , al) ,
215
- ast:: CollectionLit :: BagLit ( bl) => format ! ( "<<{}>>" , bl) ,
216
- } ,
217
- } ;
263
+ let lbl = lit_to_str ( ast) ;
218
264
219
265
let mut node = out. node_auto ( ) ;
220
266
node. set_label ( & lbl) . set_shape ( Shape :: Rectangle ) ;
@@ -399,34 +445,29 @@ impl ToDot<ast::ProjectItem> for AstToDot {
399
445
}
400
446
}
401
447
448
+ fn symbol_primitive_to_label ( sym : & ast:: SymbolPrimitive ) -> String {
449
+ use ast:: CaseSensitivity ;
450
+ let case = sym. case . clone ( ) . unwrap_or ( CaseSensitivity :: CaseInsensitive ) ;
451
+ match case {
452
+ CaseSensitivity :: CaseSensitive => format ! ( "'{}'" , sym. value) ,
453
+ CaseSensitivity :: CaseInsensitive => format ! ( "{}" , sym. value) ,
454
+ }
455
+ }
456
+
402
457
impl ToDot < ast:: SymbolPrimitive > for AstToDot {
403
458
fn to_dot ( & mut self , out : & mut Scope , ast : & ast:: SymbolPrimitive ) -> Targets {
404
- use ast:: CaseSensitivity ;
405
- let case = ast. case . clone ( ) . unwrap_or ( CaseSensitivity :: CaseInsensitive ) ;
406
- let lbl = match case {
407
- CaseSensitivity :: CaseSensitive => format ! ( "'{}'" , ast. value) ,
408
- CaseSensitivity :: CaseInsensitive => format ! ( "{}" , ast. value) ,
409
- } ;
459
+ let lbl = symbol_primitive_to_label ( ast) ;
410
460
let id = out. node_auto_labelled ( & lbl) . id ( ) ;
411
461
vec ! [ id]
412
462
}
413
463
}
414
464
415
465
impl ToDot < ast:: VarRef > for AstToDot {
416
466
fn to_dot ( & mut self , out : & mut Scope , ast : & ast:: VarRef ) -> Targets {
417
- use ast:: CaseSensitivity ;
418
- let case = ast
419
- . name
420
- . case
421
- . clone ( )
422
- . unwrap_or ( CaseSensitivity :: CaseInsensitive ) ;
423
- let prefix = match & ast. qualifier {
424
- ast:: ScopeQualifier :: Unqualified => "" ,
425
- ast:: ScopeQualifier :: Qualified => "@" ,
426
- } ;
427
- let lbl = match case {
428
- CaseSensitivity :: CaseSensitive => format ! ( "{}'{}'" , prefix, ast. name. value) ,
429
- CaseSensitivity :: CaseInsensitive => format ! ( "{}{}" , prefix, ast. name. value) ,
467
+ let lbl = symbol_primitive_to_label ( & ast. name ) ;
468
+ let lbl = match & ast. qualifier {
469
+ ast:: ScopeQualifier :: Unqualified => lbl,
470
+ ast:: ScopeQualifier :: Qualified => format ! ( "@{}" , lbl) ,
430
471
} ;
431
472
let id = out. node_auto_labelled ( & lbl) . id ( ) ;
432
473
@@ -532,6 +573,24 @@ impl ToDot<ast::CallArg> for AstToDot {
532
573
self . to_dot ( out, value) . edges ( out, & id, "value" ) ;
533
574
vec ! [ id]
534
575
}
576
+ CallArg :: PositionalType ( ty) => {
577
+ let mut node = out. node_auto_labelled ( & type_to_str ( ty) ) ;
578
+ node. set ( "shape" , "parallelogram" , false ) ;
579
+ vec ! [ node. id( ) ]
580
+ }
581
+ CallArg :: NamedType { name, ty } => {
582
+ let id = out. node_auto_labelled ( "Named" ) . id ( ) ;
583
+ self . to_dot ( out, name) . edges ( out, & id, "name" ) ;
584
+
585
+ let ty_target = {
586
+ let mut ty_node = out. node_auto_labelled ( & type_to_str ( ty) ) ;
587
+ ty_node. set ( "shape" , "parallelogram" , false ) ;
588
+ vec ! [ ty_node. id( ) ]
589
+ } ;
590
+ ty_target. edges ( out, & id, "type" ) ;
591
+
592
+ vec ! [ id]
593
+ }
535
594
}
536
595
}
537
596
}
0 commit comments