flow-php / pg-query-ext
PostgreSQL query parser PHP extension using libpg_query
Fund package maintenance!
norberttech
flow-php.com/sponsor
Installs: 58
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
Language:C
Type:php-ext
Ext name:ext-pg_query
pkg:composer/flow-php/pg-query-ext
Requires
- php: ~8.2.0 || ~8.3.0 || ~8.4.0
This package is auto-updated.
Last update: 2025-11-28 20:12:51 UTC
README
A compiled PHP extension for PostgreSQL query parsing using libpg_query.
Features
- Parse PostgreSQL SQL queries into JSON AST
- Generate query fingerprints for query grouping
- Normalize SQL queries (replace literals with placeholders)
- Parse PL/pgSQL functions
- Split multiple SQL statements
- Scan SQL into tokens
Installation
Using PIE (Recommended)
PIE is the modern PHP extension installer.
Prerequisites: Install protobuf-c library on your system:
# Ubuntu/Debian sudo apt-get install libprotobuf-c-dev git make gcc # macOS with Homebrew brew install protobuf-c # Fedora/RHEL sudo dnf install protobuf-c-devel git make gcc
Install the extension:
# Simple installation (auto-downloads libpg_query for PostgreSQL 17) pie install flow-php/pg-query-ext # Install with a specific PostgreSQL grammar version (15, 16, or 17) pie install flow-php/pg-query-ext --with-pg-version=16 # Or with a pre-installed libpg_query pie install flow-php/pg-query-ext --with-pg-query=/usr/local
The extension will automatically download and build the appropriate libpg_query version if not found on your system.
Supported PostgreSQL versions:
| PostgreSQL | libpg_query version |
|---|---|
| 17 | 17-6.1.0 (default) |
| 16 | 16-5.2.0 |
| 15 | 15-4.2.4 |
Requirements
- PHP 8.2+
- C compiler (gcc/clang)
- git (for auto-downloading libpg_query)
- make
- protobuf-c library
Manual Build
cd src/extension/pg-query-ext # This will download and build libpg_query, then build the extension make build # Run extension tests make test # Install to system PHP (optional) make install
Using Nix
From the Flow PHP monorepo root:
# Enter Nix shell with pg_query extension loaded and build tools available nix-shell --arg with-pg-query-ext true # Navigate to extension directory cd src/extension/pg-query-ext # Build and test make test
Usage
// Parse SQL and return JSON AST $json = pg_query_parse('SELECT * FROM users WHERE id = 1'); $ast = json_decode($json, true); // Generate fingerprint (same for structurally equivalent queries) $fp = pg_query_fingerprint('SELECT * FROM users WHERE id = 1'); // Returns same fingerprint for: SELECT * FROM users WHERE id = 2 // Normalize query (replace literals with $N placeholders) $normalized = pg_query_normalize("SELECT * FROM users WHERE name = 'John'"); // Returns: SELECT * FROM users WHERE name = $1 // Split multiple statements $statements = pg_query_split('SELECT 1; SELECT 2; SELECT 3'); // Returns: ['SELECT 1', ' SELECT 2', ' SELECT 3'] // Scan SQL into tokens (returns protobuf data) $protobuf = pg_query_scan('SELECT 1');
Loading the Extension
During Development
php -d extension=./ext/modules/pg_query.so your_script.php
In php.ini
extension=pg_query
Functions Reference
| Function | Description | Returns |
|---|---|---|
pg_query_parse(string $sql) |
Parse SQL to JSON AST | string (JSON) |
pg_query_fingerprint(string $sql) |
Generate query fingerprint | string|false |
pg_query_normalize(string $sql) |
Normalize query with placeholders | string|false |
pg_query_parse_plpgsql(string $sql) |
Parse PL/pgSQL function | string (JSON) |
pg_query_split(string $sql) |
Split multiple statements | array<string> |
pg_query_scan(string $sql) |
Scan SQL into tokens | string (protobuf) |
Development
# Build and run tests make test # Rebuild extension only (without rebuilding libpg_query) make rebuild # Clean build artifacts make clean # Remove everything including libpg_query make distclean
License
MIT