From 5c720474266f8667d4850fbe7689d5678c6ff143 Mon Sep 17 00:00:00 2001 From: Carsten Brandt Date: Wed, 10 May 2017 10:28:39 +0200 Subject: [PATCH] Fixed ambiguous column name in SELECT in UniqueValidator fixes #14042 --- framework/CHANGELOG.md | 1 + framework/validators/UniqueValidator.php | 7 ++++++- .../validators/UniqueValidatorTest.php | 20 +++++++++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index 87c7bdc9706..094ae4a6fb9 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -33,6 +33,7 @@ Yii Framework 2 Change Log - Bug #13594: Fixes insufficient quoting in `yii\db\QueryBuilder::prepareInsertSelectSubQuery()` (sergeymakinen) - Bug #8120: Fixes LIKE special characters escaping for Cubrid/MSSQL/Oracle/SQLite in `yii\db\QueryBuilder` (sergeymakinen) - Bug #12715: Exception `SAVEPOINT LEVEL1 does not exist` instead of deadlock exception (Vovan-VE) +- Bug #14042: Fixed ambiguous column name in SELECT in UniqueValidator (cebe) - Enh #8641: Enhanced `yii\console\Request::resolve()` to prevent passing parameters, that begin from digits (silverfire) - Enh #13278: `yii\caching\DbQueryDependency` created allowing specification of the cache dependency via `yii\db\QueryInterface` (klimov-paul) - Enh #13467: `yii\data\ActiveDataProvider` no longer queries models if models count is zero (kLkA, Kolyunya) diff --git a/framework/validators/UniqueValidator.php b/framework/validators/UniqueValidator.php index a091772024b..bfc532ebf91 100644 --- a/framework/validators/UniqueValidator.php +++ b/framework/validators/UniqueValidator.php @@ -173,7 +173,12 @@ private function modelExists($targetClass, $conditions, $model) // if current $model is in the database already we can't use exists() if ($query instanceof \yii\db\ActiveQuery) { // only select primary key to optimize query - $query->select($targetClass::primaryKey()); + $primaryAlias = array_keys($query->getTablesUsedInFrom())[0]; + $columns = $targetClass::primaryKey(); + foreach($columns as $c => $column) { + $columns[$c] = "{{{$primaryAlias}}}.$column"; + } + $query->select($columns); } $models = $query->limit(2)->asArray()->all(); $n = count($models); diff --git a/tests/framework/validators/UniqueValidatorTest.php b/tests/framework/validators/UniqueValidatorTest.php index e567ad55888..2f047aed68c 100644 --- a/tests/framework/validators/UniqueValidatorTest.php +++ b/tests/framework/validators/UniqueValidatorTest.php @@ -385,4 +385,24 @@ public function testPrepareQuery() $expected = "SELECT * FROM {$schema->quoteTableName('validator_main')} WHERE ({$schema->quoteColumnName('val_attr_b')}=:qp0) OR (val_attr_a > 0)"; $this->assertEquals($expected, $query->createCommand()->getSql()); } + + /** + * Test ambiguous column name in select clause + * @see https://github.com/yiisoft/yii2/issues/14042 + */ + public function testAmbiguousColumnName() + { + $validator = new UniqueValidator([ + 'filter' => function($query) { + $query->joinWith('items', false); + }, + ]); + $model = new Order(); + $model->id = 42; + $model->customer_id = 1; + $model->total = 800; + $model->save(false); + $validator->validateAttribute($model, 'id'); + $this->assertFalse($model->hasErrors()); + } }