You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Development branch:branch-catalog-spi — all migration PRs target this branch; it merges to master through #64304.
Background
Today Apache Doris FE hard-codes every external data source (hive, iceberg, paimon,
hudi, trino-connector, maxcompute, jdbc, es, …) inside fe/fe-core/.../datasource/,
wired into the catalog and planner layers through switch-case and instanceof *ExternalTable checks. Adding or changing a connector means touching FE
core.
This tracking issue covers the effort to decouple each concrete connector into an
independent, loadable plugin module under fe/fe-connector/*, leaving only generic
infrastructure and a stable catalog SPI bridge in fe-core.
End state: each connector ships as a self-contained plugin zip; fe-core has no
compile-time knowledge of any specific connector; the runtime discovers and loads
connectors through the catalog SPI (PluginDrivenExternalCatalog / …Table / …ScanNode).
In scope: FE-side connector code under datasource/{hive,iceberg,paimon,hudi,trinoconnector,maxcompute,jdbc,es,…}, plus the
reverse couplings (instanceof *ExternalTable, connector-specific sinks / scan-nodes)
scattered across nereids / planner / tablefunction / alter.
Out of scope: BE-side readers; fe-fs-spi file-system plugin work (separate
workstream); extension-spi; kafka / kinesis / odbc / Doris-to-Doris federation
(tracked separately). RemoteDoris stays an engine built-in catalog type; the
deprecated lakesoul type was removed rather than migrated (#65736).
Where the framework is documented
Prose docs now live in the tree and are the authoritative reference (they replaced the
branch's plan-doc/ corpus in #66251):
fe/fe-connector/README.md — architecture, module map, how a connector runs
(startup / CREATE CATALOG routing / per-statement metadata / classloading /
packaging), how to read the API, and a step-by-step "adding a new connector" guide.
fe/fe-connector/AGENTS.md — build & test recipes, the machine-checked obligations,
and the invariants that no gate can express.
Design invariants (acceptance criteria)
These invariants must hold at every step:
One-way dependencyfe-connector → fe-core. No connector module may import org.apache.doris.{catalog,common,datasource,qe,analysis,nereids,planner}.
Enforced in the validate phase by build-support/check-fe-connector-imports.sh
(self-test under build-support/tests/).
No user-visible behavior regression. SHOW CREATE CATALOG, SHOW TABLE STATUS, information_schema.tables, EXPLAIN output, error messages, and catalog type / engine names are all preserved.
Progress — phases
Each phase lands as one or more PRs against branch-catalog-spi.
P8 — cleanup(mostly done) — the SPI_READY_TYPES allowlist is gone, and so
are the reverse instanceof *ExternalTable sites (only javadoc references remain).
Still open: the legacy TableType.*_EXTERNAL_TABLE enum values. Plugin-driven
tables now report PLUGIN_EXTERNAL_TABLE; the old constants survive in persisted
metadata and in a few SHOW PARTITIONS / partition-TVF allowlists.
Supporting refactor & post-migration hardening (landed alongside / after the phases above):
Shared modules added for them (see the README's module map): fe-connector-metastore-api
/ -spi / -hms / -iceberg / -paimon (so a connector never hand-parses metastore
endpoint properties), fe-connector-cache, fe-connector-hms-hive-shade, fe-connector-paimon-hive-shade, plus fe-kerberos and fe-trino-connector-common
outside this directory.
External catalogs are served by connector plugins, shipped as zips under fe/plugins/connector/ (Config.connector_plugin_root). Existing catalogs keep
working across upgrade; no DDL change is required.
trino_connector_plugin_dir default moves from plugins/connectors to plugins/trino_plugins; the old directory is still read as a fallback.
The deprecated lakesoul catalog type is removed — creating or replaying one fails
with Lakesoul catalog is no longer supported.
Development branch:
branch-catalog-spi— all migration PRs target this branch; it merges tomasterthrough #64304.Background
Today Apache Doris FE hard-codes every external data source (hive, iceberg, paimon,
hudi, trino-connector, maxcompute, jdbc, es, …) inside
fe/fe-core/.../datasource/,wired into the catalog and planner layers through
switch-caseandinstanceof *ExternalTablechecks. Adding or changing a connector means touching FEcore.
This tracking issue covers the effort to decouple each concrete connector into an
independent, loadable plugin module under
fe/fe-connector/*, leaving only genericinfrastructure and a stable catalog SPI bridge in
fe-core.End state: each connector ships as a self-contained plugin zip;
fe-corehas nocompile-time knowledge of any specific connector; the runtime discovers and loads
connectors through the catalog SPI (
PluginDrivenExternalCatalog/…Table/…ScanNode).In scope: FE-side connector code under
datasource/{hive,iceberg,paimon,hudi,trinoconnector,maxcompute,jdbc,es,…}, plus thereverse couplings (
instanceof *ExternalTable, connector-specific sinks / scan-nodes)scattered across nereids / planner / tablefunction / alter.
Out of scope: BE-side readers;
fe-fs-spifile-system plugin work (separateworkstream);
extension-spi;kafka/kinesis/odbc/ Doris-to-Doris federation(tracked separately).
RemoteDorisstays an engine built-in catalog type; thedeprecated
lakesoultype was removed rather than migrated (#65736).Where the framework is documented
Prose docs now live in the tree and are the authoritative reference (they replaced the
branch's
plan-doc/corpus in #66251):fe/fe-connector/README.md— architecture, module map, how a connector runs(startup / CREATE CATALOG routing / per-statement metadata / classloading /
packaging), how to read the API, and a step-by-step "adding a new connector" guide.
fe/fe-connector/AGENTS.md— build & test recipes, the machine-checked obligations,and the invariants that no gate can express.
Design invariants (acceptance criteria)
These invariants must hold at every step:
fe-connector → fe-core. No connector module mayimport org.apache.doris.{catalog,common,datasource,qe,analysis,nereids,planner}.Enforced in the
validatephase bybuild-support/check-fe-connector-imports.sh(self-test under
build-support/tests/).fe-core, onlyPluginDrivenMetadatamaycall
Connector#getMetadata; exempt call sites carry an explicit marker anddeleting a marker auto-tightens the gate. Enforced by
build-support/check-fe-core-metadata-funnel.sh([perf](catalog) fe-connector-iceberg hot-path caching + fe-core per-statement metadata funnel, with session=user cache isolation #65785).IcebergExternalCatalog/PaimonExternalDatabasemust deserialize and migratetransparently to
PluginDrivenExternalCatalog. Verified by a unit-test suite whosefixtures are generated from real 4.1.3 bytecode ([test](catalog) verify 4.1.3 catalogs survive the connector-SPI cutover, with fixtures generated by real 4.1.3 bytecode #66214).
SHOW CREATE CATALOG,SHOW TABLE STATUS,information_schema.tables,EXPLAINoutput, error messages, and catalogtype/enginenames are all preserved.Progress — phases
Each phase lands as one or more PRs against
branch-catalog-spi.snapshot, vended credentials, sys-tables, statistics, write-config) + connector
import-gate CI. ([feat](connector) P0 SPI baseline + DDL/Partition + import gate (T03-T27) #63582)
translator; remove duplicated fe-core code. ([P1-T03-T05] route plugin-driven scans first in nereids translator #63641)
reusable migration playbook. ([feat](connector) P2 migrate trino-connector to catalog SPI (T01-T13) #64096)
design; live cutover deferred to P7 (hudi is parasitic on HMS metadata) and
landed there. ([feat](connector) P3 hudi connector hardening + test baseline + dispatch design (hybrid, T02-T08) #64143)
now odps-free). ([feat](connector) P4 maxcompute connector full adoption + live cutover via catalog SPI (T01-T06) #64253, [refactor](connector) P4 maxcompute: remove legacy subsystem from fe-core + make fe-core odps-free (T07-T09) #64256)
paimon-SDK-free). ([refactor](catalog) P5 paimon: migrate to catalog SPI + cutover (#64446) #64446, [refactor](catalog) P5 paimon: remove legacy subsystem from fe-core + make fe-core paimon-SDK-free (T29) #64653)
vended credentials + write path + procedures + sys-tables + views, then routing
cutover. ([refactor](catalog) P6 iceberg: migrate to catalog SPI + cutover + remove legacy fe-core subsystem #64688)
transaction write path; absorbs the hudi live cutover. ([refactor](catalog) Catalog spi 11 hive #65473)
SPI_READY_TYPESallowlist is gone, and soare the reverse
instanceof *ExternalTablesites (only javadoc references remain).Still open: the legacy
TableType.*_EXTERNAL_TABLEenum values. Plugin-driventables now report
PLUGIN_EXTERNAL_TABLE; the old constants survive in persistedmetadata and in a few
SHOW PARTITIONS/ partition-TVF allowlists.Supporting refactor & post-migration hardening (landed alongside / after the phases above):
fe-kerberos. ([refactor](catalog) P3b: consolidate kerberos authentication into fe-kerberos #64655)hive-catalog-shadewith a slim,plugin-private HMS metastore-client shade (~122 MB → ~15 MB per plugin). ([refactor](catalog) fe-connector: replace fat hive-catalog-shade with a slim HMS metastore-client shade #65721)
the dead Trino-ported directory-listing cache ([refactor](catalog) fe-core: remove dead Trino-ported DirectoryListercache cluster #65734); the dead
ExternalMetadataOpslayer, deprecated LakeSoul catalog, and odbc/statisticsstubs ([refactor](catalog) fe-core: remove dead ExternalMetadataOps layer, deprecated LakeSoul catalog, and odbc/statistics stubs #65736); and 6 dead
datasourceclasses ([refactor](catalog) fe-core: remove 6 dead datasource classes orphaned by the SPI migration #65740).caching the SPI cutover dropped, held to behavior parity, with
session=usercache isolation: iceberg hot-path caching + a per-statement
ConnectorMetadatafunnel ([perf](catalog) fe-connector-iceberg hot-path caching + fe-core per-statement metadata funnel, with session=user cache isolation #65785).
fe-core
SortedPartitionRangesreuse (Cache B). ([perf](catalog) two-level cross-query cache for external partition derived views #65829)dependencies and dead code, delegate DDL validation to connectors, drop the
hudi_metaTVF. ([refactor](catalog) fe-core: strip residual iceberg/hive/hudi deps & dead code, delegate DDL validation to connectors, remove hudi_meta TVF #65893)fidelity, SPI convergence, dead-code cleanup. ([fix](catalog) catalog-SPI abstraction-mismatch review: paimon time-travel crash, partition/schema fidelity, SPI convergence & dead-code cleanup #65970)
hot-path memoization, iceberg case-insensitive column DDL fix. ([opt](catalog) fe-connector: unify the connector cache foundation, memoize per-statement hot paths, fix iceberg case-insensitive column DDL #66029)
editing a common module; dead SPI surface deleted; 11 correctness fixes. ([refactor](catalog) connector public interface cleanup: no common-module edit to add a connector, dead-surface deletion, 11 correctness fixes #66135)
dead storage / AWS-credential surface. ([refactor](catalog) fe-core: delete the unreachable metastore property cluster and the dead storage/AWS-credential surface #66210)
apiVersion()with amanifest-carried API version gate, for all four plugin families. ([feature](plugin) replace the always-true connector apiVersion() with a manifest-carried API version gate for all four plugin families #66211)
the cutover, with fixtures generated by real 4.1.3 bytecode. ([test](catalog) verify 4.1.3 catalogs survive the connector-SPI cutover, with fixtures generated by real 4.1.3 bytecode #66214)
fe/fe-connector/README.mdandAGENTS.mdreplace the branch'splan-doc/corpus; both gates move tobuild-support/with self-tests. ([refactor](catalog) delete unused file plan-doc and add AGENTS.md #66251)fe-trino-connector-commonextracted sofe-commonno longer depends onTrino.
$position_deletessystem table served through the SPI.capability-gated credential injection (port of upstream [feature](fe) Support OIDC session credentials for Iceberg REST catalog #63068).
Connector status
fe-connector-jdbcfe-connector-esfe-connector-trinofe-connector-maxcomputefe-connector-paimonfe-connector-hudife-connector-icebergfe-connector-hive/fe-connector-hmsShared modules added for them (see the README's module map):
fe-connector-metastore-api/
-spi/-hms/-iceberg/-paimon(so a connector never hand-parses metastoreendpoint properties),
fe-connector-cache,fe-connector-hms-hive-shade,fe-connector-paimon-hive-shade, plusfe-kerberosandfe-trino-connector-commonoutside this directory.
Upstream re-ports
The branch is rebased onto
mastercontinuously, and every upstream change to analready-migrated datasource is re-ported onto the SPI rather than merged textually
(a textual merge would silently resurrect fe-core-side code paths that no longer run).
Re-ported so far: #63068, #64966, #65094, #65262, #65329, #65332, #65365, #65548,
#65676, #65782, #65784, #65834, #65870, #65904, #65955, #65984, #65991, #66004, #66008,
#66112.
User-visible changes at merge time
fe/plugins/connector/(Config.connector_plugin_root). Existing catalogs keepworking across upgrade; no DDL change is required.
trino_connector_plugin_dirdefault moves fromplugins/connectorstoplugins/trino_plugins; the old directory is still read as a fallback.lakesoulcatalog type is removed — creating or replaying one failswith
Lakesoul catalog is no longer supported.Remaining before #64304 can merge
TableType.*_EXTERNAL_TABLEenum values.connector_plugin_root, thetrino_connector_plugin_dirdefault, and thelakesoulremoval.external_table_p0/external_table_p2).This is an umbrella tracking issue; individual PRs reference it for detailed
per-phase design and review.