17
17
18
18
package org .apache .spark .sql .catalyst .expressions
19
19
20
+ import scala .math ._
21
+
20
22
import org .apache .spark .SparkFunSuite
23
+ import org .apache .spark .sql .{Row , RandomDataGenerator }
24
+ import org .apache .spark .sql .catalyst .CatalystTypeConverters
21
25
import org .apache .spark .sql .catalyst .dsl .expressions ._
22
26
import org .apache .spark .sql .catalyst .expressions .codegen ._
27
+ import org .apache .spark .sql .types .{DataTypeTestUtils , NullType , StructField , StructType }
23
28
24
29
/**
25
30
* Additional tests for code generation.
@@ -42,4 +47,47 @@ class CodeGenerationSuite extends SparkFunSuite {
42
47
43
48
futures.foreach(Await .result(_, 10 .seconds))
44
49
}
50
+
51
+ // Test GenerateOrdering for all common types. For each type, we construct random input rows that
52
+ // contain two columns of that type, then for pairs of randomly-generated rows we check that
53
+ // GenerateOrdering agrees with RowOrdering.
54
+ (DataTypeTestUtils .atomicTypes ++ Set (NullType )).foreach { dataType =>
55
+ test(s " GenerateOrdering with $dataType" ) {
56
+ val rowOrdering = RowOrdering .forSchema(Seq (dataType, dataType))
57
+ val genOrdering = GenerateOrdering .generate(
58
+ BoundReference (0 , dataType, nullable = true ).asc ::
59
+ BoundReference (1 , dataType, nullable = true ).asc :: Nil )
60
+ val rowType = StructType (
61
+ StructField (" a" , dataType, nullable = true ) ::
62
+ StructField (" b" , dataType, nullable = true ) :: Nil )
63
+ val toCatalyst = CatalystTypeConverters .createToCatalystConverter(rowType)
64
+ // Sort ordering is not defined for NaN, so skip any random inputs that contain it:
65
+ def isIncomparable (v : Any ): Boolean = v match {
66
+ case d : Double => java.lang.Double .isNaN(d)
67
+ case f : Float => java.lang.Float .isNaN(f)
68
+ case _ => false
69
+ }
70
+ RandomDataGenerator .forType(rowType, nullable = false ).foreach { randGenerator =>
71
+ for (_ <- 1 to 50 ) {
72
+ val aExt = randGenerator().asInstanceOf [Row ]
73
+ val bExt = randGenerator().asInstanceOf [Row ]
74
+ if ((aExt.toSeq ++ bExt.toSeq).forall(v => ! isIncomparable(v))) {
75
+ val a = toCatalyst(aExt).asInstanceOf [InternalRow ]
76
+ val b = toCatalyst(bExt).asInstanceOf [InternalRow ]
77
+ withClue(s " a = $a, b = $b" ) {
78
+ assert(genOrdering.compare(a, a) === 0 )
79
+ assert(genOrdering.compare(b, b) === 0 )
80
+ assert(rowOrdering.compare(a, a) === 0 )
81
+ assert(rowOrdering.compare(b, b) === 0 )
82
+ assert(signum(genOrdering.compare(a, b)) === - 1 * signum(genOrdering.compare(b, a)))
83
+ assert(signum(rowOrdering.compare(a, b)) === - 1 * signum(rowOrdering.compare(b, a)))
84
+ assert(
85
+ signum(rowOrdering.compare(a, b)) === signum(genOrdering.compare(a, b)),
86
+ " Generated and non-generated orderings should agree" )
87
+ }
88
+ }
89
+ }
90
+ }
91
+ }
92
+ }
45
93
}
0 commit comments