Skip to content

Commit 42678c7

Browse files
staabmclxmstaab
andauthored
support array-bound values to support IN(:param) expressions (#152)
Co-authored-by: Markus Staab <[email protected]>
1 parent d7d4e1b commit 42678c7

File tree

5 files changed

+255
-0
lines changed

5 files changed

+255
-0
lines changed

.phpstan-dba.cache

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -950,6 +950,78 @@
950950
)),
951951
),
952952
),
953+
'SELECT adaid FROM ada WHERE adaid IN (\'1\')' =>
954+
array (
955+
'error' => NULL,
956+
'result' =>
957+
array (
958+
3 =>
959+
PHPStan\Type\Constant\ConstantArrayType::__set_state(array(
960+
'keyType' =>
961+
PHPStan\Type\UnionType::__set_state(array(
962+
'types' =>
963+
array (
964+
0 =>
965+
PHPStan\Type\Constant\ConstantIntegerType::__set_state(array(
966+
'value' => 0,
967+
)),
968+
1 =>
969+
PHPStan\Type\Constant\ConstantStringType::__set_state(array(
970+
'value' => 'adaid',
971+
'isClassString' => false,
972+
)),
973+
),
974+
)),
975+
'itemType' =>
976+
PHPStan\Type\IntegerRangeType::__set_state(array(
977+
'min' => 0,
978+
'max' => 4294967295,
979+
)),
980+
'allArrays' => NULL,
981+
'keyTypes' =>
982+
array (
983+
0 =>
984+
PHPStan\Type\Constant\ConstantStringType::__set_state(array(
985+
'value' => 'adaid',
986+
'isClassString' => false,
987+
)),
988+
1 =>
989+
PHPStan\Type\Constant\ConstantIntegerType::__set_state(array(
990+
'value' => 0,
991+
)),
992+
),
993+
'valueTypes' =>
994+
array (
995+
0 =>
996+
PHPStan\Type\IntegerRangeType::__set_state(array(
997+
'min' => 0,
998+
'max' => 4294967295,
999+
)),
1000+
1 =>
1001+
PHPStan\Type\IntegerRangeType::__set_state(array(
1002+
'min' => 0,
1003+
'max' => 4294967295,
1004+
)),
1005+
),
1006+
'nextAutoIndex' => 1,
1007+
'optionalKeys' =>
1008+
array (
1009+
),
1010+
)),
1011+
),
1012+
),
1013+
'SELECT adaid FROM ada WHERE adaid IN (:adaids)' =>
1014+
array (
1015+
'error' =>
1016+
staabm\PHPStanDba\Error::__set_state(array(
1017+
'message' => 'You have an error in your SQL syntax; check the manual that corresponds to your MySQL/MariaDB server version for the right syntax to use near \':adaids) LIMIT 0\' at line 1',
1018+
'code' => 1064,
1019+
)),
1020+
'result' =>
1021+
array (
1022+
3 => NULL,
1023+
),
1024+
),
9531025
'SELECT adaid FROM ada WHERE email LIKE ' =>
9541026
array (
9551027
'error' =>
@@ -1850,6 +1922,72 @@
18501922
)),
18511923
),
18521924
),
1925+
'SELECT email FROM ada WHERE adaid IN (\'1\')' =>
1926+
array (
1927+
'error' => NULL,
1928+
'result' =>
1929+
array (
1930+
3 =>
1931+
PHPStan\Type\Constant\ConstantArrayType::__set_state(array(
1932+
'keyType' =>
1933+
PHPStan\Type\UnionType::__set_state(array(
1934+
'types' =>
1935+
array (
1936+
0 =>
1937+
PHPStan\Type\Constant\ConstantIntegerType::__set_state(array(
1938+
'value' => 0,
1939+
)),
1940+
1 =>
1941+
PHPStan\Type\Constant\ConstantStringType::__set_state(array(
1942+
'value' => 'email',
1943+
'isClassString' => false,
1944+
)),
1945+
),
1946+
)),
1947+
'itemType' =>
1948+
PHPStan\Type\StringType::__set_state(array(
1949+
)),
1950+
'allArrays' => NULL,
1951+
'keyTypes' =>
1952+
array (
1953+
0 =>
1954+
PHPStan\Type\Constant\ConstantStringType::__set_state(array(
1955+
'value' => 'email',
1956+
'isClassString' => false,
1957+
)),
1958+
1 =>
1959+
PHPStan\Type\Constant\ConstantIntegerType::__set_state(array(
1960+
'value' => 0,
1961+
)),
1962+
),
1963+
'valueTypes' =>
1964+
array (
1965+
0 =>
1966+
PHPStan\Type\StringType::__set_state(array(
1967+
)),
1968+
1 =>
1969+
PHPStan\Type\StringType::__set_state(array(
1970+
)),
1971+
),
1972+
'nextAutoIndex' => 1,
1973+
'optionalKeys' =>
1974+
array (
1975+
),
1976+
)),
1977+
),
1978+
),
1979+
'SELECT email FROM ada WHERE adaid IN (:adaids)' =>
1980+
array (
1981+
'error' =>
1982+
staabm\PHPStanDba\Error::__set_state(array(
1983+
'message' => 'You have an error in your SQL syntax; check the manual that corresponds to your MySQL/MariaDB server version for the right syntax to use near \':adaids) LIMIT 0\' at line 1',
1984+
'code' => 1064,
1985+
)),
1986+
'result' =>
1987+
array (
1988+
3 => NULL,
1989+
),
1990+
),
18531991
'SELECT email adaid WHERE gesperrt freigabe1u1 FROM ada' =>
18541992
array (
18551993
'error' =>

.phpunit-phpstan-dba.cache

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,6 +1009,78 @@
10091009
)),
10101010
),
10111011
),
1012+
'SELECT adaid FROM ada WHERE adaid IN (\'1\')' =>
1013+
array (
1014+
'error' => NULL,
1015+
'result' =>
1016+
array (
1017+
3 =>
1018+
PHPStan\Type\Constant\ConstantArrayType::__set_state(array(
1019+
'keyType' =>
1020+
PHPStan\Type\UnionType::__set_state(array(
1021+
'types' =>
1022+
array (
1023+
0 =>
1024+
PHPStan\Type\Constant\ConstantIntegerType::__set_state(array(
1025+
'value' => 0,
1026+
)),
1027+
1 =>
1028+
PHPStan\Type\Constant\ConstantStringType::__set_state(array(
1029+
'value' => 'adaid',
1030+
'isClassString' => false,
1031+
)),
1032+
),
1033+
)),
1034+
'itemType' =>
1035+
PHPStan\Type\IntegerRangeType::__set_state(array(
1036+
'min' => 0,
1037+
'max' => 4294967295,
1038+
)),
1039+
'allArrays' => NULL,
1040+
'keyTypes' =>
1041+
array (
1042+
0 =>
1043+
PHPStan\Type\Constant\ConstantStringType::__set_state(array(
1044+
'value' => 'adaid',
1045+
'isClassString' => false,
1046+
)),
1047+
1 =>
1048+
PHPStan\Type\Constant\ConstantIntegerType::__set_state(array(
1049+
'value' => 0,
1050+
)),
1051+
),
1052+
'valueTypes' =>
1053+
array (
1054+
0 =>
1055+
PHPStan\Type\IntegerRangeType::__set_state(array(
1056+
'min' => 0,
1057+
'max' => 4294967295,
1058+
)),
1059+
1 =>
1060+
PHPStan\Type\IntegerRangeType::__set_state(array(
1061+
'min' => 0,
1062+
'max' => 4294967295,
1063+
)),
1064+
),
1065+
'nextAutoIndex' => 1,
1066+
'optionalKeys' =>
1067+
array (
1068+
),
1069+
)),
1070+
),
1071+
),
1072+
'SELECT adaid FROM ada WHERE adaid IN (:adaids)' =>
1073+
array (
1074+
'error' =>
1075+
staabm\PHPStanDba\Error::__set_state(array(
1076+
'message' => 'You have an error in your SQL syntax; check the manual that corresponds to your MySQL/MariaDB server version for the right syntax to use near \':adaids) LIMIT 0\' at line 1',
1077+
'code' => 1064,
1078+
)),
1079+
'result' =>
1080+
array (
1081+
3 => NULL,
1082+
),
1083+
),
10121084
'SELECT adaid FROM ada WHERE email LIKE ":gesperrt%"' =>
10131085
array (
10141086
'error' => NULL,
@@ -1579,6 +1651,30 @@
15791651
)),
15801652
),
15811653
),
1654+
'SELECT email FROM ada WHERE adaid IN (\'1\')' =>
1655+
array (
1656+
'error' => NULL,
1657+
),
1658+
'SELECT email FROM ada WHERE adaid IN (:adaids)' =>
1659+
array (
1660+
'error' =>
1661+
staabm\PHPStanDba\Error::__set_state(array(
1662+
'message' => 'You have an error in your SQL syntax; check the manual that corresponds to your MySQL/MariaDB server version for the right syntax to use near \':adaids) LIMIT 0\' at line 1',
1663+
'code' => 1064,
1664+
)),
1665+
'result' =>
1666+
array (
1667+
3 => NULL,
1668+
),
1669+
),
1670+
'SELECT email FROM ada WHERE adaids IN (\'1\')' =>
1671+
array (
1672+
'error' =>
1673+
staabm\PHPStanDba\Error::__set_state(array(
1674+
'message' => 'Unknown column \'adaids\' in \'where clause\'',
1675+
'code' => 1054,
1676+
)),
1677+
),
15821678
'SELECT email adaid WHERE gesperrt freigabe1u1 FROM ada' =>
15831679
array (
15841680
'error' =>

src/QueryReflection/QuerySimulation.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace staabm\PHPStanDba\QueryReflection;
66

77
use PHPStan\Type\BooleanType;
8+
use PHPStan\Type\Constant\ConstantArrayType;
89
use PHPStan\Type\ConstantScalarType;
910
use PHPStan\Type\FloatType;
1011
use PHPStan\Type\IntegerType;
@@ -27,6 +28,12 @@ public static function simulateParamValueType(Type $paramType): ?string
2728
return (string) $paramType->getValue();
2829
}
2930

31+
if ($paramType instanceof ConstantArrayType) {
32+
$valueTypes = $paramType->getValueTypes();
33+
34+
return self::simulateParamValueType($valueTypes[0]);
35+
}
36+
3037
$integerType = new IntegerType();
3138
if ($integerType->isSuperTypeOf($paramType)->yes()) {
3239
return '1';

tests/data/pdo-prepare.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,12 @@ public function placeholderInData(PDO $pdo)
7373
$stmt->execute();
7474
assertType('PDOStatement<array{adaid: int<0, 4294967295>, 0: int<0, 4294967295>}>', $stmt);
7575
}
76+
77+
public function arrayParam(PDO $pdo)
78+
{
79+
$query = 'SELECT adaid FROM ada WHERE adaid IN (:adaids)';
80+
$stmt = $pdo->prepare($query);
81+
$stmt->execute(['adaids' => [1, 2, 3]]);
82+
assertType('PDOStatement<array{adaid: int<0, 4294967295>, 0: int<0, 4294967295>}>', $stmt);
83+
}
7684
}

tests/data/syntax-error-in-prepared-statement.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,4 +167,10 @@ public function noErrorOnPlaceholderInData(Connection $connection)
167167
$query = "SELECT adaid FROM ada WHERE email LIKE 'some strange string - :gesperrt it is'";
168168
$connection->preparedQuery($query, []);
169169
}
170+
171+
public function arrayParam(Connection $connection)
172+
{
173+
$query = 'SELECT email FROM ada WHERE adaid IN (:adaids)';
174+
$connection->preparedQuery($query, ['adaids' => [1, 2, 3]]);
175+
}
170176
}

0 commit comments

Comments
 (0)