morningman commented on code in PR #69488:
URL: https://github.com/apache/doris/pull/69488#discussion_r4363771707
##########
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/RewriteDefaultExpression.java:
##########
@@ -76,12 +81,23 @@ private static Expression
rewrite(ExpressionMatchingContext<Default> context) {
}
Column column = columnOpt.get();
- DataType targetType = DataType.fromCatalogType(column.getType());
if (column.isGeneratedColumn()) {
throw new AnalysisException("DEFAULT cannot be used on generated
column '"
+ column.getName() + "'");
}
+ Optional<TableIf> originalTable = slotRef.getOriginalTable();
+ if (originalTable.filter(PluginDrivenExternalTable.class::isInstance)
+ .filter(table -> ((PluginDrivenExternalTable)
table).hasWriteOnlyDefaults())
+ .isPresent()) {
+ column =
pinnedWriteColumn(context.cascadesContext.getStatementContext(),
originalTable.get(), column)
+ .orElseThrow(() -> new AnalysisException("DEFAULT(" +
slotRef.toSql()
+ + ") must reference a column of the table that
this statement writes"));
+ }
+ // The pinned writer column can be wider than the read column the slot
was bound with, e.g. after a type
+ // promotion committed outside Doris, and the default is a value of
the writer column.
+ DataType targetType = DataType.fromCatalogType(column.getType());
Review Comment:
Fixed in 688e8d59412. Agreed: once IF, CASE or COALESCE have been bound
against the read type, a wider writer-typed default cannot be substituted from
the DEFAULT node, because the rewriter keeps their signatures and constant
folding narrows the value back. The read and writer types of one field only
differ while Doris's cached read schema predates a type change committed
outside Doris (reads go through the table cache, the writer schema is loaded
for the statement), so the bound rewrite now fails such a DEFAULT and asks to
refresh the table instead of retyping its consumers. When the two types agree,
which is every case without an outside type change, nothing changes. DEFAULT in
VALUES, in INSERT ... SELECT projections and in UPDATE SET is resolved against
the writer schema before binding, so its consumers already bind against the
writer type. `RewriteDefaultExpressionTest` covers a direct DEFAULT and one
under an IF bound to INT; both are rejected.
##########
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/RewriteDefaultExpression.java:
##########
@@ -82,6 +87,15 @@ private static Expression
rewrite(ExpressionMatchingContext<Default> context) {
+ column.getName() + "'");
}
+ Optional<TableIf> originalTable = slotRef.getOriginalTable();
+ if (originalTable.filter(PluginDrivenExternalTable.class::isInstance)
+ .filter(table -> ((PluginDrivenExternalTable)
table).hasWriteOnlyDefaults())
+ .isPresent()) {
+ column =
pinnedWriteColumn(context.cascadesContext.getStatementContext(),
originalTable.get(), column)
Review Comment:
Follow-up: superseded in 688e8d59412 (see the newer thread on this file).
Typing the substituted default as the writer column fixed the DEFAULT node
itself but not the expressions bound around it against the read type, so a
writer column whose type differs from the read column now fails with a refresh
hint instead.
--
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]