44
55use Doctrine \ORM \Query ;
66use Doctrine \ORM \Query \AST ;
7- use function is_string ;
7+ use function is_array ;
88
99class QueryAggregateFunctionDetectorTreeWalker extends Query \TreeWalkerAdapter
1010{
@@ -13,294 +13,38 @@ class QueryAggregateFunctionDetectorTreeWalker extends Query\TreeWalkerAdapter
1313
1414 public function walkSelectStatement (AST \SelectStatement $ selectStatement ): void
1515 {
16- $ this ->doWalkSelectClause ($ selectStatement ->selectClause );
16+ $ this ->walkNode ($ selectStatement ->selectClause );
1717 }
1818
1919 /**
20- * @param AST\SelectClause $selectClause
20+ * @param mixed $node
2121 */
22- public function doWalkSelectClause ( $ selectClause ): void
22+ public function walkNode ( $ node ): void
2323 {
24- foreach ($ selectClause ->selectExpressions as $ selectExpression ) {
25- $ this ->doWalkSelectExpression ($ selectExpression );
26- }
27- }
28-
29- /**
30- * @param AST\SelectExpression $selectExpression
31- */
32- public function doWalkSelectExpression ($ selectExpression ): void
33- {
34- $ this ->doWalkNode ($ selectExpression ->expression );
35- }
36-
37- /**
38- * @param mixed $expr
39- */
40- private function doWalkNode ($ expr ): void
41- {
42- if ($ expr instanceof AST \AggregateExpression) {
43- $ this ->markAggregateFunctionFound ();
44-
45- } elseif ($ expr instanceof AST \Functions \FunctionNode) {
46- if ($ this ->isAggregateFunction ($ expr )) {
47- $ this ->markAggregateFunctionFound ();
48- }
49-
50- } elseif ($ expr instanceof AST \SimpleArithmeticExpression) {
51- foreach ($ expr ->arithmeticTerms as $ term ) {
52- $ this ->doWalkArithmeticTerm ($ term );
53- }
54-
55- } elseif ($ expr instanceof AST \ArithmeticTerm) {
56- $ this ->doWalkArithmeticTerm ($ expr );
57-
58- } elseif ($ expr instanceof AST \ArithmeticFactor) {
59- $ this ->doWalkArithmeticFactor ($ expr );
60-
61- } elseif ($ expr instanceof AST \ParenthesisExpression) {
62- $ this ->doWalkArithmeticPrimary ($ expr ->expression );
63-
64- } elseif ($ expr instanceof AST \NullIfExpression) {
65- $ this ->doWalkNullIfExpression ($ expr );
66-
67- } elseif ($ expr instanceof AST \CoalesceExpression) {
68- $ this ->doWalkCoalesceExpression ($ expr );
69-
70- } elseif ($ expr instanceof AST \GeneralCaseExpression) {
71- $ this ->doWalkGeneralCaseExpression ($ expr );
72-
73- } elseif ($ expr instanceof AST \SimpleCaseExpression) {
74- $ this ->doWalkSimpleCaseExpression ($ expr );
75-
76- } elseif ($ expr instanceof AST \ArithmeticExpression) {
77- $ this ->doWalkArithmeticExpression ($ expr );
78-
79- } elseif ($ expr instanceof AST \ComparisonExpression) {
80- $ this ->doWalkComparisonExpression ($ expr );
81-
82- } elseif ($ expr instanceof AST \BetweenExpression) {
83- $ this ->doWalkBetweenExpression ($ expr );
84- }
85- }
86-
87- public function doWalkCoalesceExpression (AST \CoalesceExpression $ coalesceExpression ): void
88- {
89- foreach ($ coalesceExpression ->scalarExpressions as $ scalarExpression ) {
90- $ this ->doWalkSimpleArithmeticExpression ($ scalarExpression );
91- }
92- }
93-
94- public function doWalkNullIfExpression (AST \NullIfExpression $ nullIfExpression ): void
95- {
96- if (!is_string ($ nullIfExpression ->firstExpression )) {
97- $ this ->doWalkSimpleArithmeticExpression ($ nullIfExpression ->firstExpression );
98- }
99-
100- if (is_string ($ nullIfExpression ->secondExpression )) {
24+ if (!$ node instanceof AST \Node) {
10125 return ;
10226 }
10327
104- $ this ->doWalkSimpleArithmeticExpression ($ nullIfExpression ->secondExpression );
105- }
106-
107- public function doWalkGeneralCaseExpression (AST \GeneralCaseExpression $ generalCaseExpression ): void
108- {
109- foreach ($ generalCaseExpression ->whenClauses as $ whenClause ) {
110- $ this ->doWalkConditionalExpression ($ whenClause ->caseConditionExpression );
111- $ this ->doWalkSimpleArithmeticExpression ($ whenClause ->thenScalarExpression );
112- }
113-
114- $ this ->doWalkSimpleArithmeticExpression ($ generalCaseExpression ->elseScalarExpression );
115- }
116-
117- public function doWalkSimpleCaseExpression (AST \SimpleCaseExpression $ simpleCaseExpression ): void
118- {
119- foreach ($ simpleCaseExpression ->simpleWhenClauses as $ simpleWhenClause ) {
120- $ this ->doWalkSimpleArithmeticExpression ($ simpleWhenClause ->caseScalarExpression );
121- $ this ->doWalkSimpleArithmeticExpression ($ simpleWhenClause ->thenScalarExpression );
122- }
123-
124- $ this ->doWalkSimpleArithmeticExpression ($ simpleCaseExpression ->elseScalarExpression );
125- }
126-
127- /**
128- * @param AST\ConditionalExpression|AST\Phase2OptimizableConditional $condExpr
129- */
130- public function doWalkConditionalExpression ($ condExpr ): void
131- {
132- if (!$ condExpr instanceof AST \ConditionalExpression) {
133- $ this ->doWalkConditionalTerm ($ condExpr ); // @phpstan-ignore-line PHPStan do not read @psalm-inheritors of Phase2OptimizableConditional
134- return ;
135- }
136-
137- foreach ($ condExpr ->conditionalTerms as $ conditionalTerm ) {
138- $ this ->doWalkConditionalTerm ($ conditionalTerm );
139- }
140- }
141-
142- /**
143- * @param AST\ConditionalTerm|AST\ConditionalPrimary|AST\ConditionalFactor $condTerm
144- */
145- public function doWalkConditionalTerm ($ condTerm ): void
146- {
147- if (!$ condTerm instanceof AST \ConditionalTerm) {
148- $ this ->doWalkConditionalFactor ($ condTerm );
28+ if ($ this ->isAggregateFunction ($ node )) {
29+ $ this ->markAggregateFunctionFound ();
14930 return ;
15031 }
15132
152- foreach ($ condTerm -> conditionalFactors as $ conditionalFactor ) {
153- $ this -> doWalkConditionalFactor ( $ conditionalFactor );
154- }
155- }
33+ foreach (( array ) $ node as $ property ) {
34+ if ( $ property instanceof AST \Node) {
35+ $ this -> walkNode ( $ property );
36+ }
15637
157- /**
158- * @param AST\ConditionalFactor|AST\ConditionalPrimary $factor
159- */
160- public function doWalkConditionalFactor ($ factor ): void
161- {
162- if (!$ factor instanceof AST \ConditionalFactor) {
163- $ this ->doWalkConditionalPrimary ($ factor );
164- } else {
165- $ this ->doWalkConditionalPrimary ($ factor ->conditionalPrimary );
166- }
167- }
38+ if (is_array ($ property )) {
39+ foreach ($ property as $ propertyValue ) {
40+ $ this ->walkNode ($ propertyValue );
41+ }
42+ }
16843
169- /**
170- * @param AST\ConditionalPrimary $primary
171- */
172- public function doWalkConditionalPrimary ($ primary ): void
173- {
174- if ($ primary ->isSimpleConditionalExpression ()) {
175- if ($ primary ->simpleConditionalExpression instanceof AST \ComparisonExpression) {
176- $ this ->doWalkComparisonExpression ($ primary ->simpleConditionalExpression );
44+ if ($ this ->wasAggregateFunctionFound ()) {
17745 return ;
17846 }
179- $ this ->doWalkNode ($ primary ->simpleConditionalExpression );
18047 }
181-
182- if (!$ primary ->isConditionalExpression ()) {
183- return ;
184- }
185-
186- if ($ primary ->conditionalExpression === null ) {
187- return ;
188- }
189-
190- $ this ->doWalkConditionalExpression ($ primary ->conditionalExpression );
191- }
192-
193- /**
194- * @param AST\BetweenExpression $betweenExpr
195- */
196- public function doWalkBetweenExpression ($ betweenExpr ): void
197- {
198- $ this ->doWalkArithmeticExpression ($ betweenExpr ->expression );
199- $ this ->doWalkArithmeticExpression ($ betweenExpr ->leftBetweenExpression );
200- $ this ->doWalkArithmeticExpression ($ betweenExpr ->rightBetweenExpression );
201- }
202-
203- /**
204- * @param AST\ComparisonExpression $compExpr
205- */
206- public function doWalkComparisonExpression ($ compExpr ): void
207- {
208- $ leftExpr = $ compExpr ->leftExpression ;
209- $ rightExpr = $ compExpr ->rightExpression ;
210-
211- if ($ leftExpr instanceof AST \Node) {
212- $ this ->doWalkNode ($ leftExpr );
213- }
214-
215- if (!($ rightExpr instanceof AST \Node)) {
216- return ;
217- }
218-
219- $ this ->doWalkNode ($ rightExpr );
220- }
221-
222- /**
223- * @param AST\ArithmeticExpression $arithmeticExpr
224- */
225- public function doWalkArithmeticExpression ($ arithmeticExpr ): void
226- {
227- if (!$ arithmeticExpr ->isSimpleArithmeticExpression ()) {
228- return ;
229- }
230-
231- if ($ arithmeticExpr ->simpleArithmeticExpression === null ) {
232- return ;
233- }
234-
235- $ this ->doWalkSimpleArithmeticExpression ($ arithmeticExpr ->simpleArithmeticExpression );
236- }
237-
238- /**
239- * @param AST\Node|string $simpleArithmeticExpr
240- */
241- public function doWalkSimpleArithmeticExpression ($ simpleArithmeticExpr ): void
242- {
243- if (!$ simpleArithmeticExpr instanceof AST \SimpleArithmeticExpression) {
244- $ this ->doWalkArithmeticTerm ($ simpleArithmeticExpr );
245- return ;
246- }
247-
248- foreach ($ simpleArithmeticExpr ->arithmeticTerms as $ term ) {
249- $ this ->doWalkArithmeticTerm ($ term );
250- }
251- }
252-
253- /**
254- * @param AST\Node|string $term
255- */
256- public function doWalkArithmeticTerm ($ term ): void
257- {
258- if (is_string ($ term )) {
259- return ;
260- }
261-
262- if (!$ term instanceof AST \ArithmeticTerm) {
263- $ this ->doWalkArithmeticFactor ($ term );
264- return ;
265- }
266-
267- foreach ($ term ->arithmeticFactors as $ factor ) {
268- $ this ->doWalkArithmeticFactor ($ factor );
269- }
270- }
271-
272- /**
273- * @param AST\Node|string $factor
274- */
275- public function doWalkArithmeticFactor ($ factor ): void
276- {
277- if (is_string ($ factor )) {
278- return ;
279- }
280-
281- if (!$ factor instanceof AST \ArithmeticFactor) {
282- $ this ->doWalkArithmeticPrimary ($ factor );
283- return ;
284- }
285-
286- $ this ->doWalkArithmeticPrimary ($ factor ->arithmeticPrimary );
287- }
288-
289- /**
290- * @param AST\Node|string $primary
291- */
292- public function doWalkArithmeticPrimary ($ primary ): void
293- {
294- if ($ primary instanceof AST \SimpleArithmeticExpression) {
295- $ this ->doWalkSimpleArithmeticExpression ($ primary );
296- return ;
297- }
298-
299- if (!($ primary instanceof AST \Node)) {
300- return ;
301- }
302-
303- $ this ->doWalkNode ($ primary );
30448 }
30549
30650 private function isAggregateFunction (AST \Node $ node ): bool
@@ -318,4 +62,9 @@ private function markAggregateFunctionFound(): void
31862 $ this ->_getQuery ()->setHint (self ::HINT_HAS_AGGREGATE_FUNCTION , true );
31963 }
32064
65+ private function wasAggregateFunctionFound (): bool
66+ {
67+ return $ this ->_getQuery ()->hasHint (self ::HINT_HAS_AGGREGATE_FUNCTION );
68+ }
69+
32170}
0 commit comments