@@ -24,6 +24,7 @@ import java.util.concurrent.atomic.AtomicBoolean
2424
2525import org .apache .spark .{AccumulatorSuite , SparkException }
2626import org .apache .spark .scheduler .{SparkListener , SparkListenerJobStart }
27+ import org .apache .spark .sql .catalyst .optimizer .ConvertToLocalRelation
2728import org .apache .spark .sql .catalyst .util .StringUtils
2829import org .apache .spark .sql .execution .aggregate .{HashAggregateExec , SortAggregateExec }
2930import org .apache .spark .sql .execution .columnar .InMemoryTableScanExec
@@ -3149,6 +3150,7 @@ class SQLQuerySuite extends QueryTest with SharedSparkSession {
31493150 checkAnswer(sql(" select * from t1 where d > '1999-13'" ), Row (result))
31503151 checkAnswer(sql(" select to_timestamp('2000-01-01 01:10:00') > '1'" ), Row (true ))
31513152 }
3153+ sql(" DROP VIEW t1" )
31523154 }
31533155
31543156 test(" SPARK-28156: self-join should not miss cached view" ) {
@@ -3192,6 +3194,21 @@ class SQLQuerySuite extends QueryTest with SharedSparkSession {
31923194 checkAnswer(df3, Array (Row (new java.math.BigDecimal (" 0.100000000000000000000000100" ))))
31933195 }
31943196 }
3197+
3198+ test(" SPARK-29239: Subquery should not cause NPE when eliminating subexpression" ) {
3199+ withSQLConf(SQLConf .WHOLESTAGE_CODEGEN_ENABLED .key -> " false" ,
3200+ SQLConf .SUBQUERY_REUSE_ENABLED .key -> " false" ,
3201+ SQLConf .CODEGEN_FACTORY_MODE .key -> " CODEGEN_ONLY" ,
3202+ SQLConf .OPTIMIZER_EXCLUDED_RULES .key -> ConvertToLocalRelation .ruleName) {
3203+ withTempView(" t1" , " t2" ) {
3204+ sql(" create temporary view t1 as select * from values ('val1a', 10L) as t1(t1a, t1b)" )
3205+ sql(" create temporary view t2 as select * from values ('val3a', 110L) as t2(t2a, t2b)" )
3206+ val df = sql(" SELECT min, min from (SELECT (SELECT min(t2b) FROM t2) min " +
3207+ " FROM t1 WHERE t1a = 'val1c')" )
3208+ assert(df.collect().size == 0 )
3209+ }
3210+ }
3211+ }
31953212}
31963213
31973214case class Foo (bar : Option [String ])
0 commit comments