Skip to content

Commit 22c4479

Browse files
committed
Test with orm3 & dbal4
1 parent 0c0d1ac commit 22c4479

File tree

4 files changed

+78
-28
lines changed

4 files changed

+78
-28
lines changed

.github/workflows/platform-matrix-test.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ jobs:
2323
php-version:
2424
- "8.0"
2525
- "8.1"
26+
update-packages:
27+
- ""
28+
include:
29+
- php-version: "8.1"
30+
update-packages: doctrine/orm:^3.0 doctrine/dbal:^4.0 carbonphp/carbon-doctrine-types:^3 gedmo/doctrine-extensions:^3
2631

2732
steps:
2833
- name: "Checkout"
@@ -39,6 +44,10 @@ jobs:
3944
- name: "Install dependencies"
4045
run: "composer install --no-interaction --no-progress"
4146

47+
- name: "Update packages"
48+
if: ${{ matrix.update-packages != '' }}
49+
run: composer require --dev ${{ matrix.update-packages }} -W
50+
4251
- name: "Run platform matrix test"
4352
run: vendor/bin/phpunit --group=platform
4453

src/Type/Doctrine/Query/QueryResultTypeWalker.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,10 @@ public function walkFunction($function): string
598598
$exprType = $this->unmarshalType($this->walkSimpleArithmeticExpression($function->simpleArithmeticExpression));
599599
$exprTypeNoNull = TypeCombinator::removeNull($exprType);
600600

601+
if (!$exprTypeNoNull->isFloat()->yes() && !$exprTypeNoNull->isNumericString()->yes() && !$exprTypeNoNull->isInteger()->yes()) {
602+
return $this->marshalType(new MixedType()); // dont try to deal with non-numeric args
603+
}
604+
601605
$driverType = DriverType::detect($this->em->getConnection());
602606

603607
if ($driverType === DriverType::MYSQLI || $driverType === DriverType::PDO_MYSQL || $driverType === DriverType::SQLITE3 || $driverType === DriverType::PDO_SQLITE) {

tests/Platform/Entity/PlatformEntity.php

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
* @ORM\Table(name="test")
1010
* @ORM\Entity
1111
*/
12+
#[ORM\Table(name: 'test')]
13+
#[ORM\Entity]
1214
class PlatformEntity
1315
{
1416

@@ -17,90 +19,106 @@ class PlatformEntity
1719
* @ORM\Column(type="string",nullable=false)
1820
* @var string
1921
*/
22+
#[ORM\Id]
23+
#[ORM\Column(type: 'string', nullable: false)]
2024
public $id;
2125

2226
/**
2327
* @ORM\Column(type="string", name="col_string", nullable=false)
2428
* @var string
2529
*/
30+
#[ORM\Column(type: 'string', name: 'col_string', nullable: false)]
2631
public $col_string;
2732

2833
/**
2934
* @ORM\Column(type="string", name="col_string_nullable", nullable=true)
3035
* @var string|null
3136
*/
37+
#[ORM\Column(type: 'string', name: 'col_string_nullable', nullable: true)]
3238
public $col_string_nullable;
3339

3440
/**
3541
* @ORM\Column(type="boolean", name="col_bool", nullable=false)
3642
* @var bool
3743
*/
44+
#[ORM\Column(type: 'boolean', name: 'col_bool', nullable: false)]
3845
public $col_bool;
3946

4047
/**
4148
* @ORM\Column(type="boolean", name="col_bool_nullable", nullable=true)
4249
* @var bool|null
4350
*/
51+
#[ORM\Column(type: 'boolean', name: 'col_bool_nullable', nullable: true)]
4452
public $col_bool_nullable;
4553

4654
/**
4755
* @ORM\Column(type="float", name="col_float", nullable=false)
4856
* @var float
4957
*/
58+
#[ORM\Column(type: 'float', name: 'col_float', nullable: false)]
5059
public $col_float;
5160

5261
/**
5362
* @ORM\Column(type="float", name="col_float_nullable", nullable=true)
5463
* @var float|null
5564
*/
65+
#[ORM\Column(type: 'float', name: 'col_float_nullable', nullable: true)]
5666
public $col_float_nullable;
5767

5868
/**
5969
* @ORM\Column(type="decimal", name="col_decimal", nullable=false, scale=1, precision=2)
6070
* @var string
6171
*/
72+
#[ORM\Column(type: 'decimal', name: 'col_decimal', nullable: false, scale: 1, precision: 2)]
6273
public $col_decimal;
6374

6475
/**
6576
* @ORM\Column(type="decimal", name="col_decimal_nullable", nullable=true, scale=1, precision=2)
6677
* @var string|null
6778
*/
79+
#[ORM\Column(type: 'decimal', name: 'col_decimal_nullable', nullable: true, scale: 1, precision: 2)]
6880
public $col_decimal_nullable;
6981

7082
/**
7183
* @ORM\Column(type="integer", name="col_int", nullable=false)
7284
* @var int
7385
*/
86+
#[ORM\Column(type: 'integer', name: 'col_int', nullable: false)]
7487
public $col_int;
7588

7689
/**
7790
* @ORM\Column(type="integer", name="col_int_nullable", nullable=true)
7891
* @var int|null
7992
*/
93+
#[ORM\Column(type: 'integer', name: 'col_int_nullable', nullable: true)]
8094
public $col_int_nullable;
8195

8296
/**
8397
* @ORM\Column(type="bigint", name="col_bigint", nullable=false)
84-
* @var string
98+
* @var int|string
8599
*/
100+
#[ORM\Column(type: 'bigint', name: 'col_bigint', nullable: false)]
86101
public $col_bigint;
87102

88103
/**
89104
* @ORM\Column(type="bigint", name="col_bigint_nullable", nullable=true)
90-
* @var string|null
105+
* @var int|string|null
91106
*/
107+
#[ORM\Column(type: 'bigint', name: 'col_bigint_nullable', nullable: true)]
92108
public $col_bigint_nullable;
93109

94110
/**
95111
* @ORM\Column(type="mixed", name="col_mixed", nullable=false)
96112
* @var mixed
97113
*/
114+
#[ORM\Column(type: 'mixed', name: 'col_mixed', nullable: false)]
98115
public $col_mixed;
99116

100117
/**
101118
* @ORM\Column(type="datetime", name="col_datetime", nullable=false)
102119
* @var DateTimeInterface
103120
*/
121+
#[ORM\Column(type: 'datetime', name: 'col_datetime', nullable: false)]
104122
public $col_datetime;
105123

106124
}

tests/Platform/QueryResultTypeWalkerFetchTypeMatrixTest.php

Lines changed: 45 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
namespace PHPStan\Platform;
44

55
use Cache\Adapter\PHPArray\ArrayCachePool;
6-
use DateTimeImmutable;
6+
use Composer\InstalledVersions;
7+
use Composer\Semver\VersionParser;
8+
use DateTime;
79
use Doctrine\Common\Annotations\AnnotationReader;
810
use Doctrine\DBAL\Connection;
911
use Doctrine\DBAL\DriverManager;
@@ -12,6 +14,7 @@
1214
use Doctrine\ORM\Configuration;
1315
use Doctrine\ORM\EntityManager;
1416
use Doctrine\ORM\Mapping\Driver\AnnotationDriver;
17+
use Doctrine\ORM\Mapping\Driver\AttributeDriver;
1518
use Doctrine\ORM\Query;
1619
use Doctrine\ORM\Tools\SchemaTool;
1720
use LogicException;
@@ -46,6 +49,7 @@
4649
use Platform\TypedExpressionStringPiFunction;
4750
use Psr\Log\LoggerInterface;
4851
use Throwable;
52+
use function class_exists;
4953
use function floor;
5054
use function getenv;
5155
use function in_array;
@@ -1458,16 +1462,16 @@ public static function provideCases(): iterable
14581462
yield 't.col_bigint' => [
14591463
'data' => self::dataDefault(),
14601464
'select' => 'SELECT t.col_bigint FROM %s t',
1461-
'mysql' => self::numericString(),
1462-
'sqlite' => self::numericString(),
1463-
'pdo_pgsql' => self::numericString(),
1464-
'pgsql' => self::numericString(),
1465-
'mssql' => self::numericString(),
1466-
'mysqlResult' => '2147483648',
1467-
'sqliteResult' => '2147483648',
1468-
'pdoPgsqlResult' => '2147483648',
1469-
'pgsqlResult' => '2147483648',
1470-
'mssqlResult' => '2147483648',
1465+
'mysql' => self::hasDbal4() ? self::int() : self::numericString(),
1466+
'sqlite' => self::hasDbal4() ? self::int() : self::numericString(),
1467+
'pdo_pgsql' => self::hasDbal4() ? self::int() : self::numericString(),
1468+
'pgsql' => self::hasDbal4() ? self::int() : self::numericString(),
1469+
'mssql' => self::hasDbal4() ? self::int() : self::numericString(),
1470+
'mysqlResult' => self::hasDbal4() ? 2147483648 : '2147483648',
1471+
'sqliteResult' => self::hasDbal4() ? 2147483648 : '2147483648',
1472+
'pdoPgsqlResult' => self::hasDbal4() ? 2147483648 : '2147483648',
1473+
'pgsqlResult' => self::hasDbal4() ? 2147483648 : '2147483648',
1474+
'mssqlResult' => self::hasDbal4() ? 2147483648 : '2147483648',
14711475
'shouldStringify' => static function (): bool {
14721476
return false;
14731477
},
@@ -3150,11 +3154,11 @@ public static function provideCases(): iterable
31503154
yield 'SQRT(t.col_mixed)' => [
31513155
'data' => self::dataSqrt(),
31523156
'select' => 'SELECT SQRT(t.col_mixed) FROM %s t',
3153-
'mysql' => self::floatOrNull(),
3154-
'sqlite' => self::floatOrNull(),
3155-
'pdo_pgsql' => self::numericStringOrNull(),
3156-
'pgsql' => TypeCombinator::union(self::floatOrNull(), self::numericStringOrNull()),
3157-
'mssql' => new MixedType(),
3157+
'mysql' => self::mixed(),
3158+
'sqlite' => self::mixed(),
3159+
'pdo_pgsql' => self::mixed(),
3160+
'pgsql' => self::mixed(),
3161+
'mssql' => self::mixed(),
31583162
'mysqlResult' => 1.0,
31593163
'sqliteResult' => 1.0,
31603164
'pdoPgsqlResult' => '1',
@@ -3169,12 +3173,12 @@ public static function provideCases(): iterable
31693173
'data' => self::dataSqrt(),
31703174
'select' => 'SELECT SQRT(t.col_int_nullable) FROM %s t',
31713175
'mysql' => self::floatOrNull(),
3172-
'sqlite' => PHP_VERSION_ID >= 80100 ? null : self::floatOrNull(), // fails in UDF since PHP 8.1: sqrt(): Passing null to parameter #1 ($num) of type float is deprecated
3176+
'sqlite' => PHP_VERSION_ID >= 80100 && !self::hasDbal4() ? null : self::floatOrNull(), // fails in UDF since PHP 8.1: sqrt(): Passing null to parameter #1 ($num) of type float is deprecated
31733177
'pdo_pgsql' => self::numericStringOrNull(),
31743178
'pgsql' => self::floatOrNull(),
31753179
'mssql' => new MixedType(),
31763180
'mysqlResult' => null,
3177-
'sqliteResult' => 0.0, // caused by UDF wired through PHP's sqrt() which returns 0.0 for null
3181+
'sqliteResult' => self::hasDbal4() ? null : 0.0, // 0.0 caused by UDF wired through PHP's sqrt() which returns 0.0 for null
31783182
'pdoPgsqlResult' => null,
31793183
'pgsqlResult' => null,
31803184
'mssqlResult' => null,
@@ -3276,8 +3280,8 @@ public static function provideCases(): iterable
32763280
yield "SQRT('foo')" => [
32773281
'data' => self::dataSqrt(),
32783282
'select' => "SELECT SQRT('foo') FROM %s t",
3279-
'mysql' => self::float(),
3280-
'sqlite' => null, // fails in UDF: sqrt(): Argument #1 ($num) must be of type float, string given
3283+
'mysql' => self::mixed(),
3284+
'sqlite' => self::hasDbal4() ? self::mixed() : null, // fails in UDF: sqrt(): Argument #1 ($num) must be of type float, string given
32813285
'pdo_pgsql' => null, // Invalid text representation
32823286
'pgsql' => null, // Invalid text representation
32833287
'mssql' => null, // Error converting data type
@@ -3294,8 +3298,8 @@ public static function provideCases(): iterable
32943298
yield 'SQRT(t.col_string)' => [
32953299
'data' => self::dataSqrt(),
32963300
'select' => 'SELECT SQRT(t.col_string) FROM %s t',
3297-
'mysql' => self::floatOrNull(),
3298-
'sqlite' => null, // fails in UDF: sqrt(): Argument #1 ($num) must be of type float, string given
3301+
'mysql' => self::mixed(),
3302+
'sqlite' => self::hasDbal4() ? self::mixed() : null, // fails in UDF: sqrt(): Argument #1 ($num) must be of type float, string given
32993303
'pdo_pgsql' => null, // undefined function
33003304
'pgsql' => null, // undefined function
33013305
'mssql' => null, // Error converting data type
@@ -3613,7 +3617,13 @@ private function getQuery(
36133617
$config->setAutoGenerateProxyClasses(false);
36143618
$config->setSecondLevelCacheEnabled(false);
36153619
$config->setMetadataCache(new ArrayCachePool());
3616-
$config->setMetadataDriverImpl(new AnnotationDriver(new AnnotationReader(), [__DIR__ . '/Entity']));
3620+
3621+
if (InstalledVersions::satisfies(new VersionParser(), 'doctrine/orm', '3.*')) {
3622+
$config->setMetadataDriverImpl(new AttributeDriver([__DIR__ . '/Entity']));
3623+
} else {
3624+
$config->setMetadataDriverImpl(new AnnotationDriver(new AnnotationReader(), [__DIR__ . '/Entity']));
3625+
}
3626+
36173627
$config->addCustomStringFunction('INT_PI', TypedExpressionIntegerPiFunction::class);
36183628
$config->addCustomStringFunction('BOOL_PI', TypedExpressionBooleanPiFunction::class);
36193629
$config->addCustomStringFunction('STRING_PI', TypedExpressionStringPiFunction::class);
@@ -3931,7 +3941,7 @@ public static function dataDefault(): array
39313941
'col_string' => 'foobar',
39323942
'col_string_nullable' => null,
39333943
'col_mixed' => 1,
3934-
'col_datetime' => new DateTimeImmutable('2024-01-31 12:59:59'),
3944+
'col_datetime' => new DateTime('2024-01-31 12:59:59'),
39353945
],
39363946
];
39373947
}
@@ -3957,7 +3967,7 @@ public static function dataAllIntLike(): array
39573967
'col_string' => '1',
39583968
'col_string_nullable' => null,
39593969
'col_mixed' => 1,
3960-
'col_datetime' => new DateTimeImmutable('2024-01-31 12:59:59'),
3970+
'col_datetime' => new DateTime('2024-01-31 12:59:59'),
39613971
],
39623972
];
39633973
}
@@ -3984,7 +3994,7 @@ public static function dataSqrt(): array
39843994
'col_string' => 'foobar',
39853995
'col_string_nullable' => null,
39863996
'col_mixed' => 1,
3987-
'col_datetime' => new DateTimeImmutable('2024-01-31 12:59:59'),
3997+
'col_datetime' => new DateTime('2024-01-31 12:59:59'),
39883998
],
39893999
];
39904000
}
@@ -4049,4 +4059,13 @@ private function getHumanReadablePhpVersion(int $phpVersion): string
40494059
return floor($phpVersion / 10000) . '.' . floor(($phpVersion % 10000) / 100);
40504060
}
40514061

4062+
private static function hasDbal4(): bool
4063+
{
4064+
if (!class_exists(InstalledVersions::class)) {
4065+
return false;
4066+
}
4067+
4068+
return InstalledVersions::satisfies(new VersionParser(), 'doctrine/dbal', '4.*');
4069+
}
4070+
40524071
}

0 commit comments

Comments
 (0)