Milestone 4: expressions + SELECT — parser, JSON emitter, ParseToJSON - #4
Merged
Conversation
internal/emit: JSON emitter with byte-parity to the pinned pg_query_outfuncs_json.c, driven by the protobuf descriptor (field order = C struct order, json_name = C field name) plus the reference's hand-written special cases. Validated by round-tripping all 42,970 corpus tree goldens byte-identically (TestGoldenRoundTrip). internal/parse: hand-written recursive-descent port of the pinned gram.y's expression and SELECT regions, one parse* method per production with attribution comments: - a_expr/b_expr/c_expr precedence climbing mirroring bison's resolution (left-assoc right-operand level, %nonassoc chain errors, %prec at the annotated sites, subquery_Op entry-vs-reduce precedence). - Constants and const typecasts (AexprConst incl. func_name Sconst/PARAM and ConstTypename/ConstInterval forms), the full Typename families. - func_expr: func_application (named args, VARIADIC, DISTINCT, agg star), WITHIN GROUP / FILTER / OVER, window specifications and frames, the func_expr_common_subexpr set (CAST/EXTRACT/OVERLAY/POSITION/SUBSTRING/ TRIM/TREAT/NULLIF/COALESCE/GREATEST/LEAST, SQL value functions, xml*, SQL/JSON constructors, query functions and aggregates, MERGE_ACTION). - SELECT end-to-end: target list with bare-label aliases, FROM with joins (bison-faithful nesting), LATERAL, function tables and ROWS FROM, TABLESAMPLE, XMLTABLE, JSON_TABLE (incl. NESTED paths), sub-selects, DISTINCT [ON], GROUP BY incl. grouping sets, HAVING, WINDOW, set operations, WITH/CTEs (MATERIALIZED, SEARCH/CYCLE), VALUES, ORDER BY, LIMIT/OFFSET/FETCH (WITH TIES), FOR locking clauses, SELECT INTO. - Grammar errors report through the C error stack's path (scanner_yyerror data, character cursor positions); gram.y action ereports carry their original funcname and positions. Parse/ParseToProtobuf/ParseToJSON are live; pg_query_go's ported parse tests now run for the implemented statement types. Corpus: 16,300+ parse cases harvested off the todo list. Remaining parse todos all start with or embed milestone-5-7 statement types. cmd/difftest ships the interim -summary/-show failure classifier that drove the milestone (mutation fuzzing arrives in milestone 12). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01543SdbotP1DX2XRMvfCHn5
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.
Implements milestone 4 of PLAN.md: the
a_expr/b_expr/c_exprprecedence machinery andSELECTend-to-end, plus the JSON emitter that makesParseToJSON(and therefore the parse corpus) verifiable.JSON emitter (
internal/emit)Byte-parity with the pinned
pg_query_outfuncs_json.c+pg_query_json_helper.c, driven by the protobuf descriptor rather than generated per-node code — the pinned proto was itself generated from the C struct metadata, so field declaration order (= C struct order),json_name(= C field name), and field kinds already encode the format. The reference's hand-written special cases are ported directly:A_Const's union wrapping, the five value nodes, theListvariants,_outToken's exact escape set (</>, control bytes, NUL truncation), and the two always-emitted empty-string fields.Validation:
TestGoldenRoundTripprotojson-decodes all 42,970 corpus tree goldens and re-emits every one byte-identically — this covers every node type in the corpus, including statement types the parser won't build until milestones 5–7. Generated per-node emitters remain an option for milestone 12 if profiling wants them.Parser (
internal/parse)Hand-written recursive descent over the pinned
gram.y's expression and SELECT regions, oneparse*method per production with attribution comments;gram.y's support functions live ingram_support.gounder their C names.%nonassoclevels error when chained within one climb,%precannotations are reproduced at their annotated sites.a_expr subquery_Op sub_typeenters the loop at the operator token's own precedence but reduces at%prec Op(so1 = 2 = ANY(...)fails at the second=while= ANY(...) + 1binds the+outside). Qual-requiring JOINs absorb further joins into their right operand (bison shifts because the rule can't reduce until itsjoin_qual); CROSS/NATURAL joins stay left-associative.AexprConstincl.func_name Sconst/PARAMandConstTypename/ConstIntervalforms), the fullTypenamefamilies, indirection/slices, CASE, rows andOVERLAPS, arrays, sublinks,ISforms incl. SQL/JSON predicates.func_application(named args,VARIADIC,DISTINCT, agg star),WITHIN GROUP/FILTER/OVER, window specifications and frames, and thefunc_expr_common_subexprset —CAST/EXTRACT/OVERLAY/POSITION/SUBSTRING/TRIM/TREAT/NULLIF/COALESCE/GREATEST/LEAST, SQL value functions,xml*, SQL/JSON constructors, query functions and aggregates,MERGE_ACTION.LATERAL/function tables/ROWS FROM/TABLESAMPLE/XMLTABLE/JSON_TABLE(incl.NESTEDpaths),DISTINCT [ON],GROUP BYincl. grouping sets,HAVING,WINDOW, set operations, CTEs (MATERIALIZED,SEARCH/CYCLE),VALUES,ORDER BY,LIMIT/OFFSET/FETCH(WITH TIES),FORlocking clauses,SELECT INTO.base_yyerror→parser_yyerror→scanner_yyerror), so messages carryscan.lerror data, character-based cursor positions, and merged tokens (NOT_LAetc.) report only their first word;gram.yaction ereports keep their original funcname and positions.Wiring and corpus
Parse,ParseToProtobuf, andParseToJSONare live; pg_query_go's ported parse tests now run for the implemented statement types.cmd/difftestships the interim-summary/-showfailure classifier that drove the milestone (mutation fuzzing replaces it in milestone 12).go build ./...andgo test -race ./...are green; the main module remains cgo-free withgoogle.golang.org/protobufas its only dependency.🤖 Generated with Claude Code
https://claude.ai/code/session_01543SdbotP1DX2XRMvfCHn5
Generated by Claude Code