diff --git a/CHANGELOG.md b/CHANGELOG.md index 08f9c9a82..19c52888c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -90,6 +90,7 @@ - Chg #972: Change in query "distinct" flag type from `bool|null` to `bool` (@vjik) - New #973: Add `upsertWithReturningPks()` method to `CommandInterface` and `DMLQueryBuilderInterface` (@Tigrov) - New #968: Add `DateTimeColumn` column class (@Tigrov) +- Bug #978: Fix memory leaking in `Command::exists()` method (@Tigrov) ## 1.3.0 March 21, 2024 diff --git a/src/QueryBuilder/AbstractDQLQueryBuilder.php b/src/QueryBuilder/AbstractDQLQueryBuilder.php index 3da5fef20..0f8df89ae 100644 --- a/src/QueryBuilder/AbstractDQLQueryBuilder.php +++ b/src/QueryBuilder/AbstractDQLQueryBuilder.php @@ -468,7 +468,7 @@ public function getExpressionBuilder(ExpressionInterface $expression): object public function selectExists(string $rawSql): string { - return 'SELECT EXISTS(' . $rawSql . ')'; + return 'SELECT EXISTS(' . $rawSql . ') AS ' . $this->quoter->quoteSimpleColumnName('0'); } public function setConditionClasses(array $classes): void diff --git a/tests/AbstractQueryBuilderTest.php b/tests/AbstractQueryBuilderTest.php index d909d9eee..70d85b721 100644 --- a/tests/AbstractQueryBuilderTest.php +++ b/tests/AbstractQueryBuilderTest.php @@ -2129,17 +2129,20 @@ public function testResetSequenceTableNoExistException(): void $qb->resetSequence('noExist', 1); } - /** - * @dataProvider \Yiisoft\Db\Tests\Provider\QueryBuilderProvider::selectExist - */ - public function testSelectExists(string $sql, string $expected): void + public function testSelectExists(): void { $db = $this->getConnection(); - $qb = $db->getQueryBuilder(); - $sqlSelectExist = $qb->selectExists($sql); - $this->assertSame($expected, $sqlSelectExist); + $sql = DbHelper::replaceQuotes('SELECT 1 FROM [[customer]] WHERE [[id]] = 1', $db->getDriverName()); + // Alias required to avoid memory leaking on MySQL. Other DBMS have the same alias for consistency. + // @link https://github.com/yiisoft/yii2/issues/20385 + $expected = DbHelper::replaceQuotes( + 'SELECT EXISTS(SELECT 1 FROM [[customer]] WHERE [[id]] = 1) AS [[0]]', + $db->getDriverName() + ); + + $this->assertSame($expected, $qb->selectExists($sql)); } /** diff --git a/tests/Provider/QueryBuilderProvider.php b/tests/Provider/QueryBuilderProvider.php index aeed12c45..a0e891d4a 100644 --- a/tests/Provider/QueryBuilderProvider.php +++ b/tests/Provider/QueryBuilderProvider.php @@ -1141,26 +1141,6 @@ public static function insertWithReturningPks(): array ]; } - public static function selectExist(): array - { - return [ - [ - DbHelper::replaceQuotes( - <<