From bc6ec05616351d46b1555cedf6a6e0fb7203b3b0 Mon Sep 17 00:00:00 2001 From: Bruce Robbins Date: Wed, 16 Nov 2022 16:04:27 -0800 Subject: [PATCH 1/2] Initial attempt --- .../spark/sql/catalyst/expressions/TryEval.scala | 14 +++++++++++++- .../sql-tests/inputs/try-string-functions.sql | 4 +++- .../sql-tests/results/try-string-functions.sql.out | 9 +++++++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/TryEval.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/TryEval.scala index a23f4f619436..8fa7ab0bbd73 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/TryEval.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/TryEval.scala @@ -20,6 +20,7 @@ package org.apache.spark.sql.catalyst.expressions import org.apache.spark.sql.catalyst.InternalRow import org.apache.spark.sql.catalyst.expressions.codegen.{CodegenContext, CodeGenerator, ExprCode} import org.apache.spark.sql.catalyst.expressions.codegen.Block._ +import org.apache.spark.sql.errors.QueryCompilationErrors import org.apache.spark.sql.types.{DataType, NumericType} case class TryEval(child: Expression) extends UnaryExpression with NullIntolerant { @@ -227,7 +228,8 @@ case class TryToBinary( def this(expr: Expression, formatExpression: Expression) = this(expr, Some(formatExpression), - TryEval(ToBinary(expr, Some(formatExpression), nullOnInvalidFormat = true))) + TryEval(ToBinary(expr, Some(TryToBinary.checkFormat(formatExpression)), + nullOnInvalidFormat = true))) override def prettyName: String = "try_to_binary" @@ -236,3 +238,13 @@ case class TryToBinary( override protected def withNewChildInternal(newChild: Expression): Expression = this.copy(replacement = newChild) } + +object TryToBinary { + def checkFormat(format: Expression): Expression = { + if (format.foldable) { + format + } else { + throw QueryCompilationErrors.requireLiteralParameter("try_to_binary", "format", "string") + } + } +} diff --git a/sql/core/src/test/resources/sql-tests/inputs/try-string-functions.sql b/sql/core/src/test/resources/sql-tests/inputs/try-string-functions.sql index 4ff3e69da67a..bef9c3d9b16c 100644 --- a/sql/core/src/test/resources/sql-tests/inputs/try-string-functions.sql +++ b/sql/core/src/test/resources/sql-tests/inputs/try-string-functions.sql @@ -45,4 +45,6 @@ select try_to_binary(null, null); select try_to_binary(null, cast(null as string)); -- invalid format select try_to_binary('abc', 1); -select try_to_binary('abc', 'invalidFormat'); \ No newline at end of file +select try_to_binary('abc', 'invalidFormat'); +-- format must be folable +SELECT try_to_binary(col1, col2) from values ('abc', 'utf-8') as data(col1, col2); diff --git a/sql/core/src/test/resources/sql-tests/results/try-string-functions.sql.out b/sql/core/src/test/resources/sql-tests/results/try-string-functions.sql.out index 4488bb649654..daf3bb860d2f 100644 --- a/sql/core/src/test/resources/sql-tests/results/try-string-functions.sql.out +++ b/sql/core/src/test/resources/sql-tests/results/try-string-functions.sql.out @@ -281,3 +281,12 @@ select try_to_binary('abc', 'invalidFormat') struct -- !query output NULL + + +-- !query +SELECT try_to_binary(col1, col2) from values ('abc', 'utf-8') as data(col1, col2) +-- !query schema +struct<> +-- !query output +org.apache.spark.sql.AnalysisException +The 'format' parameter of function 'try_to_binary' needs to be a string literal.; line 1 pos 7 From b9adc776e81009ea345c23b14b50284f7ac1a4e1 Mon Sep 17 00:00:00 2001 From: Bruce Robbins Date: Thu, 17 Nov 2022 08:23:37 -0800 Subject: [PATCH 2/2] Update tests --- .../sql-tests/inputs/string-functions.sql | 4 ++++ .../sql-tests/inputs/try-string-functions.sql | 4 +++- .../results/ansi/string-functions.sql.out | 17 +++++++++++++++++ .../sql-tests/results/string-functions.sql.out | 17 +++++++++++++++++ .../results/try-string-functions.sql.out | 8 ++++++++ 5 files changed, 49 insertions(+), 1 deletion(-) diff --git a/sql/core/src/test/resources/sql-tests/inputs/string-functions.sql b/sql/core/src/test/resources/sql-tests/inputs/string-functions.sql index cb18c547b612..41d44aaa5fb8 100644 --- a/sql/core/src/test/resources/sql-tests/inputs/string-functions.sql +++ b/sql/core/src/test/resources/sql-tests/inputs/string-functions.sql @@ -225,3 +225,7 @@ select to_binary(null, cast(null as string)); -- invalid format select to_binary('abc', 1); select to_binary('abc', 'invalidFormat'); +-- format must be foldable +SELECT to_binary(col1, col2) from values ('abc', 'utf-8') as data(col1, col2); +-- non-foldable input string +SELECT to_binary(col1, 'utf-8') from values ('abc') as data(col1); diff --git a/sql/core/src/test/resources/sql-tests/inputs/try-string-functions.sql b/sql/core/src/test/resources/sql-tests/inputs/try-string-functions.sql index bef9c3d9b16c..fedfd793ecef 100644 --- a/sql/core/src/test/resources/sql-tests/inputs/try-string-functions.sql +++ b/sql/core/src/test/resources/sql-tests/inputs/try-string-functions.sql @@ -46,5 +46,7 @@ select try_to_binary(null, cast(null as string)); -- invalid format select try_to_binary('abc', 1); select try_to_binary('abc', 'invalidFormat'); --- format must be folable +-- format must be foldable SELECT try_to_binary(col1, col2) from values ('abc', 'utf-8') as data(col1, col2); +-- non-foldable input string +SELECT try_to_binary(col1, 'utf-8') from values ('abc') as data(col1); diff --git a/sql/core/src/test/resources/sql-tests/results/ansi/string-functions.sql.out b/sql/core/src/test/resources/sql-tests/results/ansi/string-functions.sql.out index 5b82cfa957d1..f0fcffb7db1a 100644 --- a/sql/core/src/test/resources/sql-tests/results/ansi/string-functions.sql.out +++ b/sql/core/src/test/resources/sql-tests/results/ansi/string-functions.sql.out @@ -1597,3 +1597,20 @@ org.apache.spark.sql.AnalysisException "invalidValue" : "invalidformat" } } + + +-- !query +SELECT to_binary(col1, col2) from values ('abc', 'utf-8') as data(col1, col2) +-- !query schema +struct<> +-- !query output +org.apache.spark.sql.AnalysisException +The 'format' parameter of function 'to_binary' needs to be a string literal.; line 1 pos 7 + + +-- !query +SELECT to_binary(col1, 'utf-8') from values ('abc') as data(col1) +-- !query schema +struct +-- !query output +abc diff --git a/sql/core/src/test/resources/sql-tests/results/string-functions.sql.out b/sql/core/src/test/resources/sql-tests/results/string-functions.sql.out index 58a36b3299fb..9143ea938e2b 100644 --- a/sql/core/src/test/resources/sql-tests/results/string-functions.sql.out +++ b/sql/core/src/test/resources/sql-tests/results/string-functions.sql.out @@ -1529,3 +1529,20 @@ org.apache.spark.sql.AnalysisException "invalidValue" : "invalidformat" } } + + +-- !query +SELECT to_binary(col1, col2) from values ('abc', 'utf-8') as data(col1, col2) +-- !query schema +struct<> +-- !query output +org.apache.spark.sql.AnalysisException +The 'format' parameter of function 'to_binary' needs to be a string literal.; line 1 pos 7 + + +-- !query +SELECT to_binary(col1, 'utf-8') from values ('abc') as data(col1) +-- !query schema +struct +-- !query output +abc diff --git a/sql/core/src/test/resources/sql-tests/results/try-string-functions.sql.out b/sql/core/src/test/resources/sql-tests/results/try-string-functions.sql.out index daf3bb860d2f..a49eee919bbc 100644 --- a/sql/core/src/test/resources/sql-tests/results/try-string-functions.sql.out +++ b/sql/core/src/test/resources/sql-tests/results/try-string-functions.sql.out @@ -290,3 +290,11 @@ struct<> -- !query output org.apache.spark.sql.AnalysisException The 'format' parameter of function 'try_to_binary' needs to be a string literal.; line 1 pos 7 + + +-- !query +SELECT try_to_binary(col1, 'utf-8') from values ('abc') as data(col1) +-- !query schema +struct +-- !query output +abc