@@ -19,15 +19,39 @@ package org.apache.spark.sql.catalyst.expressions.codegen
1919
2020import org .apache .spark .SparkFunSuite
2121import org .apache .spark .sql .catalyst .InternalRow
22- import org .apache .spark .sql .catalyst .expressions .{UnsafeProjection , LeafExpression }
22+ import org .apache .spark .sql .catalyst .expressions .{Nondeterministic , UnsafeProjection , LeafExpression }
2323import org .apache .spark .sql .types .{BooleanType , DataType }
2424
2525/**
2626 * A test suite that makes sure code generation handles expression internally states correctly.
2727 */
2828class CodegenExpressionCachingSuite extends SparkFunSuite {
2929
30- test(" GenerateUnsafeProjection" ) {
30+ test(" GenerateUnsafeProjection should initialize expressions" ) {
31+ val expr = NondeterministicExpression ()
32+ val instance = UnsafeProjection .create(Seq (expr))
33+ assert(instance.apply(null ).getBoolean(0 ) === false )
34+ }
35+
36+ test(" GenerateProjection should initialize expressions" ) {
37+ val expr = NondeterministicExpression ()
38+ val instance = GenerateProjection .generate(Seq (expr))
39+ assert(instance.apply(null ).getBoolean(0 ) === false )
40+ }
41+
42+ test(" GenerateMutableProjection should initialize expressions" ) {
43+ val expr = NondeterministicExpression ()
44+ val instance = GenerateMutableProjection .generate(Seq (expr))()
45+ assert(instance.apply(null ).getBoolean(0 ) === false )
46+ }
47+
48+ test(" GeneratePredicate should initialize expressions" ) {
49+ val expr = NondeterministicExpression ()
50+ val instance = GeneratePredicate .generate(expr)
51+ assert(instance.apply(null ) === false )
52+ }
53+
54+ test(" GenerateUnsafeProjection should not share expression instances" ) {
3155 val expr1 = MutableExpression ()
3256 val instance1 = UnsafeProjection .create(Seq (expr1))
3357 assert(instance1.apply(null ).getBoolean(0 ) === false )
@@ -39,7 +63,7 @@ class CodegenExpressionCachingSuite extends SparkFunSuite {
3963 assert(instance2.apply(null ).getBoolean(0 ) === true )
4064 }
4165
42- test(" GenerateProjection" ) {
66+ test(" GenerateProjection should not share expression instances " ) {
4367 val expr1 = MutableExpression ()
4468 val instance1 = GenerateProjection .generate(Seq (expr1))
4569 assert(instance1.apply(null ).getBoolean(0 ) === false )
@@ -51,7 +75,7 @@ class CodegenExpressionCachingSuite extends SparkFunSuite {
5175 assert(instance2.apply(null ).getBoolean(0 ) === true )
5276 }
5377
54- test(" GenerateMutableProjection" ) {
78+ test(" GenerateMutableProjection should not share expression instances " ) {
5579 val expr1 = MutableExpression ()
5680 val instance1 = GenerateMutableProjection .generate(Seq (expr1))()
5781 assert(instance1.apply(null ).getBoolean(0 ) === false )
@@ -63,7 +87,7 @@ class CodegenExpressionCachingSuite extends SparkFunSuite {
6387 assert(instance2.apply(null ).getBoolean(0 ) === true )
6488 }
6589
66- test(" GeneratePredicate" ) {
90+ test(" GeneratePredicate should not share expression instances " ) {
6791 val expr1 = MutableExpression ()
6892 val instance1 = GeneratePredicate .generate(expr1)
6993 assert(instance1.apply(null ) === false )
@@ -77,6 +101,17 @@ class CodegenExpressionCachingSuite extends SparkFunSuite {
77101
78102}
79103
104+ /**
105+ * An expression that's non-deterministic and doesn't support codegen.
106+ */
107+ case class NondeterministicExpression ()
108+ extends LeafExpression with Nondeterministic with CodegenFallback {
109+ override protected def initInternal (): Unit = {}
110+ override protected def evalInternal (input : InternalRow ): Any = false
111+ override def nullable : Boolean = false
112+ override def dataType : DataType = BooleanType
113+ }
114+
80115
81116/**
82117 * An expression with mutable state so we can change it freely in our test suite.
0 commit comments