Github user dilipbiswal commented on a diff in the pull request:
https://github.com/apache/spark/pull/16954#discussion_r103363171
--- Diff:
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/subquery.scala
---
@@ -40,19 +42,179 @@ abstract class PlanExpression[T <: QueryPlan[_]]
extends Expression {
/**
* A base interface for expressions that contain a [[LogicalPlan]].
*/
-abstract class SubqueryExpression extends PlanExpression[LogicalPlan] {
+abstract class SubqueryExpression(
+ plan: LogicalPlan,
+ children: Seq[Expression],
+ exprId: ExprId) extends PlanExpression[LogicalPlan] {
+
+ override lazy val resolved: Boolean = childrenResolved && plan.resolved
+ override lazy val references: AttributeSet =
+ if (plan.resolved) super.references -- plan.outputSet else
super.references
override def withNewPlan(plan: LogicalPlan): SubqueryExpression
+ override def semanticEquals(o: Expression): Boolean = o match {
+ case p: SubqueryExpression =>
+ this.getClass.getName.equals(p.getClass.getName) &&
plan.sameResult(p.plan) &&
+ children.length == p.children.length &&
+ children.zip(p.children).forall(p => p._1.semanticEquals(p._2))
+ case _ => false
+ }
}
object SubqueryExpression {
+ /**
+ * Returns true when an expression contains an IN or EXISTS subquery and
false otherwise.
+ */
+ def hasInOrExistsSubquery(e: Expression): Boolean = {
+ e.find {
+ case _: ListQuery | _: Exists => true
+ case _ => false
+ }.isDefined
+ }
+
+ /**
+ * Returns true when an expression contains a subquery that has outer
reference(s). The outer
+ * reference attributes are kept as children of subquery expression by
+ * [[org.apache.spark.sql.catalyst.analysis.Analyzer.ResolveSubquery]]
+ */
def hasCorrelatedSubquery(e: Expression): Boolean = {
e.find {
- case e: SubqueryExpression if e.children.nonEmpty => true
+ case s: SubqueryExpression if s.children.nonEmpty => true
case _ => false
}.isDefined
}
}
+object SubExprUtils extends PredicateHelper {
+ /**
+ * Returns true when an expression contains correlated predicates i.e
outer references and
+ * returns false otherwise.
+ */
+ def containsOuter(e: Expression): Boolean = {
+ e.find(_.isInstanceOf[OuterReference]).isDefined
+ }
+
+ /**
+ * Returns whether there are any null-aware predicate subqueries inside
Not. If not, we could
+ * turn the null-aware predicate into not-null-aware predicate.
+ */
+ def hasNullAwarePredicateWithinNot(e: Expression): Boolean = {
+ e.find{ x =>
+ x.isInstanceOf[Not] && e.find {
--- End diff --
@hvanhovell Actually I copied this function from existing
PredicateSubquery.hasNullAwarePredicateWithinNot. I also found it a little odd
that we are doing a e.find .. but was afraid to change this.
---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at [email protected] or file a JIRA ticket
with INFRA.
---
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]