Skip to content

apstndb/spannerplanviz

Repository files navigation

spannerplanviz

Cloud Spanner Query Plan Visualizer using goccy/go-graphviz.

query plan

(Possibly) remote calls are rendered as dashed lines.

Install

go install github.com/apstndb/spannerplanviz@latest

Usage

It can read various types in JSON and YAML.

PLAN

$ gcloud spanner databases execute-sql --instance=sampleinstance sampledb --query-mode=PLAN --format=yaml \
  --sql="SELECT SongName FROM Songs WHERE STARTS_WITH(SongName, @prefix)" |
  spannerplanviz --full --type=svg --output plan.svg

PROFILE

You see verbose profile information. (Currently, histogram is not shown.)

$ gcloud spanner databases execute-sql --instance=sampleinstance sampledb --query-mode=PROFILE --format=yaml \
  --sql "SELECT * FROM Singers JOIN Songs USING(SingerId) WHERE SongName LIKE 'Th%e'" |
  spannerplanviz --full --type=svg --output profile.svg

full profile

You can emit Mermaid.js using --type mermaid (EXPERIMENTAL).

spannerplanviz --full --type=mermaid --output profile.mermaid < dca_profile.json

The generated source uses HTML labels and a browser-friendly init block (htmlLabels: true, useMaxWidth: false). See visualize/testdata/dca_profile.golden.mermaid for a full example output.

--type dot emits pure Graphviz DOT source (unlaid-out, no pos/bb layout attributes) via the dot package. Pipe it into dot -Tsvg (or any Graphviz tool) to lay it out:

spannerplanviz --full --type=dot < dca_profile.json | dot -Tsvg -o profile.svg

--type svg and --type png still produce fully laid-out output; they generate the same DOT source internally and render it with the embedded Graphviz runtime.

You can emit D2 source using --type d2 (EXPERIMENTAL). Lay it out with the d2 CLI:

spannerplanviz --full --type=d2 --output profile.d2 < dca_profile.json
d2 profile.d2 profile.svg

Node labels use D2 markdown blocks (|md ... |), tooltips carry the canonical plan YAML in |yaml ... | block strings, possible remote calls are drawn with a dashed stroke, and --show-query/--show-query-stats add a rounded query node linked from the root. See visualize/testdata/dca_profile.golden.d2 for a full example.

Output types

--type Output
svg (default), png Fully laid-out Graphviz raster/vector, rendered with the embedded runtime
dot Unlaid-out Graphviz DOT source; lay out with dot -Tsvg
mermaid Mermaid.js flowchart source
d2 D2 source; lay out with d2 in.d2 out.svg

--show-query and --show-query-stats add a query-text node and are honored by the svg, png, dot, mermaid, and d2 types.

Library usage

Build a diagram model once, then render with the backend of your choice:

stats, rowType, err := spannerplan.ExtractQueryPlan(input)
plan, err := visualize.BuildPlan(rowType, stats, visualize.StructureBuildOptions())
src, err := mermaid.Source(plan)

Presets:

  • visualize.StructureBuildOptions() — operator structure for interactive viewers (lighter than --full)
  • visualize.FullBuildOptions() — same detail level as CLI --full

Renderers:

  • mermaid.Source(plan) — Mermaid.js source using plan.Build
  • mermaid.SourceWithOptions(plan, opts) — override plan.Build at render time (including disabling flags)
  • mermaid.NewRenderer(opts).Render(ctx, w, plan) — streaming render
  • dot.Source(plan) / dot.SourceWithOptions(plan, opts) — DOT source text without a Graphviz runtime (no goccy/go-graphviz dependency); lay it out elsewhere, e.g. with a browser-side Graphviz build. This is the single source of truth for graph construction.
  • d2.Source(plan) / d2.SourceWithOptions(plan, opts)D2 source text; lay it out with the d2 CLI
  • d2.NewRenderer(opts).Render(ctx, w, plan) — streaming render
  • graphviz.NewRenderer(opts).Render(ctx, w, plan) — SVG/PNG via Graphviz; internally generates the dot package's source and hands it to the Graphviz runtime, so both paths describe an identical graph

The dot, mermaid and d2 backends all consume a shared backend-neutral graph model (visualize.BuildGraph), so they describe the same nodes, edges and labels.

Browser embedding

When rendering Mermaid in the browser (for example from Go WASM):

  1. Call visualize.BuildPlan and mermaid.Source(plan).
  2. Pass the returned source to mermaid.js render().
  3. The source includes a %%{ init: ... }%% block with htmlLabels: true and useMaxWidth: false. Keep your global mermaid.initialize() consistent with those settings if you set defaults separately.
  4. Prefer StructureBuildOptions() for large plans; --full output can be slow to lay out in the browser.

BuildOptions fields mirror CLI flags (metadata, execution-stats, hide-metadata, and so on). See option.Options.BuildOptions() for the full mapping.

Stability

  • The spannerplanviz CLI flags and behavior are treated as stable.
  • The Go library API (visualize.BuildPlan, mermaid.Source, graphviz.NewRenderer, dot.Source, and related types) is experimental and may change between releases.
  • This module follows v0 semver: breaking changes may appear in minor releases. See GitHub release notes for details.
  • Text plan rendering moved to spannerplan/cmd/rendertree; the deprecated shim in this repository has been removed.

Disclaimer

This tool is Alpha quality.

About

No description, website, or topics provided.

Resources

License

Stars

42 stars

Watchers

1 watching

Forks

Packages

 
 
 

Contributors

Languages