PageRenderTime 35ms CodeModel.GetById 3ms app.highlight 23ms RepoModel.GetById 1ms app.codeStats 0ms

/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php

https://github.com/EdgarPost/doctrine2
PHP | 877 lines | 665 code | 122 blank | 90 comment | 4 complexity | fdd23efa124849208be43b7f066be51a MD5 | raw file
  1<?php
  2
  3namespace Doctrine\Tests\ORM\Query;
  4
  5use Doctrine\ORM\Query;
  6
  7require_once __DIR__ . '/../../TestInit.php';
  8
  9class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
 10{
 11    private $_em;
 12
 13    protected function setUp()
 14    {
 15        $this->_em = $this->_getTestEntityManager();
 16    }
 17
 18    /**
 19     * Assert a valid SQL generation.
 20     * 
 21     * @param string $dqlToBeTested
 22     * @param string $sqlToBeConfirmed
 23     * @param array $queryHints
 24     * @param array $queryParams 
 25     */
 26    public function assertSqlGeneration($dqlToBeTested, $sqlToBeConfirmed, array $queryHints = array(), array $queryParams = array())
 27    {
 28        try {
 29            $query = $this->_em->createQuery($dqlToBeTested);
 30
 31            foreach ($queryParams AS $name => $value) {
 32                $query->setParameter($name, $value);
 33            }
 34
 35            $query->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true)
 36                    ->useQueryCache(false);
 37            
 38            foreach ($queryHints AS $name => $value) {
 39                $query->setHint($name, $value);
 40            }
 41
 42            parent::assertEquals($sqlToBeConfirmed, $query->getSql());
 43            $query->free();
 44        } catch (\Exception $e) {
 45            $this->fail($e->getMessage());
 46        }
 47    }
 48
 49    /**
 50     * Asser an invalid SQL generation.
 51     *
 52     * @param string $dqlToBeTested
 53     * @param string $expectedException
 54     * @param array $queryHints
 55     * @param array $queryParams
 56     */
 57    public function assertInvalidSqlGeneration($dqlToBeTested, $expectedException, array $queryHints = array(), array $queryParams = array())
 58    {
 59        $this->setExpectedException($expectedException);
 60
 61        $query = $this->_em->createQuery($dqlToBeTested);
 62
 63        foreach ($queryParams AS $name => $value) {
 64            $query->setParameter($name, $value);
 65        }
 66
 67        $query->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true)
 68                ->useQueryCache(false);
 69
 70        foreach ($queryHints AS $name => $value) {
 71            $query->setHint($name, $value);
 72        }
 73
 74        $sql = $query->getSql();
 75        $query->free();
 76
 77        // If we reached here, test failed
 78        $this->fail($sql);
 79    }
 80
 81
 82    public function testSupportsSelectForAllFields()
 83    {
 84        $this->assertSqlGeneration(
 85            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u',
 86            'SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_'
 87        );
 88    }
 89
 90    public function testSupportsSelectForOneField()
 91    {
 92        $this->assertSqlGeneration(
 93            'SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u',
 94            'SELECT c0_.id AS id0 FROM cms_users c0_'
 95        );
 96    }
 97
 98    public function testSupportsSelectForOneNestedField()
 99    {
100        $this->assertSqlGeneration(
101            'SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsArticle a JOIN a.user u',
102            'SELECT c0_.id AS id0 FROM cms_articles c1_ INNER JOIN cms_users c0_ ON c1_.user_id = c0_.id'
103        );
104    }
105
106    public function testSupportsSelectForAllNestedField()
107    {
108        $this->assertSqlGeneration(
109            'SELECT a FROM Doctrine\Tests\Models\CMS\CmsArticle a JOIN a.user u ORDER BY u.name ASC',
110            'SELECT c0_.id AS id0, c0_.topic AS topic1, c0_.text AS text2, c0_.version AS version3 FROM cms_articles c0_ INNER JOIN cms_users c1_ ON c0_.user_id = c1_.id ORDER BY c1_.name ASC'
111        );
112    }
113
114    public function testSupportsSelectForMultipleColumnsOfASingleComponent()
115    {
116        $this->assertSqlGeneration(
117            'SELECT u.username, u.name FROM Doctrine\Tests\Models\CMS\CmsUser u',
118            'SELECT c0_.username AS username0, c0_.name AS name1 FROM cms_users c0_'
119        );
120    }
121
122    public function testSupportsSelectUsingMultipleFromComponents()
123    {
124        $this->assertSqlGeneration(
125            'SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u, Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE u = p.user',
126            'SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3, c1_.phonenumber AS phonenumber4 FROM cms_users c0_, cms_phonenumbers c1_ WHERE c0_.id = c1_.user_id'
127        );
128    }
129
130    public function testSupportsSelectWithCollectionAssociationJoin()
131    {
132        $this->assertSqlGeneration(
133            'SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.phonenumbers p',
134            'SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3, c1_.phonenumber AS phonenumber4 FROM cms_users c0_ INNER JOIN cms_phonenumbers c1_ ON c0_.id = c1_.user_id'
135        );
136    }
137
138    public function testSupportsSelectWithSingleValuedAssociationJoin()
139    {
140        $this->assertSqlGeneration(
141            'SELECT u, a FROM Doctrine\Tests\Models\Forum\ForumUser u JOIN u.avatar a',
142            'SELECT f0_.id AS id0, f0_.username AS username1, f1_.id AS id2 FROM forum_users f0_ INNER JOIN forum_avatars f1_ ON f0_.avatar_id = f1_.id'
143        );
144    }
145
146    public function testSelectCorrelatedSubqueryComplexMathematicalExpression()
147    {
148        $this->assertSqlGeneration(
149            'SELECT (SELECT (count(p.phonenumber)+5)*10 FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p JOIN p.user ui WHERE ui.id = u.id) AS c FROM Doctrine\Tests\Models\CMS\CmsUser u',
150            'SELECT (SELECT (count(c0_.phonenumber) + 5) * 10 AS sclr1 FROM cms_phonenumbers c0_ INNER JOIN cms_users c1_ ON c0_.user_id = c1_.id WHERE c1_.id = c2_.id) AS sclr0 FROM cms_users c2_'
151        );
152    }
153
154    public function testSelectComplexMathematicalExpression()
155    {
156        $this->assertSqlGeneration(
157            'SELECT (count(p.phonenumber)+5)*10 FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p JOIN p.user ui WHERE ui.id = ?1',
158            'SELECT (count(c0_.phonenumber) + 5) * 10 AS sclr0 FROM cms_phonenumbers c0_ INNER JOIN cms_users c1_ ON c0_.user_id = c1_.id WHERE c1_.id = ?'
159        );
160    }
161
162    /* NOT (YET?) SUPPORTED.
163       Can be supported if SimpleSelectExpresion supports SingleValuedPathExpression instead of StateFieldPathExpression.
164
165    public function testSingleAssociationPathExpressionInSubselect()
166    {
167        $this->assertSqlGeneration(
168            'SELECT (SELECT p.user FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE p.user = u) user_id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1',
169            'SELECT (SELECT c0_.user_id FROM cms_phonenumbers c0_ WHERE c0_.user_id = c1_.id) AS sclr0 FROM cms_users c1_ WHERE c1_.id = ?'
170        );
171    }*/
172
173    public function testSupportsOrderByWithAscAsDefault()
174    {
175        $this->assertSqlGeneration(
176            'SELECT u FROM Doctrine\Tests\Models\Forum\ForumUser u ORDER BY u.id',
177            'SELECT f0_.id AS id0, f0_.username AS username1 FROM forum_users f0_ ORDER BY f0_.id ASC'
178        );
179    }
180
181    public function testSupportsOrderByAsc()
182    {
183        $this->assertSqlGeneration(
184            'SELECT u FROM Doctrine\Tests\Models\Forum\ForumUser u ORDER BY u.id asc',
185            'SELECT f0_.id AS id0, f0_.username AS username1 FROM forum_users f0_ ORDER BY f0_.id ASC'
186        );
187    }
188    public function testSupportsOrderByDesc()
189    {
190        $this->assertSqlGeneration(
191            'SELECT u FROM Doctrine\Tests\Models\Forum\ForumUser u ORDER BY u.id desc',
192            'SELECT f0_.id AS id0, f0_.username AS username1 FROM forum_users f0_ ORDER BY f0_.id DESC'
193        );
194    }
195
196    public function testSupportsSelectDistinct()
197    {
198        $this->assertSqlGeneration(
199            'SELECT DISTINCT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u',
200            'SELECT DISTINCT c0_.name AS name0 FROM cms_users c0_'
201        );
202    }
203
204    public function testSupportsAggregateFunctionInSelectedFields()
205    {
206        $this->assertSqlGeneration(
207            'SELECT COUNT(u.id) FROM Doctrine\Tests\Models\CMS\CmsUser u GROUP BY u.id',
208            'SELECT COUNT(c0_.id) AS sclr0 FROM cms_users c0_ GROUP BY c0_.id'
209        );
210    }
211
212    public function testSupportsWhereClauseWithPositionalParameter()
213    {
214        $this->assertSqlGeneration(
215            'select u from Doctrine\Tests\Models\Forum\ForumUser u where u.id = ?1',
216            'SELECT f0_.id AS id0, f0_.username AS username1 FROM forum_users f0_ WHERE f0_.id = ?'
217        );
218    }
219
220    public function testSupportsWhereClauseWithNamedParameter()
221    {
222        $this->assertSqlGeneration(
223            'select u from Doctrine\Tests\Models\Forum\ForumUser u where u.username = :name',
224            'SELECT f0_.id AS id0, f0_.username AS username1 FROM forum_users f0_ WHERE f0_.username = ?'
225        );
226    }
227
228    public function testSupportsWhereAndClauseWithNamedParameters()
229    {
230        $this->assertSqlGeneration(
231            'select u from Doctrine\Tests\Models\Forum\ForumUser u where u.username = :name and u.username = :name2',
232            'SELECT f0_.id AS id0, f0_.username AS username1 FROM forum_users f0_ WHERE f0_.username = ? AND f0_.username = ?'
233        );
234    }
235
236    public function testSupportsCombinedWhereClauseWithNamedParameter()
237    {
238        $this->assertSqlGeneration(
239            'select u from Doctrine\Tests\Models\Forum\ForumUser u where (u.username = :name OR u.username = :name2) AND u.id = :id',
240            'SELECT f0_.id AS id0, f0_.username AS username1 FROM forum_users f0_ WHERE (f0_.username = ? OR f0_.username = ?) AND f0_.id = ?'
241        );
242    }
243
244    public function testSupportsAggregateFunctionInASelectDistinct()
245    {
246        $this->assertSqlGeneration(
247            'SELECT COUNT(DISTINCT u.name) FROM Doctrine\Tests\Models\CMS\CmsUser u',
248            'SELECT COUNT(DISTINCT c0_.name) AS sclr0 FROM cms_users c0_'
249        );
250    }
251
252    // Ticket #668
253    public function testSupportsASqlKeywordInAStringLiteralParam()
254    {
255        $this->assertSqlGeneration(
256            "SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name LIKE '%foo OR bar%'",
257            "SELECT c0_.name AS name0 FROM cms_users c0_ WHERE c0_.name LIKE '%foo OR bar%'"
258        );
259    }
260
261    public function testSupportsArithmeticExpressionsInWherePart()
262    {
263        $this->assertSqlGeneration(
264            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE ((u.id + 5000) * u.id + 3) < 10000000',
265            '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'
266        );
267    }
268
269    public function testSupportsMultipleEntitiesInFromClause()
270    {
271        $this->assertSqlGeneration(
272            'SELECT u, a FROM Doctrine\Tests\Models\CMS\CmsUser u, Doctrine\Tests\Models\CMS\CmsArticle a JOIN a.user u2 WHERE u.id = u2.id',
273            'SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3, c1_.id AS id4, c1_.topic AS topic5, c1_.text AS text6, c1_.version AS version7 FROM cms_users c0_, cms_articles c1_ INNER JOIN cms_users c2_ ON c1_.user_id = c2_.id WHERE c0_.id = c2_.id'
274        );
275    }
276
277    public function testSupportsMultipleEntitiesInFromClauseUsingPathExpression()
278    {
279        $this->assertSqlGeneration(
280            'SELECT u, a FROM Doctrine\Tests\Models\CMS\CmsUser u, Doctrine\Tests\Models\CMS\CmsArticle a WHERE u.id = a.user',
281            'SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3, c1_.id AS id4, c1_.topic AS topic5, c1_.text AS text6, c1_.version AS version7 FROM cms_users c0_, cms_articles c1_ WHERE c0_.id = c1_.user_id'
282        );
283    }
284
285    public function testSupportsPlainJoinWithoutClause()
286    {
287        $this->assertSqlGeneration(
288            'SELECT u.id, a.id from Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a',
289            'SELECT c0_.id AS id0, c1_.id AS id1 FROM cms_users c0_ LEFT JOIN cms_articles c1_ ON c0_.id = c1_.user_id'
290        );
291        $this->assertSqlGeneration(
292            'SELECT u.id, a.id from Doctrine\Tests\Models\CMS\CmsUser u JOIN u.articles a',
293            'SELECT c0_.id AS id0, c1_.id AS id1 FROM cms_users c0_ INNER JOIN cms_articles c1_ ON c0_.id = c1_.user_id'
294        );
295    }
296
297    /**
298     * @group DDC-135
299     */
300    public function testSupportsJoinAndWithClauseRestriction()
301    {
302        $this->assertSqlGeneration(
303            "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a WITH a.topic LIKE '%foo%'",
304            "SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ LEFT JOIN cms_articles c1_ ON c0_.id = c1_.user_id AND (c1_.topic LIKE '%foo%')"
305        );
306        $this->assertSqlGeneration(
307            "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u INNER JOIN u.articles a WITH a.topic LIKE '%foo%'",
308            "SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ INNER JOIN cms_articles c1_ ON c0_.id = c1_.user_id AND (c1_.topic LIKE '%foo%')"
309        );
310    }
311
312    /**
313     * @group DDC-135
314     * @group DDC-177
315     */
316    public function testJoinOnClause_NotYetSupported_ThrowsException()
317    {
318        $this->setExpectedException('Doctrine\ORM\Query\QueryException');
319
320        $sql = $this->_em->createQuery(
321            "SELECT u, a FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a ON a.topic LIKE '%foo%'"
322        )->getSql();
323    }
324
325    public function testSupportsMultipleJoins()
326    {
327        $this->assertSqlGeneration(
328            'SELECT u.id, a.id, p, c.id from Doctrine\Tests\Models\CMS\CmsUser u JOIN u.articles a JOIN u.phonenumbers p JOIN a.comments c',
329            'SELECT c0_.id AS id0, c1_.id AS id1, c2_.phonenumber AS phonenumber2, c3_.id AS id3 FROM cms_users c0_ INNER JOIN cms_articles c1_ ON c0_.id = c1_.user_id INNER JOIN cms_phonenumbers c2_ ON c0_.id = c2_.user_id INNER JOIN cms_comments c3_ ON c1_.id = c3_.article_id'
330        );
331    }
332
333    public function testSupportsTrimFunction()
334    {
335        $this->assertSqlGeneration(
336            "SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE TRIM(TRAILING ' ' FROM u.name) = 'someone'",
337            "SELECT c0_.name AS name0 FROM cms_users c0_ WHERE TRIM(TRAILING ' ' FROM c0_.name) = 'someone'"
338        );
339    }
340
341    // Ticket 894
342    public function testSupportsBetweenClauseWithPositionalParameters()
343    {
344        $this->assertSqlGeneration(
345            "SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id BETWEEN ?1 AND ?2",
346            "SELECT c0_.name AS name0 FROM cms_users c0_ WHERE c0_.id BETWEEN ? AND ?"
347        );
348    }
349
350    public function testSupportsFunctionalExpressionsInWherePart()
351    {
352        $this->assertSqlGeneration(
353            "SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE TRIM(u.name) = 'someone'",
354            // String quoting in the SQL usually depends on the database platform.
355            // This test works with a mock connection which uses ' for string quoting.
356            "SELECT c0_.name AS name0 FROM cms_users c0_ WHERE TRIM(c0_.name) = 'someone'"
357        );
358    }
359
360    public function testSupportsInstanceOfExpressionsInWherePart()
361    {
362        $this->assertSqlGeneration(
363            "SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF Doctrine\Tests\Models\Company\CompanyEmployee",
364            "SELECT c0_.id AS id0, c0_.name AS name1, c0_.discr AS discr2 FROM company_persons c0_ WHERE c0_.discr = 'employee'"
365        );
366    }
367
368    public function testSupportsInstanceOfExpressionsInWherePartInDeeperLevel()
369    {
370        $this->assertSqlGeneration(
371            "SELECT u FROM Doctrine\Tests\Models\Company\CompanyEmployee u WHERE u INSTANCE OF Doctrine\Tests\Models\Company\CompanyManager",
372            "SELECT c0_.id AS id0, c0_.name AS name1, c1_.salary AS salary2, c1_.department AS department3, c0_.discr AS discr4 FROM company_employees c1_ INNER JOIN company_persons c0_ ON c1_.id = c0_.id WHERE c0_.discr = 'manager'"
373        );
374    }
375
376    public function testSupportsInstanceOfExpressionsInWherePartInDeepestLevel()
377    {
378        $this->assertSqlGeneration(
379            "SELECT u FROM Doctrine\Tests\Models\Company\CompanyManager u WHERE u INSTANCE OF Doctrine\Tests\Models\Company\CompanyManager",
380            "SELECT c0_.id AS id0, c0_.name AS name1, c1_.salary AS salary2, c1_.department AS department3, c2_.title AS title4, c0_.discr AS discr5 FROM company_managers c2_ INNER JOIN company_employees c1_ ON c2_.id = c1_.id INNER JOIN company_persons c0_ ON c2_.id = c0_.id WHERE c0_.discr = 'manager'"
381        );
382    }
383
384    public function testSupportsInstanceOfExpressionsUsingInputParameterInWherePart()
385    {
386        $this->assertSqlGeneration(
387            "SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF ?1",
388            "SELECT c0_.id AS id0, c0_.name AS name1, c0_.discr AS discr2 FROM company_persons c0_ WHERE c0_.discr = 'employee'",
389            array(), array(1 => $this->_em->getClassMetadata('Doctrine\Tests\Models\Company\CompanyEmployee'))
390        );
391    }
392
393    // Ticket #973
394    public function testSupportsSingleValuedInExpressionWithoutSpacesInWherePart()
395    {
396        $this->assertSqlGeneration(
397            "SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id IN(46)",
398            "SELECT c0_.name AS name0 FROM cms_users c0_ WHERE c0_.id IN (46)"
399        );
400    }
401
402    public function testSupportsMultipleValuedInExpressionInWherePart()
403    {
404        $this->assertSqlGeneration(
405            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id IN (1, 2)',
406            'SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE c0_.id IN (1, 2)'
407        );
408    }
409
410    public function testSupportsNotInExpressionInWherePart()
411    {
412        $this->assertSqlGeneration(
413            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id NOT IN (1)',
414            'SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE c0_.id NOT IN (1)'
415        );
416    }
417
418    public function testInExpressionWithSingleValuedAssociationPathExpressionInWherePart()
419    {
420        $this->assertSqlGeneration(
421            'SELECT u FROM Doctrine\Tests\Models\Forum\ForumUser u WHERE u.avatar IN (?1, ?2)',
422            'SELECT f0_.id AS id0, f0_.username AS username1 FROM forum_users f0_ WHERE f0_.avatar_id IN (?, ?)'
423        );
424    }
425
426    public function testInvalidInExpressionWithSingleValuedAssociationPathExpressionOnInverseSide()
427    {
428        // We do not support SingleValuedAssociationPathExpression on inverse side
429        $this->assertInvalidSqlGeneration(
430            "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.address IN (?1, ?2)",
431            "Doctrine\ORM\Query\QueryException"
432        );
433    }
434
435    public function testSupportsConcatFunctionForMysqlAndPostgresql()
436    {
437        $connMock = $this->_em->getConnection();
438        $orgPlatform = $connMock->getDatabasePlatform();
439
440        $connMock->setDatabasePlatform(new \Doctrine\DBAL\Platforms\MySqlPlatform);
441        $this->assertSqlGeneration(
442            "SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE CONCAT(u.name, 's') = ?1",
443            "SELECT c0_.id AS id0 FROM cms_users c0_ WHERE CONCAT(c0_.name, 's') = ?"
444        );
445        $this->assertSqlGeneration(
446            "SELECT CONCAT(u.id, u.name) FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1",
447            "SELECT CONCAT(c0_.id, c0_.name) AS sclr0 FROM cms_users c0_ WHERE c0_.id = ?"
448        );
449
450        $connMock->setDatabasePlatform(new \Doctrine\DBAL\Platforms\PostgreSqlPlatform);
451        $this->assertSqlGeneration(
452            "SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE CONCAT(u.name, 's') = ?1",
453            "SELECT c0_.id AS id0 FROM cms_users c0_ WHERE c0_.name || 's' = ?"
454        );
455        $this->assertSqlGeneration(
456            "SELECT CONCAT(u.id, u.name) FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1",
457            "SELECT c0_.id || c0_.name AS sclr0 FROM cms_users c0_ WHERE c0_.id = ?"
458        );
459
460        $connMock->setDatabasePlatform($orgPlatform);
461    }
462
463    public function testSupportsExistsExpressionInWherePartWithCorrelatedSubquery()
464    {
465        $this->assertSqlGeneration(
466            'SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE EXISTS (SELECT p.phonenumber FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE p.phonenumber = u.id)',
467            'SELECT c0_.id AS id0 FROM cms_users c0_ WHERE EXISTS (SELECT c1_.phonenumber FROM cms_phonenumbers c1_ WHERE c1_.phonenumber = c0_.id)'
468        );
469    }
470
471    /**
472     * @group DDC-593
473     */
474    public function testSubqueriesInComparisonExpression()
475    {
476        $this->assertSqlGeneration(
477            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE (u.id >= (SELECT u2.id FROM Doctrine\Tests\Models\CMS\CmsUser u2 WHERE u2.name = :name)) AND (u.id <= (SELECT u3.id FROM Doctrine\Tests\Models\CMS\CmsUser u3 WHERE u3.name = :name))',
478            'SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE (c0_.id >= (SELECT c1_.id FROM cms_users c1_ WHERE c1_.name = ?)) AND (c0_.id <= (SELECT c2_.id FROM cms_users c2_ WHERE c2_.name = ?))'
479        );
480    }
481
482    public function testSupportsMemberOfExpression()
483    {
484        // "Get all users who have $phone as a phonenumber." (*cough* doesnt really make sense...)
485        $q1 = $this->_em->createQuery('SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE :param MEMBER OF u.phonenumbers');
486        $q1->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true);
487
488        $phone = new \Doctrine\Tests\Models\CMS\CmsPhonenumber;
489        $phone->phonenumber = 101;
490        $q1->setParameter('param', $phone);
491
492        $this->assertEquals(
493            'SELECT c0_.id AS id0 FROM cms_users c0_ WHERE EXISTS (SELECT 1 FROM cms_phonenumbers c1_ WHERE c0_.id = c1_.user_id AND c1_.phonenumber = ?)',
494            $q1->getSql()
495        );
496
497        // "Get all users who are members of $group."
498        $q2 = $this->_em->createQuery('SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE :param MEMBER OF u.groups');
499        $q2->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true);
500
501        $group = new \Doctrine\Tests\Models\CMS\CmsGroup;
502        $group->id = 101;
503        $q2->setParameter('param', $group);
504
505        $this->assertEquals(
506            'SELECT c0_.id AS id0 FROM cms_users c0_ WHERE EXISTS (SELECT 1 FROM cms_users_groups c1_ INNER JOIN cms_groups c2_ ON c1_.group_id = c2_.id WHERE c1_.user_id = c0_.id AND c2_.id = ?)',
507            $q2->getSql()
508        );
509
510        // "Get all persons who have $person as a friend."
511        // Tough one: Many-many self-referencing ("friends") with class table inheritance
512        $q3 = $this->_em->createQuery('SELECT p FROM Doctrine\Tests\Models\Company\CompanyPerson p WHERE :param MEMBER OF p.friends');
513        $person = new \Doctrine\Tests\Models\Company\CompanyPerson;
514        $this->_em->getClassMetadata(get_class($person))->setIdentifierValues($person, array('id' => 101));
515        $q3->setParameter('param', $person);
516        $this->assertEquals(
517            'SELECT c0_.id AS id0, c0_.name AS name1, c1_.title AS title2, c1_.car_id AS car_id3, c2_.salary AS salary4, c2_.department AS department5, c0_.discr AS discr6, c0_.spouse_id AS spouse_id7 FROM company_persons c0_ LEFT JOIN company_managers c1_ ON c0_.id = c1_.id LEFT JOIN company_employees c2_ ON c0_.id = c2_.id WHERE EXISTS (SELECT 1 FROM company_persons_friends c3_ INNER JOIN company_persons c4_ ON c3_.friend_id = c4_.id WHERE c3_.person_id = c0_.id AND c4_.id = ?)',
518            $q3->getSql()
519        );
520    }
521
522    public function testSupportsCurrentDateFunction()
523    {
524        $q = $this->_em->createQuery('SELECT d.id FROM Doctrine\Tests\Models\Generic\DateTimeModel d WHERE d.datetime > current_date()');
525        $q->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true);
526        $this->assertEquals('SELECT d0_.id AS id0 FROM date_time_model d0_ WHERE d0_.col_datetime > CURRENT_DATE', $q->getSql());
527    }
528
529    public function testSupportsCurrentTimeFunction()
530    {
531        $q = $this->_em->createQuery('SELECT d.id FROM Doctrine\Tests\Models\Generic\DateTimeModel d WHERE d.time > current_time()');
532        $q->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true);
533        $this->assertEquals('SELECT d0_.id AS id0 FROM date_time_model d0_ WHERE d0_.col_time > CURRENT_TIME', $q->getSql());
534    }
535
536    public function testSupportsCurrentTimestampFunction()
537    {
538        $q = $this->_em->createQuery('SELECT d.id FROM Doctrine\Tests\Models\Generic\DateTimeModel d WHERE d.datetime > current_timestamp()');
539        $q->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true);
540        $this->assertEquals('SELECT d0_.id AS id0 FROM date_time_model d0_ WHERE d0_.col_datetime > CURRENT_TIMESTAMP', $q->getSql());
541    }
542
543    public function testExistsExpressionInWhereCorrelatedSubqueryAssocCondition()
544    {
545        $this->assertSqlGeneration(
546            // DQL
547            // The result of this query consists of all employees whose spouses are also employees.
548            'SELECT DISTINCT emp FROM Doctrine\Tests\Models\CMS\CmsEmployee emp
549                WHERE EXISTS (
550                    SELECT spouseEmp
551                    FROM Doctrine\Tests\Models\CMS\CmsEmployee spouseEmp
552                    WHERE spouseEmp = emp.spouse)',
553            // SQL
554            'SELECT DISTINCT c0_.id AS id0, c0_.name AS name1 FROM cms_employees c0_'
555                . ' WHERE EXISTS ('
556                    . 'SELECT c1_.id FROM cms_employees c1_ WHERE c1_.id = c0_.spouse_id'
557                    . ')'
558
559        );
560    }
561
562    public function testLimitFromQueryClass()
563    {
564        $q = $this->_em
565            ->createQuery('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u')
566            ->setMaxResults(10);
567
568        $this->assertEquals('SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ LIMIT 10', $q->getSql());
569    }
570
571    public function testLimitAndOffsetFromQueryClass()
572    {
573        $q = $this->_em
574            ->createQuery('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u')
575            ->setMaxResults(10)
576            ->setFirstResult(0);
577
578        $this->assertEquals('SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ LIMIT 10 OFFSET 0', $q->getSql());
579    }
580
581    public function testSizeFunction()
582    {
583        $this->assertSqlGeneration(
584            "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE SIZE(u.phonenumbers) > 1",
585            "SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE (SELECT COUNT(*) FROM cms_phonenumbers c1_ WHERE c1_.user_id = c0_.id) > 1"
586        );
587    }
588
589    public function testSizeFunctionSupportsManyToMany()
590    {
591        $this->assertSqlGeneration(
592            "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE SIZE(u.groups) > 1",
593            "SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE (SELECT COUNT(*) FROM cms_users_groups c1_ WHERE c1_.user_id = c0_.id) > 1"
594        );
595    }
596
597    public function testEmptyCollectionComparisonExpression()
598    {
599        $this->assertSqlGeneration(
600            "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.phonenumbers IS EMPTY",
601            "SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE (SELECT COUNT(*) FROM cms_phonenumbers c1_ WHERE c1_.user_id = c0_.id) = 0"
602        );
603        $this->assertSqlGeneration(
604            "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.phonenumbers IS NOT EMPTY",
605            "SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE (SELECT COUNT(*) FROM cms_phonenumbers c1_ WHERE c1_.user_id = c0_.id) > 0"
606        );
607    }
608
609    public function testNestedExpressions()
610    {
611        $this->assertSqlGeneration(
612            "select u from Doctrine\Tests\Models\CMS\CmsUser u where u.id > 10 and u.id < 42 and ((u.id * 2) > 5)",
613            "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)"
614        );
615    }
616
617    public function testNestedExpressions2()
618    {
619        $this->assertSqlGeneration(
620            "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",
621            "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"
622        );
623    }
624
625    public function testNestedExpressions3()
626    {
627        $this->assertSqlGeneration(
628            "select u from Doctrine\Tests\Models\CMS\CmsUser u where (u.id > 10) and (u.id between 1 and 10 or u.id in (1, 2, 3, 4, 5))",
629            "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 BETWEEN 1 AND 10 OR c0_.id IN (1, 2, 3, 4, 5))"
630        );
631    }
632
633    public function testOrderByCollectionAssociationSize()
634    {
635        $this->assertSqlGeneration(
636            "select u, size(u.articles) as numArticles from Doctrine\Tests\Models\CMS\CmsUser u order by numArticles",
637            "SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3, (SELECT COUNT(*) FROM cms_articles c1_ WHERE c1_.user_id = c0_.id) AS sclr4 FROM cms_users c0_ ORDER BY sclr4 ASC"
638        );
639    }
640
641    public function testBooleanLiteralInWhereOnSqlite()
642    {
643        $oldPlat = $this->_em->getConnection()->getDatabasePlatform();
644        $this->_em->getConnection()->setDatabasePlatform(new \Doctrine\DBAL\Platforms\SqlitePlatform);
645
646        $this->assertSqlGeneration(
647            "SELECT b FROM Doctrine\Tests\Models\Generic\BooleanModel b WHERE b.booleanField = true",
648            "SELECT b0_.id AS id0, b0_.booleanField AS booleanField1 FROM boolean_model b0_ WHERE b0_.booleanField = 1"
649        );
650
651        $this->assertSqlGeneration(
652            "SELECT b FROM Doctrine\Tests\Models\Generic\BooleanModel b WHERE b.booleanField = false",
653            "SELECT b0_.id AS id0, b0_.booleanField AS booleanField1 FROM boolean_model b0_ WHERE b0_.booleanField = 0"
654        );
655
656        $this->_em->getConnection()->setDatabasePlatform($oldPlat);
657    }
658
659    public function testBooleanLiteralInWhereOnPostgres()
660    {
661        $oldPlat = $this->_em->getConnection()->getDatabasePlatform();
662        $this->_em->getConnection()->setDatabasePlatform(new \Doctrine\DBAL\Platforms\PostgreSqlPlatform);
663
664        $this->assertSqlGeneration(
665            "SELECT b FROM Doctrine\Tests\Models\Generic\BooleanModel b WHERE b.booleanField = true",
666            "SELECT b0_.id AS id0, b0_.booleanField AS booleanField1 FROM boolean_model b0_ WHERE b0_.booleanField = 'true'"
667        );
668
669        $this->assertSqlGeneration(
670            "SELECT b FROM Doctrine\Tests\Models\Generic\BooleanModel b WHERE b.booleanField = false",
671            "SELECT b0_.id AS id0, b0_.booleanField AS booleanField1 FROM boolean_model b0_ WHERE b0_.booleanField = 'false'"
672        );
673
674        $this->_em->getConnection()->setDatabasePlatform($oldPlat);
675    }
676
677    public function testSingleValuedAssociationFieldInWhere()
678    {
679        $this->assertSqlGeneration(
680            "SELECT p FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE p.user = ?1",
681            "SELECT c0_.phonenumber AS phonenumber0 FROM cms_phonenumbers c0_ WHERE c0_.user_id = ?"
682        );
683    }
684
685    public function testSingleValuedAssociationNullCheckOnOwningSide()
686    {
687        $this->assertSqlGeneration(
688            "SELECT a FROM Doctrine\Tests\Models\CMS\CmsAddress a WHERE a.user IS NULL",
689            "SELECT c0_.id AS id0, c0_.country AS country1, c0_.zip AS zip2, c0_.city AS city3 FROM cms_addresses c0_ WHERE c0_.user_id IS NULL"
690        );
691    }
692
693    // Null check on inverse side has to happen through explicit JOIN.
694    // "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.address IS NULL"
695    // where the CmsUser is the inverse side is not supported.
696    public function testSingleValuedAssociationNullCheckOnInverseSide()
697    {
698        $this->assertSqlGeneration(
699            "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.address a WHERE a.id IS NULL",
700            "SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ LEFT JOIN cms_addresses c1_ ON c0_.id = c1_.user_id WHERE c1_.id IS NULL"
701        );
702    }
703
704    /**
705     * @group DDC-339
706     */
707    public function testStringFunctionLikeExpression()
708    {
709        $this->assertSqlGeneration(
710            "SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE LOWER(u.name) LIKE '%foo OR bar%'",
711            "SELECT c0_.name AS name0 FROM cms_users c0_ WHERE LOWER(c0_.name) LIKE '%foo OR bar%'"
712        );
713        $this->assertSqlGeneration(
714            "SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE LOWER(u.name) LIKE :str",
715            "SELECT c0_.name AS name0 FROM cms_users c0_ WHERE LOWER(c0_.name) LIKE ?"
716        );
717        $this->assertSqlGeneration(
718            "SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE CONCAT(UPPER(u.name), '_moo') LIKE :str",
719            "SELECT c0_.name AS name0 FROM cms_users c0_ WHERE UPPER(c0_.name) || '_moo' LIKE ?"
720        );
721    }
722
723    /**
724     * @group DDC-338
725     */
726    public function testOrderedCollectionFetchJoined()
727    {
728        $this->assertSqlGeneration(
729            "SELECT r, l FROM Doctrine\Tests\Models\Routing\RoutingRoute r JOIN r.legs l",
730            "SELECT r0_.id AS id0, r1_.id AS id1, r1_.departureDate AS departureDate2, r1_.arrivalDate AS arrivalDate3 FROM RoutingRoute r0_ INNER JOIN RoutingRouteLegs r2_ ON r0_.id = r2_.route_id INNER JOIN RoutingLeg r1_ ON r1_.id = r2_.leg_id ".
731            "ORDER BY r1_.departureDate ASC"
732        );
733    }
734
735    public function testSubselectInSelect()
736    {
737        $this->assertSqlGeneration(
738            "SELECT u.name, (SELECT COUNT(p.phonenumber) FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE p.phonenumber = 1234) pcount FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name = 'jon'",
739            "SELECT c0_.name AS name0, (SELECT COUNT(c1_.phonenumber) AS dctrn__1 FROM cms_phonenumbers c1_ WHERE c1_.phonenumber = 1234) AS sclr1 FROM cms_users c0_ WHERE c0_.name = 'jon'"
740        );
741    }
742
743    /**
744     * @group locking
745     * @group DDC-178
746     */
747    public function testPessimisticWriteLockQueryHint()
748    {
749        if ($this->_em->getConnection()->getDatabasePlatform() instanceof \Doctrine\DBAL\Platforms\SqlitePlatform) {
750            $this->markTestSkipped('SqLite does not support Row locking at all.');
751        }
752
753        $this->assertSqlGeneration(
754            "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.username = 'gblanco'",
755            "SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 ".
756            "FROM cms_users c0_ WHERE c0_.username = 'gblanco' FOR UPDATE",
757            array(Query::HINT_LOCK_MODE => \Doctrine\DBAL\LockMode::PESSIMISTIC_WRITE)
758        );
759    }
760
761    /**
762     * @group locking
763     * @group DDC-178
764     */
765    public function testPessimisticReadLockQueryHintPostgreSql()
766    {
767        $this->_em->getConnection()->setDatabasePlatform(new \Doctrine\DBAL\Platforms\PostgreSqlPlatform);
768
769        $this->assertSqlGeneration(
770            "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.username = 'gblanco'",
771            "SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 ".
772            "FROM cms_users c0_ WHERE c0_.username = 'gblanco' FOR SHARE",
773            array(Query::HINT_LOCK_MODE => \Doctrine\DBAL\LockMode::PESSIMISTIC_READ)
774                );
775    }
776
777    /**
778     * @group DDC-430
779     */
780    public function testSupportSelectWithMoreThan10InputParameters()
781    {
782        $this->assertSqlGeneration(
783            "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1 OR u.id = ?2 OR u.id = ?3 OR u.id = ?4 OR u.id = ?5 OR u.id = ?6 OR u.id = ?7 OR u.id = ?8 OR u.id = ?9 OR u.id = ?10 OR u.id = ?11",
784            "SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE c0_.id = ? OR c0_.id = ? OR c0_.id = ? OR c0_.id = ? OR c0_.id = ? OR c0_.id = ? OR c0_.id = ? OR c0_.id = ? OR c0_.id = ? OR c0_.id = ? OR c0_.id = ?"
785        );
786    }
787
788    /**
789     * @group locking
790     * @group DDC-178
791     */
792    public function testPessimisticReadLockQueryHintMySql()
793    {
794        $this->_em->getConnection()->setDatabasePlatform(new \Doctrine\DBAL\Platforms\MySqlPlatform);
795
796        $this->assertSqlGeneration(
797            "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.username = 'gblanco'",
798            "SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 ".
799            "FROM cms_users c0_ WHERE c0_.username = 'gblanco' LOCK IN SHARE MODE",
800            array(Query::HINT_LOCK_MODE => \Doctrine\DBAL\LockMode::PESSIMISTIC_READ)
801        );
802    }
803
804    /**
805     * @group locking
806     * @group DDC-178
807     */
808    public function testPessimisticReadLockQueryHintOracle()
809    {
810        $this->_em->getConnection()->setDatabasePlatform(new \Doctrine\DBAL\Platforms\OraclePlatform);
811
812        $this->assertSqlGeneration(
813            "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.username = 'gblanco'",
814            "SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 ".
815            "FROM cms_users c0_ WHERE c0_.username = 'gblanco' FOR UPDATE",
816            array(Query::HINT_LOCK_MODE => \Doctrine\DBAL\LockMode::PESSIMISTIC_READ)
817        );
818    }
819
820    /**
821     * @group DDC-431
822     */
823    public function testSupportToCustomDQLFunctions()
824    {
825        $config = $this->_em->getConfiguration();
826        $config->addCustomNumericFunction('MYABS', 'Doctrine\Tests\ORM\Query\MyAbsFunction');
827
828        $this->assertSqlGeneration(
829            'SELECT MYABS(p.phonenumber) FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p',
830            'SELECT ABS(c0_.phonenumber) AS sclr0 FROM cms_phonenumbers c0_'
831        );
832
833        $config->setCustomNumericFunctions(array());
834    }
835
836    /**
837     * @group DDC-826
838     */
839    public function testMappedSuperclassAssociationJoin()
840    {
841        $this->assertSqlGeneration(
842            'SELECT f FROM Doctrine\Tests\Models\DirectoryTree\File f JOIN f.parentDirectory d WHERE f.id = ?1',
843            'SELECT f0_.id AS id0, f0_.extension AS extension1, f0_.name AS name2 FROM "file" f0_ INNER JOIN Directory d1_ ON f0_.parentDirectory_id = d1_.id WHERE f0_.id = ?'
844        );
845    }
846}
847
848
849class MyAbsFunction extends \Doctrine\ORM\Query\AST\Functions\FunctionNode
850{
851    public $simpleArithmeticExpression;
852
853    /**
854     * @override
855     */
856    public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
857    {
858        return 'ABS(' . $sqlWalker->walkSimpleArithmeticExpression(
859            $this->simpleArithmeticExpression
860        ) . ')';
861    }
862
863    /**
864     * @override
865     */
866    public function parse(\Doctrine\ORM\Query\Parser $parser)
867    {
868        $lexer = $parser->getLexer();
869
870        $parser->match(\Doctrine\ORM\Query\Lexer::T_IDENTIFIER);
871        $parser->match(\Doctrine\ORM\Query\Lexer::T_OPEN_PARENTHESIS);
872
873        $this->simpleArithmeticExpression = $parser->SimpleArithmeticExpression();
874        
875        $parser->match(\Doctrine\ORM\Query\Lexer::T_CLOSE_PARENTHESIS);
876    }
877}