@@ -602,7 +602,7 @@ class Analyzer(
602602 }
603603
604604 private def tryResolveHavingCondition (
605- a : UnresolvedHaving , havingCond : Expression , agg : LogicalPlan ): LogicalPlan = {
605+ a : UnresolvedHaving , agg : LogicalPlan ): LogicalPlan = {
606606 val aggForResolving = agg match {
607607 // For CUBE/ROLLUP expressions, to avoid resolving repeatedly, here we delete them from
608608 // groupingExpressions for condition resolving.
@@ -616,11 +616,12 @@ class Analyzer(
616616 g.aggregations, g.child)
617617 }
618618 // Try resolving the condition of the filter as though it is in the aggregate clause
619- val (extraAggExprs, resolvedHavingCond) =
620- ResolveAggregateFunctions .resolveFilterCondInAggregate(havingCond , aggForResolving)
619+ val resolvedInfo =
620+ ResolveAggregateFunctions .resolveFilterCondInAggregate(a.havingCondition , aggForResolving)
621621
622622 // Push the aggregate expressions into the aggregate (if any).
623- if (extraAggExprs.nonEmpty) {
623+ if (resolvedInfo.nonEmpty) {
624+ val (extraAggExprs, resolvedHavingCond) = resolvedInfo.get
624625 val newChild = agg match {
625626 case Aggregate (Seq (c @ Cube (groupByExprs)), aggregateExpressions, child) =>
626627 constructAggregate(
@@ -639,7 +640,7 @@ class Analyzer(
639640 val exprMap = extraAggExprs.zip(
640641 newChild.asInstanceOf [Aggregate ].aggregateExpressions.takeRight(
641642 extraAggExprs.length)).toMap
642- val newCond = resolvedHavingCond.get. transform {
643+ val newCond = resolvedHavingCond.transform {
643644 case ne : NamedExpression if exprMap.contains(ne) => exprMap(ne)
644645 }
645646 Project (newChild.output.dropRight(extraAggExprs.length),
@@ -654,19 +655,16 @@ class Analyzer(
654655 // Filter/Sort.
655656 def apply (plan : LogicalPlan ): LogicalPlan = plan resolveOperatorsDown {
656657 case a @ UnresolvedHaving (
657- havingCondition, agg @ Aggregate (Seq (c @ Cube (groupByExprs)), aggregateExpressions, _))
658- if agg.childrenResolved && ! havingCondition.isInstanceOf [SubqueryExpression ]
659- && (groupByExprs ++ aggregateExpressions).forall(_.resolved) =>
660- tryResolveHavingCondition(a, havingCondition, agg)
658+ _, agg @ Aggregate (Seq (c @ Cube (groupByExprs)), aggregateExpressions, _))
659+ if agg.childrenResolved && (groupByExprs ++ aggregateExpressions).forall(_.resolved) =>
660+ tryResolveHavingCondition(a, agg)
661661 case a @ UnresolvedHaving (
662- havingCondition, agg @ Aggregate (Seq (r @ Rollup (groupByExprs)), aggregateExpressions, _))
663- if agg.childrenResolved && ! havingCondition.isInstanceOf [SubqueryExpression ]
664- && (groupByExprs ++ aggregateExpressions).forall(_.resolved) =>
665- tryResolveHavingCondition(a, havingCondition, agg)
666- case a @ UnresolvedHaving (havingCondition, g : GroupingSets )
667- if g.childrenResolved && ! havingCondition.isInstanceOf [SubqueryExpression ]
668- && g.expressions.forall(_.resolved) =>
669- tryResolveHavingCondition(a, havingCondition, g)
662+ _, agg @ Aggregate (Seq (r @ Rollup (groupByExprs)), aggregateExpressions, _))
663+ if agg.childrenResolved && (groupByExprs ++ aggregateExpressions).forall(_.resolved) =>
664+ tryResolveHavingCondition(a, agg)
665+ case a @ UnresolvedHaving (_, g : GroupingSets )
666+ if g.childrenResolved && g.expressions.forall(_.resolved) =>
667+ tryResolveHavingCondition(a, g)
670668
671669 case a if ! a.childrenResolved => a // be sure all of the children are resolved.
672670
@@ -2197,8 +2195,7 @@ class Analyzer(
21972195 }
21982196
21992197 def resolveFilterCondInAggregate (
2200- filterCond : Expression , agg : Aggregate ): (Seq [NamedExpression ], Option [Expression ]) = {
2201- val aggregateExpressions = ArrayBuffer .empty[NamedExpression ]
2198+ filterCond : Expression , agg : Aggregate ): Option [(Seq [NamedExpression ], Expression )] = {
22022199 try {
22032200 val aggregatedCondition =
22042201 Aggregate (
@@ -2235,26 +2232,30 @@ class Analyzer(
22352232 alias.toAttribute
22362233 }
22372234 }
2238- (aggregateExpressions, Some (transformedAggregateFilter))
2235+ if (aggregateExpressions.nonEmpty) {
2236+ Some (aggregateExpressions, transformedAggregateFilter)
2237+ } else {
2238+ None
2239+ }
22392240 } else {
2240- (aggregateExpressions, None )
2241+ None
22412242 }
22422243 } catch {
22432244 // Attempting to resolve in the aggregate can result in ambiguity. When this happens,
22442245 // just return the original plan.
2245- case ae : AnalysisException => (aggregateExpressions, None )
2246+ case ae : AnalysisException => None
22462247 }
22472248 }
22482249
22492250 def resolveHaving (filter : Filter , agg : Aggregate ): LogicalPlan = {
22502251 // Try resolving the condition of the filter as though it is in the aggregate clause
2251- val (aggregateExpressions, resolvedHavingCond) =
2252- resolveFilterCondInAggregate(filter.condition, agg)
2252+ val resolvedInfo = resolveFilterCondInAggregate(filter.condition, agg)
22532253
22542254 // Push the aggregate expressions into the aggregate (if any).
2255- if (aggregateExpressions.nonEmpty) {
2255+ if (resolvedInfo.nonEmpty) {
2256+ val (aggregateExpressions, resolvedHavingCond) = resolvedInfo.get
22562257 Project (agg.output,
2257- Filter (resolvedHavingCond.get ,
2258+ Filter (resolvedHavingCond,
22582259 agg.copy(aggregateExpressions = agg.aggregateExpressions ++ aggregateExpressions)))
22592260 } else {
22602261 filter
0 commit comments