Skip to content

Commit 846376a

Browse files
committed
[SPARK-56983][SQL] DecimalAggregates widened-Cast peel must preserve query semantics
## What changes were proposed in this pull request? Two semantic-preserving fixes to the SPARK-56627 widened-Cast peel in `DecimalAggregates`: 1. **SUM arm**: Replace `Cast(MakeDecimal(_, p + 10, s), bounded(pPrime + 10, s))` with `MakeDecimal(_, min(pPrime + 10, 38), s)`. The merged form's inner `MakeDecimal` narrowed the overflow check to `10^(p+10)`, where the un-rewritten `SUM(Cast(x, dec(pPrime, s)))` accepted up to `10^min(pPrime+10, 38)`. For `pPrime + 10 > 18`, `Decimal.setOrNull` falls into the BigDecimal branch and never rejects a Long, so the cleaner form preserves the original overflow boundary for all Long-fit sums. 2. **AVG arm**: Change the guard from `p <= 7` (`AVG_PEEL_MAX_INNER_PRECISION`) to `pPrime + 4 <= 15` (`MAX_DOUBLE_DIGITS`). The merged guard switched `AVG(CAST(x AS DECIMAL(pPrime, s)))` from full Decimal arithmetic to Double-regime whenever `p <= 7`, including the `pPrime > 11` band where un-rewritten was Decimal-exact. The new guard ensures the rewrite only fires inside the existing AVG fast-path's Double envelope. ## Why are the changes needed? A query rewrite should preserve the query's observable semantics. The SPARK-56627 rule changed semantics in two ways: - **SUM**: Inner `MakeDecimal(_, p + 10, s)` could return null (non-ANSI) or throw (ANSI) for long-fit sums in \`(10^(p+10), 10^min(pPrime+10, 38))\`. Example: \`SUM(CAST(x AS DECIMAL(15, 2)))\` where \`x: DECIMAL(5, 2)\` rejected at \`10^15\` instead of \`10^25\` -- reachable around \`~10^10\` rows of small-precision input. - **AVG**: For \`pPrime > 11, p <= 7\`, the rule switched an exact-Decimal computation into Double-regime, visible as last-digit rounding differences at any input size. TPC-DS q18 (\`p=7, pPrime=12\`) was affected. ## Does this PR introduce _any_ user-facing change? Yes -- restores the un-rewritten semantics for affected queries: - \`SUM(CAST(x AS DECIMAL(pPrime, s)))\` no longer rejects long-fit sums that the un-rewritten expression would have accepted. - \`AVG(CAST(x AS DECIMAL(pPrime, s)))\` with \`pPrime + 4 > MAX_DOUBLE_DIGITS\` is no longer peeled -- the un-rewritten Decimal-exact path is preserved. TPC-DS q18 AVG aggregations revert to the un-peeled form (visible in the regenerated \`q18\` plan-stability files). ## How was this patch tested? - \`DecimalAggregatesSuite\`: 37/37 pass, including updated SUM arm shape assertions, the property-test invariants for the new MakeDecimal-only form, and the new AVG bound boundary tests. - \`DataFrameAggregateSuite\`: SPARK-56627 numerical-equivalence PBTs pass under the new AVG generator domain (\`pPrime in [p+1, 11]\`). - TPC-DS q18 plan-stability files regenerated locally. - \`DecimalAggregatesBenchmark\` AVG cases (B2, B4) updated to \`pPrime = 11\` (the new bound). Result files left stale relative to the code change -- the \`benchmark.yml\` GHA workflow can regenerate them. ## Was this patch authored or co-authored using generative AI tooling? Generated-by: Claude Opus 4.7 Closes #56036 from cloud-fan/SPARK-decimal-aggregates-semantics-fix. Authored-by: Wenchen Fan <wenchen@databricks.com> Signed-off-by: Wenchen Fan <wenchen@databricks.com>
1 parent 74816d7 commit 846376a

8 files changed

Lines changed: 152 additions & 216 deletions

File tree

sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/optimizer/Optimizer.scala

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2564,12 +2564,8 @@ object DecimalAggregates extends Rule[LogicalPlan] {
25642564
/** Maximum number of decimal digits representable precisely in a Double */
25652565
private val MAX_DOUBLE_DIGITS = 15
25662566

2567-
/** Tighter than the AVG fast path's `prec + 4 <= MAX_DOUBLE_DIGITS` (= 11):
2568-
* the strict-subset keeps SPARK-37024 Double-regime exposure unchanged. */
2569-
private val AVG_PEEL_MAX_INNER_PRECISION = 7
2570-
2571-
/** Matches a scale-preserving widening decimal Cast; refuses CheckOverflow
2572-
* to preserve overflow semantics on the unscaled value. */
2567+
/** Matches a scale-preserving widening decimal Cast.
2568+
* Refuses CheckOverflow so per-row overflow checks are not hoisted out. */
25732569
private object WidenedDecimalChild {
25742570
def unapply(e: Expression): Option[(Expression, Int, Int, Int)] = e match {
25752571
case Cast(inner @ DecimalExpression(p, s), DecimalType.Fixed(pPrime, sPrime), _, _)
@@ -2604,27 +2600,35 @@ object DecimalAggregates extends Rule[LogicalPlan] {
26042600
case _ => we
26052601
}
26062602
case ae @ AggregateExpression(af, _, _, _, _) => af match {
2603+
// Hoist a scale-preserving widening Cast out of Sum so the existing
2604+
// Long fast-path can fire on the inner. The MakeDecimal target type
2605+
// matches `Sum(Cast(x, dec(pPrime, s))).dataType` (see Sum.resultType)
2606+
// so the final-value overflow boundary is the same as the un-rewritten
2607+
// expression.
26072608
case s @ Sum(WidenedDecimalChild(inner, p, pPrime, s_scale), _)
26082609
if p + 10 <= MAX_LONG_DIGITS =>
2609-
Cast(
2610-
MakeDecimal(
2611-
ae.copy(aggregateFunction = s.copy(child = UnscaledValue(inner))),
2612-
p + 10, s_scale),
2613-
DecimalType.bounded(pPrime + 10, s_scale),
2614-
Option(conf.sessionLocalTimeZone))
2610+
val target = DecimalType.bounded(pPrime + 10, s_scale)
2611+
MakeDecimal(
2612+
ae.copy(aggregateFunction = s.copy(child = UnscaledValue(inner))),
2613+
target.precision, target.scale)
26152614

26162615
case s @ Sum(e @ DecimalExpression(prec, scale), _) if prec + 10 <= MAX_LONG_DIGITS =>
26172616
MakeDecimal(ae.copy(aggregateFunction = s.copy(child = UnscaledValue(e))),
26182617
prec + 10, scale)
26192618

2620-
// Ordered before the un-widened Average arm: when pPrime in [8, 11],
2621-
// the outer Cast's DecimalType would otherwise match that arm first.
2619+
// Hoist a scale-preserving widening Cast out of Average. Guarded on
2620+
// the OUTER precision `pPrime + 4 <= MAX_DOUBLE_DIGITS` so the
2621+
// rewrite only fires inside the existing Double-regime envelope;
2622+
// for wider outer casts the un-rewritten Decimal-exact path is
2623+
// preserved. Ordered before the un-widened arm so the outer Cast's
2624+
// dataType does not let that arm intercept first (when pPrime <= 11,
2625+
// it would also match -- but on the outer Cast, not the inner).
26222626
case a @ Average(WidenedDecimalChild(inner, p, pPrime, s_scale), _)
2623-
if p <= AVG_PEEL_MAX_INNER_PRECISION =>
2627+
if pPrime + 4 <= MAX_DOUBLE_DIGITS =>
26242628
val newAggExpr = ae.copy(aggregateFunction = a.copy(child = UnscaledValue(inner)))
26252629
Cast(
26262630
Divide(newAggExpr, Literal.create(math.pow(10.0, s_scale), DoubleType)),
2627-
DecimalType.bounded(pPrime + 4, s_scale + 4), Option(conf.sessionLocalTimeZone))
2631+
DecimalType(pPrime + 4, s_scale + 4), Option(conf.sessionLocalTimeZone))
26282632

26292633
case a @ Average(e @ DecimalExpression(prec, scale), _) if prec + 4 <= MAX_DOUBLE_DIGITS =>
26302634
val newAggExpr = ae.copy(aggregateFunction = a.copy(child = UnscaledValue(e)))

sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/optimizer/DecimalAggregatesSuite.scala

Lines changed: 78 additions & 140 deletions
Large diffs are not rendered by default.

sql/core/src/test/resources/tpcds-plan-stability/approved-plans-v1_4/q18.sf100/explain.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ Arguments: [[cs_quantity#4, cs_list_price#5, cs_sales_price#6, cs_coupon_amt#7,
257257
(46) HashAggregate [codegen id : 13]
258258
Input [12]: [cs_quantity#4, cs_list_price#5, cs_sales_price#6, cs_coupon_amt#7, cs_net_profit#8, cd_dep_count#14, c_birth_year#22, i_item_id#28, ca_country#29, ca_state#30, ca_county#31, spark_grouping_id#32]
259259
Keys [5]: [i_item_id#28, ca_country#29, ca_state#30, ca_county#31, spark_grouping_id#32]
260-
Functions [7]: [partial_avg(cast(cs_quantity#4 as decimal(12,2))), partial_avg(UnscaledValue(cs_list_price#5)), partial_avg(UnscaledValue(cs_coupon_amt#7)), partial_avg(UnscaledValue(cs_sales_price#6)), partial_avg(UnscaledValue(cs_net_profit#8)), partial_avg(cast(c_birth_year#22 as decimal(12,2))), partial_avg(cast(cd_dep_count#14 as decimal(12,2)))]
260+
Functions [7]: [partial_avg(cast(cs_quantity#4 as decimal(12,2))), partial_avg(cast(cs_list_price#5 as decimal(12,2))), partial_avg(cast(cs_coupon_amt#7 as decimal(12,2))), partial_avg(cast(cs_sales_price#6 as decimal(12,2))), partial_avg(cast(cs_net_profit#8 as decimal(12,2))), partial_avg(cast(c_birth_year#22 as decimal(12,2))), partial_avg(cast(cd_dep_count#14 as decimal(12,2)))]
261261
Aggregate Attributes [14]: [sum#33, count#34, sum#35, count#36, sum#37, count#38, sum#39, count#40, sum#41, count#42, sum#43, count#44, sum#45, count#46]
262262
Results [19]: [i_item_id#28, ca_country#29, ca_state#30, ca_county#31, spark_grouping_id#32, sum#47, count#48, sum#49, count#50, sum#51, count#52, sum#53, count#54, sum#55, count#56, sum#57, count#58, sum#59, count#60]
263263

@@ -268,9 +268,9 @@ Arguments: hashpartitioning(i_item_id#28, ca_country#29, ca_state#30, ca_county#
268268
(48) HashAggregate [codegen id : 14]
269269
Input [19]: [i_item_id#28, ca_country#29, ca_state#30, ca_county#31, spark_grouping_id#32, sum#47, count#48, sum#49, count#50, sum#51, count#52, sum#53, count#54, sum#55, count#56, sum#57, count#58, sum#59, count#60]
270270
Keys [5]: [i_item_id#28, ca_country#29, ca_state#30, ca_county#31, spark_grouping_id#32]
271-
Functions [7]: [avg(cast(cs_quantity#4 as decimal(12,2))), avg(UnscaledValue(cs_list_price#5)), avg(UnscaledValue(cs_coupon_amt#7)), avg(UnscaledValue(cs_sales_price#6)), avg(UnscaledValue(cs_net_profit#8)), avg(cast(c_birth_year#22 as decimal(12,2))), avg(cast(cd_dep_count#14 as decimal(12,2)))]
272-
Aggregate Attributes [7]: [avg(cast(cs_quantity#4 as decimal(12,2)))#61, avg(UnscaledValue(cs_list_price#5))#62, avg(UnscaledValue(cs_coupon_amt#7))#63, avg(UnscaledValue(cs_sales_price#6))#64, avg(UnscaledValue(cs_net_profit#8))#65, avg(cast(c_birth_year#22 as decimal(12,2)))#66, avg(cast(cd_dep_count#14 as decimal(12,2)))#67]
273-
Results [11]: [i_item_id#28, ca_country#29, ca_state#30, ca_county#31, avg(cast(cs_quantity#4 as decimal(12,2)))#61 AS agg1#68, cast((avg(UnscaledValue(cs_list_price#5))#62 / 100.0) as decimal(16,6)) AS agg2#69, cast((avg(UnscaledValue(cs_coupon_amt#7))#63 / 100.0) as decimal(16,6)) AS agg3#70, cast((avg(UnscaledValue(cs_sales_price#6))#64 / 100.0) as decimal(16,6)) AS agg4#71, cast((avg(UnscaledValue(cs_net_profit#8))#65 / 100.0) as decimal(16,6)) AS agg5#72, avg(cast(c_birth_year#22 as decimal(12,2)))#66 AS agg6#73, avg(cast(cd_dep_count#14 as decimal(12,2)))#67 AS agg7#74]
271+
Functions [7]: [avg(cast(cs_quantity#4 as decimal(12,2))), avg(cast(cs_list_price#5 as decimal(12,2))), avg(cast(cs_coupon_amt#7 as decimal(12,2))), avg(cast(cs_sales_price#6 as decimal(12,2))), avg(cast(cs_net_profit#8 as decimal(12,2))), avg(cast(c_birth_year#22 as decimal(12,2))), avg(cast(cd_dep_count#14 as decimal(12,2)))]
272+
Aggregate Attributes [7]: [avg(cast(cs_quantity#4 as decimal(12,2)))#61, avg(cast(cs_list_price#5 as decimal(12,2)))#62, avg(cast(cs_coupon_amt#7 as decimal(12,2)))#63, avg(cast(cs_sales_price#6 as decimal(12,2)))#64, avg(cast(cs_net_profit#8 as decimal(12,2)))#65, avg(cast(c_birth_year#22 as decimal(12,2)))#66, avg(cast(cd_dep_count#14 as decimal(12,2)))#67]
273+
Results [11]: [i_item_id#28, ca_country#29, ca_state#30, ca_county#31, avg(cast(cs_quantity#4 as decimal(12,2)))#61 AS agg1#68, avg(cast(cs_list_price#5 as decimal(12,2)))#62 AS agg2#69, avg(cast(cs_coupon_amt#7 as decimal(12,2)))#63 AS agg3#70, avg(cast(cs_sales_price#6 as decimal(12,2)))#64 AS agg4#71, avg(cast(cs_net_profit#8 as decimal(12,2)))#65 AS agg5#72, avg(cast(c_birth_year#22 as decimal(12,2)))#66 AS agg6#73, avg(cast(cd_dep_count#14 as decimal(12,2)))#67 AS agg7#74]
274274

275275
(49) TakeOrderedAndProject
276276
Input [11]: [i_item_id#28, ca_country#29, ca_state#30, ca_county#31, agg1#68, agg2#69, agg3#70, agg4#71, agg5#72, agg6#73, agg7#74]

sql/core/src/test/resources/tpcds-plan-stability/approved-plans-v1_4/q18.sf100/simplified.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
TakeOrderedAndProject [ca_country,ca_state,ca_county,i_item_id,agg1,agg2,agg3,agg4,agg5,agg6,agg7]
22
WholeStageCodegen (14)
3-
HashAggregate [i_item_id,ca_country,ca_state,ca_county,spark_grouping_id,sum,count,sum,count,sum,count,sum,count,sum,count,sum,count,sum,count] [avg(cast(cs_quantity as decimal(12,2))),avg(UnscaledValue(cs_list_price)),avg(UnscaledValue(cs_coupon_amt)),avg(UnscaledValue(cs_sales_price)),avg(UnscaledValue(cs_net_profit)),avg(cast(c_birth_year as decimal(12,2))),avg(cast(cd_dep_count as decimal(12,2))),agg1,agg2,agg3,agg4,agg5,agg6,agg7,sum,count,sum,count,sum,count,sum,count,sum,count,sum,count,sum,count]
3+
HashAggregate [i_item_id,ca_country,ca_state,ca_county,spark_grouping_id,sum,count,sum,count,sum,count,sum,count,sum,count,sum,count,sum,count] [avg(cast(cs_quantity as decimal(12,2))),avg(cast(cs_list_price as decimal(12,2))),avg(cast(cs_coupon_amt as decimal(12,2))),avg(cast(cs_sales_price as decimal(12,2))),avg(cast(cs_net_profit as decimal(12,2))),avg(cast(c_birth_year as decimal(12,2))),avg(cast(cd_dep_count as decimal(12,2))),agg1,agg2,agg3,agg4,agg5,agg6,agg7,sum,count,sum,count,sum,count,sum,count,sum,count,sum,count,sum,count]
44
InputAdapter
55
Exchange [i_item_id,ca_country,ca_state,ca_county,spark_grouping_id] #1
66
WholeStageCodegen (13)

sql/core/src/test/resources/tpcds-plan-stability/approved-plans-v1_4/q18/explain.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ Arguments: [[cs_quantity#4, cs_list_price#5, cs_sales_price#6, cs_coupon_amt#7,
227227
(40) HashAggregate [codegen id : 7]
228228
Input [12]: [cs_quantity#4, cs_list_price#5, cs_sales_price#6, cs_coupon_amt#7, cs_net_profit#8, cd_dep_count#14, c_birth_year#19, i_item_id#28, ca_country#29, ca_state#30, ca_county#31, spark_grouping_id#32]
229229
Keys [5]: [i_item_id#28, ca_country#29, ca_state#30, ca_county#31, spark_grouping_id#32]
230-
Functions [7]: [partial_avg(cast(cs_quantity#4 as decimal(12,2))), partial_avg(UnscaledValue(cs_list_price#5)), partial_avg(UnscaledValue(cs_coupon_amt#7)), partial_avg(UnscaledValue(cs_sales_price#6)), partial_avg(UnscaledValue(cs_net_profit#8)), partial_avg(cast(c_birth_year#19 as decimal(12,2))), partial_avg(cast(cd_dep_count#14 as decimal(12,2)))]
230+
Functions [7]: [partial_avg(cast(cs_quantity#4 as decimal(12,2))), partial_avg(cast(cs_list_price#5 as decimal(12,2))), partial_avg(cast(cs_coupon_amt#7 as decimal(12,2))), partial_avg(cast(cs_sales_price#6 as decimal(12,2))), partial_avg(cast(cs_net_profit#8 as decimal(12,2))), partial_avg(cast(c_birth_year#19 as decimal(12,2))), partial_avg(cast(cd_dep_count#14 as decimal(12,2)))]
231231
Aggregate Attributes [14]: [sum#33, count#34, sum#35, count#36, sum#37, count#38, sum#39, count#40, sum#41, count#42, sum#43, count#44, sum#45, count#46]
232232
Results [19]: [i_item_id#28, ca_country#29, ca_state#30, ca_county#31, spark_grouping_id#32, sum#47, count#48, sum#49, count#50, sum#51, count#52, sum#53, count#54, sum#55, count#56, sum#57, count#58, sum#59, count#60]
233233

@@ -238,9 +238,9 @@ Arguments: hashpartitioning(i_item_id#28, ca_country#29, ca_state#30, ca_county#
238238
(42) HashAggregate [codegen id : 8]
239239
Input [19]: [i_item_id#28, ca_country#29, ca_state#30, ca_county#31, spark_grouping_id#32, sum#47, count#48, sum#49, count#50, sum#51, count#52, sum#53, count#54, sum#55, count#56, sum#57, count#58, sum#59, count#60]
240240
Keys [5]: [i_item_id#28, ca_country#29, ca_state#30, ca_county#31, spark_grouping_id#32]
241-
Functions [7]: [avg(cast(cs_quantity#4 as decimal(12,2))), avg(UnscaledValue(cs_list_price#5)), avg(UnscaledValue(cs_coupon_amt#7)), avg(UnscaledValue(cs_sales_price#6)), avg(UnscaledValue(cs_net_profit#8)), avg(cast(c_birth_year#19 as decimal(12,2))), avg(cast(cd_dep_count#14 as decimal(12,2)))]
242-
Aggregate Attributes [7]: [avg(cast(cs_quantity#4 as decimal(12,2)))#61, avg(UnscaledValue(cs_list_price#5))#62, avg(UnscaledValue(cs_coupon_amt#7))#63, avg(UnscaledValue(cs_sales_price#6))#64, avg(UnscaledValue(cs_net_profit#8))#65, avg(cast(c_birth_year#19 as decimal(12,2)))#66, avg(cast(cd_dep_count#14 as decimal(12,2)))#67]
243-
Results [11]: [i_item_id#28, ca_country#29, ca_state#30, ca_county#31, avg(cast(cs_quantity#4 as decimal(12,2)))#61 AS agg1#68, cast((avg(UnscaledValue(cs_list_price#5))#62 / 100.0) as decimal(16,6)) AS agg2#69, cast((avg(UnscaledValue(cs_coupon_amt#7))#63 / 100.0) as decimal(16,6)) AS agg3#70, cast((avg(UnscaledValue(cs_sales_price#6))#64 / 100.0) as decimal(16,6)) AS agg4#71, cast((avg(UnscaledValue(cs_net_profit#8))#65 / 100.0) as decimal(16,6)) AS agg5#72, avg(cast(c_birth_year#19 as decimal(12,2)))#66 AS agg6#73, avg(cast(cd_dep_count#14 as decimal(12,2)))#67 AS agg7#74]
241+
Functions [7]: [avg(cast(cs_quantity#4 as decimal(12,2))), avg(cast(cs_list_price#5 as decimal(12,2))), avg(cast(cs_coupon_amt#7 as decimal(12,2))), avg(cast(cs_sales_price#6 as decimal(12,2))), avg(cast(cs_net_profit#8 as decimal(12,2))), avg(cast(c_birth_year#19 as decimal(12,2))), avg(cast(cd_dep_count#14 as decimal(12,2)))]
242+
Aggregate Attributes [7]: [avg(cast(cs_quantity#4 as decimal(12,2)))#61, avg(cast(cs_list_price#5 as decimal(12,2)))#62, avg(cast(cs_coupon_amt#7 as decimal(12,2)))#63, avg(cast(cs_sales_price#6 as decimal(12,2)))#64, avg(cast(cs_net_profit#8 as decimal(12,2)))#65, avg(cast(c_birth_year#19 as decimal(12,2)))#66, avg(cast(cd_dep_count#14 as decimal(12,2)))#67]
243+
Results [11]: [i_item_id#28, ca_country#29, ca_state#30, ca_county#31, avg(cast(cs_quantity#4 as decimal(12,2)))#61 AS agg1#68, avg(cast(cs_list_price#5 as decimal(12,2)))#62 AS agg2#69, avg(cast(cs_coupon_amt#7 as decimal(12,2)))#63 AS agg3#70, avg(cast(cs_sales_price#6 as decimal(12,2)))#64 AS agg4#71, avg(cast(cs_net_profit#8 as decimal(12,2)))#65 AS agg5#72, avg(cast(c_birth_year#19 as decimal(12,2)))#66 AS agg6#73, avg(cast(cd_dep_count#14 as decimal(12,2)))#67 AS agg7#74]
244244

245245
(43) TakeOrderedAndProject
246246
Input [11]: [i_item_id#28, ca_country#29, ca_state#30, ca_county#31, agg1#68, agg2#69, agg3#70, agg4#71, agg5#72, agg6#73, agg7#74]

sql/core/src/test/resources/tpcds-plan-stability/approved-plans-v1_4/q18/simplified.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
TakeOrderedAndProject [ca_country,ca_state,ca_county,i_item_id,agg1,agg2,agg3,agg4,agg5,agg6,agg7]
22
WholeStageCodegen (8)
3-
HashAggregate [i_item_id,ca_country,ca_state,ca_county,spark_grouping_id,sum,count,sum,count,sum,count,sum,count,sum,count,sum,count,sum,count] [avg(cast(cs_quantity as decimal(12,2))),avg(UnscaledValue(cs_list_price)),avg(UnscaledValue(cs_coupon_amt)),avg(UnscaledValue(cs_sales_price)),avg(UnscaledValue(cs_net_profit)),avg(cast(c_birth_year as decimal(12,2))),avg(cast(cd_dep_count as decimal(12,2))),agg1,agg2,agg3,agg4,agg5,agg6,agg7,sum,count,sum,count,sum,count,sum,count,sum,count,sum,count,sum,count]
3+
HashAggregate [i_item_id,ca_country,ca_state,ca_county,spark_grouping_id,sum,count,sum,count,sum,count,sum,count,sum,count,sum,count,sum,count] [avg(cast(cs_quantity as decimal(12,2))),avg(cast(cs_list_price as decimal(12,2))),avg(cast(cs_coupon_amt as decimal(12,2))),avg(cast(cs_sales_price as decimal(12,2))),avg(cast(cs_net_profit as decimal(12,2))),avg(cast(c_birth_year as decimal(12,2))),avg(cast(cd_dep_count as decimal(12,2))),agg1,agg2,agg3,agg4,agg5,agg6,agg7,sum,count,sum,count,sum,count,sum,count,sum,count,sum,count,sum,count]
44
InputAdapter
55
Exchange [i_item_id,ca_country,ca_state,ca_county,spark_grouping_id] #1
66
WholeStageCodegen (7)

0 commit comments

Comments
 (0)