diff --git a/.doctrine-project.json b/.doctrine-project.json index 7b97cb45129..f68f2fd0bc3 100644 --- a/.doctrine-project.json +++ b/.doctrine-project.json @@ -11,21 +11,27 @@ "slug": "latest", "upcoming": true }, + { + "name": "2.11", + "branchName": "2.11.x", + "slug": "2.11", + "current": true, + "aliases": [ + "current", + "stable" + ] + }, { "name": "2.10", - "branchName": "master", + "branchName": "2.10.x", "slug": "2.10", - "upcoming": true + "maintained": false }, { "name": "2.9", "branchName": "2.9", "slug": "2.9", - "current": true, - "aliases": [ - "current", - "stable" - ] + "maintained": false }, { "name": "2.8", diff --git a/README.md b/README.md index 5a3582b8951..8f21ee0b5b5 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ # Doctrine DBAL -| [Master][Master] | [2.10][2.10] | +| [Master][Master] | [2.11][2.11] | |:----------------:|:----------:| -| [![Build status][Master image]][Master] | [![Build status][2.10 image]][2.10] | -| [![GitHub Actions][GA master image]][GA master] | [![GitHub Actions][GA 2.10 image]][GA 2.10] | -| [![AppVeyor][AppVeyor master image]][AppVeyor master] | [![AppVeyor][AppVeyor 2.10 image]][AppVeyor 2.10] | -| [![Code Coverage][Coverage image]][CodeCov Master] | [![Code Coverage][Coverage 2.10 image]][CodeCov 2.10] | +| [![Build status][Master image]][Master] | [![Build status][2.11 image]][2.11] | +| [![GitHub Actions][GA master image]][GA master] | [![GitHub Actions][GA 2.11 image]][GA 2.11] | +| [![AppVeyor][AppVeyor master image]][AppVeyor master] | [![AppVeyor][AppVeyor 2.11 image]][AppVeyor 2.11] | +| [![Code Coverage][Coverage image]][CodeCov Master] | [![Code Coverage][Coverage 2.11 image]][CodeCov 2.11] | Powerful database abstraction layer with many features for database schema introspection, schema management and PDO abstraction. @@ -24,11 +24,11 @@ Powerful database abstraction layer with many features for database schema intro [GA master]: https://github.com/doctrine/dbal/actions?query=workflow%3A%22Continuous+Integration%22+branch%3Amaster [GA master image]: https://github.com/doctrine/dbal/workflows/Continuous%20Integration/badge.svg - [2.10 image]: https://img.shields.io/travis/doctrine/dbal/2.10.x.svg?style=flat-square - [Coverage 2.10 image]: https://codecov.io/gh/doctrine/dbal/branch/2.10.x/graph/badge.svg - [2.10]: https://github.com/doctrine/dbal/tree/2.10.x - [CodeCov 2.10]: https://codecov.io/gh/doctrine/dbal/branch/2.10.x - [AppVeyor 2.10]: https://ci.appveyor.com/project/doctrine/dbal/branch/2.10.x - [AppVeyor 2.10 image]: https://ci.appveyor.com/api/projects/status/i88kitq8qpbm0vie/branch/2.10.x?svg=true - [GA 2.10]: https://github.com/doctrine/dbal/actions?query=workflow%3A%22Continuous+Integration%22+branch%3A2.10.x - [GA 2.10 image]: https://github.com/doctrine/dbal/workflows/Continuous%20Integration/badge.svg?branch=2.10.x + [2.11 image]: https://img.shields.io/travis/doctrine/dbal/2.11.x.svg?style=flat-square + [Coverage 2.11 image]: https://codecov.io/gh/doctrine/dbal/branch/2.11.x/graph/badge.svg + [2.11]: https://github.com/doctrine/dbal/tree/2.11.x + [CodeCov 2.11]: https://codecov.io/gh/doctrine/dbal/branch/2.11.x + [AppVeyor 2.11]: https://ci.appveyor.com/project/doctrine/dbal/branch/2.11.x + [AppVeyor 2.11 image]: https://ci.appveyor.com/api/projects/status/i88kitq8qpbm0vie/branch/2.11.x?svg=true + [GA 2.11]: https://github.com/doctrine/dbal/actions?query=workflow%3A%22Continuous+Integration%22+branch%3A2.11.x + [GA 2.11 image]: https://github.com/doctrine/dbal/workflows/Continuous%20Integration/badge.svg?branch=2.11.x diff --git a/composer.json b/composer.json index 4f426568812..cccc8b79223 100644 --- a/composer.json +++ b/composer.json @@ -65,8 +65,7 @@ }, "extra": { "branch-alias": { - "dev-master": "2.10.x-dev", - "dev-develop": "3.0.x-dev" + "dev-master": "4.0.x-dev" } } } diff --git a/composer.lock b/composer.lock index 39861217bda..ef6eaecdcf6 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "d336c771203e06590d3d78d116932bfd", + "content-hash": "7e19c98c2c188b8f60c2e434acdc980e", "packages": [ { "name": "composer/package-versions-deprecated", @@ -59,6 +59,10 @@ } ], "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", + "support": { + "issues": "https://github.com/composer/package-versions-deprecated/issues", + "source": "https://github.com/composer/package-versions-deprecated/tree/1.10.99.1" + }, "funding": [ { "url": "https://packagist.com", @@ -147,6 +151,10 @@ "cache", "caching" ], + "support": { + "issues": "https://github.com/doctrine/cache/issues", + "source": "https://github.com/doctrine/cache/tree/v1.7.1" + }, "time": "2017-08-25T07:02:50+00:00" }, { @@ -221,6 +229,10 @@ "eventdispatcher", "eventmanager" ], + "support": { + "issues": "https://github.com/doctrine/event-manager/issues", + "source": "https://github.com/doctrine/event-manager/tree/master" + }, "time": "2018-06-11T11:59:03+00:00" } ], @@ -301,6 +313,11 @@ "non-blocking", "promise" ], + "support": { + "irc": "irc://irc.freenode.org/amphp", + "issues": "https://github.com/amphp/amp/issues", + "source": "https://github.com/amphp/amp/tree/master" + }, "funding": [ { "url": "https://github.com/amphp", @@ -373,6 +390,11 @@ "non-blocking", "stream" ], + "support": { + "irc": "irc://irc.freenode.org/amphp", + "issues": "https://github.com/amphp/byte-stream/issues", + "source": "https://github.com/amphp/byte-stream/tree/master" + }, "time": "2020-06-29T18:35:05+00:00" }, { @@ -434,6 +456,11 @@ "validation", "versioning" ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/semver/issues", + "source": "https://github.com/composer/semver/tree/1.5.1" + }, "time": "2020-01-13T12:06:48+00:00" }, { @@ -478,6 +505,11 @@ "Xdebug", "performance" ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/xdebug-handler/issues", + "source": "https://github.com/composer/xdebug-handler/tree/1.4.3" + }, "funding": [ { "url": "https://packagist.com", @@ -558,6 +590,10 @@ "stylecheck", "tests" ], + "support": { + "issues": "https://github.com/dealerdirect/phpcodesniffer-composer-installer/issues", + "source": "https://github.com/dealerdirect/phpcodesniffer-composer-installer" + }, "time": "2020-06-25T14:57:39+00:00" }, { @@ -591,6 +627,10 @@ "MIT" ], "description": "implementation of xdg base directory specification for php", + "support": { + "issues": "https://github.com/dnoegel/php-xdg-base-dir/issues", + "source": "https://github.com/dnoegel/php-xdg-base-dir/tree/v0.1.1" + }, "time": "2019-12-04T15:06:13+00:00" }, { @@ -647,6 +687,10 @@ "standard", "style" ], + "support": { + "issues": "https://github.com/doctrine/coding-standard/issues", + "source": "https://github.com/doctrine/coding-standard/tree/8.1.x" + }, "time": "2020-07-05T20:35:22+00:00" }, { @@ -762,6 +806,10 @@ } ], "description": "A more advanced JSONRPC implementation", + "support": { + "issues": "https://github.com/felixfbecker/php-advanced-json-rpc/issues", + "source": "https://github.com/felixfbecker/php-advanced-json-rpc/tree/master" + }, "time": "2020-03-11T15:21:41+00:00" }, { @@ -809,6 +857,10 @@ "php", "server" ], + "support": { + "issues": "https://github.com/felixfbecker/php-language-server-protocol/issues", + "source": "https://github.com/felixfbecker/php-language-server-protocol/tree/v1.4.0" + }, "time": "2019-06-23T21:03:50+00:00" }, { @@ -853,6 +905,9 @@ "stubs", "type" ], + "support": { + "source": "https://github.com/JetBrains/phpstorm-stubs/tree/master" + }, "time": "2019-12-05T16:56:26+00:00" }, { @@ -957,6 +1012,11 @@ } ], "description": "Map nested JSON structures onto PHP classes", + "support": { + "email": "cweiske@cweiske.de", + "issues": "https://github.com/cweiske/jsonmapper/issues", + "source": "https://github.com/cweiske/jsonmapper/tree/master" + }, "time": "2020-04-16T18:48:43+00:00" }, { @@ -1009,6 +1069,10 @@ "parser", "php" ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/master" + }, "time": "2020-08-18T19:48:01+00:00" }, { @@ -1058,6 +1122,10 @@ "xml", "xml conversion" ], + "support": { + "issues": "https://github.com/nullivex/lib-array2xml/issues", + "source": "https://github.com/nullivex/lib-array2xml/tree/master" + }, "time": "2019-03-29T20:06:56+00:00" }, { @@ -1218,6 +1286,10 @@ "reflection", "static analysis" ], + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", + "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" + }, "time": "2020-06-27T09:03:43+00:00" }, { @@ -1270,6 +1342,10 @@ } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/master" + }, "time": "2020-08-15T11:14:08+00:00" }, { @@ -1315,6 +1391,10 @@ } ], "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "support": { + "issues": "https://github.com/phpDocumentor/TypeResolver/issues", + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.x" + }, "time": "2020-06-27T10:12:23+00:00" }, { @@ -1431,6 +1511,10 @@ "MIT" ], "description": "PHPDoc parser with support for nullable, intersection and generic types", + "support": { + "issues": "https://github.com/phpstan/phpdoc-parser/issues", + "source": "https://github.com/phpstan/phpdoc-parser/tree/master" + }, "time": "2020-04-13T16:28:46+00:00" }, { @@ -1473,6 +1557,10 @@ "MIT" ], "description": "PHPStan - PHP Static Analysis Tool", + "support": { + "issues": "https://github.com/phpstan/phpstan/issues", + "source": "https://github.com/phpstan/phpstan/tree/master" + }, "funding": [ { "url": "https://github.com/ondrejmirtes", @@ -1538,6 +1626,10 @@ "MIT" ], "description": "Extra strict and opinionated rules for PHPStan", + "support": { + "issues": "https://github.com/phpstan/phpstan-strict-rules/issues", + "source": "https://github.com/phpstan/phpstan-strict-rules/tree/0.12.2" + }, "time": "2020-01-20T13:08:52+00:00" }, { @@ -2009,6 +2101,10 @@ } ], "description": "Psalm plugin for PHPUnit", + "support": { + "issues": "https://github.com/psalm/psalm-plugin-phpunit/issues", + "source": "https://github.com/psalm/psalm-plugin-phpunit/tree/0.10.1" + }, "time": "2020-05-24T20:30:10+00:00" }, { @@ -2056,6 +2152,9 @@ "psr", "psr-3" ], + "support": { + "source": "https://github.com/php-fig/log/tree/1.1.3" + }, "time": "2020-03-23T09:12:05+00:00" }, { @@ -3011,6 +3110,10 @@ "MIT" ], "description": "Slevomat Coding Standard for PHP_CodeSniffer complements Consistence Coding Standard by providing sniffs with additional checks.", + "support": { + "issues": "https://github.com/slevomat/coding-standard/issues", + "source": "https://github.com/slevomat/coding-standard/tree/6.3.10" + }, "funding": [ { "url": "https://github.com/kukulich", @@ -3072,6 +3175,11 @@ "phpcs", "standards" ], + "support": { + "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", + "source": "https://github.com/squizlabs/PHP_CodeSniffer", + "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" + }, "time": "2020-04-17T01:09:41+00:00" }, { @@ -3144,6 +3252,9 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/console/tree/4.2" + }, "time": "2019-02-23T15:17:42+00:00" }, { @@ -3212,6 +3323,9 @@ "interoperability", "standards" ], + "support": { + "source": "https://github.com/symfony/contracts/tree/master" + }, "time": "2018-12-05T08:06:11+00:00" }, { @@ -3268,6 +3382,9 @@ ], "description": "Symfony Debug Component", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/debug/tree/4.0" + }, "time": "2018-02-28T21:50:02+00:00" }, { @@ -3330,6 +3447,9 @@ "polyfill", "portable" ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.18.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -3403,6 +3523,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/master" + }, "time": "2018-09-21T13:07:52+00:00" }, { @@ -3553,6 +3676,10 @@ "inspection", "php" ], + "support": { + "issues": "https://github.com/vimeo/psalm/issues", + "source": "https://github.com/vimeo/psalm/tree/3.16" + }, "time": "2020-09-15T13:39:50+00:00" }, { @@ -3602,6 +3729,10 @@ "check", "validate" ], + "support": { + "issues": "https://github.com/webmozart/assert/issues", + "source": "https://github.com/webmozart/assert/tree/master" + }, "time": "2020-07-08T17:02:28+00:00" }, { @@ -3649,6 +3780,10 @@ } ], "description": "A PHP implementation of Ant's glob.", + "support": { + "issues": "https://github.com/webmozart/glob/issues", + "source": "https://github.com/webmozart/glob/tree/master" + }, "time": "2015-12-29T11:14:33+00:00" }, { @@ -3695,6 +3830,10 @@ } ], "description": "A robust cross-platform utility for normalizing, comparing and modifying file paths.", + "support": { + "issues": "https://github.com/webmozart/path-util/issues", + "source": "https://github.com/webmozart/path-util/tree/2.3.0" + }, "time": "2015-12-17T08:42:14+00:00" } ], @@ -3710,5 +3849,5 @@ "platform-overrides": { "php": "7.3.0" }, - "plugin-api-version": "1.1.0" + "plugin-api-version": "2.0.0" } diff --git a/docs/en/explanation/implicit-indexes.rst b/docs/en/explanation/implicit-indexes.rst new file mode 100644 index 00000000000..f68edbe3ffb --- /dev/null +++ b/docs/en/explanation/implicit-indexes.rst @@ -0,0 +1,62 @@ +Implicit indexes +================ + +Ever noticed the DBAL creating indexes you did not remember asking for, +with names such as ``IDX_885DBAFAA76ED395``? In this document, we will +distinguish three types of indexes: + +user-defined indexes + indexes you did ask for + +DBAL-defined indexes + indexes you did not ask for, created on your behalf by the DBAL + +RDBMS-defined indexes + indexes you did not ask for, created on your behalf by the RDBMS + +RDBMS-defined indexes can be created by some database platforms when you +create a foreign key: they will create an index on the referencing +table, using the referencing columns. + +The rationale behind this is that these indexes improve performance, for +instance for checking that a delete operation can be performed on a +referenced table without violating the constraint in the referencing +table. + +Here are some database platforms that are known to create indexes when +creating a foreign key: + +- `MySQL `_ +- `MariaDB `_ + +These platforms can drop an existing implicit index once it is fulfilled +by a newly created user-defined index. + +Some other will not do so, on grounds that such indexes are not always +needed, and can be created in many different ways. They instead leave +that responsibility to the user: + +- `PostgreSQL `_ +- `SQLite `_ +- `SQL Server `_ + +Regardless of the behavior of the platform, the DBAL will create an +index for you and will automatically pick an index name that obeys +string length constraints of the platform you are using. That way, +differences between platforms are reduced because you always end up with +an index. + +This is a detail, but these indexes will be prefixed with ``IDX_``, and +typically look like this: + +.. code-block:: sql + + CREATE INDEX IDX_885DBAFAA76ED395 ON posts (user_id) + +In the case of MariaDB and MySQL, the creation of that DBAL-defined +index will result in the RDBMS-defined index being dropped. + +You can still explicitly create such indexes yourself, and the DBAL will +notice when your index fulfills the indexing and constraint needs of the +implicit index it would create, and will refrain from doing so, much +like some platforms drop indexes that are redundant as explained above. diff --git a/docs/en/sidebar.rst b/docs/en/sidebar.rst index c053421724a..404246e3a27 100644 --- a/docs/en/sidebar.rst +++ b/docs/en/sidebar.rst @@ -18,3 +18,5 @@ reference/caching reference/known-vendor-issues reference/upgrading + + explanation/implicit-indexes diff --git a/src/Schema/Table.php b/src/Schema/Table.php index cbe9a253c3f..24fc05ba739 100644 --- a/src/Schema/Table.php +++ b/src/Schema/Table.php @@ -572,17 +572,19 @@ protected function _addForeignKeyConstraint(ForeignKeyConstraint $constraint) $this->_fkConstraints[$name] = $constraint; - // Add an explicit index on the foreign key columns. - // If there is already an index that fulfils this requirements drop the request. - // In the case of __construct calling this method during hydration from schema-details - // all the explicitly added indexes lead to duplicates. - // This creates computation overhead in this case, - // however no duplicate indexes are ever added (based on columns). - $indexName = $this->_generateIdentifierName( + /* Add an implicit index (defined by the DBAL) on the foreign key + columns. If there is already a user-defined index that fulfills these + requirements drop the request. In the case of __construct() calling + this method during hydration from schema-details, all the explicitly + added indexes lead to duplicates. This creates computation overhead in + this case, however no duplicate indexes are ever added (based on + columns). */ + $indexName = $this->_generateIdentifierName( array_merge([$this->getName()], $constraint->getColumns()), 'idx', $this->_getMaxIdentifierLength() ); + $indexCandidate = $this->_createIndex($constraint->getColumns(), $indexName, false, false); foreach ($this->_indexes as $existingIndex) {