You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spark.apache.org by gu...@apache.org on 2024/07/20 00:53:36 UTC
(spark) branch master updated: [SPARK-48944][CONNECT] Unify the JSON-format schema handling in Connect Server
This is an automated email from the ASF dual-hosted git repository.
gurwls223 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 163256851ac0 [SPARK-48944][CONNECT] Unify the JSON-format schema handling in Connect Server
163256851ac0 is described below
commit 163256851ac08fb3cdde4c81e8db7863f3fe1272
Author: Ruifeng Zheng <ru...@apache.org>
AuthorDate: Sat Jul 20 09:53:25 2024 +0900
[SPARK-48944][CONNECT] Unify the JSON-format schema handling in Connect Server
### What changes were proposed in this pull request?
Simplify the JSON-format schema handling in Connect Server, by introducing a helper function `extractDataTypeFromJSON`
### Why are the changes needed?
to unify the schema handling
### Does this PR introduce _any_ user-facing change?
No, minor refactoring
### How was this patch tested?
CI
### Was this patch authored or co-authored using generative AI tooling?
No
Closes #47415 from zhengruifeng/simplfy_from_json.
Authored-by: Ruifeng Zheng <ru...@apache.org>
Signed-off-by: Hyukjin Kwon <gu...@apache.org>
---
.../sql/connect/planner/SparkConnectPlanner.scala | 76 +++++++++-------------
1 file changed, 30 insertions(+), 46 deletions(-)
diff --git a/connect/server/src/main/scala/org/apache/spark/sql/connect/planner/SparkConnectPlanner.scala b/connect/server/src/main/scala/org/apache/spark/sql/connect/planner/SparkConnectPlanner.scala
index 9eeec306cda8..013f0d83391c 100644
--- a/connect/server/src/main/scala/org/apache/spark/sql/connect/planner/SparkConnectPlanner.scala
+++ b/connect/server/src/main/scala/org/apache/spark/sql/connect/planner/SparkConnectPlanner.scala
@@ -1946,65 +1946,32 @@ class SparkConnectPlanner(
case "from_json" if Seq(2, 3).contains(fun.getArgumentsCount) =>
// JsonToStructs constructor doesn't accept JSON-formatted schema.
- val children = fun.getArgumentsList.asScala.map(transformExpression)
-
- var schema: DataType = null
- children(1) match {
- case Literal(s, StringType) if s != null =>
- try {
- schema = DataType.fromJson(s.toString)
- } catch {
- case _: Exception =>
- }
- case _ =>
- }
-
- if (schema != null) {
+ extractDataTypeFromJSON(fun.getArguments(1)).map { dataType =>
+ val children = fun.getArgumentsList.asScala.map(transformExpression)
+ val schema = CharVarcharUtils.failIfHasCharVarchar(dataType)
var options = Map.empty[String, String]
if (children.length == 3) {
options = extractMapData(children(2), "Options")
}
- Some(
- JsonToStructs(
- schema = CharVarcharUtils.failIfHasCharVarchar(schema),
- options = options,
- child = children.head))
- } else {
- None
+ JsonToStructs(schema = schema, options = options, child = children.head)
}
case "from_xml" if Seq(2, 3).contains(fun.getArgumentsCount) =>
// XmlToStructs constructor doesn't accept JSON-formatted schema.
- val children = fun.getArgumentsList.asScala.map(transformExpression)
-
- var schema: DataType = null
- children(1) match {
- case Literal(s, StringType) if s != null =>
- try {
- schema = DataType.fromJson(s.toString)
- } catch {
- case _: Exception =>
- }
- case _ =>
- }
-
- if (schema != null) {
- schema match {
- case t: StructType => t
- case _ => throw DataTypeErrors.failedParsingStructTypeError(schema.sql)
+ extractDataTypeFromJSON(fun.getArguments(1)).map { dataType =>
+ val children = fun.getArgumentsList.asScala.map(transformExpression)
+ val schema = dataType match {
+ case t: StructType =>
+ CharVarcharUtils
+ .failIfHasCharVarchar(t)
+ .asInstanceOf[StructType]
+ case _ => throw DataTypeErrors.failedParsingStructTypeError(dataType.sql)
}
-
var options = Map.empty[String, String]
if (children.length == 3) {
options = extractMapData(children(2), "Options")
}
- Some(
- XmlToStructs(
- schema = CharVarcharUtils.failIfHasCharVarchar(schema).asInstanceOf[StructType],
- options = options,
- child = children.head))
- } else {
- None
+ XmlToStructs(schema = schema, options = options, child = children.head)
}
// Avro-specific functions
@@ -2189,6 +2156,23 @@ class SparkConnectPlanner(
case other => throw InvalidPlanInput(s"$field should be created by map, but got $other")
}
+ // Extract the schema from a literal string representing a JSON-formatted schema
+ private def extractDataTypeFromJSON(exp: proto.Expression): Option[DataType] = {
+ exp.getExprTypeCase match {
+ case proto.Expression.ExprTypeCase.LITERAL =>
+ exp.getLiteral.getLiteralTypeCase match {
+ case proto.Expression.Literal.LiteralTypeCase.STRING =>
+ try {
+ Some(DataType.fromJson(exp.getLiteral.getString))
+ } catch {
+ case _: Exception => None
+ }
+ case _ => None
+ }
+ case _ => None
+ }
+ }
+
private def transformAlias(alias: proto.Expression.Alias): NamedExpression = {
if (alias.getNameCount == 1) {
val metadata = if (alias.hasMetadata() && alias.getMetadata.nonEmpty) {
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@spark.apache.org
For additional commands, e-mail: commits-help@spark.apache.org