Skip to content

Commit

Permalink
[SPARK-9526] [SQL] Utilize randomized tests to reveal potential bugs …
Browse files Browse the repository at this point in the history
…in sql expressions

JIRA: https://issues.apache.org/jira/browse/SPARK-9526

This PR is a follow up of #7830, aiming at utilizing randomized tests to reveal more potential bugs in sql expression.

Author: Yijie Shen <henry.yijieshen@gmail.com>

Closes #7855 from yjshen/property_check.
  • Loading branch information
yjshen authored and JoshRosen committed Aug 17, 2015
1 parent f10660f commit b265e28
Show file tree
Hide file tree
Showing 10 changed files with 410 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ class ArithmeticExpressionSuite extends SparkFunSuite with ExpressionEvalHelper
checkEvaluation(Add(positiveShortLit, negativeShortLit), -1.toShort)
checkEvaluation(Add(positiveIntLit, negativeIntLit), -1)
checkEvaluation(Add(positiveLongLit, negativeLongLit), -1L)

DataTypeTestUtils.numericAndInterval.foreach { tpe =>
checkConsistencyBetweenInterpretedAndCodegen(Add, tpe, tpe)
}
}

test("- (UnaryMinus)") {
Expand All @@ -71,6 +75,10 @@ class ArithmeticExpressionSuite extends SparkFunSuite with ExpressionEvalHelper
checkEvaluation(UnaryMinus(negativeIntLit), - negativeInt)
checkEvaluation(UnaryMinus(positiveLongLit), - positiveLong)
checkEvaluation(UnaryMinus(negativeLongLit), - negativeLong)

DataTypeTestUtils.numericAndInterval.foreach { tpe =>
checkConsistencyBetweenInterpretedAndCodegen(UnaryMinus, tpe)
}
}

test("- (Minus)") {
Expand All @@ -85,6 +93,10 @@ class ArithmeticExpressionSuite extends SparkFunSuite with ExpressionEvalHelper
(positiveShort - negativeShort).toShort)
checkEvaluation(Subtract(positiveIntLit, negativeIntLit), positiveInt - negativeInt)
checkEvaluation(Subtract(positiveLongLit, negativeLongLit), positiveLong - negativeLong)

DataTypeTestUtils.numericAndInterval.foreach { tpe =>
checkConsistencyBetweenInterpretedAndCodegen(Subtract, tpe, tpe)
}
}

test("* (Multiply)") {
Expand All @@ -99,6 +111,10 @@ class ArithmeticExpressionSuite extends SparkFunSuite with ExpressionEvalHelper
(positiveShort * negativeShort).toShort)
checkEvaluation(Multiply(positiveIntLit, negativeIntLit), positiveInt * negativeInt)
checkEvaluation(Multiply(positiveLongLit, negativeLongLit), positiveLong * negativeLong)

DataTypeTestUtils.numericTypeWithoutDecimal.foreach { tpe =>
checkConsistencyBetweenInterpretedAndCodegen(Multiply, tpe, tpe)
}
}

test("/ (Divide) basic") {
Expand All @@ -111,6 +127,10 @@ class ArithmeticExpressionSuite extends SparkFunSuite with ExpressionEvalHelper
checkEvaluation(Divide(left, Literal.create(null, right.dataType)), null)
checkEvaluation(Divide(left, Literal(convert(0))), null) // divide by zero
}

DataTypeTestUtils.numericTypeWithoutDecimal.foreach { tpe =>
checkConsistencyBetweenInterpretedAndCodegen(Divide, tpe, tpe)
}
}

test("/ (Divide) for integral type") {
Expand Down Expand Up @@ -144,6 +164,12 @@ class ArithmeticExpressionSuite extends SparkFunSuite with ExpressionEvalHelper
checkEvaluation(Remainder(negativeIntLit, negativeIntLit), 0)
checkEvaluation(Remainder(positiveLongLit, positiveLongLit), 0L)
checkEvaluation(Remainder(negativeLongLit, negativeLongLit), 0L)

// TODO: the following lines would fail the test due to inconsistency result of interpret
// and codegen for remainder between giant values, seems like a numeric stability issue
// DataTypeTestUtils.numericTypeWithoutDecimal.foreach { tpe =>
// checkConsistencyBetweenInterpretedAndCodegen(Remainder, tpe, tpe)
// }
}

test("Abs") {
Expand All @@ -161,6 +187,10 @@ class ArithmeticExpressionSuite extends SparkFunSuite with ExpressionEvalHelper
checkEvaluation(Abs(negativeIntLit), - negativeInt)
checkEvaluation(Abs(positiveLongLit), positiveLong)
checkEvaluation(Abs(negativeLongLit), - negativeLong)

DataTypeTestUtils.numericTypeWithoutDecimal.foreach { tpe =>
checkConsistencyBetweenInterpretedAndCodegen(Abs, tpe)
}
}

test("MaxOf basic") {
Expand All @@ -175,6 +205,10 @@ class ArithmeticExpressionSuite extends SparkFunSuite with ExpressionEvalHelper
checkEvaluation(MaxOf(positiveShortLit, negativeShortLit), (positiveShort).toShort)
checkEvaluation(MaxOf(positiveIntLit, negativeIntLit), positiveInt)
checkEvaluation(MaxOf(positiveLongLit, negativeLongLit), positiveLong)

DataTypeTestUtils.ordered.foreach { tpe =>
checkConsistencyBetweenInterpretedAndCodegen(MaxOf, tpe, tpe)
}
}

test("MaxOf for atomic type") {
Expand All @@ -196,6 +230,10 @@ class ArithmeticExpressionSuite extends SparkFunSuite with ExpressionEvalHelper
checkEvaluation(MinOf(positiveShortLit, negativeShortLit), (negativeShort).toShort)
checkEvaluation(MinOf(positiveIntLit, negativeIntLit), negativeInt)
checkEvaluation(MinOf(positiveLongLit, negativeLongLit), negativeLong)

DataTypeTestUtils.ordered.foreach { tpe =>
checkConsistencyBetweenInterpretedAndCodegen(MinOf, tpe, tpe)
}
}

test("MinOf for atomic type") {
Expand All @@ -222,4 +260,8 @@ class ArithmeticExpressionSuite extends SparkFunSuite with ExpressionEvalHelper
checkEvaluation(Pmod(positiveInt, negativeInt), positiveInt)
checkEvaluation(Pmod(positiveLong, negativeLong), positiveLong)
}

DataTypeTestUtils.numericTypeWithoutDecimal.foreach { tpe =>
checkConsistencyBetweenInterpretedAndCodegen(MinOf, tpe, tpe)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ class BitwiseFunctionsSuite extends SparkFunSuite with ExpressionEvalHelper {
checkEvaluation(BitwiseNot(negativeIntLit), ~negativeInt)
checkEvaluation(BitwiseNot(positiveLongLit), ~positiveLong)
checkEvaluation(BitwiseNot(negativeLongLit), ~negativeLong)

DataTypeTestUtils.integralType.foreach { dt =>
checkConsistencyBetweenInterpretedAndCodegen(BitwiseNot, dt)
}
}

test("BitwiseAnd") {
Expand All @@ -68,6 +72,10 @@ class BitwiseFunctionsSuite extends SparkFunSuite with ExpressionEvalHelper {
(positiveShort & negativeShort).toShort)
checkEvaluation(BitwiseAnd(positiveIntLit, negativeIntLit), positiveInt & negativeInt)
checkEvaluation(BitwiseAnd(positiveLongLit, negativeLongLit), positiveLong & negativeLong)

DataTypeTestUtils.integralType.foreach { dt =>
checkConsistencyBetweenInterpretedAndCodegen(BitwiseAnd, dt, dt)
}
}

test("BitwiseOr") {
Expand All @@ -91,6 +99,10 @@ class BitwiseFunctionsSuite extends SparkFunSuite with ExpressionEvalHelper {
(positiveShort | negativeShort).toShort)
checkEvaluation(BitwiseOr(positiveIntLit, negativeIntLit), positiveInt | negativeInt)
checkEvaluation(BitwiseOr(positiveLongLit, negativeLongLit), positiveLong | negativeLong)

DataTypeTestUtils.integralType.foreach { dt =>
checkConsistencyBetweenInterpretedAndCodegen(BitwiseOr, dt, dt)
}
}

test("BitwiseXor") {
Expand All @@ -110,10 +122,13 @@ class BitwiseFunctionsSuite extends SparkFunSuite with ExpressionEvalHelper {
checkEvaluation(BitwiseXor(nullLit, Literal(1)), null)
checkEvaluation(BitwiseXor(Literal(1), nullLit), null)
checkEvaluation(BitwiseXor(nullLit, nullLit), null)

checkEvaluation(BitwiseXor(positiveShortLit, negativeShortLit),
(positiveShort ^ negativeShort).toShort)
checkEvaluation(BitwiseXor(positiveIntLit, negativeIntLit), positiveInt ^ negativeInt)
checkEvaluation(BitwiseXor(positiveLongLit, negativeLongLit), positiveLong ^ negativeLong)

DataTypeTestUtils.integralType.foreach { dt =>
checkConsistencyBetweenInterpretedAndCodegen(BitwiseXor, dt, dt)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ class ConditionalExpressionSuite extends SparkFunSuite with ExpressionEvalHelper
testIf(_.toLong, TimestampType)

testIf(_.toString, StringType)

DataTypeTestUtils.propertyCheckSupported.foreach { dt =>
checkConsistencyBetweenInterpretedAndCodegen(If, BooleanType, dt, dt)
}
}

test("case when") {
Expand Down Expand Up @@ -176,6 +180,10 @@ class ConditionalExpressionSuite extends SparkFunSuite with ExpressionEvalHelper
Literal(Timestamp.valueOf("2015-07-01 08:00:00")),
Literal(Timestamp.valueOf("2015-07-01 10:00:00")))),
Timestamp.valueOf("2015-07-01 08:00:00"), InternalRow.empty)

DataTypeTestUtils.ordered.foreach { dt =>
checkConsistencyBetweenInterpretedAndCodegen(Least, dt, 2)
}
}

test("function greatest") {
Expand Down Expand Up @@ -218,6 +226,9 @@ class ConditionalExpressionSuite extends SparkFunSuite with ExpressionEvalHelper
Literal(Timestamp.valueOf("2015-07-01 08:00:00")),
Literal(Timestamp.valueOf("2015-07-01 10:00:00")))),
Timestamp.valueOf("2015-07-01 10:00:00"), InternalRow.empty)
}

DataTypeTestUtils.ordered.foreach { dt =>
checkConsistencyBetweenInterpretedAndCodegen(Greatest, dt, 2)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class DateExpressionsSuite extends SparkFunSuite with ExpressionEvalHelper {
}
}
checkEvaluation(DayOfYear(Literal.create(null, DateType)), null)
checkConsistencyBetweenInterpretedAndCodegen(DayOfYear, DateType)
}

test("Year") {
Expand All @@ -79,6 +80,7 @@ class DateExpressionsSuite extends SparkFunSuite with ExpressionEvalHelper {
}
}
}
checkConsistencyBetweenInterpretedAndCodegen(Year, DateType)
}

test("Quarter") {
Expand All @@ -98,6 +100,7 @@ class DateExpressionsSuite extends SparkFunSuite with ExpressionEvalHelper {
}
}
}
checkConsistencyBetweenInterpretedAndCodegen(Quarter, DateType)
}

test("Month") {
Expand All @@ -117,6 +120,7 @@ class DateExpressionsSuite extends SparkFunSuite with ExpressionEvalHelper {
}
}
}
checkConsistencyBetweenInterpretedAndCodegen(Month, DateType)
}

test("Day / DayOfMonth") {
Expand All @@ -135,6 +139,7 @@ class DateExpressionsSuite extends SparkFunSuite with ExpressionEvalHelper {
c.get(Calendar.DAY_OF_MONTH))
}
}
checkConsistencyBetweenInterpretedAndCodegen(DayOfMonth, DateType)
}

test("Seconds") {
Expand All @@ -149,6 +154,7 @@ class DateExpressionsSuite extends SparkFunSuite with ExpressionEvalHelper {
checkEvaluation(Second(Literal(new Timestamp(c.getTimeInMillis))),
c.get(Calendar.SECOND))
}
checkConsistencyBetweenInterpretedAndCodegen(Second, TimestampType)
}

test("WeekOfYear") {
Expand All @@ -157,6 +163,7 @@ class DateExpressionsSuite extends SparkFunSuite with ExpressionEvalHelper {
checkEvaluation(WeekOfYear(Cast(Literal(sdfDate.format(d)), DateType)), 15)
checkEvaluation(WeekOfYear(Cast(Literal(ts), DateType)), 45)
checkEvaluation(WeekOfYear(Cast(Literal("2011-05-06"), DateType)), 18)
checkConsistencyBetweenInterpretedAndCodegen(WeekOfYear, DateType)
}

test("DateFormat") {
Expand Down Expand Up @@ -184,6 +191,7 @@ class DateExpressionsSuite extends SparkFunSuite with ExpressionEvalHelper {
}
}
}
checkConsistencyBetweenInterpretedAndCodegen(Hour, TimestampType)
}

test("Minute") {
Expand All @@ -200,6 +208,7 @@ class DateExpressionsSuite extends SparkFunSuite with ExpressionEvalHelper {
c.get(Calendar.MINUTE))
}
}
checkConsistencyBetweenInterpretedAndCodegen(Minute, TimestampType)
}

test("date_add") {
Expand All @@ -218,6 +227,7 @@ class DateExpressionsSuite extends SparkFunSuite with ExpressionEvalHelper {
DateAdd(Literal(Date.valueOf("2016-02-28")), positiveIntLit), 49627)
checkEvaluation(
DateAdd(Literal(Date.valueOf("2016-02-28")), negativeIntLit), -15910)
checkConsistencyBetweenInterpretedAndCodegen(DateAdd, DateType, IntegerType)
}

test("date_sub") {
Expand All @@ -236,6 +246,7 @@ class DateExpressionsSuite extends SparkFunSuite with ExpressionEvalHelper {
DateSub(Literal(Date.valueOf("2016-02-28")), positiveIntLit), -15909)
checkEvaluation(
DateSub(Literal(Date.valueOf("2016-02-28")), negativeIntLit), 49628)
checkConsistencyBetweenInterpretedAndCodegen(DateSub, DateType, IntegerType)
}

test("time_add") {
Expand All @@ -254,6 +265,7 @@ class DateExpressionsSuite extends SparkFunSuite with ExpressionEvalHelper {
checkEvaluation(
TimeAdd(Literal.create(null, TimestampType), Literal.create(null, CalendarIntervalType)),
null)
checkConsistencyBetweenInterpretedAndCodegen(TimeAdd, TimestampType, CalendarIntervalType)
}

test("time_sub") {
Expand All @@ -277,6 +289,7 @@ class DateExpressionsSuite extends SparkFunSuite with ExpressionEvalHelper {
checkEvaluation(
TimeSub(Literal.create(null, TimestampType), Literal.create(null, CalendarIntervalType)),
null)
checkConsistencyBetweenInterpretedAndCodegen(TimeSub, TimestampType, CalendarIntervalType)
}

test("add_months") {
Expand All @@ -296,6 +309,7 @@ class DateExpressionsSuite extends SparkFunSuite with ExpressionEvalHelper {
AddMonths(Literal(Date.valueOf("2016-02-28")), positiveIntLit), 1014213)
checkEvaluation(
AddMonths(Literal(Date.valueOf("2016-02-28")), negativeIntLit), -980528)
checkConsistencyBetweenInterpretedAndCodegen(AddMonths, DateType, IntegerType)
}

test("months_between") {
Expand All @@ -320,6 +334,7 @@ class DateExpressionsSuite extends SparkFunSuite with ExpressionEvalHelper {
checkEvaluation(MonthsBetween(t, tnull), null)
checkEvaluation(MonthsBetween(tnull, t), null)
checkEvaluation(MonthsBetween(tnull, tnull), null)
checkConsistencyBetweenInterpretedAndCodegen(MonthsBetween, TimestampType, TimestampType)
}

test("last_day") {
Expand All @@ -337,6 +352,7 @@ class DateExpressionsSuite extends SparkFunSuite with ExpressionEvalHelper {
checkEvaluation(LastDay(Literal(Date.valueOf("2016-01-06"))), Date.valueOf("2016-01-31"))
checkEvaluation(LastDay(Literal(Date.valueOf("2016-02-07"))), Date.valueOf("2016-02-29"))
checkEvaluation(LastDay(Literal.create(null, DateType)), null)
checkConsistencyBetweenInterpretedAndCodegen(LastDay, DateType)
}

test("next_day") {
Expand Down Expand Up @@ -370,6 +386,7 @@ class DateExpressionsSuite extends SparkFunSuite with ExpressionEvalHelper {
ToDate(Literal(Date.valueOf("2015-07-22"))),
DateTimeUtils.fromJavaDate(Date.valueOf("2015-07-22")))
checkEvaluation(ToDate(Literal.create(null, DateType)), null)
checkConsistencyBetweenInterpretedAndCodegen(ToDate, DateType)
}

test("function trunc") {
Expand Down
Loading

0 comments on commit b265e28

Please sign in to comment.