feat(plan): carry the create-shape cause on refused statements - #84
Merged
Conversation
Kiran01bm
marked this pull request as ready for review
September 7, 2026 10:22
Kiran01bm
requested review from
JashLal,
aparajon,
eeSeeGee,
jayjanssen,
jemiahw and
morgo
as code owners
September 7, 2026 10:22
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
Kiran01bm
marked this pull request as draft
September 7, 2026 10:48
Renderers previously re-derived why a create was refused from the error, in three places that could drift from the executor's verdict. The plan now records the typed cause once, where the refusal is decided, and readers only describe it. Report format moves to v3.
The plan report and the Cause field comment stated cause as present iff a statement is refused as unsupported-statement on a plan whose table does not exist. That holds only for a diff-source report: an alter-source dry run against an absent table can carry the same refusal with no create-shape cause. Both now scope the rule to the diff source and name the alter-source exception. Pin the two halves of the contract that had no test: the fingerprint test sets Reason and Cause on the explained statement, and the partitioned-parent refusal test asserts the statement is causeless. The create-shape corpus test asserts every refusal names a cause, and the refuse-create-shapes guard wraps ErrInvariantViolation so a refusal the vocabulary cannot name fails closed the way the rest of the core does. Publish a third pinned example, a greenfield diff whose CREATE TABLE carries IF NOT EXISTS, so the doc shows cause alongside the fields it withdraws. Note in the Causes section that concurrently, multiple-operations, and unsupported-kind are rejected by ParseDesired before a report exists, align the cause rows with the execution model, and point the SchemaBot integration notes and the verdict reason table at the typed cause so an adapter reads the field instead of deriving the shape from sentinels or prose. Reword the PARTITION OF and IF NOT EXISTS descriptions so they read as one clause when spliced after "the create path refuses this statement:"; the sentinels derive from Description() and follow.
Kiran01bm
force-pushed
the
kiran01bm/ct14b-plan-statement-cause
branch
from
September 8, 2026 01:27
4df1647 to
f456fff
Compare
Kiran01bm
marked this pull request as ready for review
September 8, 2026 01:27
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
The plan report's Causes table copies the execution model's vocabulary rows, and three of them had already been paraphrased apart before the docs test noticed only that each value had a row. TestDocCauseRowsMatchExecutionModel compares the Meaning cell of every create-shape cause across the two pages, modulo the sentence-ending period the plan report's table style adds, so an integrator reading either page learns the same meaning for each value.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refused create statements in a plan now carry the executor's typed
CreateShapeCause, so every renderer describes the same cause instead of re-deriving it.Why
The executor already decides why a create shape is refused (
IF NOT EXISTS,PARTITION OF, a duplicate relation name, …) and returns it as a typed cause. The plan dropped that type at the refusal boundary, so the text renderer, the greenfield refusal summary, and the desired-schema path each recomputed a cause from the error. Three recomputations of one fact drift; the plan is the single place the verdict should live.What
plan.Statement.Cause(executor.CreateShapeCause,json:"cause,omitempty"), stamped byRefuseUnsupportedCreateShapefromexecutor.CreateShapeCauseOf(err). First refusal wins; a refusal that carries no typed cause fails closed withErrInvariantViolation.causeis explanatory: excluded from the plan fingerprint, alongsidereason. Present exactly when adiff-source plan withtable_exists: falserefuses a statement asunsupported-statement; absent for every other refusal, including analter-source refusal against an absent table.Cause.Description().format_version2 → 3;docs/plan-report.mdgains acauserow, a Causes vocabulary section, and a third pinned example (greenfieldIF NOT EXISTSrefusal alongside an admitted index), all checked by the docs tests. The SchemaBot integration notes point the adapter atstatements[].causeinstead of the executor's sentinels.diffstep (IF NOT EXISTSfixture) asserting disposition, reason, and cause in check mode.Trade-off: the duplicate-name refusal detail no longer appends the colliding name (the plan carries the typed cause only). A
cause_detailfield is the natural follow-up if the name proves necessary for operators.Before / after