This is an automated email from the ASF dual-hosted git repository.
philo-he pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gluten.git
The following commit(s) were added to refs/heads/main by this push:
new 3801653fe5 [GLUTEN-10134][VL] Add runQueryAndCheck helper for ANSI
mode tests (#13184)
3801653fe5 is described below
commit 3801653fe50c9946ea83a1dec7155d02fea64a07
Author: rdtr <[email protected]>
AuthorDate: Tue Oct 13 23:23:25 2026 -0700
[GLUTEN-10134][VL] Add runQueryAndCheck helper for ANSI mode tests (#13184)
---
.../apache/gluten/execution/FallbackSuite.scala | 40 +--
.../gluten/execution/MiscOperatorSuite.scala | 21 +-
.../gluten/expression/UDFPartialProjectSuite.scala | 5 +-
.../functions/DateFunctionsValidateSuite.scala | 2 +-
.../functions/MathFunctionsValidateSuite.scala | 4 +-
.../functions/ScalarFunctionsValidateSuite.scala | 280 +++++++++++----------
.../execution/GlutenQueryComparisonTest.scala | 30 +++
7 files changed, 220 insertions(+), 162 deletions(-)
diff --git
a/backends-velox/src/test/scala/org/apache/gluten/execution/FallbackSuite.scala
b/backends-velox/src/test/scala/org/apache/gluten/execution/FallbackSuite.scala
index 575324162b..b9279e126f 100644
---
a/backends-velox/src/test/scala/org/apache/gluten/execution/FallbackSuite.scala
+++
b/backends-velox/src/test/scala/org/apache/gluten/execution/FallbackSuite.scala
@@ -375,25 +375,29 @@ class FallbackSuite extends
VeloxWholeStageTransformerSuite with AdaptiveSparkPl
}
test("fallback when nested loop join has unsupported expression") {
- GlutenSuiteUtils.withFallbackEventListener(spark.sparkContext) {
- events =>
- val df = spark.sql("""
- |select tmp1.c1, tmp1.c2 from tmp1
- |left join tmp2 on (
- | tmp1.c1 = regexp_extract(tmp2.c1,
'(?<=@)[^.]+(?=\.)', 0)
- | or tmp2.c1 > 10
- |)
- |""".stripMargin)
- df.collect()
- GlutenSuiteUtils.waitUntilEmpty(spark.sparkContext)
+ // The join condition casts strings such as '' to bigint, which fails in
ANSI mode. This test
+ // checks the fallback reason, so run it with ANSI mode disabled.
+ withSQLConf(SQLConf.ANSI_ENABLED.key -> "false") {
+ GlutenSuiteUtils.withFallbackEventListener(spark.sparkContext) {
+ events =>
+ val df = spark.sql("""
+ |select tmp1.c1, tmp1.c2 from tmp1
+ |left join tmp2 on (
+ | tmp1.c1 = regexp_extract(tmp2.c1,
'(?<=@)[^.]+(?=\.)', 0)
+ | or tmp2.c1 > 10
+ |)
+ |""".stripMargin)
+ df.collect()
+ GlutenSuiteUtils.waitUntilEmpty(spark.sparkContext)
- val nestedLoopJoin = find(df.queryExecution.executedPlan) {
- _.isInstanceOf[BroadcastNestedLoopJoinExec]
- }
- assert(nestedLoopJoin.isDefined)
- val fallbackReasons = events.flatMap(_.fallbackNodeToReason.values)
- assert(fallbackReasons.nonEmpty)
- assert(fallbackReasons.forall(_.contains("regexp_extract due to
Pattern")))
+ val nestedLoopJoin = find(df.queryExecution.executedPlan) {
+ _.isInstanceOf[BroadcastNestedLoopJoinExec]
+ }
+ assert(nestedLoopJoin.isDefined)
+ val fallbackReasons = events.flatMap(_.fallbackNodeToReason.values)
+ assert(fallbackReasons.nonEmpty)
+ assert(fallbackReasons.forall(_.contains("regexp_extract due to
Pattern")))
+ }
}
}
diff --git
a/backends-velox/src/test/scala/org/apache/gluten/execution/MiscOperatorSuite.scala
b/backends-velox/src/test/scala/org/apache/gluten/execution/MiscOperatorSuite.scala
index 0eb44db73a..da2c0a569a 100644
---
a/backends-velox/src/test/scala/org/apache/gluten/execution/MiscOperatorSuite.scala
+++
b/backends-velox/src/test/scala/org/apache/gluten/execution/MiscOperatorSuite.scala
@@ -1664,12 +1664,17 @@ class MiscOperatorSuite extends
VeloxWholeStageTransformerSuite with AdaptiveSpa
}
test("Support multi-children count with row construct") {
- runQueryAndCompare(
- """
- |select l_orderkey, count(distinct l_partkey, l_comment),
corr(l_partkey, l_partkey+1)
- |from lineitem group by l_orderkey
- |""".stripMargin
- )(df => checkFallbackOperators(df, 0))
+ // Spark before 4.3 (SPARK-58213) throws DIVIDE_BY_ZERO for corr on a
column with zero variance
+ // in ANSI mode, while Velox returns NULL as Spark 4.3 does. Run with ANSI
mode disabled for
+ // now, see https://github.com/apache/gluten/issues/13255.
+ withSQLConf(SQLConf.ANSI_ENABLED.key -> "false") {
+ runQueryAndCompare(
+ """
+ |select l_orderkey, count(distinct l_partkey, l_comment),
corr(l_partkey, l_partkey+1)
+ |from lineitem group by l_orderkey
+ |""".stripMargin
+ )(df => checkFallbackOperators(df, 0))
+ }
}
test("Remainder with non-foldable right side") {
@@ -1680,7 +1685,7 @@ class MiscOperatorSuite extends
VeloxWholeStageTransformerSuite with AdaptiveSpa
|""".stripMargin)
spark.sql("INSERT INTO TABLE remainder VALUES(0, null)")
- runQueryAndCompare("SELECT c1 % c2 FROM remainder")(df =>
checkFallbackOperators(df, 0))
+ runQueryAndCheck("SELECT c1 % c2 FROM remainder")(df =>
checkFallbackOperators(df, 0))
}
}
@@ -1917,7 +1922,7 @@ class MiscOperatorSuite extends
VeloxWholeStageTransformerSuite with AdaptiveSpa
Seq("2023-01-01", "2023-01-02", "-1", "-111-01-01")
.toDF("dateColumn")
.createOrReplaceTempView("view")
- runQueryAndCompare("SELECT cast(dateColumn as date) from view") {
+ runQueryAndCheck("SELECT cast(dateColumn as date) from view") {
checkGlutenPlan[ProjectExecTransformer]
}
}
diff --git
a/backends-velox/src/test/scala/org/apache/gluten/expression/UDFPartialProjectSuite.scala
b/backends-velox/src/test/scala/org/apache/gluten/expression/UDFPartialProjectSuite.scala
index a8287f7e0a..1fd47bcef5 100644
---
a/backends-velox/src/test/scala/org/apache/gluten/expression/UDFPartialProjectSuite.scala
+++
b/backends-velox/src/test/scala/org/apache/gluten/expression/UDFPartialProjectSuite.scala
@@ -155,8 +155,9 @@ class UDFPartialProjectSuite extends
WholeStageTransformerSuite {
}
test("udf in agg simple") {
- runQueryAndCompare("""select sum(hash(plus_one(l_extendedprice)) +
hash(l_orderkey) ) as revenue
- | from lineitem""".stripMargin) {
+ runQueryAndCheck(
+ """select sum(hash(plus_one(l_extendedprice)) + hash(l_orderkey) ) as
revenue
+ | from lineitem""".stripMargin) {
checkGlutenPlan[ColumnarPartialProjectExec]
}
}
diff --git
a/backends-velox/src/test/scala/org/apache/gluten/functions/DateFunctionsValidateSuite.scala
b/backends-velox/src/test/scala/org/apache/gluten/functions/DateFunctionsValidateSuite.scala
index 420da5db67..72798f58d0 100644
---
a/backends-velox/src/test/scala/org/apache/gluten/functions/DateFunctionsValidateSuite.scala
+++
b/backends-velox/src/test/scala/org/apache/gluten/functions/DateFunctionsValidateSuite.scala
@@ -169,7 +169,7 @@ class DateFunctionsValidateSuite extends
FunctionsValidateSuite {
}
test("make_date") {
- runQueryAndCompare(
+ runQueryAndCheck(
"select make_date(2025, 2, 7), make_date(2024, 11, null),
make_date(2024, 11, 50)") {
checkGlutenPlan[ProjectExecTransformer]
}
diff --git
a/backends-velox/src/test/scala/org/apache/gluten/functions/MathFunctionsValidateSuite.scala
b/backends-velox/src/test/scala/org/apache/gluten/functions/MathFunctionsValidateSuite.scala
index dae50a7296..13f3f4feea 100644
---
a/backends-velox/src/test/scala/org/apache/gluten/functions/MathFunctionsValidateSuite.scala
+++
b/backends-velox/src/test/scala/org/apache/gluten/functions/MathFunctionsValidateSuite.scala
@@ -451,7 +451,7 @@ class MathFunctionsValidateSuite extends
FunctionsValidateSuite {
Seq("true", "false").foreach {
enabled =>
withSQLConf("spark.sql.decimalOperations.allowPrecisionLoss" ->
enabled) {
- runQueryAndCompare("SELECT a - b, a + b, a * b, a / b FROM t") {
+ runQueryAndCheck("SELECT a - b, a + b, a * b, a / b FROM t") {
checkGlutenPlan[ProjectExecTransformer]
}
}
@@ -598,7 +598,7 @@ class MathFunctionsValidateSuite extends
FunctionsValidateSuite {
// Query under the opposite setting -- Gluten must use the captured
context, not SQLConf.
withSQLConf("spark.sql.decimalOperations.allowPrecisionLoss" -> "true") {
- runQueryAndCompare("SELECT * FROM v") {
+ runQueryAndCheck("SELECT * FROM v") {
checkGlutenPlan[ProjectExecTransformer]
}
}
diff --git
a/backends-velox/src/test/scala/org/apache/gluten/functions/ScalarFunctionsValidateSuite.scala
b/backends-velox/src/test/scala/org/apache/gluten/functions/ScalarFunctionsValidateSuite.scala
index 266ae43290..458ca01b8c 100644
---
a/backends-velox/src/test/scala/org/apache/gluten/functions/ScalarFunctionsValidateSuite.scala
+++
b/backends-velox/src/test/scala/org/apache/gluten/functions/ScalarFunctionsValidateSuite.scala
@@ -395,7 +395,7 @@ class ScalarFunctionsValidateSuite extends
FunctionsValidateSuite {
spark.read.parquet(path.getCanonicalPath).createOrReplaceTempView("map_tbl")
- runQueryAndCompare(
+ runQueryAndCheck(
"select map_zip_with(m1, m2, (k, v1, v2) -> k == v1 + v2) from
map_tbl") {
checkGlutenPlan[ProjectExecTransformer]
}
@@ -497,7 +497,7 @@ class ScalarFunctionsValidateSuite extends
FunctionsValidateSuite {
}
test("isnan") {
- runQueryAndCompare(
+ runQueryAndCheck(
"SELECT isnan(l_orderkey), isnan(cast('NaN' as double)),
isnan(0.0F/0.0F)" +
" from lineitem limit 1") {
checkGlutenPlan[ProjectExecTransformer]
@@ -507,15 +507,15 @@ class ScalarFunctionsValidateSuite extends
FunctionsValidateSuite {
test("conditional") {
Seq("nanvl", "nullif", "nvl").foreach {
func =>
- runQueryAndCompare(s"""
- |SELECT
- | $func(cast('nan' as float), 1f),
- | $func(l_orderkey, cast('null' as double)),
- | $func(cast('null' as double), l_orderkey),
- | $func(l_orderkey, l_orderkey / 0.0d),
- | $func(cast('nan' as float), l_orderkey)
- | from lineitem limit 1
- |""".stripMargin) {
+ runQueryAndCheck(s"""
+ |SELECT
+ | $func(cast('nan' as float), 1f),
+ | $func(l_orderkey, cast('null' as double)),
+ | $func(cast('null' as double), l_orderkey),
+ | $func(l_orderkey, l_orderkey / 0.0d),
+ | $func(cast('nan' as float), l_orderkey)
+ | from lineitem limit 1
+ |""".stripMargin) {
checkGlutenPlan[ProjectExecTransformer]
}
}
@@ -524,15 +524,15 @@ class ScalarFunctionsValidateSuite extends
FunctionsValidateSuite {
test("nvl2") {
Seq("null", "l_orderkey").foreach {
expr =>
- runQueryAndCompare(s"""
- |SELECT
- | nvl2($expr, cast('nan' as float), 1f),
- | nvl2($expr, l_orderkey, cast('null' as
double)),
- | nvl2($expr, cast('null' as double),
l_orderkey),
- | nvl2($expr, l_orderkey, l_orderkey / 0.0d),
- | nvl2($expr, cast('nan' as float), l_orderkey)
- | from lineitem limit 1
- |""".stripMargin) {
+ runQueryAndCheck(s"""
+ |SELECT
+ | nvl2($expr, cast('nan' as float), 1f),
+ | nvl2($expr, l_orderkey, cast('null' as double)),
+ | nvl2($expr, cast('null' as double), l_orderkey),
+ | nvl2($expr, l_orderkey, l_orderkey / 0.0d),
+ | nvl2($expr, cast('nan' as float), l_orderkey)
+ | from lineitem limit 1
+ |""".stripMargin) {
checkGlutenPlan[ProjectExecTransformer]
}
}
@@ -864,7 +864,7 @@ class ScalarFunctionsValidateSuite extends
FunctionsValidateSuite {
}
test("bitwise_and") {
- runQueryAndCompare(
+ runQueryAndCheck(
"select cast(l_orderkey as tinyint) & cast(l_partkey as tinyint)," +
" cast(l_orderkey as int) & cast(l_partkey as int), l_orderkey &
l_partkey" +
" from lineitem") {
@@ -873,7 +873,7 @@ class ScalarFunctionsValidateSuite extends
FunctionsValidateSuite {
}
test("bitwise_not") {
- runQueryAndCompare(
+ runQueryAndCheck(
"select ~(cast(l_orderkey as tinyint)), ~(cast(l_orderkey as int)),
~l_orderkey" +
" from lineitem") {
checkGlutenPlan[ProjectExecTransformer]
@@ -881,7 +881,7 @@ class ScalarFunctionsValidateSuite extends
FunctionsValidateSuite {
}
test("bitwise_or") {
- runQueryAndCompare(
+ runQueryAndCheck(
"select cast(l_orderkey as tinyint) | cast(l_partkey as tinyint)," +
" cast(l_orderkey as int) | cast(l_partkey as int), l_orderkey |
l_partkey" +
" from lineitem") {
@@ -890,7 +890,7 @@ class ScalarFunctionsValidateSuite extends
FunctionsValidateSuite {
}
test("bitwise_xor") {
- runQueryAndCompare(
+ runQueryAndCheck(
"select cast(l_orderkey as tinyint) ^ cast(l_partkey as tinyint)," +
" cast(l_orderkey as int) ^ cast(l_partkey as int), l_orderkey ^
l_partkey" +
" from lineitem") {
@@ -1353,94 +1353,100 @@ class ScalarFunctionsValidateSuite extends
FunctionsValidateSuite {
.write
.parquet(path.getCanonicalPath)
spark.read.parquet(path.getCanonicalPath).createOrReplaceTempView("cast_table")
- runQueryAndCompare("select cast(str as bigint) from cast_table") {
+ runQueryAndCheck("select cast(str as bigint) from cast_table") {
checkGlutenPlan[ProjectExecTransformer]
}
- runQueryAndCompare("select cast(str as double) from cast_table") {
+ runQueryAndCheck("select cast(str as double) from cast_table") {
checkGlutenPlan[ProjectExecTransformer]
}
}
}
- runQueryAndCompare("select cast(' 123 ' AS int)") {
+ runQueryAndCheck("select cast(' 123 ' AS int)") {
checkGlutenPlan[ProjectExecTransformer]
}
- runQueryAndCompare("select cast('2147483648' AS int)") {
+ runQueryAndCheck("select cast('2147483648' AS int)") {
checkGlutenPlan[ProjectExecTransformer]
}
- runQueryAndCompare("select cast('12a34' AS int)") {
+ runQueryAndCheck("select cast('12a34' AS int)") {
checkGlutenPlan[ProjectExecTransformer]
}
- runQueryAndCompare("select cast('2023-08-21 ' AS date)") {
+ runQueryAndCheck("select cast('2023-08-21 ' AS date)") {
checkGlutenPlan[ProjectExecTransformer]
}
- runQueryAndCompare("select cast(' true' AS boolean)") {
+ runQueryAndCheck("select cast(' true' AS boolean)") {
checkGlutenPlan[ProjectExecTransformer]
}
- runQueryAndCompare("select cast('null' AS int)") {
+ runQueryAndCheck("select cast('null' AS int)") {
checkGlutenPlan[ProjectExecTransformer]
}
- runQueryAndCompare("select cast('on' AS BOOLEAN)") {
+ runQueryAndCheck("select cast('on' AS BOOLEAN)") {
checkGlutenPlan[ProjectExecTransformer]
}
- runQueryAndCompare("select cast(128 AS DECIMAL(2, 0))") {
+ runQueryAndCheck("select cast(128 AS DECIMAL(2, 0))") {
checkGlutenPlan[ProjectExecTransformer]
}
- runQueryAndCompare("select cast(128 AS TINYINT)") {
+ runQueryAndCheck("select cast(128 AS TINYINT)") {
checkGlutenPlan[ProjectExecTransformer]
}
- runQueryAndCompare("select cast(9223372036854775807 AS int)") {
+ runQueryAndCheck("select cast(9223372036854775807 AS int)") {
checkGlutenPlan[ProjectExecTransformer]
}
- runQueryAndCompare("select cast('123.0' AS INT)") {
+ runQueryAndCheck("select cast('123.0' AS INT)") {
checkGlutenPlan[ProjectExecTransformer]
}
// Cast Array as Array[String]
- runQueryAndCompare("select cast(array(1, null) AS array<string>)") {
+ runQueryAndCheck("select cast(array(1, null) AS array<string>)") {
checkGlutenPlan[ProjectExecTransformer]
}
- runQueryAndCompare("select cast(array(1L, null) AS array<string>)") {
+ runQueryAndCheck("select cast(array(1L, null) AS array<string>)") {
checkGlutenPlan[ProjectExecTransformer]
}
- runQueryAndCompare("select cast(array(1.1d, null) AS array<string>)") {
+ runQueryAndCheck("select cast(array(1.1d, null) AS array<string>)") {
checkGlutenPlan[ProjectExecTransformer]
}
- runQueryAndCompare("select cast(array(false, null) AS array<string>)") {
+ runQueryAndCheck("select cast(array(false, null) AS array<string>)") {
checkGlutenPlan[ProjectExecTransformer]
}
- runQueryAndCompare("select cast(array(date'2024-01-01') AS
array<string>)") {
+ runQueryAndCheck("select cast(array(date'2024-01-01') AS array<string>)") {
checkGlutenPlan[ProjectExecTransformer]
}
- runQueryAndCompare("select cast(array(timestamp'2024-01-01 12:00:00') AS
array<string>)") {
+ runQueryAndCheck(
+ "select cast(array(timestamp'2024-01-01 12:00:00') AS array<string>)") {
checkGlutenPlan[ProjectExecTransformer]
}
// Cast Array[String] to Array
- runQueryAndCompare("select cast(array('123', '-98', 'abc', null) AS
array<tinyint>)") {
+ runQueryAndCheck(
+ "select cast(array('123', '-98', 'abc', null) AS array<tinyint>)") {
checkGlutenPlan[ProjectExecTransformer]
}
- runQueryAndCompare("select cast(array('123', '-98', 'abc', null) AS
array<smallint>)") {
+ runQueryAndCheck(
+ "select cast(array('123', '-98', 'abc', null) AS array<smallint>)") {
checkGlutenPlan[ProjectExecTransformer]
}
- runQueryAndCompare("select cast(array('123', '-98', 'abc', null) AS
array<int>)") {
+ runQueryAndCheck("select cast(array('123', '-98', 'abc', null) AS
array<int>)") {
checkGlutenPlan[ProjectExecTransformer]
}
- runQueryAndCompare("select cast(array('123', '-98', 'abc', null) AS
array<bigint>)") {
+ runQueryAndCheck("select cast(array('123', '-98', 'abc', null) AS
array<bigint>)") {
checkGlutenPlan[ProjectExecTransformer]
}
- runQueryAndCompare("select cast(array('123e-2', '-234.548', 'xyz', null)
AS array<float>)") {
+ runQueryAndCheck(
+ "select cast(array('123e-2', '-234.548', 'xyz', null) AS array<float>)")
{
checkGlutenPlan[ProjectExecTransformer]
}
- runQueryAndCompare("select cast(array('123e-2', '-234.548', 'xyz', null)
AS array<double>)") {
+ runQueryAndCheck(
+ "select cast(array('123e-2', '-234.548', 'xyz', null) AS
array<double>)") {
checkGlutenPlan[ProjectExecTransformer]
}
- runQueryAndCompare("""
- |select
- | cast(
- | array('2023-01-01 12:00:00', '2023-01-02
12:00:00', 'def', null)
- | AS array<timestamp>)
- |""".stripMargin) {
+ runQueryAndCheck(
+ """
+ |select
+ | cast(
+ | array('2023-01-01 12:00:00', '2023-01-02 12:00:00', 'def', null)
+ | AS array<timestamp>)
+ |""".stripMargin) {
checkGlutenPlan[ProjectExecTransformer]
}
- runQueryAndCompare(
+ runQueryAndCheck(
"select cast(array('2024-01-01', '2024-01-02', 'uvw', null) AS
array<date>)") {
checkGlutenPlan[ProjectExecTransformer]
}
@@ -1453,27 +1459,27 @@ class ScalarFunctionsValidateSuite extends
FunctionsValidateSuite {
.write
.parquet(path.getCanonicalPath)
spark.read.parquet(path.getCanonicalPath).createOrReplaceTempView("cast_table")
- runQueryAndCompare("select cast(c1 as string) from cast_table") {
+ runQueryAndCheck("select cast(c1 as string) from cast_table") {
checkGlutenPlan[ProjectExecTransformer]
}
}
}
- runQueryAndCompare("select cast(array(1, 2) AS string)") {
+ runQueryAndCheck("select cast(array(1, 2) AS string)") {
checkGlutenPlan[ProjectExecTransformer]
}
- runQueryAndCompare("select cast(array(1L, null) AS string)") {
+ runQueryAndCheck("select cast(array(1L, null) AS string)") {
checkGlutenPlan[ProjectExecTransformer]
}
- runQueryAndCompare("select cast(array(1.1d, null) AS string)") {
+ runQueryAndCheck("select cast(array(1.1d, null) AS string)") {
checkGlutenPlan[ProjectExecTransformer]
}
- runQueryAndCompare("select cast(array(false, null) AS string)") {
+ runQueryAndCheck("select cast(array(false, null) AS string)") {
checkGlutenPlan[ProjectExecTransformer]
}
- runQueryAndCompare("select cast(array(date'2024-01-01') AS string)") {
+ runQueryAndCheck("select cast(array(date'2024-01-01') AS string)") {
checkGlutenPlan[ProjectExecTransformer]
}
- runQueryAndCompare("select cast(array(timestamp'2024-01-01 12:00:00') AS
string)") {
+ runQueryAndCheck("select cast(array(timestamp'2024-01-01 12:00:00') AS
string)") {
checkGlutenPlan[ProjectExecTransformer]
}
// Cast Map
@@ -1488,19 +1494,24 @@ class ScalarFunctionsValidateSuite extends
FunctionsValidateSuite {
spark.read.parquet(path.getCanonicalPath).createOrReplaceTempView("byte_map_tbl")
- runQueryAndCompare("select cast(c1 as map<tinyint, double>) from
byte_map_tbl") {
+ runQueryAndCheck(
+ "select cast(c1 as map<tinyint, double>) from byte_map_tbl") {
checkGlutenPlan[ProjectExecTransformer]
}
- runQueryAndCompare("select cast(c1 as map<double, tinyint>) from
byte_map_tbl") {
+ runQueryAndCheck(
+ "select cast(c1 as map<double, tinyint>) from byte_map_tbl") {
checkGlutenPlan[ProjectExecTransformer]
}
- runQueryAndCompare("select cast(c1 as map<tinyint, string>) from
byte_map_tbl") {
+ runQueryAndCheck(
+ "select cast(c1 as map<tinyint, string>) from byte_map_tbl") {
checkGlutenPlan[ProjectExecTransformer]
}
- runQueryAndCompare("select cast(c1 as map<string, tinyint>) from
byte_map_tbl") {
+ runQueryAndCheck(
+ "select cast(c1 as map<string, tinyint>) from byte_map_tbl") {
checkGlutenPlan[ProjectExecTransformer]
}
- runQueryAndCompare("select cast(c1 as map<tinyint, boolean>) from
byte_map_tbl") {
+ runQueryAndCheck(
+ "select cast(c1 as map<tinyint, boolean>) from byte_map_tbl") {
checkGlutenPlan[ProjectExecTransformer]
}
}
@@ -1520,19 +1531,24 @@ class ScalarFunctionsValidateSuite extends
FunctionsValidateSuite {
spark.read.parquet(path.getCanonicalPath).createOrReplaceTempView("small_int_map_tbl")
- runQueryAndCompare("select cast(c1 as map<smallint, double>) from
small_int_map_tbl") {
+ runQueryAndCheck(
+ "select cast(c1 as map<smallint, double>) from small_int_map_tbl")
{
checkGlutenPlan[ProjectExecTransformer]
}
- runQueryAndCompare("select cast(c1 as map<double, smallint>) from
small_int_map_tbl") {
+ runQueryAndCheck(
+ "select cast(c1 as map<double, smallint>) from small_int_map_tbl")
{
checkGlutenPlan[ProjectExecTransformer]
}
- runQueryAndCompare("select cast(c1 as map<smallint, string>) from
small_int_map_tbl") {
+ runQueryAndCheck(
+ "select cast(c1 as map<smallint, string>) from small_int_map_tbl")
{
checkGlutenPlan[ProjectExecTransformer]
}
- runQueryAndCompare("select cast(c1 as map<string, smallint>) from
small_int_map_tbl") {
+ runQueryAndCheck(
+ "select cast(c1 as map<string, smallint>) from small_int_map_tbl")
{
checkGlutenPlan[ProjectExecTransformer]
}
- runQueryAndCompare("select cast(c1 as map<smallint, boolean>) from
small_int_map_tbl") {
+ runQueryAndCheck(
+ "select cast(c1 as map<smallint, boolean>) from
small_int_map_tbl") {
checkGlutenPlan[ProjectExecTransformer]
}
}
@@ -1548,10 +1564,10 @@ class ScalarFunctionsValidateSuite extends
FunctionsValidateSuite {
spark.read.parquet(path.getCanonicalPath).createOrReplaceTempView("int_map_tbl")
- runQueryAndCompare("select cast(c1 as map<double, int>) from
int_map_tbl") {
+ runQueryAndCheck("select cast(c1 as map<double, int>) from
int_map_tbl") {
checkGlutenPlan[ProjectExecTransformer]
}
- runQueryAndCompare("select cast(c1 as map<string, string>) from
int_map_tbl") {
+ runQueryAndCheck("select cast(c1 as map<string, string>) from
int_map_tbl") {
checkGlutenPlan[ProjectExecTransformer]
}
}
@@ -1567,31 +1583,33 @@ class ScalarFunctionsValidateSuite extends
FunctionsValidateSuite {
spark.read.parquet(path.getCanonicalPath).createOrReplaceTempView("float_map_tbl")
- runQueryAndCompare("select cast(c1 as map<float, float>) from
float_map_tbl") {
+ runQueryAndCheck("select cast(c1 as map<float, float>) from
float_map_tbl") {
checkGlutenPlan[ProjectExecTransformer]
}
- runQueryAndCompare("select cast(c1 as map<string, string>) from
float_map_tbl") {
+ runQueryAndCheck(
+ "select cast(c1 as map<string, string>) from float_map_tbl") {
checkGlutenPlan[ProjectExecTransformer]
}
}
}
- runQueryAndCompare("""
- |select
- | cast(
- | map(
- | timestamp '2023-01-01 12:00:00', '2023-01-01
13:00:00',
- | timestamp '2023-01-02 12:00:00', 'xyz')
- | as map<string, timestamp>)
- |""".stripMargin) {
+ runQueryAndCheck("""
+ |select
+ | cast(
+ | map(
+ | timestamp '2023-01-01 12:00:00', '2023-01-01
13:00:00',
+ | timestamp '2023-01-02 12:00:00', 'xyz')
+ | as map<string, timestamp>)
+ |""".stripMargin) {
checkGlutenPlan[ProjectExecTransformer]
}
- runQueryAndCompare("""
- |select
- | cast(
- | map(date '2024-01-01', '2024-01-02', date
'2024-02-01', 'xyz')
- | as map<string, date>)
- |""".stripMargin) {
+ runQueryAndCheck(
+ """
+ |select
+ | cast(
+ | map(date '2024-01-01', '2024-01-02', date '2024-02-01', 'xyz')
+ | as map<string, date>)
+ |""".stripMargin) {
checkGlutenPlan[ProjectExecTransformer]
}
// Cast struct
@@ -1624,52 +1642,52 @@ class ScalarFunctionsValidateSuite extends
FunctionsValidateSuite {
spark.read.parquet(path.getCanonicalPath).createOrReplaceTempView("struct_tbl")
- runQueryAndCompare("""
- |select
- | cast(
- | c1 as
- | struct<
- | a: array<bigint>,
- | b: map<smallint, int>,
- | c: struct<x: string, y: string,
z:boolean>>)
- |from struct_tbl
- |""".stripMargin) {
+ runQueryAndCheck("""
+ |select
+ | cast(
+ | c1 as
+ | struct<
+ | a: array<bigint>,
+ | b: map<smallint, int>,
+ | c: struct<x: string, y: string,
z:boolean>>)
+ |from struct_tbl
+ |""".stripMargin) {
checkGlutenPlan[ProjectExecTransformer]
}
- runQueryAndCompare("""
- |select
- | cast(
- | c1 as
- | struct<
- | a: array<double>,
- | b: map<int, bigint>,
- | c: struct<x: int, y: boolean,
z:string>>)
- |from struct_tbl
- |""".stripMargin) {
+ runQueryAndCheck("""
+ |select
+ | cast(
+ | c1 as
+ | struct<
+ | a: array<double>,
+ | b: map<int, bigint>,
+ | c: struct<x: int, y: boolean, z:string>>)
+ |from struct_tbl
+ |""".stripMargin) {
checkGlutenPlan[ProjectExecTransformer]
}
- runQueryAndCompare("""
- |select
- | cast(
- | c1 as
- | struct<
- | a: array<timestamp>,
- | b: map<bigint, boolean>,
- | c: struct<x: tinyint, y: smallint,
z:double>>)
- |from struct_tbl
- |""".stripMargin) {
+ runQueryAndCheck("""
+ |select
+ | cast(
+ | c1 as
+ | struct<
+ | a: array<timestamp>,
+ | b: map<bigint, boolean>,
+ | c: struct<x: tinyint, y: smallint,
z:double>>)
+ |from struct_tbl
+ |""".stripMargin) {
checkGlutenPlan[ProjectExecTransformer]
}
- runQueryAndCompare("""
- |select
- | cast(
- | c1 as
- | struct<
- | a: array<date>,
- | b: map<string, double>,
- | c: struct<x: int, y: bigint, z:float>>)
- |from struct_tbl
- |""".stripMargin) {
+ runQueryAndCheck("""
+ |select
+ | cast(
+ | c1 as
+ | struct<
+ | a: array<date>,
+ | b: map<string, double>,
+ | c: struct<x: int, y: bigint, z:float>>)
+ |from struct_tbl
+ |""".stripMargin) {
checkGlutenPlan[ProjectExecTransformer]
}
}
diff --git
a/gluten-substrait/src/test/scala/org/apache/gluten/execution/GlutenQueryComparisonTest.scala
b/gluten-substrait/src/test/scala/org/apache/gluten/execution/GlutenQueryComparisonTest.scala
index e175b314bd..b13852b572 100644
---
a/gluten-substrait/src/test/scala/org/apache/gluten/execution/GlutenQueryComparisonTest.scala
+++
b/gluten-substrait/src/test/scala/org/apache/gluten/execution/GlutenQueryComparisonTest.scala
@@ -28,6 +28,8 @@ import org.apache.spark.sql.{DataFrame, GlutenQueryTest, Row}
import java.util.concurrent.atomic.AtomicBoolean
+import scala.util.Try
+
abstract class GlutenQueryComparisonTest extends GlutenQueryTest {
private val isFallbackCheckDisabled0 = new AtomicBoolean(false)
@@ -72,6 +74,34 @@ abstract class GlutenQueryComparisonTest extends
GlutenQueryTest {
cache)
}
+ /**
+ * Like `runQueryAndCompare`, but in ANSI mode also accepts a query that
fails on vanilla Spark,
+ * which happens when ANSI mode rejects its input (for example, a malformed
string cast to a
+ * number). In that case, checks that Gluten fails too.
+ */
+ protected def runQueryAndCheck(
+ sqlStr: String,
+ compareResult: Boolean = true,
+ noFallBack: Boolean = true,
+ cache: Boolean = false)(customCheck: DataFrame => Unit): Unit = {
+ if (spark.sessionState.conf.ansiEnabled) {
+ // withSQLConf returns Unit before Spark 4.0, so the result is captured
in a var.
+ var vanillaFailed = false
+ withSQLConf(vanillaSparkConfs(): _*) {
+ vanillaFailed = Try(spark.sql(sqlStr).collect()).isFailure
+ }
+ if (vanillaFailed) {
+ // TODO: Also compare the error class once native errors are
translated into Spark
+ // exceptions.
+ withClue(s"Vanilla Spark failed but Gluten did not for query:
$sqlStr\n") {
+ intercept[Exception](spark.sql(sqlStr).collect())
+ }
+ return
+ }
+ }
+ runQueryAndCompare(sqlStr, compareResult, noFallBack, cache)(customCheck)
+ }
+
protected def compareResultsAgainstVanillaSpark(
sql: String,
compareResult: Boolean = true,
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]