You are viewing a plain text version of this content. The canonical link for it is here.
Posted to reviews@spark.apache.org by "cloud-fan (via GitHub)" <gi...@apache.org> on 2023/11/01 03:26:29 UTC

Re: [PR] [SPARK-45748][SQL] Add a .fromSQL helper function for Literals [spark]

cloud-fan commented on code in PR #43612:
URL: https://github.com/apache/spark/pull/43612#discussion_r1378356375


##########
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/literals.scala:
##########
@@ -247,6 +251,67 @@ object Literal {
       s"Literal must have a corresponding value to ${dataType.catalogString}, " +
       s"but class ${Utils.getSimpleName(value.getClass)} found.")
   }
+
+  /**
+   * Parse and analyze the .sql string of a Literal, construct the Literal given the data type json.
+   * Example usage:
+   *   val serializedValue = lit.sql
+   *   val dataTypeJson = lit.dataType.json
+   *   val deserializedLit: Literal = Literal.fromSQL(serializedValue, dataTypeJson)
+   *
+   * @param valueSqlStr the .sql string of the Literal
+   * @param dataTypeJson the json format data type of the Literal
+   * @throws AnalysisException INVALID_LITERAL_VALUE_SQL_STRING_FOR_DESERIALIZATION
+   */
+  private[sql] def fromSQL(valueSqlStr: String, dataTypeJson: String): Literal = {
+    def parseAndAnalyze(valueSqlStr: String, dataType: DataType): Expression = {
+      lazy val parser = new CatalystSqlParser()
+      val parsed: Expression = try {
+        parser.parseExpression(valueSqlStr)
+      } catch {
+        case e: Exception =>
+          throw QueryCompilationErrors.invalidLiteralValueSQLStringForDeserialization(
+            "PARSE_FAILURE", valueSqlStr, dataType, Some(e))
+      }
+
+      val analyzer: Analyzer = ResolveDefaultColumns.DefaultColumnAnalyzer
+      val analyzedPlan = try {
+        val analyzed = analyzer.execute(
+          Project(
+            Seq(Alias(Cast(parsed, dataType, evalMode = EvalMode.ANSI), "alias")()),
+            OneRowRelation()
+          )
+        )
+        analyzer.checkAnalysis(analyzed)
+        // if data type is un-castable it fails here
+        ConstantFolding(analyzed)
+      } catch {
+        case e: Exception =>
+          throw QueryCompilationErrors.invalidLiteralValueSQLStringForDeserialization(
+            "ANALYSIS_FAILURE", valueSqlStr, dataType, Some(e))
+      }
+      analyzedPlan.collectFirst { case Project(Seq(a: Alias), OneRowRelation()) => a.child }.get
+    }
+
+    val dataType = DataType.fromJson(dataTypeJson)
+    val analyzedExpr = if (dataType.sameType(CalendarIntervalType)) {

Review Comment:
   we should check if it contains `CalendarIntervalType`.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org