DSL References
DSL stands for Domain Specific Language. In Flow, the DSL is a set of small functions that wrap object construction so pipelines read top-to-bottom. See the examples for usage in context.
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', column_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', column_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|string> $args Function arguments
* @param bool $distinct Use DISTINCT modifier
*/
agg(string $name, array $args, bool $distinct) : AggregateCall /**
* Create AVG aggregate.
*/
agg_avg(Expression|string $expr, bool $distinct) : AggregateCall /**
* Create COUNT(*) aggregate.
*/
agg_count(Expression|string|null $expr, bool $distinct) : AggregateCall /**
* Create MAX aggregate.
*/
agg_max(Expression|string $expr) : AggregateCall /**
* Create MIN aggregate.
*/
agg_min(Expression|string $expr) : AggregateCall /**
* Create SUM aggregate.
*/
agg_sum(Expression|string $expr, bool $distinct) : AggregateCall /**
* Create an ALL condition with a subquery or array expression.
*
* Example: all_(col('id'), ComparisonOperator::EQ, select(col('user_id'))->from(table('orders')))
* Example: all_(col('value'), ComparisonOperator::GT, col('thresholds'))
*/
all_(Expression|string $left, ComparisonOperator $operator, Expression|SelectFinalStep $arrayOrSubquery) : All /**
* Create an ANALYZE builder.
*
* Example: analyze()->table('users')
* Produces: ANALYZE users
*/
analyze() : AnalyzeFinalStep /**
* Combine conditions with AND.
*
* @param Condition ...$conditions Conditions to combine
*/
and_(Condition $conditions) : AndCondition /**
* Create an ANY condition with a subquery or array expression.
*
* Example: any_(col('id'), ComparisonOperator::EQ, select(col('user_id'))->from(table('orders')))
* Example: any_(col('attnum', 'a'), ComparisonOperator::EQ, col('conkey', 'con'))
*/
any_(Expression|string $left, ComparisonOperator $operator, Expression|SelectFinalStep $arrayOrSubquery) : Any /**
* Create an array is contained by condition (<@).
*
* Example: array_contained_by(col('tags'), array_expr([literal('sale'), literal('featured'), literal('new')]))
* Produces: tags <@ ARRAY['sale', 'featured', 'new']
*/
array_contained_by(Expression|string $left, Expression|string $right) : OperatorCondition /**
* Create an array contains condition (@>).
*
* Example: array_contains(col('tags'), array_expr([literal('sale')]))
* Produces: tags @> ARRAY['sale']
*/
array_contains(Expression|string $left, Expression|string $right) : OperatorCondition /**
* Create an array expression.
*
* @param list<Expression|string> $elements Array elements
*/
array_expr(array $elements) : ArrayExpression /**
* Create an array overlap condition (&&).
*
* Example: array_overlap(col('tags'), array_expr([literal('sale'), literal('featured')]))
* Produces: tags && ARRAY['sale', 'featured']
*/
array_overlap(Expression|string $left, Expression|string $right) : OperatorCondition /**
* Create an ORDER BY item with ASC direction.
*/
asc(Expression|string $expr, NullsPosition $nulls) : OrderBy ast_view_dependency_resolver() : AstViewDependencyResolver /**
* 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|string $expr, Expression|string $low, Expression|string $high, bool $not) : Between /**
* Create a binary expression (left op right).
*/
binary_expr(Expression|string $left, string $operator, Expression|string $right) : BinaryExpression /**
* Create an optimized bulk INSERT query for high-performance multi-row inserts.
*
* Unlike insert() which uses immutable builder patterns (O(n²) for n rows),
* this function generates SQL directly using string operations (O(n) complexity).
*
* @param string $table Table name
* @param list<string> $columns Column names
* @param int $rowCount Number of rows to insert
*/
bulk_insert(string $table, array $columns, int $rowCount) : BulkInsert /**
* 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|string $elseResult ELSE result (optional)
* @param null|Expression|string $operand CASE operand for simple CASE (optional)
*/
case_when(array $whenClauses, Expression|string|null $elseResult, Expression|string|null $operand) : CaseExpression /**
* Create a type cast expression.
*
* @param Expression|string $expr Expression to cast
* @param ColumnType $dataType Target data type (use column_type_* functions)
*/
cast(Expression|string $expr, ColumnType $dataType) : TypeCast /**
* @param list<Schema> $schemas
*/
catalog(array $schemas) : Catalog /**
* @param null|ExecutionOrderStrategy<\Flow\PostgreSql\Schema\Table> $tableOrderStrategy
*/
catalog_comparator(?RenameStrategy $renameStrategy, ?ViewDependencyResolver $viewDependencyResolver, ?ExecutionOrderStrategy $tableOrderStrategy) : CatalogComparator chain_catalog_provider(CatalogProvider $providers) : ChainCatalogProvider /**
* Create a CHECK constraint.
*/
check_constraint(Condition $condition) : CheckConstraint /**
* @param ?list<string> $schemaNames
* @param list<string> $excludeTables
*/
client_catalog_provider(Client $client, ?array $schemaNames, array $excludeTables) : CatalogProvider /**
* Close a cursor.
*
* Example: close_cursor('my_cursor')
* Produces: CLOSE my_cursor
*
* Example: close_cursor() - closes all cursors
* Produces: CLOSE ALL
*
* @param null|string $cursorName Cursor to close, or null to close all
*/
close_cursor(?string $cursorName) : CloseCursorFinalStep /**
* 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|string ...$expressions Expressions to coalesce
*/
coalesce(Expression|string $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 ColumnType $type Column data type
*/
column(string $name, ColumnType $type) : ColumnDefinition /**
* Create an array data type from an element type.
*/
column_type_array(ColumnType $elementType) : ColumnType /**
* Create a bigint data type (PostgreSQL int8).
*/
column_type_bigint() : ColumnType /**
* Create a bigserial data type.
*/
column_type_bigserial() : ColumnType /**
* Create a boolean data type.
*/
column_type_boolean() : ColumnType /**
* Create a bytea data type.
*/
column_type_bytea() : ColumnType /**
* Create a char data type with length constraint.
*/
column_type_char(int $length) : ColumnType /**
* Create a cidr data type.
*/
column_type_cidr() : ColumnType /**
* Create a custom data type.
*
* @param string $typeName Type name
* @param null|string $schema Optional schema name
*/
column_type_custom(string $typeName, ?string $schema) : ColumnType /**
* Create a date data type.
*/
column_type_date() : ColumnType /**
* Create a decimal data type with optional precision and scale.
*/
column_type_decimal(?int $precision, ?int $scale) : ColumnType /**
* Create a double precision data type (PostgreSQL float8).
*/
column_type_double_precision() : ColumnType /**
* Parse a PostgreSQL type string into a ColumnType.
*
* Handles all PostgreSQL type syntax including precision, arrays, and schema-qualified types.
*
* @param string $typeName PostgreSQL type string (e.g., 'integer', 'character varying(255)', 'text[]')
*/
column_type_from_string(string $typeName) : ColumnType /**
* Create an inet data type.
*/
column_type_inet() : ColumnType /**
* Create an integer data type (PostgreSQL int4).
*/
column_type_integer() : ColumnType /**
* Create an interval data type.
*/
column_type_interval() : ColumnType /**
* Create a JSON data type.
*/
column_type_json() : ColumnType /**
* Create a JSONB data type.
*/
column_type_jsonb() : ColumnType /**
* Create a macaddr data type.
*/
column_type_macaddr() : ColumnType /**
* Create a numeric data type with optional precision and scale.
*/
column_type_numeric(?int $precision, ?int $scale) : ColumnType /**
* Create a real data type (PostgreSQL float4).
*/
column_type_real() : ColumnType /**
* Create a serial data type.
*/
column_type_serial() : ColumnType /**
* Create a smallint data type (PostgreSQL int2).
*/
column_type_smallint() : ColumnType /**
* Create a smallserial data type.
*/
column_type_smallserial() : ColumnType /**
* Create a text data type.
*/
column_type_text() : ColumnType /**
* Create a time data type with optional precision.
*/
column_type_time(?int $precision) : ColumnType /**
* Create a timestamp data type with optional precision.
*/
column_type_timestamp(?int $precision) : ColumnType /**
* Create a timestamp with time zone data type with optional precision.
*/
column_type_timestamptz(?int $precision) : ColumnType /**
* Create a UUID data type.
*/
column_type_uuid() : ColumnType /**
* Create a varchar data type with length constraint.
*/
column_type_varchar(int $length) : ColumnType /**
* 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 /**
* Concatenate expressions with the || operator.
*
* Example: concat(col('schema'), literal('.'), col('table'))
* Produces: schema || '.' || table
*
* @param Expression|string ...$expressions At least 2 expressions to concatenate
*/
concat(Expression|string $expressions) : BinaryExpression /**
* Create a condition builder for fluent condition composition.
*
* This builder allows incremental condition building with a fluent API:
*
* ```php
* $builder = conditions();
*
* if ($hasFilter) {
* $builder = $builder->and(eq(col('status'), literal('active')));
* }
*
* if (!$builder->isEmpty()) {
* $query = select()->from(table('users'))->where($builder);
* }
* ```
*/
conditions() : ConditionBuilder /**
* 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 /**
* @template T of object
*
* @param class-string<T> $class
*
* @return ConstructorMapper<T>
*/
constructor_mapper(string $class) : ConstructorMapper /**
* 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 COUNT(*) aggregate.
*/
count_all() : AggregateCall /**
* 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 /**
* SQL standard CURRENT_DATE function.
*
* Returns the current date (at the start of the transaction).
* Useful as a column default value or in SELECT queries.
*
* Example: column('birth_date', column_type_date())->default(current_date())
* Example: select()->select(current_date()->as('today'))
*/
current_date() : SQLValueFunctionExpression /**
* SQL standard CURRENT_TIME function.
*
* Returns the current time (at the start of the transaction).
* Useful as a column default value or in SELECT queries.
*
* Example: column('start_time', column_type_time())->default(current_time())
* Example: select()->select(current_time()->as('now_time'))
*/
current_time() : SQLValueFunctionExpression /**
* SQL standard CURRENT_TIMESTAMP function.
*
* Returns the current date and time (at the start of the transaction).
* Useful as a column default value or in SELECT queries.
*
* Example: column('created_at', column_type_timestamp())->default(current_timestamp())
* Example: select()->select(current_timestamp()->as('now'))
*/
current_timestamp() : SQLValueFunctionExpression /**
* Declare a server-side cursor for a query.
*
* Cursors must be declared within a transaction and provide memory-efficient
* iteration over large result sets via FETCH commands.
*
* Example with query builder:
* declare_cursor('my_cursor', select(star())->from(table('users')))->noScroll()
* Produces: DECLARE my_cursor NO SCROLL CURSOR FOR SELECT * FROM users
*
* Example with raw SQL:
* declare_cursor('my_cursor', 'SELECT * FROM users WHERE active = true')->withHold()
* Produces: DECLARE my_cursor NO SCROLL CURSOR WITH HOLD FOR SELECT * FROM users WHERE active = true
*
* @param string $cursorName Unique cursor name
* @param SelectFinalStep|Sql|string $query Query to iterate over
*/
declare_cursor(string $cursorName, SelectFinalStep|Sql|string $query) : DeclareCursorOptionsStep /**
* 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|string $expr, NullsPosition $nulls) : OrderBy /**
* 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 /**
* Create an IS DISTINCT FROM condition.
*/
distinct_from(Expression|string $left, Expression|string $right, bool $not) : IsDistinctFrom /**
* 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|string $left, Expression|string $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 /**
* Fetch rows from a cursor.
*
* Example: fetch('my_cursor')->forward(100)
* Produces: FETCH FORWARD 100 my_cursor
*
* Example: fetch('my_cursor')->all()
* Produces: FETCH ALL my_cursor
*
* @param string $cursorName Cursor to fetch from
*/
fetch(string $cursorName) : FetchCursorBuilder /**
* 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 foreign_key_dependency_order() : ForeignKeyDependencyOrder /**
* 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 CURRENT ROW.
*/
frame_current_row() : FrameBound /**
* Create a frame bound for N FOLLOWING.
*/
frame_following(Expression|string $offset) : FrameBound /**
* Create a frame bound for N PRECEDING.
*/
frame_preceding(Expression|string $offset) : FrameBound /**
* Create a frame bound for UNBOUNDED FOLLOWING.
*/
frame_unbounded_following() : FrameBound /**
* Create a frame bound for UNBOUNDED PRECEDING.
*/
frame_unbounded_preceding() : FrameBound /**
* Create a function call expression.
*
* @param string $name Function name (can include schema like "pg_catalog.now")
* @param list<Expression|string> $args Function arguments
*/
func(string $name, array $args) : FunctionCall /**
* Creates a new function argument for use in function/procedure definitions.
*
* Example: func_arg(column_type_integer())
* Example: func_arg(column_type_text())->named('username')
* Example: func_arg(column_type_integer())->named('count')->default('0')
* Example: func_arg(column_type_text())->out()
*
* @param ColumnType $type The PostgreSQL data type for the argument
*
* @return FunctionArgument Builder for function argument options
*/
func_arg(ColumnType $type) : FunctionArgument /**
* Create a greater-than-or-equal comparison (column >= value).
*/
ge(Expression|string $left, Expression|string $right) : Comparison /**
* 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|string ...$expressions Expressions to compare
*/
greatest(Expression|string $expressions) : Greatest /**
* Create a greater-than comparison (column > value).
*/
gt(Expression|string $left, Expression|string $right) : Comparison /**
* Get the BRIN index method.
*/
index_method_brin() : IndexMethod /**
* Get the BTREE index method.
*/
index_method_btree() : IndexMethod /**
* Get the GIN index method.
*/
index_method_gin() : IndexMethod /**
* Get the GIST index method.
*/
index_method_gist() : IndexMethod /**
* Get the HASH index method.
*/
index_method_hash() : IndexMethod /**
* Get the SPGIST index method.
*/
index_method_spgist() : IndexMethod /**
* Create a new INSERT query builder.
*/
insert() : InsertIntoStep /**
* Create an IN condition.
*
* @param Expression|string $expr Expression to check
* @param list<Expression> $values List of values (must be non-empty)
*
* @throws \InvalidArgumentException when values array is empty
*/
in_(Expression|string $expr, array $values) : In /**
* Create an IS NULL condition.
*/
is_null(Expression|string $expr, bool $not) : IsNull /**
* Wrap an expression as a boolean condition for use in WHERE/HAVING/JOIN ON.
*
* Example: is_true(col('is_active')) — uses a boolean column in WHERE clause.
*/
is_true(Expression|string $expr) : BooleanCondition /**
* 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|string $left, Expression|string $right) : OperatorCondition /**
* Create a JSONB contains condition (@>).
*
* Example: json_contains(col('metadata'), literal_json('{"category": "electronics"}'))
* Produces: metadata @> '{"category": "electronics"}'
*/
json_contains(Expression|string $left, Expression|string $right) : OperatorCondition /**
* Create a JSONB key exists condition (?).
*
* Example: json_exists(col('metadata'), literal_string('category'))
* Produces: metadata ? 'category'
*/
json_exists(Expression|string $expr, Expression|string $key) : OperatorCondition /**
* Create a JSONB all keys exist condition (?&).
*
* Example: json_exists_all(col('metadata'), array_expr([literal('category'), literal('name')]))
* Produces: metadata ?& array['category', 'name']
*/
json_exists_all(Expression|string $expr, Expression|string $keys) : OperatorCondition /**
* Create a JSONB any key exists condition (?|).
*
* Example: json_exists_any(col('metadata'), array_expr([literal('category'), literal('name')]))
* Produces: metadata ?| array['category', 'name']
*/
json_exists_any(Expression|string $expr, Expression|string $keys) : OperatorCondition /**
* Create a JSON field access expression (->).
* Returns JSON.
*
* Example: json_get(col('metadata'), literal_string('category'))
* Produces: metadata -> 'category'
*/
json_get(Expression|string $expr, Expression|string $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|string $expr, Expression|string $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|string $expr, Expression|string $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|string $expr, Expression|string $path) : BinaryExpression /**
* Create a LATERAL subquery.
*
* @param TableReference $reference The subquery or table function reference
*/
lateral(TableReference $reference) : Lateral /**
* Create a less-than-or-equal comparison (column <= value).
*/
le(Expression|string $left, Expression|string $right) : Comparison /**
* Create a LEAST expression.
*
* @param Expression|string ...$expressions Expressions to compare
*/
least(Expression|string $expressions) : Least /**
* Create a LIKE condition.
*/
like(Expression|string $expr, Expression|string $pattern, bool $caseInsensitive, bool $negated) : Like /**
* Create a LISTEN statement to subscribe the current session to a notification channel.
*
* Usage:
* listen('my_channel')->toSql() // LISTEN my_channel
*/
listen(string $channel) : ListenFinalStep /**
* 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|string $left, Expression|string $right) : Comparison manual_catalog_provider(Catalog $catalog) : CatalogProvider materialized_view_dependency_order() : MaterializedViewDependencyOrder /**
* 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).
*/
ne(Expression|string $left, Expression|string $right) : Comparison noop_view_dependency_resolver() : NoopViewDependencyResolver /**
* Create a NOTIFY statement to send a notification on a channel, optionally with a payload.
*
* Usage:
* notify('my_channel')->toSql() // NOTIFY my_channel
* notify('my_channel')->withPayload('hello')->toSql() // NOTIFY my_channel, 'hello'
*/
notify(string $channel) : NotifyFinalStep /**
* Negate a condition or expression with NOT.
*
* Accepts both Condition and Expression — NOT always produces a boolean result.
* Can be used in WHERE clauses and SELECT lists (via ->as('alias')).
*/
not_(Expression|string $expression) : NotCondition /**
* Create a NOT LIKE condition.
*
* Example: not_like(col('name'), literal('pg_%'))
* Produces: name NOT LIKE 'pg_%'
*/
not_like(Expression|string $expr, Expression|string $pattern, bool $caseInsensitive) : Like /**
* 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|string $expr, Expression|string $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|string $expr, Expression|string $pattern) : OperatorCondition /**
* @return NoExecutionOrder<mixed>
*/
no_execution_order() : NoExecutionOrder /**
* Create a NULLIF expression.
*/
nullif(Expression|string $expr1, Expression|string $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|string> $updates Column updates
*/
on_conflict_update(ConflictTarget $target, array $updates) : OnConflictClause /**
* Create an ORDER BY item.
*/
order_by(Expression|string $expr, SortDirection $direction, NullsPosition $nulls) : OrderBy /**
* Combine conditions with OR.
*
* @param Condition ...$conditions Conditions to combine
*/
or_(Condition $conditions) : OrCondition /**
* Create a positional parameter ($1, $2, etc.).
*/
param(int $position) : Parameter /**
* @return list<Parameter>
*/
parameters(int $count, int $startAt) : array /**
* Create a SelectFinalStep from a raw SQL SELECT string.
*/
parsed_select(string $sql) : ParsedSelect /**
* Create a PostgreSQL client using ext-pgsql.
*
* The client connects immediately and is ready to execute queries.
*
* @param Client\ConnectionParameters $params Connection parameters
* @param null|ValueConverters $valueConverters Custom type converters (optional)
* @param null|Context $context Base mapper Context — the Client enriches it with sql/parameters/self per query before handing it to RowMapper::map()
*
* @throws ConnectionException If connection fails
*/
pgsql_client(ConnectionParameters $params, ?ValueConverters $valueConverters, ?Context $context) : Client /**
* Create connection parameters from a connection string.
*
* Accepts libpq-style connection strings:
* - Key-value format: "host=localhost port=5432 dbname=mydb user=myuser password=secret"
* - URI format: "postgresql://user:password@localhost:5432/dbname"
*
* @example
* $params = pgsql_connection('host=localhost dbname=mydb');
* $params = pgsql_connection('postgresql://user:pass@localhost/mydb');
*/
pgsql_connection(string $connectionString) : ConnectionParameters /**
* Create connection parameters from a DSN string.
*
* Parses standard PostgreSQL DSN format commonly used in environment variables
* (e.g., DATABASE_URL). Supports postgres://, postgresql://, and pgsql:// schemes.
*
* @param string $dsn DSN string in format: postgres://user:password@host:port/database?options
*
* @throws Client\DsnParserException If the DSN cannot be parsed
*
* @example
* $params = pgsql_connection_dsn('postgres://myuser:secret@localhost:5432/mydb');
* $params = pgsql_connection_dsn('postgresql://user:[email protected]/app?sslmode=require');
* $params = pgsql_connection_dsn('pgsql://user:pass@localhost/mydb'); // Symfony/Doctrine format
* $params = pgsql_connection_dsn(getenv('DATABASE_URL'));
*/
pgsql_connection_dsn(string $dsn) : ConnectionParameters /**
* Create connection parameters from individual values.
*
* Allows specifying connection parameters individually for better type safety
* and IDE support.
*
* @param string $database Database name (required)
* @param string $host Hostname (default: localhost)
* @param int $port Port number (default: 5432)
* @param null|string $user Username (optional)
* @param null|string $password Password (optional)
* @param array<string, string> $options Additional libpq options
*
* @example
* $params = pgsql_connection_params(
* database: 'mydb',
* host: 'localhost',
* user: 'myuser',
* password: 'secret',
* );
*/
pgsql_connection_params(string $database, string $host, int $port, ?string $user, ?string $password, array $options) : ConnectionParameters /**
* Create a RowMapper Context seeded with user-supplied key/value data and an optional Catalog.
*
* The Context is later enriched with a Query (sql + parameters) and the executing Client by the
* PostgreSQL Client before being handed to RowMapper::map().
*
* @param array<string, mixed> $data User-supplied key/value pairs
*/
postgresql_context(array $data, ?Catalog $catalog) : Context /**
* Create telemetry configuration for PostgreSQL client.
*
* Bundles telemetry instance, clock, and options needed to instrument a PostgreSQL client.
*
* @param Telemetry $telemetry The telemetry instance
* @param ClockInterface $clock Clock for timestamps
* @param null|PostgreSqlTelemetryOptions $options Telemetry options (default: all enabled)
*
* @example
* $config = postgresql_telemetry_config(
* telemetry(resource(['service.name' => 'my-app'])),
* new SystemClock(),
* );
*/
postgresql_telemetry_config(Telemetry $telemetry, ClockInterface $clock, ?PostgreSqlTelemetryOptions $options) : PostgreSqlTelemetryConfig /**
* Create telemetry options for PostgreSQL client instrumentation.
*
* Controls which telemetry signals (traces, metrics, logs) are enabled
* and how query information is captured.
*
* @param bool $traceQueries Create spans for query execution (default: true)
* @param bool $traceTransactions Create spans for transactions (default: true)
* @param bool $collectMetrics Collect duration and row count metrics (default: true)
* @param bool $logQueries Log executed queries (default: false)
* @param null|int $maxQueryLength Maximum query text length in telemetry (default: 1000, null = unlimited)
* @param bool $includeParameters Include query parameters in telemetry (default: false, security consideration)
*
* @example
* // Default options (traces and metrics enabled)
* $options = postgresql_telemetry_options();
*
* // Enable query logging
* $options = postgresql_telemetry_options(logQueries: true);
*
* // Disable all but metrics
* $options = postgresql_telemetry_options(
* traceQueries: false,
* traceTransactions: false,
* collectMetrics: true,
* );
*/
postgresql_telemetry_options(bool $traceQueries, bool $traceTransactions, bool $collectMetrics, bool $logQueries, ?int $maxQueryLength, bool $includeParameters, ?int $maxParameters, ?int $maxParameterLength) : PostgreSqlTelemetryOptions /**
* 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 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 /**
* Get a CASCADE referential action.
*/
ref_action_cascade() : ReferentialAction /**
* Get a NO ACTION referential action.
*/
ref_action_no_action() : ReferentialAction /**
* Get a RESTRICT referential action.
*/
ref_action_restrict() : ReferentialAction /**
* Get a SET DEFAULT referential action.
*/
ref_action_set_default() : ReferentialAction /**
* Get a SET NULL referential action.
*/
ref_action_set_null() : ReferentialAction /**
* Create a POSIX regex match condition (~*).
* Case-insensitive.
*
* Example: regex_imatch(col('email'), literal_string('.*@gmail\\.com'))
*
* Produces: email ~* '.*@gmail\.com'
*/
regex_imatch(Expression|string $expr, Expression|string $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|string $expr, Expression|string $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|string ...$expressions Expressions to return
*/
returning(Expression|string $expressions) : ReturningClause /**
* Create a RETURNING * clause.
*/
returning_all() : 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|string> $elements Row elements
*/
row_expr(array $elements) : RowExpression /**
* Create a SAVEPOINT.
*
* Example: savepoint('my_savepoint')
* Produces: SAVEPOINT my_savepoint
*/
savepoint(string $name) : SavepointFinalStep /**
* @param list<SchemaTable> $tables
* @param list<SchemaSequence> $sequences
* @param list<SchemaView> $views
* @param list<SchemaMaterializedView> $materializedViews
* @param list<SchemaFunction> $functions
* @param list<SchemaProcedure> $procedures
* @param list<SchemaDomain> $domains
* @param list<SchemaExtension> $extensions
*/
schema(string $name, array $tables, array $sequences, array $views, array $materializedViews, array $functions, array $procedures, array $domains, array $extensions) : Schema schema_check(string $expression, ?string $name, bool $noInherit) : CheckConstraint schema_column(string $name, ColumnType $type, bool $nullable, Expression|string|int|float|bool|null $default, bool $isIdentity, ?IdentityGeneration $identityGeneration, bool $isGenerated, ?string $generationExpression, ?int $ordinalPosition) : Column schema_column_bigint(string $name, bool $nullable, Expression|string|int|float|bool|null $default) : Column schema_column_big_serial(string $name) : Column schema_column_boolean(string $name, bool $nullable, Expression|string|int|float|bool|null $default) : Column schema_column_bytea(string $name, bool $nullable, Expression|string|int|float|bool|null $default) : Column schema_column_char(string $name, int $length, bool $nullable, Expression|string|int|float|bool|null $default) : Column schema_column_cidr(string $name, bool $nullable, Expression|string|int|float|bool|null $default) : Column schema_column_date(string $name, bool $nullable, Expression|string|int|float|bool|null $default) : Column schema_column_double_precision(string $name, bool $nullable, Expression|string|int|float|bool|null $default) : Column schema_column_inet(string $name, bool $nullable, Expression|string|int|float|bool|null $default) : Column schema_column_integer(string $name, bool $nullable, Expression|string|int|float|bool|null $default) : Column schema_column_interval(string $name, bool $nullable, Expression|string|int|float|bool|null $default) : Column schema_column_json(string $name, bool $nullable, Expression|string|int|float|bool|null $default) : Column schema_column_jsonb(string $name, bool $nullable, Expression|string|int|float|bool|null $default) : Column schema_column_macaddr(string $name, bool $nullable, Expression|string|int|float|bool|null $default) : Column schema_column_numeric(string $name, ?int $precision, ?int $scale, bool $nullable, Expression|string|int|float|bool|null $default) : Column schema_column_real(string $name, bool $nullable, Expression|string|int|float|bool|null $default) : Column schema_column_serial(string $name) : Column schema_column_smallint(string $name, bool $nullable, Expression|string|int|float|bool|null $default) : Column schema_column_small_serial(string $name) : Column schema_column_text(string $name, bool $nullable, Expression|string|int|float|bool|null $default) : Column schema_column_time(string $name, ?int $precision, bool $nullable, Expression|string|int|float|bool|null $default) : Column schema_column_timestamp(string $name, ?int $precision, bool $nullable, Expression|string|int|float|bool|null $default) : Column schema_column_timestamp_tz(string $name, ?int $precision, bool $nullable, Expression|string|int|float|bool|null $default) : Column schema_column_uuid(string $name, bool $nullable, Expression|string|int|float|bool|null $default) : Column schema_column_varchar(string $name, int $length, bool $nullable, Expression|string|int|float|bool|null $default) : Column /**
* @param list<SchemaCheckConstraint> $checkConstraints
*/
schema_domain(string $name, ColumnType $baseType, bool $nullable, Expression|string|int|float|bool|null $default, array $checkConstraints) : Domain schema_exclude(string $definition, ?string $name) : ExcludeConstraint schema_extension(string $name, ?string $version) : Extension /**
* @param non-empty-list<string> $columns
* @param non-empty-list<string> $referenceColumns
*/
schema_foreign_key(array $columns, string $referenceTable, array $referenceColumns, ?string $name, string $referenceSchema, ReferentialAction $onUpdate, ReferentialAction $onDelete, bool $deferrable, bool $initiallyDeferred) : ForeignKey /**
* @param list<string> $argumentTypes
*/
schema_function(string $name, string $returnType, array $argumentTypes, string $language, ?string $definition, bool $isStrict, ?FunctionVolatility $volatility) : Func /**
* @param non-empty-list<string> $columns
*/
schema_index(string $name, array $columns, bool $unique, IndexMethod $method, bool $primary, ?string $predicate) : Index /**
* @param list<SchemaIndex> $indexes
*/
schema_materialized_view(string $name, string $definition, array $indexes) : MaterializedView /**
* @param non-empty-list<string> $columns
*/
schema_primary_key(array $columns, ?string $name) : PrimaryKey /**
* @param list<string> $argumentTypes
*/
schema_procedure(string $name, array $argumentTypes, string $language, ?string $definition) : Procedure schema_sequence(string $name, string $dataType, string|int $startValue, string|int $minValue, string|int|null $maxValue, string|int $incrementBy, bool $cycle, string|int $cacheValue, ?string $ownedByTable, ?string $ownedByColumn) : Sequence /**
* @param non-empty-list<SchemaColumn> $columns
* @param list<SchemaIndex> $indexes
* @param list<SchemaForeignKey> $foreignKeys
* @param list<SchemaUniqueConstraint> $uniqueConstraints
* @param list<SchemaCheckConstraint> $checkConstraints
* @param list<SchemaExcludeConstraint> $excludeConstraints
* @param list<SchemaTrigger> $triggers
* @param list<string> $partitionColumns
* @param list<string> $inherits
*/
schema_table(string $name, array $columns, ?PrimaryKey $primaryKey, array $indexes, array $foreignKeys, array $uniqueConstraints, array $checkConstraints, array $excludeConstraints, array $triggers, string $schema, bool $unlogged, ?PartitionStrategy $partitionStrategy, array $partitionColumns, array $inherits, ?string $tablespace) : Table /**
* @param non-empty-list<TriggerEvent> $events
*/
schema_trigger(string $name, string $tableName, TriggerTiming $timing, array $events, string $functionName, bool $forEachRow, ?string $whenCondition) : Trigger /**
* @param non-empty-list<string> $columns
*/
schema_unique(array $columns, ?string $name, bool $nullsNotDistinct) : UniqueConstraint schema_view(string $name, string $definition, bool $isUpdatable) : View /**
* Create a new SELECT query builder.
*
* @param Expression|string ...$expressions Columns to select. If empty, returns SelectSelectStep.
*/
select(Expression|string $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|string $expr, Expression|string $pattern) : SimilarTo /**
* Create a plan analyzer for analyzing EXPLAIN plans.
*
* @param Plan $plan The execution plan to analyze
*
* @return PlanAnalyzer The analyzer for extracting insights
*/
sql_analyze(Plan $plan) : PlanAnalyzer /**
* 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 /**
* Create DeparseOptions for configuring SQL formatting.
*/
sql_deparse_options() : DeparseOptions /**
* Create an ExplainConfig for customizing EXPLAIN options.
*
* @param bool $analyze Whether to actually execute the query (ANALYZE)
* @param bool $verbose Include verbose output
* @param bool $costs Include cost estimates (default true)
* @param bool $buffers Include buffer usage statistics (requires analyze)
* @param bool $timing Include timing information (requires analyze)
* @param ExplainFormat $format Output format (JSON recommended for parsing)
*/
sql_explain_config(bool $analyze, bool $verbose, bool $costs, bool $buffers, bool $timing, ExplainFormat $format) : ExplainConfig /**
* Create an ExplainModifier for transforming queries into EXPLAIN queries.
*/
sql_explain_modifier(ExplainConfig $config) : ExplainModifier /**
* Parse EXPLAIN JSON output into a Plan object.
*
* @param string $jsonOutput The JSON output from EXPLAIN (FORMAT JSON)
*
* @return Plan The parsed execution plan
*/
sql_explain_parse(string $jsonOutput) : Plan /**
* 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 sql_parse(string $sql) : ParsedQuery sql_parser() : Parser /**
* Extract columns from a parsed SQL query.
*/
sql_query_columns(ParsedQuery $query) : Columns /**
* Get the maximum nesting depth of a SQL query.
*
* Example:
* - "SELECT * FROM t" => 1
* - "SELECT * FROM (SELECT * FROM t)" => 2
* - "SELECT * FROM (SELECT * FROM (SELECT * FROM t))" => 3
*/
sql_query_depth(string $sql) : int /**
* Extract functions from a parsed SQL query.
*/
sql_query_functions(ParsedQuery $query) : Functions /**
* Extract ORDER BY clauses from a parsed SQL query.
*/
sql_query_order_by(ParsedQuery $query) : OrderBy /**
* Extract tables from a parsed SQL query.
*/
sql_query_tables(ParsedQuery $query) : Tables /**
* 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 an EXPLAIN query.
*
* Returns the modified SQL with EXPLAIN wrapped around it.
* Defaults to EXPLAIN ANALYZE with JSON format for easy parsing.
*
* @param string $sql The SQL query to explain
* @param null|ExplainConfig $config EXPLAIN configuration (defaults to forAnalysis())
*
* @return string The EXPLAIN query
*/
sql_to_explain(string $sql, ?ExplainConfig $config) : string /**
* Transform a SQL query into a keyset (cursor-based) paginated query.
*
* More efficient than OFFSET for large datasets - uses indexed WHERE conditions.
* Automatically detects existing query parameters and appends keyset placeholders at the end.
*
* @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 to limit results to a specific number of rows.
*
* @param string $sql The SQL query to limit
* @param int $limit Maximum number of rows to return
*
* @return string The limited SQL query
*/
sql_to_limited_query(string $sql, int $limit) : 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 /**
* Create a SELECT * expression.
*/
star(?string $table) : Star /**
* Create a row mapper backed by a public static factory method.
*
* The factory method must accept a single array<string, mixed> $row and return
* an instance of the target class. If your factory needs access to the mapping
* Context (sql/parameters/client/catalog/user-data), implement RowMapper directly.
*
* @template T of object
*
* @param class-string<T> $class
* @param non-empty-string $method
*
* @return StaticFactoryMapper<T>
*/
static_factory_mapper(string $class, string $method) : StaticFactoryMapper /**
* 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'), func('to_tsquery', [literal('english'), literal('hello & world')]))
* Produces: document @@ to_tsquery('english', 'hello & world')
*/
text_search_match(Expression|string $document, Expression|string $query) : OperatorCondition /**
* Wrap a PostgreSQL client with telemetry instrumentation.
*
* Returns a decorator that adds spans, metrics, and logs to all
* query and transaction operations following OpenTelemetry conventions.
*
* @param Client\Client $client The PostgreSQL client to instrument
* @param PostgreSqlTelemetryConfig $telemetryConfig Telemetry configuration
*
* @example
* $client = pgsql_client(pgsql_connection('host=localhost dbname=mydb'));
*
* $traceableClient = traceable_postgresql_client(
* $client,
* postgresql_telemetry_config(
* telemetry(resource(['service.name' => 'my-app'])),
* new SystemClock(),
* postgresql_telemetry_options(
* traceQueries: true,
* traceTransactions: true,
* collectMetrics: true,
* logQueries: true,
* maxQueryLength: 500,
* ),
* ),
* );
*
* // All operations now traced
* $traceableClient->transaction(function (Client $client) {
* $user = $client->fetchSingle('SELECT * FROM users WHERE id = $1', [123]);
* $client->execute('UPDATE users SET last_login = NOW() WHERE id = $1', [123]);
* });
*/
traceable_postgresql_client(Client $client, PostgreSqlTelemetryConfig $telemetryConfig) : TraceableClient /**
* 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 /**
* Wrap a value with explicit PostgreSQL type information for parameter binding.
*
* Use when auto-detection isn't sufficient or when you need to specify
* the exact PostgreSQL type (since one PHP type can map to multiple PostgreSQL types):
* - int could be INT2, INT4, or INT8
* - string could be TEXT, VARCHAR, or CHAR
* - array must always use typed() since auto-detection cannot determine element type
* - DateTimeInterface could be TIMESTAMP or TIMESTAMPTZ
* - Json could be JSON or JSONB
*
* @param mixed $value The value to bind
* @param ValueType $targetType The PostgreSQL type to convert the value to
*
* @example
* $client->fetch(
* 'SELECT * FROM users WHERE id = $1 AND tags = $2',
* [
* typed('550e8400-e29b-41d4-a716-446655440000', ValueType::UUID),
* typed(['tag1', 'tag2'], ValueType::TEXT_ARRAY),
* ]
* );
*/
typed(?mixed $value, ValueType $targetType) : TypedValue /**
* Creates a type attribute for composite types.
*
* Example: type_attr('name', column_type_text())
* Produces: name text
*
* Example: type_attr('description', column_type_text())->collate('en_US')
* Produces: description text COLLATE "en_US"
*
* @param string $name The attribute name
* @param ColumnType $type The attribute type
*
* @return TypeAttribute Type attribute value object
*/
type_attr(string $name, ColumnType $type) : TypeAttribute /**
* @template TType
* @template TOut
*
* @param FlowType<TType> $type
* @param null|RowMapper<TOut> $next
*
* @return ($next is null ? TypeMapper<TType, TType> : TypeMapper<TType, TOut>)
*/
type_mapper(Type $type, ?RowMapper $next) : TypeMapper /**
* Create a UNIQUE constraint.
*
* @param string ...$columns Columns that must be unique together
*/
unique_constraint(string $columns) : UniqueConstraint /**
* Create an UNLISTEN statement to unsubscribe the current session from a notification channel.
*
* Usage:
* unlisten('my_channel')->toSql() // UNLISTEN my_channel
*/
unlisten(string $channel) : UnlistenFinalStep /**
* Create a new UPDATE query builder.
*/
update() : UpdateTableStep /**
* Create a VACUUM builder.
*
* Example: vacuum()->table('users')
* Produces: VACUUM users
*/
vacuum() : VacuumFinalStep /**
* Create a VALUES clause as a table reference.
*
* Usage:
* select()->from(
* values_table(
* row_expr([literal(1), literal('Alice')]),
* row_expr([literal(2), literal('Bob')])
* )->as('t', ['id', 'name'])
* )
*
* Generates: SELECT * FROM (VALUES (1, 'Alice'), (2, 'Bob')) AS t(id, name)
*/
values_table(RowExpression $rows) : ValuesTable value_type_bigint() : ValueType value_type_bit() : ValueType value_type_bool() : ValueType value_type_boolean() : ValueType value_type_bool_array() : ValueType value_type_bpchar() : ValueType value_type_bytea() : ValueType value_type_char() : ValueType value_type_cidr() : ValueType value_type_date() : ValueType value_type_double() : ValueType value_type_float4() : ValueType value_type_float4_array() : ValueType value_type_float8() : ValueType value_type_float8_array() : ValueType value_type_inet() : ValueType value_type_int2() : ValueType value_type_int2_array() : ValueType value_type_int4() : ValueType value_type_int4_array() : ValueType value_type_int8() : ValueType value_type_int8_array() : ValueType value_type_integer() : ValueType value_type_interval() : ValueType value_type_json() : ValueType value_type_jsonb() : ValueType value_type_jsonb_array() : ValueType value_type_json_array() : ValueType value_type_macaddr() : ValueType value_type_macaddr8() : ValueType value_type_money() : ValueType value_type_numeric() : ValueType value_type_oid() : ValueType value_type_real() : ValueType value_type_smallint() : ValueType value_type_text() : ValueType value_type_text_array() : ValueType value_type_time() : ValueType value_type_timestamp() : ValueType value_type_timestamptz() : ValueType value_type_timetz() : ValueType value_type_uuid() : ValueType value_type_uuid_array() : ValueType value_type_varbit() : ValueType value_type_varchar() : ValueType value_type_varchar_array() : ValueType value_type_xml() : ValueType view_dependency_order() : ViewDependencyOrder /**
* Create a WHEN clause for CASE expression.
*/
when(Expression|string $condition, Expression|string $result) : WhenClause /**
* Create a window definition for WINDOW clause.
*
* @param string $name Window name
* @param list<Expression|string> $partitionBy PARTITION BY expressions
* @param list<OrderBy> $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|string> $args Function arguments
* @param list<Expression|string> $partitionBy PARTITION BY expressions
* @param list<OrderBy> $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