Skip to content

[fix](fe) Allow table access through Iceberg JDBC V0 catalogs (branch-4.1) - #69486

Merged
yiguolei merged 2 commits into
apache:branch-4.1from
Gabriel39:fix/iceberg-jdbc-v0-branch-4.1
Oct 23, 2026
Merged

yiguolei merged 2 commits into
apache:branch-4.1from
Gabriel39:fix/iceberg-jdbc-v0-branch-4.1

Conversation

@Gabriel39

@Gabriel39 Gabriel39 commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Issue Number: N/A

Related PR: #69452

Problem Summary:

Backport #69452 to branch-4.1. Iceberg's JDBC catalog implements ViewCatalog even when its V0 metadata schema cannot store views. Treat unsupported JDBC view probes as no views so ordinary table listing and reads work without requiring a V1 migration. Preserve V1 view support, REST view routing, explicit view-operation errors, and real SQL/authorization failures.

Preserve the requested DROP kind and lifetime before invoking the legacy metadata API, which accepts none of these flags and can purge an ordinary table. Reject DROP VIEW and DROP MATERIALIZED VIEW on a table, including IF EXISTS. An external permanent table cannot satisfy DROP TEMPORARY TABLE: return without mutation for IF EXISTS, otherwise report an unknown table. Reject DROP TABLE on a view while preserving matching table/view drops and missing-object IF EXISTS behavior.

Add eight drop-dispatch tests using the actual JDBC V0 view guards and a recording writable catalog. Assert that rejected/no-op statements preserve table state and rows without purge or delete journaling. Extend the PostgreSQL V0 regression with all six wrong-kind SQL forms and check table listing and data after every statement.

Release note

Fix table access through Iceberg JDBC V0 catalogs. Prevent wrong-kind external DROP statements from deleting existing table data.

Check List (For Author)

  • Test
    • Unit Test: 27 targeted tests passed, zero failures/errors/skips. Includes eight new drop-kind tests, six JDBC view-probe tests, and existing metadata-operation tests. Before the fix, five drop-kind tests reproduced the unsafe mutation behavior on each branch.
    • FE Checkstyle: zero violations.
    • Regression test: SELECT-only V0 scenarios and six writable V0 wrong-kind DROP checks added; release-branch end-to-end SQL execution not performed locally. Regression Groovy syntax checked.
  • Behavior changed:
    • Yes. V0 view probes no longer block table access; mismatched DROP statements cannot reach destructive table operations.
  • Does this need documentation?
    • No.

Check List (For Reviewer who merge this PR)

  • Confirm the release note
  • Confirm test cases
  • Confirm document
  • Add branch pick label

…-4.1)

### What problem does this PR solve?

Issue Number: N/A

Related PR: apache#69452

Problem Summary:

Backport apache#69452 to branch-4.1. Iceberg's JDBC catalog implements `ViewCatalog` even when its V0 metadata schema does not support views. Unsupported view probes must not prevent ordinary table listing or reads.

Adapt the fix to the release branch's legacy `IcebergMetadataOps` implementation. Return no views only for unsupported JDBC view probes, preserving V1 view support, REST view routing, explicit view-operation failures, and real SQL/authorization errors.

Port the six unit-test scenarios to the legacy metadata API and retain the original PostgreSQL V0 SELECT-only regression setup and read/time-travel checks.

### Release note

Fix table discovery and access through Iceberg JDBC catalogs using the V0 metadata schema without view support.

### Check List (For Author)

- Test
    - [x] Unit Test: 19 tests passed (six new JDBC probe tests and the existing metadata-operation tests), zero failures/errors/skips. FE Checkstyle passed. Before the fix, both V0 tests reproduced the actual SDK unsupported-view exception.
    - [ ] Regression test: V0 scenarios ported unchanged from apache#69452; release-branch end-to-end execution is left to CI.
- Behavior changed:
    - [x] Yes. Unsupported JDBC view probes no longer block ordinary table operations.
- Does this need documentation?
    - [x] No.

### Check List (For Reviewer who merge this PR)

- [ ] Confirm the release note
- [ ] Confirm test cases
- [ ] Confirm document
- [ ] Add branch pick label

Adapted to the legacy metadata implementation.

(cherry picked from commit 57e41e9)
@Gabriel39
Gabriel39 requested a review from yiguolei as a code owner October 22, 2026 23:28
@Gabriel39

Copy link
Copy Markdown
Contributor Author

run buildall

@Gabriel39

Copy link
Copy Markdown
Contributor Author

/review

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

@github-actions

Copy link
Copy Markdown
Contributor

Codex automated review failed and did not complete.

Error: Review context preparation failed before Codex ran; inspect the 'Prepare authoritative PR context and required AGENTS guides' step.
Workflow run: https://github.com/apache/doris/actions/runs/39871999195

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

### What problem does this PR solve?

Issue Number: N/A

Related PR: apache#69485, apache#69486

ExternalCatalog discarded the requested view, MTMV and temporary-table flags before calling the legacy metadata API. Once JDBC V0 view probing returns false, a wrong-kind DROP could purge an ordinary permanent table. Validate kind and lifetime before dispatch, preserve valid drops, and avoid mutation/journaling for rejected or no-op requests.

### Release note

Prevent wrong-kind external DROP statements from deleting table data.

### Check List (For Author)

- Test: 27 targeted unit tests passed; five new tests failed before the fix. FE Checkstyle passed. Negative SQL regression added and Groovy syntax checked; release-branch end-to-end SQL not run locally.
- Behavior changed: Yes. Reject mismatched DROP types and protect permanent tables from temporary drops.
- Does this need documentation: No.
Gabriel39 added a commit to Gabriel39/incubator-doris that referenced this pull request Oct 23, 2026
### What problem does this PR solve?

Issue Number: N/A

Related PR: apache#69485, apache#69486

ExternalCatalog discarded the requested view, MTMV and temporary-table flags before calling the legacy metadata API. Once JDBC V0 view probing returns false, a wrong-kind DROP could purge an ordinary permanent table. Validate kind and lifetime before dispatch, preserve valid drops, and avoid mutation/journaling for rejected or no-op requests.

### Release note

Prevent wrong-kind external DROP statements from deleting table data.

### Check List (For Author)

- Test: 29 targeted unit tests passed; five new tests failed before the fix. FE Checkstyle passed. Negative SQL regression added and Groovy syntax checked; release-branch end-to-end SQL not run locally.
- Behavior changed: Yes. Reject mismatched DROP types and protect permanent tables from temporary drops.
- Does this need documentation: No.
@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 #69486 at cd815f7. Three P2 regressions are reported inline: matching HMS drops now depend on scan-format support, failed Iceberg kind initialization can block a matching DROP VIEW retry, and stale HMS name caches can turn remote-missing IF EXISTS drops into errors. No existing inline findings or additional user focus were supplied.

The JDBC V0 fallback itself is consistent with the pinned SDK: unsupported view probes become empty/false, while V1 probes, REST view gating, explicit view operations, and SQL/authorization errors retain their paths. Checked against Iceberg 1.11.0 JdbcCatalog.

Critical checkpoints:

  1. Goal and evidence: V0 table access and wrong-kind DROP protection are covered by the new unit/regression assertions; the three object-classification regressions need correction. Tests were inspected, not executed.
  2. Scope and clarity: production changes are small and focused, but placing the kind check in ExternalCatalog affects all writable connectors, including HMS.
  3. Concurrency and locks: DDL/query workers may overlap refresh and external clients. Existing table initialization monitors and Iceberg catalog-generation guards remain; the helper adds no shared state, threads, locks, or new lock order. Remote name replacement is an existing non-atomic boundary.
  4. Lifecycle: cached table shells outlive failed commands. The new guard exposes Iceberg's early objectCreated publication, as detailed inline. No new ownership cycle or static-initialization dependency was introduced.
  5. Configuration: no configuration items are added. The regression uses existing JDBC schema-version and initialization properties, correctly normalized to SDK keys.
  6. Compatibility: no storage, image, journal, protocol, or public signature changes. V0 access does not require a V1 migration; existing V1 paths remain enabled.
  7. Thrift/protobuf: no definitions changed; release-branch field/enum comparisons are inapplicable.
  8. Parallel paths: reviewed HMS, Iceberg, Paimon and MaxCompute writable dispatch, InternalCatalog semantics, both view probes, REST-enabled/disabled paths, explicit view operations, case-fold collision checks and forced database drops. No additional new defect was substantiated.
  9. Conditions: TEMPORARY and MTMV checks run before mutation; IF EXISTS does not suppress an existing-object kind mismatch. Parser/Env flags and ErrorCode arguments match the intended SQL forms.
  10. Coverage: unit tests exercise real V0 SDK guards, synthetic positive view support, error propagation, matching/wrong-kind drops and mutation/journal boundaries. The PostgreSQL V0 regression checks read-only discovery, reads, snapshots, refresh and all six wrong-kind forms. Mocked isView and null-shell absence tests miss the real classification and stale-name cases reported inline; real JDBC V1 view end-to-end coverage is not added.
  11. Results: no .out files changed. New row comparisons use ORDER BY; aggregate counts and the single initial snapshot are deterministic. No incorrect new expected value was found statically.
  12. Observability: kind errors identify database/table and requested kind. Existing SDK causes and successful-drop logs remain sufficient for these branches; no new metric is needed.
  13. Persistence and failover: the new validation rejections and early returns stop before remote mutation and journaling. Existing connector-level IF EXISTS no-ops still run cache retirement and journal hooks. Successful drops retain connector mutation, cache retirement and DropInfo logging/replay. No persisted field changes; the remote-mutation/journal crash interval predates this PR.
  14. Writes, atomicity and crashes: the guards add validation before existing destructive APIs. No new transaction protocol is introduced. Existing remote replacement/crash windows remain; no new leak or deadlock was established.
  15. FE/BE propagation: no new FE-to-BE variable or send path.
  16. Performance and memory: the helper has call-local state and bounded overhead; V0 rejects probes before SQL. Cold kind checks can add a metadata lookup. No new unbounded allocation or BE MemTracker concern; HMS scan-format initialization is unnecessary for DDL and causes the first finding.
  17. Additional concerns and limits: all five changed files and their relevant callers/consumers were reviewed, including a separate SDK/routing risk pass. There is no additional user-provided focus. This is static-only validation: no builds, test execution, source changes, or submodule initialization. Runtime pass rates, fixture reruns and real V1 view end-to-end behavior remain unverified.

Review converged after 3 round(s).

ErrorReport.reportDdlException(ErrorCode.ERR_WRONG_OBJECT, dbName, tableName, "MTMV",
"External catalogs do not support materialized views");
}
boolean actualIsView = dorisTable.isView();

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] Check HMS object kind without validating its scan format

For a nontransactional Hive table stored as Avro (also RCFile or SequenceFile), a matching DROP TABLE hms.db.t now fails here: HMSExternalTable.isView() calls makeSureInitialized(), which calls supportedHiveTable() and throws Unsupported hive input format before reaching the drop API. Previously getTableNullable() only constructed the shell, and HiveMetadataOps.dropTableImpl() checked existence/transactional status without requiring a readable format. Thus this shared guard removes a working metadata operation for tables Doris cannot scan. Resolve the kind from raw metastore metadata without scan-format validation, and cover this with a real HMS table rather than a mocked isView().

"External catalogs do not support materialized views");
}
boolean actualIsView = dorisTable.isView();
if (isView != actualIsView) {

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] Keep failed Iceberg kind probes retryable

For an existing V1 view with a cold IcebergExternalTable shell, let the first DROP VIEW encounter a transient SQL or metadata-read error in viewExists. IcebergExternalTable.makeSureInitialized() sets objectCreated = true before assigning isView, so the failure leaves the cached shell initialized with isView = false. No drop hook invalidates it. After the backend recovers, retrying the matching DROP VIEW now hits this mismatch and reports is not VIEW until refresh or cache expiry. Before this change, dropTableImpl() probed the remote kind afresh and the retry could succeed. Publish kind initialization only after a successful probe, or obtain reliable fresh classification here; add a failure-then-retry test using the real shell.

ErrorReport.reportDdlException(ErrorCode.ERR_WRONG_OBJECT, dbName, tableName, "MTMV",
"External catalogs do not support materialized views");
}
boolean actualIsView = dorisTable.isView();

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] Preserve IF EXISTS for stale HMS table names

Populate Doris' HMS table-name cache (for example with SHOW TABLES), delete t directly in Hive, then run DROP TABLE IF EXISTS hms.db.t before the name cache refreshes. getTableNullable() can still construct a cold shell from the cached name, so the null check above does not handle this case. The new HMSExternalTable.isView() call loads the now-missing table and throws HMSClientException before HiveMetadataOps.dropTableImpl() can perform its existing tableExists == false && ifExists no-op. This previously successful idempotent drop now fails. Preserve remote-missing IF EXISTS semantics during kind resolution, and test a stale name with a real HMS shell rather than only mocking a null lookup.

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 0.00% (0/19) 🎉
Increment coverage report
Complete coverage report

1 similar comment
@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 0.00% (0/19) 🎉
Increment coverage report
Complete coverage report

@yiguolei
yiguolei merged commit c88daa8 into apache:branch-4.1 Oct 23, 2026
36 of 37 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

PR approved by anyone and no changes requested.

@github-actions github-actions Bot added the approved Indicates a PR has been approved by one committer. label Oct 23, 2026
@github-actions

Copy link
Copy Markdown
Contributor

PR approved by at least one committer and no changes requested.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by one committer. reviewed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants