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

yiguolei pushed a commit to branch branch-4.2
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-4.2 by this push:
     new b323ddc5d62 branch-4.2: [fix](fe) Quote variant predefined field 
comments in generated SQL (#69756)
b323ddc5d62 is described below

commit b323ddc5d622515d838b539bd9676dd1c410b66e
Author: lihangyu <[email protected]>
AuthorDate: Thu Oct 29 09:43:07 2026 +0800

    branch-4.2: [fix](fe) Quote variant predefined field comments in generated 
SQL (#69756)
    
    cherry-pick #68194
---
 .../org/apache/doris/catalog/VariantField.java     |  3 +-
 .../doris/nereids/parser/LogicalPlanBuilder.java   |  9 +---
 .../apache/doris/nereids/types/VariantField.java   |  3 +-
 .../java/org/apache/doris/catalog/TypeTest.java    | 16 +++++++
 .../test_variant_predefine_comment_escape.out      |  4 ++
 .../test_variant_predefine_comment_escape.groovy   | 55 ++++++++++++++++++++++
 6 files changed, 81 insertions(+), 9 deletions(-)

diff --git 
a/fe/fe-common/src/main/java/org/apache/doris/catalog/VariantField.java 
b/fe/fe-common/src/main/java/org/apache/doris/catalog/VariantField.java
index adb99c52cf0..1f0ecacb492 100644
--- a/fe/fe-common/src/main/java/org/apache/doris/catalog/VariantField.java
+++ b/fe/fe-common/src/main/java/org/apache/doris/catalog/VariantField.java
@@ -75,7 +75,8 @@ public class VariantField {
         sb.append("'").append(pattern).append("'");
         sb.append(":").append(type.toSql(depth + 1));
         if (!comment.isEmpty()) {
-            sb.append(" COMMENT '").append(comment).append("'");
+            sb.append(" COMMENT \"").append(comment.replace("\\", 
"\\\\").replace("\"", "\"\""))
+                    .append("\"");
         }
         return sb.toString();
     }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java
index 9fffd1180b3..b9932c79f10 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java
@@ -5487,13 +5487,8 @@ public class LogicalPlanBuilder extends 
DorisParserBaseVisitor<Object> {
 
     @Override
     public VariantField visitVariantSubColType(VariantSubColTypeContext ctx) {
-        String comment;
-        if (ctx.commentSpec() != null) {
-            comment = ctx.commentSpec().STRING_LITERAL().getText();
-            comment = 
LogicalPlanBuilderAssistant.escapeBackSlash(comment.substring(1, 
comment.length() - 1));
-        } else {
-            comment = "";
-        }
+        String comment = ctx.commentSpec() == null ? ""
+                : 
SqlLiteralUtils.parseStringLiteral(ctx.commentSpec().STRING_LITERAL().getText());
         String pattern = ctx.STRING_LITERAL().getText();
         pattern = pattern.substring(1, pattern.length() - 1);
         if (ctx.variantSubColMatchType() != null) {
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/types/VariantField.java 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/types/VariantField.java
index 5faed6893be..20e05b840dc 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/types/VariantField.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/types/VariantField.java
@@ -17,6 +17,7 @@
 
 package org.apache.doris.nereids.types;
 
+import org.apache.doris.nereids.util.SqlLiteralUtils;
 import org.apache.doris.nereids.util.Utils;
 import org.apache.doris.thrift.TPatternType;
 
@@ -85,7 +86,7 @@ public class VariantField {
         sb.append("'").append(pattern).append("'");
         sb.append(":").append(dataType.toSql());
         if (!comment.isEmpty()) {
-            sb.append(" COMMENT '").append(comment).append("'");
+            sb.append(" COMMENT 
").append(SqlLiteralUtils.quoteStringLiteral(comment));
         }
         return sb.toString();
     }
diff --git a/fe/fe-core/src/test/java/org/apache/doris/catalog/TypeTest.java 
b/fe/fe-core/src/test/java/org/apache/doris/catalog/TypeTest.java
index 0fae4b9c191..7f1861c96d2 100644
--- a/fe/fe-core/src/test/java/org/apache/doris/catalog/TypeTest.java
+++ b/fe/fe-core/src/test/java/org/apache/doris/catalog/TypeTest.java
@@ -19,6 +19,7 @@ package org.apache.doris.catalog;
 
 
 import org.apache.doris.common.Config;
+import org.apache.doris.nereids.parser.NereidsParser;
 
 import org.junit.Assert;
 import org.junit.Test;
@@ -190,6 +191,21 @@ public class TypeTest {
         }
     }
 
+    @Test
+    public void testVariantFieldCommentToSqlRoundTrip() {
+        String comment = "O'Reilly \"quoted\" a\\b";
+        ArrayList<VariantField> fields = new ArrayList<>();
+        fields.add(new VariantField("price", Type.INT, comment));
+        String sql = new VariantType(fields, 0, false, 10000, 1, false, 0L, 
64, false).toSql();
+
+        org.apache.doris.nereids.types.VariantType parsed = 
(org.apache.doris.nereids.types.VariantType)
+                new NereidsParser().parseDataType(sql);
+        Assert.assertEquals(comment, 
parsed.getPredefinedFields().get(0).getComment());
+        org.apache.doris.nereids.types.VariantType reparsed = 
(org.apache.doris.nereids.types.VariantType)
+                new NereidsParser().parseDataType("variant<" + 
parsed.getPredefinedFields().get(0).toSql() + ">");
+        Assert.assertEquals(comment, 
reparsed.getPredefinedFields().get(0).getComment());
+    }
+
     // ===================== Mixed Nesting & Precision =====================
     @Test
     public void testArrayMapStructCombinationWithPrecision() {
diff --git 
a/regression-test/data/variant_p0/predefine/test_variant_predefine_comment_escape.out
 
b/regression-test/data/variant_p0/predefine/test_variant_predefine_comment_escape.out
new file mode 100644
index 00000000000..2b18bf6ae0e
--- /dev/null
+++ 
b/regression-test/data/variant_p0/predefine/test_variant_predefine_comment_escape.out
@@ -0,0 +1,4 @@
+-- This file is automatically generated. You should know what you did if you 
want to edit this
+-- !select_copy --
+1      10      n       p
+
diff --git 
a/regression-test/suites/variant_p0/predefine/test_variant_predefine_comment_escape.groovy
 
b/regression-test/suites/variant_p0/predefine/test_variant_predefine_comment_escape.groovy
new file mode 100644
index 00000000000..9fcc88479ed
--- /dev/null
+++ 
b/regression-test/suites/variant_p0/predefine/test_variant_predefine_comment_escape.groovy
@@ -0,0 +1,55 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+// SHOW CREATE TABLE must print predefined field comments as SQL literals that 
can be replayed.
+suite("test_variant_predefine_comment_escape") {
+    sql "DROP TABLE IF EXISTS test_variant_predefine_comment_escape"
+    sql "DROP TABLE IF EXISTS test_variant_predefine_comment_escape_copy"
+    sql """
+        CREATE TABLE test_variant_predefine_comment_escape (
+            id INT,
+            v VARIANT<
+                'price':INT COMMENT "O'Reilly",
+                'name':STRING COMMENT 'say ''hi'' and "bye"',
+                'path':STRING COMMENT 'C:\\\\tmp',
+                PROPERTIES ("variant_max_subcolumns_count" = "10")
+            >
+        ) DUPLICATE KEY(id) DISTRIBUTED BY HASH(id) BUCKETS 1
+        PROPERTIES ("replication_num" = "1")
+    """
+    // SHOW CREATE TABLE output also carries cluster-dependent properties (doc 
mode, binlog,
+    // file cache), so only the predefined field list is compared here.
+    def predefinedFields = { String ddl -> (ddl =~ /variant<(.*),PROPERTIES 
/)[0][1] }
+
+    def ddl = sql("SHOW CREATE TABLE 
test_variant_predefine_comment_escape")[0][1]
+    def fields = predefinedFields(ddl)
+    // The comments keep their quotes, so they are only replayable when 
printed as escaped literals.
+    assertTrue(fields.contains("O'Reilly"))
+    assertTrue(fields.contains('say '))
+    assertTrue(fields.contains('bye'))
+
+    // Replaying the printed DDL must yield a table whose fields print exactly 
the same again:
+    // a lost escape fails the replay, and a mangled one changes the text.
+    sql ddl.replace("`test_variant_predefine_comment_escape`", 
"`test_variant_predefine_comment_escape_copy`")
+    def copyDdl = sql("SHOW CREATE TABLE 
test_variant_predefine_comment_escape_copy")[0][1]
+    assertEquals(fields, predefinedFields(copyDdl))
+
+    // These release branches default to Variant V1; its sink parses the JSON 
string.
+    sql """INSERT INTO test_variant_predefine_comment_escape_copy
+            SELECT 1, '{"price": 10, "name": "n", "path": "p"}'"""
+    order_qt_select_copy "SELECT id, v['price'], v['name'], v['path'] FROM 
test_variant_predefine_comment_escape_copy"
+}


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

Reply via email to