PG Filters
A powerful Rust helper to generate PostgreSQL SQL for pagination, sorting, and advanced filtering with support for complex AND/OR conditions.
Usage
Column Definitions
First, define your column types:
use HashMap;
use ColumnDef;
Simple Filtering
Basic filtering with multiple AND conditions:
use ;
use ;
use SortedColumn;
let columns = setup_columns;
// Create simple conditions
let name_condition = Condition;
let age_condition = Condition;
let filters = new?;
let sql = filters.sql?;
// Results in: WHERE (LOWER(name) = LOWER('John') AND age > 18) ORDER BY age DESC, name ASC LIMIT 10 OFFSET 0
Complex Filtering
Example with complex AND/OR conditions:
use ;
let columns = setup_columns;
// Create individual conditions
let name_condition = Condition;
let age_condition = Condition;
let city_condition = Condition;
// Create a complex filter: (name = 'John' AND age > 18) OR city IN ('New York', 'London')
let filter_group = Group ;
let filters = new?;
let sql = filters.sql?;
// Results in: WHERE ((LOWER(name) = LOWER('John') AND age > 18) OR city IN ('New York', 'London')) ORDER BY name ASC LIMIT 10 OFFSET 0
JSON Filter Support
PG Filters supports creating filters from JSON input:
use ;
let columns = setup_columns;
let json_filters = vec!;
let filter_builder = from_json_filters?;
Pagination with Filtered Count
When you need to apply filtering rules for pagination:
let columns = setup_columns;
let filtering_options = new;
// Create count filters
let count_filters = new?;
// Get total count with filters applied
let count_sql = count_filters.count_sql?;
let total_rows = db.query_one.await?;
let total_records = total_rows.;
// Create pagination options
let pagination = new;
// Create final filters with pagination
let filters = new?;
Supported Column Types
- Text - Text/VARCHAR/CHAR columns
- Integer - INTEGER columns
- BigInt - BIGINT columns
- SmallInt - SMALLINT columns
- Boolean - BOOLEAN columns
- DoublePrecision - DOUBLE PRECISION columns
- Real - REAL columns
- Date - DATE columns
- Timestamp - TIMESTAMP columns
- TimestampTz - TIMESTAMP WITH TIME ZONE columns
- Uuid - UUID columns (case-sensitive comparison)
- Json/Jsonb - JSON and JSONB columns
- TextArray - TEXT[] array columns
- And many more (see documentation for full list)
Valid Filtering Operators
The filtering supports various operators for different column types:
Filtering Operators
All operators can be upper or lower case. Here are the supported operators by type:
Standard Comparison Operators
- "=" - Equal to
- "!=" - Not equal to
- ">" - Greater than
- ">=" - Greater than or equal to
- "<" - Less than
- "<=" - Less than or equal to
Text Search Operators
- "LIKE" - Pattern matching
- "NOT LIKE" - Negative pattern matching
- "STARTS WITH" - Starts with pattern
- "ENDS WITH" - Ends with pattern
Null Check Operators
- "IS NULL" - Check for null values
- "IS NOT NULL" - Check for non-null values
Collection Operators
- "IN" - Value in list
- "NOT IN" - Value not in list
Array Operators
- "CONTAINS" - Array contains all specified values (@>)
- "OVERLAPS" - Array contains any of specified values (&&)
Date Operators
- "DATE_ONLY" - Match entire day
- "DATE_RANGE" - Match date range (requires start,end format)
- "RELATIVE" - Use relative date expression
Example usage for each operator type:
// Standard comparison
"f": "=", "v": "value"
// Text search
"f": "LIKE", "v": "%pattern%"
// Null check
"f": "IS NULL", "v": ""
// Collection
"f": "IN", "v": "value1,value2,value3"
// Array
"f": "CONTAINS", "v": "item1,item2"
// Date
"f": "DATE_ONLY", "v": "2024-12-29"
"f": "DATE_RANGE", "v": "2024-12-29 00:00:00,2024-12-29 23:59:59"
"f": "RELATIVE", "v": "now() - interval '1 day'"
Array Filtering
PG Filters supports filtering on PostgreSQL array columns. Here's how to use array filtering:
let columns = setup_columns;
columns.insert;
// Using JSON filters:
// Find records where services array contains ALL specified values
let contains_filter = JsonFilter ;
// Find records where services array contains ANY of the specified values
let overlaps_filter = JsonFilter ;
// Using direct conditions:
let contains_condition = Condition;
let overlaps_condition = Condition;
Array filtering supports two operations:
- CONTAINS (@>) - Finds records where the array column contains ALL specified values
- OVERLAPS (&&) - Finds records where the array column contains ANY of the specified values
Note: Array operations are case-sensitive and perform exact matching.
Array Filtering SQL Examples
-- CONTAINS: Find all records where services include both 'EPC' and 'Search'
services @> ARRAY['EPC','Search']::text[]
-- OVERLAPS: Find all records where services include either 'EPC' or 'Search'
services && ARRAY['EPC','Search']::text[]
Date Filtering
PG Filters provides sophisticated date filtering capabilities with support for exact timestamps, date-only matching, ranges, and relative dates.
let columns = setup_columns;
// Using JSON filters:
// 1. Exact timestamp matching
let exact_filter = JsonFilter ;
// 2. Date-only matching (matches full day)
let date_only_filter = JsonFilter ;
// 3. Date range matching
let range_filter = JsonFilter ;
// 4. Relative date matching
let relative_filter = JsonFilter ;
// Using direct conditions:
let date_only_condition = date_only;
let range_condition = date_range;
let relative_condition = relative_date;
Date filtering supports several operations:
DATE_ONLY- Matches an entire day (from 00:00:00 to 23:59:59)DATE_RANGE- Custom date range with start and end timestampsRELATIVE- PostgreSQL relative date expressions- Standard operators (
=,>,<, etc.) - For exact timestamp matching
Date Filtering SQL Examples
-- Exact timestamp match
created_at = '2024-12-29 15:30:00'
-- Date-only match (entire day)
created_at >= '2024-12-29 00:00:00' AND created_at < ('2024-12-29')::date + interval '1 day'
-- Date range
created_at BETWEEN '2024-12-29 00:00:00' AND '2024-12-29 23:59:59'
-- Relative date
created_at > now - interval '1 day'
Common Relative Date Expressions
You can use PostgreSQL's interval syntax for relative dates:
// Last hour
"now() - interval '1 hour'"
// Last 24 hours
"now() - interval '24 hours'"
// Last 7 days
"now() - interval '7 days'"
// Last month
"now() - interval '1 month'"
// Start of current day
"date_trunc('day', now())"
// Start of current week
"date_trunc('week', now())"
// Start of current month
"date_trunc('month', now())"
Case Sensitivity
By default, text searches are case-insensitive. You can make them case-sensitive using:
let columns = setup_columns;
case_sensitive;
Type-Aware Filtering
PG Filters now handles different column types appropriately:
- Text columns use case-insensitive comparison by default (can be made case-sensitive)
- UUID columns always use case-sensitive comparison
- Numeric columns use direct comparison
- Date/Time types use appropriate format
- Boolean values are handled correctly
- JSON fields use appropriate operators
Pagination Details
The pagination information is returned in the following structure:
See the tests for more examples.
License
Licensed under either of these:
- MIT (https://opensource.org/licenses/MIT)
- Apache-2.0 (https://www.apache.org/licenses/LICENSE-2.0)