diff --git a/lib/Doctrine/DBAL/Platforms/DB2Platform.php b/lib/Doctrine/DBAL/Platforms/DB2Platform.php index 57eed254c0c..da0d77ced38 100644 --- a/lib/Doctrine/DBAL/Platforms/DB2Platform.php +++ b/lib/Doctrine/DBAL/Platforms/DB2Platform.php @@ -772,18 +772,26 @@ public function getTemporaryTableName($tableName) */ protected function doModifyLimitQuery($query, $limit, $offset = null) { - if ($limit === null && $offset === null) { - return $query; + $where = array(); + + if ($offset > 0) { + $where[] = sprintf('db22.DC_ROWNUM >= %d', $offset + 1); } - $limit = (int) $limit; - $offset = (int) (($offset)?:0); + if ($limit !== null) { + $where[] = sprintf('db22.DC_ROWNUM <= %d', $offset + $limit); + } - // Todo OVER() needs ORDER BY data! - $sql = 'SELECT db22.* FROM (SELECT db21.*, ROW_NUMBER() OVER() AS DC_ROWNUM '. - 'FROM (' . $query . ') db21) db22 WHERE db22.DC_ROWNUM BETWEEN ' . ($offset+1) .' AND ' . ($offset+$limit); + if (empty($where)) { + return $query; + } - return $sql; + // Todo OVER() needs ORDER BY data! + return sprintf( + 'SELECT db22.* FROM (SELECT db21.*, ROW_NUMBER() OVER() AS DC_ROWNUM FROM (%s) db21) db22 WHERE %s', + $query, + implode(' AND ', $where) + ); } /** diff --git a/tests/Doctrine/Tests/DBAL/Functional/ModifyLimitQueryTest.php b/tests/Doctrine/Tests/DBAL/Functional/ModifyLimitQueryTest.php index 8e0de221062..12a8cec6a5e 100644 --- a/tests/Doctrine/Tests/DBAL/Functional/ModifyLimitQueryTest.php +++ b/tests/Doctrine/Tests/DBAL/Functional/ModifyLimitQueryTest.php @@ -113,6 +113,16 @@ public function testModifyLimitQuerySubSelect() $this->assertLimitResult(array(2, 1), $sql, 2, 2, false); } + public function testModifyLimitQueryZeroOffsetNoLimit() + { + $this->_conn->insert('modify_limit_table', array('test_int' => 1)); + $this->_conn->insert('modify_limit_table', array('test_int' => 2)); + + $sql = "SELECT test_int FROM modify_limit_table ORDER BY test_int ASC"; + + $this->assertLimitResult(array(1, 2), $sql, null, 0); + } + public function assertLimitResult($expectedResults, $sql, $limit, $offset, $deterministic = true) { $p = $this->_conn->getDatabasePlatform(); diff --git a/tests/Doctrine/Tests/DBAL/Platforms/DB2PlatformTest.php b/tests/Doctrine/Tests/DBAL/Platforms/DB2PlatformTest.php index e8b8916539a..9e5cd32232d 100644 --- a/tests/Doctrine/Tests/DBAL/Platforms/DB2PlatformTest.php +++ b/tests/Doctrine/Tests/DBAL/Platforms/DB2PlatformTest.php @@ -358,21 +358,21 @@ public function testModifiesLimitQuery() ); $this->assertEquals( - 'SELECT db22.* FROM (SELECT db21.*, ROW_NUMBER() OVER() AS DC_ROWNUM FROM (SELECT * FROM user) db21) db22 WHERE db22.DC_ROWNUM BETWEEN 1 AND 10', + 'SELECT db22.* FROM (SELECT db21.*, ROW_NUMBER() OVER() AS DC_ROWNUM FROM (SELECT * FROM user) db21) db22 WHERE db22.DC_ROWNUM <= 10', $this->_platform->modifyLimitQuery('SELECT * FROM user', 10, 0) ); $this->assertEquals( - 'SELECT db22.* FROM (SELECT db21.*, ROW_NUMBER() OVER() AS DC_ROWNUM FROM (SELECT * FROM user) db21) db22 WHERE db22.DC_ROWNUM BETWEEN 1 AND 10', + 'SELECT db22.* FROM (SELECT db21.*, ROW_NUMBER() OVER() AS DC_ROWNUM FROM (SELECT * FROM user) db21) db22 WHERE db22.DC_ROWNUM <= 10', $this->_platform->modifyLimitQuery('SELECT * FROM user', 10) ); $this->assertEquals( - 'SELECT db22.* FROM (SELECT db21.*, ROW_NUMBER() OVER() AS DC_ROWNUM FROM (SELECT * FROM user) db21) db22 WHERE db22.DC_ROWNUM BETWEEN 6 AND 15', + 'SELECT db22.* FROM (SELECT db21.*, ROW_NUMBER() OVER() AS DC_ROWNUM FROM (SELECT * FROM user) db21) db22 WHERE db22.DC_ROWNUM >= 6 AND db22.DC_ROWNUM <= 15', $this->_platform->modifyLimitQuery('SELECT * FROM user', 10, 5) ); $this->assertEquals( - 'SELECT db22.* FROM (SELECT db21.*, ROW_NUMBER() OVER() AS DC_ROWNUM FROM (SELECT * FROM user) db21) db22 WHERE db22.DC_ROWNUM BETWEEN 6 AND 5', + 'SELECT db22.* FROM (SELECT db21.*, ROW_NUMBER() OVER() AS DC_ROWNUM FROM (SELECT * FROM user) db21) db22 WHERE db22.DC_ROWNUM >= 6 AND db22.DC_ROWNUM <= 5', $this->_platform->modifyLimitQuery('SELECT * FROM user', 0, 5) ); }