orm join condition alias handling change

This commit is contained in:
Yuri Kuznetsov
2022-11-14 14:13:59 +02:00
parent 8efe9842cf
commit a5ba3ca5db
5 changed files with 96 additions and 24 deletions
@@ -185,6 +185,8 @@ trait SelectingBuilderTrait
* A relation name or table. A relation name should be in camelCase, a table in CamelCase.
* @param string|null $alias An alias.
* @param WhereItem|array<mixed, mixed>|null $conditions Join conditions.
*
* @todo Support USE INDEX in Join.
*/
private function joinInternal(string $type, $target, ?string $alias = null, $conditions = null): self
{
@@ -201,8 +203,12 @@ trait SelectingBuilderTrait
throw new InvalidArgumentException("Conditions must be WhereItem or array.");
}
$noLeftAlias = false;
if ($conditions instanceof WhereItem) {
$conditions = $conditions->getRaw();
$noLeftAlias = true;
}
if (empty($this->params[$type])) {
@@ -235,7 +241,13 @@ trait SelectingBuilderTrait
return $this;
}
$this->params[$type][] = [$target, $alias, $conditions];
$item = [$target, $alias, $conditions];
if ($noLeftAlias) {
$item[] = ['noLeftAlias' => true];
}
$this->params[$type][] = $item;
return $this;
}
@@ -3013,7 +3013,8 @@ abstract class BaseQueryComposer implements QueryComposer
string $alias,
$left,
$right,
array $params
array $params,
bool $noLeftAlias = false
): string {
$sql = '';
@@ -3028,7 +3029,7 @@ abstract class BaseQueryComposer implements QueryComposer
$sqlList = [];
foreach ($right as $k => $v) {
$sqlList[] = $this->buildJoinConditionStatement($entity, $alias, $k, $v, $params);
$sqlList[] = $this->buildJoinConditionStatement($entity, $alias, $k, $v, $params, $noLeftAlias);
}
$sql = implode(' ' .$logicalOperator . ' ', $sqlList);
@@ -3071,16 +3072,20 @@ abstract class BaseQueryComposer implements QueryComposer
if (!$isComplex) {
if (strpos($left, '.') > 0) {
list($alias, $attribute) = explode('.', $left);
list($leftAlias, $attribute) = explode('.', $left);
$alias = $this->sanitize($alias);
$leftAlias = $this->sanitize($leftAlias);
$column = $this->toDb($this->sanitize($attribute));
}
else {
$column = $this->toDb($this->sanitize($left));
$leftAlias = $noLeftAlias ?
$this->getFromAlias($params, $entity->getEntityType()) :
$this->sanitize($alias);
}
$sql .= "{$alias}.{$column}";
$sql .= "{$leftAlias}.{$column}";
}
if (is_array($right)) {
@@ -3161,7 +3166,7 @@ abstract class BaseQueryComposer implements QueryComposer
$table = $this->toDb($this->sanitize($name));
$sql = $prefix . "JOIN " . $this->quoteIdentifier($table) . " AS " . $this->quoteIdentifier($alias) . "";
$sql = $prefix . "JOIN " . $this->quoteIdentifier($table) . " AS " . $this->quoteIdentifier($alias);
if (empty($conditions)) {
return $sql;
@@ -3177,7 +3182,8 @@ abstract class BaseQueryComposer implements QueryComposer
$alias,
$left,
$right,
$params
$params,
$joinParams['noLeftAlias'] ?? false,
);
}
@@ -855,6 +855,60 @@ class MysqlQueryComposerTest extends \PHPUnit\Framework\TestCase
$this->assertEquals($expectedSql, $sql);
}
public function testJoinConditions6(): void
{
$query = $this->queryBuilder
->select('id')
->from('Note')
->leftJoin(
'Post',
'post',
Condition::equal(
Expression::column('id'),
Expression::column('post.id')
)
)
->withDeleted()
->build();
$sql = $this->query->composeSelect($query);
$expectedSql = "SELECT note.id AS `id` FROM `note` LEFT JOIN `post` AS `post` ON note.id = post.id";
$this->assertEquals($expectedSql, $sql);
}
public function testJoinConditions7(): void
{
$query = $this->queryBuilder
->select('id')
->from('Note')
->leftJoin(
'Post',
'post',
Condition::or(
Condition::equal(
Expression::column('id'),
Expression::column('post.id')
),
Condition::equal(
Expression::column('post.id'),
Expression::column('id')
)
)
)
->withDeleted()
->build();
$sql = $this->query->composeSelect($query);
$expectedSql =
"SELECT note.id AS `id` FROM `note` ".
"LEFT JOIN `post` AS `post` ON (note.id = post.id OR post.id = note.id)";
$this->assertEquals($expectedSql, $sql);
}
public function testJoinTable1()
{
$sql = $this->query->compose(Select::fromRaw([
@@ -616,7 +616,8 @@ class SelectBuilderTest extends \PHPUnit\Framework\TestCase
'table1',
[
'table1.testId=:' => 'id'
]
],
['noLeftAlias' => true]
]
];
@@ -626,7 +627,8 @@ class SelectBuilderTest extends \PHPUnit\Framework\TestCase
'table2',
[
'table2.testId=:' => 'id'
]
],
['noLeftAlias' => true]
]
];
@@ -511,12 +511,11 @@ class RDBRepositoryTest extends \PHPUnit\Framework\TestCase
public function testJoin5()
{
$paramsExpected = Select::fromRaw([
'from' => 'Test',
'joins' => [
['Test1', 'test1', ['k=' => 'v']],
],
]);
$paramsExpected = $this->queryBuilder
->select()
->from('Test')
->join('Test1', 'test1', Cond::equal(Expr::column('k'), 'v'))
->build();
$this->mapper
->expects($this->once())
@@ -549,12 +548,11 @@ class RDBRepositoryTest extends \PHPUnit\Framework\TestCase
public function testLeftJoin2()
{
$paramsExpected = Select::fromRaw([
'from' => 'Test',
'leftJoins' => [
['Test1', 'test1', ['k=' => 'v']],
],
]);
$paramsExpected = $this->queryBuilder
->select()
->from('Test')
->leftJoin('Test1', 'test1', Cond::equal(Expr::column('k'), 'v'))
->build();
$this->mapper
->expects($this->once())
@@ -1434,7 +1432,7 @@ class RDBRepositoryTest extends \PHPUnit\Framework\TestCase
->select(['id'])
->distinct()
->where(Cond::equal(Expr::column('name'), 'test'))
->join('Test', 'test', ['id=:' => 'id'])
->join('Test', 'test', Cond::equal(Expr::column('test.id'), Expr::column('id')))
->order('id', 'DESC')
->build();
@@ -1451,7 +1449,7 @@ class RDBRepositoryTest extends \PHPUnit\Framework\TestCase
->join(
'Test',
'test',
Cond::equal(Expr::column('id'), Expr::column('id'))
Cond::equal(Expr::column('test.id'), Expr::column('id'))
)
->order('id', 'DESC')
->find();