Skip to content

Commit 690c836

Browse files
authored
[VL] Update Parquet unit tests (#12776)
1 parent 48b5fca commit 690c836

10 files changed

Lines changed: 28 additions & 955 deletions

File tree

gluten-ut/spark34/src/test/scala/org/apache/gluten/utils/velox/VeloxTestSettings.scala

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -391,27 +391,18 @@ class VeloxTestSettings extends BackendTestSettings {
391391
enableSuite[GlutenOrcV1SchemaPruningSuite]
392392
enableSuite[GlutenOrcV2SchemaPruningSuite]
393393
enableSuite[GlutenParquetColumnIndexSuite]
394-
// Rewrite by just removing test timestamp.
395-
.exclude("test reading unaligned pages - test all types")
396-
// Rewrite by converting smaller integral value to timestamp.
397-
.exclude("test reading unaligned pages - test all types (dict encode)")
398394
enableSuite[GlutenParquetCompressionCodecPrecedenceSuite]
399395
enableSuite[GlutenParquetDeltaByteArrayEncodingSuite]
400396
enableSuite[GlutenParquetDeltaEncodingInteger]
401397
enableSuite[GlutenParquetDeltaEncodingLong]
402398
enableSuite[GlutenParquetDeltaLengthByteArrayEncodingSuite]
403399
enableSuite[GlutenParquetEncodingSuite]
404-
// Velox does not support rle encoding, but it can pass when native writer enabled.
405-
.exclude("parquet v2 pages - rle encoding for boolean value columns")
406400
enableSuite[GlutenParquetFieldIdIOSuite]
407401
enableSuite[GlutenParquetFileFormatV1Suite]
408402
enableSuite[GlutenParquetFileFormatV2Suite]
409403
enableSuite[GlutenParquetV1FilterSuite]
410404
// Rewrite.
411405
.exclude("SPARK-23852: Broken Parquet push-down for partially-written stats")
412-
// Rewrite for supported INT96 - timestamp.
413-
.exclude("filter pushdown - timestamp")
414-
.exclude("filter pushdown - date")
415406
// Exception bebaviour.
416407
.exclude("SPARK-25207: exception when duplicate fields in case-insensitive mode")
417408
// Ignore Spark's filter pushdown check.
@@ -427,9 +418,6 @@ class VeloxTestSettings extends BackendTestSettings {
427418
enableSuite[GlutenParquetV2FilterSuite]
428419
// Rewrite.
429420
.exclude("SPARK-23852: Broken Parquet push-down for partially-written stats")
430-
// Rewrite for supported INT96 - timestamp.
431-
.exclude("filter pushdown - timestamp")
432-
.exclude("filter pushdown - date")
433421
// Exception bebaviour.
434422
.exclude("SPARK-25207: exception when duplicate fields in case-insensitive mode")
435423
// Ignore Spark's filter pushdown check.
@@ -443,6 +431,7 @@ class VeloxTestSettings extends BackendTestSettings {
443431
.exclude("filter pushdown - StringPredicate")
444432
.exclude("SPARK-38825: in and notIn filters")
445433
enableSuite[GlutenParquetInteroperabilitySuite]
434+
// Disabled because Velox does not implement Spark’s legacy Impala INT96 timestamp conversion semantics.
446435
.exclude("parquet timestamp conversion")
447436
enableSuite[GlutenParquetIOSuite]
448437
// Velox doesn't write file metadata into parquet file.
@@ -451,35 +440,35 @@ class VeloxTestSettings extends BackendTestSettings {
451440
.exclude("SPARK-35640: read binary as timestamp should throw schema incompatible error")
452441
// Exception msg.
453442
.exclude("SPARK-35640: int as long should throw schema incompatible error")
454-
// Velox parquet reader not allow offset zero.
455-
.exclude("SPARK-40128 read DELTA_LENGTH_BYTE_ARRAY encoded strings")
456443
enableSuite[GlutenParquetV1PartitionDiscoverySuite]
457444
enableSuite[GlutenParquetV2PartitionDiscoverySuite]
458445
enableSuite[GlutenParquetProtobufCompatibilitySuite]
459446
enableSuite[GlutenParquetV1QuerySuite]
447+
// No fix needed: INT read as LONG is allowed.
460448
.exclude("row group skipping doesn't overflow when reading into larger type")
461449
// Unsupport spark.sql.files.ignoreCorruptFiles.
462450
.exclude("Enabling/disabling ignoreCorruptFiles")
463-
// decimal failed ut
451+
// No fix needed: narrowing the scale should not be allowed.
464452
.exclude("SPARK-34212 Parquet should read decimals correctly")
465453
// new added in spark-3.3 and need fix later, random failure may caused by memory free
466454
.exclude("SPARK-39833: pushed filters with project without filter columns")
467455
.exclude("SPARK-39833: pushed filters with count()")
468456
// Rewrite because the filter after datasource is not needed.
469457
.exclude(
470458
"SPARK-26677: negated null-safe equality comparison should not filter matched row groups")
471-
// Velox currently does not distinguish `isAdjustedToUTC` in Parquet.
459+
// No fix needed: read TimestampLTZ as TimestampNTZ is allowed.
472460
.exclude("SPARK-36182: can't read TimestampLTZ as TimestampNTZ")
473461
enableSuite[GlutenParquetV2QuerySuite]
462+
// No fix needed: INT read as LONG is allowed.
474463
.exclude("row group skipping doesn't overflow when reading into larger type")
475464
// Unsupport spark.sql.files.ignoreCorruptFiles.
476465
.exclude("Enabling/disabling ignoreCorruptFiles")
477-
// decimal failed ut
466+
// No fix needed: narrowing the scale should not be allowed.
478467
.exclude("SPARK-34212 Parquet should read decimals correctly")
479468
// Rewrite because the filter after datasource is not needed.
480469
.exclude(
481470
"SPARK-26677: negated null-safe equality comparison should not filter matched row groups")
482-
// Velox currently does not distinguish `isAdjustedToUTC` in Parquet.
471+
// No fix needed: read TimestampLTZ as TimestampNTZ is allowed.
483472
.exclude("SPARK-36182: can't read TimestampLTZ as TimestampNTZ")
484473
enableSuite[GlutenParquetV1SchemaPruningSuite]
485474
enableSuite[GlutenParquetV2SchemaPruningSuite]
@@ -526,8 +515,6 @@ class VeloxTestSettings extends BackendTestSettings {
526515
enableSuite[GlutenFileMetadataStructRowIndexSuite]
527516
enableSuite[GlutenParquetV1AggregatePushDownSuite]
528517
enableSuite[GlutenParquetV2AggregatePushDownSuite]
529-
// TODO: Timestamp columns stats will lost if using int64 in parquet writer.
530-
.exclude("aggregate push down - different data types")
531518
enableSuite[GlutenOrcV1AggregatePushDownSuite]
532519
.exclude("nested column: Count(nested sub-field) not push down")
533520
enableSuite[GlutenOrcV2AggregatePushDownSuite]

gluten-ut/spark34/src/test/scala/org/apache/spark/sql/execution/datasources/parquet/GlutenParquetColumnIndexSuite.scala

Lines changed: 2 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -16,50 +16,6 @@
1616
*/
1717
package org.apache.spark.sql.execution.datasources.parquet
1818

19-
import org.apache.spark.sql.{DataFrame, GlutenSQLTestsBaseTrait}
19+
import org.apache.spark.sql.GlutenSQLTestsBaseTrait
2020

21-
class GlutenParquetColumnIndexSuite extends ParquetColumnIndexSuite with GlutenSQLTestsBaseTrait {
22-
private val actions: Seq[DataFrame => DataFrame] = Seq(
23-
"_1 = 500",
24-
"_1 = 500 or _1 = 1500",
25-
"_1 = 500 or _1 = 501 or _1 = 1500",
26-
"_1 = 500 or _1 = 501 or _1 = 1000 or _1 = 1500",
27-
"_1 >= 500 and _1 < 1000",
28-
"(_1 >= 500 and _1 < 1000) or (_1 >= 1500 and _1 < 1600)"
29-
).map(f => (df: DataFrame) => df.filter(f))
30-
31-
testGluten("test reading unaligned pages - test all types") {
32-
val df = spark
33-
.range(0, 2000)
34-
.selectExpr(
35-
"id as _1",
36-
"cast(id as short) as _3",
37-
"cast(id as int) as _4",
38-
"cast(id as float) as _5",
39-
"cast(id as double) as _6",
40-
"cast(id as decimal(20,0)) as _7",
41-
// We changed 1618161925000 to 1618161925 to avoid reaching the limitation of Velox:
42-
// Timepoint is outside of supported year range.
43-
"cast(cast(1618161925 + id * 60 * 60 * 24 as timestamp) as date) as _9"
44-
)
45-
checkUnalignedPages(df)(actions: _*)
46-
}
47-
48-
testGluten("test reading unaligned pages - test all types (dict encode)") {
49-
val df = spark
50-
.range(0, 2000)
51-
.selectExpr(
52-
"id as _1",
53-
"cast(id % 10 as byte) as _2",
54-
"cast(id % 10 as short) as _3",
55-
"cast(id % 10 as int) as _4",
56-
"cast(id % 10 as float) as _5",
57-
"cast(id % 10 as double) as _6",
58-
"cast(id % 10 as decimal(20,0)) as _7",
59-
"cast(id % 2 as boolean) as _8",
60-
"cast(cast(1618161925 + (id % 10) * 60 * 60 * 24 as timestamp) as date) as _9",
61-
"cast(1618161925 + (id % 10) as timestamp) as _10"
62-
)
63-
checkUnalignedPages(df)(actions: _*)
64-
}
65-
}
21+
class GlutenParquetColumnIndexSuite extends ParquetColumnIndexSuite with GlutenSQLTestsBaseTrait {}

gluten-ut/spark34/src/test/scala/org/apache/spark/sql/execution/datasources/parquet/GlutenParquetFilterSuite.scala

Lines changed: 1 addition & 197 deletions
Original file line numberDiff line numberDiff line change
@@ -27,25 +27,16 @@ import org.apache.spark.sql.execution.datasources.{DataSourceStrategy, HadoopFsR
2727
import org.apache.spark.sql.execution.datasources.v2.DataSourceV2ScanRelation
2828
import org.apache.spark.sql.execution.datasources.v2.parquet.ParquetScan
2929
import org.apache.spark.sql.internal.SQLConf
30-
import org.apache.spark.sql.internal.SQLConf.LegacyBehaviorPolicy.{CORRECTED, LEGACY}
31-
import org.apache.spark.sql.internal.SQLConf.ParquetOutputTimestampType.INT96
3230
import org.apache.spark.sql.types._
3331
import org.apache.spark.tags.ExtendedSQLTest
3432
import org.apache.spark.util.Utils
3533

3634
import org.apache.hadoop.fs.Path
37-
import org.apache.parquet.filter2.predicate.{FilterApi, FilterPredicate, Operators}
35+
import org.apache.parquet.filter2.predicate.{FilterApi, FilterPredicate}
3836
import org.apache.parquet.filter2.predicate.FilterApi._
39-
import org.apache.parquet.filter2.predicate.Operators.{Column => _, Eq, Gt, GtEq, Lt, LtEq, NotEq}
4037
import org.apache.parquet.hadoop.{ParquetFileReader, ParquetInputFormat, ParquetOutputFormat}
4138
import org.apache.parquet.hadoop.util.HadoopInputFile
4239

43-
import java.sql.{Date, Timestamp}
44-
import java.time.LocalDate
45-
46-
import scala.reflect.ClassTag
47-
import scala.reflect.runtime.universe.TypeTag
48-
4940
abstract class GlutenParquetFilterSuite extends ParquetFilterSuite with GlutenSQLTestsBaseTrait {
5041
protected def checkFilterPredicate(
5142
predicate: Predicate,
@@ -66,44 +57,6 @@ abstract class GlutenParquetFilterSuite extends ParquetFilterSuite with GlutenSQ
6657
getWorkspaceFilePath("sql", "core", "src", "test", "resources").toString + "/" + name)
6758
}
6859

69-
testGluten("filter pushdown - timestamp") {
70-
Seq(true, false).foreach {
71-
java8Api =>
72-
Seq(CORRECTED, LEGACY).foreach {
73-
rebaseMode =>
74-
val millisData = Seq(
75-
"1000-06-14 08:28:53.123",
76-
"1582-06-15 08:28:53.001",
77-
"1900-06-16 08:28:53.0",
78-
"2018-06-17 08:28:53.999")
79-
// INT96 doesn't support pushdown
80-
withSQLConf(
81-
SQLConf.DATETIME_JAVA8API_ENABLED.key -> java8Api.toString,
82-
SQLConf.PARQUET_INT96_REBASE_MODE_IN_WRITE.key -> rebaseMode.toString,
83-
SQLConf.PARQUET_OUTPUT_TIMESTAMP_TYPE.key -> INT96.toString
84-
) {
85-
import testImplicits._
86-
withTempPath {
87-
file =>
88-
millisData
89-
.map(i => Tuple1(Timestamp.valueOf(i)))
90-
.toDF
91-
.write
92-
.format(dataSourceName)
93-
.save(file.getCanonicalPath)
94-
readParquetFile(file.getCanonicalPath) {
95-
df =>
96-
val schema = new SparkToParquetSchemaConverter(conf).convert(df.schema)
97-
assertResult(None) {
98-
createParquetFilters(schema).createFilter(sources.IsNull("_1"))
99-
}
100-
}
101-
}
102-
}
103-
}
104-
}
105-
}
106-
10760
testGluten("SPARK-12218: 'Not' is included in Parquet filter pushdown") {
10861
import testImplicits._
10962

@@ -428,153 +381,4 @@ class GlutenParquetV2FilterSuite extends GlutenParquetFilterSuite with GlutenSQL
428381
}
429382
}
430383
}
431-
432-
/**
433-
* Takes a sequence of products `data` to generate multi-level nested dataframes as new test data.
434-
* It tests both non-nested and nested dataframes which are written and read back with Parquet
435-
* datasource.
436-
*
437-
* This is different from [[ParquetTest.withParquetDataFrame]] which does not test nested cases.
438-
*/
439-
private def withNestedParquetDataFrame[T <: Product: ClassTag: TypeTag](data: Seq[T])(
440-
runTest: (DataFrame, String, Any => Any) => Unit): Unit =
441-
withNestedParquetDataFrame(spark.createDataFrame(data))(runTest)
442-
443-
private def withNestedParquetDataFrame(inputDF: DataFrame)(
444-
runTest: (DataFrame, String, Any => Any) => Unit): Unit = {
445-
withNestedDataFrame(inputDF).foreach {
446-
case (newDF, colName, resultFun) =>
447-
withTempPath {
448-
file =>
449-
newDF.write.format(dataSourceName).save(file.getCanonicalPath)
450-
readParquetFile(file.getCanonicalPath)(df => runTest(df, colName, resultFun))
451-
}
452-
}
453-
}
454-
455-
testGluten("filter pushdown - date") {
456-
implicit class StringToDate(s: String) {
457-
def date: Date = Date.valueOf(s)
458-
}
459-
460-
val data = Seq("1000-01-01", "2018-03-19", "2018-03-20", "2018-03-21")
461-
import testImplicits._
462-
463-
// Velox backend does not support rebaseMode being LEGACY.
464-
Seq(false, true).foreach {
465-
java8Api =>
466-
Seq(CORRECTED).foreach {
467-
rebaseMode =>
468-
withSQLConf(
469-
SQLConf.DATETIME_JAVA8API_ENABLED.key -> java8Api.toString,
470-
SQLConf.PARQUET_REBASE_MODE_IN_WRITE.key -> rebaseMode.toString) {
471-
val dates = data.map(i => Tuple1(Date.valueOf(i))).toDF()
472-
withNestedParquetDataFrame(dates) {
473-
case (inputDF, colName, fun) =>
474-
implicit val df: DataFrame = inputDF
475-
476-
def resultFun(dateStr: String): Any = {
477-
val parsed = if (java8Api) LocalDate.parse(dateStr) else Date.valueOf(dateStr)
478-
fun(parsed)
479-
}
480-
481-
val dateAttr: Expression = df(colName).expr
482-
assert(df(colName).expr.dataType === DateType)
483-
484-
checkFilterPredicate(dateAttr.isNull, classOf[Eq[_]], Seq.empty[Row])
485-
checkFilterPredicate(
486-
dateAttr.isNotNull,
487-
classOf[NotEq[_]],
488-
data.map(i => Row.apply(resultFun(i))))
489-
490-
checkFilterPredicate(
491-
dateAttr === "1000-01-01".date,
492-
classOf[Eq[_]],
493-
resultFun("1000-01-01"))
494-
logWarning(s"java8Api: $java8Api, rebaseMode, $rebaseMode")
495-
checkFilterPredicate(
496-
dateAttr <=> "1000-01-01".date,
497-
classOf[Eq[_]],
498-
resultFun("1000-01-01"))
499-
checkFilterPredicate(
500-
dateAttr =!= "1000-01-01".date,
501-
classOf[NotEq[_]],
502-
Seq("2018-03-19", "2018-03-20", "2018-03-21").map(i => Row.apply(resultFun(i))))
503-
504-
checkFilterPredicate(
505-
dateAttr < "2018-03-19".date,
506-
classOf[Lt[_]],
507-
resultFun("1000-01-01"))
508-
checkFilterPredicate(
509-
dateAttr > "2018-03-20".date,
510-
classOf[Gt[_]],
511-
resultFun("2018-03-21"))
512-
checkFilterPredicate(
513-
dateAttr <= "1000-01-01".date,
514-
classOf[LtEq[_]],
515-
resultFun("1000-01-01"))
516-
checkFilterPredicate(
517-
dateAttr >= "2018-03-21".date,
518-
classOf[GtEq[_]],
519-
resultFun("2018-03-21"))
520-
521-
checkFilterPredicate(
522-
Literal("1000-01-01".date) === dateAttr,
523-
classOf[Eq[_]],
524-
resultFun("1000-01-01"))
525-
checkFilterPredicate(
526-
Literal("1000-01-01".date) <=> dateAttr,
527-
classOf[Eq[_]],
528-
resultFun("1000-01-01"))
529-
checkFilterPredicate(
530-
Literal("2018-03-19".date) > dateAttr,
531-
classOf[Lt[_]],
532-
resultFun("1000-01-01"))
533-
checkFilterPredicate(
534-
Literal("2018-03-20".date) < dateAttr,
535-
classOf[Gt[_]],
536-
resultFun("2018-03-21"))
537-
checkFilterPredicate(
538-
Literal("1000-01-01".date) >= dateAttr,
539-
classOf[LtEq[_]],
540-
resultFun("1000-01-01"))
541-
checkFilterPredicate(
542-
Literal("2018-03-21".date) <= dateAttr,
543-
classOf[GtEq[_]],
544-
resultFun("2018-03-21"))
545-
546-
checkFilterPredicate(
547-
!(dateAttr < "2018-03-21".date),
548-
classOf[GtEq[_]],
549-
resultFun("2018-03-21"))
550-
checkFilterPredicate(
551-
dateAttr < "2018-03-19".date || dateAttr > "2018-03-20".date,
552-
classOf[Operators.Or],
553-
Seq(Row(resultFun("1000-01-01")), Row(resultFun("2018-03-21"))))
554-
555-
Seq(3, 20).foreach {
556-
threshold =>
557-
withSQLConf(
558-
SQLConf.PARQUET_FILTER_PUSHDOWN_INFILTERTHRESHOLD.key -> s"$threshold") {
559-
checkFilterPredicate(
560-
In(
561-
dateAttr,
562-
Array(
563-
"2018-03-19".date,
564-
"2018-03-20".date,
565-
"2018-03-21".date,
566-
"2018-03-22".date).map(Literal.apply)),
567-
if (threshold == 3) classOf[Operators.In[_]] else classOf[Operators.Or],
568-
Seq(
569-
Row(resultFun("2018-03-19")),
570-
Row(resultFun("2018-03-20")),
571-
Row(resultFun("2018-03-21")))
572-
)
573-
}
574-
}
575-
}
576-
}
577-
}
578-
}
579-
}
580384
}

0 commit comments

Comments
 (0)