class SubqueryScope extends AnyRef
The SubqueryScope is managed through the whole resolution process of a given SubqueryExpression plan.
The reason why we need this scope is that AggregateExpressions with OuterReferences are handled in a special way. Consider this query:
-- t1.col2 is an outer reference SELECT col1 FROM VALUES (1, 2) t1 GROUP BY col1 HAVING ( SELECT * FROM VALUES (1, 2) t2 WHERE t2.col2 == MAX(t1.col2) )
During the Exists resolution inside the HAVING clause we encounter "t1.col2" name, which is
resolved to an OuterReference. There's an AggregateExpression on top of it. This whole
expression is not local to the subquery, and thus it belongs to an outer Aggregate
operator below the HAVING clause. We need top pull it up outside of the subquery, and insert
it in the Aggregate operator. So the resolution order is as follows:
- Resolve "t1.col2" to an OuterReference in ExpressionResolver.resolveAttribute;
- Resolve the AggregateExpression in AggregateExpressionResolver.resolve;
- Detect an outer reference below the aggregate expression, cut the whole subtree with outer references stripped away, alias it and insert it in this SubqueryScope;
- Replace the aggregate expression with an OuterReference to the AttributeReference from that artificial Alias;
- When the resolution of the SubqueryExpression is finished, SubqueryRegistry.popScope merges the lower scope to the upper one, and all the outer aggregate expression references are appended to the common lowerAliasedOuterAggregateExpressions list.
- Finally, the resolution of the
HAVINGclause can insert the missing aggregate expression into the lower Aggregate operator. During this process we must call ExpressionIdAssigner.mapExpression on the new alias, because this auto-generated alias is new to the query plan, so that ExpressionIdAssigner remembers it.
Notes:
- Spark only supports outer aggregates in the subqueries inside
HAVING; - The subtree under a given AggregateExpression can be arbitrary, but must contain either local or outer references, the mixed set is disallowed.
- We can have several subquery expressions in HAVING clause, that's why we append outer aggregate expressions from lower scopes in mergeChildScope.
- Alphabetic
- By Inheritance
- SubqueryScope
- AnyRef
- Any
- Hide All
- Show All
- Public
- Protected
Instance Constructors
- new SubqueryScope(aggregateExpressionsExtractor: Option[GroupingAndAggregateExpressionsExtractor] = None)
- aggregateExpressionsExtractor
GroupingAndAggregateExpressionsExtractor object defined in case the outer parent operator is a partially resolved HAVING. Used to extract the aggregate expressions from the outer Aggregate operator.
Value Members
- final def !=(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
- final def ##: Int
- Definition Classes
- AnyRef → Any
- final def ==(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
- def addAliasForOuterAggregateExpression(alias: Alias): Unit
Add an
aliasfor the outer aggregate expression.Add an
aliasfor the outer aggregate expression. Alias is either fetched from the outer Aggregate or auto-generated and will be later inserted into the outer Aggregate operator. - val aggregateExpressionsExtractor: Option[GroupingAndAggregateExpressionsExtractor]
- final def asInstanceOf[T0]: T0
- Definition Classes
- Any
- def clone(): AnyRef
- Attributes
- protected[lang]
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.CloneNotSupportedException]) @IntrinsicCandidate() @native()
- final def eq(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef
- def equals(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef → Any
- final def getClass(): Class[_ <: AnyRef]
- Definition Classes
- AnyRef → Any
- Annotations
- @IntrinsicCandidate() @native()
- def getLowerOuterAggregateExpressionAliases: Seq[Alias]
Get the outer aggregate expression aliased from the lower subquery scope.
- def hashCode(): Int
- Definition Classes
- AnyRef → Any
- Annotations
- @IntrinsicCandidate() @native()
- final def isInstanceOf[T0]: Boolean
- Definition Classes
- Any
- def mergeChildScope(childScope: SubqueryScope): Unit
Merge
childScopeby extending ourlowerAliasedOuterAggregateExpressionswithchildScope.outerAliasedAggregateExpressions. - final def ne(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef
- final def notify(): Unit
- Definition Classes
- AnyRef
- Annotations
- @IntrinsicCandidate() @native()
- final def notifyAll(): Unit
- Definition Classes
- AnyRef
- Annotations
- @IntrinsicCandidate() @native()
- final def synchronized[T0](arg0: => T0): T0
- Definition Classes
- AnyRef
- def toString(): String
- Definition Classes
- AnyRef → Any
- final def wait(arg0: Long, arg1: Int): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.InterruptedException])
- final def wait(arg0: Long): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.InterruptedException]) @native()
- final def wait(): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.InterruptedException])
Deprecated Value Members
- def finalize(): Unit
- Attributes
- protected[lang]
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.Throwable]) @Deprecated
- Deprecated
(Since version 9)