github-actions[bot] commented on code in PR #66802:
URL: https://github.com/apache/doris/pull/66802#discussion_r3791684742


##########
be/src/exec/scan/file_scanner_v2.cpp:
##########
@@ -448,16 +470,50 @@ Status FileScannerV2::_open_impl(RuntimeState* state) {
         DORIS_CHECK(_table_reader != nullptr);
         RETURN_IF_ERROR(_init_expr_ctxes());
         RETURN_IF_ERROR(_init_table_reader(_current_range));
+        // Refine the first source split before yielding the scanner worker. 
Other scanners may be
+        // waiting for its row-group children, so deferring publication until 
a later get_block()
+        // turn could let those waiters occupy the scan thread pool ahead of 
the producer.
+        bool eos = false;
+        RETURN_IF_ERROR(_prepare_next_split(&eos));

Review Comment:
   [P1] Refresh the split digest after late Runtime Filters
   
   This eagerly prepares the first split inside `open()`, before 
`ScannerScheduler` calls `try_append_late_arrival_runtime_filter()`. If an RF 
arrives during that work, a generated Parquet child or first ORC split keeps 
`digest(P)`, but the reader-null refresh changes its conjuncts to `P AND RF` 
without updating the digest/coverage flag. A Condition Cache MISS that reaches 
EOF can then publish `P AND RF` survivors under `P`; a later `P`-only HIT will 
skip granules containing valid rows. Defer preparation until after the RF hook, 
or recompute/invalidate the split cache identity on reader-null refresh, and 
cover this arrival race with a cache-reuse regression.



##########
be/src/exec/scan/file_scanner_v2.cpp:
##########
@@ -585,14 +642,51 @@ Status FileScannerV2::_prepare_next_split(bool* eos) {
             // advance exactly one scan range and preserve later files in the 
same scan.
             RETURN_IF_ERROR(_table_reader->abort_split());
             COUNTER_UPDATE(_empty_file_counter, 1);
-            _state->update_num_finished_scan_range(1);
+            RETURN_IF_ERROR(_complete_current_split());
             continue;
         }
         RETURN_IF_ERROR(status);
         if (_table_reader->current_split_pruned()) {
-            _state->update_num_finished_scan_range(1);
+            RETURN_IF_ERROR(_complete_current_split());
             continue;
         }
+        if (_current_split.is_source_split && 
can_refine_source_split(_current_range)) {
+            std::vector<FileScanSplit> generated_splits;
+            bool was_split = false;
+            const auto split_status = _table_reader->build_physical_splits(
+                    _current_split, &generated_splits, &was_split);
+            const auto ignored_split_status = _classify_ignored_split_status(
+                    split_status, 
config::ignore_not_found_file_in_external_table,
+                    _should_stop || _io_ctx->should_stop);
+            if (ignored_split_status == IgnoredSplitStatus::NOT_FOUND) {
+                RETURN_IF_ERROR(_table_reader->abort_split());
+                COUNTER_UPDATE(_not_found_file_counter, 1);
+                RETURN_IF_ERROR(_complete_current_split());
+                continue;
+            }
+            if (ignored_split_status == IgnoredSplitStatus::EMPTY) {
+                RETURN_IF_ERROR(_table_reader->abort_split());
+                COUNTER_UPDATE(_empty_file_counter, 1);
+                RETURN_IF_ERROR(_complete_current_split());
+                continue;
+            }
+            RETURN_IF_ERROR(split_status);
+            if (was_split) {
+                RETURN_IF_ERROR(_table_reader->abort_split());
+                const bool has_children = !generated_splits.empty();
+                
RETURN_IF_ERROR(_retire_current_source_split(std::move(generated_splits)));
+                if (!has_children) {
+                    RETURN_IF_ERROR(_complete_current_split());
+                }
+                continue;

Review Comment:
   [P2] Keep FileNumber tied to source ranges
   
   This `continue` skips `FileNumber` for the parent, while every generated Row 
Group child later falls through to the existing increment. One FE range 
therefore reports R files for R nonempty Row Groups (and zero for an all-empty 
refined source), whereas the unsplit/one-group path reports one. That makes the 
established file/range metric depend on a BE-local scheduling choice and 
renders profiles incomparable. Increment `FileNumber` once for the accepted 
source range, and expose generated children through a separately named counter 
if needed.



##########
be/src/format_v2/table_reader.cpp:
##########
@@ -1249,6 +1254,40 @@ Status TableReader::prepare_split(const 
SplitReadOptions& options) {
     return _parse_delete_predicates(options);
 }
 
+Status TableReader::build_physical_splits(const FileScanSplit& source_split,
+                                          std::vector<FileScanSplit>* splits, 
bool* was_split) {
+    DORIS_CHECK(splits != nullptr);
+    DORIS_CHECK(was_split != nullptr);
+    splits->clear();
+    *was_split = false;
+    if (_format != FileFormat::PARQUET || _current_split_pruned ||
+        _current_split_uses_metadata_count || _current_task == nullptr) {
+        return Status::OK();
+    }
+
+    std::unique_ptr<FileReader> reader;
+    RETURN_IF_ERROR(create_file_reader(&reader));
+    DORIS_CHECK(reader != nullptr);
+    RETURN_IF_ERROR(reader->init(_runtime_state));

Review Comment:
   [P2] Keep split planning inside the lifecycle profile hierarchy
   
   `prepare_split()`'s `TableReader` timer has ended when this method runs, and 
the method opens neither the parent total nor `CreateReaderTime`; its init and 
the 0/many-child or build-error close paths also bypass the common `FileReader` 
lifecycle timers. Nested `OpenReaderTime`/Parquet `ParseFooterTime` can 
therefore contain the primary planning cost while their parents omit it, 
materially underreporting scans that use this feature. Use the existing 
TableReader/create/init/close scopes here, and cover 0/1/many plus error paths.



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