Skip to content

Commit 31191b7

Browse files
authored
Use ordered option in ArrayMergeBuilder (#390)
1 parent 201babc commit 31191b7

3 files changed

Lines changed: 48 additions & 2 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
- Enh #377: Remove `TableSchema` class and refactor `Schema` class (@Tigrov)
5050
- Enh #380: Support column's collation (@Tigrov)
5151
- New #385: Add `Connection::getColumnBuilderClass()` method (@Tigrov)
52-
- New #384: Implement `ArrayMergeBuilder`, `GreatestBuilder` and `LeastBuilder` classes (@Tigrov)
52+
- New #384, #390: Implement `ArrayMergeBuilder`, `GreatestBuilder` and `LeastBuilder` classes (@Tigrov)
5353
- Enh #387: Refactor `DMLQueryBuilder::upsert()` method (@Tigrov)
5454

5555
## 1.2.0 March 21, 2024

src/Builder/ArrayMergeBuilder.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@ protected function buildFromExpression(MultiOperandFunction $expression, array &
4343
$selects[] = "SELECT value FROM json_each($builtOperand)";
4444
}
4545

46-
return '(SELECT json_group_array(value) AS value FROM (' . implode(' UNION ', $selects) . '))';
46+
$unions = implode(' UNION ', $selects);
47+
48+
if ($expression->getOrdered()) {
49+
$unions .= ' ORDER BY value';
50+
}
51+
52+
return '(SELECT json_group_array(value) AS value FROM (' . $unions . '))';
4753
}
4854
}

tests/QueryBuilderTest.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@
88
use PHPUnit\Framework\Attributes\DataProviderExternal;
99
use Yiisoft\Db\Constant\DataType;
1010
use Yiisoft\Db\Exception\NotSupportedException;
11+
use Yiisoft\Db\Expression\ArrayExpression;
1112
use Yiisoft\Db\Expression\CaseExpression;
1213
use Yiisoft\Db\Expression\Expression;
1314
use Yiisoft\Db\Expression\ExpressionInterface;
15+
use Yiisoft\Db\Expression\Function\ArrayMerge;
1416
use Yiisoft\Db\Expression\Param;
1517
use Yiisoft\Db\Query\Query;
1618
use Yiisoft\Db\Query\QueryInterface;
@@ -19,6 +21,7 @@
1921
use Yiisoft\Db\Sqlite\Tests\Provider\QueryBuilderProvider;
2022
use Yiisoft\Db\Sqlite\Tests\Support\TestTrait;
2123
use Yiisoft\Db\Tests\Common\CommonQueryBuilderTest;
24+
use Yiisoft\Db\Tests\Support\Assert;
2225

2326
/**
2427
* @group sqlite
@@ -746,4 +749,41 @@ public function testMultiOperandFunctionBuilderWithoutOperands(string $class): v
746749
{
747750
parent::testMultiOperandFunctionBuilderWithoutOperands($class);
748751
}
752+
753+
public function testArrayMergeWithOrdering(): void
754+
{
755+
$db = $this->getConnection();
756+
$qb = $db->getQueryBuilder();
757+
758+
$stringParam = new Param('[4,3,5]', DataType::STRING);
759+
$arrayMerge = (new ArrayMerge(
760+
"'[2,1,3]'",
761+
[6, 5, 7],
762+
$stringParam,
763+
self::getDb()->select(new ArrayExpression([10, 9])),
764+
))->ordered();
765+
$params = [];
766+
767+
$this->assertSame(
768+
'(SELECT json_group_array(value) AS value FROM ('
769+
. "SELECT value FROM json_each('[2,1,3]')"
770+
. ' UNION SELECT value FROM json_each(:qp0)'
771+
. ' UNION SELECT value FROM json_each(:qp1)'
772+
. ' UNION SELECT value FROM json_each((SELECT :qp2))'
773+
. ' ORDER BY value))',
774+
$qb->buildExpression($arrayMerge, $params)
775+
);
776+
Assert::arraysEquals(
777+
[
778+
':qp0' => new Param('[6,5,7]', DataType::STRING),
779+
':qp1' => $stringParam,
780+
':qp2' => new Param('[10,9]', DataType::STRING),
781+
],
782+
$params,
783+
);
784+
785+
$result = $db->select($arrayMerge)->scalar();
786+
787+
$this->assertEquals('[1,2,3,4,5,6,7,9,10]', $result);
788+
}
749789
}

0 commit comments

Comments
 (0)