Skip to content

Commit 677c031

Browse files
authored
Add support for UNION ALL and UNION DISTINCT (#89)
The code now supports UNION ALL and UNION DISTINCT statements in addition to the standard UNION. The MagicQueryTest.php file has been updated with added test cases to reflect these changes. Union.php and StatementFactory.php were modified to handle the additional logic required for the new union types.
1 parent 5107ebf commit 677c031

File tree

3 files changed

+26
-7
lines changed

3 files changed

+26
-7
lines changed

src/SQLParser/Query/StatementFactory.php

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,16 @@ public static function toObject(array $desc)
9292
}
9393

9494
return $select;
95-
} elseif (isset($desc['UNION'])) {
95+
}
96+
// UNION and UNION DISTINCT have similar behavior
97+
if (isset($desc['UNION']) || isset($desc['UNION ALL']) || isset($desc['UNION DISTINCT'])) {
98+
$isUnionAll = isset($desc['UNION ALL']);
99+
$unionStatement = $desc['UNION'] ?? ($desc['UNION ALL'] ?? $desc['UNION DISTINCT']);
100+
96101
/** @var Select[] $selects */
97-
$selects = array_map([self::class, 'toObject'], $desc['UNION']);
102+
$selects = array_map([self::class, 'toObject'], $unionStatement);
98103

99-
$union = new Union($selects);
104+
$union = new Union($selects, $isUnionAll);
100105

101106
if (isset($desc['0']) && isset($desc['0']['ORDER'])) {
102107
$order = NodeFactory::mapArrayToNodeObjectList($desc['0']['ORDER']);
@@ -105,9 +110,9 @@ public static function toObject(array $desc)
105110
}
106111

107112
return $union;
108-
} else {
109-
throw new \BadMethodCallException('Unknown query');
110113
}
114+
115+
throw new \BadMethodCallException('Unknown query');
111116
}
112117

113118
/**

src/SQLParser/Query/Union.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,19 @@ class Union implements StatementInterface, NodeInterface
2525
*/
2626
private $selects;
2727

28+
/**
29+
* @var bool
30+
*/
31+
private $isUnionAll;
32+
2833
/**
2934
* Union constructor.
3035
* @param Select[] $selects
3136
*/
32-
public function __construct(array $selects)
37+
public function __construct(array $selects, bool $isUnionAll)
3338
{
3439
$this->selects = $selects;
40+
$this->isUnionAll = $isUnionAll;
3541
}
3642

3743
/** @var NodeInterface[]|NodeInterface */
@@ -105,7 +111,9 @@ public function toSql(array $parameters, AbstractPlatform $platform, int $indent
105111
return $select->toSql($parameters, $platform, $indent, $conditionsMode, $extrapolateParameters);
106112
}, $this->selects);
107113

108-
$sql = '(' . implode(') UNION (', $selectsSql) . ')';
114+
$unionStatement = $this->isUnionAll ? 'UNION ALL' : 'UNION';
115+
116+
$sql = '(' . implode(') ' . $unionStatement . ' (', $selectsSql) . ')';
109117

110118
if (!empty($this->order)) {
111119
$order = NodeFactory::toSql($this->order, $platform, $parameters, ',', false, $indent + 2, $conditionsMode, $extrapolateParameters);

tests/Mouf/Database/MagicQueryTest.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,12 @@ public function testStandardSelect()
188188
$sql = 'SELECT a FROM users UNION SELECT a FROM users';
189189
$this->assertEquals('(SELECT a FROM users) UNION (SELECT a FROM users)', self::simplifySql($magicQuery->build($sql)));
190190

191+
$sql = 'SELECT a FROM users UNION ALL SELECT a FROM users';
192+
$this->assertEquals('(SELECT a FROM users) UNION ALL (SELECT a FROM users)', self::simplifySql($magicQuery->build($sql)));
193+
194+
$sql = 'SELECT a FROM users UNION DISTINCT SELECT a FROM users';
195+
$this->assertEquals('(SELECT a FROM users) UNION (SELECT a FROM users)', self::simplifySql($magicQuery->build($sql)));
196+
191197
$sql = 'SELECT a FROM users u, users u2';
192198
$this->assertEquals('SELECT a FROM users u CROSS JOIN users u2', self::simplifySql($magicQuery->build($sql)));
193199

0 commit comments

Comments
 (0)