Uh oh!
There was an error while loading. Please reload this page.
[SPARK-18137][SQL]Fix RewriteDistinctAggregates UnresolvedException when a UDAF has a foldable TypeCheck - #15668
Conversation
…hen the UDAF has a foldable TypeCheck
cloud-fan
commented
Oct 28, 2016
OK to test |
cloud-fan
commented
Oct 28, 2016
ok to test |
SparkQA
commented
Oct 28, 2016
Test build #67698 has finished for PR 15668 at commit
|
hvanhovell
commented
Oct 28, 2016
@windpiger I have taken a quick look at your PR. I think your approach has merit, however I was wondering if it is easier not to extract/move the foldable expressions at all? |
cloud-fan
commented
Oct 30, 2016
+1 on @hvanhovell 's idea, literals don't need to be pre-executed. |
windpiger
commented
Oct 31, 2016
@hvanhovell@cloud-fan Do you mean that just change distinctAggChildren/regularAggChildren to represent the unfoldable expressions, and then the followings code could be unchanged? ... val regularAggChildren = regularAggExprs.flatMap(.aggregateFunction.children).distinct.**filter(!.foldable)** |
cloud-fan
commented
Nov 1, 2016
It looks to me that after this PR, we still have literals in expand, can you call and how about this? https://github.com/apache/spark/compare/master...cloud-fan:showcase?expand=1 It's a little simpler and do avoid puting literals in expand. |
windpiger
commented
Nov 2, 2016
@cloud-fan yes,It is simpler,I check the query plan, my test case But, I miss one case that the distinct on a constant like: |
…hild;if has unfoldable children,it will only expand the unfoldable children
SparkQA
commented
Nov 7, 2016
Test build #68267 has finished for PR 15668 at commit
|
@cloud-fan I rewrite the expand logic:
for example: explained: |
hvanhovell
left a comment
There was a problem hiding this comment.
This is shaping up nicely. I left a few minor comments.
| import org.apache.spark.sql.types.IntegerType | ||
| /** | ||
| /* |
There was a problem hiding this comment.
can you revert this? this breaks scaladoc.
| // NamedExpression. This is done to prevent collisions between distinct and regular aggregate | ||
| // children, in this case attribute reuse causes the input of the regular aggregate to bound to | ||
| // the (nulled out) input of the distinct aggregate. | ||
| // We are creating a new reference here instead of reusing the attribute in case of a |
| val transformations: Map[Expression, Expression] = | ||
| (distinctAggOperatorMap.flatMap(_._2) ++ | ||
| regularAggOperatorMap.map(e => (e._1, e._3))).toMap | ||
| (distinctAggOperatorMap.flatMap(_._2) ++ |
| } | ||
| test("Generic UDAF aggregates") { | ||
| checkAnswer(sql("SELECT percentile_approx(2, 0.99999), " + |
There was a problem hiding this comment.
Use multiline strings for these tests.
| val distinctAggGroups = aggExpressions | ||
| .filter(_.isDistinct) | ||
| .groupBy(_.aggregateFunction.children.toSet) | ||
| val distinctAggGroups = aggExpressions.filter(_.isDistinct).groupBy{ |
There was a problem hiding this comment.
NIT: Space between groupBy and bracket.
| .groupBy(_.aggregateFunction.children.toSet) | ||
| val distinctAggGroups = aggExpressions.filter(_.isDistinct).groupBy{ | ||
| e => | ||
| if (e.aggregateFunction.children.exists(!_.foldable)) { |
There was a problem hiding this comment.
Just materialize the nonFoldables. Instead of filtering them twice.
| af: AggregateFunction)( | ||
| attrs: Expression => Expression): AggregateFunction = { | ||
| af.withNewChildren(af.children.map(attrs)).asInstanceOf[AggregateFunction] | ||
| def patchAggregateFunctionChildren(af: AggregateFunction)( |
There was a problem hiding this comment.
NIT: Style, please keep this the way it was.
| // count(distinct 1) will be explained to count(1) after the rewrite function. | ||
| // Generally, the distinct aggregateFunction should not run | ||
| // foldable TypeCheck for the first child. | ||
| e.aggregateFunction.children.take(1).toSet |
There was a problem hiding this comment.
This is a good catch. It would be great if we could git rid of this by constant folding (not needed in this PR). Another way of getting rid of this, would be by creating a separate processing group for these distincts.
SparkQA
commented
Nov 7, 2016
Test build #68270 has finished for PR 15668 at commit
|
SparkQA
commented
Nov 7, 2016
Test build #68274 has finished for PR 15668 at commit
|
windpiger
commented
Nov 7, 2016
retest this please |
windpiger
commented
Nov 8, 2016
@cloud-fan@hvanhovell could you please help to retest this? |
cloud-fan
commented
Nov 8, 2016
retest this please |
cloud-fan
commented
Nov 8, 2016
add to whitelist |
| val distinctAggGroups = aggExpressions | ||
| .filter(_.isDistinct) | ||
| .groupBy(_.aggregateFunction.children.toSet) | ||
| val distinctAggGroups = aggExpressions.filter(_.isDistinct).groupBy { |
cloud-fan
commented
Nov 8, 2016
LGTM, pending jenkins |
SparkQA
commented
Nov 8, 2016
Test build #68315 has finished for PR 15668 at commit
|
SparkQA
commented
Nov 8, 2016
Test build #68323 has finished for PR 15668 at commit
|
LGTM. Merging to master/2.1/2.0. Thanks! |
…when a UDAF has a foldable TypeCheck ## What changes were proposed in this pull request? In RewriteDistinctAggregates rewrite funtion,after the UDAF's childs are mapped to AttributeRefference, If the UDAF(such as ApproximatePercentile) has a foldable TypeCheck for the input, It will failed because the AttributeRefference is not foldable,then the UDAF is not resolved, and then nullify on the unresolved object will throw a Exception. In this PR, only map Unfoldable child to AttributeRefference, this can avoid the UDAF's foldable TypeCheck. and then only Expand Unfoldable child, there is no need to Expand a static value(foldable value). **Before sql result** > select percentile_approxy(key,0.99999),count(distinct key),sume(distinc key) from src limit 1 > org.apache.spark.sql.catalyst.analysis.UnresolvedException: Invalid call to dataType on unresolved object, tree: 'percentile_approx(CAST(src.`key` AS DOUBLE), CAST(0.99999BD AS DOUBLE), 10000) > at org.apache.spark.sql.catalyst.analysis.UnresolvedAttribute.dataType(unresolved.scala:92) > at org.apache.spark.sql.catalyst.optimizer.RewriteDistinctAggregates$.org$apache$spark$sql$catalyst$optimizer$RewriteDistinctAggregates$$nullify(RewriteDistinctAggregates.scala:261) **After sql result** > select percentile_approxy(key,0.99999),count(distinct key),sume(distinc key) from src limit 1 > [498.0,309,79136] ## How was this patch tested? Add a test case in HiveUDFSuit. Author: root <root@iZbp1gsnrlfzjxh82cz80vZ.(none)> Closes#15668 from windpiger/RewriteDistinctUDAFUnresolveExcep. (cherry picked from commit c291bd2) Signed-off-by: Herman van Hovell <hvanhovell@databricks.com>
…when a UDAF has a foldable TypeCheck ## What changes were proposed in this pull request? In RewriteDistinctAggregates rewrite funtion,after the UDAF's childs are mapped to AttributeRefference, If the UDAF(such as ApproximatePercentile) has a foldable TypeCheck for the input, It will failed because the AttributeRefference is not foldable,then the UDAF is not resolved, and then nullify on the unresolved object will throw a Exception. In this PR, only map Unfoldable child to AttributeRefference, this can avoid the UDAF's foldable TypeCheck. and then only Expand Unfoldable child, there is no need to Expand a static value(foldable value). **Before sql result** > select percentile_approxy(key,0.99999),count(distinct key),sume(distinc key) from src limit 1 > org.apache.spark.sql.catalyst.analysis.UnresolvedException: Invalid call to dataType on unresolved object, tree: 'percentile_approx(CAST(src.`key` AS DOUBLE), CAST(0.99999BD AS DOUBLE), 10000) > at org.apache.spark.sql.catalyst.analysis.UnresolvedAttribute.dataType(unresolved.scala:92) > at org.apache.spark.sql.catalyst.optimizer.RewriteDistinctAggregates$.org$apache$spark$sql$catalyst$optimizer$RewriteDistinctAggregates$$nullify(RewriteDistinctAggregates.scala:261) **After sql result** > select percentile_approxy(key,0.99999),count(distinct key),sume(distinc key) from src limit 1 > [498.0,309,79136] ## How was this patch tested? Add a test case in HiveUDFSuit. Author: root <root@iZbp1gsnrlfzjxh82cz80vZ.(none)> Closes#15668 from windpiger/RewriteDistinctUDAFUnresolveExcep. (cherry picked from commit c291bd2) Signed-off-by: Herman van Hovell <hvanhovell@databricks.com>
hvanhovell
commented
Nov 8, 2016
@windpiger do you have a JIRA username? So I can credit you on the JIRA. |
windpiger
commented
Nov 8, 2016
@hvanhovell username is Song Jun |
…when a UDAF has a foldable TypeCheck ## What changes were proposed in this pull request? In RewriteDistinctAggregates rewrite funtion,after the UDAF's childs are mapped to AttributeRefference, If the UDAF(such as ApproximatePercentile) has a foldable TypeCheck for the input, It will failed because the AttributeRefference is not foldable,then the UDAF is not resolved, and then nullify on the unresolved object will throw a Exception. In this PR, only map Unfoldable child to AttributeRefference, this can avoid the UDAF's foldable TypeCheck. and then only Expand Unfoldable child, there is no need to Expand a static value(foldable value). **Before sql result** > select percentile_approxy(key,0.99999),count(distinct key),sume(distinc key) from src limit 1 > org.apache.spark.sql.catalyst.analysis.UnresolvedException: Invalid call to dataType on unresolved object, tree: 'percentile_approx(CAST(src.`key` AS DOUBLE), CAST(0.99999BD AS DOUBLE), 10000) > at org.apache.spark.sql.catalyst.analysis.UnresolvedAttribute.dataType(unresolved.scala:92) > at org.apache.spark.sql.catalyst.optimizer.RewriteDistinctAggregates$.org$apache$spark$sql$catalyst$optimizer$RewriteDistinctAggregates$$nullify(RewriteDistinctAggregates.scala:261) **After sql result** > select percentile_approxy(key,0.99999),count(distinct key),sume(distinc key) from src limit 1 > [498.0,309,79136] ## How was this patch tested? Add a test case in HiveUDFSuit. Author: root <root@iZbp1gsnrlfzjxh82cz80vZ.(none)> Closesapache#15668 from windpiger/RewriteDistinctUDAFUnresolveExcep.
What changes were proposed in this pull request?
In RewriteDistinctAggregates rewrite funtion,after the UDAF's childs are mapped to AttributeRefference, If the UDAF(such as ApproximatePercentile) has a foldable TypeCheck for the input, It will failed because the AttributeRefference is not foldable,then the UDAF is not resolved, and then nullify on the unresolved object will throw a Exception.
In this PR, only map Unfoldable child to AttributeRefference, this can avoid the UDAF's foldable TypeCheck. and then only Expand Unfoldable child, there is no need to Expand a static value(foldable value).
Before sql result
After sql result
How was this patch tested?
Add a test case in HiveUDFSuit.