Skip to content

Commit

Permalink
Oracle platform ignores OFFSET in case if LIMIT is not specified
Browse files Browse the repository at this point in the history
  • Loading branch information
morozov authored and deeky666 committed Jan 16, 2017
1 parent 3a35136 commit b9a3b08
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 13 deletions.
31 changes: 18 additions & 13 deletions lib/Doctrine/DBAL/Platforms/OraclePlatform.php
Original file line number Diff line number Diff line change
Expand Up @@ -974,24 +974,29 @@ public function getName()
*/
protected function doModifyLimitQuery($query, $limit, $offset = null)
{
$limit = (int) $limit;
$offset = (int) $offset;
if ($limit === null && $offset === null) {
return $query;
}

if (preg_match('/^\s*SELECT/i', $query)) {
if (!preg_match('/\sFROM\s/i', $query)) {
$query .= " FROM dual";
}
if ($limit > 0) {
$max = $offset + $limit;
$column = '*';
if ($offset > 0) {
$min = $offset + 1;
$query = 'SELECT * FROM (SELECT a.' . $column . ', rownum AS doctrine_rownum FROM (' .
$query .
') a WHERE rownum <= ' . $max . ') WHERE doctrine_rownum >= ' . $min;
} else {
$query = 'SELECT a.' . $column . ' FROM (' . $query . ') a WHERE ROWNUM <= ' . $max;
}

$columns = array('a.*');

if ($offset > 0) {
$columns[] = 'ROWNUM AS doctrine_rownum';
}

$query = sprintf('SELECT %s FROM (%s) a', implode(', ', $columns), $query);

if ($limit !== null) {
$query .= sprintf(' WHERE ROWNUM <= %d', $offset + $limit);
}

if ($offset > 0) {
$query = sprintf('SELECT * FROM (%s) WHERE doctrine_rownum >= %d', $query, $offset + 1);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public function testModifyLimitQuerySimpleQuery()
$this->assertLimitResult(array(1, 2, 3, 4), $sql, 10, 0);
$this->assertLimitResult(array(1, 2), $sql, 2, 0);
$this->assertLimitResult(array(3, 4), $sql, 2, 2);
$this->assertLimitResult(array(2, 3, 4), $sql, null, 1);
}

public function testModifyLimitQueryJoinQuery()
Expand Down
12 changes: 12 additions & 0 deletions tests/Doctrine/Tests/DBAL/Platforms/OraclePlatformTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,18 @@ public function testModifyLimitQueryWithEmptyOffset()
$this->assertEquals('SELECT a.* FROM (SELECT * FROM user) a WHERE ROWNUM <= 10', $sql);
}

public function testModifyLimitQueryWithNonEmptyOffset()
{
$sql = $this->_platform->modifyLimitQuery('SELECT * FROM user', 10, 10);
$this->assertEquals('SELECT * FROM (SELECT a.*, ROWNUM AS doctrine_rownum FROM (SELECT * FROM user) a WHERE ROWNUM <= 20) WHERE doctrine_rownum >= 11', $sql);
}

public function testModifyLimitQueryWithEmptyLimit()
{
$sql = $this->_platform->modifyLimitQuery('SELECT * FROM user', null, 10);
$this->assertEquals('SELECT * FROM (SELECT a.*, ROWNUM AS doctrine_rownum FROM (SELECT * FROM user) a) WHERE doctrine_rownum >= 11', $sql);
}

public function testModifyLimitQueryWithAscOrderBy()
{
$sql = $this->_platform->modifyLimitQuery('SELECT * FROM user ORDER BY username ASC', 10);
Expand Down

0 comments on commit b9a3b08

Please sign in to comment.