Skip to content

Commit d700c0e

Browse files
authored
coalesce() unions only types until the first non-nullable (#519)
1 parent 7f5fc7e commit d700c0e

11 files changed

+6556
-1634
lines changed

.phpstan-dba-mysqli.cache

Lines changed: 5488 additions & 149 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: 76 additions & 201 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/QueryReflection/PdoPgSqlQueryReflector.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public function __construct(PDO $pdo)
2828
}
2929

3030
/** @return PDOException|list<PDOColumnMeta>|null */
31-
protected function simulateQuery(string $queryString)
31+
protected function simulateQuery(string $queryString) // @phpstan-ignore-line
3232
{
3333
if (\array_key_exists($queryString, $this->cache)) {
3434
return $this->cache[$queryString];

src/SqlAst/CoalesceReturnTypeExtension.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ final class CoalesceReturnTypeExtension implements QueryFunctionReturnTypeExtens
1313
{
1414
public function isFunctionSupported(FunctionCall $expression): bool
1515
{
16-
return \in_array($expression->getFunction()->getName(), [BuiltInFunction::COALESCE, BuiltInFunction::IFNULL, BuiltInFunction::NULLIF], true);
16+
return \in_array($expression->getFunction()->getName(), [BuiltInFunction::COALESCE], true);
1717
}
1818

1919
public function getReturnType(FunctionCall $expression, QueryScope $scope): Type
@@ -28,6 +28,7 @@ public function getReturnType(FunctionCall $expression, QueryScope $scope): Type
2828
$results[] = $argType;
2929
if (!TypeCombinator::containsNull($argType)) {
3030
$containsNonNullable = true;
31+
break;
3132
}
3233
}
3334

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace staabm\PHPStanDba\SqlAst;
6+
7+
use PHPStan\Type\Type;
8+
use PHPStan\Type\TypeCombinator;
9+
use SqlFtw\Sql\Expression\BuiltInFunction;
10+
use SqlFtw\Sql\Expression\FunctionCall;
11+
12+
final class IfNullReturnTypeExtension implements QueryFunctionReturnTypeExtension
13+
{
14+
public function isFunctionSupported(FunctionCall $expression): bool
15+
{
16+
return \in_array($expression->getFunction()->getName(), [BuiltInFunction::IFNULL, BuiltInFunction::NULLIF], true);
17+
}
18+
19+
public function getReturnType(FunctionCall $expression, QueryScope $scope): Type
20+
{
21+
$args = $expression->getArguments();
22+
23+
$results = [];
24+
foreach ($args as $arg) {
25+
$argType = $scope->getType($arg);
26+
27+
$results[] = $argType;
28+
}
29+
30+
return TypeCombinator::union(...$results);
31+
}
32+
}

src/SqlAst/QueryScope.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ public function __construct(Table $fromTable, array $joinedTables)
5151
$this->extensions = [
5252
new PositiveIntReturnTypeExtension(),
5353
new CoalesceReturnTypeExtension(),
54+
new IfNullReturnTypeExtension(),
5455
new ConcatReturnTypeExtension(),
5556
new InstrReturnTypeExtension(),
5657
new StrCaseReturnTypeExtension(),

0 commit comments

Comments
 (0)