@@ -25,7 +25,7 @@ import org.apache.spark.sql.catalyst.expressions.Literal
25
25
import org .apache .spark .sql .catalyst .plans ._
26
26
import org .apache .spark .sql .catalyst .plans .logical .{LocalRelation , LogicalPlan , Project }
27
27
import org .apache .spark .sql .catalyst .rules .RuleExecutor
28
- import org .apache .spark .sql .types .StructType
28
+ import org .apache .spark .sql .types .{ IntegerType , StructType }
29
29
30
30
class PropagateEmptyRelationSuite extends PlanTest {
31
31
object Optimize extends RuleExecutor [LogicalPlan ] {
@@ -37,7 +37,8 @@ class PropagateEmptyRelationSuite extends PlanTest {
37
37
ReplaceIntersectWithSemiJoin ,
38
38
PushDownPredicate ,
39
39
PruneFilters ,
40
- PropagateEmptyRelation ) :: Nil
40
+ PropagateEmptyRelation ,
41
+ CollapseProject ) :: Nil
41
42
}
42
43
43
44
object OptimizeWithoutPropagateEmptyRelation extends RuleExecutor [LogicalPlan ] {
@@ -48,7 +49,8 @@ class PropagateEmptyRelationSuite extends PlanTest {
48
49
ReplaceExceptWithAntiJoin ,
49
50
ReplaceIntersectWithSemiJoin ,
50
51
PushDownPredicate ,
51
- PruneFilters ) :: Nil
52
+ PruneFilters ,
53
+ CollapseProject ) :: Nil
52
54
}
53
55
54
56
val testRelation1 = LocalRelation .fromExternalRows(Seq (' a .int), data = Seq (Row (1 )))
@@ -79,18 +81,21 @@ class PropagateEmptyRelationSuite extends PlanTest {
79
81
80
82
(true , false , Inner , Some (LocalRelation (' a .int, ' b .int))),
81
83
(true , false , Cross , Some (LocalRelation (' a .int, ' b .int))),
82
- (true , false , LeftOuter , Some (Project (Seq (' a , Literal (null ).as(' b )), testRelation1).analyze)),
84
+ (true , false , LeftOuter ,
85
+ Some (Project (Seq (' a , Literal (null ).cast(IntegerType ).as(' b )), testRelation1).analyze)),
83
86
(true , false , RightOuter , Some (LocalRelation (' a .int, ' b .int))),
84
- (true , false , FullOuter , Some (Project (Seq (' a , Literal (null ).as(' b )), testRelation1).analyze)),
87
+ (true , false , FullOuter ,
88
+ Some (Project (Seq (' a , Literal (null ).cast(IntegerType ).as(' b )), testRelation1).analyze)),
85
89
(true , false , LeftAnti , Some (testRelation1)),
86
90
(true , false , LeftSemi , Some (LocalRelation (' a .int))),
87
91
88
92
(false , true , Inner , Some (LocalRelation (' a .int, ' b .int))),
89
93
(false , true , Cross , Some (LocalRelation (' a .int, ' b .int))),
90
94
(false , true , LeftOuter , Some (LocalRelation (' a .int, ' b .int))),
91
95
(false , true , RightOuter ,
92
- Some (Project (Seq (Literal (null ).as(' a ), ' b ), testRelation2).analyze)),
93
- (false , true , FullOuter , Some (Project (Seq (Literal (null ).as(' a ), ' b ), testRelation2).analyze)),
96
+ Some (Project (Seq (Literal (null ).cast(IntegerType ).as(' a ), ' b ), testRelation2).analyze)),
97
+ (false , true , FullOuter ,
98
+ Some (Project (Seq (Literal (null ).cast(IntegerType ).as(' a ), ' b ), testRelation2).analyze)),
94
99
(false , true , LeftAnti , Some (LocalRelation (' a .int))),
95
100
(false , true , LeftSemi , Some (LocalRelation (' a .int))),
96
101
@@ -209,4 +214,11 @@ class PropagateEmptyRelationSuite extends PlanTest {
209
214
210
215
comparePlans(optimized, correctAnswer)
211
216
}
217
+
218
+ test(" propagate empty relation keeps the plan resolved" ) {
219
+ val query = testRelation1.join(
220
+ LocalRelation (' a .int, ' b .int), UsingJoin (FullOuter , " a" :: Nil ), None )
221
+ val optimized = Optimize .execute(query.analyze)
222
+ assert(optimized.resolved)
223
+ }
212
224
}
0 commit comments