flow php

DSL stands for Domain Specific Language. In the case of Flow, the DSL is used to define simple functions that can be used to transform data. Most of those functions are initializing a new instance of a class under the hood since Flow is fully object-oriented. Please look at the examples below to get a better understanding of how to use the DSL functions.

SCHEMA


/**
 * Create a factory for building ALTER statements.
 *
 * Provides a unified entry point for all ALTER operations:
 * - alter()->table() - ALTER TABLE
 * - alter()->index() - ALTER INDEX
 * - alter()->view() - ALTER VIEW
 * - alter()->materializedView() - ALTER MATERIALIZED VIEW
 * - alter()->sequence() - ALTER SEQUENCE
 * - alter()->schema() - ALTER SCHEMA
 * - alter()->role() - ALTER ROLE
 * - alter()->function() - ALTER FUNCTION
 * - alter()->procedure() - ALTER PROCEDURE
 * - alter()->trigger() - ALTER TRIGGER
 * - alter()->extension() - ALTER EXTENSION
 * - alter()->enumType() - ALTER TYPE (enum)
 * - alter()->domain() - ALTER DOMAIN
 *
 * Rename operations are also under alter():
 * - alter()->index('old')->renameTo('new')
 * - alter()->view('old')->renameTo('new')
 * - alter()->schema('old')->renameTo('new')
 * - alter()->role('old')->renameTo('new')
 * - alter()->trigger('old')->on('table')->renameTo('new')
 *
 * Example: alter()->table('users')->addColumn(col_def('email', sql_type_text()))
 * Example: alter()->sequence('user_id_seq')->restart(1000)
 */
alter() : AlterFactory
/**
 * Create a factory for building CREATE statements.
 *
 * Provides a unified entry point for all CREATE operations:
 * - create()->table() - CREATE TABLE
 * - create()->tableAs() - CREATE TABLE AS
 * - create()->index() - CREATE INDEX
 * - create()->view() - CREATE VIEW
 * - create()->materializedView() - CREATE MATERIALIZED VIEW
 * - create()->sequence() - CREATE SEQUENCE
 * - create()->schema() - CREATE SCHEMA
 * - create()->role() - CREATE ROLE
 * - create()->function() - CREATE FUNCTION
 * - create()->procedure() - CREATE PROCEDURE
 * - create()->trigger() - CREATE TRIGGER
 * - create()->rule() - CREATE RULE
 * - create()->extension() - CREATE EXTENSION
 * - create()->compositeType() - CREATE TYPE (composite)
 * - create()->enumType() - CREATE TYPE (enum)
 * - create()->rangeType() - CREATE TYPE (range)
 * - create()->domain() - CREATE DOMAIN
 *
 * Example: create()->table('users')->columns(col_def('id', sql_type_serial()))
 * Example: create()->index('idx_email')->on('users')->columns('email')
 */
create() : CreateFactory
/**
 * Create a factory for building DROP statements.
 *
 * Provides a unified entry point for all DROP operations:
 * - drop()->table() - DROP TABLE
 * - drop()->index() - DROP INDEX
 * - drop()->view() - DROP VIEW
 * - drop()->materializedView() - DROP MATERIALIZED VIEW
 * - drop()->sequence() - DROP SEQUENCE
 * - drop()->schema() - DROP SCHEMA
 * - drop()->role() - DROP ROLE
 * - drop()->function() - DROP FUNCTION
 * - drop()->procedure() - DROP PROCEDURE
 * - drop()->trigger() - DROP TRIGGER
 * - drop()->rule() - DROP RULE
 * - drop()->extension() - DROP EXTENSION
 * - drop()->type() - DROP TYPE
 * - drop()->domain() - DROP DOMAIN
 * - drop()->owned() - DROP OWNED
 *
 * Example: drop()->table('users', 'orders')->ifExists()->cascade()
 * Example: drop()->index('idx_email')->ifExists()
 */
drop() : DropFactory
/**
 * Create an index column specification.
 *
 * Use chainable methods: ->asc(), ->desc(), ->nullsFirst(), ->nullsLast(), ->opclass(), ->collate()
 *
 * Example: index_col('email')->desc()->nullsLast()
 *
 * @param string $name The column name
 */
index_col(string $name) : IndexColumn
/**
 * Create an index column specification from an expression.
 *
 * Use chainable methods: ->asc(), ->desc(), ->nullsFirst(), ->nullsLast(), ->opclass(), ->collate()
 *
 * Example: index_expr(fn_call('lower', col('email')))->desc()
 *
 * @param Expression $expression The expression to index
 */
index_expr(Expression $expression) : IndexColumn
/**
 * Create a REFRESH MATERIALIZED VIEW builder.
 *
 * Example: refresh_materialized_view('user_stats')
 * Produces: REFRESH MATERIALIZED VIEW user_stats
 *
 * Example: refresh_materialized_view('user_stats')->concurrently()->withData()
 * Produces: REFRESH MATERIALIZED VIEW CONCURRENTLY user_stats WITH DATA
 *
 * @param string $name View name (may include schema as "schema.view")
 * @param null|string $schema Schema name (optional, overrides parsed schema)
 */
refresh_materialized_view(string $name, ?string $schema) : RefreshMatViewOptionsStep
/**
 * Start building a REINDEX DATABASE statement.
 *
 * Use chainable methods: ->concurrently(), ->verbose(), ->tablespace()
 *
 * Example: reindex_database('mydb')->concurrently()
 *
 * @param string $name The database name
 */
reindex_database(string $name) : ReindexFinalStep
/**
 * Start building a REINDEX INDEX statement.
 *
 * Use chainable methods: ->concurrently(), ->verbose(), ->tablespace()
 *
 * Example: reindex_index('idx_users_email')->concurrently()
 *
 * @param string $name The index name (may include schema: schema.index)
 */
reindex_index(string $name) : ReindexFinalStep
/**
 * Start building a REINDEX SCHEMA statement.
 *
 * Use chainable methods: ->concurrently(), ->verbose(), ->tablespace()
 *
 * Example: reindex_schema('public')->concurrently()
 *
 * @param string $name The schema name
 */
reindex_schema(string $name) : ReindexFinalStep
/**
 * Start building a REINDEX TABLE statement.
 *
 * Use chainable methods: ->concurrently(), ->verbose(), ->tablespace()
 *
 * Example: reindex_table('users')->concurrently()
 *
 * @param string $name The table name (may include schema: schema.table)
 */
reindex_table(string $name) : ReindexFinalStep

HELPER


/**
 * Create an aggregate function call (COUNT, SUM, AVG, etc.).
 *
 * @param string $name Aggregate function name
 * @param list<Expression> $args Function arguments
 * @param bool $distinct Use DISTINCT modifier
 */
agg(string $name, array $args, bool $distinct) : AggregateCall
/**
 * Create AVG aggregate.
 */
agg_avg(Expression $expr, bool $distinct) : AggregateCall
/**
 * Create COUNT(*) aggregate.
 */
agg_count(?Expression $expr, bool $distinct) : AggregateCall
/**
 * Create MAX aggregate.
 */
agg_max(Expression $expr) : AggregateCall
/**
 * Create MIN aggregate.
 */
agg_min(Expression $expr) : AggregateCall
/**
 * Create SUM aggregate.
 */
agg_sum(Expression $expr, bool $distinct) : AggregateCall
/**
 * Create an ALL condition.
 */
all_sub_selects(Expression $left, ComparisonOperator $operator, SelectFinalStep $subquery) : All
/**
 * Create an ANALYZE builder.
 *
 * Example: analyze()->table('users')
 * Produces: ANALYZE users
 */
analyze() : AnalyzeFinalStep
/**
 * Create an ANY condition.
 */
any_sub_select(Expression $left, ComparisonOperator $operator, SelectFinalStep $subquery) : Any
/**
 * Create an array is contained by condition (<@).
 *
 * Example: array_contained_by(col('tags'), raw_expr("ARRAY['sale', 'featured', 'new']"))
 * Produces: tags <@ ARRAY['sale', 'featured', 'new']
 */
array_contained_by(Expression $left, Expression $right) : OperatorCondition
/**
 * Create an array contains condition (@>).
 *
 * Example: array_contains(col('tags'), raw_expr("ARRAY['sale']"))
 * Produces: tags @> ARRAY['sale']
 */
array_contains(Expression $left, Expression $right) : OperatorCondition
/**
 * Create an array expression.
 *
 * @param list<Expression> $elements Array elements
 */
array_expr(array $elements) : ArrayExpression
/**
 * Create an array overlap condition (&&).
 *
 * Example: array_overlap(col('tags'), raw_expr("ARRAY['sale', 'featured']"))
 * Produces: tags && ARRAY['sale', 'featured']
 */
array_overlap(Expression $left, Expression $right) : OperatorCondition
/**
 * Create an ORDER BY item with ASC direction.
 */
asc(Expression $expr, NullsPosition $nulls) : OrderByItem
/**
 * Create a BEGIN transaction builder.
 *
 * Example: begin()->isolationLevel(IsolationLevel::SERIALIZABLE)->readOnly()
 * Produces: BEGIN ISOLATION LEVEL SERIALIZABLE READ ONLY
 */
begin() : BeginOptionsStep
/**
 * Create a BETWEEN condition.
 */
between(Expression $expr, Expression $low, Expression $high, bool $not) : Between
/**
 * Create a binary expression (left op right).
 */
binary_expr(Expression $left, string $operator, Expression $right) : BinaryExpression
/**
 * Creates a CALL statement builder for invoking a procedure.
 *
 * Example: call('update_stats')->with(123)
 * Produces: CALL update_stats(123)
 *
 * Example: call('process_data')->with('test', 42, true)
 * Produces: CALL process_data('test', 42, true)
 *
 * @param string $procedure The name of the procedure to call
 *
 * @return CallFinalStep Builder for call statement options
 */
call(string $procedure) : CallFinalStep
/**
 * Create a CASE expression.
 *
 * @param non-empty-list<WhenClause> $whenClauses WHEN clauses
 * @param null|Expression $elseResult ELSE result (optional)
 * @param null|Expression $operand CASE operand for simple CASE (optional)
 */
case_when(array $whenClauses, ?Expression $elseResult, ?Expression $operand) : CaseExpression
/**
 * Create a type cast expression.
 *
 * @param Expression $expr Expression to cast
 * @param string $type Target type name (can include schema like "pg_catalog.int4")
 */
cast(Expression $expr, string $type) : TypeCast
/**
 * Create a CHECK constraint.
 *
 * @param string $expression SQL expression that must evaluate to true
 */
check_constraint(string $expression) : CheckConstraint
/**
 * Create a CLUSTER builder.
 *
 * Example: cluster()->table('users')->using('idx_users_pkey')
 * Produces: CLUSTER users USING idx_users_pkey
 */
cluster() : ClusterFinalStep
/**
 * Create a COALESCE expression.
 *
 * @param Expression ...$expressions Expressions to coalesce
 */
coalesce(Expression $expressions) : Coalesce
/**
 * Create a column reference expression.
 *
 * Can be used in two modes:
 * - Parse mode: col('users.id') or col('schema.table.column') - parses dot-separated string
 * - Explicit mode: col('id', 'users') or col('id', 'users', 'schema') - separate arguments
 *
 * When $table or $schema is provided, $column must be a plain column name (no dots).
 *
 * @param string $column Column name, or dot-separated path like "table.column" or "schema.table.column"
 * @param null|string $table Table name (optional, triggers explicit mode)
 * @param null|string $schema Schema name (optional, requires $table)
 *
 * @throws InvalidExpressionException when $schema is provided without $table, or when $column contains dots in explicit mode
 */
col(string $column, ?string $table, ?string $schema) : Column
/**
 * Create a column definition for CREATE TABLE.
 *
 * @param string $name Column name
 * @param DataType $type Column data type
 */
column(string $name, DataType $type) : ColumnDefinition
/**
 * Create a COMMENT ON builder.
 *
 * Example: comment(CommentTarget::TABLE, 'users')->is('User accounts table')
 * Produces: COMMENT ON TABLE users IS 'User accounts table'
 *
 * @param CommentTarget $target Target type (TABLE, COLUMN, INDEX, etc.)
 * @param string $name Target name (use 'table.column' for COLUMN targets)
 */
comment(CommentTarget $target, string $name) : CommentFinalStep
/**
 * Create a COMMIT transaction builder.
 *
 * Example: commit()->andChain()
 * Produces: COMMIT AND CHAIN
 */
commit() : CommitOptionsStep
/**
 * Create a COMMIT PREPARED builder.
 *
 * Example: commit_prepared('my_transaction')
 * Produces: COMMIT PREPARED 'my_transaction'
 */
commit_prepared(string $transactionId) : PreparedTransactionFinalStep
/**
 * Combine conditions with AND.
 *
 * @param Condition ...$conditions Conditions to combine
 */
cond_and(Condition $conditions) : AndCondition
/**
 * Negate a condition with NOT.
 */
cond_not(Condition $condition) : NotCondition
/**
 * Combine conditions with OR.
 *
 * @param Condition ...$conditions Conditions to combine
 */
cond_or(Condition $conditions) : OrCondition
/**
 * Create a conflict target for ON CONFLICT (columns).
 *
 * @param list<string> $columns Columns that define uniqueness
 */
conflict_columns(array $columns) : ConflictTarget
/**
 * Create a conflict target for ON CONFLICT ON CONSTRAINT.
 */
conflict_constraint(string $name) : ConflictTarget
/**
 * Create a new COPY query builder for data import/export.
 *
 * Usage:
 *   copy()->from('users')->file('/tmp/users.csv')->format(CopyFormat::CSV)
 *   copy()->to('users')->file('/tmp/users.csv')->format(CopyFormat::CSV)
 *   copy()->toQuery(select(...))->file('/tmp/data.csv')
 */
copy() : CopyFactory
/**
 * Create a CTE (Common Table Expression).
 *
 * @param string $name CTE name
 * @param SelectFinalStep $query CTE query
 * @param array<string> $columnNames Column aliases (optional)
 * @param CTEMaterialization $materialization Materialization hint
 */
cte(string $name, SelectFinalStep $query, array $columnNames, CTEMaterialization $materialization, bool $recursive) : CTE
/**
 * Create a new DELETE query builder.
 */
delete() : DeleteFromStep
/**
 * Create a derived table (subquery in FROM clause).
 */
derived(SelectFinalStep $query, string $alias) : DerivedTable
/**
 * Create an ORDER BY item with DESC direction.
 */
desc(Expression $expr, NullsPosition $nulls) : OrderByItem
/**
 * Create a DISCARD builder.
 *
 * Example: discard(DiscardType::ALL)
 * Produces: DISCARD ALL
 *
 * @param DiscardType $type Type of resources to discard (ALL, PLANS, SEQUENCES, TEMP)
 */
discard(DiscardType $type) : DiscardFinalStep
/**
 * Creates a DO statement builder for executing an anonymous code block.
 *
 * Example: do_block('BEGIN RAISE NOTICE $$Hello World$$; END;')
 * Produces: DO $$ BEGIN RAISE NOTICE $$Hello World$$; END; $$ LANGUAGE plpgsql
 *
 * Example: do_block('SELECT 1')->language('sql')
 * Produces: DO $$ SELECT 1 $$ LANGUAGE sql
 *
 * @param string $code The anonymous code block to execute
 *
 * @return DoFinalStep Builder for DO statement options
 */
do_block(string $code) : DoFinalStep
/**
 * Create a DROP OWNED builder.
 *
 * Example: drop_owned('role1')
 * Produces: DROP OWNED BY role1
 *
 * Example: drop_owned('role1', 'role2')->cascade()
 * Produces: DROP OWNED BY role1, role2 CASCADE
 *
 * @param string ...$roles The roles whose owned objects should be dropped
 *
 * @return DropOwnedFinalStep Builder for drop owned options
 */
drop_owned(string $roles) : DropOwnedFinalStep
/**
 * Create an equality comparison (column = value).
 */
eq(Expression $left, Expression $right) : Comparison
/**
 * Create an EXISTS condition.
 */
exists(SelectFinalStep $subquery) : Exists
/**
 * Create an EXPLAIN builder for a query.
 *
 * Example: explain(select()->from('users'))
 * Produces: EXPLAIN SELECT * FROM users
 *
 * @param DeleteBuilder|InsertBuilder|SelectFinalStep|UpdateBuilder $query Query to explain
 */
explain(SelectFinalStep|InsertBuilder|UpdateBuilder|DeleteBuilder $query) : ExplainFinalStep
/**
 * Create a FOREIGN KEY constraint.
 *
 * @param list<string> $columns Local columns
 * @param string $referenceTable Referenced table
 * @param list<string> $referenceColumns Referenced columns (defaults to same as $columns if empty)
 */
foreign_key(array $columns, string $referenceTable, array $referenceColumns) : ForeignKeyConstraint
/**
 * Create a FOR SHARE locking clause.
 *
 * @param list<string> $tables Tables to lock (empty for all)
 */
for_share(array $tables) : LockingClause
/**
 * Create a FOR UPDATE locking clause.
 *
 * @param list<string> $tables Tables to lock (empty for all)
 */
for_update(array $tables) : LockingClause
/**
 * Create a frame bound for N FOLLOWING.
 */
frame_following(Expression $offset) : FrameBound
/**
 * Create a frame bound for N PRECEDING.
 */
frame_preceding(Expression $offset) : FrameBound
/**
 * Create a function call expression.
 *
 * @param string $name Function name (can include schema like "pg_catalog.now")
 * @param list<Expression> $args Function arguments
 */
func(string $name, array $args) : FunctionCall
/**
 * Creates a new function argument for use in function/procedure definitions.
 *
 * Example: func_arg(sql_type_integer())
 * Example: func_arg(sql_type_text())->named('username')
 * Example: func_arg(sql_type_integer())->named('count')->default('0')
 * Example: func_arg(sql_type_text())->out()
 *
 * @param DataType $type The PostgreSQL data type for the argument
 *
 * @return FunctionArgument Builder for function argument options
 */
func_arg(DataType $type) : FunctionArgument
/**
 * Create a GRANT privileges builder.
 *
 * Example: grant(TablePrivilege::SELECT)->onTable('users')->to('app_user')
 * Produces: GRANT SELECT ON users TO app_user
 *
 * Example: grant(TablePrivilege::ALL)->onAllTablesInSchema('public')->to('admin')
 * Produces: GRANT ALL ON ALL TABLES IN SCHEMA public TO admin
 *
 * @param string|TablePrivilege ...$privileges The privileges to grant
 *
 * @return GrantOnStep Builder for grant options
 */
grant(TablePrivilege|string $privileges) : GrantOnStep
/**
 * Create a GRANT role builder.
 *
 * Example: grant_role('admin')->to('user1')
 * Produces: GRANT admin TO user1
 *
 * Example: grant_role('admin', 'developer')->to('user1')->withAdminOption()
 * Produces: GRANT admin, developer TO user1 WITH ADMIN OPTION
 *
 * @param string ...$roles The roles to grant
 *
 * @return GrantRoleToStep Builder for grant role options
 */
grant_role(string $roles) : GrantRoleToStep
/**
 * Create a GREATEST expression.
 *
 * @param Expression ...$expressions Expressions to compare
 */
greatest(Expression $expressions) : Greatest
/**
 * Create a greater-than comparison (column > value).
 */
gt(Expression $left, Expression $right) : Comparison
/**
 * Create a greater-than-or-equal comparison (column >= value).
 */
gte(Expression $left, Expression $right) : Comparison
/**
 * Create a new INSERT query builder.
 */
insert() : InsertIntoStep
/**
 * Create an IS DISTINCT FROM condition.
 */
is_distinct_from(Expression $left, Expression $right, bool $not) : IsDistinctFrom
/**
 * Create an IN condition.
 *
 * @param Expression $expr Expression to check
 * @param list<Expression> $values List of values
 */
is_in(Expression $expr, array $values) : In
/**
 * Create an IS NULL condition.
 */
is_null(Expression $expr, bool $not) : IsNull
/**
 * Create a JSONB is contained by condition (<@).
 *
 * Example: json_contained_by(col('metadata'), literal_json('{"category": "electronics", "price": 100}'))
 * Produces: metadata <@ '{"category": "electronics", "price": 100}'
 */
json_contained_by(Expression $left, Expression $right) : OperatorCondition
/**
 * Create a JSONB contains condition (@>).
 *
 * Example: json_contains(col('metadata'), literal_json('{"category": "electronics"}'))
 * Produces: metadata @> '{"category": "electronics"}'
 */
json_contains(Expression $left, Expression $right) : OperatorCondition
/**
 * Create a JSONB key exists condition (?).
 *
 * Example: json_exists(col('metadata'), literal_string('category'))
 * Produces: metadata ? 'category'
 */
json_exists(Expression $expr, Expression $key) : OperatorCondition
/**
 * Create a JSONB all keys exist condition (?&).
 *
 * Example: json_exists_all(col('metadata'), raw_expr("array['category', 'name']"))
 * Produces: metadata ?& array['category', 'name']
 */
json_exists_all(Expression $expr, Expression $keys) : OperatorCondition
/**
 * Create a JSONB any key exists condition (?|).
 *
 * Example: json_exists_any(col('metadata'), raw_expr("array['category', 'name']"))
 * Produces: metadata ?| array['category', 'name']
 */
json_exists_any(Expression $expr, Expression $keys) : OperatorCondition
/**
 * Create a JSON field access expression (->).
 * Returns JSON.
 *
 * Example: json_get(col('metadata'), literal_string('category'))
 * Produces: metadata -> 'category'
 */
json_get(Expression $expr, Expression $key) : BinaryExpression
/**
 * Create a JSON field access expression (->>).
 * Returns text.
 *
 * Example: json_get_text(col('metadata'), literal_string('name'))
 * Produces: metadata ->> 'name'
 */
json_get_text(Expression $expr, Expression $key) : BinaryExpression
/**
 * Create a JSON path access expression (#>).
 * Returns JSON.
 *
 * Example: json_path(col('metadata'), literal_string('{category,name}'))
 * Produces: metadata #> '{category,name}'
 */
json_path(Expression $expr, Expression $path) : BinaryExpression
/**
 * Create a JSON path access expression (#>>).
 * Returns text.
 *
 * Example: json_path_text(col('metadata'), literal_string('{category,name}'))
 * Produces: metadata #>> '{category,name}'
 */
json_path_text(Expression $expr, Expression $path) : BinaryExpression
/**
 * Create a LATERAL subquery.
 *
 * @param TableReference $reference The subquery or table function reference
 */
lateral(TableReference $reference) : Lateral
/**
 * Create a LEAST expression.
 *
 * @param Expression ...$expressions Expressions to compare
 */
least(Expression $expressions) : Least
/**
 * Create a LIKE condition.
 */
like(Expression $expr, Expression $pattern, bool $caseInsensitive) : Like
/**
 * Create a literal value for use in queries.
 *
 * Automatically detects the type and creates the appropriate literal:
 * - literal('hello') creates a string literal
 * - literal(42) creates an integer literal
 * - literal(3.14) creates a float literal
 * - literal(true) creates a boolean literal
 * - literal(null) creates a NULL literal
 */
literal(string|int|float|bool|null $value) : Literal
/**
 * Create a locking clause (FOR UPDATE, FOR SHARE, etc.).
 *
 * @param LockStrength $strength Lock strength
 * @param list<string> $tables Tables to lock (empty for all)
 * @param LockWaitPolicy $waitPolicy Wait policy
 */
lock_for(LockStrength $strength, array $tables, LockWaitPolicy $waitPolicy) : LockingClause
/**
 * Create a LOCK TABLE builder.
 *
 * Example: lock_table('users', 'orders')->accessExclusive()
 * Produces: LOCK TABLE users, orders IN ACCESS EXCLUSIVE MODE
 */
lock_table(string $tables) : LockFinalStep
/**
 * Create a less-than comparison (column < value).
 */
lt(Expression $left, Expression $right) : Comparison
/**
 * Create a less-than-or-equal comparison (column <= value).
 */
lte(Expression $left, Expression $right) : Comparison
/**
 * Create a new MERGE query builder.
 *
 * @param string $table Target table name
 * @param null|string $alias Optional table alias
 */
merge(string $table, ?string $alias) : MergeUsingStep
/**
 * Create a not-equal comparison (column != value).
 */
neq(Expression $left, Expression $right) : Comparison
/**
 * Create a POSIX regex not match condition (!~*).
 * Case-insensitive.
 *
 * Example: not_regex_imatch(col('email'), literal_string('.*@spam\\.com'))
 *
 * Produces: email !~* '.*@spam\.com'
 */
not_regex_imatch(Expression $expr, Expression $pattern) : OperatorCondition
/**
 * Create a POSIX regex not match condition (!~).
 * Case-sensitive.
 *
 * Example: not_regex_match(col('email'), literal_string('.*@spam\\.com'))
 *
 * Produces: email !~ '.*@spam\.com'
 */
not_regex_match(Expression $expr, Expression $pattern) : OperatorCondition
/**
 * Create a NULLIF expression.
 */
nullif(Expression $expr1, Expression $expr2) : NullIf
/**
 * Create an ON CONFLICT DO NOTHING clause.
 */
on_conflict_nothing(?ConflictTarget $target) : OnConflictClause
/**
 * Create an ON CONFLICT DO UPDATE clause.
 *
 * @param ConflictTarget $target Conflict target (columns or constraint)
 * @param array<string, Expression> $updates Column updates
 */
on_conflict_update(ConflictTarget $target, array $updates) : OnConflictClause
/**
 * Create an ORDER BY item.
 */
order_by(Expression $expr, SortDirection $direction, NullsPosition $nulls) : OrderByItem
/**
 * Create a positional parameter ($1, $2, etc.).
 */
param(int $position) : Parameter
/**
 * Create a PREPARE TRANSACTION builder.
 *
 * Example: prepare_transaction('my_transaction')
 * Produces: PREPARE TRANSACTION 'my_transaction'
 */
prepare_transaction(string $transactionId) : PreparedTransactionFinalStep
/**
 * Create a PRIMARY KEY constraint.
 *
 * @param string ...$columns Columns that form the primary key
 */
primary_key(string $columns) : PrimaryKeyConstraint
/**
 * Create a raw SQL condition (use with caution).
 */
raw_cond(string $sql) : RawCondition
/**
 * Create a raw SQL expression (use with caution).
 */
raw_expr(string $sql) : RawExpression
/**
 * Create a REASSIGN OWNED builder.
 *
 * Example: reassign_owned('old_role')->to('new_role')
 * Produces: REASSIGN OWNED BY old_role TO new_role
 *
 * @param string ...$roles The roles whose owned objects should be reassigned
 *
 * @return ReassignOwnedToStep Builder for reassign owned options
 */
reassign_owned(string $roles) : ReassignOwnedToStep
/**
 * Create a POSIX regex match condition (~*).
 * Case-insensitive.
 *
 * Example: regex_imatch(col('email'), literal_string('.*@gmail\\.com'))
 *
 * Produces: email ~* '.*@gmail\.com'
 */
regex_imatch(Expression $expr, Expression $pattern) : OperatorCondition
/**
 * Create a POSIX regex match condition (~).
 * Case-sensitive.
 *
 * Example: regex_match(col('email'), literal_string('.*@gmail\\.com'))
 *
 * Produces: email ~ '.*@gmail\.com'
 */
regex_match(Expression $expr, Expression $pattern) : OperatorCondition
/**
 * Release a SAVEPOINT.
 *
 * Example: release_savepoint('my_savepoint')
 * Produces: RELEASE my_savepoint
 */
release_savepoint(string $name) : SavepointFinalStep
/**
 * Create a RESET ROLE builder.
 *
 * Example: reset_role()
 * Produces: RESET ROLE
 *
 * @return ResetRoleFinalStep Builder for reset role
 */
reset_role() : ResetRoleFinalStep
/**
 * Create a RETURNING clause.
 *
 * @param Expression ...$expressions Expressions to return
 */
returning(Expression $expressions) : ReturningClause
/**
 * Create a REVOKE privileges builder.
 *
 * Example: revoke(TablePrivilege::SELECT)->onTable('users')->from('app_user')
 * Produces: REVOKE SELECT ON users FROM app_user
 *
 * Example: revoke(TablePrivilege::ALL)->onTable('users')->from('app_user')->cascade()
 * Produces: REVOKE ALL ON users FROM app_user CASCADE
 *
 * @param string|TablePrivilege ...$privileges The privileges to revoke
 *
 * @return RevokeOnStep Builder for revoke options
 */
revoke(TablePrivilege|string $privileges) : RevokeOnStep
/**
 * Create a REVOKE role builder.
 *
 * Example: revoke_role('admin')->from('user1')
 * Produces: REVOKE admin FROM user1
 *
 * Example: revoke_role('admin')->from('user1')->cascade()
 * Produces: REVOKE admin FROM user1 CASCADE
 *
 * @param string ...$roles The roles to revoke
 *
 * @return RevokeRoleFromStep Builder for revoke role options
 */
revoke_role(string $roles) : RevokeRoleFromStep
/**
 * Create a ROLLBACK transaction builder.
 *
 * Example: rollback()->toSavepoint('my_savepoint')
 * Produces: ROLLBACK TO SAVEPOINT my_savepoint
 */
rollback() : RollbackOptionsStep
/**
 * Create a ROLLBACK PREPARED builder.
 *
 * Example: rollback_prepared('my_transaction')
 * Produces: ROLLBACK PREPARED 'my_transaction'
 */
rollback_prepared(string $transactionId) : PreparedTransactionFinalStep
/**
 * Create a row expression.
 *
 * @param list<Expression> $elements Row elements
 */
row_expr(array $elements) : RowExpression
/**
 * Create a SAVEPOINT.
 *
 * Example: savepoint('my_savepoint')
 * Produces: SAVEPOINT my_savepoint
 */
savepoint(string $name) : SavepointFinalStep
/**
 * Create a new SELECT query builder.
 *
 * @param Expression ...$expressions Columns to select. If empty, returns SelectSelectStep.
 */
select(Expression $expressions) : SelectBuilder
/**
 * Create a SET ROLE builder.
 *
 * Example: set_role('admin')
 * Produces: SET ROLE admin
 *
 * @param string $role The role to set
 *
 * @return SetRoleFinalStep Builder for set role
 */
set_role(string $role) : SetRoleFinalStep
/**
 * Create a SET SESSION CHARACTERISTICS AS TRANSACTION builder.
 *
 * Example: set_session_transaction()->isolationLevel(IsolationLevel::SERIALIZABLE)
 * Produces: SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL SERIALIZABLE
 */
set_session_transaction() : SetTransactionOptionsStep
/**
 * Create a SET TRANSACTION builder.
 *
 * Example: set_transaction()->isolationLevel(IsolationLevel::SERIALIZABLE)->readOnly()
 * Produces: SET TRANSACTION ISOLATION LEVEL SERIALIZABLE, READ ONLY
 */
set_transaction() : SetTransactionOptionsStep
/**
 * Create a SIMILAR TO condition.
 */
similar_to(Expression $expr, Expression $pattern) : SimilarTo
/**
 * Convert a ParsedQuery AST back to SQL string.
 *
 * When called without options, returns the SQL as a simple string.
 * When called with DeparseOptions, applies formatting (pretty-printing, indentation, etc.).
 *
 * @throws \RuntimeException if deparsing fails
 */
sql_deparse(ParsedQuery $query, ?DeparseOptions $options) : string
/**
 * Returns a fingerprint of the given SQL query.
 * Literal values are normalized so they won't affect the fingerprint.
 */
sql_fingerprint(string $sql) : ?string
/**
 * Parse and format SQL query with pretty printing.
 *
 * This is a convenience function that parses SQL and returns it formatted.
 *
 * @param string $sql The SQL query to format
 * @param null|DeparseOptions $options Formatting options (defaults to pretty-print enabled)
 *
 * @throws \RuntimeException if parsing or deparsing fails
 */
sql_format(string $sql, ?DeparseOptions $options) : string
/**
 * Create a KeysetColumn for keyset pagination.
 *
 * @param string $column Column name (can include table alias like "u.id")
 * @param SortOrder $order Sort order (ASC or DESC)
 */
sql_keyset_column(string $column, SortOrder $order) : KeysetColumn
/**
 * Normalize SQL query by replacing literal values and named parameters with positional parameters.
 * WHERE id = :id will be changed into WHERE id = $1
 * WHERE id = 1 will be changed into WHERE id = $1.
 */
sql_normalize(string $sql) : ?string
/**
 * Normalize utility SQL statements (DDL like CREATE, ALTER, DROP).
 * This handles DDL statements differently from pg_normalize() which is optimized for DML.
 */
sql_normalize_utility(string $sql) : ?string
/**
 * Split string with multiple SQL statements into array of individual statements.
 *
 * @return array<string>
 */
sql_split(string $sql) : array
/**
 * Generate a summary of parsed queries in protobuf format.
 * Useful for query monitoring and logging without full AST overhead.
 */
sql_summary(string $sql, int $options, int $truncateLimit) : string
/**
 * Transform a SQL query into a COUNT query for pagination.
 *
 * Wraps the query in: SELECT COUNT(*) FROM (...) AS _count_subq
 * Removes ORDER BY and LIMIT/OFFSET from the inner query.
 *
 * @param string $sql The SQL query to transform
 *
 * @return string The COUNT query
 */
sql_to_count_query(string $sql) : string
/**
 * Transform a SQL query into a keyset (cursor-based) paginated query.
 *
 * More efficient than OFFSET for large datasets - uses indexed WHERE conditions.
 *
 * @param string $sql The SQL query to paginate (must have ORDER BY)
 * @param int $limit Maximum number of rows to return
 * @param list<KeysetColumn> $columns Columns for keyset pagination (must match ORDER BY)
 * @param null|list<null|bool|float|int|string> $cursor Values from last row of previous page (null for first page)
 *
 * @return string The paginated SQL query
 */
sql_to_keyset_query(string $sql, int $limit, array $columns, ?array $cursor) : string
/**
 * Transform a SQL query into a paginated query with LIMIT and OFFSET.
 *
 * @param string $sql The SQL query to paginate
 * @param int $limit Maximum number of rows to return
 * @param int $offset Number of rows to skip (requires ORDER BY in query)
 *
 * @return string The paginated SQL query
 */
sql_to_paginated_query(string $sql, int $limit, int $offset) : string
/**
 * Parse SQL and convert to a QueryBuilder for modification.
 *
 * Only works for single-statement queries. For multiple statements,
 * use pg_split() to parse statements individually.
 *
 * @throws \InvalidArgumentException if query contains multiple statements or unsupported statement type
 */
sql_to_query_builder(string $sql) : SelectBuilder|InsertBuilder|UpdateBuilder|DeleteBuilder
/**
 * Create an ARRAY data type.
 *
 * @param DataType $elementType The type of array elements
 */
sql_type_array(DataType $elementType) : DataType
/**
 * Create a CHAR data type.
 *
 * @param int $length Fixed character length
 */
sql_type_char(int $length) : DataType
/**
 * Create a DECIMAL data type (alias for NUMERIC).
 *
 * @param null|int $precision Total number of digits
 * @param null|int $scale Number of digits after decimal point
 */
sql_type_decimal(?int $precision, ?int $scale) : DataType
/**
 * Create a NUMERIC data type.
 *
 * @param null|int $precision Total number of digits
 * @param null|int $scale Number of digits after decimal point
 */
sql_type_numeric(?int $precision, ?int $scale) : DataType
/**
 * Create a SERIAL (auto-incrementing integer) data type.
 */
sql_type_serial() : DataType
/**
 * Create a TIME data type.
 *
 * @param null|int $precision Fractional seconds precision
 */
sql_type_time(?int $precision) : DataType
/**
 * Create a TIMESTAMP data type.
 *
 * @param null|int $precision Fractional seconds precision
 */
sql_type_timestamp(?int $precision) : DataType
/**
 * Create a TIMESTAMP WITH TIME ZONE data type.
 *
 * @param null|int $precision Fractional seconds precision
 */
sql_type_timestamptz(?int $precision) : DataType
/**
 * Create a VARCHAR data type.
 *
 * @param int $length Maximum character length
 */
sql_type_varchar(int $length) : DataType
/**
 * Create a SELECT * expression.
 */
star(?string $table) : Star
/**
 * Create a subquery expression.
 */
sub_select(SelectFinalStep $query) : Subquery
/**
 * Create a table reference.
 *
 * Supports dot notation for schema-qualified names: "public.users" or explicit schema parameter.
 * Double-quoted identifiers preserve dots: '"my.table"' creates a single identifier.
 *
 * @param string $name Table name (may include schema as "schema.table")
 * @param null|string $schema Schema name (optional, overrides parsed schema)
 */
table(string $name, ?string $schema) : Table
/**
 * Create a table function reference.
 *
 * @param FunctionCall $function The table-valued function
 * @param bool $withOrdinality Whether to add WITH ORDINALITY
 */
table_func(FunctionCall $function, bool $withOrdinality) : TableFunction
/**
 * Create a full-text search match condition (@@).
 *
 * Example: text_search_match(col('document'), raw_expr("to_tsquery('english', 'hello & world')"))
 * Produces: document @@ to_tsquery('english', 'hello & world')
 */
text_search_match(Expression $document, Expression $query) : OperatorCondition
/**
 * Create a SET TRANSACTION SNAPSHOT builder.
 *
 * Example: transaction_snapshot('00000003-0000001A-1')
 * Produces: SET TRANSACTION SNAPSHOT '00000003-0000001A-1'
 */
transaction_snapshot(string $snapshotId) : SetTransactionFinalStep
/**
 * Create a TRUNCATE TABLE builder.
 *
 * @param string ...$tables Table names to truncate
 */
truncate_table(string $tables) : TruncateFinalStep
/**
 * Creates a type attribute for composite types.
 *
 * Example: type_attr('name', sql_type_text())
 * Produces: name text
 *
 * Example: type_attr('description', sql_type_text())->collate('en_US')
 * Produces: description text COLLATE "en_US"
 *
 * @param string $name The attribute name
 * @param DataType $type The attribute type
 *
 * @return TypeAttribute Type attribute value object
 */
type_attr(string $name, DataType $type) : TypeAttribute
/**
 * Create a UNIQUE constraint.
 *
 * @param string ...$columns Columns that must be unique together
 */
unique_constraint(string $columns) : UniqueConstraint
/**
 * Create a new UPDATE query builder.
 */
update() : UpdateTableStep
/**
 * Create a VACUUM builder.
 *
 * Example: vacuum()->table('users')
 * Produces: VACUUM users
 */
vacuum() : VacuumFinalStep
/**
 * Create a WHEN clause for CASE expression.
 */
when(Expression $condition, Expression $result) : WhenClause
/**
 * Create a window definition for WINDOW clause.
 *
 * @param string $name Window name
 * @param list<Expression> $partitionBy PARTITION BY expressions
 * @param list<OrderBy|OrderByItem> $orderBy ORDER BY items
 * @param null|WindowFrame $frame Window frame specification
 */
window_def(string $name, array $partitionBy, array $orderBy, ?WindowFrame $frame) : WindowDefinition
/**
 * Create a window frame specification.
 */
window_frame(FrameMode $mode, FrameBound $start, ?FrameBound $end, FrameExclusion $exclusion) : WindowFrame
/**
 * Create a window function.
 *
 * @param string $name Function name
 * @param list<Expression> $args Function arguments
 * @param list<Expression> $partitionBy PARTITION BY expressions
 * @param list<OrderBy|OrderByItem> $orderBy ORDER BY items
 */
window_func(string $name, array $args, array $partitionBy, array $orderBy) : WindowFunction
/**
 * Create a WITH clause builder for CTEs.
 *
 * Example: with(cte('users', $subquery))->select(star())->from(table('users'))
 * Example: with(cte('a', $q1), cte('b', $q2))->recursive()->select(...)->from(table('a'))
 */
with(CTE $ctes) : WithBuilder

Contributors

Join us on GitHub external resource
scroll back to top