SelectSqlGenerationTest   F
last analyzed

Complexity

Total Complexity 199

Size/Duplication

Total Lines 2389
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 911
c 1
b 0
f 0
dl 0
loc 2389
rs 1.689
wmc 199

188 Methods

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