chore: adopt released protoyaml for SHOW PLAN NODE canonical output#784
Conversation
Migrate SHOW PLAN NODE from spannerplan/protoyaml to the released github.com/apstndb/protoyaml v0.1.0 (canonical protojson-over-YAML). The previous marshaling relied on ~50 lines of custom goccy/go-yaml marshalers that emitted an accidental proto-reflection dialect (snake_case field names, numeric enums). protoyaml.Marshal with WithFlowLeafCollections now produces canonical protojson field naming (camelCase, named enums) matching gcloud and the official query plan visualizer, while keeping the identical layout (compact flow for all-scalar sub-maps). structpb data keys (execution_stats contents etc.) are unchanged. github.com/apstndb/spannerplan stays; only the protoyaml subpackage import moves to the standalone module. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Du9UR1LPdSXk4wAZr4Nf4g
There was a problem hiding this comment.
Code Review
This pull request replaces the internal protoyaml package and custom YAML marshaling logic with the external github.com/apstndb/protoyaml library. This simplifies statements_explain_describe.go by removing several custom marshaling helper functions. The test cases in statements_explain_describe_test.go have been updated to match the new YAML output format, which uses camelCase keys and string representations for enums. I have no additional feedback to provide as the changes are clean and the tests have been appropriately updated.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
Code Metrics Report📊 View detailed coverage report (available for 7 days)
Details | | main (53bd54f) | #784 (d97b778) | +/- |
|---------------------|----------------|----------------|-------|
- | Coverage | 73.2% | 73.1% | -0.1% |
| Files | 93 | 93 | 0 |
| Lines | 7933 | 7917 | -16 |
- | Covered | 5808 | 5794 | -14 |
+ | Code to Test Ratio | 1:1.3 | 1:1.3 | +0.0 |
| Code | 18517 | 18472 | -45 |
| Test | 25146 | 25146 | 0 |
- | Test Execution Time | 1m57s | 2m1s | +4s |Code coverage of files in pull request scope (63.2% → 61.7%)
Reported by octocov |
PR #784 changed SHOW PLAN NODE output from the accidental reflection YAML dialect (snake_case proto field names, numeric enums) to canonical protojson-over-YAML (camelCase field names, named enums). The example in docs/query_plan.md still showed the old dialect. Apply the same transformation to the documented node-18 dump: - kind: 1 -> kind: RELATIONAL - display_name -> displayName, child_links -> childLinks, child_index -> childIndex, execution_stats -> executionStats Keys inside metadata/executionStats children (execution_method, cpu_time, scan_method, ...) are plan data and remain unchanged; the executionStats and childLinks block containers, scanned_rows/histogram nesting, and root block style are unchanged. The unchanged metadata line remains the widest content, so the CLI table frame stays 99 columns wide; only the shrunk lines were re-padded to keep the box aligned. Claude-Session: https://claude.ai/code/session_01Du9UR1LPdSXk4wAZr4Nf4g Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Summary
Migrates
SHOW PLAN NODEfrom the in-treespannerplan/protoyamlmarshalers to the released standalone modulegithub.com/apstndb/protoyamlv0.1.0 (canonical protojson-over-YAML).github.com/apstndb/spannerplanstays as a dependency; only theprotoyamlsubpackage import moves to the standalone module.What changes for users
SHOW PLAN NODEoutput switches dialect from an accidental proto-reflection format (snake_case proto field names, numeric enums) to canonical protojson-over-YAML (camelCase, named enums) — matching the field names used ingcloudoutput and the official query plan visualizer JSON.The layout is identical: all-scalar sub-maps still render as compact flow (
{...}) viaprotoyaml.WithFlowLeafCollections(). Root-level scalar-only nodes stay as block documents (e.g.index: 1\nkind: RELATIONAL\ndisplayName: Child\n), not inline flow.structpbdata keys (the contents ofexecution_stats,metadata, etc.) are unchanged — those come from the plan payload, not proto field names.Before / after
Before (proto-reflection dialect):
After (canonical protojson-over-YAML):
Note how the proto field names change (
display_name->displayName,kind: 1->kind: RELATIONAL) while the structpb-sourcedmetadata/execution_statsdata keys stay as-is.Implementation
go get github.com/apstndb/protoyaml@v0.1.0 && go mod tidy.github.com/apstndb/spannerplan/protoyaml->github.com/apstndb/protoyaml.protoyaml.Marshal(planNode, protoyaml.WithFlowLeafCollections()).goccy/go-yamlmarshalers (getGlobalOpts,getStructOpts,hasCompound) and now-unused imports.TestShowPlanNodeStatement_Executegolden strings to the canonical output.Net: 13 insertions, 59 deletions.
Validation
go build ./...,go vet ./...clean.make checkgreen (test + lint + fmt-check;golangci-lint0 issues, formatting correct).🤖 Generated with Claude Code
https://claude.ai/code/session_01Du9UR1LPdSXk4wAZr4Nf4g