Failed Conditions
Push — master ( ddb3cd...4476ec )
by Marco
11:47
created

SelectSqlGenerationTest   F

Complexity

Total Complexity 195

Size/Duplication

Total Lines 2319
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 2319
rs 0.6314
c 0
b 0
f 0
wmc 195

184 Methods

Rating   Name   Duplication   Size   Complexity  
B assertInvalidSqlGeneration() 0 24 3
A testSupportsSelectUsingMultipleFromComponents() 0 5 1
A testJoinWithRangeVariablePutsConditionIntoSqlWhereClause() 0 6 1
A testSupportsSelectForAllNestedField() 0 5 1
A testSupportsSelectForOneNestedField() 0 5 1
A testSupportsSelectForOneField() 0 5 1
A testJoinWithRangeVariableAndInheritancePutsConditionIntoSqlWhereClause() 0 11 1
A testSupportsSelectForAllFields() 0 5 1
A setUp() 0 3 1
A testNotExistsExpression() 0 5 1
A testSupportsJoinOnMultipleComponents() 0 5 1
A testSupportsSelectForMultipleColumnsOfASingleComponent() 0 5 1
B assertSqlGeneration() 0 26 4
A testSupportsMemberOfExpressionOneToMany() 0 14 1
A testSupportsJoinOnMultipleComponentsWithJoinedInheritanceType() 0 15 1
A testColumnNameWithNumbersAndNonAlphanumericCharacters() 0 15 1
A testSupportsInnerJoinAndWithClauseRestriction() 0 5 1
A testCustomTypeValueSqlForPartialObject() 0 11 2
A testSupportsConcatFunctionMysql() 0 12 1
A testMappedSuperclassAssociationJoin() 0 5 1
A testSingleValuedAssociationFieldInWhere() 0 5 1
A testSupportsFunctionalExpressionsInWherePart() 0 7 1
A testOrderByClauseSupportsSimpleArithmeticExpression() 0 13 1
A testSupportsSingleValuedInExpressionWithoutSpacesInWherePart() 0 5 1
A testSingleValuedAssociationNullCheckOnOwningSide() 0 5 1
A testSupportsAggregateCountFunctionWithSimpleArithmeticMySql() 0 7 1
A testSubSelectDiscriminator() 0 5 1
A testSupportsInstanceOfExpressionsInWherePartPrefixedSlash() 0 5 1
A testSupportsOrderByDesc() 0 5 1
A testOrderByClauseShouldReplaceOrderByRelationMapping() 0 10 1
A testSupportsAggregateFunctionWithSimpleArithmetic() 0 5 1
A testHavingSupportResultVariableInExpression() 0 5 1
A testPessimisticWriteLockQueryHint() 0 10 2
A testOrderedCollectionFetchJoined() 0 5 1
A testSupportsBetweenClauseWithPositionalParameters() 0 5 1
A testOrderBySupportsSingleValuedPathExpressionOwningSide() 0 5 1
A testSupportsOrderByWithAscAsDefault() 0 5 1
A testSupportsCurrentDateFunction() 0 6 1
A testSupportsAggregateFunctionInASelectDistinct() 0 5 1
A testExistsExpressionInWhereCorrelatedSubqueryAssocCondition() 0 15 1
A testSubselectInSelect() 0 5 1
A testSupportsInstanceOfExpressionsInWherePartWithUnrelatedClass() 0 5 1
A testSupportsNotInExpressionInWherePart() 0 5 1
A testSupportsSelectDistinct() 0 5 1
A testCaseThenFunction() 0 15 1
A testSupportsWhereClauseWithNamedParameter() 0 5 1
A testArithmeticPriority() 0 15 1
A testMultipleFromAndInheritanceCondition() 0 5 1
A testCaseContainingCoalesce() 0 5 1
A testHavingRegressionUsingVariableWithMathOperatorsExpression() 0 5 1
A testSupportsNotBetweenForSizeFunction() 0 5 1
A testInExpressionWithSingleValuedAssociationPathExpressionInWherePart() 0 5 1
A testSupportsMultipleEntitiesInFromClauseUsingPathExpression() 0 5 1
A testSingleTableInheritanceCreatesOnConditionAndWhere() 0 10 1
A testPessimisticReadLockQueryHintOracle() 0 8 1
A testSupportsWhereClauseWithPositionalParameter() 0 5 1
A testSelectComplexMathematicalExpression() 0 5 1
A testSupportsMemberOfExpressionSelfReferencing() 0 18 1
A testSupportsMemberOfWithSingleValuedAssociation() 0 6 1
A testLockModeNoneQueryHint() 0 6 1
A testHavingSupportResultVariableNullComparisonExpression() 0 5 1
A testSupportsMemberOfExpressionManyToMany() 0 14 1
A testInvalidInExpressionWithSingleValuedAssociationPathExpressionOnInverseSide() 0 6 1
A testExistsExpressionWithSimpleSelectReturningScalar() 0 15 1
A testLimitFromQueryClass() 0 9 1
A testSupportsSelectWithCollectionAssociationJoin() 0 5 1
A testSupportsLeftJoinAndWithClauseRestriction() 0 5 1
A testJoinOnClause_NotYetSupported_ThrowsException() 0 9 1
A testSupportsInstanceOfExpressionsUsingInputParameterInWherePart() 0 6 1
A testSupportsCombinedWhereClauseWithNamedParameter() 0 5 1
A testPessimisticReadLockQueryHintMySql() 0 8 1
A testSupportsCurrentTimestampFunction() 0 6 1
A testSupportsInstanceOfExpressionsInWherePart() 0 5 1
A testSupportsInstanceOfExpressionsInWherePartInDeeperLevel() 0 5 1
A testStringFunctionNotLikeExpression() 0 14 1
A testSupportsMoreThanTwoParametersInConcatFunctionSqlServer() 0 12 1
A testSupportSelectWithMoreThan10InputParameters() 0 5 1
A testSupportsWhereAndClauseWithNamedParameters() 0 5 1
B testSupportsSubSqlFunction() 0 25 1
A testPessimisticReadLockQueryHintPostgreSql() 0 8 1
A testOrderBySupportsSingleValuedPathExpressionInverseSide() 0 5 1
A testIdVariableResultVariableReuse() 0 14 2
A testHavingSupportIsNullExpression() 0 10 1
A testHavingSupportResultVariableInAggregateFunction() 0 5 1
A testSupportsOrderByAsc() 0 5 1
A testSupportsMoreThanTwoParametersInConcatFunctionMySql() 0 12 1
A mathematicOperatorsProvider() 0 3 1
A testSelectCorrelatedSubqueryComplexMathematicalExpression() 0 5 1
A testGroupByIdentificationVariable() 0 5 1
A testCustomTypeValueSqlIgnoresIdentifierColumn() 0 11 2
A testSubqueriesInComparisonExpression() 0 5 1
A testSupportToCustomDQLFunctions() 0 11 1
A testSupportsInstanceOfExpressionInWherePartWithMultipleValues() 0 6 1
A testSupportsPlainJoinWithoutClause() 0 10 1
A testSupportsInstanceOfExpressionsInWherePartInDeepestLevel() 0 5 1
A testBooleanLiteralInWhereOnSqlite() 0 12 1
A testEmptyCollectionComparisonExpression() 0 9 1
A testSupportsTrimFunction() 0 5 1
A testGroupBy() 0 5 1
B testStringFunctionLikeExpression() 0 27 1
A testCaseContainingNullIf() 0 5 1
A testNestedExpressions() 0 5 1
A testSupportsASqlKeywordInAStringLiteralParam() 0 5 1
A testSizeFunctionSupportsManyToMany() 0 5 1
B testQuotedWalkJoinVariableDeclaration() 0 30 1
A testCaseThenParameterArithmeticExpression() 0 15 1
A testSupportsMemberOfWithIdentificationVariable() 0 6 1
A testSingleTableInheritanceJoinCreatesOnCondition() 0 8 1
A testSupportsTrimLeadingZeroString() 0 5 1
A testSizeFunction() 0 5 1
A testClassTableInheritanceJoinWithConditionAppliesToBaseTable() 0 6 1
A testHavingSupportResultVariableLikeExpression() 0 5 1
A testCustomTypeValueSqlForAllFields() 0 11 2
A testCustomTypeValueSql() 0 11 2
A testSupportsConcatFunctionPgSql() 0 12 1
A testSingleTableInheritanceLeftJoinNonAssociationWithConditionAndWhere() 0 7 1
A testSupportsMoreThanTwoParametersInConcatFunctionPgSql() 0 12 1
B testWhereFunctionIsNullComparisonExpression() 0 35 1
A testSupportsExistsExpressionInWherePartWithCorrelatedSubquery() 0 5 1
A testNestedExpressions2() 0 5 1
A testConstantValueInSelect() 0 5 1
A testSupportsMultipleEntitiesInFromClause() 0 5 1
A testSingleValuedAssociationNullCheckOnInverseSide() 0 5 1
A testSupportsMultipleValuedInExpressionInWherePart() 0 5 1
A testNestedExpressions3() 0 5 1
A testSupportsSelectWithSingleValuedAssociationJoin() 0 5 1
A testSupportsCurrentTimeFunction() 0 6 1
A testStripNonAlphanumericCharactersFromAlias() 0 15 1
A testSupportsMultipleJoins() 0 5 1
A testBooleanLiteralInWhereOnPostgres() 0 12 1
A testOrderByClauseSupportsFunction() 0 5 1
B testSupportsNewOperator() 0 30 1
A testOrderByCollectionAssociationSize() 0 5 1
A testSupportsArithmeticExpressionsInWherePart() 0 5 1
A testSingleTableInheritanceLeftJoinWithConditionAndWhere() 0 6 1
A testSingleTableInheritanceLeftJoinWithCondition() 0 6 1
A testQuotedTableDeclaration() 0 5 1
A testLimitAndOffsetFromQueryClass() 0 10 1
A testSingleTableInheritanceInnerJoinWithCondition() 0 6 1
A testSupportsMemberOfExpressionManyToManyParameterArray() 0 14 1
A testSupportsNotInExpressionForModFunction() 0 5 1
A testSupportsAggregateFunctionInSelectedFields() 0 5 1
A testGeneralCaseWithSingleWhenClauseInSubselect() 0 5 1
A testInheritanceTypeSingleTableInLeafClassWithDisabledForcePartialLoad() 0 6 1
A testInheritanceTypeJoinInChildClassWithDisabledForcePartialLoad() 0 6 1
A testInheritanceTypeJoinInLeafClassWithDisabledForcePartialLoad() 0 6 1
A testSelectForeignKeyPKWithoutFields() 0 5 1
A testSubSelectAliasesFromOuterQueryReuseInWhereClause() 0 5 1
A testInheritanceTypeJoinInRootClassWithEnabledForcePartialLoad() 0 6 1
A testInheritanceTypeJoinInRootClassWithDisabledForcePartialLoad() 0 6 1
A testSubSelectAliasesFromOuterQuery() 0 5 1
A testIdentityFunctionInSelectClause() 0 5 1
A testInheritanceTypeJoinInLeafClassWithEnabledForcePartialLoad() 0 6 1
A testSelfReferenceWithOneToOneDoesNotDuplicateAlias() 0 6 1
A testGeneralCaseWithSingleWhenClause() 0 5 1
A testSimpleCaseWithSingleWhenClauseInSubselect() 0 5 1
A testInheritanceTypeSingleTableInRootClassWithEnabledForcePartialLoad() 0 6 1
A testGeneralCaseWithMultipleWhenClause() 0 5 1
A testSelectWithArithmeticExpressionBeforeField() 0 10 1
A testInheritanceTypeSingleTableInChildClassWithDisabledForcePartialLoad() 0 6 1
A testSubSelectAliasesFromOuterQueryWithSubquery() 0 5 1
A testGroupBySupportsResultVariable() 0 5 1
A testSupportsBitComparison() 0 17 1
A testGeneralCaseWithMultipleWhenClauseInSubselect() 0 5 1
A testInheritanceTypeSingleTableInRootClassWithDisabledForcePartialLoad() 0 6 1
A testIssue331() 0 5 1
A testSimpleCaseWithMultipleWhenClause() 0 5 1
A testSimpleCaseWithSingleWhenClause() 0 5 1
A testGroupBySupportsIdentificationVariable() 0 5 1
A testSupportsParenthesisExpressionInSubSelect() 0 5 1
A testPartialWithAssociationIdentifier() 0 10 1
A testInheritanceTypeJoinInChildClassWithEnabledForcePartialLoad() 0 6 1
A testSimpleCaseWithMultipleWhenClauseInSubselect() 0 5 1
B testCaseNegativeValuesInThenExpression() 0 25 1
A testIdentityFunctionWithCompositePrimaryKey() 0 20 1
A testForeignKeyAsPrimaryKeySubselect() 0 5 1
A testInheritanceTypeSingleTableInLeafClassWithEnabledForcePartialLoad() 0 6 1
A testGroupByAllFieldsWhenObjectHasForeignKeys() 0 10 1
A testSimpleCaseWithStringPrimary() 0 5 1
A testIdentityFunctionDoesNotAcceptStateField() 0 5 1
A testIdentityFunctionInJoinedSubclass() 0 12 1
A testInheritanceTypeSingleTableInChildClassWithEnabledForcePartialLoad() 0 6 1
A testParenthesesOnTheLeftHandOfComparison() 0 13 1
A testAliasDoesNotExceedPlatformDefinedLength() 0 5 1

How to fix   Complexity   

Complex Class

Complex classes like SelectSqlGenerationTest often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use SelectSqlGenerationTest, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\Tests\ORM\Query;
6
7
use Doctrine\DBAL\LockMode;
8
use Doctrine\DBAL\Platforms\MySqlPlatform;
9
use Doctrine\DBAL\Platforms\OraclePlatform;
10
use Doctrine\DBAL\Platforms\PostgreSqlPlatform;
11
use Doctrine\DBAL\Platforms\SqlitePlatform;
12
use Doctrine\DBAL\Platforms\SQLServerPlatform;
13
use Doctrine\DBAL\Types\Type as DBALType;
14
use Doctrine\ORM\Annotation as ORM;
15
use Doctrine\ORM\Query as ORMQuery;
16
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
17
use Doctrine\ORM\Query\Lexer;
18
use Doctrine\ORM\Query\Parser;
19
use Doctrine\ORM\Query\QueryException;
20
use Doctrine\ORM\Query\SqlWalker;
21
use Doctrine\Tests\DbalTypes\NegativeToPositiveType;
22
use Doctrine\Tests\Models\CMS\CmsGroup;
23
use Doctrine\Tests\Models\CMS\CmsPhonenumber;
24
use Doctrine\Tests\Models\Company\CompanyEmployee;
25
use Doctrine\Tests\Models\Company\CompanyPerson;
26
use Doctrine\Tests\OrmTestCase;
27
28
class SelectSqlGenerationTest extends OrmTestCase
29
{
30
    private $em;
31
32
    protected function setUp()
33
    {
34
        $this->em = $this->getTestEntityManager();
35
    }
36
37
    /**
38
     * Assert a valid SQL generation.
39
     *
40
     * @param string $dqlToBeTested
41
     * @param string $sqlToBeConfirmed
42
     * @param array $queryHints
43
     * @param array $queryParams
44
     */
45
    public function assertSqlGeneration($dqlToBeTested, $sqlToBeConfirmed, array $queryHints = [], array $queryParams = [])
46
    {
47
        try {
48
            $query = $this->em->createQuery($dqlToBeTested);
49
50
            foreach ($queryParams as $name => $value) {
51
                $query->setParameter($name, $value);
52
            }
53
54
            $query
55
                ->setHint(ORMQuery::HINT_FORCE_PARTIAL_LOAD, true)
56
                ->useQueryCache(false)
57
            ;
58
59
            foreach ($queryHints as $name => $value) {
60
                $query->setHint($name, $value);
61
            }
62
63
            $sqlGenerated = $query->getSQL();
64
65
            $query->free();
66
        } catch (\Exception $e) {
67
            $this->fail($e->getMessage() ."\n".$e->getTraceAsString());
68
        }
69
70
        self::assertEquals($sqlToBeConfirmed, $sqlGenerated);
71
    }
72
73
    /**
74
     * Asser an invalid SQL generation.
75
     *
76
     * @param string $dqlToBeTested
77
     * @param string $expectedException
78
     * @param array $queryHints
79
     * @param array $queryParams
80
     */
81
    public function assertInvalidSqlGeneration($dqlToBeTested, $expectedException, array $queryHints = [], array $queryParams = [])
82
    {
83
        $this->expectException($expectedException);
84
85
        $query = $this->em->createQuery($dqlToBeTested);
86
87
        foreach ($queryParams as $name => $value) {
88
            $query->setParameter($name, $value);
89
        }
90
91
        $query
92
            ->setHint(ORMQuery::HINT_FORCE_PARTIAL_LOAD, true)
93
            ->useQueryCache(false)
94
        ;
95
96
        foreach ($queryHints as $name => $value) {
97
            $query->setHint($name, $value);
98
        }
99
100
        $sql = $query->getSql();
101
        $query->free();
102
103
        // If we reached here, test failed
104
        $this->fail($sql);
105
    }
106
107
    /**
108
     * @group DDC-3697
109
     */
110
    public function testJoinWithRangeVariablePutsConditionIntoSqlWhereClause()
111
    {
112
        $this->assertSqlGeneration(
113
            'SELECT c.id FROM Doctrine\Tests\Models\Company\CompanyPerson c JOIN Doctrine\Tests\Models\Company\CompanyPerson r WHERE c.spouse = r AND r.id = 42',
114
            'SELECT t0."id" AS c0 FROM "company_persons" t0 INNER JOIN "company_persons" t1 WHERE t0."spouse_id" = t1."id" AND t1."id" = 42',
115
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => true]
116
        );
117
    }
118
119
    /**
120
     * @group DDC-3697
121
     */
122
    public function testJoinWithRangeVariableAndInheritancePutsConditionIntoSqlWhereClause()
123
    {
124
        /*
125
         * Basically like the previous test, but this time load data for the inherited objects as well.
126
         * The important thing is that the ON clauses in LEFT JOINs only contain the conditions necessary to join the appropriate inheritance table
127
         * whereas the filtering condition must remain in the SQL WHERE clause.
128
         */
129
        $this->assertSqlGeneration(
130
            'SELECT c.id FROM Doctrine\Tests\Models\Company\CompanyPerson c JOIN Doctrine\Tests\Models\Company\CompanyPerson r WHERE c.spouse = r AND r.id = 42',
131
            'SELECT t0."id" AS c0 FROM "company_persons" t0 LEFT JOIN "company_managers" t1 ON t0."id" = t1."id" LEFT JOIN "company_employees" t2 ON t0."id" = t2."id" INNER JOIN "company_persons" t3 LEFT JOIN "company_managers" t4 ON t3."id" = t4."id" LEFT JOIN "company_employees" t5 ON t3."id" = t5."id" WHERE t0."spouse_id" = t3."id" AND t3."id" = 42',
132
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => false]
133
        );
134
    }
135
136
    public function testSupportsSelectForAllFields()
137
    {
138
        $this->assertSqlGeneration(
139
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u',
140
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0'
141
        );
142
    }
143
144
    public function testSupportsSelectForOneField()
145
    {
146
        $this->assertSqlGeneration(
147
            'SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u',
148
            'SELECT t0."id" AS c0 FROM "cms_users" t0'
149
        );
150
    }
151
152
    public function testSupportsSelectForOneNestedField()
153
    {
154
        $this->assertSqlGeneration(
155
            'SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsArticle a JOIN a.user u',
156
            'SELECT t0."id" AS c0 FROM "cms_articles" t1 INNER JOIN "cms_users" t0 ON t1."user_id" = t0."id"'
157
        );
158
    }
159
160
    public function testSupportsSelectForAllNestedField()
161
    {
162
        $this->assertSqlGeneration(
163
            'SELECT a FROM Doctrine\Tests\Models\CMS\CmsArticle a JOIN a.user u ORDER BY u.name ASC',
164
            'SELECT t0."id" AS c0, t0."topic" AS c1, t0."text" AS c2, t0."version" AS c3 FROM "cms_articles" t0 INNER JOIN "cms_users" t1 ON t0."user_id" = t1."id" ORDER BY t1."name" ASC'
165
        );
166
    }
167
168
    public function testNotExistsExpression()
169
    {
170
        $this->assertSqlGeneration(
171
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE NOT EXISTS (SELECT p.phonenumber FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE p.phonenumber = 1234)',
172
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE NOT EXISTS (SELECT t1."phonenumber" FROM "cms_phonenumbers" t1 WHERE t1."phonenumber" = 1234)'
173
        );
174
    }
175
176
    public function testSupportsSelectForMultipleColumnsOfASingleComponent()
177
    {
178
        $this->assertSqlGeneration(
179
            'SELECT u.username, u.name FROM Doctrine\Tests\Models\CMS\CmsUser u',
180
            'SELECT t0."username" AS c0, t0."name" AS c1 FROM "cms_users" t0'
181
        );
182
    }
183
184
    public function testSupportsSelectUsingMultipleFromComponents()
185
    {
186
        $this->assertSqlGeneration(
187
            'SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u, Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE u = p.user',
188
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3, t1."phonenumber" AS c4 FROM "cms_users" t0, "cms_phonenumbers" t1 WHERE t0."id" = t1."user_id"'
189
        );
190
    }
191
192
    public function testSupportsJoinOnMultipleComponents()
193
    {
194
        $this->assertSqlGeneration(
195
            'SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN Doctrine\Tests\Models\CMS\CmsPhonenumber p WITH u = p.user',
196
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3, t1."phonenumber" AS c4 FROM "cms_users" t0 INNER JOIN "cms_phonenumbers" t1 ON (t0."id" = t1."user_id")'
197
        );
198
    }
199
200
    public function testSupportsJoinOnMultipleComponentsWithJoinedInheritanceType()
201
    {
202
        $this->assertSqlGeneration(
203
            'SELECT e FROM Doctrine\Tests\Models\Company\CompanyEmployee e JOIN Doctrine\Tests\Models\Company\CompanyManager m WITH e.id = m.id',
204
            'SELECT t0."id" AS c0, t0."name" AS c1, t1."salary" AS c2, t1."department" AS c3, t1."startDate" AS c4, t0."discr" AS c5 FROM "company_employees" t1 INNER JOIN "company_persons" t0 ON t1."id" = t0."id" INNER JOIN ("company_managers" t2 INNER JOIN "company_employees" t4 ON t2."id" = t4."id" INNER JOIN "company_persons" t3 ON t2."id" = t3."id") ON (t0."id" = t3."id")'
205
        );
206
207
        $this->assertSqlGeneration(
208
            'SELECT e FROM Doctrine\Tests\Models\Company\CompanyEmployee e LEFT JOIN Doctrine\Tests\Models\Company\CompanyManager m WITH e.id = m.id',
209
            'SELECT t0."id" AS c0, t0."name" AS c1, t1."salary" AS c2, t1."department" AS c3, t1."startDate" AS c4, t0."discr" AS c5 FROM "company_employees" t1 INNER JOIN "company_persons" t0 ON t1."id" = t0."id" LEFT JOIN ("company_managers" t2 INNER JOIN "company_employees" t4 ON t2."id" = t4."id" INNER JOIN "company_persons" t3 ON t2."id" = t3."id") ON (t0."id" = t3."id")'
210
        );
211
212
        $this->assertSqlGeneration(
213
            'SELECT c FROM Doctrine\Tests\Models\Company\CompanyContract c JOIN c.salesPerson s LEFT JOIN Doctrine\Tests\Models\Company\CompanyEvent e WITH s.id = e.id',
214
            'SELECT t0."id" AS c0, t0."completed" AS c1, t0."fixPrice" AS c2, t0."hoursWorked" AS c3, t0."pricePerHour" AS c4, t0."maxPrice" AS c5, t0."discr" AS c6 FROM "company_contracts" t0 INNER JOIN "company_employees" t1 ON t0."salesPerson_id" = t1."id" LEFT JOIN "company_persons" t2 ON t1."id" = t2."id" LEFT JOIN "company_events" t3 ON (t2."id" = t3."id") WHERE t0."discr" IN (\'fix\', \'flexible\', \'flexultra\')'
215
        );
216
    }
217
218
    public function testSupportsSelectWithCollectionAssociationJoin()
219
    {
220
        $this->assertSqlGeneration(
221
            'SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.phonenumbers p',
222
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3, t1."phonenumber" AS c4 FROM "cms_users" t0 INNER JOIN "cms_phonenumbers" t1 ON t0."id" = t1."user_id"'
223
        );
224
    }
225
226
    public function testSupportsSelectWithSingleValuedAssociationJoin()
227
    {
228
        $this->assertSqlGeneration(
229
            'SELECT u, a FROM Doctrine\Tests\Models\Forum\ForumUser u JOIN u.avatar a',
230
            'SELECT t0."id" AS c0, t0."username" AS c1, t1."id" AS c2 FROM "forum_users" t0 INNER JOIN "forum_avatars" t1 ON t0."avatar_id" = t1."id"'
231
        );
232
    }
233
234
    public function testSelectCorrelatedSubqueryComplexMathematicalExpression()
235
    {
236
        $this->assertSqlGeneration(
237
            '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',
238
            'SELECT (SELECT (count(t0."phonenumber") + 5) * 10 AS c1 FROM "cms_phonenumbers" t0 INNER JOIN "cms_users" t1 ON t0."user_id" = t1."id" WHERE t1."id" = t2."id") AS c0 FROM "cms_users" t2'
239
        );
240
    }
241
242
    public function testSelectComplexMathematicalExpression()
243
    {
244
        $this->assertSqlGeneration(
245
            'SELECT (count(p.phonenumber)+5)*10 FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p JOIN p.user ui WHERE ui.id = ?1',
246
            'SELECT (count(t0."phonenumber") + 5) * 10 AS c0 FROM "cms_phonenumbers" t0 INNER JOIN "cms_users" t1 ON t0."user_id" = t1."id" WHERE t1."id" = ?'
247
        );
248
    }
249
250
    /* NOT (YET?) SUPPORTED.
251
       Can be supported if SimpleSelectExpression supports SingleValuedPathExpression instead of StateFieldPathExpression.
252
253
    public function testSingleAssociationPathExpressionInSubselect()
254
    {
255
        $this->assertSqlGeneration(
256
            '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',
257
            'SELECT (SELECT t0."user_id" FROM "cms_phonenumbers" t0 WHERE t0."user_id" = t1."id") AS c0 FROM "cms_users" t1 WHERE t1."id" = ?'
258
        );
259
    }*/
260
261
    /**
262
     * @group DDC-1077
263
     */
264
    public function testConstantValueInSelect()
265
    {
266
        $this->assertSqlGeneration(
267
            'SELECT u.name, \'foo\' AS bar FROM Doctrine\Tests\Models\CMS\CmsUser u',
268
            'SELECT t0."name" AS c0, \'foo\' AS c1 FROM "cms_users" t0'
269
        );
270
    }
271
272
    public function testSupportsOrderByWithAscAsDefault()
273
    {
274
        $this->assertSqlGeneration(
275
            'SELECT u FROM Doctrine\Tests\Models\Forum\ForumUser u ORDER BY u.id',
276
            'SELECT t0."id" AS c0, t0."username" AS c1 FROM "forum_users" t0 ORDER BY t0."id" ASC'
277
        );
278
    }
279
280
    public function testSupportsOrderByAsc()
281
    {
282
        $this->assertSqlGeneration(
283
            'SELECT u FROM Doctrine\Tests\Models\Forum\ForumUser u ORDER BY u.id asc',
284
            'SELECT t0."id" AS c0, t0."username" AS c1 FROM "forum_users" t0 ORDER BY t0."id" ASC'
285
        );
286
    }
287
    public function testSupportsOrderByDesc()
288
    {
289
        $this->assertSqlGeneration(
290
            'SELECT u FROM Doctrine\Tests\Models\Forum\ForumUser u ORDER BY u.id desc',
291
            'SELECT t0."id" AS c0, t0."username" AS c1 FROM "forum_users" t0 ORDER BY t0."id" DESC'
292
        );
293
    }
294
295
    public function testSupportsSelectDistinct()
296
    {
297
        $this->assertSqlGeneration(
298
            'SELECT DISTINCT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u',
299
            'SELECT DISTINCT t0."name" AS c0 FROM "cms_users" t0'
300
        );
301
    }
302
303
    public function testSupportsAggregateFunctionInSelectedFields()
304
    {
305
        $this->assertSqlGeneration(
306
            'SELECT COUNT(u.id) FROM Doctrine\Tests\Models\CMS\CmsUser u GROUP BY u.id',
307
            'SELECT COUNT(t0."id") AS c0 FROM "cms_users" t0 GROUP BY t0."id"'
308
        );
309
    }
310
311
    public function testSupportsAggregateFunctionWithSimpleArithmetic()
312
    {
313
        $this->assertSqlGeneration(
314
            'SELECT MAX(u.id + 4) * 2 FROM Doctrine\Tests\Models\CMS\CmsUser u',
315
            'SELECT MAX(t0."id" + 4) * 2 AS c0 FROM "cms_users" t0'
316
        );
317
    }
318
319
    /**
320
     * @group DDC-3276
321
     */
322
    public function testSupportsAggregateCountFunctionWithSimpleArithmeticMySql()
323
    {
324
        $this->em->getConnection()->setDatabasePlatform(new MySqlPlatform());
325
326
        $this->assertSqlGeneration(
327
            'SELECT COUNT(CONCAT(u.id, u.name)) FROM Doctrine\Tests\Models\CMS\CmsUser u GROUP BY u.id',
328
            'SELECT COUNT(CONCAT(t0.`id`, t0.`name`)) AS c0 FROM `cms_users` t0 GROUP BY t0.`id`'
329
        );
330
    }
331
332
    public function testSupportsWhereClauseWithPositionalParameter()
333
    {
334
        $this->assertSqlGeneration(
335
            'select u from Doctrine\Tests\Models\Forum\ForumUser u where u.id = ?1',
336
            'SELECT t0."id" AS c0, t0."username" AS c1 FROM "forum_users" t0 WHERE t0."id" = ?'
337
        );
338
    }
339
340
    public function testSupportsWhereClauseWithNamedParameter()
341
    {
342
        $this->assertSqlGeneration(
343
            'select u from Doctrine\Tests\Models\Forum\ForumUser u where u.username = :name',
344
            'SELECT t0."id" AS c0, t0."username" AS c1 FROM "forum_users" t0 WHERE t0."username" = ?'
345
        );
346
    }
347
348
    public function testSupportsWhereAndClauseWithNamedParameters()
349
    {
350
        $this->assertSqlGeneration(
351
            'select u from Doctrine\Tests\Models\Forum\ForumUser u where u.username = :name and u.username = :name2',
352
            'SELECT t0."id" AS c0, t0."username" AS c1 FROM "forum_users" t0 WHERE t0."username" = ? AND t0."username" = ?'
353
        );
354
    }
355
356
    public function testSupportsCombinedWhereClauseWithNamedParameter()
357
    {
358
        $this->assertSqlGeneration(
359
            'select u from Doctrine\Tests\Models\Forum\ForumUser u where (u.username = :name OR u.username = :name2) AND u.id = :id',
360
            'SELECT t0."id" AS c0, t0."username" AS c1 FROM "forum_users" t0 WHERE (t0."username" = ? OR t0."username" = ?) AND t0."id" = ?'
361
        );
362
    }
363
364
    public function testSupportsAggregateFunctionInASelectDistinct()
365
    {
366
        $this->assertSqlGeneration(
367
            'SELECT COUNT(DISTINCT u.name) FROM Doctrine\Tests\Models\CMS\CmsUser u',
368
            'SELECT COUNT(DISTINCT t0."name") AS c0 FROM "cms_users" t0'
369
        );
370
    }
371
372
    // Ticket #668
373
    public function testSupportsASqlKeywordInAStringLiteralParam()
374
    {
375
        $this->assertSqlGeneration(
376
            'SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name LIKE \'%foo OR bar%\'',
377
            'SELECT t0."name" AS c0 FROM "cms_users" t0 WHERE t0."name" LIKE \'%foo OR bar%\''
378
        );
379
    }
380
381
    public function testSupportsArithmeticExpressionsInWherePart()
382
    {
383
        $this->assertSqlGeneration(
384
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE ((u.id + 5000) * u.id + 3) < 10000000',
385
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE ((t0."id" + 5000) * t0."id" + 3) < 10000000'
386
        );
387
    }
388
389
    public function testSupportsMultipleEntitiesInFromClause()
390
    {
391
        $this->assertSqlGeneration(
392
            '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',
393
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3, t1."id" AS c4, t1."topic" AS c5, t1."text" AS c6, t1."version" AS c7 FROM "cms_users" t0, "cms_articles" t1 INNER JOIN "cms_users" t2 ON t1."user_id" = t2."id" WHERE t0."id" = t2."id"'
394
        );
395
    }
396
397
    public function testSupportsMultipleEntitiesInFromClauseUsingPathExpression()
398
    {
399
        $this->assertSqlGeneration(
400
            'SELECT u, a FROM Doctrine\Tests\Models\CMS\CmsUser u, Doctrine\Tests\Models\CMS\CmsArticle a WHERE u.id = a.user',
401
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3, t1."id" AS c4, t1."topic" AS c5, t1."text" AS c6, t1."version" AS c7 FROM "cms_users" t0, "cms_articles" t1 WHERE t0."id" = t1."user_id"'
402
        );
403
    }
404
405
    public function testSupportsPlainJoinWithoutClause()
406
    {
407
        $this->assertSqlGeneration(
408
            'SELECT u.id, a.id from Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a',
409
            'SELECT t0."id" AS c0, t1."id" AS c1 FROM "cms_users" t0 LEFT JOIN "cms_articles" t1 ON t0."id" = t1."user_id"'
410
        );
411
412
        $this->assertSqlGeneration(
413
            'SELECT u.id, a.id from Doctrine\Tests\Models\CMS\CmsUser u JOIN u.articles a',
414
            'SELECT t0."id" AS c0, t1."id" AS c1 FROM "cms_users" t0 INNER JOIN "cms_articles" t1 ON t0."id" = t1."user_id"'
415
        );
416
    }
417
418
    /**
419
     * @group DDC-135
420
     */
421
    public function testSupportsLeftJoinAndWithClauseRestriction()
422
    {
423
        $this->assertSqlGeneration(
424
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a WITH a.topic LIKE \'%foo%\'',
425
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 LEFT JOIN "cms_articles" t1 ON t0."id" = t1."user_id" AND (t1."topic" LIKE \'%foo%\')'
426
        );
427
    }
428
429
    /**
430
     * @group DDC-135
431
     */
432
    public function testSupportsInnerJoinAndWithClauseRestriction()
433
    {
434
        $this->assertSqlGeneration(
435
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u INNER JOIN u.articles a WITH a.topic LIKE \'%foo%\'',
436
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 INNER JOIN "cms_articles" t1 ON t0."id" = t1."user_id" AND (t1."topic" LIKE \'%foo%\')'
437
        );
438
    }
439
440
    /**
441
     * @group DDC-135
442
     * @group DDC-177
443
     */
444
    public function testJoinOnClause_NotYetSupported_ThrowsException()
445
    {
446
        $this->expectException(QueryException::class);
447
448
        $query = $this->em->createQuery(
449
            'SELECT u, a FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a ON a.topic LIKE \'%foo%\''
450
        );
451
452
        $query->getSql();
453
    }
454
455
    public function testSupportsMultipleJoins()
456
    {
457
        $this->assertSqlGeneration(
458
            'SELECT u.id, a.id, p.phonenumber, c.id from Doctrine\Tests\Models\CMS\CmsUser u JOIN u.articles a JOIN u.phonenumbers p JOIN a.comments c',
459
            'SELECT t0."id" AS c0, t1."id" AS c1, t2."phonenumber" AS c2, t3."id" AS c3 FROM "cms_users" t0 INNER JOIN "cms_articles" t1 ON t0."id" = t1."user_id" INNER JOIN "cms_phonenumbers" t2 ON t0."id" = t2."user_id" INNER JOIN "cms_comments" t3 ON t1."id" = t3."article_id"'
460
        );
461
    }
462
463
    public function testSupportsTrimFunction()
464
    {
465
        $this->assertSqlGeneration(
466
            'SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE TRIM(TRAILING \' \' FROM u.name) = \'someone\'',
467
            'SELECT t0."name" AS c0 FROM "cms_users" t0 WHERE TRIM(TRAILING \' \' FROM t0."name") = \'someone\''
468
        );
469
    }
470
471
    /**
472
     * @group DDC-2668
473
     */
474
    public function testSupportsTrimLeadingZeroString()
475
    {
476
        $this->assertSqlGeneration(
477
            'SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE TRIM(TRAILING \'0\' FROM u.name) != \'\'',
478
            'SELECT t0."name" AS c0 FROM "cms_users" t0 WHERE TRIM(TRAILING \'0\' FROM t0."name") <> \'\''
479
        );
480
    }
481
482
    // Ticket 894
483
    public function testSupportsBetweenClauseWithPositionalParameters()
484
    {
485
        $this->assertSqlGeneration(
486
            'SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id BETWEEN ?1 AND ?2',
487
            'SELECT t0."name" AS c0 FROM "cms_users" t0 WHERE t0."id" BETWEEN ? AND ?'
488
        );
489
    }
490
491
    /**
492
     * @group DDC-1802
493
     */
494
    public function testSupportsNotBetweenForSizeFunction()
495
    {
496
        $this->assertSqlGeneration(
497
            'SELECT m.name FROM Doctrine\Tests\Models\StockExchange\Market m WHERE SIZE(m.stocks) NOT BETWEEN ?1 AND ?2',
498
            'SELECT t0."name" AS c0 FROM "exchange_markets" t0 WHERE (SELECT COUNT(*) FROM "exchange_stocks" t1 WHERE t1."market_id" = t0."id") NOT BETWEEN ? AND ?'
499
        );
500
    }
501
502
    public function testSupportsFunctionalExpressionsInWherePart()
503
    {
504
        $this->assertSqlGeneration(
505
            'SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE TRIM(u.name) = \'someone\'',
506
            // String quoting in the SQL usually depends on the database platform.
507
            // This test works with a mock connection which uses ' for string quoting.
508
            'SELECT t0."name" AS c0 FROM "cms_users" t0 WHERE TRIM(t0."name") = \'someone\''
509
        );
510
    }
511
512
    public function testSupportsInstanceOfExpressionsInWherePart()
513
    {
514
        $this->assertSqlGeneration(
515
            'SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF Doctrine\Tests\Models\Company\CompanyEmployee',
516
            'SELECT t0."id" AS c0, t0."name" AS c1, t0."discr" AS c2 FROM "company_persons" t0 WHERE t0."discr" IN (\'manager\', \'employee\')'
517
        );
518
    }
519
520
    public function testSupportsInstanceOfExpressionInWherePartWithMultipleValues()
521
    {
522
        // This also uses FQCNs starting with or without a backslash in the INSTANCE OF parameter
523
        $this->assertSqlGeneration(
524
            'SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF (Doctrine\Tests\Models\Company\CompanyEmployee, \Doctrine\Tests\Models\Company\CompanyManager)',
525
            'SELECT t0."id" AS c0, t0."name" AS c1, t0."discr" AS c2 FROM "company_persons" t0 WHERE t0."discr" IN (\'manager\', \'employee\')'
526
        );
527
    }
528
529
    /**
530
     * @group DDC-1194
531
     */
532
    public function testSupportsInstanceOfExpressionsInWherePartPrefixedSlash()
533
    {
534
        $this->assertSqlGeneration(
535
            'SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF \Doctrine\Tests\Models\Company\CompanyEmployee',
536
            'SELECT t0."id" AS c0, t0."name" AS c1, t0."discr" AS c2 FROM "company_persons" t0 WHERE t0."discr" IN (\'manager\', \'employee\')'
537
        );
538
    }
539
540
    /**
541
     * @group DDC-1194
542
     */
543
    public function testSupportsInstanceOfExpressionsInWherePartWithUnrelatedClass()
544
    {
545
        $this->assertInvalidSqlGeneration(
546
            'SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF \Doctrine\Tests\Models\CMS\CmsUser',
547
            'Doctrine\\ORM\\Query\\QueryException'
548
        );
549
    }
550
551
    public function testSupportsInstanceOfExpressionsInWherePartInDeeperLevel()
552
    {
553
        $this->assertSqlGeneration(
554
            'SELECT u FROM Doctrine\Tests\Models\Company\CompanyEmployee u WHERE u INSTANCE OF Doctrine\Tests\Models\Company\CompanyManager',
555
            'SELECT t0."id" AS c0, t0."name" AS c1, t1."salary" AS c2, t1."department" AS c3, t1."startDate" AS c4, t0."discr" AS c5 FROM "company_employees" t1 INNER JOIN "company_persons" t0 ON t1."id" = t0."id" WHERE t0."discr" IN (\'manager\')'
556
        );
557
    }
558
559
    public function testSupportsInstanceOfExpressionsInWherePartInDeepestLevel()
560
    {
561
        $this->assertSqlGeneration(
562
            'SELECT u FROM Doctrine\Tests\Models\Company\CompanyManager u WHERE u INSTANCE OF Doctrine\Tests\Models\Company\CompanyManager',
563
            'SELECT t0."id" AS c0, t0."name" AS c1, t1."salary" AS c2, t1."department" AS c3, t1."startDate" AS c4, t2."title" AS c5, t0."discr" AS c6 FROM "company_managers" t2 INNER JOIN "company_employees" t1 ON t2."id" = t1."id" INNER JOIN "company_persons" t0 ON t2."id" = t0."id" WHERE t0."discr" IN (\'manager\')'
564
        );
565
    }
566
567
    public function testSupportsInstanceOfExpressionsUsingInputParameterInWherePart()
568
    {
569
        $this->assertSqlGeneration(
570
            'SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF ?1',
571
            'SELECT t0."id" AS c0, t0."name" AS c1, t0."discr" AS c2 FROM "company_persons" t0 WHERE t0."discr" IN (?)',
572
            [], [1 => $this->em->getClassMetadata(CompanyEmployee::class)]
573
        );
574
    }
575
576
    // Ticket #973
577
    public function testSupportsSingleValuedInExpressionWithoutSpacesInWherePart()
578
    {
579
        $this->assertSqlGeneration(
580
            'SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE IDENTITY(u.email) IN(46)',
581
            'SELECT t0."name" AS c0 FROM "cms_users" t0 WHERE t0."email_id" IN (46)'
582
        );
583
    }
584
585
    public function testSupportsMultipleValuedInExpressionInWherePart()
586
    {
587
        $this->assertSqlGeneration(
588
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id IN (1, 2)',
589
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE t0."id" IN (1, 2)'
590
        );
591
    }
592
593
    public function testSupportsNotInExpressionInWherePart()
594
    {
595
        $this->assertSqlGeneration(
596
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE :id NOT IN (1)',
597
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE ? NOT IN (1)'
598
        );
599
    }
600
601
    /**
602
     * @group DDC-1802
603
     */
604
    public function testSupportsNotInExpressionForModFunction()
605
    {
606
        $this->assertSqlGeneration(
607
            'SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE MOD(u.id, 5) NOT IN(1,3,4)',
608
            'SELECT t0."name" AS c0 FROM "cms_users" t0 WHERE MOD(t0."id", 5) NOT IN (1, 3, 4)'
609
        );
610
    }
611
612
    public function testInExpressionWithSingleValuedAssociationPathExpressionInWherePart()
613
    {
614
        $this->assertSqlGeneration(
615
            'SELECT u FROM Doctrine\Tests\Models\Forum\ForumUser u WHERE u.avatar IN (?1, ?2)',
616
            'SELECT t0."id" AS c0, t0."username" AS c1 FROM "forum_users" t0 WHERE t0."avatar_id" IN (?, ?)'
617
        );
618
    }
619
620
    public function testInvalidInExpressionWithSingleValuedAssociationPathExpressionOnInverseSide()
621
    {
622
        // We do not support SingleValuedAssociationPathExpression on inverse side
623
        $this->assertInvalidSqlGeneration(
624
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.address IN (?1, ?2)',
625
            'Doctrine\ORM\Query\QueryException'
626
        );
627
    }
628
629
    public function testSupportsConcatFunctionMysql()
630
    {
631
        $this->em->getConnection()->setDatabasePlatform(new MySqlPlatform());
632
633
        $this->assertSqlGeneration(
634
            'SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE CONCAT(u.name, \'s\') = ?1',
635
            'SELECT t0.`id` AS c0 FROM `cms_users` t0 WHERE CONCAT(t0.`name`, \'s\') = ?'
636
        );
637
638
        $this->assertSqlGeneration(
639
            'SELECT CONCAT(u.id, u.name) FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1',
640
            'SELECT CONCAT(t0.`id`, t0.`name`) AS c0 FROM `cms_users` t0 WHERE t0.`id` = ?'
641
        );
642
    }
643
644
    public function testSupportsConcatFunctionPgSql()
645
    {
646
        $this->em->getConnection()->setDatabasePlatform(new PostgreSqlPlatform());
647
648
        $this->assertSqlGeneration(
649
            'SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE CONCAT(u.name, \'s\') = ?1',
650
            'SELECT t0."id" AS c0 FROM "cms_users" t0 WHERE t0."name" || \'s\' = ?'
651
        );
652
653
        $this->assertSqlGeneration(
654
            'SELECT CONCAT(u.id, u.name) FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1',
655
            'SELECT t0."id" || t0."name" AS c0 FROM "cms_users" t0 WHERE t0."id" = ?'
656
        );
657
    }
658
659
    public function testSupportsExistsExpressionInWherePartWithCorrelatedSubquery()
660
    {
661
        $this->assertSqlGeneration(
662
            '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)',
663
            'SELECT t0."id" AS c0 FROM "cms_users" t0 WHERE EXISTS (SELECT t1."phonenumber" FROM "cms_phonenumbers" t1 WHERE t1."phonenumber" = t0."id")'
664
        );
665
    }
666
667
    /**
668
     * @group DDC-593
669
     */
670
    public function testSubqueriesInComparisonExpression()
671
    {
672
        $this->assertSqlGeneration(
673
            '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))',
674
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE (t0."id" >= (SELECT t1."id" FROM "cms_users" t1 WHERE t1."name" = ?)) AND (t0."id" <= (SELECT t2."id" FROM "cms_users" t2 WHERE t2."name" = ?))'
675
        );
676
    }
677
678
    public function testSupportsMemberOfExpressionOneToMany()
679
    {
680
        // "Get all users who have $phone as a phonenumber." (*cough* doesnt really make sense...)
681
        $q = $this->em->createQuery('SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE :param MEMBER OF u.phonenumbers');
682
683
        $q->setHint(ORMQuery::HINT_FORCE_PARTIAL_LOAD, true);
684
685
        $phone = new CmsPhonenumber();
686
        $phone->phonenumber = 101;
687
        $q->setParameter('param', $phone);
688
689
        self::assertEquals(
690
            'SELECT t0."id" AS c0 FROM "cms_users" t0 WHERE EXISTS (SELECT 1 FROM "cms_phonenumbers" t1 WHERE t0."id" = t1."user_id" AND t1."phonenumber" = ?)',
691
            $q->getSql()
692
        );
693
    }
694
695
    public function testSupportsMemberOfExpressionManyToMany()
696
    {
697
        // "Get all users who are members of $group."
698
        $q = $this->em->createQuery('SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE :param MEMBER OF u.groups');
699
700
        $q->setHint(ORMQuery::HINT_FORCE_PARTIAL_LOAD, true);
701
702
        $group = new CmsGroup();
703
        $group->id = 101;
704
        $q->setParameter('param', $group);
705
706
        self::assertEquals(
707
            'SELECT t0."id" AS c0 FROM "cms_users" t0 WHERE EXISTS (SELECT 1 FROM "cms_users_groups" t1 INNER JOIN "cms_groups" t2 ON t1."group_id" = t2."id" WHERE t1."user_id" = t0."id" AND t2."id" = ?)',
708
            $q->getSql()
709
        );
710
    }
711
712
    public function testSupportsMemberOfExpressionManyToManyParameterArray()
713
    {
714
        $q = $this->em->createQuery('SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE :param MEMBER OF u.groups');
715
        $q->setHint(ORMQuery::HINT_FORCE_PARTIAL_LOAD, true);
716
717
        $group = new CmsGroup();
718
        $group->id = 101;
719
        $group2 = new CmsGroup();
720
        $group2->id = 105;
721
        $q->setParameter('param', [$group, $group2]);
722
723
        self::assertEquals(
724
            'SELECT t0."id" AS c0 FROM "cms_users" t0 WHERE EXISTS (SELECT 1 FROM "cms_users_groups" t1 INNER JOIN "cms_groups" t2 ON t1."group_id" = t2."id" WHERE t1."user_id" = t0."id" AND t2."id" = ?)',
725
            $q->getSql()
726
        );
727
    }
728
729
    public function testSupportsMemberOfExpressionSelfReferencing()
730
    {
731
        // "Get all persons who have $person as a friend."
732
        // Tough one: Many-many self-referencing ("friends") with class table inheritance
733
        $q = $this->em->createQuery('SELECT p FROM Doctrine\Tests\Models\Company\CompanyPerson p WHERE :param MEMBER OF p.friends');
734
735
        $person = new CompanyPerson();
736
737
        $unitOfWork = $this->em->getUnitOfWork();
738
        $persister  = $unitOfWork->getEntityPersister(get_class($person));
739
740
        $persister->setIdentifier($person, ['id' => 101]);
741
742
        $q->setParameter('param', $person);
743
744
        self::assertEquals(
745
            'SELECT t0."id" AS c0, t0."name" AS c1, t1."title" AS c2, t2."salary" AS c3, t2."department" AS c4, t2."startDate" AS c5, t0."discr" AS c6, t0."spouse_id" AS c7, t1."car_id" AS c8 FROM "company_persons" t0 LEFT JOIN "company_managers" t1 ON t0."id" = t1."id" LEFT JOIN "company_employees" t2 ON t0."id" = t2."id" WHERE EXISTS (SELECT 1 FROM "company_persons_friends" t3 INNER JOIN "company_persons" t4 ON t3."friend_id" = t4."id" WHERE t3."person_id" = t0."id" AND t4."id" = ?)',
746
            $q->getSql()
747
        );
748
    }
749
750
    public function testSupportsMemberOfWithSingleValuedAssociation()
751
    {
752
        // Impossible example, but it illustrates the purpose
753
        $this->assertSqlGeneration(
754
            'SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.email MEMBER OF u.groups',
755
            'SELECT t0."id" AS c0 FROM "cms_users" t0 WHERE EXISTS (SELECT 1 FROM "cms_users_groups" t1 INNER JOIN "cms_groups" t2 ON t1."group_id" = t2."id" WHERE t1."user_id" = t0."id" AND t2."id" = t0."email_id")'
756
        );
757
    }
758
759
    public function testSupportsMemberOfWithIdentificationVariable()
760
    {
761
        // Impossible example, but it illustrates the purpose
762
        $this->assertSqlGeneration(
763
            'SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u MEMBER OF u.groups',
764
            'SELECT t0."id" AS c0 FROM "cms_users" t0 WHERE EXISTS (SELECT 1 FROM "cms_users_groups" t1 INNER JOIN "cms_groups" t2 ON t1."group_id" = t2."id" WHERE t1."user_id" = t0."id" AND t2."id" = t0."id")'
765
        );
766
    }
767
768
    public function testSupportsCurrentDateFunction()
769
    {
770
        $this->assertSqlGeneration(
771
            'SELECT d.id FROM Doctrine\Tests\Models\Generic\DateTimeModel d WHERE d.datetime > current_date()',
772
            'SELECT t0."id" AS c0 FROM "date_time_model" t0 WHERE t0."col_datetime" > CURRENT_DATE',
773
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => true]
774
        );
775
    }
776
777
    public function testSupportsCurrentTimeFunction()
778
    {
779
        $this->assertSqlGeneration(
780
            'SELECT d.id FROM Doctrine\Tests\Models\Generic\DateTimeModel d WHERE d.time > current_time()',
781
            'SELECT t0."id" AS c0 FROM "date_time_model" t0 WHERE t0."col_time" > CURRENT_TIME',
782
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => true]
783
        );
784
    }
785
786
    public function testSupportsCurrentTimestampFunction()
787
    {
788
        $this->assertSqlGeneration(
789
            'SELECT d.id FROM Doctrine\Tests\Models\Generic\DateTimeModel d WHERE d.datetime > current_timestamp()',
790
            'SELECT t0."id" AS c0 FROM "date_time_model" t0 WHERE t0."col_datetime" > CURRENT_TIMESTAMP',
791
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => true]
792
        );
793
    }
794
795
    public function testExistsExpressionInWhereCorrelatedSubqueryAssocCondition()
796
    {
797
        $this->assertSqlGeneration(
798
            // DQL
799
            // The result of this query consists of all employees whose spouses are also employees.
800
            'SELECT DISTINCT emp FROM Doctrine\Tests\Models\CMS\CmsEmployee emp
801
                WHERE EXISTS (
802
                    SELECT spouseEmp
803
                    FROM Doctrine\Tests\Models\CMS\CmsEmployee spouseEmp
804
                    WHERE spouseEmp = emp.spouse)',
805
            // SQL
806
            'SELECT DISTINCT t0."id" AS c0, t0."name" AS c1 FROM "cms_employees" t0'
807
                . ' WHERE EXISTS ('
808
                    . 'SELECT t1."id" FROM "cms_employees" t1 WHERE t1."id" = t0."spouse_id"'
809
                    . ')'
810
        );
811
    }
812
813
    public function testExistsExpressionWithSimpleSelectReturningScalar()
814
    {
815
        $this->assertSqlGeneration(
816
            // DQL
817
            // The result of this query consists of all employees whose spouses are also employees.
818
            'SELECT DISTINCT emp FROM Doctrine\Tests\Models\CMS\CmsEmployee emp
819
                WHERE EXISTS (
820
                    SELECT 1
821
                    FROM Doctrine\Tests\Models\CMS\CmsEmployee spouseEmp
822
                    WHERE spouseEmp = emp.spouse)',
823
            // SQL
824
            'SELECT DISTINCT t0."id" AS c0, t0."name" AS c1 FROM "cms_employees" t0'
825
                . ' WHERE EXISTS ('
826
                    . 'SELECT 1 AS c2 FROM "cms_employees" t1 WHERE t1."id" = t0."spouse_id"'
827
                    . ')'
828
        );
829
    }
830
831
    public function testLimitFromQueryClass()
832
    {
833
        $q = $this->em
834
            ->createQuery('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u')
835
            ->setMaxResults(10);
836
837
        self::assertEquals(
838
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3, t0."email_id" AS c4 FROM "cms_users" t0 LIMIT 10',
839
            $q->getSql()
840
        );
841
    }
842
843
    public function testLimitAndOffsetFromQueryClass()
844
    {
845
        $q = $this->em
846
            ->createQuery('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u')
847
            ->setMaxResults(10)
848
            ->setFirstResult(0);
849
850
        self::assertEquals(
851
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3, t0."email_id" AS c4 FROM "cms_users" t0 LIMIT 10 OFFSET 0',
852
            $q->getSql()
853
        );
854
    }
855
856
    public function testSizeFunction()
857
    {
858
        $this->assertSqlGeneration(
859
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE SIZE(u.phonenumbers) > 1',
860
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE (SELECT COUNT(*) FROM "cms_phonenumbers" t1 WHERE t1."user_id" = t0."id") > 1'
861
        );
862
    }
863
864
    public function testSizeFunctionSupportsManyToMany()
865
    {
866
        $this->assertSqlGeneration(
867
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE SIZE(u.groups) > 1',
868
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE (SELECT COUNT(*) FROM "cms_users_groups" t1 WHERE t1."user_id" = t0."id") > 1'
869
        );
870
    }
871
872
    public function testEmptyCollectionComparisonExpression()
873
    {
874
        $this->assertSqlGeneration(
875
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.phonenumbers IS EMPTY',
876
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE (SELECT COUNT(*) FROM "cms_phonenumbers" t1 WHERE t1."user_id" = t0."id") = 0'
877
        );
878
        $this->assertSqlGeneration(
879
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.phonenumbers IS NOT EMPTY',
880
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE (SELECT COUNT(*) FROM "cms_phonenumbers" t1 WHERE t1."user_id" = t0."id") > 0'
881
        );
882
    }
883
884
    public function testNestedExpressions()
885
    {
886
        $this->assertSqlGeneration(
887
            'select u from Doctrine\Tests\Models\CMS\CmsUser u where u.id > 10 and u.id < 42 and ((u.id * 2) > 5)',
888
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE t0."id" > 10 AND t0."id" < 42 AND ((t0."id" * 2) > 5)'
889
        );
890
    }
891
892
    public function testNestedExpressions2()
893
    {
894
        $this->assertSqlGeneration(
895
            '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',
896
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE (t0."id" > 10) AND (t0."id" < 42 AND ((t0."id" * 2) > 5)) OR t0."id" <> 42'
897
        );
898
    }
899
900
    public function testNestedExpressions3()
901
    {
902
        $this->assertSqlGeneration(
903
            '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))',
904
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE (t0."id" > 10) AND (t0."id" BETWEEN 1 AND 10 OR t0."id" IN (1, 2, 3, 4, 5))'
905
        );
906
    }
907
908
    public function testOrderByCollectionAssociationSize()
909
    {
910
        $this->assertSqlGeneration(
911
            'select u, size(u.articles) as numArticles from Doctrine\Tests\Models\CMS\CmsUser u order by numArticles',
912
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3, (SELECT COUNT(*) FROM "cms_articles" t1 WHERE t1."user_id" = t0."id") AS c4 FROM "cms_users" t0 ORDER BY c4 ASC'
913
        );
914
    }
915
916
    public function testOrderBySupportsSingleValuedPathExpressionOwningSide()
917
    {
918
        $this->assertSqlGeneration(
919
            'select a from Doctrine\Tests\Models\CMS\CmsArticle a order by a.user',
920
            'SELECT t0."id" AS c0, t0."topic" AS c1, t0."text" AS c2, t0."version" AS c3 FROM "cms_articles" t0 ORDER BY t0."user_id" ASC'
921
        );
922
    }
923
924
    /**
925
     * @expectedException \Doctrine\ORM\Query\QueryException
926
     */
927
    public function testOrderBySupportsSingleValuedPathExpressionInverseSide()
928
    {
929
        $q = $this->em->createQuery('select u from Doctrine\Tests\Models\CMS\CmsUser u order by u.address');
930
931
        $q->getSQL();
932
    }
933
934
    public function testBooleanLiteralInWhereOnSqlite()
935
    {
936
        $this->em->getConnection()->setDatabasePlatform(new SqlitePlatform());
937
938
        $this->assertSqlGeneration(
939
            'SELECT b FROM Doctrine\Tests\Models\Generic\BooleanModel b WHERE b.booleanField = true',
940
            'SELECT t0."id" AS c0, t0."booleanField" AS c1 FROM "boolean_model" t0 WHERE t0."booleanField" = 1'
941
        );
942
943
        $this->assertSqlGeneration(
944
            'SELECT b FROM Doctrine\Tests\Models\Generic\BooleanModel b WHERE b.booleanField = false',
945
            'SELECT t0."id" AS c0, t0."booleanField" AS c1 FROM "boolean_model" t0 WHERE t0."booleanField" = 0'
946
        );
947
    }
948
949
    public function testBooleanLiteralInWhereOnPostgres()
950
    {
951
        $this->em->getConnection()->setDatabasePlatform(new PostgreSqlPlatform());
952
953
        $this->assertSqlGeneration(
954
            'SELECT b FROM Doctrine\Tests\Models\Generic\BooleanModel b WHERE b.booleanField = true',
955
            'SELECT t0."id" AS c0, t0."booleanField" AS c1 FROM "boolean_model" t0 WHERE t0."booleanField" = true'
956
        );
957
958
        $this->assertSqlGeneration(
959
            'SELECT b FROM Doctrine\Tests\Models\Generic\BooleanModel b WHERE b.booleanField = false',
960
            'SELECT t0."id" AS c0, t0."booleanField" AS c1 FROM "boolean_model" t0 WHERE t0."booleanField" = false'
961
        );
962
    }
963
964
    public function testSingleValuedAssociationFieldInWhere()
965
    {
966
        $this->assertSqlGeneration(
967
            'SELECT p FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE p.user = ?1',
968
            'SELECT t0."phonenumber" AS c0 FROM "cms_phonenumbers" t0 WHERE t0."user_id" = ?'
969
        );
970
    }
971
972
    public function testSingleValuedAssociationNullCheckOnOwningSide()
973
    {
974
        $this->assertSqlGeneration(
975
            'SELECT a FROM Doctrine\Tests\Models\CMS\CmsAddress a WHERE a.user IS NULL',
976
            'SELECT t0."id" AS c0, t0."country" AS c1, t0."zip" AS c2, t0."city" AS c3 FROM "cms_addresses" t0 WHERE t0."user_id" IS NULL'
977
        );
978
    }
979
980
    // Null check on inverse side has to happen through explicit JOIN.
981
    // 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.address IS NULL'
982
    // where the CmsUser is the inverse side is not supported.
983
    public function testSingleValuedAssociationNullCheckOnInverseSide()
984
    {
985
        $this->assertSqlGeneration(
986
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.address a WHERE a.id IS NULL',
987
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 LEFT JOIN "cms_addresses" t1 ON t0."id" = t1."user_id" WHERE t1."id" IS NULL'
988
        );
989
    }
990
991
    /**
992
     * @group DDC-339
993
     * @group DDC-1572
994
     */
995
    public function testStringFunctionLikeExpression()
996
    {
997
        $this->assertSqlGeneration(
998
            'SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE LOWER(u.name) LIKE \'%foo OR bar%\'',
999
            'SELECT t0."name" AS c0 FROM "cms_users" t0 WHERE LOWER(t0."name") LIKE \'%foo OR bar%\''
1000
        );
1001
        $this->assertSqlGeneration(
1002
            'SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE LOWER(u.name) LIKE :str',
1003
            'SELECT t0."name" AS c0 FROM "cms_users" t0 WHERE LOWER(t0."name") LIKE ?'
1004
        );
1005
        $this->assertSqlGeneration(
1006
            'SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE CONCAT(UPPER(u.name), \'_moo\') LIKE :str',
1007
            'SELECT t0."name" AS c0 FROM "cms_users" t0 WHERE UPPER(t0."name") || \'_moo\' LIKE ?'
1008
        );
1009
1010
        // DDC-1572
1011
        $this->assertSqlGeneration(
1012
            'SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE UPPER(u.name) LIKE UPPER(:str)',
1013
            'SELECT t0."name" AS c0 FROM "cms_users" t0 WHERE UPPER(t0."name") LIKE UPPER(?)'
1014
        );
1015
        $this->assertSqlGeneration(
1016
            'SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE UPPER(LOWER(u.name)) LIKE UPPER(LOWER(:str))',
1017
            'SELECT t0."name" AS c0 FROM "cms_users" t0 WHERE UPPER(LOWER(t0."name")) LIKE UPPER(LOWER(?))'
1018
        );
1019
        $this->assertSqlGeneration(
1020
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a WITH a.topic LIKE u.name',
1021
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 LEFT JOIN "cms_articles" t1 ON t0."id" = t1."user_id" AND (t1."topic" LIKE t0."name")'
1022
        );
1023
    }
1024
1025
    /**
1026
     * @group DDC-1802
1027
     */
1028
    public function testStringFunctionNotLikeExpression()
1029
    {
1030
        $this->assertSqlGeneration(
1031
                'SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE LOWER(u.name) NOT LIKE \'%foo OR bar%\'',
1032
                'SELECT t0."name" AS c0 FROM "cms_users" t0 WHERE LOWER(t0."name") NOT LIKE \'%foo OR bar%\''
1033
        );
1034
1035
        $this->assertSqlGeneration(
1036
                'SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE UPPER(LOWER(u.name)) NOT LIKE UPPER(LOWER(:str))',
1037
                'SELECT t0."name" AS c0 FROM "cms_users" t0 WHERE UPPER(LOWER(t0."name")) NOT LIKE UPPER(LOWER(?))'
1038
        );
1039
        $this->assertSqlGeneration(
1040
                'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a WITH a.topic NOT LIKE u.name',
1041
                'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 LEFT JOIN "cms_articles" t1 ON t0."id" = t1."user_id" AND (t1."topic" NOT LIKE t0."name")'
1042
        );
1043
    }
1044
1045
    /**
1046
     * @group DDC-338
1047
     */
1048
    public function testOrderedCollectionFetchJoined()
1049
    {
1050
        $this->assertSqlGeneration(
1051
            'SELECT r, l FROM Doctrine\Tests\Models\Routing\RoutingRoute r JOIN r.legs l',
1052
            'SELECT t0."id" AS c0, t1."id" AS c1, t1."departureDate" AS c2, t1."arrivalDate" AS c3 FROM "RoutingRoute" t0 INNER JOIN "RoutingRouteLegs" t2 ON t0."id" = t2."route_id" INNER JOIN "RoutingLeg" t1 ON t1."id" = t2."leg_id" ORDER BY t1."departureDate" ASC'
1053
        );
1054
    }
1055
1056
    public function testSubselectInSelect()
1057
    {
1058
        $this->assertSqlGeneration(
1059
            '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\'',
1060
            'SELECT t0."name" AS c0, (SELECT COUNT(t1."phonenumber") AS c2 FROM "cms_phonenumbers" t1 WHERE t1."phonenumber" = 1234) AS c1 FROM "cms_users" t0 WHERE t0."name" = \'jon\''
1061
        );
1062
    }
1063
1064
    /**
1065
     * @group locking
1066
     * @group DDC-178
1067
     */
1068
    public function testPessimisticWriteLockQueryHint()
1069
    {
1070
        if ($this->em->getConnection()->getDatabasePlatform() instanceof SqlitePlatform) {
1071
            $this->markTestSkipped('SqLite does not support Row locking at all.');
1072
        }
1073
1074
        $this->assertSqlGeneration(
1075
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.username = \'gblanco\'',
1076
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE t0."username" = \'gblanco\' FOR UPDATE',
1077
            [ORMQuery::HINT_LOCK_MODE => LockMode::PESSIMISTIC_WRITE]
1078
        );
1079
    }
1080
1081
    /**
1082
     * @group locking
1083
     * @group DDC-178
1084
     */
1085
    public function testPessimisticReadLockQueryHintPostgreSql()
1086
    {
1087
        $this->em->getConnection()->setDatabasePlatform(new PostgreSqlPlatform());
1088
1089
        $this->assertSqlGeneration(
1090
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.username = \'gblanco\'',
1091
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE t0."username" = \'gblanco\' FOR SHARE',
1092
            [ORMQuery::HINT_LOCK_MODE => LockMode::PESSIMISTIC_READ]
1093
        );
1094
    }
1095
1096
    /**
1097
     * @group DDC-1693
1098
     * @group locking
1099
     */
1100
    public function testLockModeNoneQueryHint()
1101
    {
1102
        $this->assertSqlGeneration(
1103
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.username = \'gblanco\'',
1104
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE t0."username" = \'gblanco\'',
1105
            [ORMQuery::HINT_LOCK_MODE => LockMode::NONE]
1106
        );
1107
    }
1108
1109
    /**
1110
     * @group DDC-430
1111
     */
1112
    public function testSupportSelectWithMoreThan10InputParameters()
1113
    {
1114
        $this->assertSqlGeneration(
1115
            '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',
1116
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE t0."id" = ? OR t0."id" = ? OR t0."id" = ? OR t0."id" = ? OR t0."id" = ? OR t0."id" = ? OR t0."id" = ? OR t0."id" = ? OR t0."id" = ? OR t0."id" = ? OR t0."id" = ?'
1117
        );
1118
    }
1119
1120
    /**
1121
     * @group locking
1122
     * @group DDC-178
1123
     */
1124
    public function testPessimisticReadLockQueryHintMySql()
1125
    {
1126
        $this->em->getConnection()->setDatabasePlatform(new MySqlPlatform());
1127
1128
        $this->assertSqlGeneration(
1129
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.username = \'gblanco\'',
1130
            'SELECT t0.`id` AS c0, t0.`status` AS c1, t0.`username` AS c2, t0.`name` AS c3 FROM `cms_users` t0 WHERE t0.`username` = \'gblanco\' LOCK IN SHARE MODE',
1131
            [ORMQuery::HINT_LOCK_MODE => LockMode::PESSIMISTIC_READ]
1132
        );
1133
    }
1134
1135
    /**
1136
     * @group locking
1137
     * @group DDC-178
1138
     */
1139
    public function testPessimisticReadLockQueryHintOracle()
1140
    {
1141
        $this->em->getConnection()->setDatabasePlatform(new OraclePlatform());
1142
1143
        $this->assertSqlGeneration(
1144
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.username = \'gblanco\'',
1145
            'SELECT t0."id" AS C0, t0."status" AS C1, t0."username" AS C2, t0."name" AS C3 FROM "cms_users" t0 WHERE t0."username" = \'gblanco\' FOR UPDATE',
1146
            [ORMQuery::HINT_LOCK_MODE => LockMode::PESSIMISTIC_READ]
1147
        );
1148
    }
1149
1150
    /**
1151
     * @group DDC-431
1152
     */
1153
    public function testSupportToCustomDQLFunctions()
1154
    {
1155
        $config = $this->em->getConfiguration();
1156
        $config->addCustomNumericFunction('MYABS', MyAbsFunction::class);
1157
1158
        $this->assertSqlGeneration(
1159
            'SELECT MYABS(p.phonenumber) FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p',
1160
            'SELECT ABS(t0."phonenumber") AS c0 FROM "cms_phonenumbers" t0'
1161
        );
1162
1163
        $config->setCustomNumericFunctions([]);
1164
    }
1165
1166
    /**
1167
     * @group DDC-826
1168
     */
1169
    public function testMappedSuperclassAssociationJoin()
1170
    {
1171
        $this->assertSqlGeneration(
1172
            'SELECT f FROM Doctrine\Tests\Models\DirectoryTree\File f JOIN f.parentDirectory d WHERE f.id = ?1',
1173
            'SELECT t0."id" AS c0, t0."name" AS c1, t0."extension" AS c2 FROM "file" t0 INNER JOIN "Directory" t1 ON t0."parentDirectory_id" = t1."id" WHERE t0."id" = ?'
1174
        );
1175
    }
1176
1177
    /**
1178
     * @group DDC-1053
1179
     */
1180
    public function testGroupBy()
1181
    {
1182
        $this->assertSqlGeneration(
1183
            'SELECT g.id, count(u.id) FROM Doctrine\Tests\Models\CMS\CmsGroup g JOIN g.users u GROUP BY g.id',
1184
            'SELECT t0."id" AS c0, count(t1."id") AS c1 FROM "cms_groups" t0 INNER JOIN "cms_users_groups" t2 ON t0."id" = t2."group_id" INNER JOIN "cms_users" t1 ON t1."id" = t2."user_id" GROUP BY t0."id"'
1185
        );
1186
    }
1187
1188
    /**
1189
     * @group DDC-1053
1190
     */
1191
    public function testGroupByIdentificationVariable()
1192
    {
1193
        $this->assertSqlGeneration(
1194
            'SELECT g, count(u.id) FROM Doctrine\Tests\Models\CMS\CmsGroup g JOIN g.users u GROUP BY g',
1195
            'SELECT t0."id" AS c0, t0."name" AS c1, count(t1."id") AS c2 FROM "cms_groups" t0 INNER JOIN "cms_users_groups" t2 ON t0."id" = t2."group_id" INNER JOIN "cms_users" t1 ON t1."id" = t2."user_id" GROUP BY t0."id", t0."name"'
1196
        );
1197
    }
1198
1199
    public function testCaseContainingNullIf()
1200
    {
1201
        $this->assertSqlGeneration(
1202
            'SELECT NULLIF(g.id, g.name) AS NullIfEqual FROM Doctrine\Tests\Models\CMS\CmsGroup g',
1203
            'SELECT NULLIF(t0."id", t0."name") AS c0 FROM "cms_groups" t0'
1204
        );
1205
    }
1206
1207
    public function testCaseContainingCoalesce()
1208
    {
1209
        $this->assertSqlGeneration(
1210
            'SELECT COALESCE(NULLIF(u.name, \'\'), u.username) as Display FROM Doctrine\Tests\Models\CMS\CmsUser u',
1211
            'SELECT COALESCE(NULLIF(t0."name", \'\'), t0."username") AS c0 FROM "cms_users" t0'
1212
        );
1213
    }
1214
1215
    /**
1216
     * Test that the right discriminator data is inserted in a subquery.
1217
     */
1218
    public function testSubSelectDiscriminator()
1219
    {
1220
        $this->assertSqlGeneration(
1221
            'SELECT u.name, (SELECT COUNT(cfc.id) total FROM Doctrine\Tests\Models\Company\CompanyFixContract cfc) as cfc_count FROM Doctrine\Tests\Models\CMS\CmsUser u',
1222
            'SELECT t0."name" AS c0, (SELECT COUNT(t1."id") AS c2 FROM "company_contracts" t1 WHERE t1."discr" IN (\'fix\')) AS c1 FROM "cms_users" t0'
1223
        );
1224
    }
1225
1226
    public function testIdVariableResultVariableReuse()
1227
    {
1228
        $exceptionThrown = false;
1229
1230
        try {
1231
            $query = $this->em->createQuery('SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name IN (SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u)');
1232
1233
            $query->getSql();
1234
            $query->free();
1235
        } catch (\Exception $e) {
1236
            $exceptionThrown = true;
1237
        }
1238
1239
        self::assertTrue($exceptionThrown);
1240
    }
1241
1242
    public function testSubSelectAliasesFromOuterQuery()
1243
    {
1244
        $this->assertSqlGeneration(
1245
            'SELECT uo, (SELECT ui.name FROM Doctrine\Tests\Models\CMS\CmsUser ui WHERE ui.id = uo.id) AS bar FROM Doctrine\Tests\Models\CMS\CmsUser uo',
1246
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3, (SELECT t1."name" FROM "cms_users" t1 WHERE t1."id" = t0."id") AS c4 FROM "cms_users" t0'
1247
        );
1248
    }
1249
1250
    public function testSubSelectAliasesFromOuterQueryWithSubquery()
1251
    {
1252
        $this->assertSqlGeneration(
1253
            'SELECT uo, (SELECT ui.name FROM Doctrine\Tests\Models\CMS\CmsUser ui WHERE ui.id = uo.id AND ui.name IN (SELECT uii.name FROM Doctrine\Tests\Models\CMS\CmsUser uii)) AS bar FROM Doctrine\Tests\Models\CMS\CmsUser uo',
1254
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3, (SELECT t1."name" FROM "cms_users" t1 WHERE t1."id" = t0."id" AND t1."name" IN (SELECT t2."name" FROM "cms_users" t2)) AS c4 FROM "cms_users" t0'
1255
        );
1256
    }
1257
1258
    public function testSubSelectAliasesFromOuterQueryReuseInWhereClause()
1259
    {
1260
        $this->assertSqlGeneration(
1261
            'SELECT uo, (SELECT ui.name FROM Doctrine\Tests\Models\CMS\CmsUser ui WHERE ui.id = uo.id) AS bar FROM Doctrine\Tests\Models\CMS\CmsUser uo WHERE bar = ?0',
1262
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3, (SELECT t1."name" FROM "cms_users" t1 WHERE t1."id" = t0."id") AS c4 FROM "cms_users" t0 WHERE c4 = ?'
1263
        );
1264
    }
1265
1266
    /**
1267
     * @group DDC-1298
1268
     */
1269
    public function testSelectForeignKeyPKWithoutFields()
1270
    {
1271
        $this->assertSqlGeneration(
1272
            'SELECT t, s, l FROM Doctrine\Tests\Models\DDC117\DDC117Link l INNER JOIN l.target t INNER JOIN l.source s',
1273
            'SELECT t0."article_id" AS c0, t0."title" AS c1, t1."article_id" AS c2, t1."title" AS c3, t2."source_id" AS c4, t2."target_id" AS c5 FROM "DDC117Link" t2 INNER JOIN "DDC117Article" t0 ON t2."target_id" = t0."article_id" INNER JOIN "DDC117Article" t1 ON t2."source_id" = t1."article_id"'
1274
        );
1275
    }
1276
1277
    public function testGeneralCaseWithSingleWhenClause()
1278
    {
1279
        $this->assertSqlGeneration(
1280
            'SELECT g.id, CASE WHEN ((g.id / 2) > 18) THEN 1 ELSE 0 END AS test FROM Doctrine\Tests\Models\CMS\CmsGroup g',
1281
            'SELECT t0."id" AS c0, CASE WHEN ((t0."id" / 2) > 18) THEN 1 ELSE 0 END AS c1 FROM "cms_groups" t0'
1282
        );
1283
    }
1284
1285
    public function testGeneralCaseWithMultipleWhenClause()
1286
    {
1287
        $this->assertSqlGeneration(
1288
            'SELECT g.id, CASE WHEN (g.id / 2 < 10) THEN 2 WHEN ((g.id / 2) > 20) THEN 1 ELSE 0 END AS test FROM Doctrine\Tests\Models\CMS\CmsGroup g',
1289
            'SELECT t0."id" AS c0, CASE WHEN (t0."id" / 2 < 10) THEN 2 WHEN ((t0."id" / 2) > 20) THEN 1 ELSE 0 END AS c1 FROM "cms_groups" t0'
1290
        );
1291
    }
1292
1293
    public function testSimpleCaseWithSingleWhenClause()
1294
    {
1295
        $this->assertSqlGeneration(
1296
            'SELECT g FROM Doctrine\Tests\Models\CMS\CmsGroup g WHERE g.id = CASE g.name WHEN \'admin\' THEN 1 ELSE 2 END',
1297
            'SELECT t0."id" AS c0, t0."name" AS c1 FROM "cms_groups" t0 WHERE t0."id" = CASE t0."name" WHEN \'admin\' THEN 1 ELSE 2 END'
1298
        );
1299
    }
1300
1301
    public function testSimpleCaseWithMultipleWhenClause()
1302
    {
1303
        $this->assertSqlGeneration(
1304
            'SELECT g FROM Doctrine\Tests\Models\CMS\CmsGroup g WHERE g.id = (CASE g.name WHEN \'admin\' THEN 1 WHEN \'moderator\' THEN 2 ELSE 3 END)',
1305
            'SELECT t0."id" AS c0, t0."name" AS c1 FROM "cms_groups" t0 WHERE t0."id" = (CASE t0."name" WHEN \'admin\' THEN 1 WHEN \'moderator\' THEN 2 ELSE 3 END)'
1306
        );
1307
    }
1308
1309
    public function testGeneralCaseWithSingleWhenClauseInSubselect()
1310
    {
1311
        $this->assertSqlGeneration(
1312
            'SELECT g FROM Doctrine\Tests\Models\CMS\CmsGroup g WHERE g.id IN (SELECT CASE WHEN ((g2.id / 2) > 18) THEN 2 ELSE 1 END FROM Doctrine\Tests\Models\CMS\CmsGroup g2)',
1313
            'SELECT t0."id" AS c0, t0."name" AS c1 FROM "cms_groups" t0 WHERE t0."id" IN (SELECT CASE WHEN ((t1."id" / 2) > 18) THEN 2 ELSE 1 END AS c2 FROM "cms_groups" t1)'
1314
        );
1315
    }
1316
1317
    public function testGeneralCaseWithMultipleWhenClauseInSubselect()
1318
    {
1319
        $this->assertSqlGeneration(
1320
            'SELECT g FROM Doctrine\Tests\Models\CMS\CmsGroup g WHERE g.id IN (SELECT CASE WHEN (g.id / 2 < 10) THEN 3 WHEN ((g.id / 2) > 20) THEN 2 ELSE 1 END FROM Doctrine\Tests\Models\CMS\CmsGroup g2)',
1321
            'SELECT t0."id" AS c0, t0."name" AS c1 FROM "cms_groups" t0 WHERE t0."id" IN (SELECT CASE WHEN (t0."id" / 2 < 10) THEN 3 WHEN ((t0."id" / 2) > 20) THEN 2 ELSE 1 END AS c2 FROM "cms_groups" t1)'
1322
        );
1323
    }
1324
1325
    public function testSimpleCaseWithSingleWhenClauseInSubselect()
1326
    {
1327
        $this->assertSqlGeneration(
1328
            'SELECT g FROM Doctrine\Tests\Models\CMS\CmsGroup g WHERE g.id IN (SELECT CASE g2.name WHEN \'admin\' THEN 1 ELSE 2 END FROM Doctrine\Tests\Models\CMS\CmsGroup g2)',
1329
            'SELECT t0."id" AS c0, t0."name" AS c1 FROM "cms_groups" t0 WHERE t0."id" IN (SELECT CASE t1."name" WHEN \'admin\' THEN 1 ELSE 2 END AS c2 FROM "cms_groups" t1)'
1330
        );
1331
    }
1332
1333
    public function testSimpleCaseWithMultipleWhenClauseInSubselect()
1334
    {
1335
        $this->assertSqlGeneration(
1336
            'SELECT g FROM Doctrine\Tests\Models\CMS\CmsGroup g WHERE g.id IN (SELECT CASE g2.name WHEN \'admin\' THEN 1 WHEN \'moderator\' THEN 2 ELSE 3 END FROM Doctrine\Tests\Models\CMS\CmsGroup g2)',
1337
            'SELECT t0."id" AS c0, t0."name" AS c1 FROM "cms_groups" t0 WHERE t0."id" IN (SELECT CASE t1."name" WHEN \'admin\' THEN 1 WHEN \'moderator\' THEN 2 ELSE 3 END AS c2 FROM "cms_groups" t1)'
1338
        );
1339
    }
1340
1341
    /**
1342
     * @group DDC-1696
1343
     */
1344
    public function testSimpleCaseWithStringPrimary()
1345
    {
1346
        $this->assertSqlGeneration(
1347
            'SELECT g.id, CASE WHEN ((g.id / 2) > 18) THEN \'Foo\' ELSE \'Bar\' END AS test FROM Doctrine\Tests\Models\CMS\CmsGroup g',
1348
            'SELECT t0."id" AS c0, CASE WHEN ((t0."id" / 2) > 18) THEN \'Foo\' ELSE \'Bar\' END AS c1 FROM "cms_groups" t0'
1349
        );
1350
    }
1351
1352
    /**
1353
     * @group DDC-2205
1354
     */
1355
    public function testCaseNegativeValuesInThenExpression()
1356
    {
1357
        $this->assertSqlGeneration(
1358
            'SELECT CASE g.name WHEN \'admin\' THEN - 1 ELSE - 2 END FROM Doctrine\Tests\Models\CMS\CmsGroup g',
1359
            'SELECT CASE t0."name" WHEN \'admin\' THEN -1 ELSE -2 END AS c0 FROM "cms_groups" t0'
1360
        );
1361
1362
        $this->assertSqlGeneration(
1363
            'SELECT CASE g.name WHEN \'admin\' THEN  - 2 WHEN \'guest\' THEN - 1 ELSE 0 END FROM Doctrine\Tests\Models\CMS\CmsGroup g',
1364
            'SELECT CASE t0."name" WHEN \'admin\' THEN -2 WHEN \'guest\' THEN -1 ELSE 0 END AS c0 FROM "cms_groups" t0'
1365
        );
1366
1367
        $this->assertSqlGeneration(
1368
            'SELECT CASE g.name WHEN \'admin\' THEN (- 1) ELSE (- 2) END FROM Doctrine\Tests\Models\CMS\CmsGroup g',
1369
            'SELECT CASE t0."name" WHEN \'admin\' THEN (-1) ELSE (-2) END AS c0 FROM "cms_groups" t0'
1370
        );
1371
1372
        $this->assertSqlGeneration(
1373
            'SELECT CASE g.name WHEN \'admin\' THEN ( - :value) ELSE ( + :value) END FROM Doctrine\Tests\Models\CMS\CmsGroup g',
1374
            'SELECT CASE t0."name" WHEN \'admin\' THEN (-?) ELSE (+?) END AS c0 FROM "cms_groups" t0'
1375
        );
1376
1377
        $this->assertSqlGeneration(
1378
            'SELECT CASE g.name WHEN \'admin\' THEN ( - g.id) ELSE ( + g.id) END FROM Doctrine\Tests\Models\CMS\CmsGroup g',
1379
            'SELECT CASE t0."name" WHEN \'admin\' THEN (-t0."id") ELSE (+t0."id") END AS c0 FROM "cms_groups" t0'
1380
        );
1381
    }
1382
1383
    public function testIdentityFunctionWithCompositePrimaryKey()
1384
    {
1385
        $this->assertSqlGeneration(
1386
            'SELECT IDENTITY(p.poi, \'long\') AS long FROM Doctrine\Tests\Models\Navigation\NavPhotos p',
1387
            'SELECT t0."poi_long" AS c0 FROM "navigation_photos" t0'
1388
        );
1389
1390
        $this->assertSqlGeneration(
1391
            'SELECT IDENTITY(p.poi, \'lat\') AS lat FROM Doctrine\Tests\Models\Navigation\NavPhotos p',
1392
            'SELECT t0."poi_lat" AS c0 FROM "navigation_photos" t0'
1393
        );
1394
1395
        $this->assertSqlGeneration(
1396
            'SELECT IDENTITY(p.poi, \'long\') AS long, IDENTITY(p.poi, \'lat\') AS lat FROM Doctrine\Tests\Models\Navigation\NavPhotos p',
1397
            'SELECT t0."poi_long" AS c0, t0."poi_lat" AS c1 FROM "navigation_photos" t0'
1398
        );
1399
1400
        $this->assertInvalidSqlGeneration(
1401
            'SELECT IDENTITY(p.poi, \'invalid\') AS invalid FROM Doctrine\Tests\Models\Navigation\NavPhotos p',
1402
            QueryException::class
1403
        );
1404
    }
1405
1406
    /**
1407
     * @group DDC-2519
1408
     */
1409
    public function testPartialWithAssociationIdentifier()
1410
    {
1411
        $this->assertSqlGeneration(
1412
            'SELECT PARTIAL l.{source, target} FROM Doctrine\Tests\Models\Legacy\LegacyUserReference l',
1413
            'SELECT t0."iUserIdSource" AS c0, t0."iUserIdTarget" AS c1 FROM "legacy_users_reference" t0'
1414
        );
1415
1416
        $this->assertSqlGeneration(
1417
            'SELECT PARTIAL l.{description, source, target} FROM Doctrine\Tests\Models\Legacy\LegacyUserReference l',
1418
            'SELECT t0."description" AS c0, t0."iUserIdSource" AS c1, t0."iUserIdTarget" AS c2 FROM "legacy_users_reference" t0'
1419
        );
1420
    }
1421
1422
    /**
1423
     * @group DDC-1339
1424
     */
1425
    public function testIdentityFunctionInSelectClause()
1426
    {
1427
        $this->assertSqlGeneration(
1428
            'SELECT IDENTITY(u.email) as email_id FROM Doctrine\Tests\Models\CMS\CmsUser u',
1429
            'SELECT t0."email_id" AS c0 FROM "cms_users" t0'
1430
        );
1431
    }
1432
1433
    public function testIdentityFunctionInJoinedSubclass()
1434
    {
1435
        //relation is in the subclass (CompanyManager) we are querying
1436
        $this->assertSqlGeneration(
1437
            'SELECT m, IDENTITY(m.car) as car_id FROM Doctrine\Tests\Models\Company\CompanyManager m',
1438
            'SELECT t0."id" AS c0, t0."name" AS c1, t1."salary" AS c2, t1."department" AS c3, t1."startDate" AS c4, t2."title" AS c5, t2."car_id" AS c6, t0."discr" AS c7 FROM "company_managers" t2 INNER JOIN "company_employees" t1 ON t2."id" = t1."id" INNER JOIN "company_persons" t0 ON t2."id" = t0."id"'
1439
        );
1440
1441
        //relation is in the base class (CompanyPerson).
1442
        $this->assertSqlGeneration(
1443
            'SELECT m, IDENTITY(m.spouse) as spouse_id FROM Doctrine\Tests\Models\Company\CompanyManager m',
1444
            'SELECT t0."id" AS c0, t0."name" AS c1, t1."salary" AS c2, t1."department" AS c3, t1."startDate" AS c4, t2."title" AS c5, t0."spouse_id" AS c6, t0."discr" AS c7 FROM "company_managers" t2 INNER JOIN "company_employees" t1 ON t2."id" = t1."id" INNER JOIN "company_persons" t0 ON t2."id" = t0."id"'
1445
        );
1446
    }
1447
1448
    /**
1449
     * @group DDC-1339
1450
     */
1451
    public function testIdentityFunctionDoesNotAcceptStateField()
1452
    {
1453
        $this->assertInvalidSqlGeneration(
1454
            'SELECT IDENTITY(u.name) as name FROM Doctrine\Tests\Models\CMS\CmsUser u',
1455
            QueryException::class
1456
        );
1457
    }
1458
1459
    /**
1460
     * @group DDC-1389
1461
     */
1462
    public function testInheritanceTypeJoinInRootClassWithDisabledForcePartialLoad()
1463
    {
1464
        $this->assertSqlGeneration(
1465
            'SELECT p FROM Doctrine\Tests\Models\Company\CompanyPerson p',
1466
            'SELECT t0."id" AS c0, t0."name" AS c1, t1."title" AS c2, t2."salary" AS c3, t2."department" AS c4, t2."startDate" AS c5, t0."discr" AS c6, t0."spouse_id" AS c7, t1."car_id" AS c8 FROM "company_persons" t0 LEFT JOIN "company_managers" t1 ON t0."id" = t1."id" LEFT JOIN "company_employees" t2 ON t0."id" = t2."id"',
1467
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => false]
1468
        );
1469
    }
1470
1471
    /**
1472
     * @group DDC-1389
1473
     */
1474
    public function testInheritanceTypeJoinInRootClassWithEnabledForcePartialLoad()
1475
    {
1476
        $this->assertSqlGeneration(
1477
            'SELECT p FROM Doctrine\Tests\Models\Company\CompanyPerson p',
1478
            'SELECT t0."id" AS c0, t0."name" AS c1, t0."discr" AS c2 FROM "company_persons" t0',
1479
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => true]
1480
        );
1481
    }
1482
1483
    /**
1484
     * @group DDC-1389
1485
     */
1486
    public function testInheritanceTypeJoinInChildClassWithDisabledForcePartialLoad()
1487
    {
1488
        $this->assertSqlGeneration(
1489
            'SELECT e FROM Doctrine\Tests\Models\Company\CompanyEmployee e',
1490
            'SELECT t0."id" AS c0, t0."name" AS c1, t1."salary" AS c2, t1."department" AS c3, t1."startDate" AS c4, t2."title" AS c5, t0."discr" AS c6, t0."spouse_id" AS c7, t2."car_id" AS c8 FROM "company_employees" t1 INNER JOIN "company_persons" t0 ON t1."id" = t0."id" LEFT JOIN "company_managers" t2 ON t1."id" = t2."id"',
1491
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => false]
1492
        );
1493
    }
1494
1495
    /**
1496
     * @group DDC-1389
1497
     */
1498
    public function testInheritanceTypeJoinInChildClassWithEnabledForcePartialLoad()
1499
    {
1500
        $this->assertSqlGeneration(
1501
            'SELECT e FROM Doctrine\Tests\Models\Company\CompanyEmployee e',
1502
            'SELECT t0."id" AS c0, t0."name" AS c1, t1."salary" AS c2, t1."department" AS c3, t1."startDate" AS c4, t0."discr" AS c5 FROM "company_employees" t1 INNER JOIN "company_persons" t0 ON t1."id" = t0."id"',
1503
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => true]
1504
        );
1505
    }
1506
1507
    /**
1508
     * @group DDC-1389
1509
     */
1510
    public function testInheritanceTypeJoinInLeafClassWithDisabledForcePartialLoad()
1511
    {
1512
        $this->assertSqlGeneration(
1513
            'SELECT m FROM Doctrine\Tests\Models\Company\CompanyManager m',
1514
            'SELECT t0."id" AS c0, t0."name" AS c1, t1."salary" AS c2, t1."department" AS c3, t1."startDate" AS c4, t2."title" AS c5, t0."discr" AS c6, t0."spouse_id" AS c7, t2."car_id" AS c8 FROM "company_managers" t2 INNER JOIN "company_employees" t1 ON t2."id" = t1."id" INNER JOIN "company_persons" t0 ON t2."id" = t0."id"',
1515
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => false]
1516
        );
1517
    }
1518
1519
    /**
1520
     * @group DDC-1389
1521
     */
1522
    public function testInheritanceTypeJoinInLeafClassWithEnabledForcePartialLoad()
1523
    {
1524
        $this->assertSqlGeneration(
1525
            'SELECT m FROM Doctrine\Tests\Models\Company\CompanyManager m',
1526
            'SELECT t0."id" AS c0, t0."name" AS c1, t1."salary" AS c2, t1."department" AS c3, t1."startDate" AS c4, t2."title" AS c5, t0."discr" AS c6 FROM "company_managers" t2 INNER JOIN "company_employees" t1 ON t2."id" = t1."id" INNER JOIN "company_persons" t0 ON t2."id" = t0."id"',
1527
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => true]
1528
        );
1529
    }
1530
1531
    /**
1532
     * @group DDC-1389
1533
     */
1534
    public function testInheritanceTypeSingleTableInRootClassWithDisabledForcePartialLoad()
1535
    {
1536
        $this->assertSqlGeneration(
1537
            'SELECT c FROM Doctrine\Tests\Models\Company\CompanyContract c',
1538
            'SELECT t0."id" AS c0, t0."completed" AS c1, t0."fixPrice" AS c2, t0."hoursWorked" AS c3, t0."pricePerHour" AS c4, t0."maxPrice" AS c5, t0."discr" AS c6, t0."salesPerson_id" AS c7 FROM "company_contracts" t0 WHERE t0."discr" IN (\'fix\', \'flexible\', \'flexultra\')',
1539
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => false]
1540
        );
1541
    }
1542
1543
    /**
1544
     * @group DDC-1389
1545
     */
1546
    public function testInheritanceTypeSingleTableInRootClassWithEnabledForcePartialLoad()
1547
    {
1548
        $this->assertSqlGeneration(
1549
            'SELECT c FROM Doctrine\Tests\Models\Company\CompanyContract c',
1550
            'SELECT t0."id" AS c0, t0."completed" AS c1, t0."fixPrice" AS c2, t0."hoursWorked" AS c3, t0."pricePerHour" AS c4, t0."maxPrice" AS c5, t0."discr" AS c6 FROM "company_contracts" t0 WHERE t0."discr" IN (\'fix\', \'flexible\', \'flexultra\')',
1551
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => true]
1552
        );
1553
    }
1554
1555
    /**
1556
     * @group DDC-1389
1557
     */
1558
    public function testInheritanceTypeSingleTableInChildClassWithDisabledForcePartialLoad()
1559
    {
1560
        $this->assertSqlGeneration(
1561
            'SELECT fc FROM Doctrine\Tests\Models\Company\CompanyFlexContract fc',
1562
            'SELECT t0."id" AS c0, t0."completed" AS c1, t0."hoursWorked" AS c2, t0."pricePerHour" AS c3, t0."maxPrice" AS c4, t0."discr" AS c5, t0."salesPerson_id" AS c6 FROM "company_contracts" t0 WHERE t0."discr" IN (\'flexible\', \'flexultra\')',
1563
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => false]
1564
        );
1565
    }
1566
1567
    /**
1568
     * @group DDC-1389
1569
     */
1570
    public function testInheritanceTypeSingleTableInChildClassWithEnabledForcePartialLoad()
1571
    {
1572
        $this->assertSqlGeneration(
1573
            'SELECT fc FROM Doctrine\Tests\Models\Company\CompanyFlexContract fc',
1574
            'SELECT t0."id" AS c0, t0."completed" AS c1, t0."hoursWorked" AS c2, t0."pricePerHour" AS c3, t0."maxPrice" AS c4, t0."discr" AS c5 FROM "company_contracts" t0 WHERE t0."discr" IN (\'flexible\', \'flexultra\')',
1575
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => true]
1576
        );
1577
    }
1578
1579
    /**
1580
     * @group DDC-1389
1581
     */
1582
    public function testInheritanceTypeSingleTableInLeafClassWithDisabledForcePartialLoad()
1583
    {
1584
        $this->assertSqlGeneration(
1585
            'SELECT fuc FROM Doctrine\Tests\Models\Company\CompanyFlexUltraContract fuc',
1586
            'SELECT t0."id" AS c0, t0."completed" AS c1, t0."hoursWorked" AS c2, t0."pricePerHour" AS c3, t0."maxPrice" AS c4, t0."discr" AS c5, t0."salesPerson_id" AS c6 FROM "company_contracts" t0 WHERE t0."discr" IN (\'flexultra\')',
1587
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => false]
1588
        );
1589
    }
1590
1591
    /**
1592
     * @group DDC-1389
1593
     */
1594
    public function testInheritanceTypeSingleTableInLeafClassWithEnabledForcePartialLoad()
1595
    {
1596
        $this->assertSqlGeneration(
1597
            'SELECT fuc FROM Doctrine\Tests\Models\Company\CompanyFlexUltraContract fuc',
1598
            'SELECT t0."id" AS c0, t0."completed" AS c1, t0."hoursWorked" AS c2, t0."pricePerHour" AS c3, t0."maxPrice" AS c4, t0."discr" AS c5 FROM "company_contracts" t0 WHERE t0."discr" IN (\'flexultra\')',
1599
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => true]
1600
        );
1601
    }
1602
1603
    /**
1604
     * @group DDC-1161
1605
     */
1606
    public function testSelfReferenceWithOneToOneDoesNotDuplicateAlias()
1607
    {
1608
        $this->assertSqlGeneration(
1609
            'SELECT p, pp FROM Doctrine\Tests\Models\Company\CompanyPerson p JOIN p.spouse pp',
1610
            'SELECT t0."id" AS c0, t0."name" AS c1, t1."title" AS c2, t2."salary" AS c3, t2."department" AS c4, t2."startDate" AS c5, t3."id" AS c6, t3."name" AS c7, t4."title" AS c8, t5."salary" AS c9, t5."department" AS c10, t5."startDate" AS c11, t0."discr" AS c12, t0."spouse_id" AS c13, t1."car_id" AS c14, t3."discr" AS c15, t3."spouse_id" AS c16, t4."car_id" AS c17 FROM "company_persons" t0 LEFT JOIN "company_managers" t1 ON t0."id" = t1."id" LEFT JOIN "company_employees" t2 ON t0."id" = t2."id" INNER JOIN "company_persons" t3 ON t0."spouse_id" = t3."id" LEFT JOIN "company_managers" t4 ON t3."id" = t4."id" LEFT JOIN "company_employees" t5 ON t3."id" = t5."id"',
1611
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => false]
1612
        );
1613
    }
1614
1615
    /**
1616
     * @group DDC-1384
1617
     */
1618
    public function testAliasDoesNotExceedPlatformDefinedLength()
1619
    {
1620
        $this->assertSqlGeneration(
1621
            'SELECT m FROM ' . __NAMESPACE__ .  '\\DDC1384Model m',
1622
            'SELECT t0."aVeryLongIdentifierThatShouldBeShortenedByTheSQLWalker_fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo" AS c0 FROM "DDC1384Model" t0'
1623
        );
1624
    }
1625
1626
    /**
1627
     * @group DDC-331
1628
     * @group DDC-1384
1629
     */
1630
    public function testIssue331()
1631
    {
1632
        $this->assertSqlGeneration(
1633
            'SELECT e.name FROM Doctrine\Tests\Models\Company\CompanyEmployee e',
1634
            'SELECT t0."name" AS c0 FROM "company_employees" t1 INNER JOIN "company_persons" t0 ON t1."id" = t0."id"'
1635
        );
1636
    }
1637
    /**
1638
     * @group DDC-1435
1639
     */
1640
    public function testForeignKeyAsPrimaryKeySubselect()
1641
    {
1642
        $this->assertSqlGeneration(
1643
            'SELECT s FROM Doctrine\Tests\Models\DDC117\DDC117Article s WHERE EXISTS (SELECT r FROM Doctrine\Tests\Models\DDC117\DDC117Reference r WHERE r.source = s)',
1644
            'SELECT t0."article_id" AS c0, t0."title" AS c1 FROM "DDC117Article" t0 WHERE EXISTS (SELECT t1."source_id", t1."target_id" FROM "DDC117Reference" t1 WHERE t1."source_id" = t0."article_id")'
1645
        );
1646
    }
1647
1648
    /**
1649
     * @group DDC-1474
1650
     */
1651
    public function testSelectWithArithmeticExpressionBeforeField()
1652
    {
1653
        $this->assertSqlGeneration(
1654
            'SELECT - e.value AS value, e.id FROM ' . __NAMESPACE__ . '\DDC1474Entity e',
1655
            'SELECT -t0."value" AS c0, t0."id" AS c1 FROM "DDC1474Entity" t0'
1656
        );
1657
1658
        $this->assertSqlGeneration(
1659
            'SELECT e.id, + e.value AS value FROM ' . __NAMESPACE__ . '\DDC1474Entity e',
1660
            'SELECT t0."id" AS c0, +t0."value" AS c1 FROM "DDC1474Entity" t0'
1661
        );
1662
    }
1663
1664
    /**
1665
     * @group DDC-1430
1666
     */
1667
    public function testGroupByAllFieldsWhenObjectHasForeignKeys()
1668
    {
1669
        $this->assertSqlGeneration(
1670
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u GROUP BY u',
1671
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 GROUP BY t0."id", t0."status", t0."username", t0."name", t0."email_id"'
1672
        );
1673
1674
        $this->assertSqlGeneration(
1675
            'SELECT e FROM Doctrine\Tests\Models\CMS\CmsEmployee e GROUP BY e',
1676
            'SELECT t0."id" AS c0, t0."name" AS c1 FROM "cms_employees" t0 GROUP BY t0."id", t0."name", t0."spouse_id"'
1677
        );
1678
    }
1679
1680
    /**
1681
     * @group DDC-1236
1682
     */
1683
    public function testGroupBySupportsResultVariable()
1684
    {
1685
        $this->assertSqlGeneration(
1686
            'SELECT u, u.status AS st FROM Doctrine\Tests\Models\CMS\CmsUser u GROUP BY st',
1687
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3, t0."status" AS c4 FROM "cms_users" t0 GROUP BY t0."status"'
1688
        );
1689
    }
1690
1691
    /**
1692
     * @group DDC-1236
1693
     */
1694
    public function testGroupBySupportsIdentificationVariable()
1695
    {
1696
        $this->assertSqlGeneration(
1697
            'SELECT u AS user FROM Doctrine\Tests\Models\CMS\CmsUser u GROUP BY user',
1698
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 GROUP BY c0, c1, c2, c3'
1699
        );
1700
    }
1701
1702
    /**
1703
     * @group DDC-1213
1704
     */
1705
    public function testSupportsBitComparison()
1706
    {
1707
        $this->assertSqlGeneration(
1708
            'SELECT BIT_OR(4,2), BIT_AND(4,2), u FROM Doctrine\Tests\Models\CMS\CmsUser u',
1709
            'SELECT (4 | 2) AS c0, (4 & 2) AS c1, t0."id" AS c2, t0."status" AS c3, t0."username" AS c4, t0."name" AS c5 FROM "cms_users" t0'
1710
        );
1711
        $this->assertSqlGeneration(
1712
            'SELECT BIT_OR(u.id,2), BIT_AND(u.id,2) FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE BIT_OR(u.id,2) > 0',
1713
            'SELECT (t0."id" | 2) AS c0, (t0."id" & 2) AS c1 FROM "cms_users" t0 WHERE (t0."id" | 2) > 0'
1714
        );
1715
        $this->assertSqlGeneration(
1716
            'SELECT BIT_OR(u.id,2), BIT_AND(u.id,2) FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE BIT_AND(u.id , 4) > 0',
1717
            'SELECT (t0."id" | 2) AS c0, (t0."id" & 2) AS c1 FROM "cms_users" t0 WHERE (t0."id" & 4) > 0'
1718
        );
1719
        $this->assertSqlGeneration(
1720
            'SELECT BIT_OR(u.id,2), BIT_AND(u.id,2) FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE BIT_OR(u.id , 2) > 0 OR BIT_AND(u.id , 4) > 0',
1721
            'SELECT (t0."id" | 2) AS c0, (t0."id" & 2) AS c1 FROM "cms_users" t0 WHERE (t0."id" | 2) > 0 OR (t0."id" & 4) > 0'
1722
        );
1723
    }
1724
1725
    /**
1726
     * @group DDC-1539
1727
     */
1728
    public function testParenthesesOnTheLeftHandOfComparison()
1729
    {
1730
        $this->assertSqlGeneration(
1731
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u where ( (u.id + u.id) * u.id ) > 100',
1732
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE ((t0."id" + t0."id") * t0."id") > 100'
1733
        );
1734
        $this->assertSqlGeneration(
1735
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u where (u.id + u.id) * u.id > 100',
1736
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE (t0."id" + t0."id") * t0."id" > 100'
1737
        );
1738
        $this->assertSqlGeneration(
1739
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u where 100 < (u.id + u.id) * u.id ',
1740
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE 100 < (t0."id" + t0."id") * t0."id"'
1741
        );
1742
    }
1743
1744
    public function testSupportsParenthesisExpressionInSubSelect()
1745
    {
1746
        $this->assertSqlGeneration(
1747
            'SELECT u.id, (SELECT (1000*SUM(subU.id)/SUM(subU.id)) FROM Doctrine\Tests\Models\CMS\CmsUser subU where subU.id = u.id) AS subSelect FROM Doctrine\Tests\Models\CMS\CmsUser u',
1748
            'SELECT t0."id" AS c0, (SELECT (1000 * SUM(t1."id") / SUM(t1."id")) FROM "cms_users" t1 WHERE t1."id" = t0."id") AS c1 FROM "cms_users" t0'
1749
        );
1750
    }
1751
1752
    /**
1753
     * @group DDC-1557
1754
     */
1755
    public function testSupportsSubSqlFunction()
1756
    {
1757
        $this->assertSqlGeneration(
1758
            'SELECT u1 FROM Doctrine\Tests\Models\CMS\CmsUser u1 WHERE u1.name IN ( SELECT TRIM(u2.name) FROM Doctrine\Tests\Models\CMS\CmsUser u2 )',
1759
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE t0."name" IN (SELECT TRIM(t1."name") AS c4 FROM "cms_users" t1)'
1760
        );
1761
        $this->assertSqlGeneration(
1762
            'SELECT u1 FROM Doctrine\Tests\Models\CMS\CmsUser u1 WHERE u1.name IN ( SELECT TRIM(u2.name) FROM Doctrine\Tests\Models\CMS\CmsUser u2  WHERE LOWER(u2.name) LIKE \'%fabio%\')',
1763
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE t0."name" IN (SELECT TRIM(t1."name") AS c4 FROM "cms_users" t1 WHERE LOWER(t1."name") LIKE \'%fabio%\')'
1764
        );
1765
        $this->assertSqlGeneration(
1766
            'SELECT u1 FROM Doctrine\Tests\Models\CMS\CmsUser u1 WHERE u1.email IN ( SELECT TRIM(IDENTITY(u2.email)) FROM Doctrine\Tests\Models\CMS\CmsUser u2 )',
1767
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE t0."email_id" IN (SELECT TRIM(t1."email_id") AS c4 FROM "cms_users" t1)'
1768
        );
1769
        $this->assertSqlGeneration(
1770
            'SELECT u1 FROM Doctrine\Tests\Models\CMS\CmsUser u1 WHERE u1.email IN ( SELECT IDENTITY(u2.email) FROM Doctrine\Tests\Models\CMS\CmsUser u2 )',
1771
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE t0."email_id" IN (SELECT t1."email_id" AS c4 FROM "cms_users" t1)'
1772
        );
1773
        $this->assertSqlGeneration(
1774
            'SELECT u1 FROM Doctrine\Tests\Models\CMS\CmsUser u1 WHERE COUNT(u1.id) = ( SELECT SUM(u2.id) FROM Doctrine\Tests\Models\CMS\CmsUser u2 )',
1775
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE COUNT(t0."id") = (SELECT SUM(t1."id") AS c4 FROM "cms_users" t1)'
1776
        );
1777
        $this->assertSqlGeneration(
1778
            'SELECT u1 FROM Doctrine\Tests\Models\CMS\CmsUser u1 WHERE COUNT(u1.id) <= ( SELECT SUM(u2.id) + COUNT(u2.email) FROM Doctrine\Tests\Models\CMS\CmsUser u2 )',
1779
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE COUNT(t0."id") <= (SELECT SUM(t1."id") + COUNT(t1."email_id") AS c4 FROM "cms_users" t1)'
1780
        );
1781
    }
1782
1783
    /**
1784
     * @group DDC-1574
1785
     */
1786
    public function testSupportsNewOperator()
1787
    {
1788
        $this->assertSqlGeneration(
1789
            'SELECT new Doctrine\Tests\Models\CMS\CmsUserDTO(u.name, e.email, a.city) FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.email e JOIN u.address a',
1790
            'SELECT t0."name" AS c0, t1."email" AS c1, t2."city" AS c2 FROM "cms_users" t0 INNER JOIN "cms_emails" t1 ON t0."email_id" = t1."id" INNER JOIN "cms_addresses" t2 ON t0."id" = t2."user_id"'
1791
        );
1792
1793
        $this->assertSqlGeneration(
1794
            'SELECT new Doctrine\Tests\Models\CMS\CmsUserDTO(u.name, e.email, a.id + u.id) FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.email e JOIN u.address a',
1795
            'SELECT t0."name" AS c0, t1."email" AS c1, t2."id" + t0."id" AS c2 FROM "cms_users" t0 INNER JOIN "cms_emails" t1 ON t0."email_id" = t1."id" INNER JOIN "cms_addresses" t2 ON t0."id" = t2."user_id"'
1796
        );
1797
1798
        $this->assertSqlGeneration(
1799
            'SELECT new Doctrine\Tests\Models\CMS\CmsUserDTO(u.name, e.email, a.city, COUNT(p)) FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.email e JOIN u.address a JOIN u.phonenumbers p',
1800
            'SELECT t0."name" AS c0, t1."email" AS c1, t2."city" AS c2, COUNT(t3."phonenumber") AS c3 FROM "cms_users" t0 INNER JOIN "cms_emails" t1 ON t0."email_id" = t1."id" INNER JOIN "cms_addresses" t2 ON t0."id" = t2."user_id" INNER JOIN "cms_phonenumbers" t3 ON t0."id" = t3."user_id"'
1801
        );
1802
1803
        $this->assertSqlGeneration(
1804
            'SELECT new Doctrine\Tests\Models\CMS\CmsUserDTO(u.name, e.email, a.city, COUNT(p) + u.id) FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.email e JOIN u.address a JOIN u.phonenumbers p',
1805
            'SELECT t0."name" AS c0, t1."email" AS c1, t2."city" AS c2, COUNT(t3."phonenumber") + t0."id" AS c3 FROM "cms_users" t0 INNER JOIN "cms_emails" t1 ON t0."email_id" = t1."id" INNER JOIN "cms_addresses" t2 ON t0."id" = t2."user_id" INNER JOIN "cms_phonenumbers" t3 ON t0."id" = t3."user_id"'
1806
        );
1807
1808
        $this->assertSqlGeneration(
1809
            'SELECT new Doctrine\Tests\Models\CMS\CmsUserDTO(a.id, a.country, a.city), new Doctrine\Tests\Models\CMS\CmsAddressDTO(u.name, e.email) FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.email e JOIN u.address a ORDER BY u.name',
1810
            'SELECT t0."id" AS c0, t0."country" AS c1, t0."city" AS c2, t1."name" AS c3, t2."email" AS c4 FROM "cms_users" t1 INNER JOIN "cms_emails" t2 ON t1."email_id" = t2."id" INNER JOIN "cms_addresses" t0 ON t1."id" = t0."user_id" ORDER BY t1."name" ASC'
1811
        );
1812
1813
        $this->assertSqlGeneration(
1814
            'SELECT new Doctrine\Tests\Models\CMS\CmsUserDTO(a.id, (SELECT 1 FROM Doctrine\Tests\Models\CMS\CmsUser su), a.country, a.city), new Doctrine\Tests\Models\CMS\CmsAddressDTO(u.name, e.email) FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.email e JOIN u.address a ORDER BY u.name',
1815
            'SELECT t0."id" AS c0, (SELECT 1 AS c2 FROM "cms_users" t1) AS c1, t0."country" AS c3, t0."city" AS c4, t2."name" AS c5, t3."email" AS c6 FROM "cms_users" t2 INNER JOIN "cms_emails" t3 ON t2."email_id" = t3."id" INNER JOIN "cms_addresses" t0 ON t2."id" = t0."user_id" ORDER BY t2."name" ASC'
1816
        );
1817
    }
1818
1819
    /**
1820
     * @group DDC-2234
1821
     */
1822
    public function testWhereFunctionIsNullComparisonExpression()
1823
    {
1824
        $this->assertSqlGeneration(
1825
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE IDENTITY(u.email) IS NULL',
1826
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE t0."email_id" IS NULL'
1827
        );
1828
1829
        $this->assertSqlGeneration(
1830
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE NULLIF(u.name, \'FabioBatSilva\') IS NULL AND IDENTITY(u.email) IS NOT NULL',
1831
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE NULLIF(t0."name", \'FabioBatSilva\') IS NULL AND t0."email_id" IS NOT NULL'
1832
        );
1833
1834
        $this->assertSqlGeneration(
1835
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE IDENTITY(u.email) IS NOT NULL',
1836
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE t0."email_id" IS NOT NULL'
1837
        );
1838
1839
        $this->assertSqlGeneration(
1840
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE NULLIF(u.name, \'FabioBatSilva\') IS NOT NULL',
1841
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE NULLIF(t0."name", \'FabioBatSilva\') IS NOT NULL'
1842
        );
1843
1844
        $this->assertSqlGeneration(
1845
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE COALESCE(u.name, u.id) IS NOT NULL',
1846
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE COALESCE(t0."name", t0."id") IS NOT NULL'
1847
        );
1848
1849
        $this->assertSqlGeneration(
1850
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE COALESCE(u.id, IDENTITY(u.email)) IS NOT NULL',
1851
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE COALESCE(t0."id", t0."email_id") IS NOT NULL'
1852
        );
1853
1854
        $this->assertSqlGeneration(
1855
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE COALESCE(IDENTITY(u.email), NULLIF(u.name, \'FabioBatSilva\')) IS NOT NULL',
1856
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 WHERE COALESCE(t0."email_id", NULLIF(t0."name", \'FabioBatSilva\')) IS NOT NULL'
1857
        );
1858
    }
1859
1860
    public function testCustomTypeValueSql()
1861
    {
1862
        if (DBALType::hasType('negative_to_positive')) {
1863
            DBALType::overrideType('negative_to_positive', NegativeToPositiveType::class);
1864
        } else {
1865
            DBALType::addType('negative_to_positive', NegativeToPositiveType::class);
1866
        }
1867
1868
        $this->assertSqlGeneration(
1869
            'SELECT p.customInteger FROM Doctrine\Tests\Models\CustomType\CustomTypeParent p WHERE p.id = 1',
1870
            'SELECT -(t0."customInteger") AS c0 FROM "customtype_parents" t0 WHERE t0."id" = 1'
1871
        );
1872
    }
1873
1874
    public function testCustomTypeValueSqlIgnoresIdentifierColumn()
1875
    {
1876
        if (DBALType::hasType('negative_to_positive')) {
1877
            DBALType::overrideType('negative_to_positive', NegativeToPositiveType::class);
1878
        } else {
1879
            DBALType::addType('negative_to_positive', NegativeToPositiveType::class);
1880
        }
1881
1882
        $this->assertSqlGeneration(
1883
            'SELECT p.id FROM Doctrine\Tests\Models\CustomType\CustomTypeParent p WHERE p.id = 1',
1884
            'SELECT t0."id" AS c0 FROM "customtype_parents" t0 WHERE t0."id" = 1'
1885
        );
1886
    }
1887
1888
    public function testCustomTypeValueSqlForAllFields()
1889
    {
1890
        if (DBALType::hasType('negative_to_positive')) {
1891
            DBALType::overrideType('negative_to_positive', NegativeToPositiveType::class);
1892
        } else {
1893
            DBALType::addType('negative_to_positive', NegativeToPositiveType::class);
1894
        }
1895
1896
        $this->assertSqlGeneration(
1897
            'SELECT p FROM Doctrine\Tests\Models\CustomType\CustomTypeParent p',
1898
            'SELECT t0."id" AS c0, -(t0."customInteger") AS c1 FROM "customtype_parents" t0'
1899
        );
1900
    }
1901
1902
    public function testCustomTypeValueSqlForPartialObject()
1903
    {
1904
        if (DBALType::hasType('negative_to_positive')) {
1905
            DBALType::overrideType('negative_to_positive', NegativeToPositiveType::class);
1906
        } else {
1907
            DBALType::addType('negative_to_positive', NegativeToPositiveType::class);
1908
        }
1909
1910
        $this->assertSqlGeneration(
1911
            'SELECT partial p.{id, customInteger} FROM Doctrine\Tests\Models\CustomType\CustomTypeParent p',
1912
            'SELECT t0."id" AS c0, -(t0."customInteger") AS c1 FROM "customtype_parents" t0'
1913
        );
1914
    }
1915
1916
    /**
1917
     * @group DDC-1529
1918
     */
1919
    public function testMultipleFromAndInheritanceCondition()
1920
    {
1921
        $this->assertSqlGeneration(
1922
            'SELECT fix, flex FROM Doctrine\Tests\Models\Company\CompanyFixContract fix, Doctrine\Tests\Models\Company\CompanyFlexContract flex',
1923
            'SELECT t0."id" AS c0, t0."completed" AS c1, t0."fixPrice" AS c2, t1."id" AS c3, t1."completed" AS c4, t1."hoursWorked" AS c5, t1."pricePerHour" AS c6, t1."maxPrice" AS c7, t0."discr" AS c8, t1."discr" AS c9 FROM "company_contracts" t0, "company_contracts" t1 WHERE (t0."discr" IN (\'fix\') AND t1."discr" IN (\'flexible\', \'flexultra\'))'
1924
        );
1925
    }
1926
1927
    /**
1928
     * @group DDC-775
1929
     */
1930
    public function testOrderByClauseSupportsSimpleArithmeticExpression()
1931
    {
1932
        $this->assertSqlGeneration(
1933
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u ORDER BY u.id + 1 ',
1934
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 ORDER BY t0."id" + 1 ASC'
1935
        );
1936
        $this->assertSqlGeneration(
1937
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u ORDER BY ( ( (u.id + 1) * (u.id - 1) ) / 2)',
1938
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 ORDER BY (((t0."id" + 1) * (t0."id" - 1)) / 2) ASC'
1939
        );
1940
        $this->assertSqlGeneration(
1941
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u ORDER BY ((u.id + 5000) * u.id + 3) ',
1942
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 ORDER BY ((t0."id" + 5000) * t0."id" + 3) ASC'
1943
        );
1944
    }
1945
1946
    public function testOrderByClauseSupportsFunction()
1947
    {
1948
        $this->assertSqlGeneration(
1949
            'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u ORDER BY CONCAT(u.username, u.name) ',
1950
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3 FROM "cms_users" t0 ORDER BY t0."username" || t0."name" ASC'
1951
        );
1952
    }
1953
1954
    /**
1955
     * @group DDC-1719
1956
     */
1957
    public function testStripNonAlphanumericCharactersFromAlias()
1958
    {
1959
        $this->assertSqlGeneration(
1960
            'SELECT e FROM Doctrine\Tests\Models\Generic\NonAlphaColumnsEntity e',
1961
            'SELECT t0."simple-entity-id" AS c0, t0."simple-entity-value" AS c1 FROM "not-a-simple-entity" t0'
1962
        );
1963
1964
        $this->assertSqlGeneration(
1965
            'SELECT e.value FROM Doctrine\Tests\Models\Generic\NonAlphaColumnsEntity e ORDER BY e.value',
1966
            'SELECT t0."simple-entity-value" AS c0 FROM "not-a-simple-entity" t0 ORDER BY t0."simple-entity-value" ASC'
1967
        );
1968
1969
        $this->assertSqlGeneration(
1970
            'SELECT TRIM(e.value) FROM Doctrine\Tests\Models\Generic\NonAlphaColumnsEntity e ORDER BY e.value',
1971
            'SELECT TRIM(t0."simple-entity-value") AS c0 FROM "not-a-simple-entity" t0 ORDER BY t0."simple-entity-value" ASC'
1972
        );
1973
    }
1974
1975
    /**
1976
     * @group DDC-2435
1977
     */
1978
    public function testColumnNameWithNumbersAndNonAlphanumericCharacters()
1979
    {
1980
        $this->assertSqlGeneration(
1981
            'SELECT e FROM Doctrine\Tests\Models\Quote\NumericEntity e',
1982
            'SELECT t0."1:1" AS c0, t0."2:2" AS c1 FROM "table" t0'
1983
        );
1984
1985
        $this->assertSqlGeneration(
1986
            'SELECT e.value FROM Doctrine\Tests\Models\Quote\NumericEntity e',
1987
            'SELECT t0."2:2" AS c0 FROM "table" t0'
1988
        );
1989
1990
        $this->assertSqlGeneration(
1991
            'SELECT TRIM(e.value) FROM Doctrine\Tests\Models\Quote\NumericEntity e',
1992
            'SELECT TRIM(t0."2:2") AS c0 FROM "table" t0'
1993
        );
1994
    }
1995
1996
    /**
1997
     * @group DDC-1845
1998
     */
1999
    public function testQuotedTableDeclaration()
2000
    {
2001
        $this->assertSqlGeneration(
2002
            'SELECT u FROM Doctrine\Tests\Models\Quote\User u',
2003
            'SELECT t0."user-id" AS c0, t0."user-name" AS c1 FROM "quote-user" t0'
2004
        );
2005
    }
2006
2007
    /**
2008
     * @group DDC-1845
2009
     */
2010
    public function testQuotedWalkJoinVariableDeclaration()
2011
    {
2012
        $this->assertSqlGeneration(
2013
            'SELECT u, a FROM Doctrine\Tests\Models\Quote\User u JOIN u.address a',
2014
            'SELECT t0."user-id" AS c0, t0."user-name" AS c1, t1."address-id" AS c2, t1."address-zip" AS c3, t1."type" AS c4 FROM "quote-user" t0 INNER JOIN "quote-address" t1 ON t0."address-id" = t1."address-id" AND t1."type" IN (\'simple\', \'full\')'
2015
        );
2016
2017
        $this->assertSqlGeneration(
2018
            'SELECT u, p FROM Doctrine\Tests\Models\Quote\User u JOIN u.phones p',
2019
            'SELECT t0."user-id" AS c0, t0."user-name" AS c1, t1."phone-number" AS c2 FROM "quote-user" t0 INNER JOIN "quote-phone" t1 ON t0."user-id" = t1."user-id"'
2020
        );
2021
2022
        $this->assertSqlGeneration(
2023
            'SELECT u, g FROM Doctrine\Tests\Models\Quote\User u JOIN u.groups g',
2024
            'SELECT t0."user-id" AS c0, t0."user-name" AS c1, t1."group-id" AS c2, t1."group-name" AS c3 FROM "quote-user" t0 INNER JOIN "quote-users-groups" t2 ON t0."user-id" = t2."user-id" INNER JOIN "quote-group" t1 ON t1."group-id" = t2."group-id"'
2025
        );
2026
2027
        $this->assertSqlGeneration(
2028
            'SELECT a, u FROM Doctrine\Tests\Models\Quote\Address a JOIN a.user u',
2029
            'SELECT t0."address-id" AS c0, t0."address-zip" AS c1, t1."user-id" AS c2, t1."user-name" AS c3, t0."type" AS c4 FROM "quote-address" t0 INNER JOIN "quote-user" t1 ON t0."user-id" = t1."user-id" WHERE t0."type" IN (\'simple\', \'full\')'
2030
        );
2031
2032
        $this->assertSqlGeneration(
2033
            'SELECT g, u FROM Doctrine\Tests\Models\Quote\Group g JOIN g.users u',
2034
            'SELECT t0."group-id" AS c0, t0."group-name" AS c1, t1."user-id" AS c2, t1."user-name" AS c3 FROM "quote-group" t0 INNER JOIN "quote-users-groups" t2 ON t0."group-id" = t2."group-id" INNER JOIN "quote-user" t1 ON t1."user-id" = t2."user-id"'
2035
        );
2036
2037
        $this->assertSqlGeneration(
2038
            'SELECT g, p FROM Doctrine\Tests\Models\Quote\Group g JOIN g.parent p',
2039
            'SELECT t0."group-id" AS c0, t0."group-name" AS c1, t1."group-id" AS c2, t1."group-name" AS c3 FROM "quote-group" t0 INNER JOIN "quote-group" t1 ON t0."parent-id" = t1."group-id"'
2040
        );
2041
    }
2042
2043
    /**
2044
     * @group DDC-2208
2045
     */
2046
    public function testCaseThenParameterArithmeticExpression()
2047
    {
2048
        $this->assertSqlGeneration(
2049
            'SELECT SUM(CASE WHEN e.salary <= :value THEN e.salary - :value WHEN e.salary >= :value THEN :value - e.salary ELSE 0 END) FROM Doctrine\Tests\Models\Company\CompanyEmployee e',
2050
            'SELECT SUM(CASE WHEN t0."salary" <= ? THEN t0."salary" - ? WHEN t0."salary" >= ? THEN ? - t0."salary" ELSE 0 END) AS c0 FROM "company_employees" t0 INNER JOIN "company_persons" t1 ON t0."id" = t1."id"'
2051
        );
2052
2053
        $this->assertSqlGeneration(
2054
            'SELECT SUM(CASE WHEN e.salary <= :value THEN e.salary - :value WHEN e.salary >= :value THEN :value - e.salary ELSE e.salary + 0 END) FROM Doctrine\Tests\Models\Company\CompanyEmployee e',
2055
            'SELECT SUM(CASE WHEN t0."salary" <= ? THEN t0."salary" - ? WHEN t0."salary" >= ? THEN ? - t0."salary" ELSE t0."salary" + 0 END) AS c0 FROM "company_employees" t0 INNER JOIN "company_persons" t1 ON t0."id" = t1."id"'
2056
        );
2057
2058
        $this->assertSqlGeneration(
2059
            'SELECT SUM(CASE WHEN e.salary <= :value THEN (e.salary - :value) WHEN e.salary >= :value THEN (:value - e.salary) ELSE (e.salary + :value) END) FROM Doctrine\Tests\Models\Company\CompanyEmployee e',
2060
            'SELECT SUM(CASE WHEN t0."salary" <= ? THEN (t0."salary" - ?) WHEN t0."salary" >= ? THEN (? - t0."salary") ELSE (t0."salary" + ?) END) AS c0 FROM "company_employees" t0 INNER JOIN "company_persons" t1 ON t0."id" = t1."id"'
2061
        );
2062
    }
2063
2064
    /**
2065
     * @group DDC-2268
2066
     */
2067
    public function testCaseThenFunction()
2068
    {
2069
        $this->assertSqlGeneration(
2070
            'SELECT CASE WHEN LENGTH(u.name) <> 0 THEN CONCAT(u.id, u.name) ELSE u.id END AS name  FROM Doctrine\Tests\Models\CMS\CmsUser u',
2071
            'SELECT CASE WHEN LENGTH(t0."name") <> 0 THEN t0."id" || t0."name" ELSE t0."id" END AS c0 FROM "cms_users" t0'
2072
        );
2073
2074
        $this->assertSqlGeneration(
2075
            'SELECT CASE WHEN LENGTH(u.name) <> LENGTH(TRIM(u.name)) THEN TRIM(u.name) ELSE u.name END AS name  FROM Doctrine\Tests\Models\CMS\CmsUser u',
2076
            'SELECT CASE WHEN LENGTH(t0."name") <> LENGTH(TRIM(t0."name")) THEN TRIM(t0."name") ELSE t0."name" END AS c0 FROM "cms_users" t0'
2077
        );
2078
2079
        $this->assertSqlGeneration(
2080
            'SELECT CASE WHEN LENGTH(u.name) > :value THEN SUBSTRING(u.name, 0, :value) ELSE TRIM(u.name) END AS name  FROM Doctrine\Tests\Models\CMS\CmsUser u',
2081
            'SELECT CASE WHEN LENGTH(t0."name") > ? THEN SUBSTRING(t0."name" FROM 0 FOR ?) ELSE TRIM(t0."name") END AS c0 FROM "cms_users" t0'
2082
        );
2083
    }
2084
2085
    /**
2086
     * @group DDC-2268
2087
     */
2088
    public function testSupportsMoreThanTwoParametersInConcatFunctionMySql()
2089
    {
2090
        $this->em->getConnection()->setDatabasePlatform(new MySqlPlatform());
2091
2092
        $this->assertSqlGeneration(
2093
            'SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE CONCAT(u.name, u.status, \'s\') = ?1',
2094
            'SELECT t0.`id` AS c0 FROM `cms_users` t0 WHERE CONCAT(t0.`name`, t0.`status`, \'s\') = ?'
2095
        );
2096
2097
        $this->assertSqlGeneration(
2098
            'SELECT CONCAT(u.id, u.name, u.status) FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1',
2099
            'SELECT CONCAT(t0.`id`, t0.`name`, t0.`status`) AS c0 FROM `cms_users` t0 WHERE t0.`id` = ?'
2100
        );
2101
    }
2102
2103
    /**
2104
     * @group DDC-2268
2105
     */
2106
    public function testSupportsMoreThanTwoParametersInConcatFunctionPgSql()
2107
    {
2108
        $this->em->getConnection()->setDatabasePlatform(new PostgreSqlPlatform());
2109
2110
        $this->assertSqlGeneration(
2111
            'SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE CONCAT(u.name, u.status, \'s\') = ?1',
2112
            'SELECT t0."id" AS c0 FROM "cms_users" t0 WHERE t0."name" || t0."status" || \'s\' = ?'
2113
        );
2114
2115
        $this->assertSqlGeneration(
2116
            'SELECT CONCAT(u.id, u.name, u.status) FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1',
2117
            'SELECT t0."id" || t0."name" || t0."status" AS c0 FROM "cms_users" t0 WHERE t0."id" = ?'
2118
        );
2119
    }
2120
2121
    /**
2122
     * @group DDC-2268
2123
     */
2124
    public function testSupportsMoreThanTwoParametersInConcatFunctionSqlServer()
2125
    {
2126
        $this->em->getConnection()->setDatabasePlatform(new SQLServerPlatform());
2127
2128
        $this->assertSqlGeneration(
2129
            'SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE CONCAT(u.name, u.status, \'s\') = ?1',
2130
            'SELECT t0.[id] AS c0 FROM [cms_users] t0 WHERE (t0.[name] + t0.[status] + \'s\') = ?'
2131
    	);
2132
2133
        $this->assertSqlGeneration(
2134
            'SELECT CONCAT(u.id, u.name, u.status) FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1',
2135
            'SELECT (t0.[id] + t0.[name] + t0.[status]) AS c0 FROM [cms_users] t0 WHERE t0.[id] = ?'
2136
    	);
2137
    }
2138
2139
    /**
2140
     * @group DDC-2188
2141
     */
2142
    public function testArithmeticPriority()
2143
    {
2144
        $this->assertSqlGeneration(
2145
            'SELECT 100/(2*2) FROM Doctrine\Tests\Models\CMS\CmsUser u',
2146
            'SELECT 100 / (2 * 2) AS c0 FROM "cms_users" t0'
2147
        );
2148
2149
        $this->assertSqlGeneration(
2150
            'SELECT (u.id / (u.id * 2)) FROM Doctrine\Tests\Models\CMS\CmsUser u',
2151
            'SELECT (t0."id" / (t0."id" * 2)) AS c0 FROM "cms_users" t0'
2152
        );
2153
2154
        $this->assertSqlGeneration(
2155
            'SELECT 100/(2*2) + (u.id / (u.id * 2)) FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE (u.id / (u.id * 2)) > 0',
2156
            'SELECT 100 / (2 * 2) + (t0."id" / (t0."id" * 2)) AS c0 FROM "cms_users" t0 WHERE (t0."id" / (t0."id" * 2)) > 0'
2157
        );
2158
    }
2159
2160
    /**
2161
     * @group DDC-2475
2162
     */
2163
    public function testOrderByClauseShouldReplaceOrderByRelationMapping()
2164
    {
2165
        $this->assertSqlGeneration(
2166
            'SELECT r, b FROM Doctrine\Tests\Models\Routing\RoutingRoute r JOIN r.bookings b',
2167
            'SELECT t0."id" AS c0, t1."id" AS c1, t1."passengerName" AS c2 FROM "RoutingRoute" t0 INNER JOIN "RoutingRouteBooking" t1 ON t0."id" = t1."route_id" ORDER BY t1."passengerName" ASC'
2168
        );
2169
2170
        $this->assertSqlGeneration(
2171
            'SELECT r, b FROM Doctrine\Tests\Models\Routing\RoutingRoute r JOIN r.bookings b ORDER BY b.passengerName DESC',
2172
            'SELECT t0."id" AS c0, t1."id" AS c1, t1."passengerName" AS c2 FROM "RoutingRoute" t0 INNER JOIN "RoutingRouteBooking" t1 ON t0."id" = t1."route_id" ORDER BY t1."passengerName" DESC'
2173
        );
2174
    }
2175
2176
    /**
2177
     * @group DDC-1858
2178
     */
2179
    public function testHavingSupportIsNullExpression()
2180
    {
2181
        $this->assertSqlGeneration(
2182
            'SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u HAVING u.username IS NULL',
2183
            'SELECT t0."name" AS c0 FROM "cms_users" t0 HAVING t0."username" IS NULL'
2184
        );
2185
2186
        $this->assertSqlGeneration(
2187
            'SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u HAVING MAX(u.name) IS NULL',
2188
            'SELECT t0."name" AS c0 FROM "cms_users" t0 HAVING MAX(t0."name") IS NULL'
2189
        );
2190
    }
2191
2192
    /**
2193
     * @group DDC-2506
2194
     */
2195
    public function testClassTableInheritanceJoinWithConditionAppliesToBaseTable()
2196
    {
2197
        $this->assertSqlGeneration(
2198
            'SELECT e.id FROM Doctrine\Tests\Models\Company\CompanyOrganization o JOIN o.events e WITH e.id = ?1',
2199
            'SELECT t0."id" AS c0 FROM "company_organizations" t1 INNER JOIN ("company_events" t0 LEFT JOIN "company_auctions" t2 ON t0."id" = t2."id" LEFT JOIN "company_raffles" t3 ON t0."id" = t3."id") ON t1."id" = t0."org_id" AND (t0."id" = ?)',
2200
            [ORMQuery::HINT_FORCE_PARTIAL_LOAD => false]
2201
        );
2202
    }
2203
2204
    /**
2205
     * @group DDC-2235
2206
     */
2207
    public function testSingleTableInheritanceLeftJoinWithCondition()
2208
    {
2209
        // Regression test for the bug
2210
        $this->assertSqlGeneration(
2211
            'SELECT c FROM Doctrine\Tests\Models\Company\CompanyEmployee e LEFT JOIN Doctrine\Tests\Models\Company\CompanyContract c WITH c.salesPerson = e.id',
2212
            'SELECT t0."id" AS c0, t0."completed" AS c1, t0."fixPrice" AS c2, t0."hoursWorked" AS c3, t0."pricePerHour" AS c4, t0."maxPrice" AS c5, t0."discr" AS c6 FROM "company_employees" t1 INNER JOIN "company_persons" t2 ON t1."id" = t2."id" LEFT JOIN "company_contracts" t0 ON (t0."salesPerson_id" = t2."id") AND t0."discr" IN (\'fix\', \'flexible\', \'flexultra\')'
2213
        );
2214
    }
2215
2216
    /**
2217
     * @group DDC-2235
2218
     */
2219
    public function testSingleTableInheritanceLeftJoinWithConditionAndWhere()
2220
    {
2221
        // Ensure other WHERE predicates are passed through to the main WHERE clause
2222
        $this->assertSqlGeneration(
2223
            'SELECT c FROM Doctrine\Tests\Models\Company\CompanyEmployee e LEFT JOIN Doctrine\Tests\Models\Company\CompanyContract c WITH c.salesPerson = e.id WHERE e.salary > 1000',
2224
            'SELECT t0."id" AS c0, t0."completed" AS c1, t0."fixPrice" AS c2, t0."hoursWorked" AS c3, t0."pricePerHour" AS c4, t0."maxPrice" AS c5, t0."discr" AS c6 FROM "company_employees" t1 INNER JOIN "company_persons" t2 ON t1."id" = t2."id" LEFT JOIN "company_contracts" t0 ON (t0."salesPerson_id" = t2."id") AND t0."discr" IN (\'fix\', \'flexible\', \'flexultra\') WHERE t1."salary" > 1000'
2225
        );
2226
    }
2227
2228
    /**
2229
     * @group DDC-2235
2230
     */
2231
    public function testSingleTableInheritanceInnerJoinWithCondition()
2232
    {
2233
        // Test inner joins too
2234
        $this->assertSqlGeneration(
2235
            'SELECT c FROM Doctrine\Tests\Models\Company\CompanyEmployee e INNER JOIN Doctrine\Tests\Models\Company\CompanyContract c WITH c.salesPerson = e.id',
2236
            'SELECT t0."id" AS c0, t0."completed" AS c1, t0."fixPrice" AS c2, t0."hoursWorked" AS c3, t0."pricePerHour" AS c4, t0."maxPrice" AS c5, t0."discr" AS c6 FROM "company_employees" t1 INNER JOIN "company_persons" t2 ON t1."id" = t2."id" INNER JOIN "company_contracts" t0 ON (t0."salesPerson_id" = t2."id") AND t0."discr" IN (\'fix\', \'flexible\', \'flexultra\')'
2237
        );
2238
    }
2239
2240
    /**
2241
     * @group DDC-2235
2242
     */
2243
    public function testSingleTableInheritanceLeftJoinNonAssociationWithConditionAndWhere()
2244
    {
2245
        // Test that the discriminator IN() predicate is still added into
2246
        // the where clause when not joining onto that table
2247
        $this->assertSqlGeneration(
2248
            'SELECT c FROM Doctrine\Tests\Models\Company\CompanyContract c LEFT JOIN Doctrine\Tests\Models\Company\CompanyEmployee e WITH e.id = c.salesPerson WHERE c.completed = true',
2249
            'SELECT t0."id" AS c0, t0."completed" AS c1, t0."fixPrice" AS c2, t0."hoursWorked" AS c3, t0."pricePerHour" AS c4, t0."maxPrice" AS c5, t0."discr" AS c6 FROM "company_contracts" t0 LEFT JOIN ("company_employees" t1 INNER JOIN "company_persons" t2 ON t1."id" = t2."id") ON (t2."id" = t0."salesPerson_id") WHERE (t0."completed" = 1) AND t0."discr" IN (\'fix\', \'flexible\', \'flexultra\')'
2250
        );
2251
    }
2252
2253
    /**
2254
     * @group DDC-2235
2255
     */
2256
    public function testSingleTableInheritanceJoinCreatesOnCondition()
2257
    {
2258
        // Test that the discriminator IN() predicate is still added
2259
        // into the where clause when not joining onto a single table inheritance entity
2260
        // via a join association
2261
        $this->assertSqlGeneration(
2262
            'SELECT c FROM Doctrine\Tests\Models\Company\CompanyContract c JOIN c.salesPerson s WHERE c.completed = true',
2263
            'SELECT t0."id" AS c0, t0."completed" AS c1, t0."fixPrice" AS c2, t0."hoursWorked" AS c3, t0."pricePerHour" AS c4, t0."maxPrice" AS c5, t0."discr" AS c6 FROM "company_contracts" t0 INNER JOIN "company_employees" t1 ON t0."salesPerson_id" = t1."id" LEFT JOIN "company_persons" t2 ON t1."id" = t2."id" WHERE (t0."completed" = 1) AND t0."discr" IN (\'fix\', \'flexible\', \'flexultra\')'
2264
        );
2265
    }
2266
2267
    /**
2268
     * @group DDC-2235
2269
     */
2270
    public function testSingleTableInheritanceCreatesOnConditionAndWhere()
2271
    {
2272
        // Test that when joining onto an entity using single table inheritance via
2273
        // a join association that the discriminator IN() predicate is placed
2274
        // into the ON clause of the join
2275
        $this->assertSqlGeneration(
2276
            'SELECT e, COUNT(c) FROM Doctrine\Tests\Models\Company\CompanyEmployee e JOIN e.contracts c WHERE e.department = :department',
2277
            'SELECT t0."id" AS c0, t0."name" AS c1, t1."salary" AS c2, t1."department" AS c3, t1."startDate" AS c4, COUNT(t2."id") AS c5, t0."discr" AS c6 FROM "company_employees" t1 INNER JOIN "company_persons" t0 ON t1."id" = t0."id" INNER JOIN "company_contract_employees" t3 ON t1."id" = t3."employee_id" INNER JOIN "company_contracts" t2 ON t2."id" = t3."contract_id" AND t2."discr" IN (\'fix\', \'flexible\', \'flexultra\') WHERE t1."department" = ?',
2278
            [],
2279
            ['department' => 'foobar']
2280
        );
2281
    }
2282
2283
    /**
2284
     * @group DDC-1858
2285
     */
2286
    public function testHavingSupportResultVariableInExpression()
2287
    {
2288
        $this->assertSqlGeneration(
2289
            'SELECT u.name AS foo FROM Doctrine\Tests\Models\CMS\CmsUser u HAVING foo IN (?1)',
2290
            'SELECT t0."name" AS c0 FROM "cms_users" t0 HAVING c0 IN (?)'
2291
        );
2292
    }
2293
2294
    /**
2295
     * @group DDC-1858
2296
     */
2297
    public function testHavingSupportResultVariableLikeExpression()
2298
    {
2299
        $this->assertSqlGeneration(
2300
            'SELECT u.name AS foo FROM Doctrine\Tests\Models\CMS\CmsUser u HAVING foo LIKE \'3\'',
2301
            'SELECT t0."name" AS c0 FROM "cms_users" t0 HAVING c0 LIKE \'3\''
2302
        );
2303
    }
2304
2305
    /**
2306
     * @group DDC-3085
2307
     */
2308
    public function testHavingSupportResultVariableNullComparisonExpression()
2309
    {
2310
        $this->assertSqlGeneration(
2311
            'SELECT u AS user, SUM(a.id) AS score FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN Doctrine\Tests\Models\CMS\CmsAddress a WITH a.user = u GROUP BY u HAVING score IS NOT NULL AND score >= 5',
2312
            'SELECT t0."id" AS c0, t0."status" AS c1, t0."username" AS c2, t0."name" AS c3, SUM(t1."id") AS c4 FROM "cms_users" t0 LEFT JOIN "cms_addresses" t1 ON (t1."user_id" = t0."id") GROUP BY t0."id", t0."status", t0."username", t0."name", t0."email_id" HAVING c4 IS NOT NULL AND c4 >= 5'
2313
        );
2314
    }
2315
2316
    /**
2317
     * @group DDC-1858
2318
     */
2319
    public function testHavingSupportResultVariableInAggregateFunction()
2320
    {
2321
        $this->assertSqlGeneration(
2322
            'SELECT COUNT(u.name) AS countName FROM Doctrine\Tests\Models\CMS\CmsUser u HAVING countName IS NULL',
2323
            'SELECT COUNT(t0."name") AS c0 FROM "cms_users" t0 HAVING c0 IS NULL'
2324
        );
2325
    }
2326
2327
    /**
2328
     * GitHub issue #4764: https://github.com/doctrine/doctrine2/issues/4764
2329
     *
2330
     * @group DDC-3907
2331
     * @dataProvider mathematicOperatorsProvider
2332
     */
2333
    public function testHavingRegressionUsingVariableWithMathOperatorsExpression($operator)
2334
    {
2335
        $this->assertSqlGeneration(
2336
            'SELECT COUNT(u.name) AS countName FROM Doctrine\Tests\Models\CMS\CmsUser u HAVING 1 ' . $operator . ' countName > 0',
2337
            'SELECT COUNT(t0."name") AS c0 FROM "cms_users" t0 HAVING 1 ' . $operator . ' c0 > 0'
2338
        );
2339
    }
2340
2341
    /**
2342
     * @return array
2343
     */
2344
    public function mathematicOperatorsProvider()
2345
    {
2346
        return [['+'], ['-'], ['*'], ['/']];
2347
    }
2348
}
2349
2350
class MyAbsFunction extends FunctionNode
2351
{
2352
    public $simpleArithmeticExpression;
2353
2354
    /**
2355
     * @override
2356
     */
2357
    public function getSql(SqlWalker $sqlWalker)
2358
    {
2359
        return 'ABS(' . $sqlWalker->walkSimpleArithmeticExpression($this->simpleArithmeticExpression) . ')';
2360
    }
2361
2362
    /**
2363
     * @override
2364
     */
2365
    public function parse(Parser $parser)
2366
    {
2367
        $lexer = $parser->getLexer();
2368
2369
        $parser->match(Lexer::T_IDENTIFIER);
2370
        $parser->match(Lexer::T_OPEN_PARENTHESIS);
2371
2372
        $this->simpleArithmeticExpression = $parser->SimpleArithmeticExpression();
2373
2374
        $parser->match(Lexer::T_CLOSE_PARENTHESIS);
2375
    }
2376
}
2377
/**
2378
 * @ORM\Entity
2379
 */
2380
class DDC1384Model
2381
{
2382
    /**
2383
     * @ORM\Id
2384
     * @ORM\Column(type="integer")
2385
     * @ORM\GeneratedValue
2386
     */
2387
    protected $aVeryLongIdentifierThatShouldBeShortenedByTheSQLWalker_fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo;
2388
}
2389
2390
2391
/**
2392
 * @ORM\Entity
2393
 */
2394
class DDC1474Entity
2395
{
2396
2397
    /**
2398
     * @ORM\Id
2399
     * @ORM\Column(type="integer")
2400
     * @ORM\GeneratedValue()
2401
     */
2402
    protected $id;
2403
2404
    /**
2405
     * @ORM\Column(type="float")
2406
     */
2407
    private $value;
2408
2409
    /**
2410
     * @param string $float
2411
     */
2412
    public function __construct($float)
2413
    {
2414
        $this->value = $float;
2415
    }
2416
2417
    /**
2418
     * @return int
2419
     */
2420
    public function getId()
2421
    {
2422
        return $this->id;
2423
    }
2424
2425
    /**
2426
     * @return float
2427
     */
2428
    public function getValue()
2429
    {
2430
        return $this->value;
2431
    }
2432
2433
    /**
2434
     * @param float $value
2435
     */
2436
    public function setValue($value)
2437
    {
2438
        $this->value = $value;
2439
    }
2440
}
2441