From e342162425d3e63b3ae3affef82220f6b64e01f9 Mon Sep 17 00:00:00 2001 From: DarkDef Date: Tue, 30 Jun 2020 17:59:23 +0300 Subject: [PATCH] Fix #18134: Instance of `ExpressionInterface` will not be quoted in `Connection:quoteColumnName` --- framework/CHANGELOG.md | 1 + framework/db/Connection.php | 6 +++++- tests/framework/db/QueryBuilderTest.php | 17 ++++++++++++++--- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index 2acef5a119..3d1607555e 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -24,6 +24,7 @@ Yii Framework 2 Change Log - Enh #18120: Include path to the log file into error message if `FileTarget::export` fails (uaoleg) - Enh #15202: Add optional param `--silent-exit-on-exception` in `yii\console\Controller` (egorrishe) - Bug #18110: Add quotes to return value of viewName in MSSQL schema. It is `[someView]` now (darkdef) +- Bug #18134: Instance of `ExpressionInterface` will not be quoted in `Connection:quoteColumnName` (darkdef) 2.0.35 May 02, 2020 diff --git a/framework/db/Connection.php b/framework/db/Connection.php index 30c97d9646..bf9c71e27b 100644 --- a/framework/db/Connection.php +++ b/framework/db/Connection.php @@ -925,11 +925,15 @@ class Connection extends Component * If the column name contains prefix, the prefix will also be properly quoted. * If the column name is already quoted or contains special characters including '(', '[[' and '{{', * then this method will do nothing. - * @param string $name column name + * If the column name is an instance of `ExpressionInterface` it is returned as is. + * @param string $name|ExpressionInterface column name * @return string the properly quoted column name */ public function quoteColumnName($name) { + if ($name instanceof ExpressionInterface) { + return $name; + } if (isset($this->_quotedColumnNames[$name])) { return $this->_quotedColumnNames[$name]; } diff --git a/tests/framework/db/QueryBuilderTest.php b/tests/framework/db/QueryBuilderTest.php index f578388de3..6f1ad2c1c8 100644 --- a/tests/framework/db/QueryBuilderTest.php +++ b/tests/framework/db/QueryBuilderTest.php @@ -1200,7 +1200,7 @@ abstract class QueryBuilderTest extends DatabaseTestCase '([[id]], [[name]]) IN ((:qp0, :qp1), (:qp2, :qp3))', [':qp0' => 1, ':qp1' => 'oy', ':qp2' => 2, ':qp3' => 'yo'], ], - + // in object conditions [new InCondition('id', 'in', 1), '[[id]]=:qp0', [':qp0' => 1]], [new InCondition('id', 'in', [1]), '[[id]]=:qp0', [':qp0' => 1]], @@ -1208,7 +1208,7 @@ abstract class QueryBuilderTest extends DatabaseTestCase [new InCondition('id', 'not in', [1]), '[[id]]<>:qp0', [':qp0' => 1]], [new InCondition('id', 'in', [1, 2]), '[[id]] IN (:qp0, :qp1)', [':qp0' => 1, ':qp1' => 2]], [new InCondition('id', 'not in', [1, 2]), '[[id]] NOT IN (:qp0, :qp1)', [':qp0' => 1, ':qp1' => 2]], - + // exists [['exists', (new Query())->select('id')->from('users')->where(['active' => 1])], 'EXISTS (SELECT [[id]] FROM [[users]] WHERE [[active]]=:qp0)', [':qp0' => 1]], [['not exists', (new Query())->select('id')->from('users')->where(['active' => 1])], 'NOT EXISTS (SELECT [[id]] FROM [[users]] WHERE [[active]]=:qp0)', [':qp0' => 1]], @@ -2480,7 +2480,7 @@ abstract class QueryBuilderTest extends DatabaseTestCase '[[location]].[[title_ru]] LIKE :qp0', [':qp0' => 'vi%'], ], - + // like object conditions [new LikeCondition('name', 'like', new Expression('CONCAT("test", name, "%")')), '[[name]] LIKE CONCAT("test", name, "%")', []], [new LikeCondition('name', 'not like', new Expression('CONCAT("test", name, "%")')), '[[name]] NOT LIKE CONCAT("test", name, "%")', []], @@ -2523,6 +2523,17 @@ abstract class QueryBuilderTest extends DatabaseTestCase $this->assertEquals($expectedParams, $params); } + /** + * @see https://github.com/yiisoft/yii2/issues/18134 + */ + public function testExpressionIsNotQuotedInColumnName() + { + $query = (new Query())->where(['like', new Expression('name'), 'string']); + list($sql, $params) = $this->getQueryBuilder()->build($query); + $this->assertEquals('SELECT * WHERE name LIKE :qp0'.$this->likeEscapeCharSql, $sql); + $this->assertEquals([':qp0' => "%string%"], $params); + } + /** * @see https://github.com/yiisoft/yii2/issues/15653 */