Skip to content
This repository was archived by the owner on Jan 7, 2025. It is now read-only.

Commit 41192d4

Browse files
authored
feat: move data and value conversion from ExplainData to From (#137)
Move `value_to_data` and `data_to_value` to `From<&Value>` and `From<DataType>`
1 parent bbcc22d commit 41192d4

File tree

2 files changed

+27
-33
lines changed

2 files changed

+27
-33
lines changed

optd-datafusion-repr/src/plan_nodes.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use std::sync::Arc;
1818
use arrow_schema::DataType;
1919
use optd_core::{
2020
cascades::{CascadesOptimizer, GroupId},
21-
rel_node::{RelNode, RelNodeMeta, RelNodeMetaMap, RelNodeRef, RelNodeTyp, Value},
21+
rel_node::{RelNode, RelNodeMeta, RelNodeMetaMap, RelNodeRef, RelNodeTyp},
2222
};
2323

2424
pub use agg::{LogicalAgg, PhysicalAgg};
@@ -209,15 +209,13 @@ pub trait OptRelNode: 'static + Clone {
209209
}
210210

211211
/// Plan nodes that are defined through `define_plan_node` macro with data
212-
/// field should implement this trait. Since data is stored as `Value` in
213-
/// `RelNode`, we need to now how to convert between `Value` and the actual
214-
/// data type.
212+
/// field should implement this trait.
215213
///
216-
/// For reasons why `explain_data`` needs to be explicitly implemented, see
217-
/// `define_plan_node`.
214+
/// We require plan nodes to explicitly implement this instead of using `Debug`,
215+
/// because for complex data type (struct), derived debug printing
216+
/// displays struct name which should be hidden from the user. It also wraps
217+
/// the fields in braces, unlike the rest of the fields as children.
218218
pub trait ExplainData<T>: OptRelNode {
219-
fn data_to_value(data: &T) -> Value;
220-
fn value_to_data(value: &Value) -> T;
221219
fn explain_data(data: &T) -> Vec<(&'static str, Pretty<'static>)>;
222220
}
223221

optd-datafusion-repr/src/plan_nodes/macros.rs

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,3 @@
1-
/// Plan nodes with data fields must implement `ExplainData` trait.
2-
///
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-
91
macro_rules! define_plan_node {
102
(
113
$struct_name:ident : $meta_typ:tt,
@@ -39,7 +31,7 @@ macro_rules! define_plan_node {
3931
if let Some(meta_map) = meta_map {
4032
fields = fields.with_meta(self.0.get_meta(meta_map));
4133
};
42-
define_plan_node!(@expand_data_fields self, $struct_name, fields $(, $data_name)?);
34+
define_plan_node!(@expand_data_fields self, $struct_name, fields $(, $data_typ)?);
4335

4436
pretty_xmlish::Pretty::simple_record(
4537
stringify!($struct_name),
@@ -61,7 +53,7 @@ macro_rules! define_plan_node {
6153
#[allow(unused_mut, unused)]
6254
let mut data = None;
6355
$(
64-
data = Some($struct_name::data_to_value(&$data_name));
56+
data = Some($data_name.into());
6557
)*
6658
$struct_name($meta_typ(
6759
optd_core::rel_node::RelNode {
@@ -103,9 +95,9 @@ macro_rules! define_plan_node {
10395
// Dummy branch that does nothing when data is `None`.
10496
(@expand_data_fields $self:ident, $struct_name:ident, $fields:ident) => {};
10597
// Expand explain fields with data.
106-
(@expand_data_fields $self:ident, $struct_name:ident, $fields:ident, $data_name:ident) => {
98+
(@expand_data_fields $self:ident, $struct_name:ident, $fields:ident, $data_typ:ty) => {
10799
let value = $self.0 .0.data.as_ref().unwrap();
108-
$fields.extend($struct_name::explain_data(&$struct_name::value_to_data(&value)));
100+
$fields.extend($struct_name::explain_data(&value.into()));
109101
};
110102
}
111103

@@ -141,28 +133,23 @@ mod test {
141133
#[derive(Clone, Debug)]
142134
struct PhysicalComplexDummy(PlanNode);
143135

144-
define_plan_node!(
145-
PhysicalComplexDummy: PlanNode,
146-
PhysicalScan, [
147-
{ 0, child: PlanNode }
148-
], [
149-
],
150-
complex_data: ComplexData
151-
);
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())
136+
impl From<ComplexData> for Value {
137+
fn from(data: ComplexData) -> Self {
138+
Value::Serialized(bincode::serialize(&data).unwrap().into_iter().collect())
156139
}
140+
}
157141

158-
fn value_to_data(value: &Value) -> ComplexData {
142+
impl From<&Value> for ComplexData {
143+
fn from(value: &Value) -> Self {
159144
if let Value::Serialized(serialized_data) = value {
160145
bincode::deserialize(serialized_data).unwrap()
161146
} else {
162147
unreachable!()
163148
}
164149
}
150+
}
165151

152+
impl ExplainData<ComplexData> for PhysicalComplexDummy {
166153
fn explain_data(data: &ComplexData) -> Vec<(&'static str, Pretty<'static>)> {
167154
vec![
168155
("a", data.a.to_string().into()),
@@ -171,6 +158,15 @@ mod test {
171158
}
172159
}
173160

161+
define_plan_node!(
162+
PhysicalComplexDummy: PlanNode,
163+
PhysicalScan, [
164+
{ 0, child: PlanNode }
165+
], [
166+
],
167+
complex_data: ComplexData
168+
);
169+
174170
let node = PhysicalComplexDummy::new(
175171
LogicalScan::new("a".to_string()).0,
176172
ComplexData {

0 commit comments

Comments
 (0)