1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-26 20:34:47 +01:00

#9974 extended return type detection for PDOStatement::fetchAll/fetch with FETCH_COLUMN and FETCH_KEY_PAIR

This commit is contained in:
Thomas Bley 2023-07-27 01:39:21 +02:00
parent fc74ae83e6
commit 66bc28d2a8
2 changed files with 105 additions and 34 deletions

View File

@ -116,6 +116,13 @@ class PdoStatementReturnTypeProvider implements MethodReturnTypeProviderInterfac
case 6: // PDO::FETCH_BOUND - bool
return Type::getBool();
case 7: // PDO::FETCH_COLUMN - scalar|null|false
return new Union([
new TScalar(),
new TNull(),
new TFalse(),
]);
case 8: // PDO::FETCH_CLASS - object|false
return new Union([
$fetch_class_name ? new TNamedObject($fetch_class_name) : new TObject(),
@ -130,18 +137,35 @@ class PdoStatementReturnTypeProvider implements MethodReturnTypeProviderInterfac
new TFalse(),
]);
case 11: // PDO::FETCH_NAMED - array<string, scalar|list<scalar>>|false
case 11: // PDO::FETCH_NAMED - array<string, scalar|null|list<scalar|null>>|false
return new Union([
new TArray([
Type::getString(),
new Union([
new TScalar(),
Type::getListAtomic(Type::getScalar()),
new TNull(),
Type::getListAtomic(
new Union([
new TScalar(),
new TNull(),
])
),
]),
]),
new TFalse(),
]);
case 12: // PDO::FETCH_KEY_PAIR - array<array-key,scalar|null>
return new Union([
new TArray([
Type::getArrayKey(),
new Union([
new TScalar(),
new TNull(),
]),
]),
]);
case 3: // PDO::FETCH_NUM - list<scalar|null>|false
return new Union([
Type::getListAtomic(
@ -199,7 +223,7 @@ class PdoStatementReturnTypeProvider implements MethodReturnTypeProviderInterfac
new TNull(),
]),
]),
]),
])
),
]);
@ -214,7 +238,7 @@ class PdoStatementReturnTypeProvider implements MethodReturnTypeProviderInterfac
new TNull(),
]),
]),
]),
])
),
]);
@ -225,27 +249,27 @@ class PdoStatementReturnTypeProvider implements MethodReturnTypeProviderInterfac
),
]);
case 7: // PDO::FETCH_COLUMN - scalar|null|false
return new Union([
Type::getListAtomic(
new Union([
new TScalar(),
new TNull(),
new TFalse(),
])
),
]);
case 8: // PDO::FETCH_CLASS - list<object>
return new Union([
Type::getListAtomic(
new Union([
$fetch_class_name ? new TNamedObject($fetch_class_name) : new TObject()
]),
])
),
]);
case 1: // PDO::FETCH_LAZY - list<object>
// This actually returns a PDORow object, but that class is
// undocumented, and its attributes are all dynamic anyway
return new Union([
Type::getListAtomic(
new Union([
new TObject()
]),
),
]);
case 11: // PDO::FETCH_NAMED - list<array<string, scalar|list<scalar>>>
case 11: // PDO::FETCH_NAMED - list<array<string, scalar|null|list<scalar|null>>>
return new Union([
Type::getListAtomic(
new Union([
@ -253,13 +277,30 @@ class PdoStatementReturnTypeProvider implements MethodReturnTypeProviderInterfac
Type::getString(),
new Union([
new TScalar(),
Type::getListAtomic(Type::getScalar()),
new TNull(),
Type::getListAtomic(
new Union([
new TScalar(),
new TNull(),
])
),
]),
]),
]),
])
),
]);
case 12: // PDO::FETCH_KEY_PAIR - array<array-key,scalar|null>
return new Union([
new TArray([
Type::getArrayKey(),
new Union([
new TScalar(),
new TNull(),
]),
]),
]);
case 3: // PDO::FETCH_NUM - list<list<scalar|null>>
return new Union([
Type::getListAtomic(
@ -268,9 +309,9 @@ class PdoStatementReturnTypeProvider implements MethodReturnTypeProviderInterfac
new Union([
new TScalar(),
new TNull(),
]),
])
),
]),
])
),
]);
@ -279,7 +320,7 @@ class PdoStatementReturnTypeProvider implements MethodReturnTypeProviderInterfac
Type::getListAtomic(
new Union([
new TNamedObject('stdClass')
]),
])
),
]);
}

View File

@ -622,6 +622,46 @@ class MethodCallTest extends TestCase
return $foo;
}',
],
'pdoStatementFetchColumn' => [
'code' => '<?php
/** @return scalar|null|false */
function fetch_column() {
$p = new PDO("sqlite::memory:");
$sth = $p->prepare("SELECT 1");
$sth->execute();
return $sth->fetch(PDO::FETCH_COLUMN);
}',
],
'pdoStatementFetchAllColumn' => [
'code' => '<?php
/** @return list<scalar|null> */
function fetch_column() {
$p = new PDO("sqlite::memory:");
$sth = $p->prepare("SELECT 1");
$sth->execute();
return $sth->fetchAll(PDO::FETCH_COLUMN);
}',
],
'pdoStatementFetchKeyPair' => [
'code' => '<?php
/** @return array<array-key,scalar|null> */
function fetch_column() {
$p = new PDO("sqlite::memory:");
$sth = $p->prepare("SELECT 1");
$sth->execute();
return $sth->fetch(PDO::FETCH_KEY_PAIR);
}',
],
'pdoStatementFetchAllKeyPair' => [
'code' => '<?php
/** @return array<array-key,scalar|null> */
function fetch_column() {
$p = new PDO("sqlite::memory:");
$sth = $p->prepare("SELECT 1");
$sth->execute();
return $sth->fetchAll(PDO::FETCH_KEY_PAIR);
}',
],
'pdoStatementFetchAssoc' => [
'code' => '<?php
/** @return array<string,null|scalar>|false */
@ -724,19 +764,9 @@ class MethodCallTest extends TestCase
return $sth->fetch(PDO::FETCH_LAZY);
}',
],
'pdoStatementFetchAllLazy' => [
'code' => '<?php
/** @return list<object> */
function fetch_lazy() : array {
$p = new PDO("sqlite::memory:");
$sth = $p->prepare("SELECT 1");
$sth->execute();
return $sth->fetchAll(PDO::FETCH_LAZY);
}',
],
'pdoStatementFetchNamed' => [
'code' => '<?php
/** @return array<string,scalar|list<scalar>>|false */
/** @return array<string,scalar|null|list<scalar|null>>|false */
function fetch_named() {
$p = new PDO("sqlite::memory:");
$sth = $p->prepare("SELECT 1");
@ -746,7 +776,7 @@ class MethodCallTest extends TestCase
],
'pdoStatementFetchAllNamed' => [
'code' => '<?php
/** @return list<array<string,scalar|list<scalar>>> */
/** @return list<array<string,scalar|null|list<scalar|null>>> */
function fetch_named() : array {
$p = new PDO("sqlite::memory:");
$sth = $p->prepare("SELECT 1");