-
Notifications
You must be signed in to change notification settings - Fork 28.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[SPARK-13739] [SQL] Push Predicate Through Window #11635
Changes from all commits
01e4cdf
6835704
9180687
b38a21e
d2b84af
fda8025
ac0dccd
6e0018b
0546772
b37a64f
c2a872c
ab6dbd7
4276356
2dab708
0458770
1debdfa
763706d
4de6ec1
9422a4f
52bdf48
1e95df3
fab24cf
8b2e33b
2ee1876
b9f0090
ade6f7e
9fd63d2
5199d49
404214c
c001dd9
59daa48
41d5f64
472a6e3
458f7be
92136dd
f401d8b
0fba10a
3aea1da
d420246
c05b4ae
6db1940
8fa0294
cbf73b3
c08f561
474df88
3d9828d
72d2361
07afea5
8bf2007
87a165b
b9359cd
b0d7b3b
65bd090
babf2da
9e09469
50a8e4a
f3337fa
09cc36d
83a1915
0483145
236a5f4
417bdb4
cc5f0bd
436359f
fae2694
875d6b6
0469923
5c4f4d3
c4dedd2
3eaeaa5
e427ce9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -758,4 +758,223 @@ class FilterPushdownSuite extends PlanTest { | |||||||||||||||||||||||||||||||||||||||
val correctedAnswer = agg.copy(child = agg.child.where(a > 1 && b > 2)).analyze | ||||||||||||||||||||||||||||||||||||||||
comparePlans(optimized, correctedAnswer) | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
test("Window: predicate push down -- basic") { | ||||||||||||||||||||||||||||||||||||||||
val winExpr = windowExpr(count('b), windowSpec('a :: Nil, 'b.asc :: Nil, UnspecifiedFrame)) | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
val originalQuery = testRelation.select('a, 'b, 'c, winExpr.as('window)).where('a > 1) | ||||||||||||||||||||||||||||||||||||||||
val correctAnswer = testRelation | ||||||||||||||||||||||||||||||||||||||||
.where('a > 1).select('a, 'b, 'c) | ||||||||||||||||||||||||||||||||||||||||
.window(winExpr.as('window) :: Nil, 'a :: Nil, 'b.asc :: Nil) | ||||||||||||||||||||||||||||||||||||||||
.select('a, 'b, 'c, 'window).analyze | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
comparePlans(Optimize.execute(originalQuery.analyze), correctAnswer) | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
test("Window: predicate push down -- predicates with compound predicate using only one column") { | ||||||||||||||||||||||||||||||||||||||||
val winExpr = | ||||||||||||||||||||||||||||||||||||||||
windowExpr(count('b), windowSpec('a.attr :: 'b.attr :: Nil, 'b.asc :: Nil, UnspecifiedFrame)) | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
val originalQuery = testRelation.select('a, 'b, 'c, winExpr.as('window)).where('a * 3 > 15) | ||||||||||||||||||||||||||||||||||||||||
val correctAnswer = testRelation | ||||||||||||||||||||||||||||||||||||||||
.where('a * 3 > 15).select('a, 'b, 'c) | ||||||||||||||||||||||||||||||||||||||||
.window(winExpr.as('window) :: Nil, 'a.attr :: 'b.attr :: Nil, 'b.asc :: Nil) | ||||||||||||||||||||||||||||||||||||||||
.select('a, 'b, 'c, 'window).analyze | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
comparePlans(Optimize.execute(originalQuery.analyze), correctAnswer) | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
test("Window: predicate push down -- multi window expressions with the same window spec") { | ||||||||||||||||||||||||||||||||||||||||
val winSpec = windowSpec('a.attr :: 'b.attr :: Nil, 'b.asc :: Nil, UnspecifiedFrame) | ||||||||||||||||||||||||||||||||||||||||
val winExpr1 = windowExpr(count('b), winSpec) | ||||||||||||||||||||||||||||||||||||||||
val winExpr2 = windowExpr(sum('b), winSpec) | ||||||||||||||||||||||||||||||||||||||||
val originalQuery = testRelation | ||||||||||||||||||||||||||||||||||||||||
.select('a, 'b, 'c, winExpr1.as('window1), winExpr2.as('window2)).where('a > 1) | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
val correctAnswer = testRelation | ||||||||||||||||||||||||||||||||||||||||
.where('a > 1).select('a, 'b, 'c) | ||||||||||||||||||||||||||||||||||||||||
.window(winExpr1.as('window1) :: winExpr2.as('window2) :: Nil, | ||||||||||||||||||||||||||||||||||||||||
'a.attr :: 'b.attr :: Nil, 'b.asc :: Nil) | ||||||||||||||||||||||||||||||||||||||||
.select('a, 'b, 'c, 'window1, 'window2).analyze | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
comparePlans(Optimize.execute(originalQuery.analyze), correctAnswer) | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
test("Window: predicate push down -- multi window specification - 1") { | ||||||||||||||||||||||||||||||||||||||||
// order by clauses are different between winSpec1 and winSpec2 | ||||||||||||||||||||||||||||||||||||||||
val winSpec1 = windowSpec('a.attr :: 'b.attr :: Nil, 'b.asc :: Nil, UnspecifiedFrame) | ||||||||||||||||||||||||||||||||||||||||
val winExpr1 = windowExpr(count('b), winSpec1) | ||||||||||||||||||||||||||||||||||||||||
val winSpec2 = windowSpec('a.attr :: 'b.attr :: Nil, 'a.asc :: Nil, UnspecifiedFrame) | ||||||||||||||||||||||||||||||||||||||||
val winExpr2 = windowExpr(count('b), winSpec2) | ||||||||||||||||||||||||||||||||||||||||
val originalQuery = testRelation | ||||||||||||||||||||||||||||||||||||||||
.select('a, 'b, 'c, winExpr1.as('window1), winExpr2.as('window2)).where('a > 1) | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
val correctAnswer1 = testRelation | ||||||||||||||||||||||||||||||||||||||||
.where('a > 1).select('a, 'b, 'c) | ||||||||||||||||||||||||||||||||||||||||
.window(winExpr1.as('window1) :: Nil, 'a.attr :: 'b.attr :: Nil, 'b.asc :: Nil) | ||||||||||||||||||||||||||||||||||||||||
.window(winExpr2.as('window2) :: Nil, 'a.attr :: 'b.attr :: Nil, 'a.asc :: Nil) | ||||||||||||||||||||||||||||||||||||||||
.select('a, 'b, 'c, 'window1, 'window2).analyze | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
val correctAnswer2 = testRelation | ||||||||||||||||||||||||||||||||||||||||
.where('a > 1).select('a, 'b, 'c) | ||||||||||||||||||||||||||||||||||||||||
.window(winExpr2.as('window2) :: Nil, 'a.attr :: 'b.attr :: Nil, 'a.asc :: Nil) | ||||||||||||||||||||||||||||||||||||||||
.window(winExpr1.as('window1) :: Nil, 'a.attr :: 'b.attr :: Nil, 'b.asc :: Nil) | ||||||||||||||||||||||||||||||||||||||||
.select('a, 'b, 'c, 'window1, 'window2).analyze | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
// When Analyzer adding Window operators after grouping the extracted Window Expressions | ||||||||||||||||||||||||||||||||||||||||
// based on their Partition and Order Specs, the order of Window operators is | ||||||||||||||||||||||||||||||||||||||||
// non-deterministic. Thus, we have two correct plans | ||||||||||||||||||||||||||||||||||||||||
val optimizedQuery = Optimize.execute(originalQuery.analyze) | ||||||||||||||||||||||||||||||||||||||||
try { | ||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are you doing this because you cannot predict how the Analyzer will structure the window functions? In this case you could just have the analyzer take care of it, by writing: testRelation.where('a > 1).select('a, 'b, 'c, winExpr1.as('window1), winExpr2.as('window2)).analyze There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The non-deterministic results are introduced when we grouping extractedWindowExprBuffer based on their Partition and Order Specs. spark/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/Analyzer.scala Lines 1318 to 1336 in 890abd1
I did not change the behavior of the source codes since the orders of Previously, I saw different orders in multiple runs. Thus, I am afraid the way you mentioned does not work too. |
||||||||||||||||||||||||||||||||||||||||
comparePlans(optimizedQuery, correctAnswer1) | ||||||||||||||||||||||||||||||||||||||||
} catch { | ||||||||||||||||||||||||||||||||||||||||
case ae: Throwable => comparePlans(optimizedQuery, correctAnswer2) | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
test("Window: predicate push down -- multi window specification - 2") { | ||||||||||||||||||||||||||||||||||||||||
// partitioning clauses are different between winSpec1 and winSpec2 | ||||||||||||||||||||||||||||||||||||||||
val winSpec1 = windowSpec('a.attr :: Nil, 'b.asc :: Nil, UnspecifiedFrame) | ||||||||||||||||||||||||||||||||||||||||
val winExpr1 = windowExpr(count('b), winSpec1) | ||||||||||||||||||||||||||||||||||||||||
val winSpec2 = windowSpec('b.attr :: Nil, 'b.asc :: Nil, UnspecifiedFrame) | ||||||||||||||||||||||||||||||||||||||||
val winExpr2 = windowExpr(count('a), winSpec2) | ||||||||||||||||||||||||||||||||||||||||
val originalQuery = testRelation | ||||||||||||||||||||||||||||||||||||||||
.select('a, winExpr1.as('window1), 'b, 'c, winExpr2.as('window2)).where('b > 1) | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
val correctAnswer1 = testRelation.select('a, 'b, 'c) | ||||||||||||||||||||||||||||||||||||||||
.window(winExpr1.as('window1) :: Nil, 'a.attr :: Nil, 'b.asc :: Nil) | ||||||||||||||||||||||||||||||||||||||||
.where('b > 1) | ||||||||||||||||||||||||||||||||||||||||
.window(winExpr2.as('window2) :: Nil, 'b.attr :: Nil, 'b.asc :: Nil) | ||||||||||||||||||||||||||||||||||||||||
.select('a, 'window1, 'b, 'c, 'window2).analyze | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
val correctAnswer2 = testRelation.select('a, 'b, 'c) | ||||||||||||||||||||||||||||||||||||||||
.window(winExpr2.as('window2) :: Nil, 'b.attr :: Nil, 'b.asc :: Nil) | ||||||||||||||||||||||||||||||||||||||||
.window(winExpr1.as('window1) :: Nil, 'a.attr :: Nil, 'b.asc :: Nil) | ||||||||||||||||||||||||||||||||||||||||
.where('b > 1) | ||||||||||||||||||||||||||||||||||||||||
.select('a, 'window1, 'b, 'c, 'window2).analyze | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
val optimizedQuery = Optimize.execute(originalQuery.analyze) | ||||||||||||||||||||||||||||||||||||||||
// When Analyzer adding Window operators after grouping the extracted Window Expressions | ||||||||||||||||||||||||||||||||||||||||
// based on their Partition and Order Specs, the order of Window operators is | ||||||||||||||||||||||||||||||||||||||||
// non-deterministic. Thus, we have two correct plans | ||||||||||||||||||||||||||||||||||||||||
try { | ||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add a line of documentation to explain why you are using try/catch. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will do it. |
||||||||||||||||||||||||||||||||||||||||
comparePlans(optimizedQuery, correctAnswer1) | ||||||||||||||||||||||||||||||||||||||||
} catch { | ||||||||||||||||||||||||||||||||||||||||
case ae: Throwable => comparePlans(optimizedQuery, correctAnswer2) | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
test("Window: predicate push down -- predicates with multiple partitioning columns") { | ||||||||||||||||||||||||||||||||||||||||
val winExpr = | ||||||||||||||||||||||||||||||||||||||||
windowExpr(count('b), windowSpec('a.attr :: 'b.attr :: Nil, 'b.asc :: Nil, UnspecifiedFrame)) | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
val originalQuery = testRelation.select('a, 'b, 'c, winExpr.as('window)).where('a + 'b > 1) | ||||||||||||||||||||||||||||||||||||||||
val correctAnswer = testRelation | ||||||||||||||||||||||||||||||||||||||||
.where('a + 'b > 1).select('a, 'b, 'c) | ||||||||||||||||||||||||||||||||||||||||
.window(winExpr.as('window) :: Nil, 'a.attr :: 'b.attr :: Nil, 'b.asc :: Nil) | ||||||||||||||||||||||||||||||||||||||||
.select('a, 'b, 'c, 'window).analyze | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
comparePlans(Optimize.execute(originalQuery.analyze), correctAnswer) | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
// complex predicates with the same references but the same expressions | ||||||||||||||||||||||||||||||||||||||||
// Todo: in Analyzer, to enable it, we need to convert the expression in conditions | ||||||||||||||||||||||||||||||||||||||||
// to the alias that is defined as the same expression | ||||||||||||||||||||||||||||||||||||||||
ignore("Window: predicate push down -- complex predicate with the same expressions") { | ||||||||||||||||||||||||||||||||||||||||
val winSpec = windowSpec( | ||||||||||||||||||||||||||||||||||||||||
partitionSpec = 'a.attr + 'b.attr :: Nil, | ||||||||||||||||||||||||||||||||||||||||
orderSpec = 'b.asc :: Nil, | ||||||||||||||||||||||||||||||||||||||||
UnspecifiedFrame) | ||||||||||||||||||||||||||||||||||||||||
val winExpr = windowExpr(count('b), winSpec) | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
val winSpecAnalyzed = windowSpec( | ||||||||||||||||||||||||||||||||||||||||
partitionSpec = '_w0.attr :: Nil, | ||||||||||||||||||||||||||||||||||||||||
orderSpec = 'b.asc :: Nil, | ||||||||||||||||||||||||||||||||||||||||
UnspecifiedFrame) | ||||||||||||||||||||||||||||||||||||||||
val winExprAnalyzed = windowExpr(count('b), winSpecAnalyzed) | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
val originalQuery = testRelation.select('a, 'b, 'c, winExpr.as('window)).where('a + 'b > 1) | ||||||||||||||||||||||||||||||||||||||||
val correctAnswer = testRelation | ||||||||||||||||||||||||||||||||||||||||
.where('a + 'b > 1).select('a, 'b, 'c, ('a + 'b).as("_w0")) | ||||||||||||||||||||||||||||||||||||||||
.window(winExprAnalyzed.as('window) :: Nil, '_w0 :: Nil, 'b.asc :: Nil) | ||||||||||||||||||||||||||||||||||||||||
.select('a, 'b, 'c, 'window).analyze | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
comparePlans(Optimize.execute(originalQuery.analyze), correctAnswer) | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
test("Window: no predicate push down -- predicates are not from partitioning keys") { | ||||||||||||||||||||||||||||||||||||||||
val winSpec = windowSpec( | ||||||||||||||||||||||||||||||||||||||||
partitionSpec = 'a.attr :: 'b.attr :: Nil, | ||||||||||||||||||||||||||||||||||||||||
orderSpec = 'b.asc :: Nil, | ||||||||||||||||||||||||||||||||||||||||
UnspecifiedFrame) | ||||||||||||||||||||||||||||||||||||||||
val winExpr = windowExpr(count('b), winSpec) | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
// No push down: the predicate is c > 1, but the partitioning key is (a, b). | ||||||||||||||||||||||||||||||||||||||||
val originalQuery = testRelation.select('a, 'b, 'c, winExpr.as('window)).where('c > 1) | ||||||||||||||||||||||||||||||||||||||||
val correctAnswer = testRelation.select('a, 'b, 'c) | ||||||||||||||||||||||||||||||||||||||||
.window(winExpr.as('window) :: Nil, 'a.attr :: 'b.attr :: Nil, 'b.asc :: Nil) | ||||||||||||||||||||||||||||||||||||||||
.where('c > 1).select('a, 'b, 'c, 'window).analyze | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
comparePlans(Optimize.execute(originalQuery.analyze), correctAnswer) | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
test("Window: no predicate push down -- partial compound partition key") { | ||||||||||||||||||||||||||||||||||||||||
val winSpec = windowSpec( | ||||||||||||||||||||||||||||||||||||||||
partitionSpec = 'a.attr + 'b.attr :: 'b.attr :: Nil, | ||||||||||||||||||||||||||||||||||||||||
orderSpec = 'b.asc :: Nil, | ||||||||||||||||||||||||||||||||||||||||
UnspecifiedFrame) | ||||||||||||||||||||||||||||||||||||||||
val winExpr = windowExpr(count('b), winSpec) | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
// No push down: the predicate is a > 1, but the partitioning key is (a + b, b) | ||||||||||||||||||||||||||||||||||||||||
val originalQuery = testRelation.select('a, 'b, 'c, winExpr.as('window)).where('a > 1) | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
val winSpecAnalyzed = windowSpec( | ||||||||||||||||||||||||||||||||||||||||
partitionSpec = '_w0.attr :: 'b.attr :: Nil, | ||||||||||||||||||||||||||||||||||||||||
orderSpec = 'b.asc :: Nil, | ||||||||||||||||||||||||||||||||||||||||
UnspecifiedFrame) | ||||||||||||||||||||||||||||||||||||||||
val winExprAnalyzed = windowExpr(count('b), winSpecAnalyzed) | ||||||||||||||||||||||||||||||||||||||||
val correctAnswer = testRelation.select('a, 'b, 'c, ('a + 'b).as("_w0")) | ||||||||||||||||||||||||||||||||||||||||
.window(winExprAnalyzed.as('window) :: Nil, '_w0 :: 'b.attr :: Nil, 'b.asc :: Nil) | ||||||||||||||||||||||||||||||||||||||||
.where('a > 1).select('a, 'b, 'c, 'window).analyze | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
comparePlans(Optimize.execute(originalQuery.analyze), correctAnswer) | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
test("Window: no predicate push down -- complex predicates containing non partitioning columns") { | ||||||||||||||||||||||||||||||||||||||||
val winSpec = | ||||||||||||||||||||||||||||||||||||||||
windowSpec(partitionSpec = 'b.attr :: Nil, orderSpec = 'b.asc :: Nil, UnspecifiedFrame) | ||||||||||||||||||||||||||||||||||||||||
val winExpr = windowExpr(count('b), winSpec) | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
// No push down: the predicate is a + b > 1, but the partitioning key is b. | ||||||||||||||||||||||||||||||||||||||||
val originalQuery = testRelation.select('a, 'b, 'c, winExpr.as('window)).where('a + 'b > 1) | ||||||||||||||||||||||||||||||||||||||||
val correctAnswer = testRelation | ||||||||||||||||||||||||||||||||||||||||
.select('a, 'b, 'c) | ||||||||||||||||||||||||||||||||||||||||
.window(winExpr.as('window) :: Nil, 'b.attr :: Nil, 'b.asc :: Nil) | ||||||||||||||||||||||||||||||||||||||||
.where('a + 'b > 1).select('a, 'b, 'c, 'window).analyze | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
comparePlans(Optimize.execute(originalQuery.analyze), correctAnswer) | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
// complex predicates with the same references but different expressions | ||||||||||||||||||||||||||||||||||||||||
test("Window: no predicate push down -- complex predicate with different expressions") { | ||||||||||||||||||||||||||||||||||||||||
val winSpec = windowSpec( | ||||||||||||||||||||||||||||||||||||||||
partitionSpec = 'a.attr + 'b.attr :: Nil, | ||||||||||||||||||||||||||||||||||||||||
orderSpec = 'b.asc :: Nil, | ||||||||||||||||||||||||||||||||||||||||
UnspecifiedFrame) | ||||||||||||||||||||||||||||||||||||||||
val winExpr = windowExpr(count('b), winSpec) | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
val winSpecAnalyzed = windowSpec( | ||||||||||||||||||||||||||||||||||||||||
partitionSpec = '_w0.attr :: Nil, | ||||||||||||||||||||||||||||||||||||||||
orderSpec = 'b.asc :: Nil, | ||||||||||||||||||||||||||||||||||||||||
UnspecifiedFrame) | ||||||||||||||||||||||||||||||||||||||||
val winExprAnalyzed = windowExpr(count('b), winSpecAnalyzed) | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
// No push down: the predicate is a + b > 1, but the partitioning key is a + b. | ||||||||||||||||||||||||||||||||||||||||
val originalQuery = testRelation.select('a, 'b, 'c, winExpr.as('window)).where('a - 'b > 1) | ||||||||||||||||||||||||||||||||||||||||
val correctAnswer = testRelation.select('a, 'b, 'c, ('a + 'b).as("_w0")) | ||||||||||||||||||||||||||||||||||||||||
.window(winExprAnalyzed.as('window) :: Nil, '_w0 :: Nil, 'b.asc :: Nil) | ||||||||||||||||||||||||||||||||||||||||
.where('a - 'b > 1).select('a, 'b, 'c, 'window).analyze | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
comparePlans(Optimize.execute(originalQuery.analyze), correctAnswer) | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Math.pow(NIT, 100): What does the style guide say about ternary expression onliners?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nevermind, I looked it up. It is allowed.