This is an automated email from the ASF dual-hosted git repository. 924060929 pushed a commit to branch fe_local_shuffle_rebase_wip in repository https://gitbox.apache.org/repos/asf/doris.git
commit 81f59fdb617a60fdbfa46f4aa2db67eb81c4a7ce Author: 924060929 <[email protected]> AuthorDate: Tue May 19 22:07:03 2026 +0800 [fix](local shuffle) Restore LoadStatistic fileNum tracking under FE local-shuffle planner FE-side local-shuffle planner wraps a serial fragment root with a PASSTHROUGH LocalExchangeNode (AddLocalExchange#addLocalExchangeForFragment) so the data sink can fan out across pipeline tasks. That replaces `fragment.getPlanRoot()` with a LocalExchangeNode wherever the original root was a serial FileScanNode. InsertIntoTableCommand#applyInsertPlanStatistic was using `fragment.getPlanRoot() instanceof FileScanNode` to find load-source scans, so after the LE wrap the instanceof check fails, addLoadFileInfo is never called, and LoadStatistic.fileNum / totalFileSizeB stay 0 even though the BE-side scannedRows / loadBytes counters work normally. Symptom: job_p0.streaming_job.test_streaming_insert_job fails with loadStat.fileNumber == 0 (expected 2) and loadStat.fileSize == 0 (expected 256) while scannedRows / loadBytes are correct. Fix: peel any LocalExchangeNode wrappers off the fragment root before the instanceof check, then extract fileNum / totalFileSize from the underlying FileScanNode as before. Verified locally: INSERT INTO t SELECT * FROM LOCAL(...) shows FileNumber=1 FileSize=12 with the fix, FileNumber=0 FileSize=0 without it. --- .../plans/commands/insert/InsertIntoTableCommand.java | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/insert/InsertIntoTableCommand.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/insert/InsertIntoTableCommand.java index 89e4579c458..b66dc2a35c0 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/insert/InsertIntoTableCommand.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/insert/InsertIntoTableCommand.java @@ -82,8 +82,10 @@ import org.apache.doris.nereids.trees.plans.physical.PhysicalSink; import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor; import org.apache.doris.nereids.util.RelationUtil; import org.apache.doris.planner.DataSink; +import org.apache.doris.planner.LocalExchangeNode; import org.apache.doris.planner.OlapScanNode; import org.apache.doris.planner.PlanFragment; +import org.apache.doris.planner.PlanNode; import org.apache.doris.planner.ScanNode; import org.apache.doris.qe.ConnectContext; import org.apache.doris.qe.ConnectContext.ConnectType; @@ -676,8 +678,18 @@ public class InsertIntoTableCommand extends Command implements NeedAuditEncrypti return; } for (PlanFragment fragment : planner.getFragments()) { - if (fragment.getPlanRoot() instanceof FileScanNode) { - FileScanNode fileScanNode = (FileScanNode) fragment.getPlanRoot(); + // The FE local-shuffle planner may wrap the fragment root with one or more + // LocalExchangeNodes (e.g. a PASSTHROUGH fan-out above a serial FileScanNode). + // Peel those off before checking the actual operator, otherwise streaming / + // S3 INSERTs leave LoadStatistic.fileNum and totalFileSizeB at 0 and tests + // like job_p0.streaming_job.test_streaming_insert_job that inspect + // loadStatistic.fileNumber / fileSize fail. + PlanNode root = fragment.getPlanRoot(); + while (root instanceof LocalExchangeNode && !root.getChildren().isEmpty()) { + root = root.getChild(0); + } + if (root instanceof FileScanNode) { + FileScanNode fileScanNode = (FileScanNode) root; // Prefer distinct file count; fall back to split count for batch-mode scans. int fileNum = fileScanNode.getSelectedFileNum() >= 0 ? fileScanNode.getSelectedFileNum() --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
