All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- CI: Codecov coverage upload with pcov-driven clover report.
1.2.0 - 2026-06-10
- MERGE query support (ANSI SQL:2008 + PostgreSQL extensions: RETURNING, DO NOTHING). New interface:
MergeQueryInterface. New classes:MergeQuery,PgSqlMergeQuery,MergeActionUpdate,MergeActionDelete,MergeActionInsert,PgSqlMergeActionDoNothing,MergeWhenMatchedClause,MergeWhenNotMatchedClause,MergeWhenNotMatchedBySourceClause. - Comprehensive MERGE test coverage: INSERT with typed values, UPDATE SET with SelectQuery/ValuesQuery/SetClause[], USING with ValuesQuery/ExprInterface, DefaultGrammar MERGE, MERGE without WHEN clauses, multiple BY SOURCE clauses, ON with ExprInterface, PgSql MERGE without RETURNING.
- Test coverage gap fill:
QueryEdgeCaseTest(43 E2E tests for trait add*, join variants, set operations, window frame edges, lock modes, MySQL hints/partition),ExceptionFactoryTest(11 exception factory tests),ExprUnitTest(6 expression unit tests).
- Fix MySQL lock clause missing
FORprefix in single lock mode (MySqlGrammar::buildLockClause).
- Documentation: quick-start (5 → 6 query classes), dialects (PgSql MERGE feature table), GrammarInterface (
@inputincludesMergeQueryInterface), query-types (string semantics warning for MERGE actions).
1.1.0 - 2026-06-08
- Shorthand CTE syntax:
MaybeReturnableQueryInterface(SelectQuery, ValuesQuery) can now be passed directly towith()/addWith()without manualnew WithQuery(...)wrapping. Normalization is handled automatically inWithTrait.
1.0.1 - 2026-06-08
- Fix
AbstractGrammar::buildDistinctClausepassingboolinstead of'DISTINCT'string toExprconstructor, causing broken SQL in all non-PgSql dialects. - Fix
MySqlGrammar::buildLimitClausecrashing onExprInterfaceoffset/limit values by usingValueBuilderfor safe expression rendering. - Fix
andWhereandandHavingoverwriting conditions with identical string keys viaarray_merge— now wrap inAndExprto preserve all conditions. - Fix
BoolOpsExpr::doBuildcrashing on empty conditions array with explicitQueryBuilderException::emptyBoolExpression(). - Fix duplicate validation logic in
buildUpdateQueryby extractingvalidateUpdateQuery()intoAbstractGrammar. - Fix
OpExpr::doBuildusing$params ??=instead of explicit$params =assignment. - Fix
HExpr::testSelectExprduplicatingtestExprby delegating the call. - Fix
PgSqlSelectQuery::addDistinctOnusing assignment instead ofarray_merge, causing column replacement instead of appending. - CROSS JOIN больше не требует и не допускает условий соединения (ON clause), согласно стандарту SQL.
- Remove redundant parentheses around column identifiers in short-syntax JOIN conditions (
['column' => value]). String values in join condition arrays are now wrapped inColumnExprinstead ofExpr, preventing unnecessary parenthesization inOpExpr::doBuild(). - Fix
buildWithClauseto separate multiple CTEs with a comma (,) instead of a space (), correcting generated SQL for multi-CTE queries.
- Comprehensive DISTINCT/DISTINCT ON tests: 7 new test methods covering AbstractGrammar, PgSqlGrammar, multiple columns, Expr objects,
distinct(false)clearing invariant,addDistinctOnappending, and toggle on/off.
1.0.0 - 2026-06-04
- SELECT query building with all standard clauses: columns, aliases, DISTINCT, FROM, JOIN (INNER, LEFT, RIGHT, FULL, CROSS), WHERE, GROUP BY, HAVING, WINDOW functions, ORDER BY, LIMIT/OFFSET, locking (FOR UPDATE/FOR SHARE/SKIP LOCKED/NOWAIT).
- INSERT query building with column and value specification.
- UPDATE query building with SET clauses and WHERE conditions.
- DELETE query building with WHERE conditions.
- VALUES query building for row-constructor expressions.
- Set operations (UNION, UNION ALL, INTERSECT, EXCEPT) with parenthesization support.
- Common Table Expressions (WITH clause) including recursive CTEs.
- SQL expression system:
Expr,Literal,OpExpr,AndExpr,OrExpr,InExpr,BoolOpsExpr. - Three SQL dialect grammars:
DefaultGrammar— ANSI SQL with double-quote identifier escaping.MySqlGrammar— MySQL dialect with backtick escaping, PARTITION, DELETE/INSERT/UPDATE modifiers, MySQL-specific lock modes.PgSqlGrammar— PostgreSQL dialect with RETURNING, DISTINCT ON, ONLY modifier, USING clause, CTE materialization (SEARCH/CYCLE), PostgreSQL-specific lock modes.
ValueBuilder— automatic type dispatch for values (scalars, enums, expressions, sub-queries, arrays).- Named parameter binding with automatic parameter ID generation.
- Fluent trait-based architecture:
WithTrait,FromTrait,WhereTrait,JoinTrait,OperationsTrait,OrderByTrait,LimitTrait. - Support for PHP 8.5+ with property hooks and promoted properties.
- Documentation: README, quick-start, dialects, expressions, query-types guides.
- CI pipeline: GitHub Actions with PHPUnit and PHP-CS-Fixer.
.gitattributesexport-ignore configuration for distribution builds.- MERGE query support (in development).
- Additional SQL dialect implementations (in development).
- Fix
OpExprto convert!=/<> NULL/TRUE/FALSEtoIS NOT NULL/TRUE/FALSEinstead of generating invalid SQL. - Remove redundant double parentheses in VALUES row lists when row values are arrays (
VALUES ((1, 'Bob'))→VALUES (1, 'Bob')). - Fix test regex patterns to expect single parentheses in VALUES output, matching corrected production code.
- Remove excessive parentheses around column identifiers in short-syntax WHERE/HAVING conditions (
['column' => value]). AddedColumnExprmarker class to distinguish simple column identifiers from complex expressions.