From ad58e8f519cf0c17de591a22798a5801c6a0ead0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Sun, 16 Jan 2022 17:02:23 +0100 Subject: [PATCH 01/12] Delete run-all.sh --- run-all.sh | 9 --------- 1 file changed, 9 deletions(-) delete mode 100755 run-all.sh diff --git a/run-all.sh b/run-all.sh deleted file mode 100755 index 0397b75f994..00000000000 --- a/run-all.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -# This script is a small convenience wrapper for running the doctrine testsuite against a large bunch of databases. -# Create *.phpunit.xml files and specify database connection parameters in the section. - -for i in *.phpunit.xml; do - echo "RUNNING TESTS WITH CONFIG $i" - vendor/bin/phpunit -c "$i" "$@" -done From e9daeed4c0b87451f564091da88133d93ffdf313 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Sun, 16 Jan 2022 02:13:26 +0100 Subject: [PATCH 02/12] Add middlewares to the architecture documentation --- docs/en/reference/architecture.rst | 36 +++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/docs/en/reference/architecture.rst b/docs/en/reference/architecture.rst index 8ee7f910aee..32b00a2e2c4 100644 --- a/docs/en/reference/architecture.rst +++ b/docs/en/reference/architecture.rst @@ -12,11 +12,6 @@ and a ``Doctrine\DBAL\Result`` wraps a ``Doctrine\DBAL\Driver\Result``. and ``Doctrine\DBAL\Driver\Result`` are just interfaces. These interfaces are implemented by concrete drivers. -What do the wrapper components add to the underlying driver -implementations? The enhancements include SQL logging, events and -control over the transaction isolation level in a portable manner, -among others. - Apart from the three main components, a DBAL driver should also provide an implementation of the ``Doctrine\DBAL\Driver`` interface that has two primary purposes: @@ -26,18 +21,40 @@ has two primary purposes: 2. Act as a factory of other driver-specific components like platform, schema manager and exception converter. +The driver components can be decorated using the four driver interfaces in +order to add driver-independent functionality like logging or profiling. Those +decorators are configured as a middleware. + +The wrapper components ``Connection``, ``Statement`` and ``Result`` are the +objects that the application usually interacts with directly. They wrap the +middleware stack as well as the driver at the bottom of that stack. + The DBAL is separated into several different packages that separate responsibilities of the different RDBMS layers. Drivers ------- -The drivers abstract a PHP specific database API by enforcing three +The drivers abstract a PHP specific database API by enforcing four interfaces: -- ``\Doctrine\DBAL\Driver\Connection`` -- ``\Doctrine\DBAL\Driver\Statement`` -- ``\Doctrine\DBAL\Driver\Result`` +- ``Doctrine\DBAL\Driver`` +- ``Doctrine\DBAL\Driver\Connection`` +- ``Doctrine\DBAL\Driver\Statement`` +- ``Doctrine\DBAL\Driver\Result`` + +Middlewares +----------- + +A middleware sits in the middle between the wrapper components and the driver. +By implementing the ``Doctrine\DBAL\Driver\Middleware``, it decorates the +``Driver`` component of either the actual driver or a lower middleware. If +necessary, the middleware might also decorate ``Connection``, ``Statement`` +and ``Result``. + +An example for a middleware implementation is +``Doctrine\DBAL\Logging\Middleware`` which implements logging capabilities +on top of a driver. Platforms --------- @@ -72,4 +89,3 @@ The types offer an abstraction layer for the converting and generation of types between Databases and PHP. Doctrine comes bundled with some common types but offers the ability for developers to define custom types or extend existing ones easily. - From a08544b7494d9bb7a8968abb36bcc40f1d8deb11 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Tue, 18 Jan 2022 01:05:38 +0100 Subject: [PATCH 03/12] Update README for release 3.3 --- README.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index cc7167aa015..8d5475e5a0e 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ # Doctrine DBAL -| [4.0-dev][4.0] | [3.2][3.2] | [2.13][2.13] | +| [4.0-dev][4.0] | [3.3][3.3] | [2.13][2.13] | |:----------------:|:----------:|:----------:| -| [![GitHub Actions][GA 4.0 image]][GA 4.0] | [![GitHub Actions][GA 3.2 image]][GA 3.2] | [![GitHub Actions][GA 2.13 image]][GA 2.13] | -| [![AppVeyor][AppVeyor 4.0 image]][AppVeyor 4.0] | [![AppVeyor][AppVeyor 3.2 image]][AppVeyor 3.2] | [![AppVeyor][AppVeyor 2.13 image]][AppVeyor 2.13] | -| [![Code Coverage][Coverage image]][CodeCov 4.0] | [![Code Coverage][Coverage 3.2 image]][CodeCov 3.2] | [![Code Coverage][Coverage 2.13 image]][CodeCov 2.13] | -| N/A | [![Code Coverage][TypeCov 3.2 image]][TypeCov 3.2] | N/A | +| [![GitHub Actions][GA 4.0 image]][GA 4.0] | [![GitHub Actions][GA 3.3 image]][GA 3.3] | [![GitHub Actions][GA 2.13 image]][GA 2.13] | +| [![AppVeyor][AppVeyor 4.0 image]][AppVeyor 4.0] | [![AppVeyor][AppVeyor 3.3 image]][AppVeyor 3.3] | [![AppVeyor][AppVeyor 2.13 image]][AppVeyor 2.13] | +| [![Code Coverage][Coverage image]][CodeCov 4.0] | [![Code Coverage][Coverage 3.3 image]][CodeCov 3.3] | [![Code Coverage][Coverage 2.13 image]][CodeCov 2.13] | +| N/A | [![Code Coverage][TypeCov 3.3 image]][TypeCov 3.3] | N/A | Powerful database abstraction layer with many features for database schema introspection, schema management and PDO abstraction. @@ -23,13 +23,15 @@ Powerful database abstraction layer with many features for database schema intro [GA 4.0]: https://github.com/doctrine/dbal/actions?query=workflow%3A%22Continuous+Integration%22+branch%3A4.0.x [GA 4.0 image]: https://github.com/doctrine/dbal/workflows/Continuous%20Integration/badge.svg - [Coverage 3.2 image]: https://codecov.io/gh/doctrine/dbal/branch/3.2.x/graph/badge.svg - [3.2]: https://github.com/doctrine/dbal/tree/3.2.x - [CodeCov 3.2]: https://codecov.io/gh/doctrine/dbal/branch/3.2.x - [AppVeyor 3.2]: https://ci.appveyor.com/project/doctrine/dbal/branch/3.2.x - [AppVeyor 3.2 image]: https://ci.appveyor.com/api/projects/status/i88kitq8qpbm0vie/branch/3.2.x?svg=true - [GA 3.2]: https://github.com/doctrine/dbal/actions?query=workflow%3A%22Continuous+Integration%22+branch%3A3.2.x - [GA 3.2 image]: https://github.com/doctrine/dbal/workflows/Continuous%20Integration/badge.svg?branch=3.2.x + [Coverage 3.3 image]: https://codecov.io/gh/doctrine/dbal/branch/3.3.x/graph/badge.svg + [3.3]: https://github.com/doctrine/dbal/tree/3.3.x + [CodeCov 3.3]: https://codecov.io/gh/doctrine/dbal/branch/3.3.x + [AppVeyor 3.3]: https://ci.appveyor.com/project/doctrine/dbal/branch/3.3.x + [AppVeyor 3.3 image]: https://ci.appveyor.com/api/projects/status/i88kitq8qpbm0vie/branch/3.3.x?svg=true + [GA 3.3]: https://github.com/doctrine/dbal/actions?query=workflow%3A%22Continuous+Integration%22+branch%3A3.3.x + [GA 3.3 image]: https://github.com/doctrine/dbal/workflows/Continuous%20Integration/badge.svg?branch=3.3.x + [TypeCov 3.3]: https://shepherd.dev/github/doctrine/dbal + [TypeCov 3.3 image]: https://shepherd.dev/github/doctrine/dbal/coverage.svg [Coverage 2.13 image]: https://codecov.io/gh/doctrine/dbal/branch/2.13.x/graph/badge.svg [2.13]: https://github.com/doctrine/dbal/tree/2.13.x @@ -38,5 +40,3 @@ Powerful database abstraction layer with many features for database schema intro [AppVeyor 2.13 image]: https://ci.appveyor.com/api/projects/status/i88kitq8qpbm0vie/branch/2.13.x?svg=true [GA 2.13]: https://github.com/doctrine/dbal/actions?query=workflow%3A%22Continuous+Integration%22+branch%3A2.13.x [GA 2.13 image]: https://github.com/doctrine/dbal/workflows/Continuous%20Integration/badge.svg?branch=2.13.x - [TypeCov 3.2]: https://shepherd.dev/github/doctrine/dbal - [TypeCov 3.2 image]: https://shepherd.dev/github/doctrine/dbal/coverage.svg From 9a068505f4fce6a1fb847a2f1392aa7325daaca3 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Tue, 18 Jan 2022 01:11:05 +0100 Subject: [PATCH 04/12] Update branch metadata for release 3.3 --- .doctrine-project.json | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.doctrine-project.json b/.doctrine-project.json index de7af7318f3..3efda43f4ff 100644 --- a/.doctrine-project.json +++ b/.doctrine-project.json @@ -6,8 +6,8 @@ "docsSlug": "doctrine-dbal", "versions": [ { - "name": "3.2", - "branchName": "3.2.x", + "name": "3.3", + "branchName": "3.3.x", "slug": "latest", "current": true, "aliases": [ @@ -15,6 +15,12 @@ "stable" ] }, + { + "name": "3.2", + "branchName": "3.2.x", + "slug": "3.2", + "maintained": false + }, { "name": "3.1", "branchName": "3.1.x", From b54342a26be7132dbdf0f2e368163c8c00ef5905 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Wed, 19 Jan 2022 18:34:40 +0100 Subject: [PATCH 05/12] fix typo: `\Doctrine\DBAL\Statement` vs. `\Doctrine\DBAL\Driver\Statement` --- docs/en/reference/data-retrieval-and-manipulation.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/reference/data-retrieval-and-manipulation.rst b/docs/en/reference/data-retrieval-and-manipulation.rst index 1490ab760b8..17a435e6249 100644 --- a/docs/en/reference/data-retrieval-and-manipulation.rst +++ b/docs/en/reference/data-retrieval-and-manipulation.rst @@ -304,7 +304,7 @@ prepare() ~~~~~~~~~ Prepare a given SQL statement and return the -``\Doctrine\DBAL\Driver\Statement`` instance: +``\Doctrine\DBAL\Statement`` instance: .. code-block:: php From 770a436cf1d29783729dc4fb6443b8fa2cbe4580 Mon Sep 17 00:00:00 2001 From: Sergei Morozov Date: Fri, 21 Jan 2022 13:05:19 -0800 Subject: [PATCH 06/12] Handle bindng invalid named parameter errors --- src/Driver/PDO/Exception.php | 4 ++++ tests/Functional/StatementTest.php | 27 +++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/src/Driver/PDO/Exception.php b/src/Driver/PDO/Exception.php index 49f55951d82..7036a0e43cd 100644 --- a/src/Driver/PDO/Exception.php +++ b/src/Driver/PDO/Exception.php @@ -18,6 +18,10 @@ public static function new(PDOException $exception): self { if ($exception->errorInfo !== null) { [$sqlState, $code] = $exception->errorInfo; + + if ($code === null) { + $code = 0; + } } else { $code = $exception->getCode(); $sqlState = null; diff --git a/tests/Functional/StatementTest.php b/tests/Functional/StatementTest.php index dcb74ec9361..2b7fbc5a6a3 100644 --- a/tests/Functional/StatementTest.php +++ b/tests/Functional/StatementTest.php @@ -3,6 +3,7 @@ namespace Doctrine\DBAL\Tests\Functional; use Doctrine\DBAL\Driver\Exception; +use Doctrine\DBAL\Exception\DriverException; use Doctrine\DBAL\ParameterType; use Doctrine\DBAL\Result; use Doctrine\DBAL\Schema\Table; @@ -13,6 +14,10 @@ use function base64_decode; use function stream_get_contents; +use const E_ALL; +use const E_WARNING; +use const PHP_VERSION_ID; + class StatementTest extends FunctionalTestCase { protected function setUp(): void @@ -236,6 +241,28 @@ public function testBindParamWithNullLength(): void self::assertEquals(1, $stmt->executeQuery()->fetchOne()); } + public function testBindInvalidNamedParameter(): void + { + if (TestUtil::isDriverOneOf('ibm_db2', 'mysqli', 'sqlsrv')) { + self::markTestSkipped('The driver does not support named statement parameters'); + } + + if (PHP_VERSION_ID < 80000 && TestUtil::isDriverOneOf('pdo_oci')) { + self::markTestSkipped('pdo_oci on PHP 7 does not report this error'); + } + + $platform = $this->connection->getDatabasePlatform(); + $statement = $this->connection->prepare($platform->getDummySelectSQL(':foo')); + $this->expectException(DriverException::class); + + // prevent the PHPUnit error handler from handling the warning that oci_bind_by_name() may trigger + if (TestUtil::isDriverOneOf('oci8')) { + $this->iniSet('error_reporting', (string) (E_ALL & ~E_WARNING)); + } + + $statement->executeQuery(['bar' => 'baz']); + } + /** * @param mixed $expected * From a6abda57dc644b414df4486b6e4479ee82343d75 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Sat, 22 Jan 2022 09:52:27 +0100 Subject: [PATCH 07/12] [Doc] Fix a table of Type Mapping Matrix --- docs/en/reference/types.rst | 523 ++++++++++++++++++------------------ 1 file changed, 263 insertions(+), 260 deletions(-) diff --git a/docs/en/reference/types.rst b/docs/en/reference/types.rst index 1cad37e9465..94e572760e7 100644 --- a/docs/en/reference/types.rst +++ b/docs/en/reference/types.rst @@ -526,267 +526,270 @@ The following table shows an overview of Doctrine's type abstraction. The matrix contains the mapping information for how a specific Doctrine type is mapped to the database and back to PHP. Please also notice the mapping specific footnotes for additional information. +:: -+-------------------+---------------+-----------------------------------------------------------------------------------------------+ -| Doctrine | PHP | Database vendor | -| | +--------------------------+---------+----------------------------------------------------------+ -| | | Name | Version | Type | -+===================+===============+==========================+=========+==========================================================+ -| **smallint** | ``integer`` | **MySQL** | *all* | ``SMALLINT`` ``UNSIGNED`` [10]_ ``AUTO_INCREMENT`` [11]_ | -| | +--------------------------+---------+----------------------------------------------------------+ -| | | **PostgreSQL** | *all* | ``SMALLINT`` | -| | +--------------------------+---------+----------------------------------------------------------+ -| | | **Oracle** | *all* | ``NUMBER(5)`` | -| | +--------------------------+---------+----------------------------------------------------------+ -| | | **SQL Server** | *all* | ``SMALLINT`` ``IDENTITY`` [11]_ | -| | +--------------------------+---------+----------------------------------------------------------+ -| | | **SQLite** | *all* | ``INTEGER`` [15]_ | -+-------------------+---------------+--------------------------+---------+----------------------------------------------------------+ -| **integer** | ``integer`` | **MySQL** | *all* | ``INT`` ``UNSIGNED`` [10]_ ``AUTO_INCREMENT`` [11]_ | -| | +--------------------------+---------+----------------------------------------------------------+ -| | | **PostgreSQL** | *all* | ``INT`` [12]_ | -| | | | +----------------------------------------------------------+ -| | | | | ``SERIAL`` [11]_ | -| | +--------------------------+---------+----------------------------------------------------------+ -| | | **Oracle** | *all* | ``NUMBER(10)`` | -| | +--------------------------+---------+----------------------------------------------------------+ -| | | **SQL Server** | *all* | ``INT`` ``IDENTITY`` [11]_ | -| | +--------------------------+---------+----------------------------------------------------------+ -| | | **SQLite** | *all* | ``INTEGER`` [15]_ | -+-------------------+---------------+--------------------------+---------+----------------------------------------------------------+ -| **bigint** | ``string`` | **MySQL** | *all* | ``BIGINT`` ``UNSIGNED`` [10]_ ``AUTO_INCREMENT`` [11]_ | -| | [8]_ +--------------------------+---------+----------------------------------------------------------+ -| | | **PostgreSQL** | *all* | ``BIGINT`` [12]_ | -| | | | +----------------------------------------------------------+ -| | | | | ``BIGSERIAL`` [11]_ | -| | +--------------------------+---------+----------------------------------------------------------+ -| | | **Oracle** | *all* | ``NUMBER(20)`` | -| | +--------------------------+---------+----------------------------------------------------------+ -| | | **SQL Server** | *all* | ``BIGINT`` ``IDENTITY`` [11]_ | -| | +--------------------------+---------+----------------------------------------------------------+ -| | | **SQLite** | *all* | ``INTEGER`` [15]_ | -+-------------------+---------------+--------------------------+---------+----------------------------------------------------------+ -| **decimal** [7]_ | ``string`` | **MySQL** | *all* | ``NUMERIC(p, s)`` ``UNSIGNED`` [10]_ | -| | [9]_ +--------------------------+---------+----------------------------------------------------------+ -| | | **PostgreSQL** | *all* | ``NUMERIC(p, s)`` | -| | +--------------------------+ | | -| | | **Oracle** | | | -| | +--------------------------+ | | -| | | **SQL Server** | | | -| | +--------------------------+ | | -| | | **SQLite** | | | -+-------------------+---------------+--------------------------+---------+----------------------------------------------------------+ -| **float** | ``float`` | **MySQL** | *all* | ``DOUBLE PRECISION`` ``UNSIGNED`` [10]_ | -| | +--------------------------+---------+----------------------------------------------------------+ -| | | **PostgreSQL** | *all* | ``DOUBLE PRECISION`` | -| | +--------------------------+ | | -| | | **Oracle** | | | -| | +--------------------------+ | | -| | | **SQL Server** | | | -| | +--------------------------+ | | -| | | **SQLite** | | | -+-------------------+---------------+--------------------------+---------+----------------------------------------------------------+ -| **string** | ``string`` | **MySQL** | *all* | ``VARCHAR(n)`` [3]_ | -| [2]_ [5]_ | +--------------------------+ | | -| | | **PostgreSQL** | | | -| | +--------------------------+ +----------------------------------------------------------+ -| | | **SQLite** | | | -| | +--------------------------+---------+----------------------------------------------------------+ -| | | **Oracle** | *all* | ``VARCHAR2(n)`` [3]_ | -| | | | +----------------------------------------------------------+ -| | | | | ``CHAR(n)`` [4]_ | -| | +--------------------------+---------+----------------------------------------------------------+ -| | | **SQL Server** | *all* | ``NVARCHAR(n)`` [3]_ | -| | | | +----------------------------------------------------------+ -| | | | | ``NCHAR(n)`` [4]_ | -+-------------------+---------------+--------------------------+---------+----------------------------------------------------------+ -| **ascii_string** | ``string`` | **SQL Server** | | ``VARCHAR(n)`` | -| | | | | ``CHAR(n)`` | -+-------------------+---------------+--------------------------+---------+----------------------------------------------------------+ -| **text** | ``string`` | **MySQL** | *all* | ``TINYTEXT`` [16]_ | -| | | | +----------------------------------------------------------+ -| | | | | ``TEXT`` [17]_ | -| | | | +----------------------------------------------------------+ -| | | | | ``MEDIUMTEXT`` [18]_ | -| | | | +----------------------------------------------------------+ -| | | | | ``LONGTEXT`` [19]_ | -| | +--------------------------+---------+----------------------------------------------------------+ -| | | **PostgreSQL** | *all* | ``TEXT`` | -| | +--------------------------+ | | -| | | **Oracle** | *all* | ``CLOB`` | -| | +--------------------------+ | | -| | | **SQLite** | | | -| | +--------------------------+---------+----------------------------------------------------------+ -| | | **SQL Server** | *all* | ``VARCHAR(MAX)`` | -+-------------------+---------------+--------------------------+---------+----------------------------------------------------------+ -| **guid** | ``string`` | **MySQL** | *all* | ``VARCHAR(255)`` [1]_ | -| | +--------------------------+ | | -| | | **Oracle** | | | -| | +--------------------------+ | | -| | | **SQLite** | | | -| | +--------------------------+---------+----------------------------------------------------------+ -| | | **SQL Server** | *all* | ``UNIQUEIDENTIFIER`` | -| | +--------------------------+ | | -| | | **PostgreSQL** | *all* | ``UUID`` | -+-------------------+---------------+--------------------------+---------+----------------------------------------------------------+ -| **binary** | ``resource`` | **MySQL** | *all* | ``VARBINARY(n)`` [3]_ | -| [2]_ [6]_ | +--------------------------+ | | -| | | **SQL Server** | +----------------------------------------------------------+ -| | +--------------------------+ | ``BINARY(n)`` [4]_ | -| | | **Oracle** | *all* | ``RAW(n)`` | -| | +--------------------------+---------+----------------------------------------------------------+ -| | | **PostgreSQL** | *all* | ``BYTEA`` [15]_ | -| | +--------------------------+---------+----------------------------------------------------------+ -| | | **SQLite** | *all* | ``BLOB`` [15]_ | -+-------------------+---------------+--------------------------+---------+----------------------------------------------------------+ -| **blob** | ``resource`` | **MySQL** | *all* | ``TINYBLOB`` [16]_ | -| | | | +----------------------------------------------------------+ -| | | | | ``BLOB`` [17]_ | -| | | | +----------------------------------------------------------+ -| | | | | ``MEDIUMBLOB`` [18]_ | -| | | | +----------------------------------------------------------+ -| | | | | ``LONGBLOB`` [19]_ | -| | +--------------------------+---------+----------------------------------------------------------+ -| | | **Oracle** | *all* | ``BLOB`` | -| | +--------------------------+ | | -| | | **SQLite** | | | -| | +--------------------------+---------+----------------------------------------------------------+ -| | | **SQL Server** | *all* | ``VARBINARY(MAX)`` | -| | +--------------------------+---------+----------------------------------------------------------+ -| | | **PostgreSQL** | *all* | ``BYTEA`` | -+-------------------+---------------+--------------------------+---------+----------------------------------------------------------+ -| **boolean** | ``boolean`` | **MySQL** | *all* | ``TINYINT(1)`` | -| | +--------------------------+---------+----------------------------------------------------------+ -| | | **PostgreSQL** | *all* | ``BOOLEAN`` | -| | +--------------------------+ | | -| | | **SQLite** | | | -| | +--------------------------+---------+----------------------------------------------------------+ -| | | **SQL Server** | *all* | ``BIT`` | -| | +--------------------------+ | | -| | | **Oracle** | *all* | ``NUMBER(1)`` | -+-------------------+---------------+--------------------------+---------+----------------------------------------------------------+ -| **date** | ``\DateTime`` | **MySQL** | *all* | ``DATE`` | -| | +--------------------------+ | | -| | | **PostgreSQL** | | | -| | +--------------------------+ | | -| | | **Oracle** | | | -| | +--------------------------+ | | -| | | **SQLite** | | | -| | +--------------------------+---------+ | -| | | **SQL Server** | "all" | | -+-------------------+---------------+--------------------------+---------+----------------------------------------------------------+ -| **datetime** | ``\DateTime`` | **MySQL** | *all* | ``DATETIME`` [13]_ | -| | +--------------------------+---------+----------------------------------------------------------+ -| | | **SQL Server** | *all* | ``DATETIME`` | -| | +--------------------------+ | | -| | | **SQLite** | | | -| | +--------------------------+---------+----------------------------------------------------------+ -| | | **PostgreSQL** | *all* | ``TIMESTAMP(0) WITHOUT TIME ZONE`` | -| | +--------------------------+---------+----------------------------------------------------------+ -| | | **Oracle** | *all* | ``TIMESTAMP(0)`` | -+-------------------+---------------+--------------------------+---------+----------------------------------------------------------+ -| **datetimetz** | ``\DateTime`` | **MySQL** | *all* | ``DATETIME`` [14]_ [15]_ | -| | +--------------------------+ | | -| | | **SQLite** | | | -| | +--------------------------+---------+ | -| | | **SQL Server** | "all" | | -| | +--------------------------+---------+----------------------------------------------------------+ -| | | **PostgreSQL** | *all* | ``TIMESTAMP(0) WITH TIME ZONE`` | -| | +--------------------------+ | | -| | | **Oracle** | | | -+-------------------+---------------+--------------------------+---------+----------------------------------------------------------+ -| **time** | ``\DateTime`` | **MySQL** | *all* | ``TIME`` | -| | +--------------------------+ | | -| | | **SQLite** | | | -| | +--------------------------+---------+----------------------------------------------------------+ -| | | **PostgreSQL** | *all* | ``TIME(0) WITHOUT TIME ZONE`` | -| | +--------------------------+---------+----------------------------------------------------------+ -| | | **Oracle** | *all* | ``DATE`` [15]_ | -| | +--------------------------+---------+----------------------------------------------------------+ -| | | **SQL Server** | "all" | ``TIME(0)`` | -+-------------------+---------------+--------------------------+---------+----------------------------------------------------------+ -| **array** [1]_ | ``array`` | **MySQL** | *all* | ``TINYTEXT`` [16]_ | -+-------------------+ | | +----------------------------------------------------------+ -| **simple array** | | | | ``TEXT`` [17]_ | -| [1]_ | | | +----------------------------------------------------------+ -| | | | | ``MEDIUMTEXT`` [18]_ | -| | | | +----------------------------------------------------------+ -| | | | | ``LONGTEXT`` [19]_ | -| | +--------------------------+---------+----------------------------------------------------------+ -| | | **PostgreSQL** | *all* | ``TEXT`` | -| | +--------------------------+ | | -| | | **Oracle** | *all* | ``CLOB`` | -| | +--------------------------+ | | -| | | **SQLite** | | | -| | +--------------------------+---------+----------------------------------------------------------+ -| | | **SQL Server** | *all* | ``VARCHAR(MAX)`` | -+-------------------+---------------+--------------------------+---------+----------------------------------------------------------+ -| **json** | ``mixed`` | **MySQL** | *all* | ``JSON`` | -| | +--------------------------+---------+----------------------------------------------------------+ -| | | **PostgreSQL** | *all* | ``JSON`` [20]_ | -| | | | +----------------------------------------------------------+ -| | | | | ``JSONB`` [21]_ | -| | +--------------------------+---------+----------------------------------------------------------+ -| | | **Oracle** | *all* | ``CLOB`` [1]_ | -| | +--------------------------+ | | -| | | **SQLite** | | | -| | +--------------------------+---------+----------------------------------------------------------+ -| | | **SQL Server** | *all* | ``VARCHAR(MAX)`` [1]_ | -+-------------------+---------------+--------------------------+---------+----------------------------------------------------------+ -| **object** [1]_ | ``object`` | **MySQL** | *all* | ``TINYTEXT`` [16]_ | -| | | | +----------------------------------------------------------+ -| | | | | ``TEXT`` [17]_ | -| | | | +----------------------------------------------------------+ -| | | | | ``MEDIUMTEXT`` [18]_ | -| | | | +----------------------------------------------------------+ -| | | | | ``LONGTEXT`` [19]_ | -| | +--------------------------+---------+----------------------------------------------------------+ -| | | **PostgreSQL** | *all* | ``TEXT`` | -| | +--------------------------+ | | -| | | **Oracle** | *all* | ``CLOB`` | -| | +--------------------------+ | | -| | | **SQLite** | | | -| | +--------------------------+---------+----------------------------------------------------------+ -| | | **SQL Server** | *all* | ``VARCHAR(MAX)`` | -+-------------------+---------------+--------------------------+---------+----------------------------------------------------------+ - -.. [1] Requires hint in the column comment for proper reverse engineering of the appropriate - Doctrine type mapping. -.. [2] **n** is the **length** attribute set in the column definition (defaults to 255 if omitted). -.. [3] Chosen if the column definition has the **fixed** attribute set to ``false`` (default). -.. [4] Chosen if the column definition has the **fixed** attribute set to ``true``. -.. [5] Silently maps to the vendor specific ``text`` type if the given **length** attribute for - **n** exceeds the maximum length the related platform allows. If this is the case, please - see [15]_. -.. [6] Silently maps to the vendor specific ``blob`` type if the given **length** attribute for - **n** exceeds the maximum length the related platform allows. If this is the case, please - see [15]_. -.. [7] **p** is the precision and **s** the scale set in the column definition. - The precision defaults to ``10`` and the scale to ``0`` if not set. -.. [8] Returns PHP ``string`` type value instead of ``integer`` because of maximum integer value - implications on non 64bit platforms. -.. [9] Returns PHP ``string`` type value instead of ``double`` because of PHP's limitation in - preserving the exact precision when casting to ``double``. -.. [10] Used if **unsigned** attribute is set to ``true`` in the column definition (default ``false``). -.. [11] Used if **autoincrement** attribute is set to ``true`` in the column definition (default ``false``). -.. [12] Chosen if the column definition has the **autoincrement** attribute set to ``false`` (default). -.. [13] Chosen if the column definition does not contain the **version** option inside the **platformOptions** - attribute array or is set to ``false`` which marks it as a non-locking information column. -.. [14] Fallback type as the vendor does not support a native date time type with timezone information. - This means that the timezone information gets lost when storing a value. -.. [15] Cannot be safely reverse engineered to the same Doctrine type as the vendor does not have a - native distinct data type for this mapping. Using this type with this vendor can therefore - have implications on schema comparison (*online* vs *offline* schema) and PHP type safety - (data conversion from database to PHP value) because it silently falls back to its - appropriate Doctrine type. -.. [16] Chosen if the column length is less or equal to **2 ^ 8 - 1 = 255**. -.. [17] Chosen if the column length is less or equal to **2 ^ 16 - 1 = 65535**. -.. [18] Chosen if the column length is less or equal to **2 ^ 24 - 1 = 16777215**. -.. [19] Chosen if the column length is less or equal to **2 ^ 32 - 1 = 4294967295** or empty. -.. [20] Chosen if the column definition does not contain the **jsonb** option inside the **platformOptions** - attribute array or is set to ``false``. -.. [21] Chosen if the column definition contains the **jsonb** option inside the **platformOptions** - attribute array and is set to ``true``. + +-------------------+---------------+-----------------------------------------------------------------------------------------------+ + | Doctrine | PHP | Database vendor | + | | +--------------------------+---------+----------------------------------------------------------+ + | | | Name | Version | Type | + +===================+===============+==========================+=========+==========================================================+ + | **smallint** | ``integer`` | **MySQL** | *all* | ``SMALLINT`` ``UNSIGNED`` [10] ``AUTO_INCREMENT`` [11] | + | | +--------------------------+---------+----------------------------------------------------------+ + | | | **PostgreSQL** | *all* | ``SMALLINT`` | + | | +--------------------------+---------+----------------------------------------------------------+ + | | | **Oracle** | *all* | ``NUMBER(5)`` | + | | +--------------------------+---------+----------------------------------------------------------+ + | | | **SQL Server** | *all* | ``SMALLINT`` ``IDENTITY`` [11] | + | | +--------------------------+---------+----------------------------------------------------------+ + | | | **SQLite** | *all* | ``INTEGER`` [15] | + +-------------------+---------------+--------------------------+---------+----------------------------------------------------------+ + | **integer** | ``integer`` | **MySQL** | *all* | ``INT`` ``UNSIGNED`` [10] ``AUTO_INCREMENT`` [11] | + | | +--------------------------+---------+----------------------------------------------------------+ + | | | **PostgreSQL** | *all* | ``INT`` [12] | + | | | | +----------------------------------------------------------+ + | | | | | ``SERIAL`` [11] | + | | +--------------------------+---------+----------------------------------------------------------+ + | | | **Oracle** | *all* | ``NUMBER(10)`` | + | | +--------------------------+---------+----------------------------------------------------------+ + | | | **SQL Server** | *all* | ``INT`` ``IDENTITY`` [11] | + | | +--------------------------+---------+----------------------------------------------------------+ + | | | **SQLite** | *all* | ``INTEGER`` [15] | + +-------------------+---------------+--------------------------+---------+----------------------------------------------------------+ + | **bigint** | ``string`` | **MySQL** | *all* | ``BIGINT`` ``UNSIGNED`` [10] ``AUTO_INCREMENT`` [11] | + | | [8] +--------------------------+---------+----------------------------------------------------------+ + | | | **PostgreSQL** | *all* | ``BIGINT`` [12] | + | | | | +----------------------------------------------------------+ + | | | | | ``BIGSERIAL`` [11] | + | | +--------------------------+---------+----------------------------------------------------------+ + | | | **Oracle** | *all* | ``NUMBER(20)`` | + | | +--------------------------+---------+----------------------------------------------------------+ + | | | **SQL Server** | *all* | ``BIGINT`` ``IDENTITY`` [11] | + | | +--------------------------+---------+----------------------------------------------------------+ + | | | **SQLite** | *all* | ``INTEGER`` [15] | + +-------------------+---------------+--------------------------+---------+----------------------------------------------------------+ + | **decimal** [7] | ``string`` | **MySQL** | *all* | ``NUMERIC(p, s)`` ``UNSIGNED`` [10] | + | | [9] +--------------------------+---------+----------------------------------------------------------+ + | | | **PostgreSQL** | *all* | ``NUMERIC(p, s)`` | + | | +--------------------------+ | | + | | | **Oracle** | | | + | | +--------------------------+ | | + | | | **SQL Server** | | | + | | +--------------------------+ | | + | | | **SQLite** | | | + +-------------------+---------------+--------------------------+---------+----------------------------------------------------------+ + | **float** | ``float`` | **MySQL** | *all* | ``DOUBLE PRECISION`` ``UNSIGNED`` [10] | + | | +--------------------------+---------+----------------------------------------------------------+ + | | | **PostgreSQL** | *all* | ``DOUBLE PRECISION`` | + | | +--------------------------+ | | + | | | **Oracle** | | | + | | +--------------------------+ | | + | | | **SQL Server** | | | + | | +--------------------------+ | | + | | | **SQLite** | | | + +-------------------+---------------+--------------------------+---------+----------------------------------------------------------+ + | **string** | ``string`` | **MySQL** | *all* | ``VARCHAR(n)`` [3] | + | [2] [5] | +--------------------------+ | | + | | | **PostgreSQL** | | | + | | +--------------------------+ +----------------------------------------------------------+ + | | | **SQLite** | | | + | | +--------------------------+---------+----------------------------------------------------------+ + | | | **Oracle** | *all* | ``VARCHAR2(n)`` [3] | + | | | | +----------------------------------------------------------+ + | | | | | ``CHAR(n)`` [4] | + | | +--------------------------+---------+----------------------------------------------------------+ + | | | **SQL Server** | *all* | ``NVARCHAR(n)`` [3] | + | | | | +----------------------------------------------------------+ + | | | | | ``NCHAR(n)`` [4] | + +-------------------+---------------+--------------------------+---------+----------------------------------------------------------+ + | **ascii_string** | ``string`` | **SQL Server** | | ``VARCHAR(n)`` | + | | | | | ``CHAR(n)`` | + +-------------------+---------------+--------------------------+---------+----------------------------------------------------------+ + | **text** | ``string`` | **MySQL** | *all* | ``TINYTEXT`` [16] | + | | | | +----------------------------------------------------------+ + | | | | | ``TEXT`` [17] | + | | | | +----------------------------------------------------------+ + | | | | | ``MEDIUMTEXT`` [18] | + | | | | +----------------------------------------------------------+ + | | | | | ``LONGTEXT`` [19] | + | | +--------------------------+---------+----------------------------------------------------------+ + | | | **PostgreSQL** | *all* | ``TEXT`` | + | | +--------------------------+ | | + | | | **Oracle** | *all* | ``CLOB`` | + | | +--------------------------+ | | + | | | **SQLite** | | | + | | +--------------------------+---------+----------------------------------------------------------+ + | | | **SQL Server** | *all* | ``VARCHAR(MAX)`` | + +-------------------+---------------+--------------------------+---------+----------------------------------------------------------+ + | **guid** | ``string`` | **MySQL** | *all* | ``VARCHAR(255)`` [1] | + | | +--------------------------+ | | + | | | **Oracle** | | | + | | +--------------------------+ | | + | | | **SQLite** | | | + | | +--------------------------+---------+----------------------------------------------------------+ + | | | **SQL Server** | *all* | ``UNIQUEIDENTIFIER`` | + | | +--------------------------+ | | + | | | **PostgreSQL** | *all* | ``UUID`` | + +-------------------+---------------+--------------------------+---------+----------------------------------------------------------+ + | **binary** | ``resource`` | **MySQL** | *all* | ``VARBINARY(n)`` [3] | + | [2] [6] | +--------------------------+ | | + | | | **SQL Server** | +----------------------------------------------------------+ + | | +--------------------------+ | ``BINARY(n)`` [4] | + | | | **Oracle** | *all* | ``RAW(n)`` | + | | +--------------------------+---------+----------------------------------------------------------+ + | | | **PostgreSQL** | *all* | ``BYTEA`` [15] | + | | +--------------------------+---------+----------------------------------------------------------+ + | | | **SQLite** | *all* | ``BLOB`` [15] | + +-------------------+---------------+--------------------------+---------+----------------------------------------------------------+ + | **blob** | ``resource`` | **MySQL** | *all* | ``TINYBLOB`` [16] | + | | | | +----------------------------------------------------------+ + | | | | | ``BLOB`` [17] | + | | | | +----------------------------------------------------------+ + | | | | | ``MEDIUMBLOB`` [18] | + | | | | +----------------------------------------------------------+ + | | | | | ``LONGBLOB`` [19] | + | | +--------------------------+---------+----------------------------------------------------------+ + | | | **Oracle** | *all* | ``BLOB`` | + | | +--------------------------+ | | + | | | **SQLite** | | | + | | +--------------------------+---------+----------------------------------------------------------+ + | | | **SQL Server** | *all* | ``VARBINARY(MAX)`` | + | | +--------------------------+---------+----------------------------------------------------------+ + | | | **PostgreSQL** | *all* | ``BYTEA`` | + +-------------------+---------------+--------------------------+---------+----------------------------------------------------------+ + | **boolean** | ``boolean`` | **MySQL** | *all* | ``TINYINT(1)`` | + | | +--------------------------+---------+----------------------------------------------------------+ + | | | **PostgreSQL** | *all* | ``BOOLEAN`` | + | | +--------------------------+ | | + | | | **SQLite** | | | + | | +--------------------------+---------+----------------------------------------------------------+ + | | | **SQL Server** | *all* | ``BIT`` | + | | +--------------------------+ | | + | | | **Oracle** | *all* | ``NUMBER(1)`` | + +-------------------+---------------+--------------------------+---------+----------------------------------------------------------+ + | **date** | ``\DateTime`` | **MySQL** | *all* | ``DATE`` | + | | +--------------------------+ | | + | | | **PostgreSQL** | | | + | | +--------------------------+ | | + | | | **Oracle** | | | + | | +--------------------------+ | | + | | | **SQLite** | | | + | | +--------------------------+---------+ | + | | | **SQL Server** | "all" | | + +-------------------+---------------+--------------------------+---------+----------------------------------------------------------+ + | **datetime** | ``\DateTime`` | **MySQL** | *all* | ``DATETIME`` [13] | + | | +--------------------------+---------+----------------------------------------------------------+ + | | | **SQL Server** | *all* | ``DATETIME`` | + | | +--------------------------+ | | + | | | **SQLite** | | | + | | +--------------------------+---------+----------------------------------------------------------+ + | | | **PostgreSQL** | *all* | ``TIMESTAMP(0) WITHOUT TIME ZONE`` | + | | +--------------------------+---------+----------------------------------------------------------+ + | | | **Oracle** | *all* | ``TIMESTAMP(0)`` | + +-------------------+---------------+--------------------------+---------+----------------------------------------------------------+ + | **datetimetz** | ``\DateTime`` | **MySQL** | *all* | ``DATETIME`` [14] [15] | + | | +--------------------------+ | | + | | | **SQLite** | | | + | | +--------------------------+---------+ | + | | | **SQL Server** | "all" | | + | | +--------------------------+---------+----------------------------------------------------------+ + | | | **PostgreSQL** | *all* | ``TIMESTAMP(0) WITH TIME ZONE`` | + | | +--------------------------+ | | + | | | **Oracle** | | | + +-------------------+---------------+--------------------------+---------+----------------------------------------------------------+ + | **time** | ``\DateTime`` | **MySQL** | *all* | ``TIME`` | + | | +--------------------------+ | | + | | | **SQLite** | | | + | | +--------------------------+---------+----------------------------------------------------------+ + | | | **PostgreSQL** | *all* | ``TIME(0) WITHOUT TIME ZONE`` | + | | +--------------------------+---------+----------------------------------------------------------+ + | | | **Oracle** | *all* | ``DATE`` [15] | + | | +--------------------------+---------+----------------------------------------------------------+ + | | | **SQL Server** | "all" | ``TIME(0)`` | + +-------------------+---------------+--------------------------+---------+----------------------------------------------------------+ + | **array** [1] | ``array`` | **MySQL** | *all* | ``TINYTEXT`` [16] | + +-------------------+ | | +----------------------------------------------------------+ + | **simple array** | | | | ``TEXT`` [17] | + | [1] | | | +----------------------------------------------------------+ + | | | | | ``MEDIUMTEXT`` [18] | + | | | | +----------------------------------------------------------+ + | | | | | ``LONGTEXT`` [19] | + | | +--------------------------+---------+----------------------------------------------------------+ + | | | **PostgreSQL** | *all* | ``TEXT`` | + | | +--------------------------+ | | + | | | **Oracle** | *all* | ``CLOB`` | + | | +--------------------------+ | | + | | | **SQLite** | | | + | | +--------------------------+---------+----------------------------------------------------------+ + | | | **SQL Server** | *all* | ``VARCHAR(MAX)`` | + +-------------------+---------------+--------------------------+---------+----------------------------------------------------------+ + | **json** | ``mixed`` | **MySQL** | *all* | ``JSON`` | + | | +--------------------------+---------+----------------------------------------------------------+ + | | | **PostgreSQL** | *all* | ``JSON`` [20] | + | | | | +----------------------------------------------------------+ + | | | | | ``JSONB`` [21] | + | | +--------------------------+---------+----------------------------------------------------------+ + | | | **Oracle** | *all* | ``CLOB`` [1] | + | | +--------------------------+ | | + | | | **SQLite** | | | + | | +--------------------------+---------+----------------------------------------------------------+ + | | | **SQL Server** | *all* | ``VARCHAR(MAX)`` [1] | + +-------------------+---------------+--------------------------+---------+----------------------------------------------------------+ + | **object** [1] | ``object`` | **MySQL** | *all* | ``TINYTEXT`` [16] | + | | | | +----------------------------------------------------------+ + | | | | | ``TEXT`` [17] | + | | | | +----------------------------------------------------------+ + | | | | | ``MEDIUMTEXT`` [18] | + | | | | +----------------------------------------------------------+ + | | | | | ``LONGTEXT`` [19] | + | | +--------------------------+---------+----------------------------------------------------------+ + | | | **PostgreSQL** | *all* | ``TEXT`` | + | | +--------------------------+ | | + | | | **Oracle** | *all* | ``CLOB`` | + | | +--------------------------+ | | + | | | **SQLite** | | | + | | +--------------------------+---------+----------------------------------------------------------+ + | | | **SQL Server** | *all* | ``VARCHAR(MAX)`` | + +-------------------+---------------+--------------------------+---------+----------------------------------------------------------+ + +**Notes** + +* [1] Requires hint in the column comment for proper reverse engineering of the appropriate + Doctrine type mapping. +* [2] **n** is the **length** attribute set in the column definition (defaults to 255 if omitted). +* [3] Chosen if the column definition has the **fixed** attribute set to ``false`` (default). +* [4] Chosen if the column definition has the **fixed** attribute set to ``true``. +* [5] Silently maps to the vendor specific ``text`` type if the given **length** attribute for + **n** exceeds the maximum length the related platform allows. If this is the case, please + see [15] . +* [6] Silently maps to the vendor specific ``blob`` type if the given **length** attribute for + **n** exceeds the maximum length the related platform allows. If this is the case, please + see [15] . +* [7] **p** is the precision and **s** the scale set in the column definition. + The precision defaults to ``10`` and the scale to ``0`` if not set. +* [8] Returns PHP ``string`` type value instead of ``integer`` because of maximum integer value + implications on non 64bit platforms. +* [9] Returns PHP ``string`` type value instead of ``double`` because of PHP's limitation in + preserving the exact precision when casting to ``double``. +* [10] Used if **unsigned** attribute is set to ``true`` in the column definition (default ``false``). +* [11] Used if **autoincrement** attribute is set to ``true`` in the column definition (default ``false``). +* [12] Chosen if the column definition has the **autoincrement** attribute set to ``false`` (default). +* [13] Chosen if the column definition does not contain the **version** option inside the **platformOptions** + attribute array or is set to ``false`` which marks it as a non-locking information column. +* [14] Fallback type as the vendor does not support a native date time type with timezone information. + This means that the timezone information gets lost when storing a value. +* [15] Cannot be safely reverse engineered to the same Doctrine type as the vendor does not have a + native distinct data type for this mapping. Using this type with this vendor can therefore + have implications on schema comparison (*online* vs *offline* schema) and PHP type safety + (data conversion from database to PHP value) because it silently falls back to its + appropriate Doctrine type. +* [16] Chosen if the column length is less or equal to **2 ^ 8 - 1 = 255**. +* [17] Chosen if the column length is less or equal to **2 ^ 16 - 1 = 65535**. +* [18] Chosen if the column length is less or equal to **2 ^ 24 - 1 = 16777215**. +* [19] Chosen if the column length is less or equal to **2 ^ 32 - 1 = 4294967295** or empty. +* [20] Chosen if the column definition does not contain the **jsonb** option inside the **platformOptions** + attribute array or is set to ``false``. +* [21] Chosen if the column definition contains the **jsonb** option inside the **platformOptions** + attribute array and is set to ``true``. Detection of Database Types --------------------------- From 160ab1bfee421e0eddd21ea1df73fb104fd6609d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Sat, 22 Jan 2022 12:31:47 +0100 Subject: [PATCH 08/12] Make test cases easier to identify --- tests/Functional/Schema/ComparatorTest.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tests/Functional/Schema/ComparatorTest.php b/tests/Functional/Schema/ComparatorTest.php index 189336f445e..e7cb8e6e734 100644 --- a/tests/Functional/Schema/ComparatorTest.php +++ b/tests/Functional/Schema/ComparatorTest.php @@ -10,6 +10,8 @@ use Doctrine\DBAL\Tests\FunctionalTestCase; use function array_merge; +use function sprintf; +use function var_export; class ComparatorTest extends FunctionalTestCase { @@ -44,14 +46,19 @@ public function testDefaultValueComparison(callable $comparatorFactory, string $ */ public static function defaultValueProvider(): iterable { - foreach (ComparatorTestUtils::comparatorProvider() as $comparatorArguments) { + foreach (ComparatorTestUtils::comparatorProvider() as $comparatorType => $comparatorArguments) { foreach ( [ ['integer', 1], ['boolean', false], ] as $testArguments ) { - yield array_merge($comparatorArguments, $testArguments); + yield sprintf( + '%s with default %s value %s', + $comparatorType, + $testArguments[0], + var_export($testArguments[1], true) + ) => array_merge($comparatorArguments, $testArguments); } } } From 8d596ac519a9049127c56e6a961956467dca99b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Sun, 23 Jan 2022 12:12:17 +0100 Subject: [PATCH 09/12] Explain former main purpose of the comments That documentation looks quite strange right now because the only described use-case is not very convincing. --- docs/en/explanation/dc2type-comments.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/en/explanation/dc2type-comments.rst b/docs/en/explanation/dc2type-comments.rst index 8a669a0449c..2b5f18d0962 100644 --- a/docs/en/explanation/dc2type-comments.rst +++ b/docs/en/explanation/dc2type-comments.rst @@ -37,3 +37,11 @@ A table with such a column may have a declaration that looks as follows: …, PRIMARY KEY(uuid) ) + +In the past, these comments were also useful to avoid false positives +when diffing a schema created with the DBAL API with a schema +introspected from the database. Since `platform-aware comparison was +introduced in 3.2.0 +`_, this is +no longer the case. They must be kept in order to keep the +platform-unaware comparison APIs working though. From 68f5935d514e6b6bef9949b53e9c132ec0d8ee7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Sun, 23 Jan 2022 12:13:01 +0100 Subject: [PATCH 10/12] Warn against relying on DC2Type comments. --- docs/en/explanation/dc2type-comments.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/en/explanation/dc2type-comments.rst b/docs/en/explanation/dc2type-comments.rst index 2b5f18d0962..cdce6da8e6e 100644 --- a/docs/en/explanation/dc2type-comments.rst +++ b/docs/en/explanation/dc2type-comments.rst @@ -45,3 +45,6 @@ introduced in 3.2.0 `_, this is no longer the case. They must be kept in order to keep the platform-unaware comparison APIs working though. + +It is important to note that these comments are an implementation detail +of the DBAL and should not be relied upon by application code. From 0ed09e17061595475dfb1ed5bcb53c625098098c Mon Sep 17 00:00:00 2001 From: Sergei Morozov Date: Sun, 23 Jan 2022 09:14:41 -0800 Subject: [PATCH 11/12] Optimize AbstractMySQLPlatform::getListTableForeignKeysSQL() --- src/Platforms/AbstractMySQLPlatform.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Platforms/AbstractMySQLPlatform.php b/src/Platforms/AbstractMySQLPlatform.php index 9030f30c3da..43b9eb81427 100644 --- a/src/Platforms/AbstractMySQLPlatform.php +++ b/src/Platforms/AbstractMySQLPlatform.php @@ -179,15 +179,18 @@ public function getListViewsSQL($database) */ public function getListTableForeignKeysSQL($table, $database = null) { + // The schema name is passed multiple times as a literal in the WHERE clause instead of using a JOIN condition + // in order to avoid performance issues on MySQL older than 8.0 and the corresponding MariaDB versions + // caused by https://bugs.mysql.com/bug.php?id=81347 return 'SELECT k.CONSTRAINT_NAME, k.COLUMN_NAME, k.REFERENCED_TABLE_NAME, ' . 'k.REFERENCED_COLUMN_NAME /*!50116 , c.UPDATE_RULE, c.DELETE_RULE */ ' . 'FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE k /*!50116 ' . 'INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS c ON ' . 'c.CONSTRAINT_NAME = k.CONSTRAINT_NAME AND ' . - 'c.TABLE_NAME = k.TABLE_NAME AND ' . - 'c.CONSTRAINT_SCHEMA = k.CONSTRAINT_SCHEMA */ ' . + 'c.TABLE_NAME = k.TABLE_NAME */ ' . 'WHERE k.TABLE_NAME = ' . $this->quoteStringLiteral($table) . ' ' . - 'AND k.TABLE_SCHEMA = ' . $this->getDatabaseNameSQL($database) . ' ' . + 'AND k.TABLE_SCHEMA = ' . $this->getDatabaseNameSQL($database) . ' /*!50116 ' . + 'AND c.CONSTRAINT_SCHEMA = ' . $this->getDatabaseNameSQL($database) . ' */' . 'ORDER BY k.ORDINAL_POSITION'; } From 9a929bb34a749d9d558d809d988e125e79ee5195 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Sun, 23 Jan 2022 20:02:03 +0100 Subject: [PATCH 12/12] Deprecate methods related to type comments This implementation detail is going to be removed in 4.0 AbstractSchemaManager::extractDoctrineTypeFromComment() is already marked as internal. --- UPGRADE.md | 8 ++++++++ docs/en/explanation/dc2type-comments.rst | 3 ++- psalm.xml.dist | 5 +++++ src/Platforms/AbstractPlatform.php | 18 ++++++++++++++++++ 4 files changed, 33 insertions(+), 1 deletion(-) diff --git a/UPGRADE.md b/UPGRADE.md index 386b5f15b55..dab5b16032b 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -6,6 +6,14 @@ awareness about deprecated code. - Use of our low-overhead runtime deprecation API, details: https://github.com/doctrine/deprecations/ +# Upgrade to 3.4 + +# Deprecated `AbstractPlatform::getColumnComment()` and `AbstractPlatform::getDoctrineTypeComment()` + +DBAL no longer needs column comments to ensure proper diffing. Note that both +methods should probably have been marked as internal as these comments were an +implementation detail of the DBAL. + # Upgrade to 3.3 ## Deprecated `Type::canRequireSQLConversion()`. diff --git a/docs/en/explanation/dc2type-comments.rst b/docs/en/explanation/dc2type-comments.rst index cdce6da8e6e..6193603faef 100644 --- a/docs/en/explanation/dc2type-comments.rst +++ b/docs/en/explanation/dc2type-comments.rst @@ -47,4 +47,5 @@ no longer the case. They must be kept in order to keep the platform-unaware comparison APIs working though. It is important to note that these comments are an implementation detail -of the DBAL and should not be relied upon by application code. +of the DBAL and should not be relied upon by application code. They are +removed in DBAL 4.0. diff --git a/psalm.xml.dist b/psalm.xml.dist index 196787652cd..e9c0cf2bf18 100644 --- a/psalm.xml.dist +++ b/psalm.xml.dist @@ -224,6 +224,11 @@ See https://github.com/doctrine/dbal/pull/5136 --> + + diff --git a/src/Platforms/AbstractPlatform.php b/src/Platforms/AbstractPlatform.php index 5b9d645a9a0..94a7289dda9 100644 --- a/src/Platforms/AbstractPlatform.php +++ b/src/Platforms/AbstractPlatform.php @@ -499,20 +499,38 @@ public function markDoctrineTypeCommented($doctrineType) /** * Gets the comment to append to a column comment that helps parsing this type in reverse engineering. * + * @deprecated This method will be removed without replacement. + * * @return string */ public function getDoctrineTypeComment(Type $doctrineType) { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5107', + '%s is deprecated and will be removed in Doctrine DBAL 4.0.', + __METHOD__ + ); + return '(DC2Type:' . $doctrineType->getName() . ')'; } /** * Gets the comment of a passed column modified by potential doctrine type comment hints. * + * @deprecated This method will be removed without replacement. + * * @return string|null */ protected function getColumnComment(Column $column) { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5107', + '%s is deprecated and will be removed in Doctrine DBAL 4.0.', + __METHOD__ + ); + $comment = $column->getComment(); if ($column->getType()->requiresSQLCommentHint($this)) {