1
- /// Plan nodes with data fields must implement `ExplainData` trait. An example:
1
+ /// Plan nodes with data fields must implement `ExplainData` trait.
2
2
///
3
- /// ```ignore
4
- /// #[derive(Clone, Debug)]
5
- /// struct PhysicalDummy(PlanNode);
6
- ///
7
- /// // Implement `OptRelNode` using `define_plan_node!`...
8
- ///
9
- /// impl ExplainData for PhysicalDummy {
10
- /// fn explain_data(data: &Value) -> Vec<(&'static str, Pretty<'static>)> {
11
- /// if let Value::Int32(i) = data {
12
- /// vec![("primitive_data", i.to_string().into())]
13
- /// } else {
14
- /// unreachable!()
15
- /// }
16
- /// }
17
- /// }
18
- /// ```
3
+ /// The generated `dispatch_explain` method delegates explaining data to
4
+ /// rel node implementations of `ExplainData` trait instead of just debug
5
+ /// printing it, because for complex data type (struct), derived debug printing
6
+ /// displays struct name which should be hidden from the user. It also wraps
7
+ /// the fields in braces, unlike the rest of the fields as children.
8
+
19
9
macro_rules! define_plan_node {
20
10
(
21
11
$struct_name: ident : $meta_typ: tt,
22
12
$variant: ident,
23
13
[ $( { $child_id: literal, $child_name: ident : $child_meta_typ: ty } ) ,* ] ,
24
14
[ $( { $attr_id: literal, $attr_name: ident : $attr_meta_typ: ty } ) ,* ]
25
15
$( , { $inner_name: ident : $inner_typ: ty } ) ?
26
- $( , $data_name: ident) ?
16
+ $( , $data_name: ident: $data_typ : ty ) ?
27
17
) => {
28
18
impl OptRelNode for $struct_name {
29
19
fn into_rel_node( self ) -> OptRelNodeRef {
@@ -49,7 +39,7 @@ macro_rules! define_plan_node {
49
39
if let Some ( meta_map) = meta_map {
50
40
fields = fields. with_meta( self . 0 . get_meta( meta_map) ) ;
51
41
} ;
52
- define_plan_node!( @expand_fields self , $struct_name, fields $( , $data_name) ?) ;
42
+ define_plan_node!( @expand_data_fields self , $struct_name, fields $( , $data_name) ?) ;
53
43
54
44
pretty_xmlish:: Pretty :: simple_record(
55
45
stringify!( $struct_name) ,
@@ -65,13 +55,13 @@ macro_rules! define_plan_node {
65
55
pub fn new(
66
56
$( $child_name : $child_meta_typ, ) *
67
57
$( $attr_name : $attr_meta_typ) ,*
68
- $( $data_name: Value ) ?
58
+ $( $data_name: $data_typ ) ?
69
59
$( , $inner_name : $inner_typ) ?
70
60
) -> $struct_name {
71
61
#[ allow( unused_mut, unused) ]
72
62
let mut data = None ;
73
63
$(
74
- data = Some ( $data_name) ;
64
+ data = Some ( $struct_name :: data_to_value ( & $ data_name) ) ;
75
65
) *
76
66
$struct_name( $meta_typ(
77
67
optd_core:: rel_node:: RelNode {
@@ -111,11 +101,11 @@ macro_rules! define_plan_node {
111
101
}
112
102
} ;
113
103
// Dummy branch that does nothing when data is `None`.
114
- ( @expand_fields $self: ident, $struct_name: ident, $fields: ident) => { } ;
104
+ ( @expand_data_fields $self: ident, $struct_name: ident, $fields: ident) => { } ;
115
105
// Expand explain fields with data.
116
- ( @expand_fields $self: ident, $struct_name: ident, $fields: ident, $data_name: ident) => {
117
- let data = $self. 0 . 0 . data. as_ref( ) . unwrap( ) ;
118
- $fields. extend( $struct_name:: explain_data( data ) ) ;
106
+ ( @expand_data_fields $self: ident, $struct_name: ident, $fields: ident, $data_name: ident) => {
107
+ let value = $self. 0 . 0 . data. as_ref( ) . unwrap( ) ;
108
+ $fields. extend( $struct_name:: explain_data( & $struct_name :: value_to_data ( & value ) ) ) ;
119
109
} ;
120
110
}
121
111
@@ -151,40 +141,42 @@ mod test {
151
141
#[ derive( Clone , Debug ) ]
152
142
struct PhysicalComplexDummy ( PlanNode ) ;
153
143
154
- impl ExplainData for PhysicalComplexDummy {
155
- fn explain_data ( data : & Value ) -> Vec < ( & ' static str , Pretty < ' static > ) > {
156
- if let Value :: Serialized ( serialized_data) = data {
157
- let data: ComplexData = bincode:: deserialize ( serialized_data) . unwrap ( ) ;
158
- vec ! [
159
- ( "a" , data. a. to_string( ) . into( ) ) ,
160
- ( "b" , data. b. to_string( ) . into( ) ) ,
161
- ]
162
- } else {
163
- unreachable ! ( )
164
- }
165
- }
166
- }
167
-
168
144
define_plan_node ! (
169
145
PhysicalComplexDummy : PlanNode ,
170
146
PhysicalScan , [
171
147
{ 0 , child: PlanNode }
172
148
] , [
173
149
] ,
174
- complex_data
150
+ complex_data: ComplexData
175
151
) ;
176
152
153
+ impl ExplainData < ComplexData > for PhysicalComplexDummy {
154
+ fn data_to_value ( data : & ComplexData ) -> Value {
155
+ Value :: Serialized ( bincode:: serialize ( data) . unwrap ( ) . into_iter ( ) . collect ( ) )
156
+ }
157
+
158
+ fn value_to_data ( value : & Value ) -> ComplexData {
159
+ if let Value :: Serialized ( serialized_data) = value {
160
+ bincode:: deserialize ( serialized_data) . unwrap ( )
161
+ } else {
162
+ unreachable ! ( )
163
+ }
164
+ }
165
+
166
+ fn explain_data ( data : & ComplexData ) -> Vec < ( & ' static str , Pretty < ' static > ) > {
167
+ vec ! [
168
+ ( "a" , data. a. to_string( ) . into( ) ) ,
169
+ ( "b" , data. b. to_string( ) . into( ) ) ,
170
+ ]
171
+ }
172
+ }
173
+
177
174
let node = PhysicalComplexDummy :: new (
178
175
LogicalScan :: new ( "a" . to_string ( ) ) . 0 ,
179
- Value :: Serialized (
180
- bincode:: serialize ( & ComplexData {
181
- a : 1 ,
182
- b : "a" . to_string ( ) ,
183
- } )
184
- . unwrap ( )
185
- . into_iter ( )
186
- . collect ( ) ,
187
- ) ,
176
+ ComplexData {
177
+ a : 1 ,
178
+ b : "a" . to_string ( ) ,
179
+ } ,
188
180
) ;
189
181
let pretty = node. dispatch_explain ( None ) ;
190
182
println ! ( "{}" , get_explain_str( & pretty) ) ;
0 commit comments