[feature](fe) Add constraint-based colocate join inference with distribution mappings - #66307
[feature](fe) Add constraint-based colocate join inference with distribution mappings#66307nooneuse wants to merge 56 commits into
Conversation
|
Thank you for your contribution to Apache Doris. Please clearly describe your PR:
|
|
run buildall |
TPC-H: Total hot run time: 29764 ms |
TPC-DS: Total hot run time: 178166 ms |
ClickBench: Total hot run time: 24.91 s |
FE Regression Coverage ReportIncrement line coverage |
|
run buildall |
TPC-H: Total hot run time: 30059 ms |
TPC-DS: Total hot run time: 178121 ms |
ClickBench: Total hot run time: 24.8 s |
FE Regression Coverage ReportIncrement line coverage |
|
run buildall |
TPC-H: Total hot run time: 28512 ms |
TPC-DS: Total hot run time: 169891 ms |
FE Regression Coverage ReportIncrement line coverage |
|
run buildall |
TPC-H: Total hot run time: 29137 ms |
FE UT Coverage ReportIncrement line coverage |
TPC-H: Total hot run time: 28673 ms |
TPC-DS: Total hot run time: 169918 ms |
TPC-H: Total hot run time: 16834 ms |
TPC-DS: Total hot run time: 81542 ms |
ClickBench: Total hot run time: 14.61 s |
FE Regression Coverage ReportIncrement line coverage |
|
run buildall |
|
/review |
There was a problem hiding this comment.
Review completed in 2 rounds. All required full-coverage and risk-focused passes returned NO_NEW_VALUABLE_FINDINGS. After independent verification and deduplication against the existing review context, no new actionable inline finding remains; this is a summary-only review, and the review is complete rather than capped.
Critical checkpoint conclusions
- Goal and proof: The PR adds an opt-in
COLOCATE MAPPINGconstraint and lets Nereids prove colocate joins from declared determinant-to-distribution-key mappings. The command, persistence, scan-property, aggregate/project propagation, and final join-proof paths implement that goal, with focused unit and regression coverage. - Scope and clarity: Although the feature necessarily spans metadata, persistence, parser, planner properties, and tests, the changes stay within the FE-side constraint/planning contract and reuse the existing BE colocate-join execution path.
- Concurrency: Mapping ADD/DROP uses database-read -> table-write ->
ConstraintManagerlocking, revalidates the concrete table while locked, submits the immutable journal payload with protected metadata, and performsawait()after releasing metadata locks. The reviewed lock order is consistent and no deadlock or unjournaled publication path survived the lifecycle review. - Lifecycle and static state: Mappings are owned by the concrete
OlapTable.TableAttributes, so rename, recycle/recover, truncate, replace, copy, backup, and restore behavior follows physical table ownership. Restore and planning revalidate schema bindings. No new cross-TU/static-initialization or circular-lifetime issue applies to this Java-only change. - Configuration:
enable_colocate_mapping_constraintis a dynamic, plan-affecting experimental session variable and is disabled by default. Enabled and disabled planner behavior is covered; no process restart or FE-BE propagation is required. - Compatibility: Image metadata uses an optional concrete field, and ADD/DROP reuse a backward-readable
OP_MODIFY_TABLE_PROPERTIESenvelope. Supported mixed/unknown-version operation fails explicitly through the exact-build gate; the documented downgrade and membership restrictions are consistent with older FEs ignoring the optional metadata. The challenged same-host heartbeat scenario requires an FE topology that cannot bootstrap/heartbeat with the cluster-global RPC/HTTP port contract, so it was dismissed rather than reported. - Parallel paths: ADD, DROP, SHOW, replay, image load, backup/restore, schema change, HASH-to-RANDOM conversion, rename, replace, truncate, recycle/recover, selected rollups, and mapping-enabled scan planning were compared. No distinct omitted parallel path remained after deduplication.
- Special checks: Internal non-temporary OLAP ownership, Hash distribution, ordered target-key subsets, stable column identity/schema-version fallback, selected-index provenance, stable colocate group, table/index/partition identity, determinant order, target positions, and join equalities are all rechecked at the appropriate boundaries. Unsupported or redistributed property shapes fail closed.
- Test coverage: The added FE tests cover parser/command validation, constraint locking and binding, persistence/replay, restore rejection, schema and lifecycle behavior, scan provenance, property derivation/regulation/enforcement, aggregate/project propagation, join variants, composite/direct mappings, selected rollups, set operations, and the session gate. The full regression suite and expected output were reviewed, including ordered results and negative cases; no additional supported failure case survived the second pass.
- Test results: This review runner was explicitly restricted from builds and test execution, so no tests were rerun. The committed unit/regression code and expected result file were reviewed statically and are internally consistent with the changed behavior.
- Observability: User-visible failures name the incompatible frontend or mapping/table condition, and metadata mutation/replay paths have appropriate logging. No new critical runtime metric is required for this disabled-by-default planner optimization.
- Persistence and failover: Table attributes, edit-log submission, replay locking, backup copies, and restore validation cover the new metadata. New-FE replay/checkpoint preserves mappings, while supported mixed-version use is rejected before consumption; no distinct supported failover gap survived review.
- Data writes and atomicity: The feature does not alter DML, transactions, load, compaction, or BE data writes. The constraint is explicitly
NOT ENFORCED, so Doris trusts the declared business invariant; metadata mutations remain atomic with their journal submission. - FE-BE variables/protocol: No new FE-BE field, thrift payload, constant-folding path, or point-query variable is introduced. Execution continues through the existing colocate hash-join path.
- Performance: The optimization is disabled by default, does not insert an enforceable Exchange, and disables SQL-result caching only after a usable mapping proof is constructed. No new distinct CPU/memory or asymptotic issue survived; previously raised comparison-scale concerns were not duplicated.
- Other issues: The conservative schema-version invalidation for legacy columns is an explicit fail-closed contract, and the atomic-restore name-collision variant is covered by existing atomic-restore constraint-transition threads. No additional actionable issue remains.
FE UT Coverage ReportIncrement line coverage |
|
run buildall |
|
/review |
There was a problem hiding this comment.
Review status: complete after three review rounds; every candidate is accepted, duplicate-fenced, or dismissed with concrete evidence.
Requesting changes for three blocking correctness issues:
- Hidden mapping locality can survive runtime boundaries that no longer preserve or truthfully report storage bucket-to-task placement, allowing an outer mapping-colocate join to build an expression-less bucket repair and miss matching rows.
- Mapping DROP skips the atomic-restore ALTER fence, so a successful DROP can be silently reversed by the staged table swap.
- Atomic restore can publish a table-local mapping whose name collides with an existing centralized constraint, leaving SHOW and mapping-enabled planning unusable.
Checkpoint conclusions:
- Goal and tests: the opt-in constraint model, stable schema binding, persistence, ordinary Project/Aggregate/join planning, compatibility fallback, and ordered result paths are broadly covered. Missing multi-task runtime-boundary cases and the two restore sequences correspond directly to the blocking findings.
- Scope and design: the patch is focused on mapping metadata, property derivation, join selection, lifecycle hooks, and tests. Mapping identity, determinant order/arity, target positions, selected-index provenance, and final two-child validation are otherwise conservative.
- Concurrency and locking: database-read -> table-write -> manager-write ordering, object revalidation, immutable journal payloads, and waiting outside metadata locks are sound. The concrete gap is the missing normal-state check on DROP during atomic restore.
- Lifecycle, persistence, and compatibility: legacy readers, replay, schema mismatch, and mixed/unknown FE state fall back conservatively. Atomic publication is the remaining unsafe boundary because it skips the DROP state fence and destination constraint namespace invariant.
- Parallel paths, configuration, and cache: the feature defaults off, participates in plan-result identity, and disables SQL result caching once consumed. Generate, Window/PartitionTopN, ordinary NLJ, and serial/force-passthrough broadcast are the verified runtime placement barriers; redistribution, set operations, Repeat/source-Aggregate, global ordering, CTE, and ordinary aggregate paths were cleared.
- Performance and observability: no new non-duplicate issue survived; existing candidate-scale and logging discussions were treated as hard duplicate fences.
- Verification: reviewed the authoritative 43-file bundle at head fc90803 against base 1197ae1 and deduplicated against the live review history. Per the review-only mandate, no local build or test was run. At submission time BE UT, Cloud UT, coverage, large-file, and review-status checks pass; Performance fails; Compile, FE UT, and automated code-review remain pending.
|
run buildall |
|
/review |
There was a problem hiding this comment.
Request changes: two P1 correctness blockers remain on the exact reviewed head. One rolling-upgrade sequence can durably lose a committed distribution mapping through a later old-FE checkpoint; one hidden-key COUNT(DISTINCT ...) plan can rebuild BUCKET placement with determinant/grouping hashes and produce a wrong-result colocate join. The review converged in Round 2 after a complete 44-file sweep, duplicate fencing against all existing threads, three independent normal passes, and a separate risk challenge.
Critical checkpoint conclusions:
- Goal and proof: the PR implements distribution-mapping DDL, persistence, optimizer proof propagation, and colocate planning, with substantial unit and regression coverage, but the two missing end-to-end cases below mean correctness is not yet established.
- Scope and focus: the 44 changed files are broad but cohesive around this feature; no unrelated source changes were identified. No additional user focus was provided.
- Concurrency: mapping ADD/DROP follows database-read -> table-write -> constraint-manager-write ordering, journals immutable payloads, and waits outside metadata locks. No new deadlock or lock-scope defect was found, but FE admission/election is outside the point-in-time compatibility check and creates the first blocker.
- Lifecycle and static/global state: table-owned mappings were traced through backup, restore, rename, replace, truncate, recycle, recover, image, and replay. Current-code ownership is coherent; no static-initialization, reference-cycle, or unreleased-lifecycle issue applies. The old-writer checkpoint lifecycle remains unsafe.
- Configuration: the new session flag is dynamic and included in result-affecting state; actual mapping use disables SQL result caching. Once enabled, default local-shuffle/distinct-streaming settings reach the second blocker.
- Compatibility: the new JSON envelope is parseable by old FEs but is not semantically round-trip-preserving if an old FE is admitted later and becomes leader/checkpointer. Rolling-upgrade safety is therefore incomplete.
- Parallel paths and conditions: schema changes, restore variants, selected-index binding, join orientation/types, projection/casts, set operations, Repeat, and known runtime barriers were traced. Existing barrier issues were not duplicated; the distinct-dedup Aggregate path is a separate uncovered condition. The compatibility and Aggregate guards have clear local intent, but their downstream invariants do not hold in the two reported sequences.
- Tests and results: changed unit/regression outputs were reviewed and are consistent with their queries. Negative syntax/schema, persistence, lifecycle, proof, and barrier coverage is extensive. Missing are ADD -> old-FE failover/checkpoint -> new-FE reload and a multi-bucket, multi-task asymmetric distinct-aggregate-vs-scan result test whose determinant hash differs from the storage-key hash. Per the review runner instructions, no builds or tests were executed.
- Error handling, memory safety, and nullability: this is FE Java metadata/planner work plus existing BE exchange consumption; no unchecked Status, C++ ownership/allocation, or BE nullable-column issue is introduced in the changed code. Analysis errors carry actionable constraint/version context.
- Observability: compatibility failure and mapping fallback paths have usable messages/rate-limited logging; no separate logging or metrics blocker was substantiated.
- Persistence and failover: current-code EditLog write/replay is symmetric and table-ID based, but old-FE semantic discard plus checkpoint cleanup violates failover durability as reported inline.
- Data writes and FE/BE variables: there is no BE storage-data mutation or new FE-to-BE configuration field. FE planner properties choose existing BE local-exchange modes; the second blocker is precisely a mismatch between the FE BUCKET claim and the expressions BE hashes.
- Performance: mapping/proof checks are bounded metadata work and the exact-version scan is on rare DDL/restore paths; no substantiated CPU, memory, or asymptotic regression was found.
- Other issues: the information_schema candidate was dismissed because TABLE_CONSTRAINTS is deliberately part of the MySQL key-metadata adapter, while SHOW CONSTRAINTS is Doris's broader registry. No unresolved candidate remains beyond the two inline P1s.
FE UT Coverage ReportIncrement line coverage |
|
run buildall |
|
/review |
There was a problem hiding this comment.
Reviewed exact head 1669edacec4b5af5c731d64eba7b28e111626927. Requesting changes for two correctness issues and one documentation contract mismatch: existing-table non-atomic Restore can retain an invalid destination mapping proof; CCR full sync can retain a stale proof after a source-side DROP; and the design documents overstate Atomic Restore support.
Checkpoint conclusions: the feature goal and default-off scope are coherent; DDL locking, replay durability, lifecycle handling, dynamic configuration, exact-FE admission, optimizer parallel paths, runtime barriers, observability, atomic publication, FE/BE interface boundaries, and mapping-index performance are otherwise sound or already covered by current duplicate-fenced threads. Persistence/failover and Restore/CCR lifecycle are not safe in the two cases called out inline. Comments and special-condition handling are consistent except for the Atomic Restore documentation. Test coverage is broad but misses the existing-target Restore and CCR DROP sequences described inline. No builds or tests were run, as required by the review prompt.
FE UT Coverage ReportIncrement line coverage |
|
run buildall |
|
/review |
There was a problem hiding this comment.
Automated review result for exact head 645a1b81f81fd1a773f68829edae858d39761b6c: no new distinct blocking or actionable issue found.
Round 1 converged after three normal full-review passes and two separate risk-focused passes. Existing inline threads were treated as hard duplicate fences; the only plausible selected-rollup provenance concern was exactly covered by existing comment 3702605388, and the other follow-ups were dismissed with direct parser or restore-contract evidence.
Critical checkpoint conclusions:
- Goal and proof: the PR implements an opt-in,
NOT ENFORCEDtable-local distribution-mapping proof for colocate joins. The scan, property, aggregate, join, translator, and fallback paths accomplish that goal, and the changed unit/regression artifacts cover direct and aggregate successes plus wrong-row barriers. - Scope and clarity: the implementation stays focused on FE metadata, Nereids physical properties, parser/DDL, compatibility, and tests. I found no unnecessary FE-BE protocol or data-write expansion.
- Concurrency and locking: mapping ADD/DROP use database-read -> table-write -> constraint-manager locking, revalidate the concrete table and state while protected, submit the complete snapshot under the metadata locks, and wait for durability only after releasing them. Restore preflight occurs before publication; no distinct deadlock or unsafe failure window remained.
- Lifecycle: mappings follow the concrete table object across rename, recycle/recover, truncate, and replace/swap semantics. Backup, non-atomic restore, atomic-restore rejection, cancellation/replay, and CCR stripping were traced end to end; the live/backup mismatch, namespace collision, old-FE checkpoint, and CCR lifecycle concerns are already represented by existing review threads.
- Configuration:
enable_colocate_mapping_constraintis an online experimental session variable, defaults off, participates in plan-result cache state, and promptly changes planner behavior. - Compatibility: the persistent source of truth is a deterministic JSON snapshot in the existing generic
TableProperty.propertiesenvelope. Supporting FEs rebuild the derived map; older-FE-shaped round trips preserve the opaque key. Mixed/unknown FE versions make planning fall back and gate ADD/non-atomic mapped restore. No new wire symbol or storage-data format is introduced. - Parallel and conditional paths: mapped base-column DROP/RENAME/MODIFY and HASH-to-RANDOM conversion are fenced; stale replayed bindings fail schema/type/unique-ID/layout compatibility and are ignored by planning. Selected rollups, projection/casts, set operations, Repeat/CTE, distinct/dedup, Generate, Window/PartitionTopN, nested-loop/broadcast joins, outer/mark joins, local shuffle, and plan recomputation were checked.
- Persistence and failover: ADD/DROP journal complete snapshots (including
[]for the final DROP), replay rebuilds the derived state under the table lock, and allowed restore paths register the same validated object on leader and replay. No new unresolved EditLog or failover defect was substantiated beyond existing threads. - Data writes and transactions: this change does not add a BE data-write or transaction path. The user assertion remains explicitly unenforced; correctness depends on the declared invariant, while planner consumption is gated by schema, version, stable colocate layout, and complete bucket-position proof.
- Tests and results: changed FE tests cover persistence, compatibility, restore/CCR, DDL lifecycle, property derivation, enforcer behavior, aggregates, and join selection. All 11 result queries have deterministic ordered expected-output sections, including non-coincidental multi-bucket wrong-row oracles and negative placement barriers. Per the review-runner instruction, I did not run builds or tests; this conclusion is based on code and committed test-artifact review.
- Observability and performance: fallback warnings are rate-limited and identify the table/reason; mapping planning is opt-in and candidate matching is indexed. I found no distinct material logging, CPU, memory, or asymptotic issue on this head.
- Other issues: none remained after the explicit 48-file final sweep and unresolved-candidate audit.
User focus: review_focus.txt supplied no additional focus, so the complete PR and all applicable Doris review checkpoints were reviewed.
Status: review complete on the exact bundled/live head; zero new inline comments.
|
run buildall |
FE UT Coverage ReportIncrement line coverage |
What problem does this PR solve?
Problem Summary:
Doris can currently use Colocate Join when the join equality conditions directly cover all Hash distribution keys of two tables in the same stable Colocate Group.
However, some data models contain determinant columns that consistently map to distribution keys across tables. For example, if both tables are distributed by
tenant_id, and eachuser_idalways belongs to exactly onetenant_id, joining the tables byuser_idis also colocated when the mapping fromuser_idtotenant_idis consistent across both tables.Previously, Doris could not declare or use this cross-table mapping relationship. Such queries therefore required Shuffle Join even though matching rows were already located in corresponding Buckets.
This PR introduces a
COLOCATE MAPPINGconstraint and allows Nereids to use the declared mapping when proving that a Join can run as a Colocate Join.The implementation supports:
The optimization is controlled by the session variable:
It is disabled by default. When disabled, scan distribution properties, join property requests, and Colocate Join decisions retain their original behavior.
The constraint is declared as
NOT ENFORCED. Doris trusts the mapping supplied by the user and does not validate it during INSERT, UPDATE, load, compaction, or schema change. Declaring an incorrect mapping may produce incorrect query results when the optimization is enabled.The mapping metadata is supported only for internal, non-temporary OLAP tables with Hash distribution. It is stored in the physical
OlapTableobject rather than in the global name-keyed constraint index. This keeps lifecycle behavior aligned with physical table ownership and avoids adding mapping-specific repair logic to external Catalog, HMS event, Rename, Replace, Recover, and recycle-bin paths.This change is implemented entirely in FE. It reuses the existing Colocate Hash Join execution path and does not change BE Hash Join semantics or add FE-BE protocol fields.
Release note
Added an experimental
COLOCATE MAPPINGconstraint that allows Nereids to derive Colocate Join eligibility from user-declared mappings between join columns and Hash distribution keys. Mapping-enabled queries fall back to ordinary distribution planning when a valid locality proof is unavailable. DISTINCT/MultiDistinct and pure deduplication Aggregates do not propagate mapping proofs, while ordinary non-DISTINCT Aggregates remain supported under conservative proof conditions. Atomic Restore rejects a selected table when its backup metadata contains mappings; use a non-atomic Restore or create a backup without mappings.Applicable Scenarios
This feature is useful when:
A typical example is:
where both tables are distributed by
tenant_id, but queries frequently join byuser_id.This feature should only be used when the declared mapping has identical semantics across every participating table. The mapping ID, determinant order, and target distribution-key positions are part of that cross-table contract.
Usage
Create two internal OLAP tables in the same Colocate Group:
Declare the same logical mapping on both tables:
The constraint name is table-local, while the mapping identifier must match across tables:
Enable the optimization:
A Join using the determinant columns can then use Colocate Join:
Use
EXPLAINto verify the selected distribution strategy:The plan should contain:
The constraints can be removed with:
Metadata Lifecycle and Operational Behavior
A
COLOCATE MAPPINGconstraint is stored as a complete JSON snapshot under the reserved__distribution_mapping_constraintskey in theTableProperty.propertiesmap owned by itsOlapTable. It is not inserted into the global, qualified-name-keyedConstraintManager.constraintsMapused by PRIMARY KEY, FOREIGN KEY, and UNIQUE constraints.This table-local ownership defines the lifecycle behavior:
TRUNCATE TABLEpreserves the table object and table properties, so mappings remain present after the partitions are replaced.REPLACE TABLE ... PROPERTIES("swap"="false"), the replacement table object takes the target name and keeps the replacement object's mappings. The replaced object and its mappings follow the normal replacement lifecycle.REPLACE TABLE ... PROPERTIES("swap"="true"), the two physical table objects exchange names while each object's mappings remain attached to that object.OlapTablemetadata, including mappings.in_atomic_restore, before staging metadata is prepared, and before replicas are created, even when the destination currently has no conflicting constraint. Use a non-atomic Restore or create a backup without mappings.CREATE TABLE LIKEand CTAS create new physical table objects and do not copy mappings. ANOT ENFORCEDbusiness invariant cannot be inferred from schema similarity.ADD binds each determinant and target distribution column to its current name, type, stable column unique ID, and base schema version. Planning and non-atomic Restore revalidate that binding before consuming the mapping. Query planning ignores an incompatible mapping and falls back to the ordinary distribution alternatives, while non-atomic Restore rejects it before changing target state. This prevents a same-name replacement column or an incompatible replayed schema change from silently producing a stale proof.
The following operations are rejected when they directly affect a determinant or target distribution column referenced by a mapping:
DROP COLUMN.RENAME COLUMN.MODIFY COLUMN.For legacy tables whose referenced columns do not have stable column unique IDs, a base schema-version change invalidates the mapping conservatively. Drop and recreate the mapping after completing the schema change.
ADD and DROP use database read lock -> table write lock ->
ConstraintManagerlock ordering. The in-memory mutation and journal submission occur while metadata is protected. The journalawait()runs only after database, table, and manager locks have been released.While a table is participating in an Atomic Restore, both Mapping ADD and Mapping DROP are rejected by the normal ALTER-state fence. After cancellation, the fence is removed and the original table and mappings remain available. After successful replacement, the restored table owns exactly the mappings present in the backup; because selected backup tables containing mappings are rejected for Atomic Restore, the replacement table has no mappings.
Image persistence uses the reserved
__distribution_mapping_constraintsentry in the existingTableProperty.propertiesmap. Each ADD or DROP serializes the complete mapping set in deterministic constraint-name order; dropping the final mapping persists[]instead of removing the key. The same one-entry properties map is journaled through the existingOP_MODIFY_TABLE_PROPERTIESenvelope. An older FE can replay and checkpoint the opaque property without understanding the feature, while a supporting FE decodes the snapshot into its derived in-memory mapping map. Supporting FE versions do not publish these records as ordinary table-property binlogs.SQL cache publication is disabled only after a Scan constructs at least one usable mapping proof. A table merely containing a mapping does not disable SQL cache when the session switch is off or when no proof is constructed. The feature changes physical distribution planning only and does not add mapping-specific MTMV rewrite-cache lifecycle hooks.
Rolling Upgrade Restrictions
Mapping ADD and a non-atomic Restore of selected tables whose backup metadata contains mappings require every registered FE to report the exact current
version-shortHash. Query planning uses mappings only under the same condition; if an FE has not reported a version or reports a different version, the query ignores mappings and falls back to the ordinary distribution alternatives. Atomic Restore of such a table remains unsupported even after all FE versions converge.The restrictions are:
Recommended rolling-upgrade sequence:
enable_colocate_mapping_constraintenabled; queries use ordinary planning while versions are mixed.version-shortHash.Downgrading an FE to a version that does not implement this feature while mappings remain is unsupported. Drop all mappings with a supporting FE version before starting the downgrade.
External Catalog Constraint Consistency
COLOCATE MAPPINGis deliberately unsupported for external Catalogs, HMS tables,RemoteOlapTable, and temporary tables. An ADD attempt on these table types fails instead of creating metadata that would need asynchronous reconciliation.Consequently, this PR does not change external Catalog refresh, HMS notification, external Rename/Drop, connector event cursor, Catalog source-transition, or MTMV invalidation behavior. Existing PRIMARY KEY, FOREIGN KEY, and UNIQUE constraint behavior for external objects is unchanged by this feature.
This scope is intentional. External metadata can change outside Doris and is identified through Catalog-specific names, IDs, refreshes, and event streams. Supporting a user-trusted physical Bucket mapping there would require a separate identity, persistence, reconciliation, and failure model. Rejecting the feature at the DDL boundary avoids a large lifecycle patch surface unrelated to the core internal-OLAP optimization.
Limitations
NOT ENFORCED; Doris does not verify mapping consistency during writes.COLOCATE MAPPINGconstraints is unsupported. Non-atomic Restore remains supported after FE-version and schema validation.The following examples use
ordersandusersdistributed bytenant_id, withuser_iddeclared as the determinant oftenant_id.An ordinary Aggregate can preserve the mapping when the complete determinant covers the distribution-key position:
A query containing a DISTINCT aggregate function remains executable, but the Aggregate is a mapping-proof barrier. An upper Join that would need the proof to cross this Aggregate therefore uses ordinary distribution planning:
The same conservative fallback applies to MultiDistinct phases and pure deduplication such as
SELECT DISTINCT user_id FROM orders. This boundary prevents a DISTINCT plan from incorrectly forwarding a locality proof derived for a different row grouping.The following Aggregate shapes do not propagate a usable mapping proof:
For a table distributed by
HASH(tenant_id, region_id), where onlyuser_id -> tenant_idis declared, the following Group By leaves theregion_idBucket position uncovered:For a composite determinant
(country_id, user_id) -> tenant_id, both determinant columns must be present in the proof. Joining or grouping only byuser_idis insufficient.An Aggregate may group by a determinant without returning it, but an upper Join cannot use that determinant after it has been removed from the Aggregate output:
An Aggregate also does not propagate the mapping if its input has already been changed from the table's natural Bucket locality by an Exchange. For example, if the Join below requires Shuffle on
region_id, the Aggregate above it cannot recover the originaltenant_idBucket locality:UNION ALLdoes not preserve mapping locality even when each input independently has a valid mapping:Multi-hop closure is not derived. Declaring or knowing
email -> user_idanduser_id -> tenant_iddoes not let Doris inferemail -> tenant_id; a determinant must map directly to the distribution-key positions in a supported constraint.Expression-based determinants are not accepted. For example, the following conceptual declaration is unsupported; determinants must be column Slots:
COLOCATE MAPPING tenant_by_email (LOWER(email)) DETERMINES DISTRIBUTION KEY (tenant_id) NOT ENFORCEDUpgrade and compatibility considerations
Mapping metadata is encoded for backward readability:
__distribution_mapping_constraintsentry of theTableProperty.propertiesmap owned by theOlapTable, separate from the global polymorphic constraint map.OP_MODIFY_TABLE_PROPERTIESjournal record. The final DROP writes[], so replay and checkpoint cannot resurrect an older mapping set.Backward readability prevents an older FE from failing merely because an image or journal contains the reserved property and preserves the opaque snapshot across checkpoint. It does not make the feature supported on that FE: an older FE cannot show or use mappings and does not enforce mapping-specific DDL safeguards.
The exact-version gate therefore remains required:
Required downgrade procedure:
enable_colocate_mapping_constraint.COLOCATE MAPPINGconstraints while a supporting FE version is still running.SHOW CONSTRAINTSon the affected tables.Do not complete a downgrade while mappings remain. Although an unsupported FE preserves the opaque snapshot, it cannot use or manage the feature and does not enforce mapping-specific DDL safeguards.
The same rules apply in Cloud mode. Wait until every expected FE is visible in the registered FE set and reports the exact current build before Mapping ADD or non-atomic Restore of selected tables containing mappings. Mapping-enabled queries fall back to ordinary planning while versions are mixed and resume the optimization after convergence. DROP remains the recovery path when versions are mixed, except while a table is fenced by an Atomic Restore.
Check List (For Author)
Test
Behavior changed:
Does this need documentation?
Check List (For Reviewer who merge this PR)