tomato·bazeldocs v0 · latest
Docs/Reference/Modules/pgquery

pgquery

libpg_query's parse tree as Lean 4, plus the C decoder that fills it — the READING side of the leangres AST split. Generated from pg_query.proto; nothing is proven about it by design.

Latest17.6.0
Versions1
CategoryModules & tooling
MaintainersMatt Marshall
Registryhttps://registry.tbzl.dev/modules/pgquery/
Sourcegithub.com/leangres/pgquery
MODULE.bazelstarlark
bazel_dep(name = "pgquery", version = "17.6.0")

View source & releases on GitHub ↗

libpg_query’s parse tree, as Lean 4 — plus the C decoder that fills it.

Postgres’s own parse-node taxonomy, generated from pg_query.proto, with a hand-curated typed layer over the statement shapes that downstream folds care about.

Part of leangres.

Two AST layers, on purpose

leangres has two representations of a Postgres statement and conflating them would be a mistake.

This module is the reading side. Pg.Query.Generated mirrors libpg_query’s protobuf faithfully — complete over Postgres’s grammar, machine-generated, regenerated wholesale on a libpg_query bump. Nothing is proven about it. It exists to get real SQL into Lean.

pgast is the writing side: small, hand-curated, closed, every constructor carrying a printer and a place in an exhaustiveness lock. Deliberately not complete, because completeness would mean carrying grammar corners nobody can state a theorem about.

The bridge between them is where round-trip guarantees live — emit from the typed AST, parse with Postgres’s own parser, ingest here, compare.

Contents

piecewhat
Pg.Query.Generatedproto-derived enums + messages: the full parse-node taxonomy
Pg.Query.Tophand-written typed dispatch — statement shapes with fields pre-decoded from protobuf bytes
//tools/pgpb_to_lean_astthe C decoder: .pgpb → Lean, with --typed emitting Top*Stmt values
//tools/pgpb_codegenregenerates Generated.lean from pg_query.proto

Top.lean carries fields already decoded — a QualifiedName split into schema + name, rather than a raw list of proto String message bytes. That pre-decoding lives in the C tool deliberately, so the Lean side stays simple enough to reason about.

The pipeline

SQL ──sql_to_protobuf──▶ .pgpb ──pgpb_to_lean_ast --typed──▶ Lean ──▶ a fold

sql_to_protobuf comes from rules_postgres; it is the ruleset’s tool, and this module is a consumer of it. CI exercises the whole chain rather than just checking the C compiles.

Dependencies

  • pgcatalogTop.lean imports Pg.Catalog.Tables for ArgMode alone, the proc-param direction enum. That single import is why pgquery sits above pgcatalog in the graph rather than beside it.
  • rules_postgres (non-dev) — the C decoder is built against libpg_query’s protobuf-c bindings and is part of this module’s surface, so the libpg_query dependency is not gated dev-only.

Lean core otherwise. No mathlib, no batteries.

Consuming it

bazel_dep(name = "pgquery", version = "17.6.0")
lean_library(
    name = "my_fold",
    srcs = ["MyFold.lean"],
    deps = ["@pgquery//lean:pgquery"],
)

Published as compiled oleans. .olean is a compacted heap image — neither Lean-version- nor architecture-portable — so pin the same toolchain (leanprover/lean4:v4.30.0-rc2) and select the artifact for your platform.

Versioning

<pg_major>.<pg_minor>.<patch>. This module mirrors pg_query.proto, and libpg_query releases are themselves keyed to a Postgres major (17-6.2.2), so the version tracks the Postgres release modelled.

⚠ A convention, not an enforced constraint. compatibility_level was the mechanism that would have made bzlmod refuse a build mixing Postgres majors, and Bazel 9 made it a no-op. See pgcatalog’s MODULE.bazel for the two candidate enforcement mechanisms, neither built yet.

Provenance

Carved from tomato-bazel/rules_postgres with git filter-repo, history preserved. Commit hashes quoted in those messages may refer to commits that were filtered out.

License

MIT.

Conformance#

No gate findings. 8 contested atoms. See how gating works or the full report.

Contested atoms

Third-party modules where this module resolves a different version than others do. Not a violation of anything this module did — it is the actionable form of a registry-level convergence finding, and the sentence a maintainer can act on.

AtomResolved hereElsewhere
apple_support 1.24.2 2.2.0 ×1
bazel_skylib 1.8.2 1.9.0 ×2
nlohmann_json 3.6.1 3.12.0.bcr.1 ×1
protobuf 33.4 34.0.bcr.1 ×2
rules_jvm_external 6.7 6.8 ×4
rules_python 1.7.0 2.0.1 ×1
rules_swift 3.1.2 3.6.1 ×1
upb 0.0.0-20220923-a547704 0.0.0-20230516-61a97ef ×1

Dependencies#

pgquery in the registry graph — what it depends on (left) and what depends on it (right).

Depends on

Used by (1 in the registry)

Versions#

1 published version, newest first. Each resolves to an immutable, integrity-checked archive.

VersionIntegrity (sha256)Source archive
17.6.0 latest Rbv0lKEoBDlyLcxo… tag archive ↗

Changelog#

17.6.0 — carved out of rules_postgres

Pg.Query.* plus the two codegen/decode tools, extracted from tomato-bazel/rules_postgres with git filter-repo, history preserved (11 commits). 9 files, each verified byte-identical to source by sha256.

Its own module because it regenerates on a different clock. Generated.lean is machine-generated from pg_query.proto and rewritten wholesale when libpg_query bumps; the hand-curated AST above it is edited daily. rules_lean compiles a whole library in one action, so sharing a module would recompile this on every AST edit.

//tools:sql_to_protobuf repointed to @rules_postgres//tools:sql_to_protobuf. The genrule that builds the decoder’s smoke fixture referenced an in-repo //tools package that belongs to the ruleset, not to this module. It is rules_postgres’s tool and pgquery is a consumer of it.

Depends on pgcatalog for one enum. Top.lean imports Pg.Catalog.Tables solely for ArgMode. That single import is why pgquery sits above pgcatalog rather than beside it.

Ships compiled, and CI exercises the decoder chain — SQL through sql_to_protobuf, .pgpb through pgpb_to_lean_ast --typed, out as Lean — rather than only checking that the C compiles.

Requires rules_lean 0.6.1: earlier releases’ lean_olean_archive fails on linux.

← All modules