Problem
The current renderers are optimized for terminal/table output. plantree.ProcessPlan returns rows that are useful for ASCII rendering, but richer web UIs would benefit from a structured tree representation that does not require reverse-parsing rendered prefixes or table text.
Proposed design
Add an additive public API in plantree that exposes the visible relational plan tree as machine-readable data before ASCII row rendering.
Suggested type shape:
type PlanTreeNode struct {
ID int32 `json:"id"`
Text string `json:"text"`
LinkType string `json:"linkType,omitempty"`
Predicates []PlanTreePredicate `json:"predicates,omitempty"`
ScalarLinks map[string][]ScalarLink `json:"scalarLinks,omitempty"`
ExecutionStats stats.ExecutionStats `json:"executionStats,omitempty"`
Children []*PlanTreeNode `json:"children,omitempty"`
}
type PlanTreePredicate struct {
Type string `json:"type"`
Description string `json:"description"`
NodeID int32 `json:"nodeId"`
}
type ScalarLink struct {
Type string `json:"type,omitempty"`
Variable string `json:"variable,omitempty"`
NodeID int32 `json:"nodeId"`
Description string `json:"description"`
}
Add a public builder:
func ProcessPlanTree(qp *spannerplan.QueryPlan, opts ...Option) (*PlanTreeNode, error)
The function should use the same title formatting options as ProcessPlan, including WithQueryPlanOptions and EnableCompact, but it should not apply line wrapping or table rendering. Wrapping remains a renderer concern.
Semantics
- Only visible relational nodes should appear as
Children, matching ProcessPlan traversal.
- Predicate function nodes should be represented in
Predicates on their parent row/node, not as visible children.
- Scalar child links should be represented in
ScalarLinks, with enough information for UIs to display parameters without protobuf traversal.
Text should be the unwrapped node title including node-local link prefixes such as [Input] and [Map] when applicable.
LinkType should expose the link type separately so UIs do not have to parse [Input] out of Text.
Implementation notes
There is already an internal renderedNode tree used before ASCII rendering. The implementation can either:
- convert that internal tree into the public
PlanTreeNode shape, or
- refactor the builder to produce the public structure first and derive render rows from it.
The first option is likely safer for an initial PR because it avoids broad renderer churn.
Tests
Add tests covering:
- a small plan with input/map children keeps tree structure
- predicates are attached to the expected node
- scalar child links are exposed in
ScalarLinks
- formatting options affect
Text consistently with ProcessPlan
Documentation
Document this as the preferred API for web UIs or other consumers that need structured data rather than rendered ASCII.
Notes
This should be additive and can coexist with RowWithPredicates and ProcessPlan.
Problem
The current renderers are optimized for terminal/table output.
plantree.ProcessPlanreturns rows that are useful for ASCII rendering, but richer web UIs would benefit from a structured tree representation that does not require reverse-parsing rendered prefixes or table text.Proposed design
Add an additive public API in
plantreethat exposes the visible relational plan tree as machine-readable data before ASCII row rendering.Suggested type shape:
Add a public builder:
The function should use the same title formatting options as
ProcessPlan, includingWithQueryPlanOptionsandEnableCompact, but it should not apply line wrapping or table rendering. Wrapping remains a renderer concern.Semantics
Children, matchingProcessPlantraversal.Predicateson their parent row/node, not as visible children.ScalarLinks, with enough information for UIs to display parameters without protobuf traversal.Textshould be the unwrapped node title including node-local link prefixes such as[Input]and[Map]when applicable.LinkTypeshould expose the link type separately so UIs do not have to parse[Input]out ofText.Implementation notes
There is already an internal
renderedNodetree used before ASCII rendering. The implementation can either:PlanTreeNodeshape, orThe first option is likely safer for an initial PR because it avoids broad renderer churn.
Tests
Add tests covering:
ScalarLinksTextconsistently withProcessPlanDocumentation
Document this as the preferred API for web UIs or other consumers that need structured data rather than rendered ASCII.
Notes
This should be additive and can coexist with
RowWithPredicatesandProcessPlan.