Skip to main content
Puri is a type-safe query builder, but when complex SQL expressions are needed, you can use Raw SQL.

Raw Function Overview

Raw Type Functions

Type-specific Raw functions rawString, rawNumber

WHERE Raw

Complex conditions whereRaw

CASE WHEN

Conditional value selection CASE expressions

Subqueries

Writing nested queries Subquery

Raw Type Functions

rawString - Returns String

rawNumber - Returns Number

rawBoolean - Returns Boolean

rawDate - Returns Date

rawStringArray - Returns String Array

Parameter Bindings

Raw functions support Knex-style parameter bindings. Use placeholders in the SQL string and pass binding values as the second argument.

Placeholder Rules

Value Bindings (?)

Always use ? bindings for user input or dynamic values.

Identifier Bindings (??)

Use ?? bindings when dynamically specifying table or column names. Strings in table.column format are automatically converted to "table"."column".

Mixed Usage

You can use ? and ?? together in a single expression.
Don’t confuse ?? and ?. Using ? for a column name will escape it as a value, causing SQL errors. Conversely, using ?? for user input will escape it as an identifier, leading to unintended behavior.

Static SQL Functions

Built-in SQL functions provided by Puri.

String Functions

Aggregate Functions

WHERE Raw

You can write complex WHERE conditions directly.

Basic WHERE Raw

SQL Injection Warning: Always use bindings (?) with whereRaw. Never put user input directly in strings.

Complex Conditions

Date Functions

CASE WHEN - Conditional Values

CASE WHEN expressions can return different values based on conditions.

Basic CASE WHEN

Numeric Calculations

Boolean Results

Subqueries and Raw SQL

Scalar Subqueries

COALESCE - NULL Handling

Practical Examples

User Statistics Dashboard

Hourly Statistics

Ranking Calculation

Window Functions

ROW_NUMBER

RANK / DENSE_RANK

LAG / LEAD - Previous/Next Row

JSON Functions (PostgreSQL)

JSON Field Extraction

JSON Aggregation

Performance Optimization

Using EXPLAIN

Index Hints (Not supported in PostgreSQL)

PostgreSQL’s optimizer automatically selects indexes. Instead, update statistics:

Type Safety

Raw functions specify return types.

Raw Queries and Hydrate

When using Raw SQL, you must either manually call hydrate() or follow field naming conventions to properly structure JOIN data.

Subset vs Raw Puri Differences

What Hydrate Does

hydrate() transforms flat query results into nested object structures. Before hydrate (Flat):
After hydrate (Nested):

Field Naming Convention: Double Underscore (__)

JOIN table fields must use the tableName__fieldName format.

Automatic vs Manual Hydrate

Subset Query (Automatic Hydrate)

Raw Puri Query (Manual Hydrate)

Automatic Hydrate in executeSubsetQuery

executeSubsetQuery() internally calls hydrate automatically.

Hydrate Call Summary

Practical Example: Raw Query + Hydrate

Cautions when using Hydrate: 1. Field naming: JOIN fields must use __ (double underscore) 2. Manual call: Raw Puri queries require manual hydrate() call 3. Type safety: Types after hydrate must be manually defined 4. Performance: hydrate has runtime overhead, so use Subset queries for simple cases
Recommendations: - Use Subset queries when possible (automatic hydrate) - Only use manual hydrate when complex Raw SQL is needed - Apply field naming conventions (__) consistently

Next Steps

Type Safety

Understanding Puri’s type safety

Advanced Patterns

Subqueries and transactions

Aggregations

Using aggregate functions

Basic Queries

Back to basic queries