Skip to content

Commit 6439355

Browse files
committed
WIP
1 parent f6a34b3 commit 6439355

33 files changed

+425
-55
lines changed

Diff for: src/Type/Doctrine/DescriptorRegistry.php

+11
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ public function __construct(array $descriptors)
2121
}
2222
}
2323

24+
/**
25+
* @throws DescriptorNotRegisteredException
26+
*/
2427
public function get(string $type): DoctrineTypeDescriptor
2528
{
2629
$typesMap = Type::getTypesMap();
@@ -36,4 +39,12 @@ public function get(string $type): DoctrineTypeDescriptor
3639
return $this->descriptors[$typeClass];
3740
}
3841

42+
public function getByClassName(string $className): DoctrineTypeDescriptor
43+
{
44+
if (!isset($this->descriptors[$className])) {
45+
throw new DescriptorNotRegisteredException();
46+
}
47+
return $this->descriptors[$className];
48+
}
49+
3950
}

Diff for: src/Type/Doctrine/Descriptors/ArrayType.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace PHPStan\Type\Doctrine\Descriptors;
44

5+
use Doctrine\DBAL\Driver;
56
use PHPStan\Type\MixedType;
67
use PHPStan\Type\StringType;
78
use PHPStan\Type\Type;
@@ -24,7 +25,7 @@ public function getWritableToDatabaseType(): Type
2425
return new \PHPStan\Type\ArrayType(new MixedType(), new MixedType());
2526
}
2627

27-
public function getDatabaseInternalType(): Type
28+
public function getDatabaseInternalType(Driver $driver): Type
2829
{
2930
return new StringType();
3031
}

Diff for: src/Type/Doctrine/Descriptors/AsciiStringType.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace PHPStan\Type\Doctrine\Descriptors;
44

5+
use Doctrine\DBAL\Driver;
56
use PHPStan\Type\StringType;
67
use PHPStan\Type\Type;
78

@@ -23,7 +24,7 @@ public function getWritableToDatabaseType(): Type
2324
return new StringType();
2425
}
2526

26-
public function getDatabaseInternalType(): Type
27+
public function getDatabaseInternalType(Driver $driver): Type
2728
{
2829
return new StringType();
2930
}

Diff for: src/Type/Doctrine/Descriptors/BigIntType.php

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace PHPStan\Type\Doctrine\Descriptors;
44

5+
use Doctrine\DBAL\Driver;
56
use PHPStan\Type\Accessory\AccessoryNumericStringType;
67
use PHPStan\Type\IntegerType;
78
use PHPStan\Type\StringType;
@@ -23,10 +24,10 @@ public function getWritableToPropertyType(): Type
2324

2425
public function getWritableToDatabaseType(): Type
2526
{
26-
return TypeCombinator::union(new StringType(), new IntegerType());
27+
return TypeCombinator::union(new StringType());
2728
}
2829

29-
public function getDatabaseInternalType(): Type
30+
public function getDatabaseInternalType(Driver $driver): Type
3031
{
3132
return new IntegerType();
3233
}

Diff for: src/Type/Doctrine/Descriptors/BinaryType.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace PHPStan\Type\Doctrine\Descriptors;
44

5+
use Doctrine\DBAL\Driver;
56
use PHPStan\Type\MixedType;
67
use PHPStan\Type\ResourceType;
78
use PHPStan\Type\StringType;
@@ -25,7 +26,7 @@ public function getWritableToDatabaseType(): Type
2526
return new MixedType();
2627
}
2728

28-
public function getDatabaseInternalType(): Type
29+
public function getDatabaseInternalType(Driver $driver): Type
2930
{
3031
return new StringType();
3132
}

Diff for: src/Type/Doctrine/Descriptors/BlobType.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace PHPStan\Type\Doctrine\Descriptors;
44

5+
use Doctrine\DBAL\Driver;
56
use PHPStan\Type\MixedType;
67
use PHPStan\Type\ResourceType;
78
use PHPStan\Type\Type;
@@ -24,7 +25,7 @@ public function getWritableToDatabaseType(): Type
2425
return new MixedType();
2526
}
2627

27-
public function getDatabaseInternalType(): Type
28+
public function getDatabaseInternalType(Driver $driver): Type
2829
{
2930
return new MixedType();
3031
}

Diff for: src/Type/Doctrine/Descriptors/BooleanType.php

+8-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
namespace PHPStan\Type\Doctrine\Descriptors;
44

5+
use Doctrine\DBAL\Driver;
6+
use Doctrine\DBAL\Driver\PDO\PgSQL\Driver as PdoPgSQLDriver;
7+
use Doctrine\DBAL\Driver\PgSQL\Driver as PgSQLDriver;
58
use PHPStan\Type\Constant\ConstantIntegerType;
69
use PHPStan\Type\Type;
710
use PHPStan\Type\TypeCombinator;
@@ -24,8 +27,12 @@ public function getWritableToDatabaseType(): Type
2427
return new \PHPStan\Type\BooleanType();
2528
}
2629

27-
public function getDatabaseInternalType(): Type
30+
public function getDatabaseInternalType(Driver $driver): Type
2831
{
32+
if ($driver instanceof PgSQLDriver || $driver instanceof PdoPgSQLDriver) {
33+
return new \PHPStan\Type\BooleanType();
34+
}
35+
2936
return TypeCombinator::union(
3037
new ConstantIntegerType(0),
3138
new ConstantIntegerType(1)

Diff for: src/Type/Doctrine/Descriptors/DateImmutableType.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace PHPStan\Type\Doctrine\Descriptors;
44

55
use DateTimeImmutable;
6+
use Doctrine\DBAL\Driver;
67
use PHPStan\Type\ObjectType;
78
use PHPStan\Type\StringType;
89
use PHPStan\Type\Type;
@@ -25,7 +26,7 @@ public function getWritableToDatabaseType(): Type
2526
return new ObjectType(DateTimeImmutable::class);
2627
}
2728

28-
public function getDatabaseInternalType(): Type
29+
public function getDatabaseInternalType(Driver $driver): Type
2930
{
3031
return new StringType();
3132
}

Diff for: src/Type/Doctrine/Descriptors/DateIntervalType.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace PHPStan\Type\Doctrine\Descriptors;
44

55
use DateInterval;
6+
use Doctrine\DBAL\Driver;
67
use PHPStan\Type\ObjectType;
78
use PHPStan\Type\StringType;
89
use PHPStan\Type\Type;
@@ -25,7 +26,7 @@ public function getWritableToDatabaseType(): Type
2526
return new ObjectType(DateInterval::class);
2627
}
2728

28-
public function getDatabaseInternalType(): Type
29+
public function getDatabaseInternalType(Driver $driver): Type
2930
{
3031
return new StringType();
3132
}

Diff for: src/Type/Doctrine/Descriptors/DateTimeImmutableType.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace PHPStan\Type\Doctrine\Descriptors;
44

55
use DateTimeImmutable;
6+
use Doctrine\DBAL\Driver;
67
use PHPStan\Type\ObjectType;
78
use PHPStan\Type\StringType;
89
use PHPStan\Type\Type;
@@ -25,7 +26,7 @@ public function getWritableToDatabaseType(): Type
2526
return new ObjectType(DateTimeImmutable::class);
2627
}
2728

28-
public function getDatabaseInternalType(): Type
29+
public function getDatabaseInternalType(Driver $driver): Type
2930
{
3031
return new StringType();
3132
}

Diff for: src/Type/Doctrine/Descriptors/DateTimeType.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use DateTime;
66
use DateTimeInterface;
7+
use Doctrine\DBAL\Driver;
78
use PHPStan\Type\ObjectType;
89
use PHPStan\Type\StringType;
910
use PHPStan\Type\Type;
@@ -26,7 +27,7 @@ public function getWritableToDatabaseType(): Type
2627
return new ObjectType(DateTimeInterface::class);
2728
}
2829

29-
public function getDatabaseInternalType(): Type
30+
public function getDatabaseInternalType(Driver $driver): Type
3031
{
3132
return new StringType();
3233
}

Diff for: src/Type/Doctrine/Descriptors/DateTimeTzImmutableType.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace PHPStan\Type\Doctrine\Descriptors;
44

55
use DateTimeImmutable;
6+
use Doctrine\DBAL\Driver;
67
use PHPStan\Type\ObjectType;
78
use PHPStan\Type\StringType;
89
use PHPStan\Type\Type;
@@ -25,7 +26,7 @@ public function getWritableToDatabaseType(): Type
2526
return new ObjectType(DateTimeImmutable::class);
2627
}
2728

28-
public function getDatabaseInternalType(): Type
29+
public function getDatabaseInternalType(Driver $driver): Type
2930
{
3031
return new StringType();
3132
}

Diff for: src/Type/Doctrine/Descriptors/DateTimeTzType.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use DateTime;
66
use DateTimeInterface;
7+
use Doctrine\DBAL\Driver;
78
use PHPStan\Type\ObjectType;
89
use PHPStan\Type\StringType;
910
use PHPStan\Type\Type;
@@ -26,7 +27,7 @@ public function getWritableToDatabaseType(): Type
2627
return new ObjectType(DateTimeInterface::class);
2728
}
2829

29-
public function getDatabaseInternalType(): Type
30+
public function getDatabaseInternalType(Driver $driver): Type
3031
{
3132
return new StringType();
3233
}

Diff for: src/Type/Doctrine/Descriptors/DateType.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use DateTime;
66
use DateTimeInterface;
7+
use Doctrine\DBAL\Driver;
78
use PHPStan\Type\ObjectType;
89
use PHPStan\Type\StringType;
910
use PHPStan\Type\Type;
@@ -26,7 +27,7 @@ public function getWritableToDatabaseType(): Type
2627
return new ObjectType(DateTimeInterface::class);
2728
}
2829

29-
public function getDatabaseInternalType(): Type
30+
public function getDatabaseInternalType(Driver $driver): Type
3031
{
3132
return new StringType();
3233
}

Diff for: src/Type/Doctrine/Descriptors/DecimalType.php

+14-2
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,13 @@
22

33
namespace PHPStan\Type\Doctrine\Descriptors;
44

5+
use Doctrine\DBAL\Driver;
6+
use Doctrine\DBAL\Driver\PDO\SQLite\Driver as PdoSqliteDriver;
7+
use Doctrine\DBAL\Driver\SQLite3\Driver as Sqlite3Driver;
58
use PHPStan\Type\Accessory\AccessoryNumericStringType;
69
use PHPStan\Type\FloatType;
710
use PHPStan\Type\IntegerType;
11+
use PHPStan\Type\IntersectionType;
812
use PHPStan\Type\StringType;
913
use PHPStan\Type\Type;
1014
use PHPStan\Type\TypeCombinator;
@@ -27,9 +31,17 @@ public function getWritableToDatabaseType(): Type
2731
return TypeCombinator::union(new StringType(), new FloatType(), new IntegerType());
2832
}
2933

30-
public function getDatabaseInternalType(): Type
34+
public function getDatabaseInternalType(Driver $driver): Type
3135
{
32-
return TypeCombinator::union(new FloatType(), new IntegerType());
36+
if ($driver instanceof Sqlite3Driver || $driver instanceof PdoSqliteDriver) {
37+
return new FloatType();
38+
}
39+
40+
// TODO use mixed as fallback for any untested driver or some guess?
41+
return new IntersectionType([
42+
new StringType(),
43+
new AccessoryNumericStringType(),
44+
]);
3345
}
3446

3547
}

Diff for: src/Type/Doctrine/Descriptors/DoctrineTypeDescriptor.php

+21-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace PHPStan\Type\Doctrine\Descriptors;
44

5+
use Doctrine\DBAL\Driver;
56
use PHPStan\Type\Type;
67

78
/** @api */
@@ -13,10 +14,29 @@ interface DoctrineTypeDescriptor
1314
*/
1415
public function getType(): string;
1516

17+
/**
18+
* This is used for inferring direct column results, e.g. SELECT e.field
19+
* It should comply with convertToPHPValue return value
20+
*/
1621
public function getWritableToPropertyType(): Type;
1722

1823
public function getWritableToDatabaseType(): Type;
1924

20-
public function getDatabaseInternalType(): Type;
25+
/**
26+
* This is used for inferring how database fetches column of such type
27+
* It should return the native type without stringification that may occur on certain PHP versions or driver configuration
28+
*
29+
* This is not used for direct column type inferring,
30+
* but when such column appears in expression like SELECT MAX(e.field)
31+
*
32+
* See: https://github.com/janedbal/php-database-drivers-fetch-test
33+
*
34+
* mysql sqlite pdo_pgsql pgsql
35+
* - decimal: string float string string
36+
* - float: float float string float
37+
* - bigint: int int int int
38+
* - bool: int int bool bool
39+
*/
40+
public function getDatabaseInternalType(Driver $driver): Type;
2141

2242
}

Diff for: src/Type/Doctrine/Descriptors/FloatType.php

+13-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@
22

33
namespace PHPStan\Type\Doctrine\Descriptors;
44

5+
use Doctrine\DBAL\Driver;
6+
use Doctrine\DBAL\Driver\PDO\PgSQL\Driver as PdoPgSQLDriver;
7+
use PHPStan\Type\Accessory\AccessoryNumericStringType;
58
use PHPStan\Type\IntegerType;
9+
use PHPStan\Type\IntersectionType;
10+
use PHPStan\Type\StringType;
611
use PHPStan\Type\Type;
712
use PHPStan\Type\TypeCombinator;
813

@@ -24,9 +29,15 @@ public function getWritableToDatabaseType(): Type
2429
return TypeCombinator::union(new \PHPStan\Type\FloatType(), new IntegerType());
2530
}
2631

27-
public function getDatabaseInternalType(): Type
32+
public function getDatabaseInternalType(Driver $driver): Type
2833
{
29-
return TypeCombinator::union(new \PHPStan\Type\FloatType(), new IntegerType());
34+
if ($driver instanceof PdoPgSQLDriver) {
35+
return new IntersectionType([
36+
new StringType(),
37+
new AccessoryNumericStringType(),
38+
]);
39+
}
40+
return new \PHPStan\Type\FloatType();
3041
}
3142

3243
}

Diff for: src/Type/Doctrine/Descriptors/GuidType.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace PHPStan\Type\Doctrine\Descriptors;
44

5+
use Doctrine\DBAL\Driver;
56
use PHPStan\Type\StringType;
67
use PHPStan\Type\Type;
78

@@ -23,7 +24,7 @@ public function getWritableToDatabaseType(): Type
2324
return new StringType();
2425
}
2526

26-
public function getDatabaseInternalType(): Type
27+
public function getDatabaseInternalType(Driver $driver): Type
2728
{
2829
return new StringType();
2930
}

Diff for: src/Type/Doctrine/Descriptors/IntegerType.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace PHPStan\Type\Doctrine\Descriptors;
44

5+
use Doctrine\DBAL\Driver;
56
use PHPStan\Type\Type;
67

78
class IntegerType implements DoctrineTypeDescriptor
@@ -22,7 +23,7 @@ public function getWritableToDatabaseType(): Type
2223
return new \PHPStan\Type\IntegerType();
2324
}
2425

25-
public function getDatabaseInternalType(): Type
26+
public function getDatabaseInternalType(Driver $driver): Type
2627
{
2728
return new \PHPStan\Type\IntegerType();
2829
}

0 commit comments

Comments
 (0)