Skip to content

Latest commit

 

History

History
108 lines (80 loc) · 4.1 KB

File metadata and controls

108 lines (80 loc) · 4.1 KB

Claude Development Guide

Next Steps

To find the next parser test case to work on (files closest to fully passing first), run from the repository root:

go run ./cmd/next-test

This prints the case's SQL, the expected parse tree, and overall progress.

Running Tests

Always run parser tests with a 60 second timeout:

go test ./... -timeout 60s

The tests are fast. If a test times out, it almost certainly indicates an infinite loop in the parser.

Checking for Newly Passing Cases

IMPORTANT: After implementing parser/dump changes, ALWAYS run check-parse to update metadata files:

go test ./parser -check-parse -v 2>&1 | grep "PARSE PASSES NOW"

This command:

  1. Runs all cases listed in parse_todo in the metadata files
  2. Automatically removes now-passing cases from parse_todo
  3. Reports which cases now pass

You must run this after every change to parser, lexer, ast, or dump code, then commit the updated .metadata.json files along with your code changes.

Test Structure

parser/testdata/*.test files are vendored unmodified from google/googlesql release 2026.01.1 (googlesql/parser/testdata/). Each file contains cases separated by == lines; each case has the SQL input, the expected parse tree (or ERROR: message), and the expected unparse output, separated by -- lines. See internal/testfile for the format parser.

Each <name>.metadata.json sidecar (ours, not vendored) tracks:

  • parse_todo — cases whose output doesn't match yet. Keys are case_N for ordinary cases and case_N.alt_K for the K-th expansion of an alternation case ({{a|b}} groups; see below).
  • alternations — alternation cases the harness cannot confidently expand and therefore skips entirely (currently none; kept for safety). Expandable alternation cases are tracked per-expansion in parse_todo instead.
  • skip — reason string to skip the whole file

A .test file with no sidecar passes completely.

Alternation Groups

Cases whose SQL or option lines contain {{a|b|c}} groups expand into the cartesian product of the groups' alternatives (last group varies fastest), matching file_based_test_driver. internal/testfile substitutes each combination and matches it to its expected parse tree by the driver's ALTERNATION GROUP label; each expansion runs as its own sub-test (case_N/alt_K) with independent parse_todo tracking. Byte offsets in an expansion's expected tree are relative to that expansion's substituted SQL. Regenerate per-expansion todos the same way as ordinary cases, with go test ./parser -check-parse (it re-triages every expansion, harvesting ones that now pass and recording ones that still fail).

Important Rules

  • NEVER modify .test files — they are vendored golden files from the reference implementation. If output doesn't match, fix the Go code.
  • NEVER hand-edit expected output into metadata — metadata only marks what is not implemented yet.
  • The dump format must match ZetaSQL's ASTNode::DebugString (googlesql/parser/parse_tree.cc) byte-for-byte, including the summarized source text (see GetSummaryString in googlesql/common/utf_util.cc, ported in internal/dump).
  • Parse error output must match ZetaSQL's error format: Syntax error: <message> [at line:col] plus the source line and a caret.
  • When porting logic or tables (keywords, precedence) from googlesql source, keep the attribution note in the file header. GoogleSQL is Apache 2.0.

Reference Implementation

The grammar and AST are defined in google/googlesql:

  • googlesql/parser/parse_tree.h — AST node definitions and details
  • googlesql/parser/parse_tree.ccSingleNodeDebugString per-node output
  • googlesql/parser/keywords.cc — keyword and reserved word tables
  • googlesql/parser/*.tm / grammar files — syntax reference

For new test queries, golden output comes from the prebuilt reference binary (pinned in cmd/regenerate-parse/main.go, must match the vendored testdata release):

go run ./cmd/regenerate-parse -sql "select 1 + 2"