This is an automated email from the ASF dual-hosted git repository. maxgekk pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/spark.git
The following commit(s) were added to refs/heads/master by this push: new 9840a0327a3 [SPARK-41582][CORE][SQL] Reuse `INVALID_TYPED_LITERAL` instead of `_LEGACY_ERROR_TEMP_0022` 9840a0327a3 is described below commit 9840a0327a3f242877759c97d2e7bbf8b4ac1072 Author: yangjie01 <yangji...@baidu.com> AuthorDate: Tue Dec 20 18:15:08 2022 +0300 [SPARK-41582][CORE][SQL] Reuse `INVALID_TYPED_LITERAL` instead of `_LEGACY_ERROR_TEMP_0022` ### What changes were proposed in this pull request? This pr aims reuse `INVALID_TYPED_LITERAL` instead of `_LEGACY_ERROR_TEMP_0022`. ### Why are the changes needed? Proper names of error classes to improve user experience with Spark SQL. ### Does this PR introduce _any_ user-facing change? Yes, the PR changes user-facing error message. ### How was this patch tested? Pass GitHub Actions Closes #39122 from LuciferYang/SPARK-41582. Authored-by: yangjie01 <yangji...@baidu.com> Signed-off-by: Max Gekk <max.g...@gmail.com> --- core/src/main/resources/error/error-classes.json | 5 - .../spark/sql/catalyst/parser/AstBuilder.scala | 130 ++++++++++----------- .../spark/sql/errors/QueryParsingErrors.scala | 9 -- .../catalyst/parser/ExpressionParserSuite.scala | 8 +- .../sql-tests/results/ansi/literals.sql.out | 6 +- .../resources/sql-tests/results/literals.sql.out | 6 +- 6 files changed, 77 insertions(+), 87 deletions(-) diff --git a/core/src/main/resources/error/error-classes.json b/core/src/main/resources/error/error-classes.json index 68034a5221e..30b0a5ce8f3 100644 --- a/core/src/main/resources/error/error-classes.json +++ b/core/src/main/resources/error/error-classes.json @@ -1663,11 +1663,6 @@ "Function trim doesn't support with type <trimOption>. Please use BOTH, LEADING or TRAILING as trim type." ] }, - "_LEGACY_ERROR_TEMP_0022" : { - "message" : [ - "<msg>." - ] - }, "_LEGACY_ERROR_TEMP_0023" : { "message" : [ "Numeric literal <rawStrippedQualifier> does not fit in range [<minValue>, <maxValue>] for type <typeName>." diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala index 545d5d97d88..ea752a420d5 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala @@ -2379,76 +2379,72 @@ class AstBuilder extends SqlBaseParserBaseVisitor[AnyRef] with SQLConfHelper wit specialTs.getOrElse(toLiteral(stringToTimestamp(_, zoneId), TimestampType)) } - try { - valueType match { - case "DATE" => - val zoneId = getZoneId(conf.sessionLocalTimeZone) - val specialDate = convertSpecialDate(value, zoneId).map(Literal(_, DateType)) - specialDate.getOrElse(toLiteral(stringToDate, DateType)) - case "TIMESTAMP_NTZ" => - convertSpecialTimestampNTZ(value, getZoneId(conf.sessionLocalTimeZone)) - .map(Literal(_, TimestampNTZType)) - .getOrElse(toLiteral(stringToTimestampWithoutTimeZone, TimestampNTZType)) - case "TIMESTAMP_LTZ" => - constructTimestampLTZLiteral(value) - case "TIMESTAMP" => - SQLConf.get.timestampType match { - case TimestampNTZType => - convertSpecialTimestampNTZ(value, getZoneId(conf.sessionLocalTimeZone)) - .map(Literal(_, TimestampNTZType)) - .getOrElse { - val containsTimeZonePart = - DateTimeUtils.parseTimestampString(UTF8String.fromString(value))._2.isDefined - // If the input string contains time zone part, return a timestamp with local time - // zone literal. - if (containsTimeZonePart) { - constructTimestampLTZLiteral(value) - } else { - toLiteral(stringToTimestampWithoutTimeZone, TimestampNTZType) - } + valueType match { + case "DATE" => + val zoneId = getZoneId(conf.sessionLocalTimeZone) + val specialDate = convertSpecialDate(value, zoneId).map(Literal(_, DateType)) + specialDate.getOrElse(toLiteral(stringToDate, DateType)) + case "TIMESTAMP_NTZ" => + convertSpecialTimestampNTZ(value, getZoneId(conf.sessionLocalTimeZone)) + .map(Literal(_, TimestampNTZType)) + .getOrElse(toLiteral(stringToTimestampWithoutTimeZone, TimestampNTZType)) + case "TIMESTAMP_LTZ" => + constructTimestampLTZLiteral(value) + case "TIMESTAMP" => + SQLConf.get.timestampType match { + case TimestampNTZType => + convertSpecialTimestampNTZ(value, getZoneId(conf.sessionLocalTimeZone)) + .map(Literal(_, TimestampNTZType)) + .getOrElse { + val containsTimeZonePart = + DateTimeUtils.parseTimestampString(UTF8String.fromString(value))._2.isDefined + // If the input string contains time zone part, return a timestamp with local time + // zone literal. + if (containsTimeZonePart) { + constructTimestampLTZLiteral(value) + } else { + toLiteral(stringToTimestampWithoutTimeZone, TimestampNTZType) } + } - case TimestampType => - constructTimestampLTZLiteral(value) - } + case TimestampType => + constructTimestampLTZLiteral(value) + } - case "INTERVAL" => - val interval = try { - IntervalUtils.stringToInterval(UTF8String.fromString(value)) - } catch { - case e: IllegalArgumentException => - val ex = QueryParsingErrors.cannotParseValueTypeError(valueType, value, ctx) - ex.setStackTrace(e.getStackTrace) - throw ex - } - if (!conf.legacyIntervalEnabled) { - val units = value - .split("\\s") - .map(_.toLowerCase(Locale.ROOT).stripSuffix("s")) - .filter(s => s != "interval" && s.matches("[a-z]+")) - constructMultiUnitsIntervalLiteral(ctx, interval, units) - } else { - Literal(interval, CalendarIntervalType) - } - case "X" => - val padding = if (value.length % 2 != 0) "0" else "" - try { - Literal(Hex.decodeHex(padding + value)) - } catch { - case _: DecoderException => - throw new IllegalArgumentException( - s"contains illegal character for hexBinary: $padding$value"); - } - case other => - throw QueryParsingErrors.literalValueTypeUnsupportedError( - unsupportedType = other, - supportedTypes = - Seq("DATE", "TIMESTAMP_NTZ", "TIMESTAMP_LTZ", "TIMESTAMP", "INTERVAL", "X"), - ctx) - } - } catch { - case e: IllegalArgumentException => - throw QueryParsingErrors.parsingValueTypeError(e, valueType, ctx) + case "INTERVAL" => + val interval = try { + IntervalUtils.stringToInterval(UTF8String.fromString(value)) + } catch { + case e: IllegalArgumentException => + val ex = QueryParsingErrors.cannotParseValueTypeError(valueType, value, ctx) + ex.setStackTrace(e.getStackTrace) + throw ex + } + if (!conf.legacyIntervalEnabled) { + val units = value + .split("\\s") + .map(_.toLowerCase(Locale.ROOT).stripSuffix("s")) + .filter(s => s != "interval" && s.matches("[a-z]+")) + constructMultiUnitsIntervalLiteral(ctx, interval, units) + } else { + Literal(interval, CalendarIntervalType) + } + case "X" => + val padding = if (value.length % 2 != 0) "0" else "" + try { + Literal(Hex.decodeHex(padding + value)) + } catch { + case e: DecoderException => + val ex = QueryParsingErrors.cannotParseValueTypeError("X", value, ctx) + ex.setStackTrace(e.getStackTrace) + throw ex + } + case other => + throw QueryParsingErrors.literalValueTypeUnsupportedError( + unsupportedType = other, + supportedTypes = + Seq("DATE", "TIMESTAMP_NTZ", "TIMESTAMP_LTZ", "TIMESTAMP", "INTERVAL", "X"), + ctx) } } diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/errors/QueryParsingErrors.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/errors/QueryParsingErrors.scala index aef95a538a6..773a79a3f3f 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/errors/QueryParsingErrors.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/errors/QueryParsingErrors.scala @@ -231,15 +231,6 @@ private[sql] object QueryParsingErrors extends QueryErrorsBase { ctx) } - def parsingValueTypeError( - e: IllegalArgumentException, valueType: String, ctx: TypeConstructorContext): Throwable = { - val message = Option(e.getMessage).getOrElse(s"Exception parsing $valueType") - new ParseException( - errorClass = "_LEGACY_ERROR_TEMP_0022", - messageParameters = Map("msg" -> message), - ctx) - } - def invalidNumericLiteralRangeError(rawStrippedQualifier: String, minValue: BigDecimal, maxValue: BigDecimal, typeName: String, ctx: NumberContext): Throwable = { new ParseException( diff --git a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/parser/ExpressionParserSuite.scala b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/parser/ExpressionParserSuite.scala index 760b8630f63..8fc199163cd 100644 --- a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/parser/ExpressionParserSuite.scala +++ b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/parser/ExpressionParserSuite.scala @@ -669,8 +669,12 @@ class ExpressionParserSuite extends AnalysisTest { assertEqual("x'A10C'", Literal(Array(0xa1, 0x0c).map(_.toByte))) checkError( exception = parseException("x'A1OC'"), - errorClass = "_LEGACY_ERROR_TEMP_0022", - parameters = Map("msg" -> "contains illegal character for hexBinary: A1OC"), + errorClass = "INVALID_TYPED_LITERAL", + sqlState = "42000", + parameters = Map( + "valueType" -> "\"X\"", + "value" -> "'A1OC'" + ), context = ExpectedContext( fragment = "x'A1OC'", start = 0, diff --git a/sql/core/src/test/resources/sql-tests/results/ansi/literals.sql.out b/sql/core/src/test/resources/sql-tests/results/ansi/literals.sql.out index f878d350e92..6606d9dd1ce 100644 --- a/sql/core/src/test/resources/sql-tests/results/ansi/literals.sql.out +++ b/sql/core/src/test/resources/sql-tests/results/ansi/literals.sql.out @@ -503,9 +503,11 @@ struct<> -- !query output org.apache.spark.sql.catalyst.parser.ParseException { - "errorClass" : "_LEGACY_ERROR_TEMP_0022", + "errorClass" : "INVALID_TYPED_LITERAL", + "sqlState" : "42000", "messageParameters" : { - "msg" : "contains illegal character for hexBinary: 0XuZ" + "value" : "'XuZ'", + "valueType" : "\"X\"" }, "queryContext" : [ { "objectType" : "", diff --git a/sql/core/src/test/resources/sql-tests/results/literals.sql.out b/sql/core/src/test/resources/sql-tests/results/literals.sql.out index f878d350e92..6606d9dd1ce 100644 --- a/sql/core/src/test/resources/sql-tests/results/literals.sql.out +++ b/sql/core/src/test/resources/sql-tests/results/literals.sql.out @@ -503,9 +503,11 @@ struct<> -- !query output org.apache.spark.sql.catalyst.parser.ParseException { - "errorClass" : "_LEGACY_ERROR_TEMP_0022", + "errorClass" : "INVALID_TYPED_LITERAL", + "sqlState" : "42000", "messageParameters" : { - "msg" : "contains illegal character for hexBinary: 0XuZ" + "value" : "'XuZ'", + "valueType" : "\"X\"" }, "queryContext" : [ { "objectType" : "", --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@spark.apache.org For additional commands, e-mail: commits-h...@spark.apache.org