class NameScopeStack extends SQLConfHelper
The NameScopeStack is a stack of NameScopes managed by the Resolver. Usually a top scope is used for name resolution, but in case of correlated subqueries we can lookup names in the parent scopes. Low-level scope creation is managed internally, and only high-level api like withNewScope is available to the resolvers. Freshly-created NameScopeStack contains an empty root NameScope, which in the context of Resolver corresponds to the query output.
- Alphabetic
- By Inheritance
- NameScopeStack
- SQLConfHelper
- AnyRef
- Any
- Hide All
- Show All
- Public
- Protected
Instance Constructors
- new NameScopeStack()
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
- 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()
- def conf: SQLConf
The active config object within the current scope.
The active config object within the current scope. See SQLConf.get for more information.
- Definition Classes
- SQLConfHelper
- 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 hashCode(): Int
- Definition Classes
- AnyRef → Any
- Annotations
- @IntrinsicCandidate() @native()
- final def isInstanceOf[T0]: Boolean
- Definition Classes
- Any
- 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()
- def overwriteTop(output: Seq[Attribute]): Unit
Completely overwrite the top scope state with operator
output.Completely overwrite the top scope state with operator
output.This method is called by the Resolver when we've calculated the output of an operator that is being resolved. The new output is calculated based on the outputs of operator's children.
Example for SubqueryAlias, here we rewrite the top NameScope's attributes to prepend subquery qualifier to their names:
val qualifier = sa.identifier.qualifier :+ sa.alias scope.overwriteTop(scope.output.map(attribute => attribute.withQualifier(qualifier)))
Trivially, we would call this method for every operator in the query plan, however some operators just propagate the output of their children without any changes, so we can omit this call for them (e.g. Filter).
This method should be preferred over withNewScope.
- final def synchronized[T0](arg0: => T0): T0
- Definition Classes
- AnyRef
- def toString(): String
- Definition Classes
- AnyRef → Any
- def top: NameScope
Get the top scope, which is a default choice for name resolution.
- 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])
- def withNewScope[R](body: => R): R
Execute
bodyin a context of a fresh scope.Execute
bodyin a context of a fresh scope.This method is called by the Resolver before recursing into the operator's child resolution _only_ in cases where a fresh scope is required.
For example, Project or Aggregate introduce their own scopes semantically, so that a lower resolution can lookup correlated names:
CREATE TABLE IF NOT EXISTS t1 (col1 INT, col2 STRING); CREATE TABLE IF NOT EXISTS t2 (col1 INT, col2 STRING); -- Here we need a scope for the upper [[Project]], and a separate scope for the correlated -- subquery, because its [[Filter]] need to lookup `t1.col1` from the upper scope. -- Those scopes have to be independent to avoid polluting each other's attributes. SELECT col1, (SELECT col2 FROM t2 WHERE t2.col1 == t1.col1 LIMIT 1) FROM t1;
Also, we need separate scopes for the operators with multiple children, so that the next child's resolution wouldn't try to work with the data from it's sibling's scope, to avoid all kinds of undefined behavior:
val resolvedLeftChild = withNewScope { resolve(unresolvedExcept.left) } // Right child should not see the left child's resolution data to avoid subtle bugs, so we // create a fresh scope here. val resolvedRightChild = withNewScope { resolve(unresolvedExcept.right) }
- def withSQLConf[T](pairs: (String, String)*)(f: => T): T
Sets all SQL configurations specified in
pairs, callsf, and then restores all SQL configurations.Sets all SQL configurations specified in
pairs, callsf, and then restores all SQL configurations.- Attributes
- protected
- Definition Classes
- SQLConfHelper
Deprecated Value Members
- def finalize(): Unit
- Attributes
- protected[lang]
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.Throwable]) @Deprecated
- Deprecated
(Since version 9)