Skip to content

refactor(plan): remove legacy UPDATE planner - #27482

Merged
mergify[bot] merged 14 commits into
matrixorigin:mainfrom
ck89119:issue-26343-main
Aug 23, 2026
Merged

refactor(plan): remove legacy UPDATE planner#27482
mergify[bot] merged 14 commits into
matrixorigin:mainfrom
ck89119:issue-26343-main

Conversation

@ck89119

@ck89119 ck89119 commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

What type of PR is this?

  • API-change
  • BUG
  • Improvement
  • Documentation
  • Feature
  • Test and CI
  • Code Refactoring

Which issue(s) this PR fixes:

issue #26343

What this PR does / why we need it:

This change performs the final source-level cutover from the legacy UPDATE
planner to MULTI_UPDATE and explicit route dispositions while preserving the
existing SQL compatibility contract.

  • removes the generic ErrUnsupportedDML -> buildTableUpdate fallback, the
    legacy route type, and the now-unreachable build_update.go implementation;
  • keeps shared INSERT, DELETE, LOAD, REPLACE, FK-recursion, PRE_INSERT, compile,
    and explain consumers intact;
  • preserves the named Iceberg specialized route and converts unsupported FK
    graphs and irregular-index algorithms into stable pre-mutation rejections;
  • keeps derived tables and CTEs usable as read-only UPDATE table-list sources
    without treating them as writable DML targets;
  • restores self-referencing ON UPDATE CASCADE/SET NULL by folding explicit
    roots and action rows into one physical MULTI_UPDATE writer;
  • preserves affected-row semantics for self actions and ordinary multi-target
    updates, including partitioned targets, CLIENT_FOUND_ROWS, and changed-row
    modes;
  • supports cascades that change simple or composite child primary keys and
    atomically maintains their regular hidden indexes;
  • removes the orphaned checkInsertPkDup planner field so SCA remains clean;
  • restores a two-level stored generated-column row-image oracle and adds
    physical index checks;
  • prevents materialized dispatch fanout from persisting pipeline control
    batches as data rows;
  • adds a guard proving that an arbitrary ErrUnsupportedDML cannot trigger a
    second planner attempt;
  • fixes UPDATE build-duration accounting to use the UPDATE histogram.

Validation completed across this change series, with final affected-row
retesting on mo/main 6ff9be9646a6ac43e05ba3063de27b2248bbac62
at PR head 89c73965f55bde0c41044d1e124da402966f61b0:

  • make generate-pb twice with identical generated hashes;
  • mo-cgo-test -count=1 -timeout=600s ./pkg/sql/plan ./pkg/sql/colexec/multi_update ./pkg/sql/colexec/dispatch;
  • exact embedded regressions:
    • TestIssue27334UpdateAffectedRowsHonorsClientFoundRows;
    • TestUpdateIgnoreRepeatedAliasesAdvanceGreedily;
  • modified-function coverage: insert_table 91.2%; partition context clones and
    physicalInsertAffectedRows 100%;
  • make build;
  • make static-check (go vet/molint, license checks, and golangci-lint with
    zero final issues);
  • mo-tester pessimistic BVT:
    • fk_issue_26831.sql: 36/36 passed;
    • foreign_key_multilayer.sql: 160/160 passed;
    • update_modern_fk.sql: 183/183 passed;
    • update_multi_target_modern.sql: 309/309 passed;
  • git diff --check.

The external regression/soak observation window required by #26343 was not
available in the local environment. This PR remains Draft pending that evidence
and repository CI; no zero-legacy/zero-unknown production observation is claimed
by the local validation above.

@ck89119
ck89119 marked this pull request as ready for review August 23, 2026 10:23
@qodo-code-review

Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@XuPeng-SH XuPeng-SH 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.

[blocker] Parent-key CASCADE can drop a child row when its PK changes and it has a nullable single-column secondary index.

appendUpdateParentMutation now maintains every regular index when primaryKeyChanged, but the old-index scan is still INNER for every non-unique index. A one-part index stores the raw key, and check_null_and_insert_table omits NULL keys, so a child row whose indexed value is NULL has no hidden-index row. The INNER join therefore removes the base child row before the CASCADE write; the parent key can be updated while the child FK/PK is left unchanged.

Minimal case:

create table p (id int primary key);
create table c (
  parent_id int primary key,
  payload int,
  key idx_payload (payload),
  foreign key (parent_id) references p(id) on update cascade
);
insert into p values (1);
insert into c values (1, null);
update p set id = 2 where id = 1;

I also added a temporary plan assertion on this exact head: the secondary-index lookup join must be LEFT, but it is emitted as INNER. Please keep the child base row independent of hidden-index presence (for example, mirror the root UPDATE path and use LEFT when the child PK changes), and add a runtime regression with payload IS NULL.

@XuPeng-SH XuPeng-SH 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.

Re-reviewed exact head ac7cfae. The prior nullable-secondary-index blocker is fixed and mutation-sensitive: removing the primary-key-change LEFT-join condition makes the focused regression fail. Focused count=10, focused race, full owning-package tests, build, vet, diff check, and current required CI all pass. No remaining code correctness blocker found. Approving the implementation; the issue's soak/optimistic evidence remains an independent merge-policy gate for the merge owner.

@mergify mergify Bot added the queued label Aug 23, 2026
@mergify

mergify Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Merge Queue Status

  • Entered queue2026-08-23 15:31 UTC · Rule: main · triggered by rule Automatic queue on approval for main
  • Checks skipped · PR is already up-to-date
  • Merged2026-08-23 15:31 UTC · at ac7cfae88a5e1277a4d612c0fb040c492bca632b · squash

This pull request spent 15 seconds in the queue, including 2 seconds running CI.

Required conditions to merge
  • #review-threads-unresolved = 0 [🛡 GitHub branch protection]
  • github-review-approved [🛡 GitHub branch protection]
  • any of [🛡 GitHub branch protection]:
    • check-success = Matrixone CI / UT Test on Ubuntu/x86
    • check-neutral = Matrixone CI / UT Test on Ubuntu/x86
    • check-skipped = Matrixone CI / UT Test on Ubuntu/x86
  • any of [🛡 GitHub branch protection]:
    • check-success = Matrixone CI / SCA Test on Linux/arm64
    • check-neutral = Matrixone CI / SCA Test on Linux/arm64
    • check-skipped = Matrixone CI / SCA Test on Linux/arm64
  • any of [🛡 GitHub branch protection]:
    • check-success = Matrixone Compose CI / multi cn e2e bvt test docker compose(PROXY)
    • check-neutral = Matrixone Compose CI / multi cn e2e bvt test docker compose(PROXY)
    • check-skipped = Matrixone Compose CI / multi cn e2e bvt test docker compose(PROXY)
  • any of [🛡 GitHub branch protection]:
    • check-success = Matrixone Utils CI / Coverage
    • check-neutral = Matrixone Utils CI / Coverage
    • check-skipped = Matrixone Utils CI / Coverage
  • any of [🛡 GitHub branch protection]:
    • check-success = Matrixone UT Coverage / UT Coverage on Ubuntu/x86
    • check-neutral = Matrixone UT Coverage / UT Coverage on Ubuntu/x86
    • check-skipped = Matrixone UT Coverage / UT Coverage on Ubuntu/x86
  • any of [🛡 GitHub branch protection]:
    • check-success = Matrixone Standlone CI / multi CN e2e BVT Test on Linux/x64(COMPOSE, PESSIMISTIC)
    • check-neutral = Matrixone Standlone CI / multi CN e2e BVT Test on Linux/x64(COMPOSE, PESSIMISTIC)
    • check-skipped = Matrixone Standlone CI / multi CN e2e BVT Test on Linux/x64(COMPOSE, PESSIMISTIC)

@mergify
mergify Bot merged commit d949463 into matrixorigin:main Aug 23, 2026
26 of 27 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind/bug Something isn't working kind/refactor Code refactor size/XXL Denotes a PR that changes 2000+ lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants