Skip to content

Commit a4d41d6

Browse files
authored
Support LogicalPlan Debug differently than Display (#11774)
* Derive Debug for logical plan nodes * Improve LogicalPlan debug printing * Fix tests * Fix tests * Fix tests
1 parent f4e519f commit a4d41d6

File tree

30 files changed

+211
-186
lines changed

30 files changed

+211
-186
lines changed

benchmarks/src/tpch/run.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,12 +205,12 @@ impl RunOpt {
205205
let (state, plan) = plan.into_parts();
206206

207207
if debug {
208-
println!("=== Logical plan ===\n{plan:?}\n");
208+
println!("=== Logical plan ===\n{plan}\n");
209209
}
210210

211211
let plan = state.optimize(&plan)?;
212212
if debug {
213-
println!("=== Optimized logical plan ===\n{plan:?}\n");
213+
println!("=== Optimized logical plan ===\n{plan}\n");
214214
}
215215
let physical_plan = state.create_physical_plan(&plan).await?;
216216
if debug {

datafusion/core/src/dataframe/mod.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2553,7 +2553,7 @@ mod tests {
25532553
\n TableScan: a\
25542554
\n Projection: b.c1, b.c2\
25552555
\n TableScan: b";
2556-
assert_eq!(expected_plan, format!("{:?}", join.logical_plan()));
2556+
assert_eq!(expected_plan, format!("{}", join.logical_plan()));
25572557

25582558
Ok(())
25592559
}
@@ -2572,7 +2572,7 @@ mod tests {
25722572
let expected_plan = "CrossJoin:\
25732573
\n TableScan: a projection=[c1], full_filters=[Boolean(NULL)]\
25742574
\n TableScan: b projection=[c1]";
2575-
assert_eq!(expected_plan, format!("{:?}", join.into_optimized_plan()?));
2575+
assert_eq!(expected_plan, format!("{}", join.into_optimized_plan()?));
25762576

25772577
// JOIN ON expression must be boolean type
25782578
let join = left.join_on(right, JoinType::Inner, Some(lit("TRUE")))?;
@@ -2914,7 +2914,7 @@ mod tests {
29142914
\n Inner Join: t1.c1 = t2.c1\
29152915
\n TableScan: t1\
29162916
\n TableScan: t2",
2917-
format!("{:?}", df_with_column.logical_plan())
2917+
format!("{}", df_with_column.logical_plan())
29182918
);
29192919

29202920
assert_eq!(
@@ -2927,7 +2927,7 @@ mod tests {
29272927
\n TableScan: aggregate_test_100 projection=[c1]\
29282928
\n SubqueryAlias: t2\
29292929
\n TableScan: aggregate_test_100 projection=[c1]",
2930-
format!("{:?}", df_with_column.clone().into_optimized_plan()?)
2930+
format!("{}", df_with_column.clone().into_optimized_plan()?)
29312931
);
29322932

29332933
let df_results = df_with_column.collect().await?;
@@ -3109,7 +3109,7 @@ mod tests {
31093109
\n Inner Join: t1.c1 = t2.c1\
31103110
\n TableScan: t1\
31113111
\n TableScan: t2",
3112-
format!("{:?}", df_renamed.logical_plan())
3112+
format!("{}", df_renamed.logical_plan())
31133113
);
31143114

31153115
assert_eq!("\
@@ -3121,7 +3121,7 @@ mod tests {
31213121
\n TableScan: aggregate_test_100 projection=[c1, c2, c3]\
31223122
\n SubqueryAlias: t2\
31233123
\n TableScan: aggregate_test_100 projection=[c1, c2, c3]",
3124-
format!("{:?}", df_renamed.clone().into_optimized_plan()?)
3124+
format!("{}", df_renamed.clone().into_optimized_plan()?)
31253125
);
31263126

31273127
let df_results = df_renamed.collect().await?;
@@ -3306,7 +3306,7 @@ mod tests {
33063306

33073307
assert_eq!(
33083308
"TableScan: ?table? projection=[c2, c3, sum]",
3309-
format!("{:?}", cached_df.clone().into_optimized_plan()?)
3309+
format!("{}", cached_df.clone().into_optimized_plan()?)
33103310
);
33113311

33123312
let df_results = df.collect().await?;

datafusion/core/tests/custom_sources_cases/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ async fn custom_source_dataframe() -> Result<()> {
246246
}
247247

248248
let expected = format!("TableScan: {UNNAMED_TABLE} projection=[c2]");
249-
assert_eq!(format!("{optimized_plan:?}"), expected);
249+
assert_eq!(format!("{optimized_plan}"), expected);
250250

251251
let physical_plan = state.create_physical_plan(&optimized_plan).await?;
252252

datafusion/core/tests/expr_api/simplification.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ fn get_optimized_plan_formatted(plan: LogicalPlan, date_time: &DateTime<Utc>) ->
119119
let optimizer = Optimizer::with_rules(vec![Arc::new(SimplifyExpressions::new())]);
120120
let optimized_plan = optimizer.optimize(plan, &config, observe).unwrap();
121121

122-
format!("{optimized_plan:?}")
122+
format!("{optimized_plan}")
123123
}
124124

125125
// ------------------------------

datafusion/core/tests/optimizer_integration.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,13 @@ fn timestamp_nano_ts_utc_predicates() {
8181
let sql = "SELECT col_int32
8282
FROM test
8383
WHERE col_ts_nano_utc < (now() - interval '1 hour')";
84-
let plan = test_sql(sql).unwrap();
8584
// a scan should have the now()... predicate folded to a single
8685
// constant and compared to the column without a cast so it can be
8786
// pushed down / pruned
8887
let expected =
8988
"Projection: test.col_int32\n Filter: test.col_ts_nano_utc < TimestampNanosecond(1666612093000000000, Some(\"+00:00\"))\
9089
\n TableScan: test projection=[col_int32, col_ts_nano_utc]";
91-
assert_eq!(expected, format!("{plan:?}"));
90+
quick_test(sql, expected);
9291
}
9392

9493
#[test]
@@ -117,7 +116,7 @@ fn concat_ws_literals() -> Result<()> {
117116

118117
fn quick_test(sql: &str, expected_plan: &str) {
119118
let plan = test_sql(sql).unwrap();
120-
assert_eq!(expected_plan, format!("{:?}", plan));
119+
assert_eq!(expected_plan, format!("{}", plan));
121120
}
122121

123122
fn test_sql(sql: &str) -> Result<LogicalPlan> {

datafusion/core/tests/sql/explain_analyze.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ async fn csv_explain_plans() {
253253

254254
// Optimized logical plan
255255
let state = ctx.state();
256-
let msg = format!("Optimizing logical plan for '{sql}': {plan:?}");
256+
let msg = format!("Optimizing logical plan for '{sql}': {plan}");
257257
let plan = state.optimize(plan).expect(&msg);
258258
let optimized_logical_schema = plan.schema();
259259
// Both schema has to be the same
@@ -327,7 +327,7 @@ async fn csv_explain_plans() {
327327

328328
// Physical plan
329329
// Create plan
330-
let msg = format!("Creating physical plan for '{sql}': {plan:?}");
330+
let msg = format!("Creating physical plan for '{sql}': {plan}");
331331
let plan = state.create_physical_plan(&plan).await.expect(&msg);
332332
//
333333
// Execute plan
@@ -548,7 +548,7 @@ async fn csv_explain_verbose_plans() {
548548

549549
// Physical plan
550550
// Create plan
551-
let msg = format!("Creating physical plan for '{sql}': {plan:?}");
551+
let msg = format!("Creating physical plan for '{sql}': {plan}");
552552
let plan = state.create_physical_plan(&plan).await.expect(&msg);
553553
//
554554
// Execute plan

datafusion/core/tests/user_defined/user_defined_aggregates.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ async fn test_parameterized_aggregate_udf() -> Result<()> {
413413
.build()?;
414414

415415
assert_eq!(
416-
format!("{plan:?}"),
416+
format!("{plan}"),
417417
"Aggregate: groupBy=[[t.text]], aggr=[[geo_mean(t.text) AS a, geo_mean(t.text) AS b]]\n TableScan: t projection=[text]"
418418
);
419419

datafusion/core/tests/user_defined/user_defined_scalar_functions.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ async fn scalar_udf() -> Result<()> {
139139
.build()?;
140140

141141
assert_eq!(
142-
format!("{plan:?}"),
142+
format!("{plan}"),
143143
"Projection: t.a, t.b, my_add(t.a, t.b)\n TableScan: t projection=[a, b]"
144144
);
145145

@@ -393,7 +393,7 @@ async fn udaf_as_window_func() -> Result<()> {
393393
TableScan: my_table"#;
394394

395395
let dataframe = context.sql(sql).await.unwrap();
396-
assert_eq!(format!("{:?}", dataframe.logical_plan()), expected);
396+
assert_eq!(format!("{}", dataframe.logical_plan()), expected);
397397
Ok(())
398398
}
399399

@@ -1124,7 +1124,7 @@ async fn test_parameterized_scalar_udf() -> Result<()> {
11241124
.build()?;
11251125

11261126
assert_eq!(
1127-
format!("{plan:?}"),
1127+
format!("{plan}"),
11281128
"Filter: t.text IS NOT NULL\n Filter: regex_udf(t.text) AND regex_udf(t.text)\n TableScan: t projection=[text]"
11291129
);
11301130

datafusion/expr/src/logical_plan/builder.rs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1749,7 +1749,7 @@ mod tests {
17491749
\n Filter: employee_csv.state = Utf8(\"CO\")\
17501750
\n TableScan: employee_csv projection=[id, state]";
17511751

1752-
assert_eq!(expected, format!("{plan:?}"));
1752+
assert_eq!(expected, format!("{plan}"));
17531753

17541754
Ok(())
17551755
}
@@ -1802,7 +1802,7 @@ mod tests {
18021802
let expected = "Sort: employee_csv.state ASC NULLS FIRST, employee_csv.salary DESC NULLS LAST\
18031803
\n TableScan: employee_csv projection=[state, salary]";
18041804

1805-
assert_eq!(expected, format!("{plan:?}"));
1805+
assert_eq!(expected, format!("{plan}"));
18061806

18071807
Ok(())
18081808
}
@@ -1822,7 +1822,7 @@ mod tests {
18221822
\n TableScan: t1\
18231823
\n TableScan: t2";
18241824

1825-
assert_eq!(expected, format!("{plan:?}"));
1825+
assert_eq!(expected, format!("{plan}"));
18261826

18271827
Ok(())
18281828
}
@@ -1847,7 +1847,7 @@ mod tests {
18471847
\n TableScan: employee_csv projection=[state, salary]\
18481848
\n TableScan: employee_csv projection=[state, salary]";
18491849

1850-
assert_eq!(expected, format!("{plan:?}"));
1850+
assert_eq!(expected, format!("{plan}"));
18511851

18521852
Ok(())
18531853
}
@@ -1876,7 +1876,7 @@ mod tests {
18761876
\n TableScan: employee_csv projection=[state, salary]\
18771877
\n TableScan: employee_csv projection=[state, salary]";
18781878

1879-
assert_eq!(expected, format!("{plan:?}"));
1879+
assert_eq!(expected, format!("{plan}"));
18801880

18811881
Ok(())
18821882
}
@@ -1913,7 +1913,7 @@ mod tests {
19131913
\n Filter: employee_csv.state = Utf8(\"CO\")\
19141914
\n TableScan: employee_csv projection=[id, state]";
19151915

1916-
assert_eq!(expected, format!("{plan:?}"));
1916+
assert_eq!(expected, format!("{plan}"));
19171917

19181918
Ok(())
19191919
}
@@ -1940,7 +1940,7 @@ mod tests {
19401940
\n TableScan: foo\
19411941
\n Projection: bar.a\
19421942
\n TableScan: bar";
1943-
assert_eq!(expected, format!("{outer_query:?}"));
1943+
assert_eq!(expected, format!("{outer_query}"));
19441944

19451945
Ok(())
19461946
}
@@ -1968,7 +1968,7 @@ mod tests {
19681968
\n TableScan: foo\
19691969
\n Projection: bar.a\
19701970
\n TableScan: bar";
1971-
assert_eq!(expected, format!("{outer_query:?}"));
1971+
assert_eq!(expected, format!("{outer_query}"));
19721972

19731973
Ok(())
19741974
}
@@ -1994,7 +1994,7 @@ mod tests {
19941994
\n Projection: foo.b\
19951995
\n TableScan: foo\
19961996
\n TableScan: bar";
1997-
assert_eq!(expected, format!("{outer_query:?}"));
1997+
assert_eq!(expected, format!("{outer_query}"));
19981998

19991999
Ok(())
20002000
}
@@ -2116,7 +2116,7 @@ mod tests {
21162116
let expected = "\
21172117
Unnest: lists[test_table.strings] structs[]\
21182118
\n TableScan: test_table";
2119-
assert_eq!(expected, format!("{plan:?}"));
2119+
assert_eq!(expected, format!("{plan}"));
21202120

21212121
// Check unnested field is a scalar
21222122
let field = plan.schema().field_with_name(None, "strings").unwrap();
@@ -2130,7 +2130,7 @@ mod tests {
21302130
let expected = "\
21312131
Unnest: lists[] structs[test_table.struct_singular]\
21322132
\n TableScan: test_table";
2133-
assert_eq!(expected, format!("{plan:?}"));
2133+
assert_eq!(expected, format!("{plan}"));
21342134

21352135
for field_name in &["a", "b"] {
21362136
// Check unnested struct field is a scalar
@@ -2153,7 +2153,7 @@ mod tests {
21532153
\n Unnest: lists[test_table.structs] structs[]\
21542154
\n Unnest: lists[test_table.strings] structs[]\
21552155
\n TableScan: test_table";
2156-
assert_eq!(expected, format!("{plan:?}"));
2156+
assert_eq!(expected, format!("{plan}"));
21572157

21582158
// Check unnested struct list field should be a struct.
21592159
let field = plan.schema().field_with_name(None, "structs").unwrap();
@@ -2171,7 +2171,7 @@ mod tests {
21712171
let expected = "\
21722172
Unnest: lists[test_table.strings, test_table.structs] structs[test_table.struct_singular]\
21732173
\n TableScan: test_table";
2174-
assert_eq!(expected, format!("{plan:?}"));
2174+
assert_eq!(expected, format!("{plan}"));
21752175

21762176
// Unnesting missing column should fail.
21772177
let plan = nested_table_scan("test_table")?.unnest_column("missing");
@@ -2263,9 +2263,9 @@ mod tests {
22632263
])?
22642264
.build()?;
22652265

2266-
let plan_expected = format!("{plan:?}");
2266+
let plan_expected = format!("{plan}");
22672267
let plan_builder: LogicalPlanBuilder = Arc::new(plan).into();
2268-
assert_eq!(plan_expected, format!("{:?}", plan_builder.plan));
2268+
assert_eq!(plan_expected, format!("{}", plan_builder.plan));
22692269

22702270
Ok(())
22712271
}

datafusion/expr/src/logical_plan/ddl.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use datafusion_common::{Constraints, DFSchemaRef, SchemaReference, TableReferenc
2929
use sqlparser::ast::Ident;
3030

3131
/// Various types of DDL (CREATE / DROP) catalog manipulation
32-
#[derive(Clone, PartialEq, Eq, Hash)]
32+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3333
pub enum DdlStatement {
3434
/// Creates an external table.
3535
CreateExternalTable(CreateExternalTable),
@@ -179,7 +179,7 @@ impl DdlStatement {
179179
}
180180

181181
/// Creates an external table.
182-
#[derive(Clone, PartialEq, Eq)]
182+
#[derive(Debug, Clone, PartialEq, Eq)]
183183
pub struct CreateExternalTable {
184184
/// The table schema
185185
pub schema: DFSchemaRef,
@@ -224,7 +224,7 @@ impl Hash for CreateExternalTable {
224224
}
225225

226226
/// Creates an in memory table.
227-
#[derive(Clone, PartialEq, Eq, Hash)]
227+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
228228
pub struct CreateMemoryTable {
229229
/// The table name
230230
pub name: TableReference,
@@ -241,7 +241,7 @@ pub struct CreateMemoryTable {
241241
}
242242

243243
/// Creates a view.
244-
#[derive(Clone, PartialEq, Eq, Hash)]
244+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
245245
pub struct CreateView {
246246
/// The table name
247247
pub name: TableReference,
@@ -254,7 +254,7 @@ pub struct CreateView {
254254
}
255255

256256
/// Creates a catalog (aka "Database").
257-
#[derive(Clone, PartialEq, Eq, Hash)]
257+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
258258
pub struct CreateCatalog {
259259
/// The catalog name
260260
pub catalog_name: String,
@@ -265,7 +265,7 @@ pub struct CreateCatalog {
265265
}
266266

267267
/// Creates a schema.
268-
#[derive(Clone, PartialEq, Eq, Hash)]
268+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
269269
pub struct CreateCatalogSchema {
270270
/// The table schema
271271
pub schema_name: String,
@@ -276,7 +276,7 @@ pub struct CreateCatalogSchema {
276276
}
277277

278278
/// Drops a table.
279-
#[derive(Clone, PartialEq, Eq, Hash)]
279+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
280280
pub struct DropTable {
281281
/// The table name
282282
pub name: TableReference,
@@ -287,7 +287,7 @@ pub struct DropTable {
287287
}
288288

289289
/// Drops a view.
290-
#[derive(Clone, PartialEq, Eq, Hash)]
290+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
291291
pub struct DropView {
292292
/// The view name
293293
pub name: TableReference,
@@ -298,7 +298,7 @@ pub struct DropView {
298298
}
299299

300300
/// Drops a schema
301-
#[derive(Clone, PartialEq, Eq, Hash)]
301+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
302302
pub struct DropCatalogSchema {
303303
/// The schema name
304304
pub name: SchemaReference,

0 commit comments

Comments
 (0)