From 25cc2a285a286ba5862b9b0407fa02b8231bf6a8 Mon Sep 17 00:00:00 2001 From: Jan Langer Date: Mon, 22 Nov 2021 16:43:13 +0100 Subject: [PATCH 1/3] Fix integer decimal casting to string in PHP 8.1 with SQLite --- lib/Doctrine/DBAL/Types/DecimalType.php | 5 ++-- .../DBAL/Functional/Types/DecimalTest.php | 28 +++++++++++++++++-- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/lib/Doctrine/DBAL/Types/DecimalType.php b/lib/Doctrine/DBAL/Types/DecimalType.php index f75d3db2c68..c70067f2b4f 100644 --- a/lib/Doctrine/DBAL/Types/DecimalType.php +++ b/lib/Doctrine/DBAL/Types/DecimalType.php @@ -5,6 +5,7 @@ use Doctrine\DBAL\Platforms\AbstractPlatform; use function is_float; +use function is_int; use const PHP_VERSION_ID; @@ -34,9 +35,9 @@ public function getSQLDeclaration(array $column, AbstractPlatform $platform) */ public function convertToPHPValue($value, AbstractPlatform $platform) { - // Some drivers starting from PHP 8.1 can represent decimals as float + // Some drivers starting from PHP 8.1 can represent decimals as float/int // See also: https://github.com/doctrine/dbal/pull/4818 - if (PHP_VERSION_ID >= 80100 && is_float($value)) { + if (PHP_VERSION_ID >= 80100 && (is_float($value) || is_int($value))) { return (string) $value; } diff --git a/tests/Doctrine/Tests/DBAL/Functional/Types/DecimalTest.php b/tests/Doctrine/Tests/DBAL/Functional/Types/DecimalTest.php index 5e7e98e4e96..c9cbbf53a72 100644 --- a/tests/Doctrine/Tests/DBAL/Functional/Types/DecimalTest.php +++ b/tests/Doctrine/Tests/DBAL/Functional/Types/DecimalTest.php @@ -9,9 +9,25 @@ use Doctrine\DBAL\Types\Types; use Doctrine\Tests\DbalFunctionalTestCase; +use function rtrim; + final class DecimalTest extends DbalFunctionalTestCase { - public function testInsertAndRetrieveDecimal(): void + /** + * @return string[][] + */ + public function dataValuesProvider(): array + { + return [ + ['13.37'], + ['13.0'], + ]; + } + + /** + * @dataProvider dataValuesProvider + */ + public function testInsertAndRetrieveDecimal(string $expected): void { $table = new Table('decimal_table'); $table->addColumn('val', Types::DECIMAL, ['precision' => 4, 'scale' => 2]); @@ -21,7 +37,7 @@ public function testInsertAndRetrieveDecimal(): void $this->connection->insert( 'decimal_table', - ['val' => '13.37'], + ['val' => $expected], ['val' => Types::DECIMAL] ); @@ -30,6 +46,12 @@ public function testInsertAndRetrieveDecimal(): void $this->connection->getDatabasePlatform() ); - self::assertSame('13.37', $value); + self::assertIsString($value); + self::assertSame($this->stripTrailingZero($expected), $this->stripTrailingZero($value)); + } + + private function stripTrailingZero(string $expected): string + { + return rtrim(rtrim($expected, '0'), '.'); } } From 5f07192b0973a4541e633ac574f07f150974ac70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Thu, 25 Nov 2021 11:58:44 +0100 Subject: [PATCH 2/3] docs: fix docs for the json type --- docs/en/reference/types.rst | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/docs/en/reference/types.rst b/docs/en/reference/types.rst index ee9214c20cf..7be8ffd34c6 100644 --- a/docs/en/reference/types.rst +++ b/docs/en/reference/types.rst @@ -425,8 +425,9 @@ json Maps and converts array data based on PHP's JSON encoding functions. If you know that the data to be stored always is in a valid UTF-8 encoded JSON format string, you should consider using this type. -Values retrieved from the database are always converted to PHP's ``array`` or -``null`` types using PHP's ``json_decode()`` function. +Values retrieved from the database are always converted to PHP's +native types using PHP's ``json_decode()`` function. +JSON objects are always converted to PHP associative arrays. .. note:: @@ -809,6 +810,34 @@ Please also notice the mapping specific footnotes for additional information. | | +--------------------------+---------+----------------------------------------------------------+ | | | **SQL Server** | *all* | ``VARCHAR(MAX)`` [1]_ | +-------------------+---------------+--------------------------+---------+----------------------------------------------------------+ +| **json** | ``mixed`` | **MySQL** | < 5.7 | ``TINYTEXT`` [1]_ [17]_ | +| | | | +----------------------------------------------------------+ +| | | | | ``TEXT`` [1]_ [18]_ | +| | | | +----------------------------------------------------------+ +| | | | | ``MEDIUMTEXT`` [1]_ [19]_ | +| | | | +----------------------------------------------------------+ +| | | | | ``LONGTEXT`` [1]_ [20]_ | +| | | +---------+----------------------------------------------------------+ +| | | | >= 5.7 | ``JSON`` | +| | +--------------------------+---------+----------------------------------------------------------+ +| | | **PostgreSQL** | < 9.2 | ``TEXT`` [1]_ | +| | | +---------+----------------------------------------------------------+ +| | | | < 9.4 | ``JSON`` | +| | | +---------+----------------------------------------------------------+ +| | | | >= 9.4 | ``JSON`` [21]_ | +| | | | +----------------------------------------------------------+ +| | | | | ``JSONB`` [22]_ | +| | +--------------------------+---------+----------------------------------------------------------+ +| | | **SQL Anywhere** | *all* | ``TEXT`` [1]_ | +| | +--------------------------+ | | +| | | **Drizzle** | | | +| | +--------------------------+---------+----------------------------------------------------------+ +| | | **Oracle** | *all* | ``CLOB`` [1]_ | +| | +--------------------------+ | | +| | | **SQLite** | | | +| | +--------------------------+---------+----------------------------------------------------------+ +| | | **SQL Server** | *all* | ``VARCHAR(MAX)`` [1]_ | ++-------------------+---------------+--------------------------+---------+----------------------------------------------------------+ | **object** [1]_ | ``object`` | **MySQL** | *all* | ``TINYTEXT`` [17]_ | | | | | +----------------------------------------------------------+ | | | | | ``TEXT`` [18]_ | From cc25533230e119ab5ca56f3380f923694b7416f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Thu, 25 Nov 2021 12:06:48 +0100 Subject: [PATCH 3/3] add a note about types --- docs/en/reference/types.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/en/reference/types.rst b/docs/en/reference/types.rst index 7be8ffd34c6..4051a1d21cf 100644 --- a/docs/en/reference/types.rst +++ b/docs/en/reference/types.rst @@ -429,6 +429,15 @@ Values retrieved from the database are always converted to PHP's native types using PHP's ``json_decode()`` function. JSON objects are always converted to PHP associative arrays. +.. note:: + + The ``json`` type doesn't preserve the type of PHP objects. + PHP objects will always be encoded as (anonymous) JSON objects. + JSON objects will always be decoded as PHP associative arrays. + + To preserve the type of PHP objects, consider using + `Doctrine JSON ODM `_. + .. note:: Some vendors have a native JSON type and Doctrine will use it if possible