github-actions[bot] commented on code in PR #69176:
URL: https://github.com/apache/doris/pull/69176#discussion_r4323713695
##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/RowLevelDmlCommand.java:
##########
@@ -80,10 +89,34 @@ public void run(ConnectContext ctx, StmtExecutor
stmtExecutor) throws Exception
Callable<Void> execute = () -> {
LogicalPlanAdapter logicalPlanAdapter = new
LogicalPlanAdapter(plan, ctx.getStatementContext());
NereidsPlanner planner = new
NereidsPlanner(ctx.getStatementContext());
+ if (op == RowLevelDmlOp.DELETE) {
+ captureAnalyzedPlan(ctx);
Review Comment:
[P2] Preserve physical slot provenance in fallback conflict filters
This new capture also supplies the analyzed plan to
`applyWriteConstraintIfPresent` after the metadata path falls back. Consider
the analyzed mask plan:
```text
DeleteSink
Project(operation, row_id)
Filter(a#masked = 1)
Project(b AS a#masked, b, row_id)
Scan(t)
```
The exact extractor rejects the renamed slot, but fallback
`extractWriteConstraint` still uses the loose extractor, which checks only the
original table and emits physical `a = 1`. On an unpartitioned table with
serializable delete isolation, a concurrent appended file containing
`(a=0,b=1)` is then excluded from `RowDelta.conflictDetectionFilter`, so
`validateNoConflictingDataFiles` misses a matching write. Previously a plain
DELETE supplied no analyzed plan and left this conflict check unfiltered.
Validate/rewrite projected slot provenance in the loose extractor too, or omit
this conjunct conservatively. This is the newly activated fallback conflict
consumer; the earlier projection thread covers direct metadata-file deletion.
##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/PositionDeleteRowLevelDmlTransform.java:
##########
@@ -209,10 +212,45 @@ public void finalizeSink(BaseExternalTableInsertExecutor
executor, RowLevelDmlOp
@Override
public Optional<ConnectorPredicate> extractWriteConstraint(Plan
analyzedPlan, TableIf table) {
+ return WriteConstraintExtractor.extract(analyzedPlan, table.getId(),
syntheticColumnExclusion(table));
Review Comment:
[P2] Distinguish the target relation from self-joined source scans
The newly captured DELETE plan also makes this loose extractor visit filters
inside a `USING` source. For example:
```sql
DELETE FROM t d
USING (SELECT id FROM t WHERE flag = 1) s
WHERE d.id = s.id + 1
```
The analyzed tree contains `Join(Scan(t d), Project(id, Filter(flag=1,
Scan(t))))`. Both scans have the same table ID, so `isTargetOnlyPredicate`
accepts the source-only `flag=1` conjunct and the fallback installs it as the
target's `RowDelta.conflictDetectionFilter`. With rows `(id=1,flag=1)` and
`(id=2,flag=0)`, the DELETE targets the second row, yet serializable validation
excludes a concurrently appended `(id=2,flag=0)` file. The strict metadata
extractor rejects the join, so this reaches the row-level commit; the earlier
uncaptured plan left its conflict check unfiltered. Track the target scan's
relation/slot identity, or omit source-subtree predicates conservatively.
Matching physical column names alone cannot distinguish the two relation
instances.
--
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]