This is an automated email from the ASF dual-hosted git repository.
wenchen pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/spark.git
The following commit(s) were added to refs/heads/master by this push:
new 4fd2d6807bf [SPARK-45009][SQL] Decorrelate predicate subqueries in
join condition
4fd2d6807bf is described below
commit 4fd2d6807bffdfe015b95398aa2206b3145ce598
Author: Andy Lam <[email protected]>
AuthorDate: Mon Oct 16 11:40:16 2023 +0800
[SPARK-45009][SQL] Decorrelate predicate subqueries in join condition
### What changes were proposed in this pull request?
Pulling up correlated subquery predicates in Joins, and re-writing them
into ExistenceJoins if they are not pushed down into the join inputs.
### Why are the changes needed?
This change allows correlated IN and EXISTS subqueries in join condition.
This is valid SQL that is not yet supported by Spark SQL.
### Does this PR introduce _any_ user-facing change?
Yes, previously unsupported queries become supported.
### How was this patch tested?
Added SQL tests for IN and EXISTS in join conditions, and crossed-check
correctness with postgres (except for ANTI joins, which are not supported in
postgres).
Permutations of the tests:
1. Exists / Not exists / in / not in
2. Subquery references left child / right child
3. Join type: inner / left outer
4. Transitive predicates to try invoking filter inference
Closes #42725 from andylam-db/correlated-subquery-in-join-cond.
Authored-by: Andy Lam <[email protected]>
Signed-off-by: Wenchen Fan <[email protected]>
---
.../spark/sql/catalyst/optimizer/Optimizer.scala | 3 +-
.../spark/sql/catalyst/optimizer/subquery.scala | 68 ++
.../spark/sql/errors/QueryCompilationErrors.scala | 9 +
.../org/apache/spark/sql/internal/SQLConf.scala | 19 +
.../exists-in-join-condition.sql.out | 1006 ++++++++++++++++++++
.../subquery/in-subquery/in-null-semantics.sql.out | 46 +
.../in-subquery-in-join-condition.sql.out | 918 ++++++++++++++++++
.../exists-subquery/exists-in-join-condition.sql | 90 ++
.../subquery/in-subquery/in-null-semantics.sql | 9 +-
.../in-subquery/in-subquery-in-join-condition.sql | 85 ++
.../exists-in-join-condition.sql.out | 474 +++++++++
.../subquery/in-subquery/in-null-semantics.sql.out | 42 +
.../in-subquery-in-join-condition.sql.out | 436 +++++++++
13 files changed, 3203 insertions(+), 2 deletions(-)
diff --git
a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/optimizer/Optimizer.scala
b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/optimizer/Optimizer.scala
index f83cd36f0a8..6f65afada17 100644
---
a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/optimizer/Optimizer.scala
+++
b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/optimizer/Optimizer.scala
@@ -55,7 +55,8 @@ abstract class Optimizer(catalogManager: CatalogManager)
Set(
"PartitionPruning",
"RewriteSubquery",
- "Extract Python UDFs")
+ "Extract Python UDFs",
+ "Infer Filters")
protected def fixedPoint =
FixedPoint(
diff --git
a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/optimizer/subquery.scala
b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/optimizer/subquery.scala
index 08cbd29b20f..5b95ee1df1b 100644
---
a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/optimizer/subquery.scala
+++
b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/optimizer/subquery.scala
@@ -33,6 +33,7 @@ import org.apache.spark.sql.catalyst.rules._
import org.apache.spark.sql.catalyst.trees.TreePattern.{EXISTS_SUBQUERY,
IN_SUBQUERY, LATERAL_JOIN, LIST_SUBQUERY, PLAN_EXPRESSION, SCALAR_SUBQUERY}
import org.apache.spark.sql.errors.{QueryCompilationErrors,
QueryExecutionErrors}
import org.apache.spark.sql.internal.SQLConf
+import
org.apache.spark.sql.internal.SQLConf.{DECORRELATE_PREDICATE_SUBQUERIES_IN_JOIN_CONDITION,
OPTIMIZE_UNCORRELATED_IN_SUBQUERIES_IN_JOIN_CONDITION}
import org.apache.spark.sql.types._
import org.apache.spark.util.Utils
@@ -176,6 +177,71 @@ object RewritePredicateSubquery extends Rule[LogicalPlan]
with PredicateHelper {
Project(p.output, Filter(newCond.get, inputPlan))
}
+ // This case takes care of predicate subqueries in join conditions that
are not pushed down
+ // to the children nodes by [[PushDownPredicates]].
+ case j: Join if j.condition.exists(cond =>
+ SubqueryExpression.hasInOrCorrelatedExistsSubquery(cond)) &&
+ conf.getConf(DECORRELATE_PREDICATE_SUBQUERIES_IN_JOIN_CONDITION) =>
+
+ val optimizeUncorrelatedInSubqueries =
+ conf.getConf(OPTIMIZE_UNCORRELATED_IN_SUBQUERIES_IN_JOIN_CONDITION)
+ val relevantSubqueries = j.condition.get.collect {
+ case i: InSubquery if i.query.isCorrelated => i
+ case i: InSubquery if !i.query.isCorrelated &&
optimizeUncorrelatedInSubqueries => i
+ case e: Exists if e.isCorrelated => e
+ }
+ if (relevantSubqueries.isEmpty) {
+ j
+ } else {
+ // `subqueriesWithJoinInputReferenceInfo`is of type Seq[(Expression,
Boolean, Boolean)]
+ // (1): Expression, the join predicate containing some predicate
subquery we are interested
+ // in re-writing
+ // (2): Boolean, whether (1) references the left join input
+ // (3): Boolean, whether (1) references the right join input
+ val subqueriesWithJoinInputReferenceInfo = relevantSubqueries.map { e
=>
+ val referenceLeft = e.references.intersect(j.left.outputSet).nonEmpty
+ val referenceRight =
e.references.intersect(j.right.outputSet).nonEmpty
+ (e, referenceLeft, referenceRight)
+ }
+ val subqueriesReferencingBothJoinInputs =
subqueriesWithJoinInputReferenceInfo
+ .filter(i => i._2 && i._3)
+
+ // Currently do not support correlated subqueries in the join
predicate that reference both
+ // join inputs
+ if (subqueriesReferencingBothJoinInputs.nonEmpty) {
+ throw
QueryCompilationErrors.unsupportedCorrelatedSubqueryInJoinConditionError(
+ subqueriesReferencingBothJoinInputs.map(_._1))
+ }
+ val subqueriesReferencingLeft =
subqueriesWithJoinInputReferenceInfo.filter(_._2).map(_._1)
+ val subqueriesReferencingRight =
subqueriesWithJoinInputReferenceInfo.filter(_._3).map(_._1)
+ if (subqueriesReferencingLeft.isEmpty &&
subqueriesReferencingRight.isEmpty) {
+ j
+ } else {
+ var newCondition = j.condition.get
+ val newLeft = subqueriesReferencingLeft.foldLeft(j.left) {
+ case (p, e) =>
+ val (newCond, newInputPlan) = rewriteExistentialExpr(Seq(e), p)
+ // Update the join condition to rewrite the subquery expression
+ newCondition = newCondition.transform {
+ case expr if expr.fastEquals(e) => newCond.get
+ }
+ newInputPlan
+ }
+ val newRight = subqueriesReferencingRight.foldLeft(j.right) {
+ case (p, e) =>
+ val (newCond, newInputPlan) = rewriteExistentialExpr(Seq(e), p)
+ // Update the join condition to rewrite the subquery expression
+ newCondition = newCondition.transform {
+ case expr if expr.fastEquals(e) => newCond.get
+ }
+ newInputPlan
+ }
+ // Remove unwanted exists columns from new existence joins with new
Project
+ Project(j.output, j.copy(left = newLeft, right = newRight,
+ condition = Some(newCondition)))
+ }
+ }
+
case u: UnaryNode if u.expressions.exists(
SubqueryExpression.hasInOrCorrelatedExistsSubquery) =>
var newChild = u.child
@@ -410,6 +476,8 @@ object PullupCorrelatedPredicates extends Rule[LogicalPlan]
with PredicateHelper
} else {
newPlan
}
+ case j: Join if
conf.getConf(DECORRELATE_PREDICATE_SUBQUERIES_IN_JOIN_CONDITION) =>
+ rewriteSubQueries(j)
// Only a few unary nodes (Project/Filter/Aggregate) can contain
subqueries.
case q: UnaryNode =>
rewriteSubQueries(q)
diff --git
a/sql/catalyst/src/main/scala/org/apache/spark/sql/errors/QueryCompilationErrors.scala
b/sql/catalyst/src/main/scala/org/apache/spark/sql/errors/QueryCompilationErrors.scala
index 2f2341ab47f..5dfdd7757ad 100644
---
a/sql/catalyst/src/main/scala/org/apache/spark/sql/errors/QueryCompilationErrors.scala
+++
b/sql/catalyst/src/main/scala/org/apache/spark/sql/errors/QueryCompilationErrors.scala
@@ -2099,6 +2099,15 @@ private[sql] object QueryCompilationErrors extends
QueryErrorsBase with Compilat
messageParameters = Map("expr" -> expr.sql, "dataType" ->
dataType.typeName))
}
+ def unsupportedCorrelatedSubqueryInJoinConditionError(
+ unsupportedSubqueryExpressions: Seq[Expression]): Throwable = {
+ new AnalysisException(
+ errorClass = "UNSUPPORTED_SUBQUERY_EXPRESSION_CATEGORY." +
+ "UNSUPPORTED_CORRELATED_EXPRESSION_IN_JOIN_CONDITION",
+ messageParameters = Map("subqueryExpression" ->
+ unsupportedSubqueryExpressions.map(_.sql).mkString(", ")))
+ }
+
def functionCannotProcessInputError(
unbound: UnboundFunction,
arguments: Seq[Expression],
diff --git
a/sql/catalyst/src/main/scala/org/apache/spark/sql/internal/SQLConf.scala
b/sql/catalyst/src/main/scala/org/apache/spark/sql/internal/SQLConf.scala
index 000694f6f1b..9fd70692c06 100644
--- a/sql/catalyst/src/main/scala/org/apache/spark/sql/internal/SQLConf.scala
+++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/internal/SQLConf.scala
@@ -4455,6 +4455,25 @@ object SQLConf {
.booleanConf
.createWithDefault(true)
+ val DECORRELATE_PREDICATE_SUBQUERIES_IN_JOIN_CONDITION =
+
buildConf("spark.sql.optimizer.decorrelatePredicateSubqueriesInJoinPredicate.enabled")
+ .internal()
+ .doc("Decorrelate predicate (in and exists) subqueries with correlated
references in join " +
+ "predicates.")
+ .version("4.0.0")
+ .booleanConf
+ .createWithDefault(true)
+
+ val OPTIMIZE_UNCORRELATED_IN_SUBQUERIES_IN_JOIN_CONDITION =
+
buildConf("spark.sql.optimizer.optimizeUncorrelatedInSubqueriesInJoinCondition.enabled")
+ .internal()
+ .doc("When true, optimize uncorrelated IN subqueries in join predicates
by rewriting them " +
+ s"to joins. This interacts with
${LEGACY_NULL_IN_EMPTY_LIST_BEHAVIOR.key} because it " +
+ "can rewrite IN predicates.")
+ .version("4.0.0")
+ .booleanConf
+ .createWithDefault(true)
+
val LEGACY_PERCENTILE_DISC_CALCULATION =
buildConf("spark.sql.legacy.percentileDiscCalculation")
.internal()
.doc("If true, the old bogus percentile_disc calculation is used. The old
calculation " +
diff --git
a/sql/core/src/test/resources/sql-tests/analyzer-results/subquery/exists-subquery/exists-in-join-condition.sql.out
b/sql/core/src/test/resources/sql-tests/analyzer-results/subquery/exists-subquery/exists-in-join-condition.sql.out
new file mode 100644
index 00000000000..035bbf9ec60
--- /dev/null
+++
b/sql/core/src/test/resources/sql-tests/analyzer-results/subquery/exists-subquery/exists-in-join-condition.sql.out
@@ -0,0 +1,1006 @@
+-- Automatically generated by SQLQueryTestSuite
+-- !query
+CREATE TEMP VIEW x(x1, x2) AS VALUES
+ (2, 1),
+ (1, 1),
+ (3, 4)
+-- !query analysis
+CreateViewCommand `x`, [(x1,None), (x2,None)], VALUES
+ (2, 1),
+ (1, 1),
+ (3, 4), false, false, LocalTempView, true
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+CREATE TEMP VIEW y(y1, y2) AS VALUES
+ (0, 2),
+ (1, 4),
+ (4, 11)
+-- !query analysis
+CreateViewCommand `y`, [(y1,None), (y2,None)], VALUES
+ (0, 2),
+ (1, 4),
+ (4, 11), false, false, LocalTempView, true
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+CREATE TEMP VIEW z(z1, z2) AS VALUES
+ (4, 2),
+ (3, 3),
+ (8, 1)
+-- !query analysis
+CreateViewCommand `z`, [(z1,None), (z2,None)], VALUES
+ (4, 2),
+ (3, 3),
+ (8, 1), false, false, LocalTempView, true
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x inner join y on x1 = y1 and exists (select * from z where z2 =
x2) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join Inner, ((x1#x = y1#x) AND exists#x [x2#x])
+ : +- Project [z1#x, z2#x]
+ : +- Filter (z2#x = outer(x2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x inner join y on x1 = y1 and not exists (select * from z where
z2 = x2) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join Inner, ((x1#x = y1#x) AND NOT exists#x [x2#x])
+ : +- Project [z1#x, z2#x]
+ : +- Filter (z2#x = outer(x2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x inner join y on x1 = y1 and exists (select * from z where z2 =
y2) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join Inner, ((x1#x = y1#x) AND exists#x [y2#x])
+ : +- Project [z1#x, z2#x]
+ : +- Filter (z2#x = outer(y2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x inner join y on x1 = y1 and not exists (select * from z where
z2 = y2) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join Inner, ((x1#x = y1#x) AND NOT exists#x [y2#x])
+ : +- Project [z1#x, z2#x]
+ : +- Filter (z2#x = outer(y2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x left join y on x1 = y1 and exists (select * from z where z2 =
x2) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join LeftOuter, ((x1#x = y1#x) AND exists#x [x2#x])
+ : +- Project [z1#x, z2#x]
+ : +- Filter (z2#x = outer(x2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x left join y on x1 = y1 and not exists (select * from z where
z2 = x2) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join LeftOuter, ((x1#x = y1#x) AND NOT exists#x [x2#x])
+ : +- Project [z1#x, z2#x]
+ : +- Filter (z2#x = outer(x2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x left join y on x1 = y1 and exists (select * from z where z2 =
y2) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join LeftOuter, ((x1#x = y1#x) AND exists#x [y2#x])
+ : +- Project [z1#x, z2#x]
+ : +- Filter (z2#x = outer(y2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x left join y on x1 = y1 and not exists (select * from z where
z2 = y2) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join LeftOuter, ((x1#x = y1#x) AND NOT exists#x [y2#x])
+ : +- Project [z1#x, z2#x]
+ : +- Filter (z2#x = outer(y2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x right join y on x1 = y1 and exists (select * from z where z2 =
x2) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join RightOuter, ((x1#x = y1#x) AND exists#x [x2#x])
+ : +- Project [z1#x, z2#x]
+ : +- Filter (z2#x = outer(x2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x right join y on x1 = y1 and not exists (select * from z where
z2 = x2) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join RightOuter, ((x1#x = y1#x) AND NOT exists#x [x2#x])
+ : +- Project [z1#x, z2#x]
+ : +- Filter (z2#x = outer(x2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x right join y on x1 = y1 and exists (select * from z where z2 =
y2) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join RightOuter, ((x1#x = y1#x) AND exists#x [y2#x])
+ : +- Project [z1#x, z2#x]
+ : +- Filter (z2#x = outer(y2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x right join y on x1 = y1 and not exists (select * from z where
z2 = y2) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join RightOuter, ((x1#x = y1#x) AND NOT exists#x [y2#x])
+ : +- Project [z1#x, z2#x]
+ : +- Filter (z2#x = outer(y2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x right join y on x1 = y1 and exists (select * from z where z2 =
x2) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join RightOuter, ((x1#x = y1#x) AND exists#x [x2#x])
+ : +- Project [z1#x, z2#x]
+ : +- Filter (z2#x = outer(x2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x right join y on x1 = y1 and not exists (select * from z where
z2 = x2) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join RightOuter, ((x1#x = y1#x) AND NOT exists#x [x2#x])
+ : +- Project [z1#x, z2#x]
+ : +- Filter (z2#x = outer(x2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x right join y on x1 = y1 and exists (select * from z where z2 =
y2) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join RightOuter, ((x1#x = y1#x) AND exists#x [y2#x])
+ : +- Project [z1#x, z2#x]
+ : +- Filter (z2#x = outer(y2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x right join y on x1 = y1 and not exists (select * from z where
z2 = y2) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join RightOuter, ((x1#x = y1#x) AND NOT exists#x [y2#x])
+ : +- Project [z1#x, z2#x]
+ : +- Filter (z2#x = outer(y2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x left semi join y on x1 = y1 and exists (select * from z where
z2 = x2) order by x1, x2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST], true
++- Project [x1#x, x2#x]
+ +- Join LeftSemi, ((x1#x = y1#x) AND exists#x [x2#x])
+ : +- Project [z1#x, z2#x]
+ : +- Filter (z2#x = outer(x2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x left semi join y on x1 = y1 and not exists (select * from z
where z2 = x2) order by x1, x2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST], true
++- Project [x1#x, x2#x]
+ +- Join LeftSemi, ((x1#x = y1#x) AND NOT exists#x [x2#x])
+ : +- Project [z1#x, z2#x]
+ : +- Filter (z2#x = outer(x2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x left semi join y on x1 = y1 and exists (select * from z where
z2 = y2) order by x1, x2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST], true
++- Project [x1#x, x2#x]
+ +- Join LeftSemi, ((x1#x = y1#x) AND exists#x [y2#x])
+ : +- Project [z1#x, z2#x]
+ : +- Filter (z2#x = outer(y2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x left semi join y on x1 = y1 and not exists (select * from z
where z2 = y2) order by x1, x2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST], true
++- Project [x1#x, x2#x]
+ +- Join LeftSemi, ((x1#x = y1#x) AND NOT exists#x [y2#x])
+ : +- Project [z1#x, z2#x]
+ : +- Filter (z2#x = outer(y2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x left anti join y on x1 = y1 and exists (select * from z where
z2 = x2) order by x1, x2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST], true
++- Project [x1#x, x2#x]
+ +- Join LeftAnti, ((x1#x = y1#x) AND exists#x [x2#x])
+ : +- Project [z1#x, z2#x]
+ : +- Filter (z2#x = outer(x2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x left anti join y on x1 = y1 and not exists (select * from z
where z2 = x2) order by x1, x2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST], true
++- Project [x1#x, x2#x]
+ +- Join LeftAnti, ((x1#x = y1#x) AND NOT exists#x [x2#x])
+ : +- Project [z1#x, z2#x]
+ : +- Filter (z2#x = outer(x2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x left anti join y on x1 = y1 and exists (select * from z where
z2 = y2) order by x1, x2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST], true
++- Project [x1#x, x2#x]
+ +- Join LeftAnti, ((x1#x = y1#x) AND exists#x [y2#x])
+ : +- Project [z1#x, z2#x]
+ : +- Filter (z2#x = outer(y2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x left anti join y on x1 = y1 and not exists (select * from z
where z2 = y2) order by x1, x2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST], true
++- Project [x1#x, x2#x]
+ +- Join LeftAnti, ((x1#x = y1#x) AND NOT exists#x [y2#x])
+ : +- Project [z1#x, z2#x]
+ : +- Filter (z2#x = outer(y2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x full outer join y on x1 = y1 and exists (select * from z where
z2 = x2) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join FullOuter, ((x1#x = y1#x) AND exists#x [x2#x])
+ : +- Project [z1#x, z2#x]
+ : +- Filter (z2#x = outer(x2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x full outer join y on x1 = y1 and not exists (select * from z
where z2 = x2) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join FullOuter, ((x1#x = y1#x) AND NOT exists#x [x2#x])
+ : +- Project [z1#x, z2#x]
+ : +- Filter (z2#x = outer(x2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x full outer join y on x1 = y1 and exists (select * from z where
z2 = y2) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join FullOuter, ((x1#x = y1#x) AND exists#x [y2#x])
+ : +- Project [z1#x, z2#x]
+ : +- Filter (z2#x = outer(y2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x full outer join y on x1 = y1 and not exists (select * from z
where z2 = y2) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join FullOuter, ((x1#x = y1#x) AND NOT exists#x [y2#x])
+ : +- Project [z1#x, z2#x]
+ : +- Filter (z2#x = outer(y2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x inner join y on x1 = y1 or exists (select * from z where z1 =
x1) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join Inner, ((x1#x = y1#x) OR exists#x [x1#x])
+ : +- Project [z1#x, z2#x]
+ : +- Filter (z1#x = outer(x1#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x inner join y on x1 = y1 or not exists (select * from z where
z1 = x1) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join Inner, ((x1#x = y1#x) OR NOT exists#x [x1#x])
+ : +- Project [z1#x, z2#x]
+ : +- Filter (z1#x = outer(x1#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x left join y on x1 = y1 or exists (select * from z where z1 =
x1) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join LeftOuter, ((x1#x = y1#x) OR exists#x [x1#x])
+ : +- Project [z1#x, z2#x]
+ : +- Filter (z1#x = outer(x1#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x left join y on x1 = y1 or not exists (select * from z where z1
= x1) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join LeftOuter, ((x1#x = y1#x) OR NOT exists#x [x1#x])
+ : +- Project [z1#x, z2#x]
+ : +- Filter (z1#x = outer(x1#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x inner join y on x1 = y1 or exists (select * from z where z1 =
y1) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join Inner, ((x1#x = y1#x) OR exists#x [y1#x])
+ : +- Project [z1#x, z2#x]
+ : +- Filter (z1#x = outer(y1#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x inner join y on x1 = y1 or not exists (select * from z where
z1 = y1) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join Inner, ((x1#x = y1#x) OR NOT exists#x [y1#x])
+ : +- Project [z1#x, z2#x]
+ : +- Filter (z1#x = outer(y1#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x left join y on x1 = y1 or exists (select * from z where z1 =
y1) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join LeftOuter, ((x1#x = y1#x) OR exists#x [y1#x])
+ : +- Project [z1#x, z2#x]
+ : +- Filter (z1#x = outer(y1#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x left join y on x1 = y1 or not exists (select * from z where z1
= y1) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join LeftOuter, ((x1#x = y1#x) OR NOT exists#x [y1#x])
+ : +- Project [z1#x, z2#x]
+ : +- Filter (z1#x = outer(y1#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x inner join y on x1 = y1 and exists (select * from z where z1 =
x1) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join Inner, ((x1#x = y1#x) AND exists#x [x1#x])
+ : +- Project [z1#x, z2#x]
+ : +- Filter (z1#x = outer(x1#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x inner join y on x1 = y1 and not exists (select * from z where
z1 = x1) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join Inner, ((x1#x = y1#x) AND NOT exists#x [x1#x])
+ : +- Project [z1#x, z2#x]
+ : +- Filter (z1#x = outer(x1#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x left join y on x1 = y1 and exists (select * from z where z1 =
x1) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join LeftOuter, ((x1#x = y1#x) AND exists#x [x1#x])
+ : +- Project [z1#x, z2#x]
+ : +- Filter (z1#x = outer(x1#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x left join y on x1 = y1 and not exists (select * from z where
z1 = x1) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join LeftOuter, ((x1#x = y1#x) AND NOT exists#x [x1#x])
+ : +- Project [z1#x, z2#x]
+ : +- Filter (z1#x = outer(x1#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x inner join y on x1 = y1 and exists (select * from z where z1 =
y1) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join Inner, ((x1#x = y1#x) AND exists#x [y1#x])
+ : +- Project [z1#x, z2#x]
+ : +- Filter (z1#x = outer(y1#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x inner join y on x1 = y1 and not exists (select * from z where
z1 = y1) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join Inner, ((x1#x = y1#x) AND NOT exists#x [y1#x])
+ : +- Project [z1#x, z2#x]
+ : +- Filter (z1#x = outer(y1#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x left join y on x1 = y1 and exists (select * from z where z1 =
y1) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join LeftOuter, ((x1#x = y1#x) AND exists#x [y1#x])
+ : +- Project [z1#x, z2#x]
+ : +- Filter (z1#x = outer(y1#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x left join y on x1 = y1 and not exists (select * from z where
z1 = y1) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join LeftOuter, ((x1#x = y1#x) AND NOT exists#x [y1#x])
+ : +- Project [z1#x, z2#x]
+ : +- Filter (z1#x = outer(y1#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
diff --git
a/sql/core/src/test/resources/sql-tests/analyzer-results/subquery/in-subquery/in-null-semantics.sql.out
b/sql/core/src/test/resources/sql-tests/analyzer-results/subquery/in-subquery/in-null-semantics.sql.out
index ac5c41dd307..7816958795d 100644
---
a/sql/core/src/test/resources/sql-tests/analyzer-results/subquery/in-subquery/in-null-semantics.sql.out
+++
b/sql/core/src/test/resources/sql-tests/analyzer-results/subquery/in-subquery/in-null-semantics.sql.out
@@ -163,6 +163,40 @@ Project [NOT cast(null as int) IN (list#x []) AS (NOT
(NULL IN (listquery())))#x
+- OneRowRelation
+-- !query
+select * from t left join t2 on (t.c in (select e from t_empty)) is null
+-- !query analysis
+Project [c#x, d#x]
++- Join LeftOuter, isnull(c#x IN (list#x []))
+ : +- Project [e#x]
+ : +- SubqueryAlias spark_catalog.default.t_empty
+ : +- Relation spark_catalog.default.t_empty[e#x] json
+ :- SubqueryAlias spark_catalog.default.t
+ : +- Relation spark_catalog.default.t[c#x] json
+ +- SubqueryAlias spark_catalog.default.t2
+ +- Relation spark_catalog.default.t2[d#x] json
+
+
+-- !query
+select * from t left join t2 on (t.c not in (select e from t_empty)) is null
+-- !query analysis
+Project [c#x, d#x]
++- Join LeftOuter, isnull(NOT c#x IN (list#x []))
+ : +- Project [e#x]
+ : +- SubqueryAlias spark_catalog.default.t_empty
+ : +- Relation spark_catalog.default.t_empty[e#x] json
+ :- SubqueryAlias spark_catalog.default.t
+ : +- Relation spark_catalog.default.t[c#x] json
+ +- SubqueryAlias spark_catalog.default.t2
+ +- Relation spark_catalog.default.t2[d#x] json
+
+
+-- !query
+set
spark.sql.optimizer.optimizeUncorrelatedInSubqueriesInJoinCondition.enabled=true
+-- !query analysis
+SetCommand
(spark.sql.optimizer.optimizeUncorrelatedInSubqueriesInJoinCondition.enabled,Some(true))
+
+
-- !query
select * from t left join t2 on (t.c in (select e from t_empty)) is null
-- !query analysis
@@ -197,6 +231,12 @@ set spark.sql.legacy.nullInEmptyListBehavior = true
SetCommand (spark.sql.legacy.nullInEmptyListBehavior,Some(true))
+-- !query
+set
spark.sql.optimizer.optimizeUncorrelatedInSubqueriesInJoinCondition.enabled=false
+-- !query analysis
+SetCommand
(spark.sql.optimizer.optimizeUncorrelatedInSubqueriesInJoinCondition.enabled,Some(false))
+
+
-- !query
select null in (select e from t_empty)
-- !query analysis
@@ -283,6 +323,12 @@ reset spark.sql.legacy.nullInEmptyListBehavior
ResetCommand spark.sql.legacy.nullInEmptyListBehavior
+-- !query
+reset
spark.sql.optimizer.optimizeUncorrelatedInSubqueriesInJoinCondition.enabled
+-- !query analysis
+ResetCommand
spark.sql.optimizer.optimizeUncorrelatedInSubqueriesInJoinCondition.enabled
+
+
-- !query
drop table t
-- !query analysis
diff --git
a/sql/core/src/test/resources/sql-tests/analyzer-results/subquery/in-subquery/in-subquery-in-join-condition.sql.out
b/sql/core/src/test/resources/sql-tests/analyzer-results/subquery/in-subquery/in-subquery-in-join-condition.sql.out
new file mode 100644
index 00000000000..c69988358fc
--- /dev/null
+++
b/sql/core/src/test/resources/sql-tests/analyzer-results/subquery/in-subquery/in-subquery-in-join-condition.sql.out
@@ -0,0 +1,918 @@
+-- Automatically generated by SQLQueryTestSuite
+-- !query
+CREATE TEMP VIEW x(x1, x2) AS VALUES
+ (2, 1),
+ (1, 1),
+ (3, 4)
+-- !query analysis
+CreateViewCommand `x`, [(x1,None), (x2,None)], VALUES
+ (2, 1),
+ (1, 1),
+ (3, 4), false, false, LocalTempView, true
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+CREATE TEMP VIEW y(y1, y2) AS VALUES
+ (0, 2),
+ (1, 4),
+ (4, 11)
+-- !query analysis
+CreateViewCommand `y`, [(y1,None), (y2,None)], VALUES
+ (0, 2),
+ (1, 4),
+ (4, 11), false, false, LocalTempView, true
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+CREATE TEMP VIEW z(z1, z2) AS VALUES
+ (4, 2),
+ (3, 3),
+ (8, 1)
+-- !query analysis
+CreateViewCommand `z`, [(z1,None), (z2,None)], VALUES
+ (4, 2),
+ (3, 3),
+ (8, 1), false, false, LocalTempView, true
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x inner join y on x1 = y1 and x2 IN (select z1 from z where z2 =
x2) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join Inner, ((x1#x = y1#x) AND x2#x IN (list#x [x2#x]))
+ : +- Project [z1#x]
+ : +- Filter (z2#x = outer(x2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x inner join y on x1 = y1 and x2 not IN (select z1 from z where
z2 = x2) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join Inner, ((x1#x = y1#x) AND NOT x2#x IN (list#x [x2#x]))
+ : +- Project [z1#x]
+ : +- Filter (z2#x = outer(x2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x inner join y on x1 = y1 and y2 IN (select z1 from z where z2 =
y2) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join Inner, ((x1#x = y1#x) AND y2#x IN (list#x [y2#x]))
+ : +- Project [z1#x]
+ : +- Filter (z2#x = outer(y2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x inner join y on x1 = y1 and y2 not IN (select z1 from z where
z2 = y2) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join Inner, ((x1#x = y1#x) AND NOT y2#x IN (list#x [y2#x]))
+ : +- Project [z1#x]
+ : +- Filter (z2#x = outer(y2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x left join y on x1 = y1 and x2 IN (select z1 from z where z2 =
x2) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join LeftOuter, ((x1#x = y1#x) AND x2#x IN (list#x [x2#x]))
+ : +- Project [z1#x]
+ : +- Filter (z2#x = outer(x2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x left join y on x1 = y1 and x2 not IN (select z1 from z where
z2 = x2) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join LeftOuter, ((x1#x = y1#x) AND NOT x2#x IN (list#x [x2#x]))
+ : +- Project [z1#x]
+ : +- Filter (z2#x = outer(x2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x left join y on x1 = y1 and y2 IN (select z1 from z where z2 =
y2) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join LeftOuter, ((x1#x = y1#x) AND y2#x IN (list#x [y2#x]))
+ : +- Project [z1#x]
+ : +- Filter (z2#x = outer(y2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x left join y on x1 = y1 and y2 not IN (select z1 from z where
z2 = y2) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join LeftOuter, ((x1#x = y1#x) AND NOT y2#x IN (list#x [y2#x]))
+ : +- Project [z1#x]
+ : +- Filter (z2#x = outer(y2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x right join y on x1 = y1 and x2 IN (select z1 from z where z2 =
x2) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join RightOuter, ((x1#x = y1#x) AND x2#x IN (list#x [x2#x]))
+ : +- Project [z1#x]
+ : +- Filter (z2#x = outer(x2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x right join y on x1 = y1 and x2 not IN (select z1 from z where
z2 = x2) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join RightOuter, ((x1#x = y1#x) AND NOT x2#x IN (list#x [x2#x]))
+ : +- Project [z1#x]
+ : +- Filter (z2#x = outer(x2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x right join y on x1 = y1 and y2 IN (select z1 from z where z2 =
y2) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join RightOuter, ((x1#x = y1#x) AND y2#x IN (list#x [y2#x]))
+ : +- Project [z1#x]
+ : +- Filter (z2#x = outer(y2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x right join y on x1 = y1 and y2 not IN (select z1 from z where
z2 = y2) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join RightOuter, ((x1#x = y1#x) AND NOT y2#x IN (list#x [y2#x]))
+ : +- Project [z1#x]
+ : +- Filter (z2#x = outer(y2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x left semi join y on x1 = y1 and x2 IN (select z1 from z where
z2 = x2) order by x1, x2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST], true
++- Project [x1#x, x2#x]
+ +- Join LeftSemi, ((x1#x = y1#x) AND x2#x IN (list#x [x2#x]))
+ : +- Project [z1#x]
+ : +- Filter (z2#x = outer(x2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x left semi join y on x1 = y1 and x2 not IN (select z1 from z
where z2 = x2) order by x1, x2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST], true
++- Project [x1#x, x2#x]
+ +- Join LeftSemi, ((x1#x = y1#x) AND NOT x2#x IN (list#x [x2#x]))
+ : +- Project [z1#x]
+ : +- Filter (z2#x = outer(x2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x left semi join y on x1 = y1 and y2 IN (select z1 from z where
z2 = y2) order by x1, x2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST], true
++- Project [x1#x, x2#x]
+ +- Join LeftSemi, ((x1#x = y1#x) AND y2#x IN (list#x [y2#x]))
+ : +- Project [z1#x]
+ : +- Filter (z2#x = outer(y2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x left semi join y on x1 = y1 and y2 not IN (select z1 from z
where z2 = y2) order by x1, x2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST], true
++- Project [x1#x, x2#x]
+ +- Join LeftSemi, ((x1#x = y1#x) AND NOT y2#x IN (list#x [y2#x]))
+ : +- Project [z1#x]
+ : +- Filter (z2#x = outer(y2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x left anti join y on x1 = y1 and x2 IN (select z1 from z where
z2 = x2) order by x1, x2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST], true
++- Project [x1#x, x2#x]
+ +- Join LeftAnti, ((x1#x = y1#x) AND x2#x IN (list#x [x2#x]))
+ : +- Project [z1#x]
+ : +- Filter (z2#x = outer(x2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x left anti join y on x1 = y1 and x2 not IN (select z1 from z
where z2 = x2) order by x1, x2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST], true
++- Project [x1#x, x2#x]
+ +- Join LeftAnti, ((x1#x = y1#x) AND NOT x2#x IN (list#x [x2#x]))
+ : +- Project [z1#x]
+ : +- Filter (z2#x = outer(x2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x left anti join y on x1 = y1 and y2 IN (select z1 from z where
z2 = y2) order by x1, x2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST], true
++- Project [x1#x, x2#x]
+ +- Join LeftAnti, ((x1#x = y1#x) AND y2#x IN (list#x [y2#x]))
+ : +- Project [z1#x]
+ : +- Filter (z2#x = outer(y2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x left anti join y on x1 = y1 and y2 not IN (select z1 from z
where z2 = y2) order by x1, x2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST], true
++- Project [x1#x, x2#x]
+ +- Join LeftAnti, ((x1#x = y1#x) AND NOT y2#x IN (list#x [y2#x]))
+ : +- Project [z1#x]
+ : +- Filter (z2#x = outer(y2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x full outer join y on x1 = y1 and x2 IN (select z1 from z where
z2 = x2) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join FullOuter, ((x1#x = y1#x) AND x2#x IN (list#x [x2#x]))
+ : +- Project [z1#x]
+ : +- Filter (z2#x = outer(x2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x full outer join y on x1 = y1 and x2 not IN (select z1 from z
where z2 = x2) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join FullOuter, ((x1#x = y1#x) AND NOT x2#x IN (list#x [x2#x]))
+ : +- Project [z1#x]
+ : +- Filter (z2#x = outer(x2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x full outer join y on x1 = y1 and y2 IN (select z1 from z where
z2 = y2) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join FullOuter, ((x1#x = y1#x) AND y2#x IN (list#x [y2#x]))
+ : +- Project [z1#x]
+ : +- Filter (z2#x = outer(y2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x full outer join y on x1 = y1 and y2 not IN (select z1 from z
where z2 = y2) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join FullOuter, ((x1#x = y1#x) AND NOT y2#x IN (list#x [y2#x]))
+ : +- Project [z1#x]
+ : +- Filter (z2#x = outer(y2#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x inner join y on x1 = y1 or x2 IN (select z1 from z where z1 =
x1) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join Inner, ((x1#x = y1#x) OR x2#x IN (list#x [x1#x]))
+ : +- Project [z1#x]
+ : +- Filter (z1#x = outer(x1#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x inner join y on x1 = y1 or x2 not IN (select z1 from z where
z1 = x1) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join Inner, ((x1#x = y1#x) OR NOT x2#x IN (list#x [x1#x]))
+ : +- Project [z1#x]
+ : +- Filter (z1#x = outer(x1#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x left join y on x1 = y1 or x2 IN (select z1 from z where z1 =
x1) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join LeftOuter, ((x1#x = y1#x) OR x2#x IN (list#x [x1#x]))
+ : +- Project [z1#x]
+ : +- Filter (z1#x = outer(x1#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x left join y on x1 = y1 or x2 not IN (select z1 from z where z1
= x1) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join LeftOuter, ((x1#x = y1#x) OR NOT x2#x IN (list#x [x1#x]))
+ : +- Project [z1#x]
+ : +- Filter (z1#x = outer(x1#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x inner join y on x1 = y1 or y2 IN (select z1 from z where z1 =
y1) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join Inner, ((x1#x = y1#x) OR y2#x IN (list#x [y1#x]))
+ : +- Project [z1#x]
+ : +- Filter (z1#x = outer(y1#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x inner join y on x1 = y1 or y2 not IN (select z1 from z where
z1 = y1) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join Inner, ((x1#x = y1#x) OR NOT y2#x IN (list#x [y1#x]))
+ : +- Project [z1#x]
+ : +- Filter (z1#x = outer(y1#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x left join y on x1 = y1 or y2 IN (select z1 from z where z1 =
y1) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join LeftOuter, ((x1#x = y1#x) OR y2#x IN (list#x [y1#x]))
+ : +- Project [z1#x]
+ : +- Filter (z1#x = outer(y1#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x left join y on x1 = y1 or y2 not IN (select z1 from z where z1
= y1) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join LeftOuter, ((x1#x = y1#x) OR NOT y2#x IN (list#x [y1#x]))
+ : +- Project [z1#x]
+ : +- Filter (z1#x = outer(y1#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x inner join y on x1 = y1 and x2 IN (select z1 from z where z1 =
x1) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join Inner, ((x1#x = y1#x) AND x2#x IN (list#x [x1#x]))
+ : +- Project [z1#x]
+ : +- Filter (z1#x = outer(x1#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x inner join y on x1 = y1 and x2 not IN (select z1 from z where
z1 = x1) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join Inner, ((x1#x = y1#x) AND NOT x2#x IN (list#x [x1#x]))
+ : +- Project [z1#x]
+ : +- Filter (z1#x = outer(x1#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x left join y on x1 = y1 and x2 IN (select z1 from z where z1 =
x1) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join LeftOuter, ((x1#x = y1#x) AND x2#x IN (list#x [x1#x]))
+ : +- Project [z1#x]
+ : +- Filter (z1#x = outer(x1#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x left join y on x1 = y1 and x2 not IN (select z1 from z where
z1 = x1) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join LeftOuter, ((x1#x = y1#x) AND NOT x2#x IN (list#x [x1#x]))
+ : +- Project [z1#x]
+ : +- Filter (z1#x = outer(x1#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x inner join y on x1 = y1 and y2 IN (select z1 from z where z1 =
y1) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join Inner, ((x1#x = y1#x) AND y2#x IN (list#x [y1#x]))
+ : +- Project [z1#x]
+ : +- Filter (z1#x = outer(y1#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x inner join y on x1 = y1 and y2 not IN (select z1 from z where
z1 = y1) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join Inner, ((x1#x = y1#x) AND NOT y2#x IN (list#x [y1#x]))
+ : +- Project [z1#x]
+ : +- Filter (z1#x = outer(y1#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x left join y on x1 = y1 and y2 IN (select z1 from z where z1 =
y1) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join LeftOuter, ((x1#x = y1#x) AND y2#x IN (list#x [y1#x]))
+ : +- Project [z1#x]
+ : +- Filter (z1#x = outer(y1#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
+
+
+-- !query
+select * from x left join y on x1 = y1 and y2 not IN (select z1 from z where
z1 = y1) order by x1, x2, y1, y2
+-- !query analysis
+Sort [x1#x ASC NULLS FIRST, x2#x ASC NULLS FIRST, y1#x ASC NULLS FIRST, y2#x
ASC NULLS FIRST], true
++- Project [x1#x, x2#x, y1#x, y2#x]
+ +- Join LeftOuter, ((x1#x = y1#x) AND NOT y2#x IN (list#x [y1#x]))
+ : +- Project [z1#x]
+ : +- Filter (z1#x = outer(y1#x))
+ : +- SubqueryAlias z
+ : +- View (`z`, [z1#x,z2#x])
+ : +- Project [cast(col1#x as int) AS z1#x, cast(col2#x as
int) AS z2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ :- SubqueryAlias x
+ : +- View (`x`, [x1#x,x2#x])
+ : +- Project [cast(col1#x as int) AS x1#x, cast(col2#x as int) AS
x2#x]
+ : +- LocalRelation [col1#x, col2#x]
+ +- SubqueryAlias y
+ +- View (`y`, [y1#x,y2#x])
+ +- Project [cast(col1#x as int) AS y1#x, cast(col2#x as int) AS
y2#x]
+ +- LocalRelation [col1#x, col2#x]
diff --git
a/sql/core/src/test/resources/sql-tests/inputs/subquery/exists-subquery/exists-in-join-condition.sql
b/sql/core/src/test/resources/sql-tests/inputs/subquery/exists-subquery/exists-in-join-condition.sql
new file mode 100644
index 00000000000..5cff53d3381
--- /dev/null
+++
b/sql/core/src/test/resources/sql-tests/inputs/subquery/exists-subquery/exists-in-join-condition.sql
@@ -0,0 +1,90 @@
+-- Test that correlated EXISTS subqueries in join conditions are supported.
+
+-- Permutations of the test:
+-- 1. Exists / Not Exists
+-- 2. Reference left / right child
+-- 3. Join type: inner / left outer / right outer / full outer / left semi /
left anti
+-- 4. AND or OR for the join condition
+
+CREATE TEMP VIEW x(x1, x2) AS VALUES
+ (2, 1),
+ (1, 1),
+ (3, 4);
+
+CREATE TEMP VIEW y(y1, y2) AS VALUES
+ (0, 2),
+ (1, 4),
+ (4, 11);
+
+CREATE TEMP VIEW z(z1, z2) AS VALUES
+ (4, 2),
+ (3, 3),
+ (8, 1);
+
+-- Correlated EXISTS, REFERENCE LEFT, INNER JOIN
+select * from x inner join y on x1 = y1 and exists (select * from z where z2 =
x2) order by x1, x2, y1, y2;
+
+-- Correlated NOT EXISTS, REFERENCE LEFT, INNER JOIN
+select * from x inner join y on x1 = y1 and not exists (select * from z where
z2 = x2) order by x1, x2, y1, y2;
+
+-- Correlated EXISTS, REFERENCE RIGHT, INNER JOIN
+select * from x inner join y on x1 = y1 and exists (select * from z where z2 =
y2) order by x1, x2, y1, y2;
+
+-- Correlated NOT EXISTS, REFERENCE RIGHT, INNER JOIN
+select * from x inner join y on x1 = y1 and not exists (select * from z where
z2 = y2) order by x1, x2, y1, y2;
+
+-- Same as above, but for left outer join
+select * from x left join y on x1 = y1 and exists (select * from z where z2 =
x2) order by x1, x2, y1, y2;
+select * from x left join y on x1 = y1 and not exists (select * from z where
z2 = x2) order by x1, x2, y1, y2;
+select * from x left join y on x1 = y1 and exists (select * from z where z2 =
y2) order by x1, x2, y1, y2;
+select * from x left join y on x1 = y1 and not exists (select * from z where
z2 = y2) order by x1, x2, y1, y2;
+
+-- Same as above, but for right outer join
+select * from x right join y on x1 = y1 and exists (select * from z where z2 =
x2) order by x1, x2, y1, y2;
+select * from x right join y on x1 = y1 and not exists (select * from z where
z2 = x2) order by x1, x2, y1, y2;
+select * from x right join y on x1 = y1 and exists (select * from z where z2 =
y2) order by x1, x2, y1, y2;
+select * from x right join y on x1 = y1 and not exists (select * from z where
z2 = y2) order by x1, x2, y1, y2;
+
+-- Same as above, but for full outer join
+select * from x right join y on x1 = y1 and exists (select * from z where z2 =
x2) order by x1, x2, y1, y2;
+select * from x right join y on x1 = y1 and not exists (select * from z where
z2 = x2) order by x1, x2, y1, y2;
+select * from x right join y on x1 = y1 and exists (select * from z where z2 =
y2) order by x1, x2, y1, y2;
+select * from x right join y on x1 = y1 and not exists (select * from z where
z2 = y2) order by x1, x2, y1, y2;
+
+-- Same as above, but for left semi join
+select * from x left semi join y on x1 = y1 and exists (select * from z where
z2 = x2) order by x1, x2;
+select * from x left semi join y on x1 = y1 and not exists (select * from z
where z2 = x2) order by x1, x2;
+select * from x left semi join y on x1 = y1 and exists (select * from z where
z2 = y2) order by x1, x2;
+select * from x left semi join y on x1 = y1 and not exists (select * from z
where z2 = y2) order by x1, x2;
+
+-- Same as above, but for left anti join
+select * from x left anti join y on x1 = y1 and exists (select * from z where
z2 = x2) order by x1, x2;
+select * from x left anti join y on x1 = y1 and not exists (select * from z
where z2 = x2) order by x1, x2;
+select * from x left anti join y on x1 = y1 and exists (select * from z where
z2 = y2) order by x1, x2;
+select * from x left anti join y on x1 = y1 and not exists (select * from z
where z2 = y2) order by x1, x2;
+
+-- Same as above, but for full outer join
+select * from x full outer join y on x1 = y1 and exists (select * from z where
z2 = x2) order by x1, x2, y1, y2;
+select * from x full outer join y on x1 = y1 and not exists (select * from z
where z2 = x2) order by x1, x2, y1, y2;
+select * from x full outer join y on x1 = y1 and exists (select * from z where
z2 = y2) order by x1, x2, y1, y2;
+select * from x full outer join y on x1 = y1 and not exists (select * from z
where z2 = y2) order by x1, x2, y1, y2;
+
+-- OR instead of AND in the join condition
+select * from x inner join y on x1 = y1 or exists (select * from z where z1 =
x1) order by x1, x2, y1, y2;
+select * from x inner join y on x1 = y1 or not exists (select * from z where
z1 = x1) order by x1, x2, y1, y2;
+select * from x left join y on x1 = y1 or exists (select * from z where z1 =
x1) order by x1, x2, y1, y2;
+select * from x left join y on x1 = y1 or not exists (select * from z where z1
= x1) order by x1, x2, y1, y2;
+select * from x inner join y on x1 = y1 or exists (select * from z where z1 =
y1) order by x1, x2, y1, y2;
+select * from x inner join y on x1 = y1 or not exists (select * from z where
z1 = y1) order by x1, x2, y1, y2;
+select * from x left join y on x1 = y1 or exists (select * from z where z1 =
y1) order by x1, x2, y1, y2;
+select * from x left join y on x1 = y1 or not exists (select * from z where z1
= y1) order by x1, x2, y1, y2;
+
+-- Transitive predicates to test if inferring filters can cause issues.
+select * from x inner join y on x1 = y1 and exists (select * from z where z1 =
x1) order by x1, x2, y1, y2;
+select * from x inner join y on x1 = y1 and not exists (select * from z where
z1 = x1) order by x1, x2, y1, y2;
+select * from x left join y on x1 = y1 and exists (select * from z where z1 =
x1) order by x1, x2, y1, y2;
+select * from x left join y on x1 = y1 and not exists (select * from z where
z1 = x1) order by x1, x2, y1, y2;
+select * from x inner join y on x1 = y1 and exists (select * from z where z1 =
y1) order by x1, x2, y1, y2;
+select * from x inner join y on x1 = y1 and not exists (select * from z where
z1 = y1) order by x1, x2, y1, y2;
+select * from x left join y on x1 = y1 and exists (select * from z where z1 =
y1) order by x1, x2, y1, y2;
+select * from x left join y on x1 = y1 and not exists (select * from z where
z1 = y1) order by x1, x2, y1, y2;
diff --git
a/sql/core/src/test/resources/sql-tests/inputs/subquery/in-subquery/in-null-semantics.sql
b/sql/core/src/test/resources/sql-tests/inputs/subquery/in-subquery/in-null-semantics.sql
index cc01887a4e2..aad655f0509 100644
---
a/sql/core/src/test/resources/sql-tests/inputs/subquery/in-subquery/in-null-semantics.sql
+++
b/sql/core/src/test/resources/sql-tests/inputs/subquery/in-subquery/in-null-semantics.sql
@@ -32,10 +32,16 @@ select null not in (select e from v_empty);
select * from t left join t2 on (t.c in (select e from t_empty)) is null;
select * from t left join t2 on (t.c not in (select e from t_empty)) is null;
+-- Should have the same results as above with optimize IN subqueries enabled
+set
spark.sql.optimizer.optimizeUncorrelatedInSubqueriesInJoinCondition.enabled=true;
+-- IN subquery which IS rewritten to join
+select * from t left join t2 on (t.c in (select e from t_empty)) is null;
+select * from t left join t2 on (t.c not in (select e from t_empty)) is null;
--- Test legacy behavior flag
set spark.sql.legacy.nullInEmptyListBehavior = true;
+-- Disable optimize IN subqueries to joins because it affects null semantics
+set
spark.sql.optimizer.optimizeUncorrelatedInSubqueriesInJoinCondition.enabled=false;
-- constant null IN (empty subquery) - rewritten by NullPropagation rule
@@ -50,6 +56,7 @@ select * from t left join t2 on (t.c in (select e from
t_empty)) is null;
select * from t left join t2 on (t.c not in (select e from t_empty)) is null;
reset spark.sql.legacy.nullInEmptyListBehavior;
+reset
spark.sql.optimizer.optimizeUncorrelatedInSubqueriesInJoinCondition.enabled;
drop table t;
drop table t2;
diff --git
a/sql/core/src/test/resources/sql-tests/inputs/subquery/in-subquery/in-subquery-in-join-condition.sql
b/sql/core/src/test/resources/sql-tests/inputs/subquery/in-subquery/in-subquery-in-join-condition.sql
new file mode 100644
index 00000000000..d4fa2f6b0e8
--- /dev/null
+++
b/sql/core/src/test/resources/sql-tests/inputs/subquery/in-subquery/in-subquery-in-join-condition.sql
@@ -0,0 +1,85 @@
+-- Test that correlated EXISTS subqueries in join conditions are supported.
+
+-- Permutations of the test:
+-- 1. In / Not In
+-- 2. Reference left / right child
+-- 3. Join type: inner / left outer / right outer / full outer / left semi /
left anti
+-- 4. AND or OR for the join condition
+
+CREATE TEMP VIEW x(x1, x2) AS VALUES
+ (2, 1),
+ (1, 1),
+ (3, 4);
+
+CREATE TEMP VIEW y(y1, y2) AS VALUES
+ (0, 2),
+ (1, 4),
+ (4, 11);
+
+CREATE TEMP VIEW z(z1, z2) AS VALUES
+ (4, 2),
+ (3, 3),
+ (8, 1);
+
+
+--Correlated IN, REFERENCE LEFT, INNER JOIN
+select * from x inner join y on x1 = y1 and x2 IN (select z1 from z where z2 =
x2) order by x1, x2, y1, y2;
+
+--Correlated NOT IN, REFERENCE LEFT, INNER JOIN
+select * from x inner join y on x1 = y1 and x2 not IN (select z1 from z where
z2 = x2) order by x1, x2, y1, y2;
+
+--Correlated IN, REFERENCE RIGHT, INNER JOIN
+select * from x inner join y on x1 = y1 and y2 IN (select z1 from z where z2 =
y2) order by x1, x2, y1, y2;
+
+--Correlated NOT IN, REFERENCE RIGHT, INNER JOIN
+select * from x inner join y on x1 = y1 and y2 not IN (select z1 from z where
z2 = y2) order by x1, x2, y1, y2;
+
+-- Same as above, but for left join
+select * from x left join y on x1 = y1 and x2 IN (select z1 from z where z2 =
x2) order by x1, x2, y1, y2;
+select * from x left join y on x1 = y1 and x2 not IN (select z1 from z where
z2 = x2) order by x1, x2, y1, y2;
+select * from x left join y on x1 = y1 and y2 IN (select z1 from z where z2 =
y2) order by x1, x2, y1, y2;
+select * from x left join y on x1 = y1 and y2 not IN (select z1 from z where
z2 = y2) order by x1, x2, y1, y2;
+
+-- Same as above, but for right join
+select * from x right join y on x1 = y1 and x2 IN (select z1 from z where z2 =
x2) order by x1, x2, y1, y2;
+select * from x right join y on x1 = y1 and x2 not IN (select z1 from z where
z2 = x2) order by x1, x2, y1, y2;
+select * from x right join y on x1 = y1 and y2 IN (select z1 from z where z2 =
y2) order by x1, x2, y1, y2;
+select * from x right join y on x1 = y1 and y2 not IN (select z1 from z where
z2 = y2) order by x1, x2, y1, y2;
+
+-- Same as above, but for left semi join
+select * from x left semi join y on x1 = y1 and x2 IN (select z1 from z where
z2 = x2) order by x1, x2;
+select * from x left semi join y on x1 = y1 and x2 not IN (select z1 from z
where z2 = x2) order by x1, x2;
+select * from x left semi join y on x1 = y1 and y2 IN (select z1 from z where
z2 = y2) order by x1, x2;
+select * from x left semi join y on x1 = y1 and y2 not IN (select z1 from z
where z2 = y2) order by x1, x2;
+
+-- Same as above, but for left anti join
+select * from x left anti join y on x1 = y1 and x2 IN (select z1 from z where
z2 = x2) order by x1, x2;
+select * from x left anti join y on x1 = y1 and x2 not IN (select z1 from z
where z2 = x2) order by x1, x2;
+select * from x left anti join y on x1 = y1 and y2 IN (select z1 from z where
z2 = y2) order by x1, x2;
+select * from x left anti join y on x1 = y1 and y2 not IN (select z1 from z
where z2 = y2) order by x1, x2;
+
+-- Same as above, but for full outer join
+select * from x full outer join y on x1 = y1 and x2 IN (select z1 from z where
z2 = x2) order by x1, x2, y1, y2;
+select * from x full outer join y on x1 = y1 and x2 not IN (select z1 from z
where z2 = x2) order by x1, x2, y1, y2;
+select * from x full outer join y on x1 = y1 and y2 IN (select z1 from z where
z2 = y2) order by x1, x2, y1, y2;
+select * from x full outer join y on x1 = y1 and y2 not IN (select z1 from z
where z2 = y2) order by x1, x2, y1, y2;
+
+-- OR instead of AND in the join condition
+select * from x inner join y on x1 = y1 or x2 IN (select z1 from z where z1 =
x1) order by x1, x2, y1, y2;
+select * from x inner join y on x1 = y1 or x2 not IN (select z1 from z where
z1 = x1) order by x1, x2, y1, y2;
+select * from x left join y on x1 = y1 or x2 IN (select z1 from z where z1 =
x1) order by x1, x2, y1, y2;
+select * from x left join y on x1 = y1 or x2 not IN (select z1 from z where z1
= x1) order by x1, x2, y1, y2;
+select * from x inner join y on x1 = y1 or y2 IN (select z1 from z where z1 =
y1) order by x1, x2, y1, y2;
+select * from x inner join y on x1 = y1 or y2 not IN (select z1 from z where
z1 = y1) order by x1, x2, y1, y2;
+select * from x left join y on x1 = y1 or y2 IN (select z1 from z where z1 =
y1) order by x1, x2, y1, y2;
+select * from x left join y on x1 = y1 or y2 not IN (select z1 from z where z1
= y1) order by x1, x2, y1, y2;
+
+-- Transitive predicates to test if inferring filters can cause issues.
+select * from x inner join y on x1 = y1 and x2 IN (select z1 from z where z1 =
x1) order by x1, x2, y1, y2;
+select * from x inner join y on x1 = y1 and x2 not IN (select z1 from z where
z1 = x1) order by x1, x2, y1, y2;
+select * from x left join y on x1 = y1 and x2 IN (select z1 from z where z1 =
x1) order by x1, x2, y1, y2;
+select * from x left join y on x1 = y1 and x2 not IN (select z1 from z where
z1 = x1) order by x1, x2, y1, y2;
+select * from x inner join y on x1 = y1 and y2 IN (select z1 from z where z1 =
y1) order by x1, x2, y1, y2;
+select * from x inner join y on x1 = y1 and y2 not IN (select z1 from z where
z1 = y1) order by x1, x2, y1, y2;
+select * from x left join y on x1 = y1 and y2 IN (select z1 from z where z1 =
y1) order by x1, x2, y1, y2;
+select * from x left join y on x1 = y1 and y2 not IN (select z1 from z where
z1 = y1) order by x1, x2, y1, y2;
diff --git
a/sql/core/src/test/resources/sql-tests/results/subquery/exists-subquery/exists-in-join-condition.sql.out
b/sql/core/src/test/resources/sql-tests/results/subquery/exists-subquery/exists-in-join-condition.sql.out
new file mode 100644
index 00000000000..b490704bebc
--- /dev/null
+++
b/sql/core/src/test/resources/sql-tests/results/subquery/exists-subquery/exists-in-join-condition.sql.out
@@ -0,0 +1,474 @@
+-- Automatically generated by SQLQueryTestSuite
+-- !query
+CREATE TEMP VIEW x(x1, x2) AS VALUES
+ (2, 1),
+ (1, 1),
+ (3, 4)
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+CREATE TEMP VIEW y(y1, y2) AS VALUES
+ (0, 2),
+ (1, 4),
+ (4, 11)
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+CREATE TEMP VIEW z(z1, z2) AS VALUES
+ (4, 2),
+ (3, 3),
+ (8, 1)
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+select * from x inner join y on x1 = y1 and exists (select * from z where z2 =
x2) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+1 1 1 4
+
+
+-- !query
+select * from x inner join y on x1 = y1 and not exists (select * from z where
z2 = x2) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+
+
+
+-- !query
+select * from x inner join y on x1 = y1 and exists (select * from z where z2 =
y2) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+
+
+
+-- !query
+select * from x inner join y on x1 = y1 and not exists (select * from z where
z2 = y2) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+1 1 1 4
+
+
+-- !query
+select * from x left join y on x1 = y1 and exists (select * from z where z2 =
x2) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+1 1 1 4
+2 1 NULL NULL
+3 4 NULL NULL
+
+
+-- !query
+select * from x left join y on x1 = y1 and not exists (select * from z where
z2 = x2) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+1 1 NULL NULL
+2 1 NULL NULL
+3 4 NULL NULL
+
+
+-- !query
+select * from x left join y on x1 = y1 and exists (select * from z where z2 =
y2) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+1 1 NULL NULL
+2 1 NULL NULL
+3 4 NULL NULL
+
+
+-- !query
+select * from x left join y on x1 = y1 and not exists (select * from z where
z2 = y2) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+1 1 1 4
+2 1 NULL NULL
+3 4 NULL NULL
+
+
+-- !query
+select * from x right join y on x1 = y1 and exists (select * from z where z2 =
x2) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+NULL NULL 0 2
+NULL NULL 4 11
+1 1 1 4
+
+
+-- !query
+select * from x right join y on x1 = y1 and not exists (select * from z where
z2 = x2) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+NULL NULL 0 2
+NULL NULL 1 4
+NULL NULL 4 11
+
+
+-- !query
+select * from x right join y on x1 = y1 and exists (select * from z where z2 =
y2) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+NULL NULL 0 2
+NULL NULL 1 4
+NULL NULL 4 11
+
+
+-- !query
+select * from x right join y on x1 = y1 and not exists (select * from z where
z2 = y2) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+NULL NULL 0 2
+NULL NULL 4 11
+1 1 1 4
+
+
+-- !query
+select * from x right join y on x1 = y1 and exists (select * from z where z2 =
x2) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+NULL NULL 0 2
+NULL NULL 4 11
+1 1 1 4
+
+
+-- !query
+select * from x right join y on x1 = y1 and not exists (select * from z where
z2 = x2) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+NULL NULL 0 2
+NULL NULL 1 4
+NULL NULL 4 11
+
+
+-- !query
+select * from x right join y on x1 = y1 and exists (select * from z where z2 =
y2) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+NULL NULL 0 2
+NULL NULL 1 4
+NULL NULL 4 11
+
+
+-- !query
+select * from x right join y on x1 = y1 and not exists (select * from z where
z2 = y2) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+NULL NULL 0 2
+NULL NULL 4 11
+1 1 1 4
+
+
+-- !query
+select * from x left semi join y on x1 = y1 and exists (select * from z where
z2 = x2) order by x1, x2
+-- !query schema
+struct<x1:int,x2:int>
+-- !query output
+1 1
+
+
+-- !query
+select * from x left semi join y on x1 = y1 and not exists (select * from z
where z2 = x2) order by x1, x2
+-- !query schema
+struct<x1:int,x2:int>
+-- !query output
+
+
+
+-- !query
+select * from x left semi join y on x1 = y1 and exists (select * from z where
z2 = y2) order by x1, x2
+-- !query schema
+struct<x1:int,x2:int>
+-- !query output
+
+
+
+-- !query
+select * from x left semi join y on x1 = y1 and not exists (select * from z
where z2 = y2) order by x1, x2
+-- !query schema
+struct<x1:int,x2:int>
+-- !query output
+1 1
+
+
+-- !query
+select * from x left anti join y on x1 = y1 and exists (select * from z where
z2 = x2) order by x1, x2
+-- !query schema
+struct<x1:int,x2:int>
+-- !query output
+2 1
+3 4
+
+
+-- !query
+select * from x left anti join y on x1 = y1 and not exists (select * from z
where z2 = x2) order by x1, x2
+-- !query schema
+struct<x1:int,x2:int>
+-- !query output
+1 1
+2 1
+3 4
+
+
+-- !query
+select * from x left anti join y on x1 = y1 and exists (select * from z where
z2 = y2) order by x1, x2
+-- !query schema
+struct<x1:int,x2:int>
+-- !query output
+1 1
+2 1
+3 4
+
+
+-- !query
+select * from x left anti join y on x1 = y1 and not exists (select * from z
where z2 = y2) order by x1, x2
+-- !query schema
+struct<x1:int,x2:int>
+-- !query output
+2 1
+3 4
+
+
+-- !query
+select * from x full outer join y on x1 = y1 and exists (select * from z where
z2 = x2) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+NULL NULL 0 2
+NULL NULL 4 11
+1 1 1 4
+2 1 NULL NULL
+3 4 NULL NULL
+
+
+-- !query
+select * from x full outer join y on x1 = y1 and not exists (select * from z
where z2 = x2) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+NULL NULL 0 2
+NULL NULL 1 4
+NULL NULL 4 11
+1 1 NULL NULL
+2 1 NULL NULL
+3 4 NULL NULL
+
+
+-- !query
+select * from x full outer join y on x1 = y1 and exists (select * from z where
z2 = y2) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+NULL NULL 0 2
+NULL NULL 1 4
+NULL NULL 4 11
+1 1 NULL NULL
+2 1 NULL NULL
+3 4 NULL NULL
+
+
+-- !query
+select * from x full outer join y on x1 = y1 and not exists (select * from z
where z2 = y2) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+NULL NULL 0 2
+NULL NULL 4 11
+1 1 1 4
+2 1 NULL NULL
+3 4 NULL NULL
+
+
+-- !query
+select * from x inner join y on x1 = y1 or exists (select * from z where z1 =
x1) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+1 1 1 4
+3 4 0 2
+3 4 1 4
+3 4 4 11
+
+
+-- !query
+select * from x inner join y on x1 = y1 or not exists (select * from z where
z1 = x1) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+1 1 0 2
+1 1 1 4
+1 1 4 11
+2 1 0 2
+2 1 1 4
+2 1 4 11
+
+
+-- !query
+select * from x left join y on x1 = y1 or exists (select * from z where z1 =
x1) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+1 1 1 4
+2 1 NULL NULL
+3 4 0 2
+3 4 1 4
+3 4 4 11
+
+
+-- !query
+select * from x left join y on x1 = y1 or not exists (select * from z where z1
= x1) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+1 1 0 2
+1 1 1 4
+1 1 4 11
+2 1 0 2
+2 1 1 4
+2 1 4 11
+3 4 NULL NULL
+
+
+-- !query
+select * from x inner join y on x1 = y1 or exists (select * from z where z1 =
y1) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+1 1 1 4
+1 1 4 11
+2 1 4 11
+3 4 4 11
+
+
+-- !query
+select * from x inner join y on x1 = y1 or not exists (select * from z where
z1 = y1) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+1 1 0 2
+1 1 1 4
+2 1 0 2
+2 1 1 4
+3 4 0 2
+3 4 1 4
+
+
+-- !query
+select * from x left join y on x1 = y1 or exists (select * from z where z1 =
y1) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+1 1 1 4
+1 1 4 11
+2 1 4 11
+3 4 4 11
+
+
+-- !query
+select * from x left join y on x1 = y1 or not exists (select * from z where z1
= y1) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+1 1 0 2
+1 1 1 4
+2 1 0 2
+2 1 1 4
+3 4 0 2
+3 4 1 4
+
+
+-- !query
+select * from x inner join y on x1 = y1 and exists (select * from z where z1 =
x1) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+
+
+
+-- !query
+select * from x inner join y on x1 = y1 and not exists (select * from z where
z1 = x1) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+1 1 1 4
+
+
+-- !query
+select * from x left join y on x1 = y1 and exists (select * from z where z1 =
x1) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+1 1 NULL NULL
+2 1 NULL NULL
+3 4 NULL NULL
+
+
+-- !query
+select * from x left join y on x1 = y1 and not exists (select * from z where
z1 = x1) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+1 1 1 4
+2 1 NULL NULL
+3 4 NULL NULL
+
+
+-- !query
+select * from x inner join y on x1 = y1 and exists (select * from z where z1 =
y1) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+
+
+
+-- !query
+select * from x inner join y on x1 = y1 and not exists (select * from z where
z1 = y1) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+1 1 1 4
+
+
+-- !query
+select * from x left join y on x1 = y1 and exists (select * from z where z1 =
y1) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+1 1 NULL NULL
+2 1 NULL NULL
+3 4 NULL NULL
+
+
+-- !query
+select * from x left join y on x1 = y1 and not exists (select * from z where
z1 = y1) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+1 1 1 4
+2 1 NULL NULL
+3 4 NULL NULL
diff --git
a/sql/core/src/test/resources/sql-tests/results/subquery/in-subquery/in-null-semantics.sql.out
b/sql/core/src/test/resources/sql-tests/results/subquery/in-subquery/in-null-semantics.sql.out
index 169b49fda84..68211e3ff1c 100644
---
a/sql/core/src/test/resources/sql-tests/results/subquery/in-subquery/in-null-semantics.sql.out
+++
b/sql/core/src/test/resources/sql-tests/results/subquery/in-subquery/in-null-semantics.sql.out
@@ -149,6 +149,32 @@ struct<c:int,d:int>
NULL NULL
+-- !query
+set
spark.sql.optimizer.optimizeUncorrelatedInSubqueriesInJoinCondition.enabled=true
+-- !query schema
+struct<key:string,value:string>
+-- !query output
+spark.sql.optimizer.optimizeUncorrelatedInSubqueriesInJoinCondition.enabled
true
+
+
+-- !query
+select * from t left join t2 on (t.c in (select e from t_empty)) is null
+-- !query schema
+struct<c:int,d:int>
+-- !query output
+1 NULL
+NULL NULL
+
+
+-- !query
+select * from t left join t2 on (t.c not in (select e from t_empty)) is null
+-- !query schema
+struct<c:int,d:int>
+-- !query output
+1 NULL
+NULL NULL
+
+
-- !query
set spark.sql.legacy.nullInEmptyListBehavior = true
-- !query schema
@@ -157,6 +183,14 @@ struct<key:string,value:string>
spark.sql.legacy.nullInEmptyListBehavior true
+-- !query
+set
spark.sql.optimizer.optimizeUncorrelatedInSubqueriesInJoinCondition.enabled=false
+-- !query schema
+struct<key:string,value:string>
+-- !query output
+spark.sql.optimizer.optimizeUncorrelatedInSubqueriesInJoinCondition.enabled
false
+
+
-- !query
select null in (select e from t_empty)
-- !query schema
@@ -215,6 +249,14 @@ struct<>
+-- !query
+reset
spark.sql.optimizer.optimizeUncorrelatedInSubqueriesInJoinCondition.enabled
+-- !query schema
+struct<>
+-- !query output
+
+
+
-- !query
drop table t
-- !query schema
diff --git
a/sql/core/src/test/resources/sql-tests/results/subquery/in-subquery/in-subquery-in-join-condition.sql.out
b/sql/core/src/test/resources/sql-tests/results/subquery/in-subquery/in-subquery-in-join-condition.sql.out
new file mode 100644
index 00000000000..9f829d522ad
--- /dev/null
+++
b/sql/core/src/test/resources/sql-tests/results/subquery/in-subquery/in-subquery-in-join-condition.sql.out
@@ -0,0 +1,436 @@
+-- Automatically generated by SQLQueryTestSuite
+-- !query
+CREATE TEMP VIEW x(x1, x2) AS VALUES
+ (2, 1),
+ (1, 1),
+ (3, 4)
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+CREATE TEMP VIEW y(y1, y2) AS VALUES
+ (0, 2),
+ (1, 4),
+ (4, 11)
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+CREATE TEMP VIEW z(z1, z2) AS VALUES
+ (4, 2),
+ (3, 3),
+ (8, 1)
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+select * from x inner join y on x1 = y1 and x2 IN (select z1 from z where z2 =
x2) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+
+
+
+-- !query
+select * from x inner join y on x1 = y1 and x2 not IN (select z1 from z where
z2 = x2) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+1 1 1 4
+
+
+-- !query
+select * from x inner join y on x1 = y1 and y2 IN (select z1 from z where z2 =
y2) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+
+
+
+-- !query
+select * from x inner join y on x1 = y1 and y2 not IN (select z1 from z where
z2 = y2) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+1 1 1 4
+
+
+-- !query
+select * from x left join y on x1 = y1 and x2 IN (select z1 from z where z2 =
x2) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+1 1 NULL NULL
+2 1 NULL NULL
+3 4 NULL NULL
+
+
+-- !query
+select * from x left join y on x1 = y1 and x2 not IN (select z1 from z where
z2 = x2) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+1 1 1 4
+2 1 NULL NULL
+3 4 NULL NULL
+
+
+-- !query
+select * from x left join y on x1 = y1 and y2 IN (select z1 from z where z2 =
y2) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+1 1 NULL NULL
+2 1 NULL NULL
+3 4 NULL NULL
+
+
+-- !query
+select * from x left join y on x1 = y1 and y2 not IN (select z1 from z where
z2 = y2) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+1 1 1 4
+2 1 NULL NULL
+3 4 NULL NULL
+
+
+-- !query
+select * from x right join y on x1 = y1 and x2 IN (select z1 from z where z2 =
x2) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+NULL NULL 0 2
+NULL NULL 1 4
+NULL NULL 4 11
+
+
+-- !query
+select * from x right join y on x1 = y1 and x2 not IN (select z1 from z where
z2 = x2) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+NULL NULL 0 2
+NULL NULL 4 11
+1 1 1 4
+
+
+-- !query
+select * from x right join y on x1 = y1 and y2 IN (select z1 from z where z2 =
y2) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+NULL NULL 0 2
+NULL NULL 1 4
+NULL NULL 4 11
+
+
+-- !query
+select * from x right join y on x1 = y1 and y2 not IN (select z1 from z where
z2 = y2) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+NULL NULL 0 2
+NULL NULL 4 11
+1 1 1 4
+
+
+-- !query
+select * from x left semi join y on x1 = y1 and x2 IN (select z1 from z where
z2 = x2) order by x1, x2
+-- !query schema
+struct<x1:int,x2:int>
+-- !query output
+
+
+
+-- !query
+select * from x left semi join y on x1 = y1 and x2 not IN (select z1 from z
where z2 = x2) order by x1, x2
+-- !query schema
+struct<x1:int,x2:int>
+-- !query output
+1 1
+
+
+-- !query
+select * from x left semi join y on x1 = y1 and y2 IN (select z1 from z where
z2 = y2) order by x1, x2
+-- !query schema
+struct<x1:int,x2:int>
+-- !query output
+
+
+
+-- !query
+select * from x left semi join y on x1 = y1 and y2 not IN (select z1 from z
where z2 = y2) order by x1, x2
+-- !query schema
+struct<x1:int,x2:int>
+-- !query output
+1 1
+
+
+-- !query
+select * from x left anti join y on x1 = y1 and x2 IN (select z1 from z where
z2 = x2) order by x1, x2
+-- !query schema
+struct<x1:int,x2:int>
+-- !query output
+1 1
+2 1
+3 4
+
+
+-- !query
+select * from x left anti join y on x1 = y1 and x2 not IN (select z1 from z
where z2 = x2) order by x1, x2
+-- !query schema
+struct<x1:int,x2:int>
+-- !query output
+2 1
+3 4
+
+
+-- !query
+select * from x left anti join y on x1 = y1 and y2 IN (select z1 from z where
z2 = y2) order by x1, x2
+-- !query schema
+struct<x1:int,x2:int>
+-- !query output
+1 1
+2 1
+3 4
+
+
+-- !query
+select * from x left anti join y on x1 = y1 and y2 not IN (select z1 from z
where z2 = y2) order by x1, x2
+-- !query schema
+struct<x1:int,x2:int>
+-- !query output
+2 1
+3 4
+
+
+-- !query
+select * from x full outer join y on x1 = y1 and x2 IN (select z1 from z where
z2 = x2) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+NULL NULL 0 2
+NULL NULL 1 4
+NULL NULL 4 11
+1 1 NULL NULL
+2 1 NULL NULL
+3 4 NULL NULL
+
+
+-- !query
+select * from x full outer join y on x1 = y1 and x2 not IN (select z1 from z
where z2 = x2) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+NULL NULL 0 2
+NULL NULL 4 11
+1 1 1 4
+2 1 NULL NULL
+3 4 NULL NULL
+
+
+-- !query
+select * from x full outer join y on x1 = y1 and y2 IN (select z1 from z where
z2 = y2) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+NULL NULL 0 2
+NULL NULL 1 4
+NULL NULL 4 11
+1 1 NULL NULL
+2 1 NULL NULL
+3 4 NULL NULL
+
+
+-- !query
+select * from x full outer join y on x1 = y1 and y2 not IN (select z1 from z
where z2 = y2) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+NULL NULL 0 2
+NULL NULL 4 11
+1 1 1 4
+2 1 NULL NULL
+3 4 NULL NULL
+
+
+-- !query
+select * from x inner join y on x1 = y1 or x2 IN (select z1 from z where z1 =
x1) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+1 1 1 4
+
+
+-- !query
+select * from x inner join y on x1 = y1 or x2 not IN (select z1 from z where
z1 = x1) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+1 1 0 2
+1 1 1 4
+1 1 4 11
+2 1 0 2
+2 1 1 4
+2 1 4 11
+3 4 0 2
+3 4 1 4
+3 4 4 11
+
+
+-- !query
+select * from x left join y on x1 = y1 or x2 IN (select z1 from z where z1 =
x1) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+1 1 1 4
+2 1 NULL NULL
+3 4 NULL NULL
+
+
+-- !query
+select * from x left join y on x1 = y1 or x2 not IN (select z1 from z where z1
= x1) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+1 1 0 2
+1 1 1 4
+1 1 4 11
+2 1 0 2
+2 1 1 4
+2 1 4 11
+3 4 0 2
+3 4 1 4
+3 4 4 11
+
+
+-- !query
+select * from x inner join y on x1 = y1 or y2 IN (select z1 from z where z1 =
y1) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+1 1 1 4
+
+
+-- !query
+select * from x inner join y on x1 = y1 or y2 not IN (select z1 from z where
z1 = y1) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+1 1 0 2
+1 1 1 4
+1 1 4 11
+2 1 0 2
+2 1 1 4
+2 1 4 11
+3 4 0 2
+3 4 1 4
+3 4 4 11
+
+
+-- !query
+select * from x left join y on x1 = y1 or y2 IN (select z1 from z where z1 =
y1) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+1 1 1 4
+2 1 NULL NULL
+3 4 NULL NULL
+
+
+-- !query
+select * from x left join y on x1 = y1 or y2 not IN (select z1 from z where z1
= y1) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+1 1 0 2
+1 1 1 4
+1 1 4 11
+2 1 0 2
+2 1 1 4
+2 1 4 11
+3 4 0 2
+3 4 1 4
+3 4 4 11
+
+
+-- !query
+select * from x inner join y on x1 = y1 and x2 IN (select z1 from z where z1 =
x1) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+
+
+
+-- !query
+select * from x inner join y on x1 = y1 and x2 not IN (select z1 from z where
z1 = x1) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+1 1 1 4
+
+
+-- !query
+select * from x left join y on x1 = y1 and x2 IN (select z1 from z where z1 =
x1) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+1 1 NULL NULL
+2 1 NULL NULL
+3 4 NULL NULL
+
+
+-- !query
+select * from x left join y on x1 = y1 and x2 not IN (select z1 from z where
z1 = x1) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+1 1 1 4
+2 1 NULL NULL
+3 4 NULL NULL
+
+
+-- !query
+select * from x inner join y on x1 = y1 and y2 IN (select z1 from z where z1 =
y1) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+
+
+
+-- !query
+select * from x inner join y on x1 = y1 and y2 not IN (select z1 from z where
z1 = y1) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+1 1 1 4
+
+
+-- !query
+select * from x left join y on x1 = y1 and y2 IN (select z1 from z where z1 =
y1) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+1 1 NULL NULL
+2 1 NULL NULL
+3 4 NULL NULL
+
+
+-- !query
+select * from x left join y on x1 = y1 and y2 not IN (select z1 from z where
z1 = y1) order by x1, x2, y1, y2
+-- !query schema
+struct<x1:int,x2:int,y1:int,y2:int>
+-- !query output
+1 1 1 4
+2 1 NULL NULL
+3 4 NULL NULL
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]