Commit 475097dd authored by Bill Schaller's avatar Bill Schaller Committed by GitHub

Merge pull request #2408 from TwoWholeWorms/hotfix-2313-infinite-loop

Hotfix 2313 infinite loop
parents 30044735 7c8fe9c9
...@@ -1224,12 +1224,16 @@ class SQLServerPlatform extends AbstractPlatform ...@@ -1224,12 +1224,16 @@ class SQLServerPlatform extends AbstractPlatform
*/ */
private function scrubInnerOrderBy($query) private function scrubInnerOrderBy($query)
{ {
$count = substr_count(strtoupper($query), "ORDER BY"); $count = substr_count(strtoupper($query), 'ORDER BY');
$offset = 0; $offset = 0;
while ($count-- > 0) { while ($count-- > 0) {
$orderByPos = stripos($query, ' ORDER BY', $offset);
if ($orderByPos === false) {
break;
}
$qLen = strlen($query); $qLen = strlen($query);
$orderByPos = stripos($query, " ORDER BY", $offset);
$parenCount = 0; $parenCount = 0;
$currentPosition = $orderByPos; $currentPosition = $orderByPos;
...@@ -1281,7 +1285,7 @@ class SQLServerPlatform extends AbstractPlatform ...@@ -1281,7 +1285,7 @@ class SQLServerPlatform extends AbstractPlatform
} }
// Only yank query text on the same nesting level as the ORDER BY clause. // Only yank query text on the same nesting level as the ORDER BY clause.
$subQueryBuffer = ($parenCount === 0 ? $query[$currentPosition] : " ") . $subQueryBuffer; $subQueryBuffer = ($parenCount === 0 ? $query[$currentPosition] : ' ') . $subQueryBuffer;
$currentPosition--; $currentPosition--;
} }
......
...@@ -7,6 +7,7 @@ use Doctrine\DBAL\Platforms\SQLServerPlatform; ...@@ -7,6 +7,7 @@ use Doctrine\DBAL\Platforms\SQLServerPlatform;
class SQLServerPlatformTest extends AbstractSQLServerPlatformTestCase class SQLServerPlatformTest extends AbstractSQLServerPlatformTestCase
{ {
public function createPlatform() public function createPlatform()
{ {
return new SQLServerPlatform; return new SQLServerPlatform;
...@@ -24,6 +25,15 @@ class SQLServerPlatformTest extends AbstractSQLServerPlatformTestCase ...@@ -24,6 +25,15 @@ class SQLServerPlatformTest extends AbstractSQLServerPlatformTestCase
$this->assertSame($expectedResult, $this->_platform->appendLockHint($fromClause, $lockMode)); $this->assertSame($expectedResult, $this->_platform->appendLockHint($fromClause, $lockMode));
} }
/**
* @group DBAL-2408
* @dataProvider getModifyLimitQueries
*/
public function testScrubInnerOrderBy($query, $limit, $offset, $expectedResult)
{
$this->assertSame($expectedResult, $this->_platform->modifyLimitQuery($query, $limit, $offset));
}
public function getLockHints() public function getLockHints()
{ {
return array( return array(
...@@ -36,4 +46,16 @@ class SQLServerPlatformTest extends AbstractSQLServerPlatformTestCase ...@@ -36,4 +46,16 @@ class SQLServerPlatformTest extends AbstractSQLServerPlatformTestCase
array(LockMode::PESSIMISTIC_WRITE, ' WITH (UPDLOCK, ROWLOCK)'), array(LockMode::PESSIMISTIC_WRITE, ' WITH (UPDLOCK, ROWLOCK)'),
); );
} }
public function getModifyLimitQueries()
{
return array(
// Test re-ordered query with correctly-scrubbed ORDER BY clause
array('SELECT id_0, MIN(sclr_2) AS dctrn_minrownum FROM (SELECT c0_.id AS id_0, c0_.title AS title_1, ROW_NUMBER() OVER(ORDER BY c0_.title ASC) AS sclr_2 FROM TestTable c0_ ORDER BY c0_.title ASC) dctrn_result GROUP BY id_0 ORDER BY dctrn_minrownum ASC', 30, null, 'WITH dctrn_cte AS (SELECT TOP 30 id_0, MIN(sclr_2) AS dctrn_minrownum FROM (SELECT c0_.id AS id_0, c0_.title AS title_1, ROW_NUMBER() OVER(ORDER BY c0_.title ASC) AS sclr_2 FROM TestTable c0_) dctrn_result GROUP BY id_0 ORDER BY dctrn_minrownum ASC) SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS doctrine_rownum FROM dctrn_cte) AS doctrine_tbl WHERE doctrine_rownum BETWEEN 1 AND 30 ORDER BY doctrine_rownum ASC'),
// Test re-ordered query with no scrubbed ORDER BY clause
array('SELECT id_0, MIN(sclr_2) AS dctrn_minrownum FROM (SELECT c0_.id AS id_0, c0_.title AS title_1, ROW_NUMBER() OVER(ORDER BY c0_.title ASC) AS sclr_2 FROM TestTable c0_) dctrn_result GROUP BY id_0 ORDER BY dctrn_minrownum ASC', 30, null, 'WITH dctrn_cte AS (SELECT TOP 30 id_0, MIN(sclr_2) AS dctrn_minrownum FROM (SELECT c0_.id AS id_0, c0_.title AS title_1, ROW_NUMBER() OVER(ORDER BY c0_.title ASC) AS sclr_2 FROM TestTable c0_) dctrn_result GROUP BY id_0 ORDER BY dctrn_minrownum ASC) SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS doctrine_rownum FROM dctrn_cte) AS doctrine_tbl WHERE doctrine_rownum BETWEEN 1 AND 30 ORDER BY doctrine_rownum ASC'),
);
}
} }
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