Skip to content

Commit a045f6a

Browse files
committed
updated TPC-H benchmark snapshots
1 parent 35f0591 commit a045f6a

13 files changed

Lines changed: 167 additions & 37 deletions

File tree

datafusion/core/src/physical_planner.rs

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2402,6 +2402,7 @@ pub fn create_aggregate_expr_with_name_and_maybe_filter(
24022402
e: &Expr,
24032403
name: Option<String>,
24042404
human_display: Option<String>,
2405+
human_display_is_aliased: bool,
24052406
logical_input_schema: &DFSchema,
24062407
physical_input_schema: &Schema,
24072408
execution_props: &ExecutionProps,
@@ -2450,6 +2451,7 @@ pub fn create_aggregate_expr_with_name_and_maybe_filter(
24502451
.order_by(order_bys.clone())
24512452
.schema(Arc::new(physical_input_schema.to_owned()))
24522453
.alias(name)
2454+
.with_aliased_human_display(human_display_is_aliased)
24532455
.with_ignore_nulls(ignore_nulls)
24542456
.with_distinct(*distinct);
24552457
if let Some(human_display) = human_display {
@@ -2477,30 +2479,37 @@ pub fn create_aggregate_expr_and_maybe_filter(
24772479
// Physical explain prefers the lowered aggregate form, so unwrap all alias
24782480
// layers to recover the underlying aggregate function and then re-attach
24792481
// only the visible output alias.
2480-
let (name, human_display, e) = match e {
2482+
let (name, human_display, human_display_is_aliased, e) = match e {
24812483
Expr::Alias(alias) => {
24822484
let unaliased = e.clone().unalias_nested().data;
24832485
let human_display = unaliased.human_display().to_string();
2484-
let human_display = if human_display.is_empty() || human_display == alias.name
2485-
{
2486-
alias.name.clone()
2487-
} else {
2488-
format!("{human_display} as {}", alias.name)
2489-
};
2490-
(Some(alias.name.clone()), Some(human_display), unaliased)
2486+
let (human_display, human_display_is_aliased) =
2487+
if human_display.is_empty() || human_display == alias.name {
2488+
(alias.name.clone(), false)
2489+
} else {
2490+
(format!("{human_display} as {}", alias.name), true)
2491+
};
2492+
(
2493+
Some(alias.name.clone()),
2494+
Some(human_display),
2495+
human_display_is_aliased,
2496+
unaliased,
2497+
)
24912498
}
24922499
Expr::AggregateFunction(_) => (
24932500
Some(e.schema_name().to_string()),
24942501
Some(e.human_display().to_string()),
2502+
false,
24952503
e.clone(),
24962504
),
2497-
_ => (None, None, e.clone()),
2505+
_ => (None, None, false, e.clone()),
24982506
};
24992507

25002508
create_aggregate_expr_with_name_and_maybe_filter(
25012509
&e,
25022510
name,
25032511
human_display,
2512+
human_display_is_aliased,
25042513
logical_input_schema,
25052514
physical_input_schema,
25062515
execution_props,

datafusion/expr/src/expr.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1834,11 +1834,6 @@ impl Expr {
18341834
Expr::Alias(Alias::new(self, relation, name.into()).with_metadata(metadata))
18351835
}
18361836

1837-
#[doc(hidden)]
1838-
pub fn alias_with_existing(self, alias: &Alias) -> Expr {
1839-
Expr::Alias(alias.clone().with_expr(self))
1840-
}
1841-
18421837
/// Remove an alias from an expression if one exists.
18431838
///
18441839
/// If the expression is not an alias, the expression is returned unchanged.

datafusion/physical-expr/src/aggregate.rs

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ pub struct AggregateExprBuilder {
6767
alias: Option<String>,
6868
/// A human readable name
6969
human_display: Option<String>,
70+
/// Whether `human_display` includes an explicit `... as <alias>` suffix.
71+
human_display_is_aliased: bool,
7072
/// Arrow Schema for the aggregate function
7173
schema: SchemaRef,
7274
/// The physical order by expressions
@@ -86,6 +88,7 @@ impl AggregateExprBuilder {
8688
args,
8789
alias: None,
8890
human_display: None,
91+
human_display_is_aliased: false,
8992
schema: Arc::new(Schema::empty()),
9093
order_bys: vec![],
9194
ignore_nulls: false,
@@ -190,6 +193,7 @@ impl AggregateExprBuilder {
190193
args,
191194
alias,
192195
human_display,
196+
human_display_is_aliased,
193197
schema,
194198
order_bys,
195199
ignore_nulls,
@@ -239,6 +243,7 @@ impl AggregateExprBuilder {
239243
return_field,
240244
name,
241245
human_display,
246+
human_display_is_aliased,
242247
schema: Arc::unwrap_or_clone(schema),
243248
order_bys,
244249
ignore_nulls,
@@ -261,6 +266,12 @@ impl AggregateExprBuilder {
261266
self
262267
}
263268

269+
#[doc(hidden)]
270+
pub fn with_aliased_human_display(mut self, human_display_is_aliased: bool) -> Self {
271+
self.human_display_is_aliased = human_display_is_aliased;
272+
self
273+
}
274+
264275
pub fn schema(mut self, schema: SchemaRef) -> Self {
265276
self.schema = schema;
266277
self
@@ -317,6 +328,8 @@ pub struct AggregateFunctionExpr {
317328
name: String,
318329
/// Simplified name for `tree` explain.
319330
human_display: Option<String>,
331+
/// Whether `human_display` includes an explicit `... as <alias>` suffix.
332+
human_display_is_aliased: bool,
320333
schema: Schema,
321334
// The physical order by expressions
322335
order_bys: Vec<PhysicalSortExpr>,
@@ -352,6 +365,11 @@ impl AggregateFunctionExpr {
352365
self.human_display.as_deref()
353366
}
354367

368+
#[doc(hidden)]
369+
pub fn has_aliased_human_display(&self) -> bool {
370+
self.human_display_is_aliased
371+
}
372+
355373
/// Return if the aggregation is distinct
356374
pub fn is_distinct(&self) -> bool {
357375
self.is_distinct
@@ -462,6 +480,7 @@ impl AggregateFunctionExpr {
462480
.order_by(self.order_bys.clone())
463481
.schema(Arc::new(self.schema.clone()))
464482
.alias(self.name().to_string())
483+
.with_aliased_human_display(self.human_display_is_aliased)
465484
.with_ignore_nulls(self.ignore_nulls)
466485
.with_distinct(self.is_distinct)
467486
.with_reversed(self.is_reversed);
@@ -586,15 +605,15 @@ impl AggregateFunctionExpr {
586605
ReversedUDAF::NotSupported => None,
587606
ReversedUDAF::Identical => Some(self.clone()),
588607
ReversedUDAF::Reversed(reverse_udf) => {
589-
let aliased_human_display = self
590-
.human_display()
591-
.and_then(|human_display| {
592-
strip_alias_suffix(human_display, self.name())
593-
})
594-
.map(str::to_string);
595-
let was_aliased = aliased_human_display.is_some();
608+
let was_aliased = self.has_aliased_human_display();
596609
let mut name = self.name().to_string();
597610
let mut human_display = self.human_display().map(str::to_string);
611+
// Reversing display follows two paths:
612+
// - aliased display keeps the output `name` unchanged and rewrites only
613+
// the lowered expression in `human_display`, then re-attaches
614+
// `as <alias>`.
615+
// - non-aliased display rewrites the canonical `name`, and rewrites
616+
// `human_display` only when present.
598617
// If the function is changed, we need to reverse order_by clause as well
599618
// i.e. First(a order by b asc null first) -> Last(a order by b desc null last)
600619
if !was_aliased && self.fun().name() != reverse_udf.name() {
@@ -609,8 +628,19 @@ impl AggregateFunctionExpr {
609628
}
610629

611630
if let Some(human_display) = human_display.as_mut() {
612-
if let Some(expr_display) = aliased_human_display {
613-
*human_display = expr_display;
631+
if was_aliased {
632+
let stripped = match strip_alias_suffix(
633+
human_display,
634+
self.name(),
635+
) {
636+
Some(stripped) => stripped.to_string(),
637+
None => panic!(
638+
"invariant violated: aliased aggregate human_display must end with ` as {}`: {}",
639+
self.name(),
640+
human_display
641+
),
642+
};
643+
*human_display = stripped;
614644
}
615645

616646
if self.fun().name() != reverse_udf.name() {
@@ -632,6 +662,7 @@ impl AggregateFunctionExpr {
632662
.order_by(self.order_bys.iter().map(|e| e.reverse()).collect())
633663
.schema(Arc::new(self.schema.clone()))
634664
.alias(name)
665+
.with_aliased_human_display(was_aliased)
635666
.with_ignore_nulls(self.ignore_nulls)
636667
.with_distinct(self.is_distinct)
637668
.with_reversed(!self.is_reversed);
@@ -693,6 +724,7 @@ impl AggregateFunctionExpr {
693724
name: self.name.clone(),
694725
// TODO: Human name should be updated after re-write to not mislead
695726
human_display: self.human_display.clone(),
727+
human_display_is_aliased: self.human_display_is_aliased,
696728
schema: self.schema.clone(),
697729
order_bys: new_order_bys,
698730
ignore_nulls: self.ignore_nulls,

datafusion/physical-plan/src/aggregates/mod.rs

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1447,7 +1447,7 @@ impl DisplayAs for AggregateExec {
14471447
}
14481448

14491449
fn format_aggregate_exec_expr(agg: &AggregateFunctionExpr) -> &str {
1450-
if has_aliased_human_display(agg) {
1450+
if agg.has_aliased_human_display() {
14511451
agg.human_display().unwrap_or_else(|| agg.name())
14521452
} else {
14531453
agg.name()
@@ -1458,12 +1458,6 @@ fn format_tree_aggregate_expr(agg: &AggregateFunctionExpr) -> &str {
14581458
agg.human_display().unwrap_or_else(|| agg.name())
14591459
}
14601460

1461-
fn has_aliased_human_display(agg: &AggregateFunctionExpr) -> bool {
1462-
agg.human_display()
1463-
.and_then(|human_display| human_display.strip_suffix(agg.name()))
1464-
.is_some_and(|prefix| prefix.ends_with(" as "))
1465-
}
1466-
14671461
impl ExecutionPlan for AggregateExec {
14681462
fn name(&self) -> &'static str {
14691463
"AggregateExec"
@@ -3053,6 +3047,7 @@ mod tests {
30533047
.human_display(
30543048
"first_value(b) ORDER BY [b ASC NULLS LAST] as agg".to_string(),
30553049
)
3050+
.with_aliased_human_display(true)
30563051
.build()?;
30573052

30583053
let reversed = agg.reverse_expr().expect("expected reverse expr");
@@ -3087,6 +3082,7 @@ mod tests {
30873082
"first_value(first_value_col) ORDER BY [first_value_col ASC NULLS LAST] as agg"
30883083
.to_string(),
30893084
)
3085+
.with_aliased_human_display(true)
30903086
.build()?;
30913087

30923088
let reversed = agg.reverse_expr().expect("expected reverse expr");
@@ -3121,6 +3117,29 @@ mod tests {
31213117
Ok(())
31223118
}
31233119

3120+
#[test]
3121+
fn test_reverse_expr_preserves_non_aliased_display_path() -> Result<()> {
3122+
let schema = create_test_schema()?;
3123+
let agg = AggregateExprBuilder::new(first_value_udaf(), vec![col("b", &schema)?])
3124+
.order_by(vec![PhysicalSortExpr {
3125+
expr: col("b", &schema)?,
3126+
options: SortOptions::new(false, false),
3127+
}])
3128+
.schema(Arc::clone(&schema))
3129+
.alias("first_value(b) ORDER BY [b ASC NULLS LAST]")
3130+
.build()?;
3131+
3132+
let reversed = agg.reverse_expr().expect("expected reverse expr");
3133+
3134+
assert_eq!(
3135+
reversed.name(),
3136+
"last_value(b) ORDER BY [b DESC NULLS FIRST]"
3137+
);
3138+
assert_eq!(reversed.human_display(), None);
3139+
3140+
Ok(())
3141+
}
3142+
31243143
// This function constructs the physical plan below,
31253144
//
31263145
// "AggregateExec: mode=Final, gby=[a@0 as a], aggr=[FIRST_VALUE(b)]",

datafusion/proto/proto/datafusion.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -943,6 +943,7 @@ message PhysicalAggregateExprNode {
943943
bool ignore_nulls = 6;
944944
optional bytes fun_definition = 7;
945945
string human_display = 8;
946+
bool human_display_is_aliased = 9;
946947
}
947948

948949
message PhysicalWindowExprNode {

datafusion/proto/src/generated/pbjson.rs

Lines changed: 18 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

datafusion/proto/src/generated/prost.rs

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

datafusion/proto/src/physical_plan/mod.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1264,7 +1264,10 @@ impl protobuf::PhysicalPlanNode {
12641264
.with_ignore_nulls(agg_node.ignore_nulls)
12651265
.with_distinct(agg_node.distinct)
12661266
.order_by(order_bys)
1267-
.human_display(agg_node.human_display.clone());
1267+
.human_display(agg_node.human_display.clone())
1268+
.with_aliased_human_display(
1269+
agg_node.human_display_is_aliased,
1270+
);
12681271
builder.build().map(Arc::new)
12691272
}
12701273
})

datafusion/proto/src/physical_plan/to_proto.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ pub fn serialize_physical_aggr_expr(
8484
.human_display()
8585
.unwrap_or_default()
8686
.to_string(),
87+
human_display_is_aliased: aggr_expr.has_aliased_human_display(),
8788
},
8889
)),
8990
})

0 commit comments

Comments
 (0)