diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/jsonExpressions.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/jsonExpressions.scala index 3ec17c6ca584a..ed1b7191963c8 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/jsonExpressions.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/jsonExpressions.scala @@ -454,23 +454,28 @@ case class SchemaOfJson( override def nullable: Boolean = false - @transient - private lazy val json = child.eval().asInstanceOf[UTF8String] - override def checkInputDataTypes(): TypeCheckResult = { - if (child.foldable && json != null) { - super.checkInputDataTypes() - } else if (!child.foldable) { + if (!child.foldable) { DataTypeMismatch( errorSubClass = "NON_FOLDABLE_INPUT", messageParameters = Map( "inputName" -> toSQLId("json"), "inputType" -> toSQLType(child.dataType), "inputExpr" -> toSQLExpr(child))) - } else { + } else if (child.eval() == null) { DataTypeMismatch( errorSubClass = "UNEXPECTED_NULL", messageParameters = Map("exprName" -> "json")) + } else if (child.dataType != StringType) { + DataTypeMismatch( + errorSubClass = "UNEXPECTED_INPUT_TYPE", + messageParameters = Map( + "paramIndex" -> ordinalNumber(0), + "inputSql" -> toSQLExpr(child), + "inputType" -> toSQLType(child.dataType), + "requiredType" -> toSQLType(StringType))) + } else { + super.checkInputDataTypes() } } diff --git a/sql/core/src/test/resources/sql-tests/analyzer-results/json-functions.sql.out b/sql/core/src/test/resources/sql-tests/analyzer-results/json-functions.sql.out index 9afb3e1749ed7..4fb1f0f04231a 100644 --- a/sql/core/src/test/resources/sql-tests/analyzer-results/json-functions.sql.out +++ b/sql/core/src/test/resources/sql-tests/analyzer-results/json-functions.sql.out @@ -446,6 +446,30 @@ org.apache.spark.sql.catalyst.ExtendedAnalysisException } +-- !query +select schema_of_json(42) +-- !query analysis +org.apache.spark.sql.catalyst.ExtendedAnalysisException +{ + "errorClass" : "DATATYPE_MISMATCH.UNEXPECTED_INPUT_TYPE", + "sqlState" : "42K09", + "messageParameters" : { + "inputSql" : "\"42\"", + "inputType" : "\"INT\"", + "paramIndex" : "first", + "requiredType" : "\"STRING\"", + "sqlExpr" : "\"schema_of_json(42)\"" + }, + "queryContext" : [ { + "objectType" : "", + "objectName" : "", + "startIndex" : 8, + "stopIndex" : 25, + "fragment" : "schema_of_json(42)" + } ] +} + + -- !query CREATE TEMPORARY VIEW jsonTable(jsonField, a) AS SELECT * FROM VALUES ('{"a": 1, "b": 2}', 'a') -- !query analysis diff --git a/sql/core/src/test/resources/sql-tests/inputs/json-functions.sql b/sql/core/src/test/resources/sql-tests/inputs/json-functions.sql index 71706d3c2e238..66134545107a3 100644 --- a/sql/core/src/test/resources/sql-tests/inputs/json-functions.sql +++ b/sql/core/src/test/resources/sql-tests/inputs/json-functions.sql @@ -75,6 +75,7 @@ select to_json(array(array(1, 2, 3), array(4))); select schema_of_json('{"c1":1}', map('primitivesAsString', 'true')); select schema_of_json('{"c1":01, "c2":0.1}', map('allowNumericLeadingZeros', 'true', 'prefersDecimal', 'true')); select schema_of_json(null); +select schema_of_json(42); CREATE TEMPORARY VIEW jsonTable(jsonField, a) AS SELECT * FROM VALUES ('{"a": 1, "b": 2}', 'a'); SELECT schema_of_json(jsonField) FROM jsonTable; diff --git a/sql/core/src/test/resources/sql-tests/results/json-functions.sql.out b/sql/core/src/test/resources/sql-tests/results/json-functions.sql.out index 53ade56684add..96c6dab19dc7c 100644 --- a/sql/core/src/test/resources/sql-tests/results/json-functions.sql.out +++ b/sql/core/src/test/resources/sql-tests/results/json-functions.sql.out @@ -496,6 +496,32 @@ org.apache.spark.sql.catalyst.ExtendedAnalysisException } +-- !query +select schema_of_json(42) +-- !query schema +struct<> +-- !query output +org.apache.spark.sql.catalyst.ExtendedAnalysisException +{ + "errorClass" : "DATATYPE_MISMATCH.UNEXPECTED_INPUT_TYPE", + "sqlState" : "42K09", + "messageParameters" : { + "inputSql" : "\"42\"", + "inputType" : "\"INT\"", + "paramIndex" : "first", + "requiredType" : "\"STRING\"", + "sqlExpr" : "\"schema_of_json(42)\"" + }, + "queryContext" : [ { + "objectType" : "", + "objectName" : "", + "startIndex" : 8, + "stopIndex" : 25, + "fragment" : "schema_of_json(42)" + } ] +} + + -- !query CREATE TEMPORARY VIEW jsonTable(jsonField, a) AS SELECT * FROM VALUES ('{"a": 1, "b": 2}', 'a') -- !query schema