Commit 0f7bf0ce authored by Sergei Morozov's avatar Sergei Morozov Committed by Steve Müller

Process LIMIT and OFFSET individually by using >= and <= instead of BETWEEN

parent b9a3b087
......@@ -772,18 +772,26 @@ class DB2Platform extends AbstractPlatform
*/
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)
);
}
/**
......
......@@ -113,6 +113,16 @@ class ModifyLimitQueryTest extends \Doctrine\Tests\DbalFunctionalTestCase
$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();
......
......@@ -358,21 +358,21 @@ class DB2PlatformTest extends AbstractPlatformTestCase
);
$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)
);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment