Skip to content

Commit 516047c

Browse files
authored
Fix bigint PHP_INT_MIN/PHP_INT_MAX string to int convert (#6410)
<!-- Fill in the relevant information below to help triage your pull request. --> | Q | A |------------- | ----------- | Type | bug | Fixed issues | n/a #### Summary Resolve #6177 (comment) discussion and related original #6177. Whole native php `int` range is guaranteed to be supported per https://www.doctrine-project.org/projects/doctrine-dbal/en/4.0/reference/types.html#bigint docs.
1 parent 9715fe1 commit 516047c

File tree

3 files changed

+21
-44
lines changed

3 files changed

+21
-44
lines changed

psalm.xml.dist

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,12 @@
131131
<file name="tests/Types/DateIntervalTest.php"/>
132132
</errorLevel>
133133
</InaccessibleProperty>
134+
<InvalidCast>
135+
<errorLevel type="suppress">
136+
<!-- See https://github.com/vimeo/psalm/issues/10995 -->
137+
<file name="src/Types/BigIntType.php"/>
138+
</errorLevel>
139+
</InvalidCast>
134140
<InvalidArgument>
135141
<errorLevel type="suppress">
136142
<!-- We're testing with invalid input here. -->
@@ -185,6 +191,8 @@
185191
</MoreSpecificReturnType>
186192
<NoValue>
187193
<errorLevel type="suppress">
194+
<!-- See https://github.com/vimeo/psalm/issues/10995 -->
195+
<file name="src/Types/BigIntType.php"/>
188196
<!--
189197
This error looks bogus.
190198
-->
@@ -291,6 +299,8 @@
291299
<!-- Ignore isset() checks in destructors. -->
292300
<file name="src/Driver/PgSQL/Connection.php"/>
293301
<file name="src/Driver/PgSQL/Statement.php"/>
302+
<!-- See https://github.com/vimeo/psalm/issues/10995 -->
303+
<file name="src/Types/BigIntType.php"/>
294304
</errorLevel>
295305
</TypeDoesNotContainType>
296306
<UndefinedClass>

src/Types/BigIntType.php

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,18 @@ public function convertToPHPValue(mixed $value, AbstractPlatform $platform): int
4747
return $value;
4848
}
4949

50-
if ($value > PHP_INT_MIN && $value < PHP_INT_MAX) {
51-
return (int) $value;
52-
}
53-
5450
assert(
5551
is_string($value),
5652
'DBAL assumes values outside of the integer range to be returned as string by the database driver.',
5753
);
5854

55+
if (
56+
($value > PHP_INT_MIN && $value < PHP_INT_MAX)
57+
|| $value === (string) (int) $value
58+
) {
59+
return (int) $value;
60+
}
61+
5962
return $value;
6063
}
6164
}

tests/Functional/Types/BigIntTypeTest.php

Lines changed: 4 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
use Doctrine\DBAL\Types\Types;
1111
use Generator;
1212
use PHPUnit\Framework\Attributes\DataProvider;
13-
use PHPUnit\Framework\Constraint\IsIdentical;
14-
use PHPUnit\Framework\Constraint\LogicalOr;
1513

1614
use const PHP_INT_MAX;
1715
use const PHP_INT_MIN;
@@ -49,44 +47,10 @@ public static function provideBigIntLiterals(): Generator
4947
yield 'null' => ['null', null];
5048
yield 'positive number' => ['42', 42];
5149
yield 'negative number' => ['-42', -42];
52-
53-
if (PHP_INT_SIZE < 8) {
54-
// The following tests only work on 64bit systems.
55-
return;
56-
}
57-
58-
yield 'large positive number' => ['9223372036854775806', PHP_INT_MAX - 1];
59-
yield 'large negative number' => ['-9223372036854775807', PHP_INT_MIN + 1];
60-
}
61-
62-
#[DataProvider('provideBigIntEdgeLiterals')]
63-
public function testSelectBigIntEdge(int $value): void
64-
{
65-
$table = new Table('bigint_type_test');
66-
$table->addColumn('id', Types::SMALLINT, ['notnull' => true]);
67-
$table->addColumn('my_integer', Types::BIGINT, ['notnull' => false]);
68-
$table->setPrimaryKey(['id']);
69-
$this->dropAndCreateTable($table);
70-
71-
$this->connection->executeStatement(<<<SQL
72-
INSERT INTO bigint_type_test (id, my_integer)
73-
VALUES (42, $value)
74-
SQL);
75-
76-
self::assertThat(
77-
$this->connection->convertToPHPValue(
78-
$this->connection->fetchOne('SELECT my_integer from bigint_type_test WHERE id = 42'),
79-
Types::BIGINT,
80-
),
81-
LogicalOr::fromConstraints(new IsIdentical($value), new IsIdentical((string) $value)),
82-
);
83-
}
84-
85-
/** @return Generator<string, array{int}> */
86-
public static function provideBigIntEdgeLiterals(): Generator
87-
{
88-
yield 'max int' => [PHP_INT_MAX];
89-
yield 'min int' => [PHP_INT_MIN];
50+
yield 'large positive number' => [PHP_INT_SIZE === 4 ? '2147483646' : '9223372036854775806', PHP_INT_MAX - 1];
51+
yield 'large negative number' => [PHP_INT_SIZE === 4 ? '-2147483647' : '-9223372036854775807', PHP_INT_MIN + 1];
52+
yield 'largest positive number' => [PHP_INT_SIZE === 4 ? '2147483647' : '9223372036854775807', PHP_INT_MAX];
53+
yield 'largest negative number' => [PHP_INT_SIZE === 4 ? '-2147483648' : '-9223372036854775808', PHP_INT_MIN];
9054
}
9155

9256
public function testUnsignedBigIntOnMySQL(): void

0 commit comments

Comments
 (0)