From 50f3435e846105e7d4ae59c8cd7760498af7e17f Mon Sep 17 00:00:00 2001 From: Guilherme Blanco Date: Thu, 29 Apr 2010 22:15:36 -0300 Subject: [PATCH] Optimized Query AST resultant of the parsing process phase 1 --- lib/Doctrine/ORM/Query/Parser.php | 62 +++++- lib/Doctrine/ORM/Query/SqlWalker.php | 189 +++++++++++------- lib/Doctrine/ORM/Query/TreeWalker.php | 16 ++ lib/Doctrine/ORM/Query/TreeWalkerAdapter.php | 16 ++ lib/Doctrine/ORM/Query/TreeWalkerChain.php | 26 +++ .../ORM/Functional/CustomTreeWalkersTest.php | 72 +++++-- .../ORM/Query/SelectSqlGenerationTest.php | 6 +- 7 files changed, 284 insertions(+), 103 deletions(-) diff --git a/lib/Doctrine/ORM/Query/Parser.php b/lib/Doctrine/ORM/Query/Parser.php index b15248689..241a28751 100644 --- a/lib/Doctrine/ORM/Query/Parser.php +++ b/lib/Doctrine/ORM/Query/Parser.php @@ -267,11 +267,11 @@ class Parser { $AST = $this->getAST(); - if ($customWalkers = $this->_query->getHint(Query::HINT_CUSTOM_TREE_WALKERS)) { + if (($customWalkers = $this->_query->getHint(Query::HINT_CUSTOM_TREE_WALKERS)) !== false) { $this->_customTreeWalkers = $customWalkers; } - if ($customOutputWalker = $this->_query->getHint(Query::HINT_CUSTOM_OUTPUT_WALKER)) { + if (($customOutputWalker = $this->_query->getHint(Query::HINT_CUSTOM_OUTPUT_WALKER)) !== false) { $this->_customOutputWalker = $customOutputWalker; } @@ -1786,6 +1786,12 @@ class Parser $conditionalTerms[] = $this->ConditionalTerm(); } + // Phase 1 AST optimization: Prevent AST\ConditionalExpression + // if only one AST\ConditionalTerm is defined + if (count($conditionalTerms) == 1) { + return $conditionalTerms[0]; + } + return new AST\ConditionalExpression($conditionalTerms); } @@ -1804,6 +1810,12 @@ class Parser $conditionalFactors[] = $this->ConditionalFactor(); } + // Phase 1 AST optimization: Prevent AST\ConditionalTerm + // if only one AST\ConditionalFactor is defined + if (count($conditionalFactors) == 1) { + return $conditionalFactors[0]; + } + return new AST\ConditionalTerm($conditionalFactors); } @@ -1820,11 +1832,19 @@ class Parser $this->match(Lexer::T_NOT); $not = true; } + + $conditionalPrimary = $this->ConditionalPrimary(); - $condFactor = new AST\ConditionalFactor($this->ConditionalPrimary()); - $condFactor->not = $not; + // Phase 1 AST optimization: Prevent AST\ConditionalFactor + // if only one AST\ConditionalPrimary is defined + if ( ! $not) { + return $conditionalPrimary; + } - return $condFactor; + $conditionalFactor = new AST\ConditionalFactor($conditionalPrimary); + $conditionalFactor->not = $not; + + return $conditionalFactor; } /** @@ -2104,6 +2124,12 @@ class Parser $terms[] = $this->ArithmeticTerm(); } + // Phase 1 AST optimization: Prevent AST\SimpleArithmeticExpression + // if only one AST\ArithmeticTerm is defined + if (count($terms) == 1) { + return $terms[0]; + } + return new AST\SimpleArithmeticExpression($terms); } @@ -2124,6 +2150,12 @@ class Parser $factors[] = $this->ArithmeticFactor(); } + // Phase 1 AST optimization: Prevent AST\ArithmeticTerm + // if only one AST\ArithmeticFactor is defined + if (count($factors) == 1) { + return $factors[0]; + } + return new AST\ArithmeticTerm($factors); } @@ -2134,14 +2166,22 @@ class Parser */ public function ArithmeticFactor() { - $sign = null; + $sign = null; - if (($isPlus = $this->_lexer->isNextToken(Lexer::T_PLUS)) || $this->_lexer->isNextToken(Lexer::T_MINUS)) { - $this->match(($isPlus) ? Lexer::T_PLUS : Lexer::T_MINUS); - $sign = $isPlus; - } + if (($isPlus = $this->_lexer->isNextToken(Lexer::T_PLUS)) || $this->_lexer->isNextToken(Lexer::T_MINUS)) { + $this->match(($isPlus) ? Lexer::T_PLUS : Lexer::T_MINUS); + $sign = $isPlus; + } + + $primary = $this->ArithmeticPrimary(); - return new AST\ArithmeticFactor($this->ArithmeticPrimary(), $sign); + // Phase 1 AST optimization: Prevent AST\ArithmeticFactor + // if only one AST\ArithmeticPrimary is defined + if ($sign === null) { + return $primary; + } + + return new AST\ArithmeticFactor($primary, $sign); } /** diff --git a/lib/Doctrine/ORM/Query/SqlWalker.php b/lib/Doctrine/ORM/Query/SqlWalker.php index 78017e634..5aab37925 100644 --- a/lib/Doctrine/ORM/Query/SqlWalker.php +++ b/lib/Doctrine/ORM/Query/SqlWalker.php @@ -668,9 +668,7 @@ class SqlWalker implements TreeWalker */ public function walkHavingClause($havingClause) { - return ' HAVING ' . implode( - ' OR ', array_map(array($this, 'walkConditionalTerm'), $havingClause->conditionalExpression->conditionalTerms) - ); + return ' HAVING ' . $this->walkConditionalExpression($havingClause->conditionalExpression); } /** @@ -778,10 +776,10 @@ class SqlWalker implements TreeWalker } // Handle WITH clause - if ($join->conditionalExpression !== null) { - $sql .= ' AND (' . implode(' OR ', - array_map(array($this, 'walkConditionalTerm'), $join->conditionalExpression->conditionalTerms) - ). ')'; + if (($condExpr = $join->conditionalExpression) !== null) { + // Phase 2 AST optimization: Skip processment of ConditionalExpression + // if only one ConditionalTerm is defined + $sql .= ' AND (' . $this->walkConditionalExpression($condExpr) . ')'; } $discrSql = $this->_generateDiscriminatorColumnConditionSql($joinedDqlAlias); @@ -790,7 +788,7 @@ class SqlWalker implements TreeWalker $sql .= ' AND ' . $discrSql; } - //FIXME: these should either be nested or all forced to be left joins (DDC-XXX) + // FIXME: these should either be nested or all forced to be left joins (DDC-XXX) if ($targetClass->isInheritanceTypeJoined()) { $sql .= $this->_generateClassTableInheritanceJoins($targetClass, $joinedDqlAlias); } @@ -882,7 +880,12 @@ class SqlWalker implements TreeWalker $columnAlias = $this->_platform->getSQLResultCasing($columnAlias); $this->_rsm->addScalarResult($columnAlias, $resultAlias); } - else if ($expr instanceof AST\SimpleArithmeticExpression) { + else if ( + $expr instanceof AST\SimpleArithmeticExpression || + $expr instanceof AST\ArithmeticTerm || + $expr instanceof AST\ArithmeticFactor || + $expr instanceof AST\ArithmeticPrimary + ) { if ( ! $selectExpression->fieldIdentificationVariable) { $resultAlias = $this->_scalarResultCounter++; } else { @@ -1214,20 +1217,27 @@ class SqlWalker implements TreeWalker */ public function walkWhereClause($whereClause) { - $sql = ' WHERE '; - $condExpr = $whereClause->conditionalExpression; - - $sql .= implode( - ' OR ', array_map(array($this, 'walkConditionalTerm'), $condExpr->conditionalTerms) - ); - $discrSql = $this->_generateDiscriminatorColumnConditionSql($this->_currentRootAlias); + $condSql = $this->walkConditionalExpression($whereClause->conditionalExpression); - if ($discrSql) { - $sql .= ' AND ' . $discrSql; - } + return ' WHERE ' . (( ! $discrSql) ? $condSql : '(' . $condSql . ') AND ' . $discrSql); + } - return $sql; + /** + * Walk down a ConditionalExpression AST node, thereby generating the appropriate SQL. + * + * @param ConditionalExpression + * @return string The SQL. + */ + public function walkConditionalExpression($condExpr) + { + // Phase 2 AST optimization: Skip processment of ConditionalExpression + // if only one ConditionalTerm is defined + return ( ! ($condExpr instanceof AST\ConditionalExpression)) + ? $this->walkConditionalTerm($condExpr) + : implode( + ' OR ', array_map(array($this, 'walkConditionalTerm'), $condExpr->conditionalTerms) + ); } /** @@ -1238,9 +1248,13 @@ class SqlWalker implements TreeWalker */ public function walkConditionalTerm($condTerm) { - return implode( - ' AND ', array_map(array($this, 'walkConditionalFactor'), $condTerm->conditionalFactors) - ); + // Phase 2 AST optimization: Skip processment of ConditionalTerm + // if only one ConditionalFactor is defined + return ( ! ($condTerm instanceof AST\ConditionalTerm)) + ? $this->walkConditionalFactor($condTerm) + : implode( + ' AND ', array_map(array($this, 'walkConditionalFactor'), $condTerm->conditionalFactors) + ); } /** @@ -1251,21 +1265,28 @@ class SqlWalker implements TreeWalker */ public function walkConditionalFactor($factor) { - $sql = ($factor->not) ? 'NOT ' : ''; - - $primary = $factor->conditionalPrimary; + // Phase 2 AST optimization: Skip processment of ConditionalFactor + // if only one ConditionalPrimary is defined + return ( ! ($factor instanceof AST\ConditionalFactor)) + ? $this->walkConditionalPrimary($factor) + : ($factor->not ? 'NOT ' : '') . $this->walkConditionalPrimary($factor->conditionalPrimary); + } + /** + * Walks down a ConditionalPrimary AST node, thereby generating the appropriate SQL. + * + * @param ConditionalPrimary + * @return string The SQL. + */ + public function walkConditionalPrimary($primary) + { if ($primary->isSimpleConditionalExpression()) { - $sql .= $primary->simpleConditionalExpression->dispatch($this); + return $primary->simpleConditionalExpression->dispatch($this); } else if ($primary->isConditionalExpression()) { $condExpr = $primary->conditionalExpression; - $sql .= '(' . implode( - ' OR ', array_map(array($this, 'walkConditionalTerm'), $condExpr->conditionalTerms) - ) . ')'; + return '(' . $this->walkConditionalExpression($condExpr) . ')'; } - - return $sql; } /** @@ -1605,6 +1626,21 @@ class SqlWalker implements TreeWalker : $this->walkSubselect($arithmeticExpr->subselect); } + /** + * Walks down an SimpleArithmeticExpression AST node, thereby generating the appropriate SQL. + * + * @param SimpleArithmeticExpression + * @return string The SQL. + */ + public function walkSimpleArithmeticExpression($simpleArithmeticExpr) + { + return ( ! ($simpleArithmeticExpr instanceof AST\SimpleArithmeticExpression)) + ? $this->walkArithmeticTerm($simpleArithmeticExpr) + : implode( + ' ', array_map(array($this, 'walkArithmeticTerm'), $simpleArithmeticExpr->arithmeticTerms) + ); + } + /** * Walks down an ArithmeticTerm AST node, thereby generating the appropriate SQL. * @@ -1613,11 +1649,55 @@ class SqlWalker implements TreeWalker */ public function walkArithmeticTerm($term) { - if (is_string($term)) return $term; + if (is_string($term)) { + return $term; + } - return implode( - ' ', array_map(array($this, 'walkArithmeticFactor'), $term->arithmeticFactors) - ); + // Phase 2 AST optimization: Skip processment of ArithmeticTerm + // if only one ArithmeticFactor is defined + return ( ! ($term instanceof AST\ArithmeticTerm)) + ? $this->walkArithmeticFactor($term) + : implode( + ' ', array_map(array($this, 'walkArithmeticFactor'), $term->arithmeticFactors) + ); + } + + /** + * Walks down an ArithmeticFactor that represents an AST node, thereby generating the appropriate SQL. + * + * @param mixed + * @return string The SQL. + */ + public function walkArithmeticFactor($factor) + { + if (is_string($factor)) { + return $factor; + } + + // Phase 2 AST optimization: Skip processment of ArithmeticFactor + // if only one ArithmeticPrimary is defined + return ( ! ($factor instanceof AST\ArithmeticFactor)) + ? $this->walkArithmeticPrimary($factor) + : ($factor->isNegativeSigned() ? '-' : ($factor->isPositiveSigned() ? '+' : '')) + . $this->walkArithmeticPrimary($factor->arithmeticPrimary); + } + + /** + * Walks down an ArithmeticPrimary that represents an AST node, thereby generating the appropriate SQL. + * + * @param mixed + * @return string The SQL. + */ + public function walkArithmeticPrimary($primary) + { + if ($primary instanceof AST\SimpleArithmeticExpression) { + return '(' . $this->walkSimpleArithmeticExpression($primary) . ')'; + } else if ($primary instanceof AST\Node) { + return $primary->dispatch($this); + } + + // We need to deal with IdentificationVariable here + return ''; } /** @@ -1632,41 +1712,4 @@ class SqlWalker implements TreeWalker ? $this->_conn->quote($stringPrimary) : $stringPrimary->dispatch($this); } - - /** - * Walks down an ArithmeticFactor that represents an AST node, thereby generating the appropriate SQL. - * - * @param mixed - * @return string The SQL. - */ - public function walkArithmeticFactor($factor) - { - if (is_string($factor)) return $factor; - - $sql = ($factor->isNegativeSigned() ? '-' : ($factor->isPositiveSigned() ? '+' : '')); - $primary = $factor->arithmeticPrimary; - - if ($primary instanceof AST\SimpleArithmeticExpression) { - $sql .= '(' . $this->walkSimpleArithmeticExpression($primary) . ')'; - } else if ($primary instanceof AST\Node) { - $sql .= $primary->dispatch($this); - } else if (is_string($primary)) { - // We need to deal with IdentificationVariable here - } - - return $sql; - } - - /** - * Walks down an SimpleArithmeticExpression AST node, thereby generating the appropriate SQL. - * - * @param SimpleArithmeticExpression - * @return string The SQL. - */ - public function walkSimpleArithmeticExpression($simpleArithmeticExpr) - { - return implode( - ' ', array_map(array($this, 'walkArithmeticTerm'), $simpleArithmeticExpr->arithmeticTerms) - ); - } } diff --git a/lib/Doctrine/ORM/Query/TreeWalker.php b/lib/Doctrine/ORM/Query/TreeWalker.php index b76b77258..1654f2a1c 100644 --- a/lib/Doctrine/ORM/Query/TreeWalker.php +++ b/lib/Doctrine/ORM/Query/TreeWalker.php @@ -218,6 +218,14 @@ interface TreeWalker */ function walkWhereClause($whereClause); + /** + * Walks down a ConditionalExpression AST node, thereby generating the appropriate SQL. + * + * @param ConditionalExpression + * @return string The SQL. + */ + function walkConditionalExpression($condExpr); + /** * Walks down a ConditionalTerm AST node, thereby generating the appropriate SQL. * @@ -234,6 +242,14 @@ interface TreeWalker */ function walkConditionalFactor($factor); + /** + * Walks down a ConditionalPrimary AST node, thereby generating the appropriate SQL. + * + * @param ConditionalPrimary + * @return string The SQL. + */ + function walkConditionalPrimary($primary); + /** * Walks down an ExistsExpression AST node, thereby generating the appropriate SQL. * diff --git a/lib/Doctrine/ORM/Query/TreeWalkerAdapter.php b/lib/Doctrine/ORM/Query/TreeWalkerAdapter.php index 669409630..7f5f33f3c 100644 --- a/lib/Doctrine/ORM/Query/TreeWalkerAdapter.php +++ b/lib/Doctrine/ORM/Query/TreeWalkerAdapter.php @@ -252,6 +252,14 @@ abstract class TreeWalkerAdapter implements TreeWalker */ public function walkWhereClause($whereClause) {} + /** + * Walks down a ConditionalExpression AST node, thereby generating the appropriate SQL. + * + * @param ConditionalExpression + * @return string The SQL. + */ + public function walkConditionalExpression($condExpr) {} + /** * Walks down a ConditionalTerm AST node, thereby generating the appropriate SQL. * @@ -268,6 +276,14 @@ abstract class TreeWalkerAdapter implements TreeWalker */ public function walkConditionalFactor($factor) {} + /** + * Walks down a ConditionalPrimary AST node, thereby generating the appropriate SQL. + * + * @param ConditionalPrimary + * @return string The SQL. + */ + public function walkConditionalPrimary($primary) {} + /** * Walks down an ExistsExpression AST node, thereby generating the appropriate SQL. * diff --git a/lib/Doctrine/ORM/Query/TreeWalkerChain.php b/lib/Doctrine/ORM/Query/TreeWalkerChain.php index 0a83939cf..28ff54b95 100644 --- a/lib/Doctrine/ORM/Query/TreeWalkerChain.php +++ b/lib/Doctrine/ORM/Query/TreeWalkerChain.php @@ -355,6 +355,19 @@ class TreeWalkerChain implements TreeWalker } } + /** + * Walks down a ConditionalExpression AST node, thereby generating the appropriate SQL. + * + * @param ConditionalExpression + * @return string The SQL. + */ + public function walkConditionalExpression($condExpr) + { + foreach ($this->_walkers as $walker) { + $walker->walkConditionalExpression($condExpr); + } + } + /** * Walks down a ConditionalTerm AST node, thereby generating the appropriate SQL. * @@ -381,6 +394,19 @@ class TreeWalkerChain implements TreeWalker } } + /** + * Walks down a ConditionalPrimary AST node, thereby generating the appropriate SQL. + * + * @param ConditionalPrimary + * @return string The SQL. + */ + public function walkConditionalPrimary($condPrimary) + { + foreach ($this->_walkers as $walker) { + $walker->walkConditionalPrimary($condPrimary); + } + } + /** * Walks down an ExistsExpression AST node, thereby generating the appropriate SQL. * diff --git a/tests/Doctrine/Tests/ORM/Functional/CustomTreeWalkersTest.php b/tests/Doctrine/Tests/ORM/Functional/CustomTreeWalkersTest.php index 817a79eb3..d7c7a4259 100644 --- a/tests/Doctrine/Tests/ORM/Functional/CustomTreeWalkersTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/CustomTreeWalkersTest.php @@ -39,20 +39,43 @@ class CustomTreeWalkersTest extends \Doctrine\Tests\OrmFunctionalTestCase $this->useModelSet('cms'); parent::setUp(); } - + + public function assertSqlGeneration($dqlToBeTested, $sqlToBeConfirmed) + { + try { + $query = $this->_em->createQuery($dqlToBeTested); + $query->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\Tests\ORM\Functional\CustomTreeWalker')) + ->useQueryCache(false); + + parent::assertEquals($sqlToBeConfirmed, $query->getSql()); + $query->free(); + } catch (\Exception $e) { + $this->fail($e->getMessage()); + } + } + public function testSupportsQueriesWithoutWhere() { - - $q = $this->_em->createQuery('select u from Doctrine\Tests\Models\CMS\CmsUser u where u.name = :name or u.name = :otherName'); - $q->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\Tests\ORM\Functional\CustomTreeWalker')); - - $this->assertEquals("SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE (c0_.name = ? OR c0_.name = ?) AND c0_.id = 1", $q->getSql()); - - $q->setDql('select u from Doctrine\Tests\Models\CMS\CmsUser u'); - $this->assertEquals("SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE c0_.id = 1", $q->getSql()); - - $q->setDql('select u from Doctrine\Tests\Models\CMS\CmsUser u where u.name = :name'); - $this->assertEquals("SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE c0_.name = ? AND c0_.id = 1", $q->getSql()); + $this->assertSqlGeneration( + 'select u from Doctrine\Tests\Models\CMS\CmsUser u where u.name = :name or u.name = :otherName', + "SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE (c0_.name = ? OR c0_.name = ?) AND c0_.id = 1" + ); + } + + public function testSupportsQueriesWithSimpleConditionalExpressions() + { + $this->assertSqlGeneration( + 'select u from Doctrine\Tests\Models\CMS\CmsUser u where u.name = :name', + "SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE c0_.name = ? AND c0_.id = 1" + ); + } + + public function testSupportsQueriesWithMultipleConditionalExpressions() + { + $this->assertSqlGeneration( + 'select u from Doctrine\Tests\Models\CMS\CmsUser u', + "SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE c0_.id = 1" + ); } } @@ -62,6 +85,7 @@ class CustomTreeWalker extends Query\TreeWalkerAdapter { // Get the DQL aliases of all the classes we want to modify $dqlAliases = array(); + foreach ($this->_getQueryComponents() as $dqlAlias => $comp) { // Hard-coded check just for demonstration: We want to modify the query if // it involves the CmsUser class. @@ -84,10 +108,19 @@ class CustomTreeWalker extends Query\TreeWalkerAdapter $factors[] = $factor; } - if ($selectStatement->whereClause !== null) { + if (($whereClause = $selectStatement->whereClause) !== null) { // There is already a WHERE clause, so append the conditions - - $existingTerms = $selectStatement->whereClause->conditionalExpression->conditionalTerms; + $condExpr = $whereClause->conditionalExpression; + + // Since Phase 1 AST optimizations were included, we need to re-add the ConditionalExpression + if ( ! ($condExpr instanceof Query\AST\ConditionalExpression)) { + $condExpr = new Query\AST\ConditionalExpression(array($condExpr)); + + $whereClause->conditionalExpression = $condExpr; + } + + $existingTerms = $whereClause->conditionalExpression->conditionalTerms; + if (count($existingTerms) > 1) { // More than one term, so we need to wrap all these terms in a single root term // i.e: "WHERE u.name = :foo or u.other = :bar" => "WHERE (u.name = :foo or u.other = :bar) AND " @@ -100,8 +133,15 @@ class CustomTreeWalker extends Query\TreeWalkerAdapter $selectStatement->whereClause->conditionalExpression->conditionalTerms = array($term); } else { // Just one term so we can simply append our factors to that term - $singleTerm = $selectStatement->whereClause->conditionalExpression->conditionalTerms[0]; + + // Since Phase 1 AST optimizations were included, we need to re-add the ConditionalExpression + if ( ! ($singleTerm instanceof Query\AST\ConditionalTerm)) { + $singleTerm = new Query\AST\ConditionalTerm(array($singleTerm)); + + $selectStatement->whereClause->conditionalExpression->conditionalTerms[0] = $singleTerm; + } + $singleTerm->conditionalFactors = array_merge($singleTerm->conditionalFactors, $factors); $selectStatement->whereClause->conditionalExpression->conditionalTerms = array($singleTerm); } diff --git a/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php b/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php index a85873a92..716182ac1 100644 --- a/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php +++ b/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php @@ -177,7 +177,7 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase { $this->assertSqlGeneration( 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE ((u.id + 5000) * u.id + 3) < 10000000', - 'SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE ((c0_.id + 5000) * c0_.id + 3) < 10000000' + 'SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE (c0_.id + 5000) * c0_.id + 3 < 10000000' ); } @@ -456,7 +456,7 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase { $this->assertSqlGeneration( "select u from Doctrine\Tests\Models\CMS\CmsUser u where u.id > 10 and u.id < 42 and ((u.id * 2) > 5)", - "SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE c0_.id > 10 AND c0_.id < 42 AND ((c0_.id * 2) > 5)" + "SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE c0_.id > 10 AND c0_.id < 42 AND (c0_.id * 2 > 5)" ); } @@ -464,7 +464,7 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase { $this->assertSqlGeneration( "select u from Doctrine\Tests\Models\CMS\CmsUser u where (u.id > 10) and (u.id < 42 and ((u.id * 2) > 5)) or u.id <> 42", - "SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE (c0_.id > 10) AND (c0_.id < 42 AND ((c0_.id * 2) > 5)) OR c0_.id <> 42" + "SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE (c0_.id > 10) AND (c0_.id < 42 AND (c0_.id * 2 > 5)) OR c0_.id <> 42" ); }