SelectSqlGenerationTest   F
last analyzed

Complexity

Total Complexity 195

Size/Duplication

Total Lines 2322
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 883
dl 0
loc 2322
rs 1.717
c 0
b 0
f 0
wmc 195

184 Methods

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

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
2410
    }
2411
2412
    /**
2413
     * @return int
2414
     */
2415
    public function getId()
2416
    {
2417
        return $this->id;
2418
    }
2419
2420
    /**
2421
     * @return float
2422
     */
2423
    public function getValue()
2424
    {
2425
        return $this->value;
2426
    }
2427
2428
    /**
2429
     * @param float $value
2430
     */
2431
    public function setValue($value)
2432
    {
2433
        $this->value = $value;
2434
    }
2435
}
2436