morningman commented on code in PR #69488:
URL: https://github.com/apache/doris/pull/69488#discussion_r4376106072


##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/insert/InsertUtils.java:
##########
@@ -477,15 +490,62 @@ private static Plan normalizePlanWithoutLock(LogicalPlan 
plan, TableIf table,
     }
 
     static List<Column> connectorWriteSchema(TableIf table, boolean full) {
+        return pinnedConnectorWriteSchema(table).orElseGet(() -> 
table.getBaseSchema(full));
+    }
+
+    private static Optional<List<Column>> pinnedConnectorWriteSchema(TableIf 
table) {
         ConnectContext context = ConnectContext.get();
-        if (context != null && context.getStatementContext() != null) {
-            Optional<List<Column>> pinned =
-                    
context.getStatementContext().getConnectorWriteSchema(table.getId());
-            if (pinned.isPresent()) {
-                return pinned.get();
-            }
+        if (context == null || context.getStatementContext() == null) {
+            return Optional.empty();
+        }
+        return 
context.getStatementContext().getConnectorWriteSchema(table.getId());
+    }
+
+    /**
+     * The pinned writer schema of a target whose column defaults apply to 
writes only. The read schema of such a
+     * table carries no defaults, so DEFAULT(column) in an INSERT into it must 
resolve against this schema.
+     */
+    private static Optional<List<Column>> writeOnlyDefaultColumns(TableIf 
table) {
+        if (!(table instanceof PluginDrivenExternalTable)
+                || !((PluginDrivenExternalTable) 
table).hasWriteOnlyDefaults()) {
+            return Optional.empty();
         }
-        return table.getBaseSchema(full);
+        return pinnedConnectorWriteSchema(table);
+    }
+
+    /** Resolve DEFAULT(column) in one inserted value by name against the 
target's pinned writer schema. */
+    private static NamedExpression resolveDefaultReferences(NamedExpression 
value,
+            Optional<List<Column>> writeOnlyDefaultColumns, TableIf table, 
List<String> targetNameParts) {
+        if (!writeOnlyDefaultColumns.isPresent()) {
+            return value;
+        }
+        return (NamedExpression) 
ConnectorWriteSchemaUtils.resolveDefaultReferences(value,
+                writeOnlyDefaultColumns.get(), (ExternalTable) table, 
ConnectContext.get(), targetNameParts, null);
+    }
+
+    /**
+     * Resolve DEFAULT(column) in the select lists of an INSERT ... SELECT by 
name against the target's pinned
+     * writer schema, before the source relations are bound, so it names a 
target column whatever the source is.
+     */
+    private static Plan resolveSelectDefaultReferences(Plan query, 
Optional<List<Column>> writeOnlyDefaultColumns,
+            TableIf table, List<String> targetNameParts) {
+        return query.rewriteUp(plan -> {

Review Comment:
   Fixed in 724071d42a8. `resolveSelectDefaultReferences` no longer walks into 
a `LogicalSubQueryAlias`: a derived table in FROM is a query of its own, so 
`DEFAULT(column)` in it is left to binding and names a column of that table's 
own FROM clause, qualified (`DEFAULT(src.c)`) or not, as on master. The rest of 
the walk is unchanged and still bottom-up, so the INSERT's own select lists, 
set operation branches included, still resolve against the pinned writer schema.
   
   `InsertUtilsTest#writeOnlyDefaultInDerivedTableNamesItsOwnSource` covers an 
unqualified and a qualified `DEFAULT(score)` inside a derived table while the 
outer `DEFAULT(name)` resolves to the pinned default, and a UNION whose first 
branch resolves and whose second branch reads a derived table. With the 
previous `rewriteUp` walk it fails on the first case: the inner reference 
became the target's default 9. branch-4.2's 
`InsertUtils#resolveIcebergSelectDefaultReferences` walks the plan the same 
way, so it has the same problem; I'll pass that on.
   



-- 
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