lateral join
This commit is contained in:
@@ -47,6 +47,7 @@ class Join
|
||||
|
||||
private ?WhereItem $conditions = null;
|
||||
private bool $onlyMiddle = false;
|
||||
private bool $isLateral = false;
|
||||
|
||||
private function __construct(
|
||||
private string|Select $target,
|
||||
@@ -132,6 +133,16 @@ class Join
|
||||
return $this->onlyMiddle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is LATERAL.
|
||||
*
|
||||
* @since 9.1.6
|
||||
*/
|
||||
public function isLateral(): bool
|
||||
{
|
||||
return $this->isLateral;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create.
|
||||
*
|
||||
@@ -216,4 +227,21 @@ class Join
|
||||
|
||||
return $obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* With LATERAL. Only for a sub-query join.
|
||||
*
|
||||
* @since 9.1.6
|
||||
*/
|
||||
public function withLateral(bool $isLateral = true): self
|
||||
{
|
||||
if (!$this->isSubQuery()) {
|
||||
throw new LogicException("Lateral can be used only with sub-query joins.");
|
||||
}
|
||||
|
||||
$obj = clone $this;
|
||||
$obj->isLateral = $isLateral;
|
||||
|
||||
return $obj;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,6 +201,7 @@ trait SelectingBuilderTrait
|
||||
): self {
|
||||
|
||||
$onlyMiddle = false;
|
||||
$isLateral = false;
|
||||
|
||||
/** @var string|Join|array<int, mixed> $target */
|
||||
|
||||
@@ -208,6 +209,8 @@ trait SelectingBuilderTrait
|
||||
$alias = $alias ?? $target->getAlias();
|
||||
$conditions = $conditions ?? $target->getConditions();
|
||||
$onlyMiddle = $target->isOnlyMiddle();
|
||||
$isLateral = $target->isLateral();
|
||||
|
||||
$target = $target->getTarget();
|
||||
}
|
||||
|
||||
@@ -256,6 +259,10 @@ trait SelectingBuilderTrait
|
||||
$params['onlyMiddle'] = true;
|
||||
}
|
||||
|
||||
if ($isLateral) {
|
||||
$params['isLateral'] = true;
|
||||
}
|
||||
|
||||
if ($params !== []) {
|
||||
$this->params[$type][] = [$target, $alias, $conditions, $params];
|
||||
|
||||
|
||||
@@ -3140,6 +3140,18 @@ abstract class BaseQueryComposer implements QueryComposer
|
||||
|
||||
$value = $right;
|
||||
|
||||
if ($isNotValue) {
|
||||
if (is_null($value)) {
|
||||
return $sql;
|
||||
}
|
||||
|
||||
$rightPart = $this->convertComplexExpression($entity, $value, false, $params);
|
||||
|
||||
$sql .= " " . $operator . " " . $rightPart;
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
if (is_null($value)) {
|
||||
if ($operator === '=') {
|
||||
$sql .= " IS NULL";
|
||||
@@ -3150,14 +3162,6 @@ abstract class BaseQueryComposer implements QueryComposer
|
||||
return $sql;
|
||||
}
|
||||
|
||||
if ($isNotValue) {
|
||||
$rightPart = $this->convertComplexExpression($entity, $value, false, $params);
|
||||
|
||||
$sql .= " " . $operator . " " . $rightPart;
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
$sql .= " " . $operator . " " . $this->quote($value);
|
||||
|
||||
return $sql;
|
||||
@@ -3206,7 +3210,13 @@ abstract class BaseQueryComposer implements QueryComposer
|
||||
|
||||
$aliasPart = $this->quoteIdentifier($alias);
|
||||
|
||||
$sql = $prefixPart . "JOIN $targetPart AS $aliasPart";
|
||||
$sql = $prefixPart . "JOIN ";
|
||||
|
||||
if (!empty($joinParams['isLateral'])) {
|
||||
$sql .= "LATERAL ";
|
||||
}
|
||||
|
||||
$sql .= "$targetPart AS $aliasPart";
|
||||
|
||||
if ($conditions === []) {
|
||||
return $sql;
|
||||
|
||||
@@ -1057,6 +1057,39 @@ class MysqlQueryComposerTest extends \PHPUnit\Framework\TestCase
|
||||
);
|
||||
}
|
||||
|
||||
public function testJoinSubQueryLateral(): void
|
||||
{
|
||||
$sql =
|
||||
"SELECT post.id AS `id` FROM `post` " .
|
||||
"JOIN LATERAL (SELECT post.id AS `id` FROM `post` LIMIT 0, 1) AS `a` ON TRUE";
|
||||
|
||||
$select = SelectBuilder::create()
|
||||
->select('id')
|
||||
->from('Post')
|
||||
->join(
|
||||
Join::createWithSubQuery(
|
||||
SelectBuilder::create()
|
||||
->select('id')
|
||||
->from('Post')
|
||||
->limit(0, 1)
|
||||
->withDeleted()
|
||||
->build(),
|
||||
'a',
|
||||
)
|
||||
->withLateral()
|
||||
->withConditions(
|
||||
Expression::value(true)
|
||||
)
|
||||
)
|
||||
->withDeleted()
|
||||
->build();
|
||||
|
||||
$this->assertEquals(
|
||||
$sql,
|
||||
$this->query->composeSelect($select)
|
||||
);
|
||||
}
|
||||
|
||||
public function testJoinSubQueryException1(): void
|
||||
{
|
||||
$this->expectException(LogicException::class);
|
||||
|
||||
Reference in New Issue
Block a user