Skip to content

Explain: let plugin drivers return raw explain output parsed by @tabularis/explain (SQL Server SHOWPLAN) #2

Closed

Description

@debba

Context

For built-in drivers, explain_query returns ExplainQueryOutput::Raw { raw: RawExplainOutput } — a payload plus a format tag — and the parsing lives in the @tabularis/explain TypeScript package (parseRawExplain).

For plugin drivers, the host wraps the JSON-RPC result as ExplainQueryOutput::Plan { plan } and passes it to the frontend untouched (src-tauri/src/plugins/driver.rs). A plugin must therefore ship its own parser and emit the visual-plan model directly: the SQL Server plugin currently parses SHOWPLAN_XML in Rust (src/driver/showplan.rs) and returns the parsed tree.

Goal

Make plugin explain output flow through @tabularis/explain the same way built-in drivers do:

  1. Add the SQL Server SHOWPLAN XML parser to @tabularis/explain (a complete implementation already exists in PR feat(sqlserver): add built-in SQL Server driver tabularis#560: packages/explain/src/parsers/sqlserver.ts + tests, format tag sqlserver-showplan-xml).
  2. Extend the plugin protocol so a plugin's explain_query can return a RawExplainOutput-shaped result ({ engine, format, payload, original_query }) that the host forwards as ExplainQueryOutput::Raw, letting parseRawExplain handle it in the frontend. Plugins that already return a parsed plan keep working (Plan pass-through stays the fallback).
  3. Switch the SQL Server plugin to return the raw XML and drop its in-process parser.

Why

  • One parser, one place: plan-rendering fixes and new metrics land in @tabularis/explain without re-releasing plugins.
  • explain.tabularis.dev consumes @tabularis/explain, so it gains direct SQL Server compatibility — paste a SHOWPLAN_XML document and get the visual plan, with no plugin involved.
  • Keeps plugins thin: they hand over what the engine produced, tagged with its format, exactly like built-in drivers.

Notes

  • The parser from PR feat(sqlserver): add built-in SQL Server driver tabularis#560 sums per-thread ActualRows/ActualExecutions and takes the max ActualElapsedms from RunTimeInformation, so STATISTICS XML (Analyze) is covered too.
  • Registry/versioning: the manifest could declare an explain_format (or the result itself is self-describing via the format tag) so older hosts keep treating plugin results as pre-parsed plans.

Activity

  1. debba commented on Aug 30, 2026

    @debba
    ContributorAuthor

    SS-030 has frozen the implementation contract for this work after checking the current core and plugin code. The contract will live at docs/explain-architecture.md.

    The agreed design differs from the issue's original proposal in one important way: SQL Server parsing does not move into @tabularis/explain. The plugin remains its owner and keeps one TypeScript parser source, built as:

    • an IIFE (explain/dist/index.iife.js) shipped in the plugin archive and registered into the desktop's new engine-neutral @tabularis/explain registry; and
    • the ESM package @tabularis/explain-sqlserver, imported by explain.tabularis.dev.

    Core gains the registry seam, structural raw-plugin output support, manifest plumbing and an isolated bundle loader, but no SQL Server parser. That lets third-party plugins use the same mechanism without a core release and lets the standalone site consume the identical parser without a plugin process.

    The verification pass also corrected details from the initial design: raw.ts and parsers/source.ts currently have separate dispatch tables; opening formats also requires opening source engine/format types; an acyclic built-in registry needs a leaf parsers/builtins.ts module; the IIFE and ESM outputs need distinct filenames and entry points to avoid double registration; the runtime and Tabularium manifest schemas both need the field; and the current Rust/PR #560 parser stores subtree cost directly and does not use AvgRowSize or subtract child cost.

    The contract now specifies exact unknown-format errors, deterministic replacement with one warning, unload/restoration behavior, structural RawExplainOutput detection, bundle-failure isolation, parser semantics, real SQL Server fixture coverage and the runtime-version floor required when the plugin switches to raw XML.

  2. debba commented on Sep 2, 2026

    @debba
    ContributorAuthor

    The implementation is complete on the release-candidate branches:

    The plugin now returns sqlserver-showplan-xml, declares explain/dist/index.iife.js, and requires the intended compatible host floor, Tabularis 0.23.0. The same parser source builds @tabularis/explain-sqlserver for the standalone site.

    I am leaving this issue open because none of those cross-repository PRs has shipped yet, @tabularis/explain 0.2.0 and @tabularis/explain-sqlserver are not published, and the site change is not deployed. Closing it now would provide the requested links to artifacts that do not exist. Publication and the final close-with-shipped-links step are tracked in #4.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions