Skip to content

Commit

Permalink
Process LIMIT and OFFSET individually by using >= and <= instead of B…
Browse files Browse the repository at this point in the history
…ETWEEN
  • Loading branch information
morozov committed Sep 13, 2016
1 parent ec8fc16 commit 9175755
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 7 deletions.
13 changes: 10 additions & 3 deletions lib/Doctrine/DBAL/Platforms/DB2Platform.php
Original file line number Diff line number Diff line change
Expand Up @@ -775,12 +775,19 @@ protected function doModifyLimitQuery($query, $limit, $offset = null)
return $query;
}

$limit = (int) $limit;
$offset = (int) (($offset)?:0);
$where = array();

if ($offset !== null) {
$where[] = 'db22.DC_ROWNUM >= ' . ($offset + 1);
}

if ($limit !== null) {
$where[] = 'db22.DC_ROWNUM <= ' . (($offset ?: 0) + $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);
'FROM (' . $query . ') db21) db22 WHERE ' . implode(' AND ', $where);

return $sql;
}
Expand Down
10 changes: 10 additions & 0 deletions tests/Doctrine/Tests/DBAL/Functional/ModifyLimitQueryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,16 @@ public function testModifyLimitQueryLineBreaks()
$this->assertLimitResult(array(2), $sql, 1, 1);
}

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();
Expand Down
8 changes: 4 additions & 4 deletions tests/Doctrine/Tests/DBAL/Platforms/DB2PlatformTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 >= 1 AND 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)
);
}
Expand Down

0 comments on commit 9175755

Please sign in to comment.