pg_query.rs

This Rust library uses the actual PostgreSQL server source to parse SQL queries and return the internal PostgreSQL parse tree.
It also allows you to normalize queries (replacing constant values with $1, etc.) and parse these normalized queries into a parse tree again.
When you build this library, it builds parts of the PostgreSQL server source (see libpg_query), and then statically links it into this library.
You can find further examples and a longer rationale for the original Ruby implementation here. The Rust version tries to have a very similar API.
Getting started
Add the following to your Cargo.toml
[]
= "6.1"
Examples
Parsing a query
use NodeRef;
let result = parse;
assert!;
let result = result.unwrap;
assert_eq!;
assert!;
Normalizing a query
let result = normalize.unwrap;
assert_eq!;
Fingerprinting a query
let result = fingerprint.unwrap;
assert_eq!;
Truncating a query
let query = "INSERT INTO \"x\" (a, b, c, d, e, f) VALUES (?)";
let result = parse.unwrap;
assert_eq!;
Credits
Thanks to Paul Mason for his work on pg_parse that this crate is based on.
After version 0.6.0, Paul donated the pg_query crate to the pganalyze team. pg_parse is a lighter alternative that focuses on query parsing, while pg_query aims for feature parity with the Ruby gem.
License
PostgreSQL server source code, used under the PostgreSQL license. Portions Copyright (c) 1996-2023, The PostgreSQL Global Development Group Portions Copyright (c) 1994, The Regents of the University of California
All other parts are licensed under the MIT license, see LICENSE file for details. Copyright (c) 2021 Paul Mason paul@form1.co.nz Copyright (c) 2021-2023, Duboce Labs, Inc. (pganalyze) team@pganalyze.com
PL/pgSQL catalog types
parse_plpgsql_with_catalog accepts an immutable PlpgsqlCatalog snapshot containing namespace OIDs, the effective type search path, and PlpgsqlType metadata. It distinguishes domain and other scalar declarations from composite records, preserving variable defaults and constraints. Catalog-aware PLpgSQL_type nodes include the resolved typoid, so callers can bind quoted types and domain arrays without re-resolving display names. The ordinary parse_plpgsql entry point retains its catalog-free behavior. Catalog pointers remain local to the synchronous parse; independent snapshots can be used concurrently.
Protobuf decode frames
The generated PostgreSQL Node oneof keeps each message variant's construction in a separate function frame so debug WebAssembly decoding does not accumulate temporaries for all 271 alternatives in every recursive call. Regeneration applies the same deterministic transformation. Tags, payload types, encoding and decoding primitives remain those generated by Prost. An existing variant merges in place; a different variant replaces the field only after successful decoding, preserving partial-failure state, input consumption, diagnostics and the original recursion limit. Unit tests compare these observations against an independently derived Prost oneof, including boxed payloads, repeated fields, variant switches, unknown fields and truncated inputs.