-
Notifications
You must be signed in to change notification settings - Fork 29.3k
[SPARK-38112][SQL] Use error classes in the execution errors of date/timestamp handling #35670
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
1f816f1
ca46610
cfd6052
9730b12
e58052d
d51c6ab
d7795f9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,12 +17,22 @@ | |
|
|
||
| package org.apache.spark.sql.errors | ||
|
|
||
| import org.apache.spark.{SparkException, SparkIllegalArgumentException, SparkRuntimeException, SparkUnsupportedOperationException} | ||
| import org.apache.spark.sql.{DataFrame, QueryTest} | ||
| import java.sql.Timestamp | ||
|
|
||
| import org.apache.spark.{SparkException, SparkIllegalArgumentException, SparkRuntimeException, SparkUnsupportedOperationException, SparkUpgradeException} | ||
| import org.apache.spark.sql.{DataFrame, QueryTest, Row} | ||
| import org.apache.spark.sql.execution.datasources.orc.OrcTest | ||
| import org.apache.spark.sql.execution.datasources.parquet.ParquetTest | ||
| import org.apache.spark.sql.functions.{lit, lower, struct, sum} | ||
| import org.apache.spark.sql.internal.SQLConf | ||
| import org.apache.spark.sql.internal.SQLConf.LegacyBehaviorPolicy.EXCEPTION | ||
| import org.apache.spark.sql.test.SharedSparkSession | ||
| import org.apache.spark.sql.types.{StructField, StructType, TimestampNTZType, TimestampType} | ||
| import org.apache.spark.sql.util.ArrowUtils | ||
|
|
||
| class QueryExecutionErrorsSuite extends QueryTest | ||
| with ParquetTest with OrcTest with SharedSparkSession { | ||
|
|
||
| class QueryExecutionErrorsSuite extends QueryTest with SharedSparkSession { | ||
| import testImplicits._ | ||
|
|
||
| private def getAesInputs(): (DataFrame, DataFrame) = { | ||
|
|
@@ -171,4 +181,72 @@ class QueryExecutionErrorsSuite extends QueryTest with SharedSparkSession { | |
| assert(e2.getSqlState === "0A000") | ||
| assert(e2.getMessage === "The feature is not supported: Pivot not after a groupBy.") | ||
| } | ||
|
|
||
| test("INCONSISTENT_BEHAVIOR_CROSS_VERSION: " + | ||
| "compatibility with Spark 2.4/3.2 in reading/writing dates") { | ||
|
|
||
| // Fail to read ancient datetime values. | ||
| withSQLConf(SQLConf.PARQUET_REBASE_MODE_IN_READ.key -> EXCEPTION.toString) { | ||
| val fileName = "before_1582_date_v2_4_5.snappy.parquet" | ||
| val filePath = getResourceParquetFilePath("test-data/" + fileName) | ||
| val e = intercept[SparkException] { | ||
| spark.read.parquet(filePath).collect() | ||
| }.getCause.asInstanceOf[SparkUpgradeException] | ||
|
|
||
| assert(e.getErrorClass === "INCONSISTENT_BEHAVIOR_CROSS_VERSION") | ||
| assert(e.getMessage | ||
| .startsWith("You may get a different result due to the upgrading of Spark 3.0: \n" + | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The message confuses slightly. We run Spark 3.3.0-SNAPSHOT (almost 3.3) and try to read a file written by Spark 2.4 but the message says: due to the upgrading of Spark 3.0. Should be somehow: ... due to upgrading to Spark >= 3.0?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Spark >= 3.0 sounds good. Will address in next iteration. |
||
| "reading dates before")) | ||
| } | ||
|
|
||
| // Fail to write ancient datetime values. | ||
| withSQLConf(SQLConf.PARQUET_REBASE_MODE_IN_WRITE.key -> EXCEPTION.toString) { | ||
| withTempPath { dir => | ||
| val df = Seq(java.sql.Date.valueOf("1001-01-01")).toDF("dt") | ||
| val e = intercept[SparkException] { | ||
| df.write.parquet(dir.getCanonicalPath) | ||
| }.getCause.getCause.getCause.asInstanceOf[SparkUpgradeException] | ||
|
|
||
| assert(e.getErrorClass === "INCONSISTENT_BEHAVIOR_CROSS_VERSION") | ||
| assert(e.getMessage | ||
| .startsWith("You may get a different result due to the upgrading of Spark 3.0: \n" + | ||
| "writing dates before")) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| test("UNSUPPORTED_OPERATION: timeZoneId not specified while converting TimestampType to Arrow") { | ||
| val schema = new StructType().add("value", TimestampType) | ||
| val e = intercept[SparkUnsupportedOperationException] { | ||
| ArrowUtils.toArrowSchema(schema, null) | ||
| } | ||
|
|
||
| assert(e.getErrorClass === "UNSUPPORTED_OPERATION") | ||
| assert(e.getMessage === "The operation is not supported: " + | ||
| "timestamp must supply timeZoneId parameter while converting to ArrowType") | ||
| } | ||
|
|
||
| test("UNSUPPORTED_OPERATION - SPARK-36346: can't read Timestamp as TimestampNTZ") { | ||
| val data = (1 to 10).map { i => | ||
| val ts = new Timestamp(i) | ||
| Row(ts) | ||
| } | ||
|
|
||
| val actualSchema = StructType(Seq(StructField("time", TimestampType, false))) | ||
| val providedSchema = StructType(Seq(StructField("time", TimestampNTZType, false))) | ||
|
|
||
| withTempPath { file => | ||
| val df = spark.createDataFrame(sparkContext.parallelize(data), actualSchema) | ||
| df.write.orc(file.getCanonicalPath) | ||
| withAllNativeOrcReaders { | ||
| val e = intercept[SparkException] { | ||
| spark.read.schema(providedSchema).orc(file.getCanonicalPath).collect() | ||
| }.getCause.asInstanceOf[SparkUnsupportedOperationException] | ||
|
|
||
| assert(e.getErrorClass === "UNSUPPORTED_OPERATION") | ||
| assert(e.getMessage === "The operation is not supported: " + | ||
| "Unable to convert timestamp of Orc to data type 'timestamp_ntz'") | ||
| } | ||
| } | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's avoid error message duplication. error-classes.json should be one source of truth:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @MaxGekk. Will fix this.