Metadata-Version: 2.4
Name: postgast
Version: 0.0.3
Summary: Python bindings to libpg_query — parse, deparse, normalize, fingerprint, split, and scan PostgreSQL SQL
Project-URL: Homepage, https://github.com/eddieland/postgast
Project-URL: Repository, https://github.com/eddieland/postgast
Project-URL: Issues, https://github.com/eddieland/postgast/issues
Project-URL: Changelog, https://github.com/eddieland/postgast/releases
Project-URL: Documentation, https://postgast.readthedocs.io
Author-email: Edward Jones <edwardrjones97@gmail.com>
License-Expression: BSD-2-Clause
License-File: LICENSE
License-File: THIRD-PARTY-LICENSES
Keywords: ast,libpg_query,parser,postgresql,sql
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: BSD License
Classifier: Operating System :: MacOS
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: C
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Topic :: Database
Classifier: Topic :: Database :: Front-Ends
Classifier: Topic :: Software Development :: Libraries
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: protobuf>=5.27.2
Description-Content-Type: text/markdown

# postgast

[![PyPI](https://img.shields.io/pypi/v/postgast)](https://pypi.org/project/postgast/)
[![Python](https://img.shields.io/pypi/pyversions/postgast)](https://pypi.org/project/postgast/)
[![License](https://img.shields.io/pypi/l/postgast)](https://github.com/eddieland/postgast/blob/main/LICENSE)
[![CI](https://img.shields.io/github/actions/workflow/status/eddieland/postgast/ci.yml?label=CI)](https://github.com/eddieland/postgast/actions/workflows/ci.yml)
[![Coverage](https://codecov.io/gh/eddieland/postgast/graph/badge.svg)](https://codecov.io/gh/eddieland/postgast)
[![Docs](https://readthedocs.org/projects/postgast/badge/?version=latest)](https://postgast.readthedocs.io)
[![Downloads](https://img.shields.io/pypi/dm/postgast)](https://pypi.org/project/postgast/)

BSD-licensed Python bindings to [libpg_query](https://github.com/pganalyze/libpg_query), the PostgreSQL parser extracted
as a standalone C library.

Parse, deparse, normalize, fingerprint, split, and scan PostgreSQL SQL statements from Python with a minimal dependency
footprint — just `protobuf` and the vendored C library.

<p align="center">
  <img src="docs/logo.png" width="350" alt="postgast logo"/>
</p>

## Features

| Feature          | Status                                      | Description                                                                |
| ---------------- | ------------------------------------------- | -------------------------------------------------------------------------- |
| **Parse**        | [Available](openspec/specs/operations/)     | SQL text to protobuf AST                                                   |
| **Deparse**      | [Available](openspec/specs/operations/)     | AST back to SQL text                                                       |
| **Normalize**    | [Available](openspec/specs/operations/)     | Replace constants with parameter placeholders                              |
| **Fingerprint**  | [Available](openspec/specs/operations/)     | Identify structurally equivalent statements                                |
| **Split**        | [Available](openspec/specs/operations/)     | Split multi-statement strings (respects strings, comments, dollar-quoting) |
| **Scan**         | [Available](openspec/specs/operations/)     | Tokenize SQL with keyword classification                                   |
| **Tree Walking** | [Available](openspec/specs/ast-navigation/) | Walk/visit AST nodes with depth-first traversal and visitor pattern        |
| **AST Helpers**  | [Available](openspec/specs/ast-navigation/) | Extract tables, columns, functions; generate DROP from CREATE DDL          |

Built on `libpg_query` 17-latest (PostgreSQL 17 parser).

## Installation

```bash
pip install postgast
```

## Quick Start

```python
import postgast

# Parse a query into an AST
tree = postgast.parse("SELECT id, name FROM users WHERE active = true")

# Deparse an AST back to SQL
sql = postgast.deparse(tree)

# Normalize a query (replace constants with placeholders)
normalized = postgast.normalize("SELECT * FROM users WHERE id = 42")
# => "SELECT * FROM users WHERE id = $1"

# Fingerprint a query
fp = postgast.fingerprint("SELECT * FROM users WHERE id = 42")

# Split a multi-statement string
stmts = postgast.split("SELECT 1; SELECT 2;")
# => ["SELECT 1", "SELECT 2"]
```

## Motivation

[pglast](https://github.com/lelit/pglast) is an excellent library that wraps `libpg_query` for Python, but it is
licensed under GPLv3, which makes it unusable in many commercial and permissively-licensed projects. `postgast` provides
a BSD-licensed alternative that leans directly on `libpg_query`'s C API via `ctypes`, keeping the implementation minimal
and the dependency footprint small.

## How It Works

`postgast` calls `libpg_query`'s C functions directly through Python's `ctypes` module. Parse results are returned as
protobuf messages, deserialized into Python objects. There is no Cython, no Rust, and no C extension module to compile —
just a vendored shared library and pure Python on top.

## License

BSD 2-Clause. See [LICENSE](LICENSE) for details.

`libpg_query` is licensed under the
[BSD 3-Clause License](https://github.com/pganalyze/libpg_query/blob/17-latest/LICENSE). Portions of the PostgreSQL
source code used by `libpg_query` are licensed under the
[PostgreSQL License](https://www.postgresql.org/about/licence/).
