Skip to content

Commit 34e3a21

Browse files
authored
Sql AST: avg/min/max/count can get null on empty result sets (#579)
1 parent a1bb0c6 commit 34e3a21

File tree

9 files changed

+130
-1201
lines changed

9 files changed

+130
-1201
lines changed

.phpstan-dba-mysqli.cache

Lines changed: 1 addition & 515 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.phpstan-dba-pdo-mysql.cache

Lines changed: 1 addition & 515 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/QueryReflection/QueryReflection.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,15 +161,17 @@ private function stringifyResult(Type $type): Type
161161

162162
private function stringifyType(Type $type): Type
163163
{
164+
$containsNull = TypeCombinator::containsNull($type);
165+
164166
$numberType = new UnionType([new IntegerType(), new FloatType()]);
165167

166-
if ($numberType->isSuperTypeOf($type)->yes()) {
168+
if ($numberType->isSuperTypeOf(TypeCombinator::removeNull($type))->yes()) {
167169
$stringified = new IntersectionType([
168170
new StringType(),
169171
new AccessoryNumericStringType(),
170172
]);
171173

172-
if (TypeCombinator::containsNull($type)) {
174+
if ($containsNull) {
173175
return TypeCombinator::addNull($stringified);
174176
}
175177

src/SqlAst/AvgReturnTypeExtension.php

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,6 @@ public function getReturnType(FunctionCall $expression, QueryScope $scope): ?Typ
2727
$argType = $scope->getType($args[0]);
2828
$numberType = $argType->toNumber();
2929

30-
if (TypeCombinator::containsNull($argType)) {
31-
return TypeCombinator::addNull($numberType);
32-
}
33-
34-
return $numberType;
30+
return TypeCombinator::addNull($numberType);
3531
}
3632
}

src/SqlAst/PositiveIntReturnTypeExtension.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use PHPStan\Type\IntegerRangeType;
88
use PHPStan\Type\Type;
9+
use PHPStan\Type\TypeCombinator;
910
use SqlFtw\Sql\Expression\BuiltInFunction;
1011
use SqlFtw\Sql\Expression\FunctionCall;
1112

@@ -30,6 +31,12 @@ public function isFunctionSupported(FunctionCall $expression): bool
3031

3132
public function getReturnType(FunctionCall $expression, QueryScope $scope): Type
3233
{
33-
return IntegerRangeType::fromInterval(0, null);
34+
$positiveInt = IntegerRangeType::fromInterval(0, null);
35+
36+
if ($expression->getFunction()->getName() === BuiltInFunction::COUNT) {
37+
return TypeCombinator::addNull($positiveInt);
38+
}
39+
40+
return $positiveInt;
3441
}
3542
}

tests/default/config/.phpunit-phpstan-dba-mysqli.cache

Lines changed: 53 additions & 77 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)