feat(expressions): add statement-discriminator contract + Into/Keyword accessors - #63
Merged
sjincho merged 1 commit intoAug 5, 2026
Conversation
…d accessors Give consumers a typed, normalized read surface for classifying a parsed statement, without changing parse or generate output. - Export the bounded discriminator vocabularies as constants: IntoOutfile/ IntoDumpfile, SetItemTransaction, and the distinguished MySQL Show* labels. - Add Expression.Into, a typed read of the into arg, replacing a hand-written type assertion; and Expression.Keyword, the normalized Command leading keyword, stable across both Command builder paths and multi-word command tokens, so a consumer never keys on a Command's untokenized remainder. - Document + test-enforce that the structured string discriminators — Into.kind, Create/Alter/Drop.kind, SetItem.kind, Show.this — are canonical uppercase, so a consumer compares them directly with no ToUpper. This matches upstream (which upper-cases these itself); it is a documented invariant, not a divergence, so it carries no DEVIATIONS entry — the Into/Keyword accessors are additive Go sugar, peers of the existing TableName/SchemaName accessors. Two boundaries the contract is explicit about: Show.this is canonical only for MySQL SHOW (a Postgres SHOW carries the verbatim config-parameter name, e.g. search_path); and the Create/Alter/Drop object-type vocabulary is deliberately not exported as constants because which objects are structured is verb/dialect-dependent (DROP TRIGGER structures, CREATE TRIGGER is a Command). The Command node's this/expression stay verbatim by design for round-trip fidelity. Documented in statement_discriminators.go, enforced by TestStatementDiscriminatorContract. Co-Authored-By: Claude Opus 4.8 <[email protected]> Claude-Session: https://claude.ai/code/session_01UpLPXA4aqraDVKB84Gwxi2
sjincho
force-pushed
the
sjcho/expressions/command-keyword-discriminator-contract
branch
from
August 5, 2026 10:40
2d0a587 to
a85c092
Compare
sjincho
deleted the
sjcho/expressions/command-keyword-discriminator-contract
branch
August 5, 2026 10:45
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.
Adds a read-side surface so a consumer can classify a parsed statement without re-normalizing strings or cracking a
Command's raw remainder. No change to parse or generate output.What's added (
expressions/statement_discriminators.go)IntoOutfile/IntoDumpfile,SetItemTransaction, and the distinguished MySQLShow*labels.Expression.Into()— typed read of theintoarg (replaces a hand-written type assertion) — andExpression.Keyword()— the normalizedCommandleading keyword, stable across both Command builder paths and multi-word tokens (LOCK TABLES).Into.kind,Create/Alter/Drop.kind,SetItem.kind,Show.this) are canonical uppercase, so a consumer compares them directly (noToUpper). This matches upstream (which upper-cases these itself) — a documented invariant, not a divergence, so noDEVIATIONS.mdentry; the accessors are additive Go sugar, peers of the existingTableName()/SchemaName()accessors.Boundaries worth knowing (the traps)
Show.thisis canonical only for MySQL SHOW; a Postgres SHOW carries the verbatim config-parameter name (e.g.search_path,timezone) — pinned by a dedicated test so it can't silently start being uppercased.Create/Alter/Dropobject-type vocabulary is deliberately not exported as constants: which objects are structured is verb/dialect-dependent (DROP TRIGGERstructures,CREATE TRIGGERis aCommand; PG structuresCREATE TYPE, MySQL doesn't). A consumer maps the (canonical) keyword itself.Commandnode'sthis/expressionstay verbatim by design for round-trip fidelity —Keyword()normalizes on read.Verification:
go test ./...green,gofmt/go vetclean. Reviewed via three-modeldual-review; findings (Postgres SHOW over-claim, phantom object constants, aKeyword()docstring over-claim) applied.Context: first of two slices enabling the proxy-monster statement classifier to drop its defensive
ToUpper/remainder-parsing. The follow-up structures the replication +RENAME TABLE/RENAME USERstatements.🤖 Generated with Claude Code
https://claude.ai/code/session_01UpLPXA4aqraDVKB84Gwxi2