@@ -645,9 +645,14 @@ class Analyzer(
645
645
646
646
/**
647
647
* From a Seq of [[NamedExpression ]]s, extract expressions containing window expressions and
648
- * other regular expressions that do not contain any window expression.
648
+ * other regular expressions that do not contain any window expression. For example, for
649
+ * `col1, Sum(col2 + col3) OVER (PARTITION BY col4 ORDER BY col5)`, we will extract
650
+ * `col1`, `col2 + col3`, `col4`, and `col5` out and replace them appearances in
651
+ * the window expression as attribute references. So, the first returned value will be
652
+ * `[Sum(_w0) OVER (PARTITION BY _w1 ORDER BY _w2)]` and the second returned value will be
653
+ * [col1, col2 + col3 as _w0, col4 as _w1, col5 as _w2].
649
654
*/
650
- private def extractRegularExpressions (
655
+ private def extract (
651
656
expressions : Seq [NamedExpression ]): (Seq [NamedExpression ], Seq [NamedExpression ]) = {
652
657
// First, we partition the input expressions to two part. For the first part,
653
658
// every expression in it contain at least one WindowExpression.
@@ -662,8 +667,8 @@ class Analyzer(
662
667
val extractedExprBuffer = new ArrayBuffer [NamedExpression ]()
663
668
def extractExpr (expr : Expression ): Expression = expr match {
664
669
case ne : NamedExpression =>
665
- // If a named expression is not in regularExpressions, add extract it and replace it
666
- // with an AttributeReference.
670
+ // If a named expression is not in regularExpressions, add it to
671
+ // extractedExprBuffer and replace it with an AttributeReference.
667
672
val missingExpr =
668
673
AttributeSet (Seq (expr)) -- (regularExpressions ++ extractedExprBuffer)
669
674
if (missingExpr.nonEmpty) {
@@ -709,7 +714,7 @@ class Analyzer(
709
714
}
710
715
711
716
(newExpressionsWithWindowFunctions, regularExpressions ++ extractedExprBuffer)
712
- } // end of extractRegularExpressions
717
+ } // end of extract
713
718
714
719
/**
715
720
* Adds operators for Window Expressions. Every Window operator handles a single Window Spec.
@@ -756,6 +761,8 @@ class Analyzer(
756
761
if (distinctWindowSpec.length == 0 ) {
757
762
failAnalysis(s " $expr does not have any WindowExpression. " )
758
763
} else if (distinctWindowSpec.length > 1 ) {
764
+ // newExpressionsWithWindowFunctions only have expressions with a single
765
+ // WindowExpression. If we reach here, we have a bug.
759
766
failAnalysis(s " $expr has multiple Window Specifications ( $distinctWindowSpec). " +
760
767
s " Please file a bug report with this error message, stack trace, and the query. " )
761
768
} else {
@@ -790,7 +797,7 @@ class Analyzer(
790
797
if child.resolved &&
791
798
hasWindowFunction(aggregateExprs) &&
792
799
a.expressions.forall(_.resolved) =>
793
- val (windowExpressions, aggregateExpressions) = extractRegularExpressions (aggregateExprs)
800
+ val (windowExpressions, aggregateExpressions) = extract (aggregateExprs)
794
801
// Create an Aggregate operator to evaluate aggregation functions.
795
802
val withAggregate = Aggregate (groupingExprs, aggregateExpressions, child)
796
803
// Add a Filter operator for conditions in the Having clause.
@@ -807,7 +814,7 @@ class Analyzer(
807
814
case a @ Aggregate (groupingExprs, aggregateExprs, child)
808
815
if hasWindowFunction(aggregateExprs) &&
809
816
a.expressions.forall(_.resolved) =>
810
- val (windowExpressions, aggregateExpressions) = extractRegularExpressions (aggregateExprs)
817
+ val (windowExpressions, aggregateExpressions) = extract (aggregateExprs)
811
818
// Create an Aggregate operator to evaluate aggregation functions.
812
819
val withAggregate = Aggregate (groupingExprs, aggregateExpressions, child)
813
820
// Add Window operators.
@@ -821,7 +828,7 @@ class Analyzer(
821
828
// have been resolved.
822
829
case p @ Project (projectList, child)
823
830
if hasWindowFunction(projectList) && ! p.expressions.exists(! _.resolved) =>
824
- val (windowExpressions, regularExpressions) = extractRegularExpressions (projectList)
831
+ val (windowExpressions, regularExpressions) = extract (projectList)
825
832
// We add a project to get all needed expressions for window expressions from the child
826
833
// of the original Project operator.
827
834
val withProject = Project (regularExpressions, child)
0 commit comments