Skip to content

Parse Spanner-only DDL under a new SPANNER_DDL feature - #2

Merged
kyleconroy merged 1 commit into
mainfrom
claude/charming-keller-wy9qp3
Oct 14, 2026
Merged

kyleconroy merged 1 commit into
mainfrom
claude/charming-keller-wy9qp3

Conversation

@kyleconroy

Copy link
Copy Markdown
Contributor

Summary

Adds SPANNER_DDL, a zetajones-only language feature (not a GoogleSQL LanguageFeature, not in MAXIMUM) that parses the Cloud Spanner syntax the reference parser rejects — all 150 statements in parser/testdata/spanner/**/*.spanner.sql. Vendored test behavior is unchanged.

Reference nodes reused where Spanner has a GoogleSQL equivalent

  • , ROW DELETION POLICY (...) / , OPTIONS (...) after PRIMARY KEY → TtlClause / OptionsList, identical to the reference's comma-less form (verified against the reference binary, offsets aside)
  • , INTERLEAVE IN t (no PARENT) → SpannerInterleaveClause
  • NOT NULL before DEFAULT/AS → attribute list after the default/generated child, as in SpannerAlterColumnAction; non-stored ALTER COLUMN ... AS (...)
  • ARRAY<FLOAT32>(vector_length=>N) → NamedArgument in TypeParameterList
  • ROLE / PLACEMENT become generic entity types, SYNONYM a generic sub-entity type
  • Dashed database ids; trailing comma in OPTIONS
  • Search/vector index ORDER BY / WHERE → OrderBy / WhereClause

New nodes (ast/spanner.go, dump in internal/dump/spanner.go)

GRANT/REVOKE … TO/FROM ROLE and GRANT ROLE, change streams, proto bundles, queues, ALTER LOCALITY GROUP, identity SKIP RANGE / START COUNTER WITH / ALTER IDENTITY, PLACEMENT KEY, AUTO_INCREMENT, ON UPDATE, table synonyms, ALTER INDEX ADD/DROP STORED COLUMN. DROP CHANGE STREAM / DROP LOCALITY GROUP use DropStatement; RENAME TABLE accepts further pairs.

Reference syntax also implemented

CREATE LOCALITY GROUP (FEATURE_CREATE_LOCALITY_GROUP) and the CREATE TABLE ttl_clause. The corpus generator now enables +TTL,+CREATE_LOCALITY_GROUP, turning 8 former backlog statements into golden cases. Two backlog entries missing a semicolon in the docs are reclassified as typo. Regeneration rewrites the feature line in the generated .test files and drops the empty {} sidecars.

Note

ParseStatement and friends (nil features = everything enabled) now accept Spanner syntax by default.

Tests

  • TestSpannerOnlySyntax: every backlog statement parses with SPANNER_DDL and fails without it (ids checked against the SQL hash to catch format drift)
  • 79 hand-reviewed expected trees in parser/testdata/extensions/spanner/, run by TestParser as extensions/..., including feature-off errors
  • Fuzz target now also runs with SPANNER_DDL (~2M execs, no crashes)
  • go test ./... -timeout 60s and -check-parse clean

🤖 Generated with Claude Code

https://claude.ai/code/session_01FTpNRheE3PdSX5XftfH7Nq


Generated by Claude Code

Add SPANNER_DDL, a zetajones-only feature (not in MAXIMUM) that parses
the Cloud Spanner syntax the GoogleSQL reference parser rejects: all 150
statements in parser/testdata/spanner/**/*.spanner.sql.

Reference nodes are reused where Spanner has a GoogleSQL equivalent:
- ", ROW DELETION POLICY (...)" / ", OPTIONS (...)" after PRIMARY KEY
  produce TtlClause / OptionsList, as without the comma;
  ", INTERLEAVE IN t" is a SpannerInterleaveClause
- NOT NULL before DEFAULT/AS joins the attribute list after it, as in
  SpannerAlterColumnAction; non-stored ALTER COLUMN AS (...)
- ARRAY<FLOAT32>(vector_length=>N) is a NamedArgument type parameter
- ROLE and PLACEMENT become generic entity types, SYNONYM a generic
  sub-entity type; dashed database ids; trailing comma in OPTIONS
- search/vector index ORDER BY and WHERE reuse OrderBy and WhereClause

New nodes (ast/spanner.go) cover GRANT/REVOKE ... TO/FROM ROLE and
GRANT ROLE, change streams, proto bundles, queues, ALTER LOCALITY GROUP,
identity SKIP RANGE / START COUNTER WITH / ALTER IDENTITY, PLACEMENT
KEY, AUTO_INCREMENT, ON UPDATE, table synonyms and ALTER INDEX
ADD/DROP STORED COLUMN. DROP CHANGE STREAM / LOCALITY GROUP use
DropStatement, and RENAME TABLE takes further pairs.

Also implement the reference's CREATE LOCALITY GROUP
(FEATURE_CREATE_LOCALITY_GROUP) and CREATE TABLE ttl_clause. The corpus
generator now enables +TTL,+CREATE_LOCALITY_GROUP, which turns 8 former
backlog statements into golden cases. Two backlog entries missing a
semicolon in the docs are reclassified as typos.

Tests: TestSpannerOnlySyntax checks that every backlog statement parses
with SPANNER_DDL and fails without it; hand-reviewed expected trees live
in parser/testdata/extensions/spanner (79 cases, run by TestParser); the
fuzz target now also runs with SPANNER_DDL.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FTpNRheE3PdSX5XftfH7Nq
@kyleconroy
kyleconroy merged commit 5906960 into main Oct 14, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants