diff options
author | Alex Pott | 2016-07-25 09:22:14 (GMT) |
---|---|---|
committer | Alex Pott | 2016-07-25 09:22:14 (GMT) |
commit | 6d3fd71023d38616f4fdf7ae094a46b3ee0f7635 (patch) | |
tree | 0586d38f15d5c136bc3b35e0473c38aeaafc130e | |
parent | 7c0a466ba66121489c7cf7889e3c7453327d2ed8 (diff) |
Issue #1145076 by daffie, David_Rothstein, johnnydarkko, cbergmann, drewish, rpayanm, somersoft, jhedstrom: UNION queries don't support ORDER BY clauses
-rw-r--r-- | core/lib/Drupal/Core/Database/Query/Select.php | 16 | ||||
-rw-r--r-- | core/tests/Drupal/KernelTests/Core/Database/SelectTest.php | 58 |
2 files changed, 66 insertions, 8 deletions
diff --git a/core/lib/Drupal/Core/Database/Query/Select.php b/core/lib/Drupal/Core/Database/Query/Select.php index a5e93e8..b7db605 100644 --- a/core/lib/Drupal/Core/Database/Query/Select.php +++ b/core/lib/Drupal/Core/Database/Query/Select.php @@ -860,6 +860,14 @@ class Select extends Query implements SelectInterface { $query .= "\nHAVING " . $this->having; } + // UNION is a little odd, as the select queries to combine are passed into + // this query, but syntactically they all end up on the same level. + if ($this->union) { + foreach ($this->union as $union) { + $query .= ' ' . $union['type'] . ' ' . (string) $union['query']; + } + } + // ORDER BY if ($this->order) { $query .= "\nORDER BY "; @@ -879,14 +887,6 @@ class Select extends Query implements SelectInterface { $query .= "\nLIMIT " . (int) $this->range['length'] . " OFFSET " . (int) $this->range['start']; } - // UNION is a little odd, as the select queries to combine are passed into - // this query, but syntactically they all end up on the same level. - if ($this->union) { - foreach ($this->union as $union) { - $query .= ' ' . $union['type'] . ' ' . (string) $union['query']; - } - } - if ($this->forUpdate) { $query .= ' FOR UPDATE'; } diff --git a/core/tests/Drupal/KernelTests/Core/Database/SelectTest.php b/core/tests/Drupal/KernelTests/Core/Database/SelectTest.php index b524863..cc857a2 100644 --- a/core/tests/Drupal/KernelTests/Core/Database/SelectTest.php +++ b/core/tests/Drupal/KernelTests/Core/Database/SelectTest.php @@ -323,6 +323,64 @@ class SelectTest extends DatabaseTestBase { } /** + * Tests that we can UNION multiple Select queries together and set the ORDER. + */ + function testUnionOrder() { + // This gives George and Ringo. + $query_1 = db_select('test', 't') + ->fields('t', array('name')) + ->condition('age', array(27, 28), 'IN'); + + // This gives Paul. + $query_2 = db_select('test', 't') + ->fields('t', array('name')) + ->condition('age', 26); + + $query_1->union($query_2); + $query_1->orderBy('name', 'DESC'); + + $names = $query_1->execute()->fetchCol(); + + // Ensure we get all 3 records. + $this->assertEqual(count($names), 3, 'UNION returned rows from both queries.'); + + // Ensure that the names are in the correct reverse alphabetical order, + // regardless of which query they came from. + $this->assertEqual($names[0], 'Ringo', 'First query returned correct name.'); + $this->assertEqual($names[1], 'Paul', 'Second query returned correct name.'); + $this->assertEqual($names[2], 'George', 'Third query returned correct name.'); + } + + /** + * Tests that we can UNION multiple Select queries together with and a LIMIT. + */ + function testUnionOrderLimit() { + // This gives George and Ringo. + $query_1 = db_select('test', 't') + ->fields('t', array('name')) + ->condition('age', array(27, 28), 'IN'); + + // This gives Paul. + $query_2 = db_select('test', 't') + ->fields('t', array('name')) + ->condition('age', 26); + + $query_1->union($query_2); + $query_1->orderBy('name', 'DESC'); + $query_1->range(0, 2); + + $names = $query_1->execute()->fetchCol(); + + // Ensure we get all only 2 of the 3 records. + $this->assertEqual(count($names), 2, 'UNION with a limit returned rows from both queries.'); + + // Ensure that the names are in the correct reverse alphabetical order, + // regardless of which query they came from. + $this->assertEqual($names[0], 'Ringo', 'First query returned correct name.'); + $this->assertEqual($names[1], 'Paul', 'Second query returned correct name.'); + } + + /** * Tests that random ordering of queries works. * * We take the approach of testing the Drupal layer only, rather than trying |