Skip to content

[branch-4.2] Backport external data and FileScannerV2 updates - #69722

Merged
yiguolei merged 4 commits into
apache:branch-4.2from
Gabriel39:dev/external-backports-4.2
Oct 30, 2026
Merged

yiguolei merged 4 commits into
apache:branch-4.2from
Gabriel39:dev/external-backports-4.2

Conversation

@Gabriel39

@Gabriel39 Gabriel39 commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Backport the requested external-data and FileScannerV2 changes to branch-4.2 in their actual master merge order:

Order Master PR Change Backport
1 #69545 Preserve Paimon schema options after field renames Included
2 #69551 Expand Iceberg capability, transaction and snapshot tests Included with 4.2 API adaptations
3 #69614 Elasticsearch HTTP scans in FileScannerV2 Already present through #69644 (2104b7509cda); not applied twice
4 #69612 Check catalog visibility before SHOW DATABASES accesses metadata Included
5 #69615 Publish Iceberg Parquet split offsets Included
6 #69650 Preserve ES compound residuals and expand scanner coverage Included
7 #69651 Accept Elasticsearch 9.x during node discovery Included
8 #69646 Prioritize Parquet V2 row groups using TopN bounds Included
9 #69668 Arrow loads and schema inference in FileScannerV2 Included

The eight outstanding changes are combined in one commit. This branch retains the 4.2 FE datasource APIs instead of importing master's connector-module refactor.

Backport adaptations

  • Port Paimon schema restoration, catalog-option provenance, fallback handling and tests to the existing table-copy/serialization lifecycle. Keep statement-bound fields when reader options are applied after a schema-only rename.
  • Exercise Iceberg's existing metadata and transaction entry points with real in-memory tables and retained-generation fixtures. Preserve the nine disabled known-bug reproductions; omit two connector-only lifecycle tests. Expiration checks verify live data-file sets and exact delete-file counters; 4.2's separate manifest-name/data-counter issue remains unchanged. The delete/history SQL suite checks visible rows and eager/late-materialization parity because 4.2 does not expose master's _file/_pos columns. The inventory labels upstream-only evidence explicitly.
  • Port ES residual tracking to the legacy planner and add compound OR/NOT, docvalue eligibility and Thrift-context tests there. Use Java 8-compatible HTTP APIs for opt-in ES 9 tests and the branch's supported node-address fixtures.
  • Keep the existing full-schema Iceberg metadata-table scan, which already supplies the file-size dependency for split offsets. Adapt the external write suite to verify offsets without requiring master-only distribution plans or golden output.
  • Use the existing Parquet statistics interface and physical row-location representation. Keep the TopN scheduling and pruning invariants.
  • Include the shared Arrow array normalizer required by the new reader, taken from the same master revision. Preserve 4.2 Lance/Avro dispatch; omit the schema-inference test for the unavailable Hive OpenCSV parser.

Validation

  • FE production and test sources compile with the branch's Java 8 target. Across the targeted runs and focused reruns, 20 test classes report 181 discovered, 171 passed, zero failures/errors, and 10 skipped: nine intentionally disabled known-bug reproductions plus the opt-in live ES 9 class.
  • FE Checkstyle: passed with zero violations.
  • Clang compiler syntax checks: all 23 affected C++ translation units passed against the current sources and freshly generated Thrift, using cached third-party/generated build dependencies. Focused BE runtime validation is listed below.
  • clang-format 16: all 30 affected C++ source/header files passed.
  • Groovy 4.0.19 syntax and AST conversion: all seven changed suites passed. All 105 local inventory links resolve.
  • Complete staged-diff self-review, whitespace/conflict checks, and sensitive-information checks passed.

A full BE rebuild and SQL/external-service regressions were not run locally. Live ES 9 tests require their opt-in endpoint. CI is requested for the combined backport.

Release note

Fix Paimon reads after field renames, external-catalog SHOW DATABASES authorization, and ES compound residual filtering. Support ES 9.x node discovery, publish Iceberg Parquet split offsets, improve Parquet V2 TopN row-group scheduling, and use FileScannerV2 for Arrow loads and text/JSON schema inference.

Check List (For Author)

  • Test
    • Unit Test
    • Regression test additions and syntax checks; SQL execution pending CI
  • Behavior changed:
    • Yes. Backport the changes listed above.
  • Does this need documentation?
    • No. Existing interfaces and settings are retained; the test coverage inventory is included.

Follow-up fixes

  • Set the Thrift enable_file_scanner_v2 default to true, matching the session default. Preserve explicit false for legacy query scans and extend the existing load-selection test.
  • Keep the selected Paimon snapshot and schema together during relation projection. Historical sequence/aggregation options must not be combined with the latest field names. Read-only principals can resolve historical selectors without INSERT permission.
  • Read legacy append schemas with missing or empty bucket keys without bucket pruning, preserving every historical file. The regression covers both unaware and multiple fixed buckets.

Follow-up validation: 169 targeted Paimon FE tests passed with zero failures/errors/skips. FE production compilation and Checkstyle passed. Both changed C++ test translation units passed compiler syntax checks and clang-format 16. Regenerated Java/C++ defaults are enabled; a Java 8-targeted protocol check verifies constructor/clear defaults, an omitted wire field, and an explicit-false round trip. Complete BE CI and live external SQL suites remain pending.

The two new reproductions first failed with the same missing-bucket-key and renamed-sequence-field errors as CI. A separate read-only-principal reproduction also failed before the permission correction. Complete external regression execution remains pending CI.

BE unit-test compatibility

  • Complete the native Arrow Variant input dependency for branch-4.2: accept binary storage and the Parquet Variant extension, validate metadata and payloads before appending, and retain owned data after Arrow buffers are released. Allow that ingestion path through the load reader while preserving query-format restrictions and source-default validation.
  • Preserve Variant V2 markers in the Arrow test fixtures, including nested types. Verify timestamp input against this branch's SerDe for positive, negative, and second-boundary values. Match the existing DATE range diagnostic in the TopN pruning test.
  • Add tests for sliced and empty reads, invalid ranges and carriers, malformed metadata/payloads, NULL children, atomic failure, buffer ownership, and the query capability boundary.

Validation: all 13 previously failing BE tests passed. The expanded run passed all 309 tests across nine suites, including Arrow/JSON loads, load validation, Iceberg, table mapping, and Variant input/output. The focused executable rebuilds the affected readers and SerDe against cached 4.2 build dependencies; this is not a complete BE rebuild. All seven changed C++ translation units passed compiler checks with current headers/generated Thrift, and all 33 affected C/C++ files passed clang-format 16. The complete staged diff, whitespace, and sensitive-information checks passed. Full CI is requested with run buildall and /review.

@Gabriel39
Gabriel39 requested a review from yiguolei as a code owner October 28, 2026 04:56
@hello-stephen

Copy link
Copy Markdown
Contributor

Thank you for your contribution to Apache Doris.
Don't know what should be done next? See How to process your PR.

Please clearly describe your PR:

  1. What problem was fixed (it's best to include specific error reporting information). How it was fixed.
  2. Which behaviors were modified. What was the previous behavior, what is it now, why was it modified, and what possible impacts might there be.
  3. What features were added. Why was this function added?
  4. Which code was refactored and why was this part of the code refactored?
  5. Which functions were optimized and what is the difference before and after the optimization?

@Gabriel39

Copy link
Copy Markdown
Contributor Author

run buildall

@Gabriel39

Copy link
Copy Markdown
Contributor Author

/review

@github-actions

Copy link
Copy Markdown
Contributor

Codex automated review failed and did not complete.

Error: workspace routing discovery unauthorized (401)
Workflow run: https://github.com/apache/doris/actions/runs/40635124750

Please inspect the workflow logs and rerun the review after the underlying issue is resolved.

@Gabriel39

Copy link
Copy Markdown
Contributor Author

/review

@github-actions

Copy link
Copy Markdown
Contributor

Codex automated review failed and did not complete.

Error: workspace routing discovery unauthorized (401)
Workflow run: https://github.com/apache/doris/actions/runs/40642737493

Please inspect the workflow logs and rerun the review after the underlying issue is resolved.

Gabriel39 added a commit to Gabriel39/incubator-doris that referenced this pull request Oct 28, 2026
Reader option resolution now merges catalog defaults, but four existing
PaimonExternalTable tests construct real-method mocks without initializing
their catalog. Construct table spies with an empty catalog and database so
the tests exercise the existing snapshot and projection assertions.

Related PR: apache#69722

Validation:
- Reproduced all four catalog-null errors locally before the fix.
- 87 tests passed across PaimonExternalTableTest, PaimonScanParamsTest,
  PaimonReaderOptionsTest and PaimonHistoricalSchemaOptionsTest.
- FE Checkstyle and git diff --check passed.
@Gabriel39

Copy link
Copy Markdown
Contributor Author

run buildall

@Gabriel39

Copy link
Copy Markdown
Contributor Author

/review

@github-actions

Copy link
Copy Markdown
Contributor

Codex automated review failed and did not complete.

Error: workspace routing discovery unauthorized (401)
Workflow run: https://github.com/apache/doris/actions/runs/40644735213

Please inspect the workflow logs and rerun the review after the underlying issue is resolved.

@hello-stephen

Copy link
Copy Markdown
Contributor

Cloud UT Coverage Report

Increment line coverage 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 76.75% (2004/2611)
Line Coverage 65.03% (36057/55450)
Region Coverage 52.73% (34404/65241)
Branch Coverage 55.80% (10739/19246)

@Gabriel39

Copy link
Copy Markdown
Contributor Author

run buildall

@Gabriel39

Copy link
Copy Markdown
Contributor Author

/review

@github-actions

Copy link
Copy Markdown
Contributor

Codex automated review failed and did not complete.

Error: This content was flagged for possible cybersecurity risk. If this seems wrong, try rephrasing your request. If you’re doing authorized security work that requires more cyber permissive safeguards, apply for Daybreak access via https://platform.openai.com/settings/organization/status-and-access before retrying.
Workflow run: https://github.com/apache/doris/actions/runs/40659513309

Please inspect the workflow logs and rerun the review after the underlying issue is resolved.

@hello-stephen

Copy link
Copy Markdown
Contributor

Cloud UT Coverage Report

Increment line coverage 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 76.75% (2004/2611)
Line Coverage 65.07% (36082/55450)
Region Coverage 52.95% (34545/65241)
Branch Coverage 55.83% (10746/19246)

@Gabriel39

Copy link
Copy Markdown
Contributor Author

run buildall

@Gabriel39

Copy link
Copy Markdown
Contributor Author

/review

@github-actions

Copy link
Copy Markdown
Contributor

Codex automated review failed and did not complete.

Error: Selected model is at capacity. Please try a different model.
Workflow run: https://github.com/apache/doris/actions/runs/40826835623

Please inspect the workflow logs and rerun the review after the underlying issue is resolved.

@hello-stephen

Copy link
Copy Markdown
Contributor

BE UT Coverage Report

Increment line coverage 76.61% (773/1009) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 64.65% (30202/46719)
Line Coverage 49.50% (319504/645415)
Region Coverage 45.32% (257711/568692)
Branch Coverage 46.96% (121690/259114)

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 77.40% (781/1009) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 76.31% (34625/45374)
Line Coverage 61.15% (391384/640036)
Region Coverage 58.04% (330612/569585)
Branch Coverage 58.95% (152577/258822)

Apply the outstanding changes in master merge order:
apache#69545 7d16729
apache#69551 7224a2d
apache#69612 61d1aef
apache#69615 8d2bd1e
apache#69650 3dc7341
apache#69651 c00ecb1
apache#69646 e493c61
apache#69668 7865646

apache#69614 already exists on branch-4.2 through apache#69644.
Adapt datasource APIs and tests to the release branch, retaining its
existing scanner dispatch and statement-bound metadata contracts.
Reader option resolution now merges catalog defaults, but four existing
PaimonExternalTable tests construct real-method mocks without initializing
their catalog. Construct table spies with an empty catalog and database so
the tests exercise the existing snapshot and projection assertions.

Related PR: apache#69722

Validation:
- Reproduced all four catalog-null errors locally before the fix.
- 87 tests passed across PaimonExternalTableTest, PaimonScanParamsTest,
  PaimonReaderOptionsTest and PaimonHistoricalSchemaOptionsTest.
- FE Checkstyle and git diff --check passed.
Keep the selected snapshot and schema together through relation projection,
including readers with SELECT permission only. Read all buckets for legacy
append schemas without explicit bucket keys instead of rejecting valid
historical metadata or pruning files using incomplete hash information.

Default FileScannerV2 to enabled in Thrift, matching the session default,
and retain explicit disabling for legacy query scans.
@Gabriel39
Gabriel39 force-pushed the dev/external-backports-4.2 branch from bc1836e to acfd04b Compare October 29, 2026 14:07
@Gabriel39

Copy link
Copy Markdown
Contributor Author

run buildall

@Gabriel39

Copy link
Copy Markdown
Contributor Author

/review

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Static review of PR #69722 at acfd04bc8cbf1c97ee0b87f810de46413700602c found two P2 defects: a valid NULL outer STRUCT containing native Variant can abort Arrow ingestion, and historical Paimon restoration can redirect a privilege-wrapped fallback branch to main and omit its rows. Both are reported inline. There were no existing inline threads or additional user-provided focus points.

All 81 changed paths were reviewed from the authoritative aggregate diff, with BE and FE complete reviews and an independent review of the suspicious mechanisms. Critical checkpoint conclusions:

  1. Goal and evidence: the backports implement the intended scanner/external-data changes, with the two inline exceptions; unit and regression assertions were inspected, not executed.
  2. Scope: the bundle is broad, but each mechanism and branch adaptation is related to its stated backport.
  3. Concurrency: Arrow state is scanner-local, IPC decompression stays on that thread, and TopN bounds use locked, monotonic snapshots. No new lock-order or shared-mutation defect was found.
  4. Lifecycle: IPC objects release before their memory pool; schema profiles outlive readers; Iceberg footer collection follows successful close. No new static-initialization dependency was found.
  5. Configuration: no new configuration item; the existing scanner option defaults to enabled and preserves explicit overrides for ordinary query scans. Load dispatch remains format based.
  6. Compatibility: optional split offsets tolerate old/empty fragments and are ignored for ORC; native/JNI and legacy scanner boundaries were traced.
  7. Shared definitions: complete touched Thrift definitions were compared on HEAD, master and branches 4.2/4.1/4.0/3.1. No new reused ID, conflicting meaning or required field was found; unrelated older collisions predate this PR.
  8. Parallel paths: load/query Arrow, Paimon native/JNI/system/fallback, ES v1/v2 and Parquet/ORC writer paths were checked. The privilege-wrapped fallback exception is inline.
  9. Conditions: row-ID and safe-conjunct ordering fences, unsupported statistics/type fallbacks, NULL-first handling and equality ties preserve TopN semantics. CSV/JSON schema probing preserves the legacy header, root/path and sampled-pipe behavior.
  10. Tests: positive and negative additions cover many conversion, ownership, protocol, snapshot and residual cases. The two reported paths need targeted regressions. The new multi-row-group/dictionary split-offset helper has no callers, so that intended coverage is inactive.
  11. Results: golden rows agree with explicit suite fixtures by static inspection; their generation and runtime correctness were not verified. Disabled known-bug tests remain skipped evidence.
  12. Observability: Arrow read/materialization timers and row accounting are present; TopN reuses pruning/read counters. No new excessive logging was found.
  13. Transactions and persistence: no EditLog, visible-version, MoW bitmap or failover protocol change. Iceberg manifest split metadata follows the existing commit path.
  14. Writes and atomicity: native Variant validates into owned temporary data before publishing values; destination defaults/filtering/error accounting remain in LoadTableReader. The ancestor-NULL defect is inline.
  15. FE/BE propagation: the split-offset producer, optional wire field, both FE builder paths and manifest consumer were traced; scanner defaults and explicit stream-load selection agree.
  16. Performance: scheduling adds per-file sorting to obtain earlier TopN bounds; IPC normalization is once per batch with tracked Arrow allocations. No runtime performance claim is made.
  17. Remaining concerns: candidate and risk dispositions are recorded in the shared ledger; no unresolved source-review question or unread changed path remains after the final review round.

Validation limits: this was static-only. No builds, tests, benchmarks, external-service runs, source edits or submodule initialization were performed. ES9 live behavior, the external writer/backend matrix, concurrency stress, golden generation and the inactive split-offset test matrix remain runtime/coverage limits. The design document's older statement that Arrow loads stay on V1 is stale relative to this change; actual code governed the review.

Review converged after 3 round(s).

_file_slots[id.value()]->type()));
// Bind differing numeric widths before concrete SerDe array casts. Timestamp units
// stay on the wire even inside containers, so Doris retains its own rounding semantics.
if (!array->type()->Equals(binding)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Propagate ancestor NULLs even when the binding type is unchanged

For an IPC column matching STRUCT<payload: VARIANT>, Arrow StructBuilder::AppendNull() produces a NULL outer struct with a valid hidden child carrier containing empty metadata/value bytes. This branch skips masking because the types match, but DataTypeStructSerDe still reads every child and the new Variant SerDe rejects the hidden empty metadata, aborting a valid load instead of loading SQL NULL. Propagate ancestor validity before SerDe decoding independently of the cast decision, and cover a NULL outer STRUCT<VARIANT> with unchanged wire types.

// Chain groups have their own option filtering and are not ordinary fallback readers.
return table.copy(dynamicOptions);
}
if (table instanceof FallbackReadFileStoreTable) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Handle fallback pairs hidden by privilege wrappers

A privilege-enabled catalog can return PrivilegedFileStoreTable(FallbackReadFileStoreTable), so this check misses a real handle. For a SELECT+INSERT principal reading a main snapshot older than its current schema, restoreHistoricalSchema calls table.copy(TableSchema), broadcasting the main schema/options to both branches. Normal main options omit branch; the SDK only restores the other branch when that key is present, so the fallback table now defaults to main too. The later copy(Map) does not repair it: a partition present only in the backup branch disappears from the historical query. Traverse the privilege delegate while preserving authorization and restore each fallback branch independently.

@hello-stephen

Copy link
Copy Markdown
Contributor

Cloud UT Coverage Report

Increment line coverage 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 76.75% (2004/2611)
Line Coverage 65.02% (36070/55473)
Region Coverage 52.85% (34489/65260)
Branch Coverage 55.82% (10750/19258)

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 61.31% (84/137) 🎉
Increment coverage report
Complete coverage report

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 77.40% (781/1009) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 76.26% (34617/45391)
Line Coverage 61.08% (391063/640228)
Region Coverage 57.91% (329937/569727)
Branch Coverage 58.84% (152335/258905)

@yiguolei
yiguolei merged commit 68943c4 into apache:branch-4.2 Oct 30, 2026
30 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants