mrhhsg commented on code in PR #63528:
URL: https://github.com/apache/doris/pull/63528#discussion_r4228218739


##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/ComplexTypeDefaultValue.java:
##########
@@ -0,0 +1,184 @@
+// 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.
+
+package org.apache.doris.nereids.trees.plans.commands.info;
+
+import org.apache.doris.nereids.exceptions.AnalysisException;
+import org.apache.doris.nereids.parser.NereidsParser;
+import org.apache.doris.nereids.trees.expressions.Expression;
+import org.apache.doris.nereids.trees.expressions.literal.ArrayLiteral;
+import org.apache.doris.nereids.trees.expressions.literal.BooleanLiteral;
+import org.apache.doris.nereids.trees.expressions.literal.Literal;
+import org.apache.doris.nereids.trees.expressions.literal.MapLiteral;
+import org.apache.doris.nereids.trees.expressions.literal.NullLiteral;
+import org.apache.doris.nereids.trees.expressions.literal.StructLiteral;
+import org.apache.doris.nereids.types.ArrayType;
+import org.apache.doris.nereids.types.DataType;
+import org.apache.doris.nereids.types.MapType;
+import org.apache.doris.nereids.types.StructField;
+import org.apache.doris.nereids.types.StructType;
+
+import com.google.common.base.Preconditions;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringJoiner;
+
+/**
+ * Validates a non-null ARRAY/MAP/STRUCT column default and rewrites it into a 
canonical literal text.
+ *
+ * <p>The user supplied text is parsed as a SQL literal and every nested value 
is cast to the declared
+ * nested type, so a type mismatch is rejected at DDL time instead of when old 
rows are read. The
+ * canonical text only contains plain nested values (unquoted numbers, double 
quoted strings, nested
+ * brackets and NULL). BE parses the stored text in two places that must 
agree: the complex SerDe
+ * {@code from_fe_string} used by the default value iterator and schema 
change, and the
+ * string-to-complex cast used when INSERT fills an unmentioned column. 
Neither of them decodes
+ * escape sequences, and the DDL parser keeps the text of a default value 
verbatim when SHOW CREATE
+ * TABLE output is replayed, so string values containing quotes or backslashes 
are rejected instead
+ * of stored.
+ */
+public class ComplexTypeDefaultValue {
+    private ComplexTypeDefaultValue() {
+    }
+
+    /**
+     * Validate the default literal of a complex column and return its 
canonical text.
+     */
+    public static String canonicalize(DataType type, String defaultValue) 
throws AnalysisException {
+        Preconditions.checkArgument(type.isArrayType() || type.isMapType() || 
type.isStructType(),
+                "%s is not a complex type", type);
+        Expression expression;
+        try {
+            expression = new NereidsParser().parseExpression(defaultValue);

Review Comment:
   Fixed in f0b6e2027a4. `canonicalize()` now parses the default text with 
`ComplexTypeDefaultValue.LiteralBuilder`, a `LogicalPlanBuilder` that overrides 
`visitArrayLiteral` / `visitMapLiteral` to keep every array item and map 
key/value exactly as written (no `typeCoercionItems`, so no inferred common 
type and no `checkedCastWithStrictChecking` that turns a failed cast into 
`NullLiteral` when `enable_strict_cast=false`). `render()` then casts each item 
to the declared nested type with `checkedCastTo`, so `ARRAY<DATEV2> DEFAULT 
'[DATEV2 "2024-01-01", 1]'` is rejected with `Invalid default value ... 1 can't 
cast to DATEV2 in strict mode.` regardless of the session setting; nested 
arrays/maps inside STRUCT or ARRAY go through the same overrides. 
`NereidsParser.parseExpression` gained an overload taking the builder, 
mirroring `parseSingle`.
   
   Tests: `ColumnDefinitionTest` adds mixed-type rejections for ARRAY<DATEV2>, 
ARRAY<ARRAY<DATEV2>>, MAP<DATEV2, INT> key, MAP<STRING, DATEV2> value and 
STRUCT<f1:ARRAY<DATEV2>> (asserting `enable_strict_cast` is off), plus 
`ARRAY<INT> '[DATEV2 "2024-01-01", 1]'` canonicalizing to `[20240101, 1]` 
instead of `[20240101, NULL]`. `test_complex_default_value` adds four CREATE 
TABLE and two ADD COLUMN negative cases under the default session settings. FE 
UT, checkstyle and the regression suite pass locally.



-- 
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: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


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

Reply via email to