Skip to content

Commit 32d4a2b

Browse files
wangyumcloud-fan
authored andcommitted
[SPARK-33861][SQL] Simplify conditional in predicate
### What changes were proposed in this pull request? This pr simplify conditional in predicate, after this change we can push down the filter to datasource: Expression | After simplify -- | -- IF(cond, trueVal, false) | AND(cond, trueVal) IF(cond, trueVal, true) | OR(NOT(cond), trueVal) IF(cond, false, falseVal) | AND(NOT(cond), elseVal) IF(cond, true, falseVal) | OR(cond, elseVal) CASE WHEN cond THEN trueVal ELSE false END | AND(cond, trueVal) CASE WHEN cond THEN trueVal END | AND(cond, trueVal) CASE WHEN cond THEN trueVal ELSE null END | AND(cond, trueVal) CASE WHEN cond THEN trueVal ELSE true END | OR(NOT(cond), trueVal) CASE WHEN cond THEN false ELSE elseVal END | AND(NOT(cond), elseVal) CASE WHEN cond THEN false END | false CASE WHEN cond THEN true ELSE elseVal END | OR(cond, elseVal) CASE WHEN cond THEN true END | cond ### Why are the changes needed? Improve query performance. ### Does this PR introduce _any_ user-facing change? No. ### How was this patch tested? Unit test. Closes apache#30865 from wangyum/SPARK-33861. Authored-by: Yuming Wang <[email protected]> Signed-off-by: Wenchen Fan <[email protected]>
1 parent d7dc42d commit 32d4a2b

File tree

23 files changed

+378
-58
lines changed

23 files changed

+378
-58
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ abstract class Optimizer(catalogManager: CatalogManager)
103103
RemoveDispensableExpressions,
104104
SimplifyBinaryComparison,
105105
ReplaceNullWithFalseInPredicate,
106+
SimplifyConditionalsInPredicate,
106107
PruneFilters,
107108
SimplifyCasts,
108109
SimplifyCaseConversionExpressions,
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.spark.sql.catalyst.optimizer
19+
20+
import org.apache.spark.sql.catalyst.expressions.{And, CaseWhen, Expression, If, Literal, Not, Or}
21+
import org.apache.spark.sql.catalyst.expressions.Literal.{FalseLiteral, TrueLiteral}
22+
import org.apache.spark.sql.catalyst.plans.logical._
23+
import org.apache.spark.sql.catalyst.rules.Rule
24+
import org.apache.spark.sql.types.BooleanType
25+
26+
/**
27+
* A rule that converts conditional expressions to predicate expressions, if possible, in the
28+
* search condition of the WHERE/HAVING/ON(JOIN) clauses, which contain an implicit Boolean operator
29+
* "(search condition) = TRUE". After this converting, we can potentially push the filter down to
30+
* the data source.
31+
*
32+
* Supported cases are:
33+
* - IF(cond, trueVal, false) => AND(cond, trueVal)
34+
* - IF(cond, trueVal, true) => OR(NOT(cond), trueVal)
35+
* - IF(cond, false, falseVal) => AND(NOT(cond), elseVal)
36+
* - IF(cond, true, falseVal) => OR(cond, elseVal)
37+
* - CASE WHEN cond THEN trueVal ELSE false END => AND(cond, trueVal)
38+
* - CASE WHEN cond THEN trueVal END => AND(cond, trueVal)
39+
* - CASE WHEN cond THEN trueVal ELSE null END => AND(cond, trueVal)
40+
* - CASE WHEN cond THEN trueVal ELSE true END => OR(NOT(cond), trueVal)
41+
* - CASE WHEN cond THEN false ELSE elseVal END => AND(NOT(cond), elseVal)
42+
* - CASE WHEN cond THEN false END => false
43+
* - CASE WHEN cond THEN true ELSE elseVal END => OR(cond, elseVal)
44+
* - CASE WHEN cond THEN true END => cond
45+
*/
46+
object SimplifyConditionalsInPredicate extends Rule[LogicalPlan] {
47+
48+
def apply(plan: LogicalPlan): LogicalPlan = plan transform {
49+
case f @ Filter(cond, _) => f.copy(condition = simplifyConditional(cond))
50+
case j @ Join(_, _, _, Some(cond), _) => j.copy(condition = Some(simplifyConditional(cond)))
51+
case d @ DeleteFromTable(_, Some(cond)) => d.copy(condition = Some(simplifyConditional(cond)))
52+
case u @ UpdateTable(_, _, Some(cond)) => u.copy(condition = Some(simplifyConditional(cond)))
53+
}
54+
55+
private def simplifyConditional(e: Expression): Expression = e match {
56+
case And(left, right) => And(simplifyConditional(left), simplifyConditional(right))
57+
case Or(left, right) => Or(simplifyConditional(left), simplifyConditional(right))
58+
case If(cond, trueValue, FalseLiteral) => And(cond, trueValue)
59+
case If(cond, trueValue, TrueLiteral) => Or(Not(cond), trueValue)
60+
case If(cond, FalseLiteral, falseValue) => And(Not(cond), falseValue)
61+
case If(cond, TrueLiteral, falseValue) => Or(cond, falseValue)
62+
case CaseWhen(Seq((cond, trueValue)),
63+
Some(FalseLiteral) | Some(Literal(null, BooleanType)) | None) =>
64+
And(cond, trueValue)
65+
case CaseWhen(Seq((cond, trueValue)), Some(TrueLiteral)) =>
66+
Or(Not(cond), trueValue)
67+
case CaseWhen(Seq((_, FalseLiteral)), Some(FalseLiteral) | None) =>
68+
FalseLiteral
69+
case CaseWhen(Seq((cond, FalseLiteral)), Some(elseValue)) =>
70+
And(Not(cond), elseValue)
71+
case CaseWhen(Seq((cond, TrueLiteral)), Some(FalseLiteral) | None) =>
72+
cond
73+
case CaseWhen(Seq((cond, TrueLiteral)), Some(elseValue)) =>
74+
Or(cond, elseValue)
75+
case e if e.dataType == BooleanType => e
76+
case e =>
77+
assert(e.dataType != BooleanType,
78+
"Expected a Boolean type expression in SimplifyConditionalsInPredicate, " +
79+
s"but got the type `${e.dataType.catalogString}` in `${e.sql}`.")
80+
e
81+
}
82+
}
Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.spark.sql.catalyst.optimizer
19+
20+
import org.apache.spark.sql.AnalysisException
21+
import org.apache.spark.sql.catalyst.analysis.UnresolvedAttribute
22+
import org.apache.spark.sql.catalyst.dsl.expressions._
23+
import org.apache.spark.sql.catalyst.dsl.plans._
24+
import org.apache.spark.sql.catalyst.expressions.{And, CaseWhen, Expression, If, IsNotNull, Literal, Or}
25+
import org.apache.spark.sql.catalyst.expressions.Literal.{FalseLiteral, TrueLiteral}
26+
import org.apache.spark.sql.catalyst.plans.{Inner, PlanTest}
27+
import org.apache.spark.sql.catalyst.plans.logical.{DeleteFromTable, LocalRelation, LogicalPlan, UpdateTable}
28+
import org.apache.spark.sql.catalyst.rules.RuleExecutor
29+
import org.apache.spark.sql.types.{BooleanType, IntegerType}
30+
31+
class SimplifyConditionalsInPredicateSuite extends PlanTest {
32+
33+
object Optimize extends RuleExecutor[LogicalPlan] {
34+
val batches =
35+
Batch("SimplifyConditionalsInPredicate", FixedPoint(10),
36+
NullPropagation,
37+
ConstantFolding,
38+
BooleanSimplification,
39+
SimplifyConditionals,
40+
SimplifyConditionalsInPredicate) :: Nil
41+
}
42+
43+
private val testRelation =
44+
LocalRelation('i.int, 'b.boolean, 'a.array(IntegerType), 'm.map(IntegerType, IntegerType))
45+
private val anotherTestRelation = LocalRelation('d.int)
46+
47+
test("IF(cond, trueVal, false) => AND(cond, trueVal)") {
48+
val originalCond = If(
49+
UnresolvedAttribute("i") > Literal(10),
50+
UnresolvedAttribute("b"),
51+
FalseLiteral)
52+
val expectedCond = And(
53+
UnresolvedAttribute("i") > Literal(10),
54+
UnresolvedAttribute("b"))
55+
testFilter(originalCond, expectedCond = expectedCond)
56+
testJoin(originalCond, expectedCond = expectedCond)
57+
testDelete(originalCond, expectedCond = expectedCond)
58+
testUpdate(originalCond, expectedCond = expectedCond)
59+
testProjection(originalCond, expectedExpr = originalCond)
60+
}
61+
62+
test("IF(cond, trueVal, true) => OR(NOT(cond), trueVal)") {
63+
val originalCond = If(
64+
UnresolvedAttribute("i") > Literal(10),
65+
UnresolvedAttribute("b"),
66+
TrueLiteral)
67+
val expectedCond = Or(
68+
UnresolvedAttribute("i") <= Literal(10),
69+
UnresolvedAttribute("b"))
70+
testFilter(originalCond, expectedCond = expectedCond)
71+
testJoin(originalCond, expectedCond = expectedCond)
72+
testDelete(originalCond, expectedCond = expectedCond)
73+
testUpdate(originalCond, expectedCond = expectedCond)
74+
testProjection(originalCond, expectedExpr = originalCond)
75+
}
76+
77+
test("IF(cond, false, falseVal) => AND(NOT(cond), elseVal)") {
78+
val originalCond = If(
79+
UnresolvedAttribute("i") > Literal(10),
80+
FalseLiteral,
81+
UnresolvedAttribute("b"))
82+
val expectedCond = And(
83+
UnresolvedAttribute("i") <= Literal(10),
84+
UnresolvedAttribute("b"))
85+
testFilter(originalCond, expectedCond = expectedCond)
86+
testJoin(originalCond, expectedCond = expectedCond)
87+
testDelete(originalCond, expectedCond = expectedCond)
88+
testUpdate(originalCond, expectedCond = expectedCond)
89+
testProjection(originalCond, expectedExpr = originalCond)
90+
}
91+
92+
test("IF(cond, true, falseVal) => OR(cond, elseVal)") {
93+
val originalCond = If(
94+
UnresolvedAttribute("i") > Literal(10),
95+
TrueLiteral,
96+
UnresolvedAttribute("b"))
97+
val expectedCond = Or(
98+
UnresolvedAttribute("i") > Literal(10),
99+
UnresolvedAttribute("b"))
100+
testFilter(originalCond, expectedCond = expectedCond)
101+
testJoin(originalCond, expectedCond = expectedCond)
102+
testDelete(originalCond, expectedCond = expectedCond)
103+
testUpdate(originalCond, expectedCond = expectedCond)
104+
testProjection(originalCond, expectedExpr = originalCond)
105+
}
106+
107+
test("CASE WHEN cond THEN trueVal ELSE false END => AND(cond, trueVal)") {
108+
Seq(Some(FalseLiteral), None, Some(Literal(null, BooleanType))).foreach { elseExp =>
109+
val originalCond = CaseWhen(
110+
Seq((UnresolvedAttribute("i") > Literal(10), UnresolvedAttribute("b"))),
111+
elseExp)
112+
val expectedCond = And(
113+
UnresolvedAttribute("i") > Literal(10),
114+
UnresolvedAttribute("b"))
115+
testFilter(originalCond, expectedCond = expectedCond)
116+
testJoin(originalCond, expectedCond = expectedCond)
117+
testDelete(originalCond, expectedCond = expectedCond)
118+
testUpdate(originalCond, expectedCond = expectedCond)
119+
testProjection(originalCond, expectedExpr = originalCond)
120+
}
121+
}
122+
123+
test("CASE WHEN cond THEN trueVal ELSE true END => OR(NOT(cond), trueVal)") {
124+
val originalCond = CaseWhen(
125+
Seq((UnresolvedAttribute("i") > Literal(10), UnresolvedAttribute("b"))),
126+
TrueLiteral)
127+
val expectedCond = Or(
128+
UnresolvedAttribute("i") <= Literal(10),
129+
UnresolvedAttribute("b"))
130+
testFilter(originalCond, expectedCond = expectedCond)
131+
testJoin(originalCond, expectedCond = expectedCond)
132+
testDelete(originalCond, expectedCond = expectedCond)
133+
testUpdate(originalCond, expectedCond = expectedCond)
134+
testProjection(originalCond, expectedExpr = originalCond)
135+
}
136+
137+
test("CASE WHEN cond THEN false ELSE elseVal END => AND(NOT(cond), elseVal)") {
138+
val originalCond = CaseWhen(
139+
Seq((UnresolvedAttribute("i") > Literal(10), FalseLiteral)),
140+
UnresolvedAttribute("b"))
141+
val expectedCond = And(
142+
UnresolvedAttribute("i") <= Literal(10),
143+
UnresolvedAttribute("b"))
144+
testFilter(originalCond, expectedCond = expectedCond)
145+
testJoin(originalCond, expectedCond = expectedCond)
146+
testDelete(originalCond, expectedCond = expectedCond)
147+
testUpdate(originalCond, expectedCond = expectedCond)
148+
testProjection(originalCond, expectedExpr = originalCond)
149+
}
150+
151+
test("CASE WHEN cond THEN false END => false") {
152+
val originalCond = CaseWhen(
153+
Seq((UnresolvedAttribute("i") > Literal(10), FalseLiteral)))
154+
testFilter(originalCond, expectedCond = FalseLiteral)
155+
testJoin(originalCond, expectedCond = FalseLiteral)
156+
testDelete(originalCond, expectedCond = FalseLiteral)
157+
testUpdate(originalCond, expectedCond = FalseLiteral)
158+
testProjection(originalCond, expectedExpr = originalCond)
159+
}
160+
161+
test("CASE WHEN cond THEN true ELSE elseVal END => OR(cond, elseVal)") {
162+
val originalCond = CaseWhen(
163+
Seq((UnresolvedAttribute("i") > Literal(10), TrueLiteral)),
164+
UnresolvedAttribute("b"))
165+
val expectedCond = Or(
166+
UnresolvedAttribute("i") > Literal(10),
167+
UnresolvedAttribute("b"))
168+
testFilter(originalCond, expectedCond = expectedCond)
169+
testJoin(originalCond, expectedCond = expectedCond)
170+
testDelete(originalCond, expectedCond = expectedCond)
171+
testUpdate(originalCond, expectedCond = expectedCond)
172+
testProjection(originalCond, expectedExpr = originalCond)
173+
}
174+
175+
test("CASE WHEN cond THEN true END => cond") {
176+
val originalCond = CaseWhen(
177+
Seq((UnresolvedAttribute("i") > Literal(10), TrueLiteral)))
178+
val expectedCond = UnresolvedAttribute("i") > Literal(10)
179+
testFilter(originalCond, expectedCond = expectedCond)
180+
testJoin(originalCond, expectedCond = expectedCond)
181+
testDelete(originalCond, expectedCond = expectedCond)
182+
testUpdate(originalCond, expectedCond = expectedCond)
183+
testProjection(originalCond, expectedExpr = originalCond)
184+
}
185+
186+
test("Simplify conditional in conditions of CaseWhen inside another CaseWhen") {
187+
val nestedCaseWhen = CaseWhen(
188+
Seq((UnresolvedAttribute("i") > Literal(10)) -> UnresolvedAttribute("b")),
189+
FalseLiteral)
190+
val originalCond = CaseWhen(Seq(IsNotNull(nestedCaseWhen) -> FalseLiteral))
191+
val expectedCond = FalseLiteral
192+
193+
testFilter(originalCond, expectedCond = expectedCond)
194+
testJoin(originalCond, expectedCond = expectedCond)
195+
testDelete(originalCond, expectedCond = expectedCond)
196+
testUpdate(originalCond, expectedCond = expectedCond)
197+
testProjection(originalCond, expectedExpr = originalCond)
198+
}
199+
200+
test("Not expected type - SimplifyConditionalsInPredicate") {
201+
val e = intercept[AnalysisException] {
202+
testFilter(originalCond = Literal(null, IntegerType), expectedCond = FalseLiteral)
203+
}.getMessage
204+
assert(e.contains("'CAST(NULL AS INT)' of type int is not a boolean"))
205+
}
206+
207+
private def testFilter(originalCond: Expression, expectedCond: Expression): Unit = {
208+
test((rel, exp) => rel.where(exp), originalCond, expectedCond)
209+
}
210+
211+
private def testJoin(originalCond: Expression, expectedCond: Expression): Unit = {
212+
test((rel, exp) => rel.join(anotherTestRelation, Inner, Some(exp)), originalCond, expectedCond)
213+
}
214+
215+
private def testProjection(originalExpr: Expression, expectedExpr: Expression): Unit = {
216+
test((rel, exp) => rel.select(exp), originalExpr, expectedExpr)
217+
}
218+
219+
private def testDelete(originalCond: Expression, expectedCond: Expression): Unit = {
220+
test((rel, expr) => DeleteFromTable(rel, Some(expr)), originalCond, expectedCond)
221+
}
222+
223+
private def testUpdate(originalCond: Expression, expectedCond: Expression): Unit = {
224+
test((rel, expr) => UpdateTable(rel, Seq.empty, Some(expr)), originalCond, expectedCond)
225+
}
226+
227+
private def test(
228+
func: (LogicalPlan, Expression) => LogicalPlan,
229+
originalExpr: Expression,
230+
expectedExpr: Expression): Unit = {
231+
232+
val originalPlan = func(testRelation, originalExpr).analyze
233+
val optimizedPlan = Optimize.execute(originalPlan)
234+
val expectedPlan = func(testRelation, expectedExpr).analyze
235+
comparePlans(optimizedPlan, expectedPlan)
236+
}
237+
}

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -120,15 +120,15 @@ Input [5]: [ss_customer_sk#2, ss_hdemo_sk#3, ss_store_sk#4, ss_ticket_number#5,
120120
Output [4]: [hd_demo_sk#13, hd_buy_potential#14, hd_dep_count#15, hd_vehicle_count#16]
121121
Batched: true
122122
Location [not included in comparison]/{warehouse_dir}/household_demographics]
123-
PushedFilters: [IsNotNull(hd_vehicle_count), Or(EqualTo(hd_buy_potential,>10000),EqualTo(hd_buy_potential,Unknown)), GreaterThan(hd_vehicle_count,0), IsNotNull(hd_demo_sk)]
123+
PushedFilters: [IsNotNull(hd_vehicle_count), IsNotNull(hd_dep_count), Or(EqualTo(hd_buy_potential,>10000),EqualTo(hd_buy_potential,Unknown)), GreaterThan(hd_vehicle_count,0), GreaterThan(hd_vehicle_count,0), IsNotNull(hd_demo_sk)]
124124
ReadSchema: struct<hd_demo_sk:int,hd_buy_potential:string,hd_dep_count:int,hd_vehicle_count:int>
125125

126126
(19) ColumnarToRow [codegen id : 3]
127127
Input [4]: [hd_demo_sk#13, hd_buy_potential#14, hd_dep_count#15, hd_vehicle_count#16]
128128

129129
(20) Filter [codegen id : 3]
130130
Input [4]: [hd_demo_sk#13, hd_buy_potential#14, hd_dep_count#15, hd_vehicle_count#16]
131-
Condition : ((((isnotnull(hd_vehicle_count#16) AND ((hd_buy_potential#14 = >10000) OR (hd_buy_potential#14 = Unknown))) AND (hd_vehicle_count#16 > 0)) AND (CASE WHEN (hd_vehicle_count#16 > 0) THEN (cast(hd_dep_count#15 as double) / cast(hd_vehicle_count#16 as double)) ELSE null END > 1.2)) AND isnotnull(hd_demo_sk#13))
131+
Condition : (((((isnotnull(hd_vehicle_count#16) AND isnotnull(hd_dep_count#15)) AND ((hd_buy_potential#14 = >10000) OR (hd_buy_potential#14 = Unknown))) AND (hd_vehicle_count#16 > 0)) AND ((cast(hd_dep_count#15 as double) / cast(hd_vehicle_count#16 as double)) > 1.2)) AND isnotnull(hd_demo_sk#13))
132132

133133
(21) Project [codegen id : 3]
134134
Output [1]: [hd_demo_sk#13]
@@ -156,7 +156,7 @@ Results [3]: [ss_ticket_number#5, ss_customer_sk#2, count#19]
156156

157157
(26) Exchange
158158
Input [3]: [ss_ticket_number#5, ss_customer_sk#2, count#19]
159-
Arguments: hashpartitioning(ss_ticket_number#5, ss_customer_sk#2, 5), true, [id=#20]
159+
Arguments: hashpartitioning(ss_ticket_number#5, ss_customer_sk#2, 5), ENSURE_REQUIREMENTS, [id=#20]
160160

161161
(27) HashAggregate [codegen id : 5]
162162
Input [3]: [ss_ticket_number#5, ss_customer_sk#2, count#19]
@@ -171,7 +171,7 @@ Condition : ((cnt#22 >= 15) AND (cnt#22 <= 20))
171171

172172
(29) Exchange
173173
Input [3]: [ss_ticket_number#5, ss_customer_sk#2, cnt#22]
174-
Arguments: hashpartitioning(ss_customer_sk#2, 5), true, [id=#23]
174+
Arguments: hashpartitioning(ss_customer_sk#2, 5), ENSURE_REQUIREMENTS, [id=#23]
175175

176176
(30) Sort [codegen id : 6]
177177
Input [3]: [ss_ticket_number#5, ss_customer_sk#2, cnt#22]
@@ -193,7 +193,7 @@ Condition : isnotnull(c_customer_sk#24)
193193

194194
(34) Exchange
195195
Input [5]: [c_customer_sk#24, c_salutation#25, c_first_name#26, c_last_name#27, c_preferred_cust_flag#28]
196-
Arguments: hashpartitioning(c_customer_sk#24, 5), true, [id=#29]
196+
Arguments: hashpartitioning(c_customer_sk#24, 5), ENSURE_REQUIREMENTS, [id=#29]
197197

198198
(35) Sort [codegen id : 8]
199199
Input [5]: [c_customer_sk#24, c_salutation#25, c_first_name#26, c_last_name#27, c_preferred_cust_flag#28]
@@ -210,7 +210,7 @@ Input [8]: [ss_ticket_number#5, ss_customer_sk#2, cnt#22, c_customer_sk#24, c_sa
210210

211211
(38) Exchange
212212
Input [6]: [c_last_name#27, c_first_name#26, c_salutation#25, c_preferred_cust_flag#28, ss_ticket_number#5, cnt#22]
213-
Arguments: rangepartitioning(c_last_name#27 ASC NULLS FIRST, c_first_name#26 ASC NULLS FIRST, c_salutation#25 ASC NULLS FIRST, c_preferred_cust_flag#28 DESC NULLS LAST, 5), true, [id=#30]
213+
Arguments: rangepartitioning(c_last_name#27 ASC NULLS FIRST, c_first_name#26 ASC NULLS FIRST, c_salutation#25 ASC NULLS FIRST, c_preferred_cust_flag#28 DESC NULLS LAST, 5), ENSURE_REQUIREMENTS, [id=#30]
214214

215215
(39) Sort [codegen id : 10]
216216
Input [6]: [c_last_name#27, c_first_name#26, c_salutation#25, c_preferred_cust_flag#28, ss_ticket_number#5, cnt#22]

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ WholeStageCodegen (10)
4747
BroadcastExchange #6
4848
WholeStageCodegen (3)
4949
Project [hd_demo_sk]
50-
Filter [hd_vehicle_count,hd_buy_potential,hd_dep_count,hd_demo_sk]
50+
Filter [hd_vehicle_count,hd_dep_count,hd_buy_potential,hd_demo_sk]
5151
ColumnarToRow
5252
InputAdapter
5353
Scan parquet default.household_demographics [hd_demo_sk,hd_buy_potential,hd_dep_count,hd_vehicle_count]

0 commit comments

Comments
 (0)