@@ -443,4 +443,40 @@ class CometJoinSuite extends CometTestBase {
443443 }
444444 }
445445 }
446+
447+ // Reproducer for SPARK-43113: full outer SMJ with a join filter that references
448+ // a nullable column should not match when the filter evaluates to NULL.
449+ test(" SPARK-43113: Full outer SMJ with NULL in join filter" ) {
450+ withTempView(" l" , " r" ) {
451+ // testData2: (a, b) — all non-null
452+ Seq ((1 , 1 ), (1 , 2 ), (2 , 1 ), (2 , 2 ), (3 , 1 ), (3 , 2 ))
453+ .toDF(" a" , " b" )
454+ .createOrReplaceTempView(" l" )
455+
456+ // testData3: (a, b) — b is nullable
457+ Seq ((1 , None ), (2 , Some (2 )))
458+ .toDF(" a" , " b" )
459+ .createOrReplaceTempView(" r" )
460+
461+ val query =
462+ """ select /*+ MERGE(r) */ *
463+ |from l
464+ |full outer join r
465+ |on l.a = r.a
466+ |and l.b < (r.b + 1)
467+ |and l.b < (r.a + 1)""" .stripMargin
468+
469+ val expected = Seq (
470+ (Some (1 ), Some (1 ), None , None ),
471+ (Some (1 ), Some (2 ), None , None ),
472+ (None , None , Some (1 ), None ),
473+ (Some (2 ), Some (1 ), Some (2 ), Some (2 )),
474+ (Some (2 ), Some (2 ), Some (2 ), Some (2 )),
475+ (Some (3 ), Some (1 ), None , None ),
476+ (Some (3 ), Some (2 ), None , None )).toDF(" a" , " b" , " a" , " b" )
477+
478+ val df = sql(query)
479+ checkAnswer(df, expected)
480+ }
481+ }
446482}
0 commit comments