This is an automated email from the ASF dual-hosted git repository.
csun5285 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new 886cb3ea48d [fix](struct) Preserve nested field comments in SHOW
CREATE TABLE (#68307)
886cb3ea48d is described below
commit 886cb3ea48d7cf6cd3344edce0b1422ec5700634
Author: Chenyang Sun <[email protected]>
AuthorDate: Tue Oct 20 15:47:58 2026 +0800
[fix](struct) Preserve nested field comments in SHOW CREATE TABLE (#68307)
### What problem does this PR solve?
```sql
CREATE TABLE t (id INT, s STRUCT<a:INT COMMENT 'field doc'>)
DUPLICATE KEY(id)
DISTRIBUTED BY HASH(id) BUCKETS 1
PROPERTIES ("replication_num" = "1");
SHOW CREATE TABLE t;
```
Before: `s` is shown as `struct<a:int>`.
After: `s` is shown as `struct<a:int comment "field doc">`.
---
.../main/java/org/apache/doris/catalog/Column.java | 2 +-
.../java/org/apache/doris/catalog/TypeTest.java | 38 +++++++++++++++
.../ddl/test_struct_nested_comment_ddl.out | 10 ++++
.../ddl/test_struct_nested_comment_ddl.groovy | 55 ++++++++++++++++++++++
4 files changed, 104 insertions(+), 1 deletion(-)
diff --git a/fe/fe-catalog/src/main/java/org/apache/doris/catalog/Column.java
b/fe/fe-catalog/src/main/java/org/apache/doris/catalog/Column.java
index 6272cfc0a3b..c4895ec5160 100644
--- a/fe/fe-catalog/src/main/java/org/apache/doris/catalog/Column.java
+++ b/fe/fe-catalog/src/main/java/org/apache/doris/catalog/Column.java
@@ -906,7 +906,7 @@ public class Column implements GsonPostProcessable {
// show change datetimeV2/dateV2 to datetime/date
if (isCompatible) {
- sb.append(type.hideVersionForVersionColumn(true));
+ sb.append(type.hideVersionForVersionColumn(true, true));
} else {
sb.append(typeStr);
}
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 a4909a8aeed..7c66345fb6d 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
@@ -316,4 +316,42 @@ public class TypeTest {
Assertions.assertFalse(dtv2s6.matchesType(timestampNs));
Assertions.assertFalse(Type.matchExactType(timestampNs,
wildcardDatetimeV2, false));
}
+
+ // ===================== STRUCT nested comment in DDL =====================
+
+ /** SHOW CREATE TABLE has to print the comment of every nested field. */
+ @Test
+ public void testStructDdlKeepsNestedFieldComment() {
+ StructType structType = new StructType(
+ new StructField("a", Type.INT, null, true),
+ new StructField("b", Type.STRING, "field doc", true));
+ Column column = new Column("s", structType, false, null, true, null,
"top-level");
+
+ Assertions.assertEquals(
+ "`s` struct<a:int,b:text comment \"field doc\"> NULL COMMENT
\"top-level\"",
+ column.toSql(false, true));
+ }
+
+ /** A nested comment has to stay a readable literal, quotes and back
slashes included. */
+ @Test
+ public void testStructDdlEscapesNestedFieldComment() {
+ StructType structType = new StructType(
+ new StructField("b", Type.STRING, "owner''s \\path and
\"quotes\"", true));
+ Column column = new Column("s", structType, false, null, true, null,
null);
+
+ Assertions.assertEquals(
+ "`s` struct<b:text comment \"owner''s \\\\path and
\"\"quotes\"\"\"> NULL",
+ column.toSql(false, true));
+ }
+
+ /** Nested comments belong to DDL, but DESCRIBE only prints them when
asked for. */
+ @Test
+ public void testStructDescribeHidesNestedCommentUnlessRequested() {
+ StructType structType = new StructType(
+ new StructField("b", Type.STRING, "field doc", true));
+ Assertions.assertEquals("struct<b:text>",
+ structType.hideVersionForVersionColumn(true, false));
+ Assertions.assertEquals("struct<b:text comment \"field doc\">",
+ structType.hideVersionForVersionColumn(true, true));
+ }
}
diff --git
a/regression-test/data/datatype_p0/nested_types/ddl/test_struct_nested_comment_ddl.out
b/regression-test/data/datatype_p0/nested_types/ddl/test_struct_nested_comment_ddl.out
new file mode 100644
index 00000000000..239892b5bf8
--- /dev/null
+++
b/regression-test/data/datatype_p0/nested_types/ddl/test_struct_nested_comment_ddl.out
@@ -0,0 +1,10 @@
+-- This file is automatically generated. You should know what you did if you
want to edit this
+-- !show_create --
+struct_nested_comment `id` int NULL,\n `s` struct<a:int,b:text comment
"owner''s \\\\path",c:int> NULL COMMENT "top-level",\n `n`
struct<lvl1:struct<lvl2:int comment "deep doc">> NULL,\n `arr`
array<struct<inside:int comment "in array">> NULL
+
+-- !show_create_replay --
+struct_nested_comment_replay `id` int NULL,\n `s` struct<a:int,b:text
comment "owner''s \\\\path",c:int> NULL COMMENT "top-level",\n `n`
struct<lvl1:struct<lvl2:int comment "deep doc">> NULL,\n `arr`
array<struct<inside:int comment "in array">> NULL
+
+-- !show_create_like --
+struct_nested_comment_like `id` int NULL,\n `s` struct<a:int,b:text
comment "owner''s \\\\path",c:int> NULL COMMENT "top-level",\n `n`
struct<lvl1:struct<lvl2:int comment "deep doc">> NULL,\n `arr`
array<struct<inside:int comment "in array">> NULL
+
diff --git
a/regression-test/suites/datatype_p0/nested_types/ddl/test_struct_nested_comment_ddl.groovy
b/regression-test/suites/datatype_p0/nested_types/ddl/test_struct_nested_comment_ddl.groovy
new file mode 100644
index 00000000000..035dcdf1c13
--- /dev/null
+++
b/regression-test/suites/datatype_p0/nested_types/ddl/test_struct_nested_comment_ddl.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.
+
+suite("test_struct_nested_comment_ddl", "p0") {
+ sql "DROP TABLE IF EXISTS struct_nested_comment"
+ sql "DROP TABLE IF EXISTS struct_nested_comment_replay"
+ sql "DROP TABLE IF EXISTS struct_nested_comment_like"
+
+ // The comment on b carries a single quote and a back slash, both have to
survive the DDL.
+ sql """
+ CREATE TABLE struct_nested_comment (
+ id INT,
+ s STRUCT<a:INT, b:TEXT COMMENT "owner''s \\\\path", c:INT> COMMENT
"top-level",
+ n STRUCT<lvl1:STRUCT<lvl2:INT COMMENT "deep doc">>,
+ arr ARRAY<STRUCT<inside:INT COMMENT "in array">>
+ )
+ DUPLICATE KEY(id)
+ DISTRIBUTED BY HASH(id) BUCKETS 1
+ PROPERTIES ("replication_num" = "1")
+ """
+
+ // Only compare column definitions; table properties depend on the
deployment and FE configuration.
+ def columnDefinitions = { row ->
+ def ddl = row[1].toString()
+ [row[0], ddl.substring(ddl.indexOf("(\n") + 2, ddl.indexOf("\n)
ENGINE="))]
+ }
+
+ // SHOW CREATE TABLE used to drop every nested field comment.
+ quickRunTest("show_create", "SHOW CREATE TABLE struct_nested_comment",
false, columnDefinitions)
+ def createStmt = (sql "SHOW CREATE TABLE
struct_nested_comment")[0][1].toString()
+
+ // The printed DDL still has to parse back.
+ def replayStmt = createStmt.replace("`struct_nested_comment`",
"`struct_nested_comment_replay`")
+ sql replayStmt
+ quickRunTest("show_create_replay", "SHOW CREATE TABLE
struct_nested_comment_replay", false, columnDefinitions)
+
+ // CREATE TABLE LIKE re-parses the same generated DDL, so a dropped nested
comment is
+ // gone from the new table for good, not just hidden from the user.
+ sql "CREATE TABLE struct_nested_comment_like LIKE struct_nested_comment"
+ quickRunTest("show_create_like", "SHOW CREATE TABLE
struct_nested_comment_like", false, columnDefinitions)
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]