diff --git a/src/Type/Doctrine/Query/QueryResultTypeWalker.php b/src/Type/Doctrine/Query/QueryResultTypeWalker.php index c186a5e3..14519922 100644 --- a/src/Type/Doctrine/Query/QueryResultTypeWalker.php +++ b/src/Type/Doctrine/Query/QueryResultTypeWalker.php @@ -933,12 +933,29 @@ public function walkAggregateExpression($aggExpression): string switch ($aggExpression->functionName) { case 'MAX': case 'MIN': + $type = $this->unmarshalType( + $this->walkSimpleArithmeticExpression($aggExpression->pathExpression) + ); + + return $this->marshalType(TypeCombinator::addNull($type)); + case 'AVG': + $type = $this->unmarshalType( + $this->walkSimpleArithmeticExpression($aggExpression->pathExpression) + ); + + $type = TypeCombinator::union($type, $type->toFloat()); + $type = TypeUtils::generalizeType($type, GeneralizePrecision::lessSpecific()); + + return $this->marshalType(TypeCombinator::addNull($type)); + case 'SUM': $type = $this->unmarshalType( $this->walkSimpleArithmeticExpression($aggExpression->pathExpression) ); + $type = TypeUtils::generalizeType($type, GeneralizePrecision::lessSpecific()); + return $this->marshalType(TypeCombinator::addNull($type)); case 'COUNT': diff --git a/tests/Type/Doctrine/Query/QueryResultTypeWalkerTest.php b/tests/Type/Doctrine/Query/QueryResultTypeWalkerTest.php index 27d1acab..ea1e0aea 100644 --- a/tests/Type/Doctrine/Query/QueryResultTypeWalkerTest.php +++ b/tests/Type/Doctrine/Query/QueryResultTypeWalkerTest.php @@ -681,6 +681,82 @@ public function getTestData(): iterable ', ]; + yield 'aggregate on literal' => [ + $this->constantArray([ + [ + new ConstantIntegerType(1), + TypeCombinator::union( + new ConstantStringType('1'), + new ConstantIntegerType(1), + new NullType() + ), + ], + [ + new ConstantIntegerType(2), + TypeCombinator::union( + new ConstantStringType('0'), + new ConstantIntegerType(0), + new ConstantStringType('1'), + new ConstantIntegerType(1), + new NullType() + ), + ], + [ + new ConstantIntegerType(3), + TypeCombinator::union( + new ConstantStringType('1'), + new ConstantIntegerType(1), + new NullType() + ), + ], + [ + new ConstantIntegerType(4), + TypeCombinator::union( + new ConstantStringType('0'), + new ConstantIntegerType(0), + new ConstantStringType('1'), + new ConstantIntegerType(1), + new NullType() + ), + ], + [ + new ConstantIntegerType(5), + TypeCombinator::union( + $this->intStringified(), + new FloatType(), + new NullType() + ), + ], + [ + new ConstantIntegerType(6), + TypeCombinator::union( + $this->intStringified(), + new FloatType(), + new NullType() + ), + ], + [ + new ConstantIntegerType(7), + TypeCombinator::addNull($this->intStringified()), + ], + [ + new ConstantIntegerType(8), + TypeCombinator::addNull($this->intStringified()), + ], + ]), + ' + SELECT MAX(1), + MAX(CASE WHEN m.intColumn = 0 THEN 1 ELSE 0 END), + MIN(1), + MIN(CASE WHEN m.intColumn = 0 THEN 1 ELSE 0 END), + AVG(1), + AVG(CASE WHEN m.intColumn = 0 THEN 1 ELSE 0 END), + SUM(1), + SUM(CASE WHEN m.intColumn = 0 THEN 1 ELSE 0 END) + FROM QueryResult\Entities\Many m + ', + ]; + yield 'literal' => [ $this->constantArray([ [