2525use PHPStan \Platform \Entity \PlatformEntity ;
2626use PHPStan \Platform \Entity \PlatformRelatedEntity ;
2727use PHPStan \Testing \PHPStanTestCase ;
28+ use PHPStan \Type \Accessory \AccessoryLowercaseStringType ;
2829use PHPStan \Type \Accessory \AccessoryNumericStringType ;
30+ use PHPStan \Type \Accessory \AccessoryUppercaseStringType ;
2931use PHPStan \Type \BooleanType ;
3032use PHPStan \Type \Constant \ConstantBooleanType ;
3133use PHPStan \Type \Constant \ConstantFloatType ;
@@ -1949,7 +1951,7 @@ public static function provideCases(): iterable
19491951 yield 'COALESCE(t.col_decimal, t.col_decimal) + int data ' => [
19501952 'data ' => self ::dataAllIntLike (),
19511953 'select ' => 'SELECT COALESCE(t.col_decimal, t.col_decimal) FROM %s t ' ,
1952- 'mysql ' => self ::numericString (),
1954+ 'mysql ' => self ::numericString (false , true ),
19531955 'sqlite ' => self ::floatOrInt (),
19541956 'pdo_pgsql ' => self ::numericString (),
19551957 'pgsql ' => self ::numericString (),
@@ -1997,11 +1999,11 @@ public static function provideCases(): iterable
19971999 yield 't.col_decimal ' => [
19982000 'data ' => self ::dataDefault (),
19992001 'select ' => 'SELECT t.col_decimal FROM %s t ' ,
2000- 'mysql ' => self ::numericString (),
2001- 'sqlite ' => self ::numericString (),
2002- 'pdo_pgsql ' => self ::numericString (),
2003- 'pgsql ' => self ::numericString (),
2004- 'mssql ' => self ::numericString (),
2002+ 'mysql ' => self ::numericString (false , true ),
2003+ 'sqlite ' => self ::numericString (false , true ),
2004+ 'pdo_pgsql ' => self ::numericString (false , true ),
2005+ 'pgsql ' => self ::numericString (false , true ),
2006+ 'mssql ' => self ::numericString (false , true ),
20052007 'mysqlResult ' => '0.1 ' ,
20062008 'sqliteResult ' => '0.1 ' ,
20072009 'pdoPgsqlResult ' => '0.1 ' ,
@@ -2029,11 +2031,11 @@ public static function provideCases(): iterable
20292031 yield 't.col_bigint ' => [
20302032 'data ' => self ::dataDefault (),
20312033 'select ' => 'SELECT t.col_bigint FROM %s t ' ,
2032- 'mysql ' => self ::hasDbal4 () ? self ::int () : self ::numericString (),
2033- 'sqlite ' => self ::hasDbal4 () ? self ::int () : self ::numericString (),
2034- 'pdo_pgsql ' => self ::hasDbal4 () ? self ::int () : self ::numericString (),
2035- 'pgsql ' => self ::hasDbal4 () ? self ::int () : self ::numericString (),
2036- 'mssql ' => self ::hasDbal4 () ? self ::int () : self ::numericString (),
2034+ 'mysql ' => self ::hasDbal4 () ? self ::int () : self ::numericString (true , true ),
2035+ 'sqlite ' => self ::hasDbal4 () ? self ::int () : self ::numericString (true , true ),
2036+ 'pdo_pgsql ' => self ::hasDbal4 () ? self ::int () : self ::numericString (true , true ),
2037+ 'pgsql ' => self ::hasDbal4 () ? self ::int () : self ::numericString (true , true ),
2038+ 'mssql ' => self ::hasDbal4 () ? self ::int () : self ::numericString (true , true ),
20372039 'mysqlResult ' => self ::hasDbal4 () ? 2147483648 : '2147483648 ' ,
20382040 'sqliteResult ' => self ::hasDbal4 () ? 2147483648 : '2147483648 ' ,
20392041 'pdoPgsqlResult ' => self ::hasDbal4 () ? 2147483648 : '2147483648 ' ,
@@ -2141,10 +2143,10 @@ public static function provideCases(): iterable
21412143 yield 'AVG(t.col_decimal) + int data ' => [
21422144 'data ' => self ::dataAllIntLike (),
21432145 'select ' => 'SELECT AVG(t.col_decimal) FROM %s t ' ,
2144- 'mysql ' => self ::numericStringOrNull (),
2146+ 'mysql ' => self ::numericStringOrNull (false , true ),
21452147 'sqlite ' => self ::floatOrNull (),
2146- 'pdo_pgsql ' => self ::numericStringOrNull (),
2147- 'pgsql ' => self ::numericStringOrNull (),
2148+ 'pdo_pgsql ' => self ::numericStringOrNull (false , true ),
2149+ 'pgsql ' => self ::numericStringOrNull (false , true ),
21482150 'mssql ' => self ::mixed (),
21492151 'mysqlResult ' => '1.00000 ' ,
21502152 'sqliteResult ' => 1.0 ,
@@ -2173,10 +2175,10 @@ public static function provideCases(): iterable
21732175 yield 'AVG(t.col_int) ' => [
21742176 'data ' => self ::dataDefault (),
21752177 'select ' => 'SELECT AVG(t.col_int) FROM %s t ' ,
2176- 'mysql ' => self ::numericStringOrNull (),
2178+ 'mysql ' => self ::numericStringOrNull (false , true ),
21772179 'sqlite ' => self ::floatOrNull (),
2178- 'pdo_pgsql ' => self ::numericStringOrNull (),
2179- 'pgsql ' => self ::numericStringOrNull (),
2180+ 'pdo_pgsql ' => self ::numericStringOrNull (false , true ),
2181+ 'pgsql ' => self ::numericStringOrNull (false , true ),
21802182 'mssql ' => self ::mixed (),
21812183 'mysqlResult ' => '9.0000 ' ,
21822184 'sqliteResult ' => 9.0 ,
@@ -2189,7 +2191,7 @@ public static function provideCases(): iterable
21892191 yield 'AVG(t.col_bool) ' => [
21902192 'data ' => self ::dataDefault (),
21912193 'select ' => 'SELECT AVG(t.col_bool) FROM %s t ' ,
2192- 'mysql ' => self ::numericStringOrNull (),
2194+ 'mysql ' => self ::numericStringOrNull (false , true ),
21932195 'sqlite ' => self ::floatOrNull (),
21942196 'pdo_pgsql ' => null , // Undefined function
21952197 'pgsql ' => null , // Undefined function
@@ -2221,10 +2223,10 @@ public static function provideCases(): iterable
22212223 yield 'AVG(1) ' => [
22222224 'data ' => self ::dataDefault (),
22232225 'select ' => 'SELECT AVG(1) FROM %s t ' ,
2224- 'mysql ' => self ::numericStringOrNull (),
2226+ 'mysql ' => self ::numericStringOrNull (false , true ),
22252227 'sqlite ' => self ::floatOrNull (),
2226- 'pdo_pgsql ' => self ::numericStringOrNull (),
2227- 'pgsql ' => self ::numericStringOrNull (),
2228+ 'pdo_pgsql ' => self ::numericStringOrNull (false , true ),
2229+ 'pgsql ' => self ::numericStringOrNull (false , true ),
22282230 'mssql ' => self ::mixed (),
22292231 'mysqlResult ' => '1.0000 ' ,
22302232 'sqliteResult ' => 1.0 ,
@@ -2429,10 +2431,10 @@ public static function provideCases(): iterable
24292431 yield 'SUM(t.col_decimal) ' => [
24302432 'data ' => self ::dataDefault (),
24312433 'select ' => 'SELECT SUM(t.col_decimal) FROM %s t ' ,
2432- 'mysql ' => self ::numericStringOrNull (),
2434+ 'mysql ' => self ::numericStringOrNull (false , true ),
24332435 'sqlite ' => self ::floatOrIntOrNull (),
2434- 'pdo_pgsql ' => self ::numericStringOrNull (),
2435- 'pgsql ' => self ::numericStringOrNull (),
2436+ 'pdo_pgsql ' => self ::numericStringOrNull (false , true ),
2437+ 'pgsql ' => self ::numericStringOrNull (false , true ),
24362438 'mssql ' => self ::mixed (),
24372439 'mysqlResult ' => '0.1 ' ,
24382440 'sqliteResult ' => 0.1 ,
@@ -2445,10 +2447,10 @@ public static function provideCases(): iterable
24452447 yield 'SUM(t.col_decimal) + int data ' => [
24462448 'data ' => self ::dataAllIntLike (),
24472449 'select ' => 'SELECT SUM(t.col_decimal) FROM %s t ' ,
2448- 'mysql ' => self ::numericStringOrNull (),
2450+ 'mysql ' => self ::numericStringOrNull (false , true ),
24492451 'sqlite ' => self ::floatOrIntOrNull (),
2450- 'pdo_pgsql ' => self ::numericStringOrNull (),
2451- 'pgsql ' => self ::numericStringOrNull (),
2452+ 'pdo_pgsql ' => self ::numericStringOrNull (false , true ),
2453+ 'pgsql ' => self ::numericStringOrNull (false , true ),
24522454 'mssql ' => self ::mixed (),
24532455 'mysqlResult ' => '1.0 ' ,
24542456 'sqliteResult ' => 1 ,
@@ -2749,10 +2751,10 @@ public static function provideCases(): iterable
27492751 yield 'MAX(t.col_decimal) ' => [
27502752 'data ' => self ::dataDefault (),
27512753 'select ' => 'SELECT MAX(t.col_decimal) FROM %s t ' ,
2752- 'mysql ' => self ::numericStringOrNull (),
2754+ 'mysql ' => self ::numericStringOrNull (false , true ),
27532755 'sqlite ' => self ::floatOrIntOrNull (),
2754- 'pdo_pgsql ' => self ::numericStringOrNull (),
2755- 'pgsql ' => self ::numericStringOrNull (),
2756+ 'pdo_pgsql ' => self ::numericStringOrNull (false , true ),
2757+ 'pgsql ' => self ::numericStringOrNull (false , true ),
27562758 'mssql ' => self ::mixed (),
27572759 'mysqlResult ' => '0.1 ' ,
27582760 'sqliteResult ' => 0.1 ,
@@ -2765,10 +2767,10 @@ public static function provideCases(): iterable
27652767 yield 'MAX(t.col_decimal) + int data ' => [
27662768 'data ' => self ::dataAllIntLike (),
27672769 'select ' => 'SELECT MAX(t.col_decimal) FROM %s t ' ,
2768- 'mysql ' => self ::numericStringOrNull (),
2770+ 'mysql ' => self ::numericStringOrNull (false , true ),
27692771 'sqlite ' => self ::floatOrIntOrNull (),
2770- 'pdo_pgsql ' => self ::numericStringOrNull (),
2771- 'pgsql ' => self ::numericStringOrNull (),
2772+ 'pdo_pgsql ' => self ::numericStringOrNull (false , true ),
2773+ 'pgsql ' => self ::numericStringOrNull (false , true ),
27722774 'mssql ' => self ::mixed (),
27732775 'mysqlResult ' => '1.0 ' ,
27742776 'sqliteResult ' => 1 ,
@@ -2989,10 +2991,10 @@ public static function provideCases(): iterable
29892991 yield 'ABS(t.col_decimal) ' => [
29902992 'data ' => self ::dataDefault (),
29912993 'select ' => 'SELECT ABS(t.col_decimal) FROM %s t ' ,
2992- 'mysql ' => self ::numericString (),
2994+ 'mysql ' => self ::numericString (false , true ),
29932995 'sqlite ' => self ::floatOrInt (),
2994- 'pdo_pgsql ' => self ::numericString (),
2995- 'pgsql ' => self ::numericString (),
2996+ 'pdo_pgsql ' => self ::numericString (false , true ),
2997+ 'pgsql ' => self ::numericString (false , true ),
29962998 'mssql ' => self ::mixed (),
29972999 'mysqlResult ' => '0.1 ' ,
29983000 'sqliteResult ' => 0.1 ,
@@ -3005,10 +3007,10 @@ public static function provideCases(): iterable
30053007 yield 'ABS(t.col_decimal) + int data ' => [
30063008 'data ' => self ::dataAllIntLike (),
30073009 'select ' => 'SELECT ABS(t.col_decimal) FROM %s t ' ,
3008- 'mysql ' => self ::numericString (),
3010+ 'mysql ' => self ::numericString (false , true ),
30093011 'sqlite ' => self ::floatOrInt (),
3010- 'pdo_pgsql ' => self ::numericString (),
3011- 'pgsql ' => self ::numericString (),
3012+ 'pdo_pgsql ' => self ::numericString (false , true ),
3013+ 'pgsql ' => self ::numericString (false , true ),
30123014 'mssql ' => self ::mixed (),
30133015 'mysqlResult ' => '1.0 ' ,
30143016 'sqliteResult ' => 1 ,
@@ -4319,10 +4321,10 @@ public static function provideCases(): iterable
43194321 yield 'COALESCE(t.col_int_nullable, t.col_decimal_nullable, 0) ' => [
43204322 'data ' => self ::dataDefault (),
43214323 'select ' => 'SELECT COALESCE(t.col_int_nullable, t.col_decimal_nullable, 0) FROM %s t ' ,
4322- 'mysql ' => self ::numericString (),
4324+ 'mysql ' => self ::numericString (false , true ),
43234325 'sqlite ' => TypeCombinator::union (self ::float (), self ::int ()),
4324- 'pdo_pgsql ' => TypeCombinator::union (self ::numericString (), self ::int ()),
4325- 'pgsql ' => TypeCombinator::union (self ::numericString (), self ::int ()),
4326+ 'pdo_pgsql ' => TypeCombinator::union (self ::numericString (false , true ), self ::int ()),
4327+ 'pgsql ' => TypeCombinator::union (self ::numericString (false , true ), self ::int ()),
43264328 'mssql ' => self ::mixed (),
43274329 'mysqlResult ' => '0.0 ' ,
43284330 'sqliteResult ' => 0 ,
@@ -4338,9 +4340,9 @@ public static function provideCases(): iterable
43384340 'mysql ' => self ::float (),
43394341 'sqlite ' => TypeCombinator::union (self ::float (), self ::int ()),
43404342 'pdo_pgsql ' => PHP_VERSION_ID < 80400
4341- ? TypeCombinator::union (self ::numericString (), self ::int ())
4342- : TypeCombinator::union (self ::numericString (), self ::int (), self ::float ()),
4343- 'pgsql ' => TypeCombinator::union (self ::numericString (), self ::int (), self ::float ()),
4343+ ? TypeCombinator::union (self ::numericString (false , true ), self ::int ())
4344+ : TypeCombinator::union (self ::numericString (false , true ), self ::int (), self ::float ()),
4345+ 'pgsql ' => TypeCombinator::union (self ::numericString (false , true ), self ::int (), self ::float ()),
43444346 'mssql ' => self ::mixed (),
43454347 'mysqlResult ' => 0.0 ,
43464348 'sqliteResult ' => 0 ,
@@ -4356,9 +4358,9 @@ public static function provideCases(): iterable
43564358 'mysql ' => self ::float (),
43574359 'sqlite ' => TypeCombinator::union (self ::float (), self ::int ()),
43584360 'pdo_pgsql ' => PHP_VERSION_ID < 80400
4359- ? TypeCombinator::union (self ::numericString (), self ::int ())
4360- : TypeCombinator::union (self ::numericString (), self ::int (), self ::float ()),
4361- 'pgsql ' => TypeCombinator::union (self ::numericString (), self ::int (), self ::float ()),
4361+ ? TypeCombinator::union (self ::numericString (false , true ), self ::int ())
4362+ : TypeCombinator::union (self ::numericString (false , true ), self ::int (), self ::float ()),
4363+ 'pgsql ' => TypeCombinator::union (self ::numericString (false , true ), self ::int (), self ::float ()),
43624364 'mssql ' => self ::mixed (),
43634365 'mysqlResult ' => 0.0 ,
43644366 'sqliteResult ' => 0.0 ,
@@ -4374,9 +4376,9 @@ public static function provideCases(): iterable
43744376 'mysql ' => self ::float (),
43754377 'sqlite ' => TypeCombinator::union (self ::float (), self ::int ()),
43764378 'pdo_pgsql ' => PHP_VERSION_ID < 80400
4377- ? TypeCombinator::union (self ::numericString (), self ::int ())
4378- : TypeCombinator::union (self ::numericString (), self ::int (), self ::float ()),
4379- 'pgsql ' => TypeCombinator::union (self ::numericString (), self ::int (), self ::float ()),
4379+ ? TypeCombinator::union (self ::numericString (false , true ), self ::int ())
4380+ : TypeCombinator::union (self ::numericString (false , true ), self ::int (), self ::float ()),
4381+ 'pgsql ' => TypeCombinator::union (self ::numericString (false , true ), self ::int (), self ::float ()),
43804382 'mssql ' => self ::mixed (),
43814383 'mysqlResult ' => 0.0 ,
43824384 'sqliteResult ' => 0.0 ,
@@ -4389,12 +4391,12 @@ public static function provideCases(): iterable
43894391 yield "COALESCE(t.col_int_nullable, t.col_decimal_nullable, t.col_float_nullable, '0') " => [
43904392 'data ' => self ::dataDefault (),
43914393 'select ' => 'SELECT COALESCE(t.col_int_nullable, t.col_decimal_nullable, t.col_float_nullable, \'0 \') FROM %s t ' ,
4392- 'mysql ' => self ::numericString (),
4394+ 'mysql ' => self ::numericString (false , true ),
43934395 'sqlite ' => TypeCombinator::union (self ::float (), self ::int (), self ::numericString ()),
43944396 'pdo_pgsql ' => PHP_VERSION_ID < 80400
4395- ? TypeCombinator::union (self ::numericString (), self ::int ())
4396- : TypeCombinator::union (self ::numericString (), self ::int (), self ::float ()),
4397- 'pgsql ' => TypeCombinator::union (self ::numericString (), self ::int (), self ::float ()),
4397+ ? TypeCombinator::union (self ::numericString (false , true ), self ::int ())
4398+ : TypeCombinator::union (self ::numericString (false , true ), self ::int (), self ::float ()),
4399+ 'pgsql ' => TypeCombinator::union (self ::numericString (false , true ), self ::int (), self ::float ()),
43984400 'mssql ' => self ::mixed (),
43994401 'mysqlResult ' => '0 ' ,
44004402 'sqliteResult ' => '0 ' ,
@@ -4842,25 +4844,30 @@ private static function boolOrNull(): Type
48424844 return TypeCombinator::addNull (new BooleanType ());
48434845 }
48444846
4845- private static function numericString (): Type
4847+ private static function numericString (bool $ lowercase = false , bool $ uppercase = false ): Type
48464848 {
4847- return new IntersectionType ( [
4849+ $ types = [
48484850 new StringType (),
48494851 new AccessoryNumericStringType (),
4850- ]);
4852+ ];
4853+ if ($ lowercase ) {
4854+ $ types [] = new AccessoryLowercaseStringType ();
4855+ }
4856+ if ($ uppercase ) {
4857+ $ types [] = new AccessoryUppercaseStringType ();
4858+ }
4859+
4860+ return new IntersectionType ($ types );
48514861 }
48524862
48534863 private static function string (): Type
48544864 {
48554865 return new StringType ();
48564866 }
48574867
4858- private static function numericStringOrNull (): Type
4868+ private static function numericStringOrNull (bool $ lowercase = false , bool $ uppercase = false ): Type
48594869 {
4860- return TypeCombinator::addNull (new IntersectionType ([
4861- new StringType (),
4862- new AccessoryNumericStringType (),
4863- ]));
4870+ return TypeCombinator::addNull (self ::numericString ($ lowercase , $ uppercase ));
48644871 }
48654872
48664873 private static function int (): Type
0 commit comments