This is an automated email from the ASF dual-hosted git repository.

dongjoon-hyun pushed a commit to branch branch-3.5
in repository https://gitbox.apache.org/repos/asf/spark.git


The following commit(s) were added to refs/heads/branch-3.5 by this push:
     new a318afa9f7b0 [SPARK-57446][SQL] Apply `escapeSql` to `comment` in JDBC 
`table/schema` comment queries
a318afa9f7b0 is described below

commit a318afa9f7b0c11dd4665e97da3396e2083eb982
Author: Dongjoon Hyun <[email protected]>
AuthorDate: Sun Jun 14 18:29:21 2026 -0700

    [SPARK-57446][SQL] Apply `escapeSql` to `comment` in JDBC `table/schema` 
comment queries
    
    This PR applies `escapeSql` to the `comment` argument of the JDBC dialect 
comment query
    methods: `JdbcDialect.getTableCommentQuery`, 
`JdbcDialect.getSchemaCommentQuery`, and the
    `MySQLDialect.getTableCommentQuery` override.
    
    The `comment` was embedded into a single-quoted SQL literal without 
escaping, so a comment
    containing `'` breaks the statement. `escapeSql` doubles single quotes (`'` 
-> `''`):
    
    - Before: `COMMENT ON TABLE t IS 'a'b'` (invalid)
    - After: `COMMENT ON TABLE t IS 'a''b'` (correct)
    
    This is consistent with the existing string value treatment.
    
    
https://github.com/apache/spark/blob/875982c4a65bc703bce88fb17683b423d8f88255/sql/core/src/main/scala/org/apache/spark/sql/jdbc/JdbcDialects.scala#L384-L385
    
    Yes. A table or schema comment containing a single quote is now stored 
correctly instead
    of failing with a SQL syntax error.
    
    Pass the CIs with a newly added test case.
    
    Generated-by: Claude Code (Claude Opus 4.8)
    
    Closes #56506 from dongjoon-hyun/SPARK-57446.
    
    Authored-by: Dongjoon Hyun <[email protected]>
    Signed-off-by: Dongjoon Hyun <[email protected]>
    (cherry picked from commit 072994d33c042ed60f28af1c11cc2c4584162638)
    Signed-off-by: Dongjoon Hyun <[email protected]>
    (cherry picked from commit 012a3d8ad3589110186e173bba034acb2a66a9b9)
    Signed-off-by: Dongjoon Hyun <[email protected]>
    (cherry picked from commit bf50ad9247f19586fb3aaad0f92eff484a065de8)
    Signed-off-by: Dongjoon Hyun <[email protected]>
    (cherry picked from commit 4c57f430e218edfbe162a0666f6d8e5deb04757a)
    Signed-off-by: Dongjoon Hyun <[email protected]>
    (cherry picked from commit 748f6023fafc6062519353dfa76343874f058a17)
    Signed-off-by: Dongjoon Hyun <[email protected]>
---
 .../main/scala/org/apache/spark/sql/jdbc/JdbcDialects.scala |  4 ++--
 .../main/scala/org/apache/spark/sql/jdbc/MySQLDialect.scala |  2 +-
 .../test/scala/org/apache/spark/sql/jdbc/JDBCSuite.scala    | 13 +++++++++++++
 3 files changed, 16 insertions(+), 3 deletions(-)

diff --git 
a/sql/core/src/main/scala/org/apache/spark/sql/jdbc/JdbcDialects.scala 
b/sql/core/src/main/scala/org/apache/spark/sql/jdbc/JdbcDialects.scala
index 90fc48ff5276..bea31a6ecd88 100644
--- a/sql/core/src/main/scala/org/apache/spark/sql/jdbc/JdbcDialects.scala
+++ b/sql/core/src/main/scala/org/apache/spark/sql/jdbc/JdbcDialects.scala
@@ -534,11 +534,11 @@ abstract class JdbcDialect extends Serializable with 
Logging {
   }
 
   def getTableCommentQuery(table: String, comment: String): String = {
-    s"COMMENT ON TABLE $table IS '$comment'"
+    s"COMMENT ON TABLE $table IS '${escapeSql(comment)}'"
   }
 
   def getSchemaCommentQuery(schema: String, comment: String): String = {
-    s"COMMENT ON SCHEMA ${quoteIdentifier(schema)} IS '$comment'"
+    s"COMMENT ON SCHEMA ${quoteIdentifier(schema)} IS '${escapeSql(comment)}'"
   }
 
   def removeSchemaCommentQuery(schema: String): String = {
diff --git 
a/sql/core/src/main/scala/org/apache/spark/sql/jdbc/MySQLDialect.scala 
b/sql/core/src/main/scala/org/apache/spark/sql/jdbc/MySQLDialect.scala
index 5d9ff94838f1..fbb77ade9aad 100644
--- a/sql/core/src/main/scala/org/apache/spark/sql/jdbc/MySQLDialect.scala
+++ b/sql/core/src/main/scala/org/apache/spark/sql/jdbc/MySQLDialect.scala
@@ -198,7 +198,7 @@ private case object MySQLDialect extends JdbcDialect with 
SQLConfHelper {
 
   // See https://dev.mysql.com/doc/refman/8.0/en/alter-table.html
   override def getTableCommentQuery(table: String, comment: String): String = {
-    s"ALTER TABLE $table COMMENT = '$comment'"
+    s"ALTER TABLE $table COMMENT = '${escapeSql(comment)}'"
   }
 
   override def getJDBCType(dt: DataType): Option[JdbcType] = dt match {
diff --git a/sql/core/src/test/scala/org/apache/spark/sql/jdbc/JDBCSuite.scala 
b/sql/core/src/test/scala/org/apache/spark/sql/jdbc/JDBCSuite.scala
index f4702ee9edb3..e6038938f2b9 100644
--- a/sql/core/src/test/scala/org/apache/spark/sql/jdbc/JDBCSuite.scala
+++ b/sql/core/src/test/scala/org/apache/spark/sql/jdbc/JDBCSuite.scala
@@ -826,6 +826,19 @@ class JDBCSuite extends QueryTest with SharedSparkSession {
     assert(doCompileFilter(EqualTo("col0.nested", 3)).isEmpty)
   }
 
+  test("SPARK-57446: escape single quotes in JDBC comment queries") {
+    val defaultDialect = JdbcDialects.get("jdbc:")
+    assert(defaultDialect.getTableCommentQuery("t", "a'b") ===
+      "COMMENT ON TABLE t IS 'a''b'")
+    assert(defaultDialect.getSchemaCommentQuery("s", "a'b") ===
+      """COMMENT ON SCHEMA "s" IS 'a''b'""")
+
+    // MySQL overrides getTableCommentQuery with its own ALTER TABLE syntax.
+    val mySQLDialect = JdbcDialects.get("jdbc:mysql://127.0.0.1/db")
+    assert(mySQLDialect.getTableCommentQuery("t", "a'b") ===
+      "ALTER TABLE t COMMENT = 'a''b'")
+  }
+
   test("Dialect unregister") {
     JdbcDialects.unregisterDialect(H2Dialect)
     try {


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to