Failed Conditions
Pull Request — master (#6959)
by Matthew
19:32
created

WhereInWalker   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 102
Duplicated Lines 0 %

Test Coverage

Coverage 87.5%

Importance

Changes 0
Metric Value
dl 0
loc 102
rs 10
c 0
b 0
f 0
ccs 42
cts 48
cp 0.875
wmc 10

1 Method

Rating   Name   Duplication   Size   Complexity  
C walkSelectStatement() 0 77 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\ORM\Tools\Pagination;
6
7
use Doctrine\ORM\Mapping\AssociationMetadata;
8
use Doctrine\ORM\Mapping\ToOneAssociationMetadata;
9
use Doctrine\ORM\Query\AST\ArithmeticExpression;
10
use Doctrine\ORM\Query\AST\ConditionalExpression;
11
use Doctrine\ORM\Query\AST\ConditionalFactor;
12
use Doctrine\ORM\Query\AST\ConditionalPrimary;
13
use Doctrine\ORM\Query\AST\ConditionalTerm;
14
use Doctrine\ORM\Query\AST\InExpression;
15
use Doctrine\ORM\Query\AST\InputParameter;
16
use Doctrine\ORM\Query\AST\NullComparisonExpression;
17
use Doctrine\ORM\Query\AST\PathExpression;
18
use Doctrine\ORM\Query\AST\SelectStatement;
19
use Doctrine\ORM\Query\AST\SimpleArithmeticExpression;
20
use Doctrine\ORM\Query\AST\WhereClause;
21
use Doctrine\ORM\Query\TreeWalkerAdapter;
22
23
/**
24
 * Replaces the whereClause of the AST with a WHERE id IN (:foo_1, :foo_2) equivalent.
25
 */
26
class WhereInWalker extends TreeWalkerAdapter
27
{
28
    /**
29
     * ID Count hint name.
30
     */
31
    public const HINT_PAGINATOR_ID_COUNT = 'doctrine.id.count';
32
33
    /**
34
     * Primary key alias for query.
35
     */
36
    public const PAGINATOR_ID_ALIAS = 'dpid';
37
38
    /**
39
     * Replaces the whereClause in the AST.
40
     *
41
     * Generates a clause equivalent to WHERE IN (:dpid_1, :dpid_2, ...)
42
     *
43
     * The parameter namespace (dpid) is defined by
44
     * the PAGINATOR_ID_ALIAS
45
     *
46
     * The total number of parameters is retrieved from
47
     * the HINT_PAGINATOR_ID_COUNT query hint.
48
     *
49
     * @throws \RuntimeException
50
     */
51 57
    public function walkSelectStatement(SelectStatement $AST)
52
    {
53 57
        $queryComponents = $this->getQueryComponents();
54
        // Get the root entity and alias from the AST fromClause
55 57
        $from = $AST->fromClause->identificationVariableDeclarations;
56
57 57
        if (count($from) > 1) {
58
            throw new \RuntimeException('Cannot count query which selects two FROM components, cannot make distinction');
59
        }
60
61 57
        $fromRoot  = reset($from);
62 57
        $rootAlias = $fromRoot->rangeVariableDeclaration->aliasIdentificationVariable;
63 57
        $rootClass = $queryComponents[$rootAlias]['metadata'];
64 57
        $property  = $rootClass->getProperty($rootClass->getSingleIdentifierFieldName());
65 57
        $pathType  = PathExpression::TYPE_STATE_FIELD;
66
67 57
        if ($property instanceof AssociationMetadata) {
68
            $pathType = $property instanceof ToOneAssociationMetadata
69
                ? PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION
70
                : PathExpression::TYPE_COLLECTION_VALUED_ASSOCIATION
71
            ;
72
        }
73
74 57
        $pathExpression = new PathExpression(
75 57
            PathExpression::TYPE_STATE_FIELD | PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION,
76 57
            $rootAlias,
77 57
            $property->getName()
78
        );
79
80 57
        $pathExpression->type = $pathType;
81
82 57
        $count = $this->getQuery()->getHint(self::HINT_PAGINATOR_ID_COUNT);
83
84 57
        if ($count > 0) {
85 57
            $arithmeticExpression                             = new ArithmeticExpression();
86 57
            $arithmeticExpression->simpleArithmeticExpression = new SimpleArithmeticExpression(
87 57
                [$pathExpression]
88
            );
89 57
            $expression                                       = new InExpression($arithmeticExpression);
90 57
            $expression->literals[]                           = new InputParameter(':' . self::PAGINATOR_ID_ALIAS);
91
        } else {
92
            $expression      = new NullComparisonExpression($pathExpression);
93
            $expression->not = false;
94
        }
95
96 57
        $conditionalPrimary                              = new ConditionalPrimary;
97 57
        $conditionalPrimary->simpleConditionalExpression = $expression;
98
99 57
        if ($AST->whereClause) {
100 9
            if ($AST->whereClause->conditionalExpression instanceof ConditionalTerm) {
101 2
                $AST->whereClause->conditionalExpression->conditionalFactors[] = $conditionalPrimary;
102 7
            } elseif ($AST->whereClause->conditionalExpression instanceof ConditionalPrimary) {
103 4
                $AST->whereClause->conditionalExpression = new ConditionalExpression(
104 4
                    [new ConditionalTerm(
105
                        [
106 4
                                $AST->whereClause->conditionalExpression,
107 4
                                $conditionalPrimary,
108
                            ]
109
                    ),
110
                    ]
111
                );
112 3
            } elseif ($AST->whereClause->conditionalExpression instanceof ConditionalExpression
113 3
                || $AST->whereClause->conditionalExpression instanceof ConditionalFactor
114
            ) {
115 3
                $tmpPrimary                              = new ConditionalPrimary;
116 3
                $tmpPrimary->conditionalExpression       = $AST->whereClause->conditionalExpression;
117 3
                $AST->whereClause->conditionalExpression = new ConditionalTerm(
0 ignored issues
show
Documentation Bug introduced by
It seems like new Doctrine\ORM\Query\A..., $conditionalPrimary)) of type Doctrine\ORM\Query\AST\ConditionalTerm is incompatible with the declared type Doctrine\ORM\Query\AST\ConditionalExpression of property $conditionalExpression.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
118
                    [
119 3
                        $tmpPrimary,
120 9
                        $conditionalPrimary,
121
                    ]
122
                );
123
            }
124
        } else {
125 48
            $AST->whereClause = new WhereClause(
126 48
                new ConditionalExpression(
127 48
                    [new ConditionalTerm([$conditionalPrimary])]
128
                )
129
            );
130
        }
131 57
    }
132
}
133