Skip to main content

pg_query/
lib.rs

1//! Rust pg_query   [![Build Status]][actions] [![Latest Version]][crates.io] [![Docs Badge]][docs]
2//! ===========
3//!
4//! [Build Status]: https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2Fpganalyze%2Fpg_query.rs%2Fbadge%3Fref%3Dmain&style=flat&label=build&logo=none
5//! [actions]: https://actions-badge.atrox.dev/pganalyze/pg_query.rs/goto?ref=main
6//! [Latest Version]: https://img.shields.io/crates/v/pg_query.svg
7//! [crates.io]: https://crates.io/crates/pg_query
8//! [Docs Badge]: https://docs.rs/pg_query/badge.svg
9//! [docs]: https://docs.rs/pg_query
10//!
11//! This Rust library uses the actual PostgreSQL server source to parse SQL queries and return the internal PostgreSQL parse tree.
12//!
13//! It also allows you to normalize queries (replacing constant values with $1, etc.) and parse these normalized queries into a parse tree again.
14//!
15//! When you build this library, it builds parts of the PostgreSQL server source (see [libpg_query](https://github.com/pganalyze/libpg_query)), and then statically links it into this library.
16//!
17//! You can find further examples and a longer rationale for the original Ruby implementation [here](https://pganalyze.com/blog/parse-postgresql-queries-in-ruby.html). The Rust version tries to have a very similar API.
18//!
19//! ## Getting started
20//!
21//! Add the following to your `Cargo.toml`
22//!
23//! ```toml
24//! [dependencies]
25//! pg_query = "6.1"
26//! ```
27//!
28//! # Example: Parsing a query
29//!
30//! ```rust
31//! use pg_query::NodeRef;
32//!
33//! let result = pg_query::parse("SELECT * FROM contacts");
34//! assert!(result.is_ok());
35//! let result = result.unwrap();
36//! assert_eq!(result.tables(), vec!["contacts"]);
37//! assert!(matches!(result.protobuf.nodes()[0].0, NodeRef::SelectStmt(_)));
38//! ```
39//!
40
41mod bindings;
42mod error;
43mod node_enum;
44mod node_mut;
45mod node_ref;
46mod node_structs;
47mod parse_result;
48mod plpgsql_catalog;
49pub use plpgsql_catalog::{
50    parse_plpgsql_with_catalog, parse_plpgsql_with_mode, parse_plpgsql_with_options,
51    PlpgsqlCatalog, PlpgsqlCompileMode, PlpgsqlType,
52};
53mod parse_options;
54pub use parse_options::{parse_with_options, Diagnostic, ParseOptions, ParseOutcome};
55#[macro_use]
56mod protobuf_oneof;
57#[rustfmt::skip]
58pub mod protobuf;
59mod query;
60mod summary;
61mod summary_result;
62mod truncate;
63
64pub use error::*;
65pub use node_enum::*;
66pub use node_mut::*;
67pub use node_ref::*;
68pub use parse_result::*;
69pub use query::*;
70pub use summary::*;
71pub use summary_result::*;
72pub use truncate::*;
73
74pub use protobuf::Node;
75
76// From Postgres source: src/include/storage/lockdefs.h
77#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
78#[repr(i32)]
79pub enum LockMode {
80    NoLock = 0, // NoLock is not a lock mode, but a flag value meaning "don't get a lock"
81    AccessShareLock = 1, // SELECT
82    RowShareLock = 2, // SELECT FOR UPDATE/FOR SHARE
83    RowExclusiveLock = 3, // INSERT, UPDATE, DELETE
84    ShareUpdateExclusiveLock = 4, // VACUUM (non-FULL), ANALYZE, CREATE INDEX CONCURRENTLY
85    ShareLock = 5, // CREATE INDEX (WITHOUT CONCURRENTLY)
86    ShareRowExclusiveLock = 6, // like EXCLUSIVE MODE, but allows ROW SHARE
87    ExclusiveLock = 7, // blocks ROW SHARE/SELECT...FOR UPDATE
88    AccessExclusiveLock = 8, // ALTER TABLE, DROP TABLE, VACUUM FULL, and unqualified LOCK TABLE
89}
90
91// From Postgres source: src/include/catalog/pg_trigger.h
92#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
93#[repr(i32)]
94pub enum TriggerType {
95    Row = 1,
96    Before = 2,
97    Insert = 4,
98    Delete = 8,
99    Update = 16,
100    Truncate = 32,
101    Instead = 64,
102}