1 unstable release
| 0.2.0 | Oct 3, 2025 |
|---|
#237 in Template engine
28KB
210 lines
pg_liquid
A high-performance PostgreSQL extension for Liquid template processing, built with Rust and pgrx.
Overview
pg_liquid brings the power of Liquid templating directly into PostgreSQL. This extension provides two main functions for validating and rendering Liquid templates with JSON data, enabling dynamic content generation within your database.
Liquid is a safe, template language originally created by Shopify and used by Jekyll, GitHub Pages, and many other platforms. With pg_liquid, you can leverage this powerful templating system directly in your PostgreSQL queries and stored procedures.
Features
- ๐ Syntax Validation: Check if Liquid template code has valid syntax
- ๐จ Template Rendering: Process Liquid templates with JSON data to generate final output
- โก High Performance: Built in Rust for optimal performance and memory safety
- ๐ PostgreSQL Native: Seamless integration with PostgreSQL's JSONB type
- ๐ Full Liquid Support: Complete support for Liquid syntax including filters, conditionals, loops, and more
- ๐ก๏ธ Memory Safe: Rust implementation prevents memory leaks and crashes
- ๐งช Well Tested: Comprehensive test suite ensuring reliability
Installation
Prerequisites
- PostgreSQL 13+ with development headers
- Rust 1.70+
- pgrx framework
Quick Start
1. Install pgrx
cargo install --locked cargo-pgrx
2. Initialize pgrx
Replace pg17 with your PostgreSQL version (pg13, pg14, pg15, pg16, or pg17):
cargo pgrx init --pg17 $(which pg_config)
3. Build and Install the Extension
# Clone just the pg_liquid directory or download the standalone package
git clone https://github.com/pitorg/pg_liquid
cd pg_liquid
cargo pgrx install --release
4. Enable the Extension
Connect to your PostgreSQL database and run:
CREATE EXTENSION liquid;
Development Installation
For development and testing:
cd pg_liquid
cargo pgrx run --release
Note: This extension is completely standalone and does not require any other components from the liquid-rust repository. It uses the published liquid crate from crates.io.
Architecture: The extension follows the pgrx pattern where the crate is named pg_liquid but creates an extension called liquid with functions in the liquid schema.
This will start a PostgreSQL instance with the extension already loaded.
Verify Installation
Once installed, verify the extension works:
-- Connect to your PostgreSQL database
CREATE EXTENSION liquid;
-- Test basic functionality
SELECT liquid.check_valid_syntax('Hello {{ name }}!');
-- Should return: true
SELECT liquid.render('Hello {{ name }}!', '{"name": "World"}'::jsonb);
-- Should return: "Hello World!"
Functions
The extension provides two main functions in the liquid schema:
liquid.check_valid_syntax(liquid_code TEXT) โ BOOLEAN
Validates whether the provided Liquid template code has valid syntax.
Parameters:
liquid_code(TEXT): The Liquid template code to validate
Returns:
BOOLEAN:trueif the syntax is valid,falseotherwise
Examples:
-- Valid syntax examples
SELECT liquid.check_valid_syntax('Hello {{ name }}!');
-- Returns: true
liquid.render(liquid_code TEXT, data JSONB) โ TEXT
Renders a Liquid template with the provided JSON data.
Parameters:
liquid_code(TEXT): The Liquid template code to renderdata(JSONB): JSON object containing the data to use in template rendering
Returns:
TEXT: The rendered template output
Examples:
-- Basic variable substitution
SELECT liquid.render(
'Hello {{ user.name }}! You have {{ user.credits }} credits.',
'{
"user": {
"name": "Alice",
"credits": 100
}
}'::jsonb
);
-- Returns: "Hello Alice! You have 100 credits."
-- Conditional rendering
SELECT liquid.render(
'{% if user.is_premium %}Premium user{% else %}Regular user{% endif %}',
'{"user": {"is_premium": true}}'::jsonb
);
-- Returns: "Premium user"
Liquid Syntax Support
pg_liquid supports the complete Liquid syntax.
Performance
pg_liquid is built with performance in mind:
- Rust Implementation: Leverages Rust's zero-cost abstractions and memory safety
- Compiled Templates: Templates are parsed once and can be cached for repeated use
- Efficient JSON Handling: Direct integration with PostgreSQL's JSONB type
- Memory Safe: No memory leaks or buffer overflows
Benchmarks
Real-world performance testing shows excellent throughput for template rendering:
-- Test: 1 million simple liquid template renders
SELECT count(*) FROM (
SELECT liquid.render(
'Hej {{ user.name }}'::text,
format('{"user":{"name":"%s"}}', generate_series)::jsonb
)
FROM generate_series(1,1000000)
) AS x;
-- Result: 1,000,000 renders in 13.716 seconds
-- Performance: ~73,000 renders per second
-- Per-operation: ~13.7 microseconds per render
Performance Summary:
- Throughput: ~73,000 template renders per second
- Latency: ~13.7 microseconds per render operation
- Comparison: ~96x slower than simple
replace()(expected for full template engine) - Use Case: Excellent for high-throughput applications requiring dynamic content
Error Handling
The extension handles errors gracefully:
- Syntax Validation: Use
check_valid_syntax()to check templates before rendering - Detailed Error Messages: Clear error messages for debugging template issues
- Safe Failures: Invalid templates return errors rather than crashing the database
-- Validate before rendering
SELECT CASE
WHEN liquid.check_valid_syntax('{{ user.name }') THEN
liquid.render('{{ user.name }', '{"user": {"name": "Alice"}}'::jsonb)
ELSE
'Invalid template syntax'
END;
Testing
Run the test suite:
cargo pgrx test
This will run both Rust unit tests and PostgreSQL integration tests.
Development Setup
- Get the pg_liquid directory (standalone)
- Install dependencies:
cargo install cargo-pgrx - Initialize pgrx:
cargo pgrx init - Run tests:
cargo pgrx test - Start development server:
cargo pgrx run
Dependencies: This extension only depends on the published liquid crate from crates.io and does not require any local dependencies.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Related Projects
- liquid-rust - The underlying Liquid implementation
- pgrx - PostgreSQL extension framework
- Liquid - The original Liquid template language
Dependencies
~30MB
~662K SLoC