feat(frontend): support schema evolution in data branch diff/merge#25882
feat(frontend): support schema evolution in data branch diff/merge#25882VioletQwQ-0 wants to merge 38 commits into
Conversation
Replace strict schema equivalence check with named-column compatibility check that allows compatible schema evolution (extra columns). Project base-side batches to target layout before hashmap encoding. Limit row comparison to common columns only. Fixes matrixorigin#24549
Fixes index out of range panic when base data batch has more columns than base table definition (e.g., composite PK columns). Clamp baseColCount to len(baseColToTarIdx) and validate tarColIdx against len(colNames) before accessing out.Vecs.
When target table has extra columns not present in base (schema evolution), INSERT SQL for MERGE must only reference common columns. Filter visibleNames in newPKBatchInfo and use commonIdxes in appendBatchRowsAsSQLValues/writeInsertRowValues when tarOnlyIdxes is non-empty. Also update diff_schema_evolve.result to expect 5 columns including the extra column c in DIFF output.
…olution - compareRowInWrappedBatches: use batchIdx for Vecs access, colIdx for pk check - baseColToTarIdx: build after colNames populated, filter hidden cols, map to colNames positions - data_branch_pick: add missing idxes parameter for writeInsertRowValues
The merge_schema_evolve.sql test creates snapshots sp0 and sp1 but never drops them. Since snapshot names are globally unique (checked by sname without level filtering), these leftover snapshots conflict with clone_reference.sql which creates account-level sp0, causing 6 BVT failures and dropping the pass rate below 100%. Add explicit drop snapshot sp1/sp0 cleanup matching the pattern in diff_schema_evolve.sql.
# Conflicts: # pkg/frontend/data_branch_output.go # pkg/frontend/data_branch_pick.go # pkg/frontend/data_branch_test.go
Expand diff_schema_evolve (8 cases) and merge_schema_evolve (5 cases) to cover: basic evolution, multiple extra columns, UPDATE on common col, UPDATE on target-only col (no diff), DELETE, composite PK, idempotent merge, type mismatch rejection, and PK removal rejection. Update branch_unhappy_path and branch_edge_cases to reflect the new schema evolution behavior: ALTER ADD COLUMN no longer errors, and type mismatch on common columns is the new rejection path.
The getTupleColumnValue function had an off-by-one bug for tuples with totalColCnt+1 elements. When projectBaseBatchToTarget creates a batch with [RowID, data...] (no commit_ts), the value tuple has totalColCnt+1 elements with RowID at index 0. The old code used tuple[colIdx] which read RowID bytes as data column values, causing 'unexpected byte slice for fixed-width column type INT' errors. Fix: use tuple[colIdx+1] for totalColCnt+1 tuples, matching the existing totalColCnt+2 case which already skips the leading RowID. Also add WHEN CONFLICT ACCEPT to merge_schema_evolve.sql Cases 2 and 4 which have UPDATE conflicts (same PK, different values on common columns). Without this clause, merge defaults to CONFLICT_FAIL.
|
Addressed all blocking review feedback on the current review head and resolved the Changes:
Coverage:
Validation on
The new BVT fixtures were not executed locally because this worktree has no standalone |
XuPeng-SH
left a comment
There was a problem hiding this comment.
Requesting changes on 08cd75d. One blocking historical-schema path remains.
[P1] Project incompatible target-only columns out of LCA probes — pkg/frontend/data_branch_hashdiff.go:114
The latest fix correctly maps an incompatible target-only historical column to -1 in dataBranchSourceColToTargetIdx, but lcaProbeColumnLayout independently selects every LCA column whose ColId and Seqnum match the target, without checking its logical type or targetOnlyIdxes. handleDelsOnLCA then appends that old LCA vector into the endpoint-typed dBat; appendLCAProbeValue rejects every non-ENUM type mismatch with unexpected LCA probe type conversion.
This is reachable when the fork point contains c INT, one descendant changes c to VARCHAR, and the sibling drops c. The endpoint compatibility check accepts c as target-only, but an UPDATE of an LCA row forces the probe to read c INT and append it into target c VARCHAR. A review-only unit with LCA c INT and target c VARCHAR sharing the same ColId/Seqnum expected the probe layout to contain only a; the current head returned [a,c]. DIFF/MERGE therefore fail before comparison even though c is excluded from comparison and MERGE apply.
Please thread the endpoint target-only/type-compatibility rule into LCA layout construction so such columns are omitted and reconstructed as NULL, matching the historical CollectChanges projection. Add DIFF/MERGE coverage with a common ancestor containing c INT, one endpoint MODIFY c VARCHAR, the sibling DROP c, and an updated ancestor row that exercises handleDelsOnLCA.
The prior Seqnum-redefinition and account/database-owner blockers are closed. The four affected package test suites and focused race x10 pass; the failing review-only case exposes the missing LCA branch in the current matrix.
|
Fixed in 7a0fb11. The LCA probe now excludes endpoint target-only columns on both the SQL and reader paths, including the no-column-metadata fallback. Common columns still fail closed on identity/type mismatches, and full-layout reader results now resolve ENUM metadata by target index. This also prevents hidden RowID identity collisions from being appended as user column values, which was the source of the ROWID-to-INT/VARCHAR CI failures. Validation:
Added DIFF and MERGE BVT regressions for the common-ancestor c INT -> target c VARCHAR / sibling DROP c path. CI is rerunning on the new head. |
|
Updated head: I rechecked the complete PR diff and all previous change-request clusters. The earlier target-only projection, explicit ALTER semantics, deleted-generation compaction, owner-scope cleanup, DROP/ADD identity, and LCA target-only type fixes remain intact. This update fixes the remaining composed historical-schema case found during preflight:
Validation:
Please re-review this head. |
XuPeng-SH
left a comment
There was a problem hiding this comment.
Approved on exact head 5b57d3fa0ec18283cb15397262e5b163d04c00a6. No blocking findings remain.
I revalidated the complete PR diff and every prior P1 cluster: target-only historical type projection, explicit ALTER transaction semantics, deleted intermediate-generation reclamation, account/database historical ownership after current-table-first deletion, DROP/ADD Seqnum identity, and incompatible target-only LCA probes. The latest derived composite-key fix is fail-closed on ordered component names, component Seqnums/types/nullability, handles accidental RowID identity collisions, and quotes PK identifiers in both VALUES aliases and join expressions.
| Audit area | Q1 trigger/ownership | Q2 cleanup/failure path | Q3 completion/reuse |
|---|---|---|---|
| LCA SQL/reader probe | Input PK batch and snapshot reader callbacks have explicit ownership; concurrent callbacks are serialized | temporary/filter/output batches close on success and error; target-only columns are reconstructed as NULL | full/projected layouts map by target index; duplicate/missing keys complete deterministically |
| Historical generation projection | vectors are transferred once from source batches | hydration/probe errors clean projected data and tombstones | Seqnum/type mismatches fail closed except the verified derived composite key identity |
| Snapshot/PITR lineage compaction | owner mutation and compaction share one explicit transaction | any compaction DELETE failure rolls back the owner mutation and paired metadata work | deleted generations remain retained while owned and are reclaimed after the final owner disappears |
Validation on this head:
go test ./pkg/frontend/databranchutils ./pkg/frontend ./pkg/sql/compile -count=1- focused
go test -racefor LCA layout/reader/SQL, rebuilt composite PK mapping, DROP snapshot rollback, and timestamp overflow go vet ./pkg/frontend/databranchutils ./pkg/frontend ./pkg/sql/compilegit diff --check origin/main...HEAD
GitHub SCA and completed checks are green; UT/BVT/coverage jobs were still running with no failures at review submission.
What type of PR is this?
Which issue(s) this PR fixes:
issue #24549
What this PR does / why we need it:
This PR continues the unfinished work from #24666 while preserving its original commits and authorship.
It supports schema evolution in DATA BRANCH DIFF/MERGE by matching columns with stable identity, separating physical and visible common-column indexes, projecting compatible historical batches, comparing common columns, preserving target-only data, and maintaining ALTER lineage ownership.
Review fixes on the latest head:
Seqnum, while preserving pureFIRST/AFTERreorderings;Validation
go test ./pkg/frontend/databranchutils ./pkg/frontend ./pkg/sql/compile ./pkg/vm/engine/test -count=1go test -racefor identity mapping, projection, and lineage-owner lifecycle pathsgo vet ./pkg/frontend/databranchutils ./pkg/frontend ./pkg/sql/compile ./pkg/vm/engine/testgo build ./pkg/frontend/databranchutils ./pkg/frontend ./pkg/sql/compile ./pkg/vm/engine/testgit diff upstream/main --checkmo-pr-preflight-reviewandmo-self-reviewThe BVT fixtures are included for DIFF/MERGE identity redefinition and table/account/database historical-owner cleanup; they will be executed by CI because this local worktree has no standalone
mo-testerrunner.