Packages

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 HAVING clause 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.
Linear Supertypes
AnyRef, Any
Ordering
  1. Alphabetic
  2. By Inheritance
Inherited
  1. SubqueryScope
  2. AnyRef
  3. Any
  1. Hide All
  2. Show All
Visibility
  1. Public
  2. Protected

Instance Constructors

  1. 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

  1. final def !=(arg0: Any): Boolean
    Definition Classes
    AnyRef → Any
  2. final def ##: Int
    Definition Classes
    AnyRef → Any
  3. final def ==(arg0: Any): Boolean
    Definition Classes
    AnyRef → Any
  4. def addAliasForOuterAggregateExpression(alias: Alias): Unit

    Add an alias for the outer aggregate expression.

    Add an alias for 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.

  5. val aggregateExpressionsExtractor: Option[GroupingAndAggregateExpressionsExtractor]
  6. final def asInstanceOf[T0]: T0
    Definition Classes
    Any
  7. def clone(): AnyRef
    Attributes
    protected[lang]
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.CloneNotSupportedException]) @IntrinsicCandidate() @native()
  8. final def eq(arg0: AnyRef): Boolean
    Definition Classes
    AnyRef
  9. def equals(arg0: AnyRef): Boolean
    Definition Classes
    AnyRef → Any
  10. final def getClass(): Class[_ <: AnyRef]
    Definition Classes
    AnyRef → Any
    Annotations
    @IntrinsicCandidate() @native()
  11. def getLowerOuterAggregateExpressionAliases: Seq[Alias]

    Get the outer aggregate expression aliased from the lower subquery scope.

  12. def hashCode(): Int
    Definition Classes
    AnyRef → Any
    Annotations
    @IntrinsicCandidate() @native()
  13. final def isInstanceOf[T0]: Boolean
    Definition Classes
    Any
  14. def mergeChildScope(childScope: SubqueryScope): Unit

    Merge childScope by extending our lowerAliasedOuterAggregateExpressions with childScope.outerAliasedAggregateExpressions.

  15. final def ne(arg0: AnyRef): Boolean
    Definition Classes
    AnyRef
  16. final def notify(): Unit
    Definition Classes
    AnyRef
    Annotations
    @IntrinsicCandidate() @native()
  17. final def notifyAll(): Unit
    Definition Classes
    AnyRef
    Annotations
    @IntrinsicCandidate() @native()
  18. final def synchronized[T0](arg0: => T0): T0
    Definition Classes
    AnyRef
  19. def toString(): String
    Definition Classes
    AnyRef → Any
  20. final def wait(arg0: Long, arg1: Int): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.InterruptedException])
  21. final def wait(arg0: Long): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.InterruptedException]) @native()
  22. final def wait(): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.InterruptedException])

Deprecated Value Members

  1. def finalize(): Unit
    Attributes
    protected[lang]
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.Throwable]) @Deprecated
    Deprecated

    (Since version 9)

Inherited from AnyRef

Inherited from Any

Ungrouped