Skip to content

flow-php/pg-query-ext

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

pg_query PHP Extension

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

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Sponsor this project

  •  

Packages

No packages published