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#[rustfmt::skip]
56pub mod protobuf;
57mod query;
58mod summary;
59mod summary_result;
60mod truncate;
61
62pub use error::*;
63pub use node_enum::*;
64pub use node_mut::*;
65pub use node_ref::*;
66pub use parse_result::*;
67pub use query::*;
68pub use summary::*;
69pub use summary_result::*;
70pub use truncate::*;
71
72pub use protobuf::Node;
73
74// From Postgres source: src/include/storage/lockdefs.h
75#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
76#[repr(i32)]
77pub enum LockMode {
78 NoLock = 0, // NoLock is not a lock mode, but a flag value meaning "don't get a lock"
79 AccessShareLock = 1, // SELECT
80 RowShareLock = 2, // SELECT FOR UPDATE/FOR SHARE
81 RowExclusiveLock = 3, // INSERT, UPDATE, DELETE
82 ShareUpdateExclusiveLock = 4, // VACUUM (non-FULL), ANALYZE, CREATE INDEX CONCURRENTLY
83 ShareLock = 5, // CREATE INDEX (WITHOUT CONCURRENTLY)
84 ShareRowExclusiveLock = 6, // like EXCLUSIVE MODE, but allows ROW SHARE
85 ExclusiveLock = 7, // blocks ROW SHARE/SELECT...FOR UPDATE
86 AccessExclusiveLock = 8, // ALTER TABLE, DROP TABLE, VACUUM FULL, and unqualified LOCK TABLE
87}
88
89// From Postgres source: src/include/catalog/pg_trigger.h
90#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
91#[repr(i32)]
92pub enum TriggerType {
93 Row = 1,
94 Before = 2,
95 Insert = 4,
96 Delete = 8,
97 Update = 16,
98 Truncate = 32,
99 Instead = 64,
100}