You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
SELECT "documents".*,"dup".*
FROM "documents"
LEFT JOIN "documents" "dup"
ON ("documents"."filehash" = "dup"."filehash"
AND "documents"."company_id" = "dup"."company_id"
AND "documents"."id" != "dup"."id"
)
Try to define a relation in model Document
public function getDuplicates()
{
return $this->hasMany(Document::class, ['filehash' => 'filehash', 'company_id' => 'company_id'])
->alias('dup')
->onCondition(new Expression('"dup"."id" != "documents"."id"'));
}
SQLSTATE[42P01]: Undefined table: 7 ERROR: invalid reference to FROM-clause entry for table "documents"
LINE 1: ..._id") IN (($1, $2), ($3, $4))) AND ("dup"."id" != "documents...
^
HINT: Perhaps you meant to reference the table alias "dup".
The SQL being executed was: SELECT * FROM "documents" "dup" WHERE (("filehash", "company_id") IN (('e53d24bd42e888cd7d7824132f1fd5a0c9ed9fe2', 5), ('e53d24bd42e888cd7d7824132f1fd5a0c9ed9fe2', 5))) AND ("dup"."id" != "documents"."id")
But command SQL is OK :
$query = new ActiveQuery(Document::class);
$query->alias('documents')->joinWith('duplicates')->createCommand()->getRawSql();
return SELECT "documents".* FROM "documents" "documents" LEFT JOIN "documents" "dup" ON ("documents"."filehash" = "dup"."filehash" AND "documents"."company_id" = "dup"."company_id") AND ("dup"."id" != "documents"."id")
@Insolita
This could be possible with my changes introduced in #19137
So it would look like this:
class Document extends ActiveRecord
{
public function getDuplicates()
{
return $this->hasMany(Document::class, ['filehash' => 'filehash', 'company_id' => 'company_id']);
}
}
$query = New ActiveQuery(Document::class);
$query->joinWith(['duplicates' => function ($q) use ($query) {
$q->andOnCondition(['NOT', ['id' => new Expression($query->field('id'))]]);
}])->all();
And it will generate query:
SELECT `document`.* FROM `document` LEFT JOIN `document` `Document<duplicates>` ON (`document`.`filehash` = `Document<duplicates>`.`filehash` AND `document`.`company_id` = `Document<duplicates>`.`company_id`) AND (NOT (`Document<duplicates>`.`id`=`document`.`id`))
So you don't need to do any alias, even if join with same table
Required query
Try to define a relation in model Document
Query
Fails with error
But command SQL is OK :
return
SELECT "documents".* FROM "documents" "documents" LEFT JOIN "documents" "dup" ON ("documents"."filehash" = "dup"."filehash" AND "documents"."company_id" = "dup"."company_id") AND ("dup"."id" != "documents"."id")
The problem comes from ActiveQuery populate
https://github.com/yiisoft/yii2/blob/master/framework/db/Query.php#L251
https://github.com/yiisoft/yii2/blob/master/framework/db/ActiveQuery.php#L224
https://github.com/yiisoft/yii2/blob/master/framework/db/ActiveQueryTrait.php#L151
This method replaces values from relation "link" to real values, but it doesn't touch "onCondition" expression,
https://github.com/yiisoft/yii2/blob/master/framework/db/ActiveRelationTrait.php#L517
This method executes the wrong query
https://github.com/yiisoft/yii2/blob/master/framework/db/ActiveRelationTrait.php#L270
(Same for yii3 yiisoft/active-record#153)
The text was updated successfully, but these errors were encountered: