Deprecate Column::getType() in favor of Column::getTypeName() - #7490
Open
GromNaN wants to merge 1 commit into
Open
Deprecate Column::getType() in favor of Column::getTypeName()#7490GromNaN wants to merge 1 commit into
Column::getType() in favor of Column::getTypeName()#7490GromNaN wants to merge 1 commit into
Conversation
Member
|
Please rebase onto 4.5.x. We don't introduce deprecations or new public APIs in bugfix releases. |
derrabus
reviewed
Aug 4, 2026
GromNaN
marked this pull request as draft
August 4, 2026 09:50
GromNaN
force-pushed
the
feature/column-type-name
branch
3 times, most recently
from
August 4, 2026 20:56
bc24537 to
72ba22d
Compare
GromNaN
marked this pull request as ready for review
August 4, 2026 20:56
GromNaN
force-pushed
the
feature/column-type-name
branch
2 times, most recently
from
August 4, 2026 21:21
be4c958 to
379f651
Compare
GromNaN
added a commit
to GromNaN/dbal
that referenced
this pull request
Aug 5, 2026
It was inserted directly after the "Upgrade to 4.4" heading, so it documented a 4.5 deprecation under 4.4. Placed next to the related Column mutator notes. Same fix as on the doctrine#7490 branch, where the note originates.
GromNaN
force-pushed
the
feature/column-type-name
branch
from
August 19, 2026 09:17
fdb05f8 to
19bc7ff
Compare
`Column::getType()` returns a `Type` instance. In DBAL 4 the canonical identifier of a type is its name, not its class or instance: `Type::getName()` was removed in favor of `TypeRegistry::lookupName()`, and consumers that only need the name (ORM `DatabaseDriver`, RSM, schema comparison, reverse engineering, dumps to cache) end up doing a useless instance -> name round-trip via the global static registry. Expose the type name directly on `Column`: - `Column::setTypeName(string): self` and `Column::getTypeName(): string` (throws `TypesException` if the name cannot be resolved). `_typeName` is the source of truth. - `Column::setType(Type)` deprecated (still populates `_typeName` eagerly so unregistered types now fail early instead of silently). - `Column::getType()` deprecated. - `AbstractPlatform::getType(Column)` protected helper introduced as the single call site for `Type::getType()`, so a future `TypeRegistry` injection has one hook. Migrated `OraclePlatform`, `PostgreSQLPlatform`, `DB2Platform` and `PostgreSQLSchemaManager` off `Column::getType()`. - `ColumnDiff::hasTypeChanged()` now compares type *names* instead of instance classes. - Tests updated to construct columns via `setTypeName()`; two comparator tests that only made sense under class-based identity (`clone Type`, `overrideType`) collapsed into a single name-based equivalence test.
GromNaN
force-pushed
the
feature/column-type-name
branch
from
August 19, 2026 09:18
19bc7ff to
6b9d498
Compare
GromNaN
added a commit
to GromNaN/dbal
that referenced
this pull request
Aug 19, 2026
…instance-based lookups All internal type resolution (Connection, Statement, AbstractPlatform, SchemaManagers, MetadataProviders) now goes through Configuration::getTypeRegistry() instead of the global Type::getType() / Type::hasType() / Type::getTypesMap() static methods. Table receives an optional Configuration so addColumn() uses the instance registry when available, falling back to Type::getType() for user code without a Configuration. ColumnEditor::setTypeName() similarly falls back to Type::getType() for user code; internal callers (MetadataProviders) now use setType() with the configuration registry. Deprecate `Column::getType()` in favor of `Column::getTypeName()` `Column::getType()` returns a `Type` instance. In DBAL 4 the canonical identifier of a type is its name, not its class or instance: `Type::getName()` was removed in favor of `TypeRegistry::lookupName()`, and consumers that only need the name (ORM `DatabaseDriver`, RSM, schema comparison, reverse engineering, dumps to cache) end up doing a useless instance -> name round-trip via the global static registry. Expose the type name directly on `Column`: - `Column::setTypeName(string): self` and `Column::getTypeName(): string` (throws `TypesException` if the name cannot be resolved). `_typeName` is the source of truth. - `Column::setType(Type)` deprecated (still populates `_typeName` eagerly so unregistered types now fail early instead of silently). - `Column::getType()` deprecated. - `AbstractPlatform::getType(Column)` protected helper introduced as the single call site for `Type::getType()`, so a future `TypeRegistry` injection has one hook. Migrated `OraclePlatform`, `PostgreSQLPlatform`, `DB2Platform` and `PostgreSQLSchemaManager` off `Column::getType()`. - `ColumnDiff::hasTypeChanged()` now compares type *names* instead of instance classes. - Tests updated to construct columns via `setTypeName()`; two comparator tests that only made sense under class-based identity (`clone Type`, `overrideType`) collapsed into a single name-based equivalence test. Document per-connection type registries in UPGRADE.md Covers Configuration::get/setTypeRegistry(), the fallback to the global singleton for connections that do not set one, and the deliberate isolation from Type::addType(). Also notes two things that are easy to trip over: new TypeRegistry() is now pre-populated with the built-in types, and mocking Configuration requires stubbing getTypeRegistry() because TypeRegistry is final. Introduce the TypeProvider interface, addressing review feedback Configuration now exposes get/setTypeProvider() typed against the new Doctrine\DBAL\Types\TypeProvider instead of the final TypeRegistry, so the type source can be extended or stubbed. The ORM testsuite previously had to instantiate a real registry and touch unrelated tests because the final class could not be doubled. The interface extends PSR-11 ContainerInterface and Traversable, since a type registry is a container of types that callers may also enumerate. get() is redeclared to narrow the return type to Type; without that, every call site would degrade to mixed. register() and override() stay off the interface, so Type::getTypeRegistry() keeps returning the concrete class for Type::addType(). Because interface inheritance is resolved eagerly, psr/container moves back to a hard requirement. getMap() is replaced by iteration: TypeRegistry implements IteratorAggregate with a generator that yields from each source in turn rather than merging them, so iteration allocates nothing extra and stopping early leaves the remaining types uninstantiated. Also from the review: - Drop the unset() in get()'s finally. It was redundant, since $instances is checked first and shadows the service ID, and being in finally it also ran on failure: a transient container error permanently dropped the type, so has() flipped to false and a retry reported an unknown type instead of retrying. - Deprecate TypeRegistry::lookupName() and Type::lookupName(). They cannot be removed yet because the deprecated Column::setType(), ColumnEditor::setType() and ORM's TypedExpression branch still need to derive a name from an instance. Both go in 5.0, along with the one-instance-one-name restriction. - Add a runtime deprecation to Column::getType(). It uses triggerIfCalledFromOutside because toArray() calls it internally when $skipType is false, and that path already triggers its own deprecation. Remove a stray blank line in UPGRADE.md Stop extending ContainerInterface in TypeProvider Extending PSR-11 made psr/container a hard requirement, because interface inheritance is resolved eagerly. That is not worth it yet: nothing in DBAL consumes a TypeProvider as a container, and the interface can still be widened later without breaking implementors. psr/container therefore returns to require-dev. It stays a soft dependency: TypeRegistry still accepts a container and catches ContainerExceptionInterface, but those are parameter and catch positions, which PHP only resolves when a container is actually passed. Verified by running the array-based path with an autoloader that fails on any Psr\Container\* lookup. Move the Column::getType() upgrade note to the 4.5 section It was inserted directly after the "Upgrade to 4.4" heading, so it documented a 4.5 deprecation under 4.4. Placed next to the related Column mutator notes. Same fix as on the doctrine#7490 branch, where the note originates. Mention the connection's TypeProvider in UnknownColumnType The message told users to register the type with Type::addType(), which does not help a connection that has its own TypeProvider: such a connection does not see globally registered types, so following the advice led nowhere. Also normalises Foo#bar() to Foo::bar(); that notation appeared nowhere else in src/. Deprecate the static Type methods They all operate on the process-wide registry, which behaves unexpectedly once a connection has its own type provider: a type registered with Type::addType() is invisible to that connection, and Type::getType() resolves against the global registry rather than the connection's. Nothing signalled that, so the failure surfaced later as an unrelated UnknownColumnType. All seven now carry an @deprecated docblock and a runtime trigger. getTypeRegistry() and getType() use triggerIfCalledFromOutside, because Configuration::getTypeProvider(), AbstractPlatform and the deprecated Column::getType() call them internally; that keeps the supported default path silent and avoids reporting one user call twice. Verified that each static fires exactly once, that Column::getType() still reports once rather than twice, and that a plain connection stays silent through insert and schema introspection. UnknownColumnType no longer recommends Type::addType(), which this change deprecates and which would not have fixed the error for a connection with its own provider. DBAL 5 will have no static type provider.
GromNaN
added a commit
to GromNaN/dbal
that referenced
this pull request
Aug 19, 2026
…instance-based lookups All internal type resolution (Connection, Statement, AbstractPlatform, SchemaManagers, MetadataProviders) now goes through Configuration::getTypeRegistry() instead of the global Type::getType() / Type::hasType() / Type::getTypesMap() static methods. Table receives an optional Configuration so addColumn() uses the instance registry when available, falling back to Type::getType() for user code without a Configuration. ColumnEditor::setTypeName() similarly falls back to Type::getType() for user code; internal callers (MetadataProviders) now use setType() with the configuration registry. Deprecate `Column::getType()` in favor of `Column::getTypeName()` `Column::getType()` returns a `Type` instance. In DBAL 4 the canonical identifier of a type is its name, not its class or instance: `Type::getName()` was removed in favor of `TypeRegistry::lookupName()`, and consumers that only need the name (ORM `DatabaseDriver`, RSM, schema comparison, reverse engineering, dumps to cache) end up doing a useless instance -> name round-trip via the global static registry. Expose the type name directly on `Column`: - `Column::setTypeName(string): self` and `Column::getTypeName(): string` (throws `TypesException` if the name cannot be resolved). `_typeName` is the source of truth. - `Column::setType(Type)` deprecated (still populates `_typeName` eagerly so unregistered types now fail early instead of silently). - `Column::getType()` deprecated. - `AbstractPlatform::getType(Column)` protected helper introduced as the single call site for `Type::getType()`, so a future `TypeRegistry` injection has one hook. Migrated `OraclePlatform`, `PostgreSQLPlatform`, `DB2Platform` and `PostgreSQLSchemaManager` off `Column::getType()`. - `ColumnDiff::hasTypeChanged()` now compares type *names* instead of instance classes. - Tests updated to construct columns via `setTypeName()`; two comparator tests that only made sense under class-based identity (`clone Type`, `overrideType`) collapsed into a single name-based equivalence test. Document per-connection type registries in UPGRADE.md Covers Configuration::get/setTypeRegistry(), the fallback to the global singleton for connections that do not set one, and the deliberate isolation from Type::addType(). Also notes two things that are easy to trip over: new TypeRegistry() is now pre-populated with the built-in types, and mocking Configuration requires stubbing getTypeRegistry() because TypeRegistry is final. Introduce the TypeProvider interface, addressing review feedback Configuration now exposes get/setTypeProvider() typed against the new Doctrine\DBAL\Types\TypeProvider instead of the final TypeRegistry, so the type source can be extended or stubbed. The ORM testsuite previously had to instantiate a real registry and touch unrelated tests because the final class could not be doubled. The interface extends PSR-11 ContainerInterface and Traversable, since a type registry is a container of types that callers may also enumerate. get() is redeclared to narrow the return type to Type; without that, every call site would degrade to mixed. register() and override() stay off the interface, so Type::getTypeRegistry() keeps returning the concrete class for Type::addType(). Because interface inheritance is resolved eagerly, psr/container moves back to a hard requirement. getMap() is replaced by iteration: TypeRegistry implements IteratorAggregate with a generator that yields from each source in turn rather than merging them, so iteration allocates nothing extra and stopping early leaves the remaining types uninstantiated. Also from the review: - Drop the unset() in get()'s finally. It was redundant, since $instances is checked first and shadows the service ID, and being in finally it also ran on failure: a transient container error permanently dropped the type, so has() flipped to false and a retry reported an unknown type instead of retrying. - Deprecate TypeRegistry::lookupName() and Type::lookupName(). They cannot be removed yet because the deprecated Column::setType(), ColumnEditor::setType() and ORM's TypedExpression branch still need to derive a name from an instance. Both go in 5.0, along with the one-instance-one-name restriction. - Add a runtime deprecation to Column::getType(). It uses triggerIfCalledFromOutside because toArray() calls it internally when $skipType is false, and that path already triggers its own deprecation. Remove a stray blank line in UPGRADE.md Stop extending ContainerInterface in TypeProvider Extending PSR-11 made psr/container a hard requirement, because interface inheritance is resolved eagerly. That is not worth it yet: nothing in DBAL consumes a TypeProvider as a container, and the interface can still be widened later without breaking implementors. psr/container therefore returns to require-dev. It stays a soft dependency: TypeRegistry still accepts a container and catches ContainerExceptionInterface, but those are parameter and catch positions, which PHP only resolves when a container is actually passed. Verified by running the array-based path with an autoloader that fails on any Psr\Container\* lookup. Move the Column::getType() upgrade note to the 4.5 section It was inserted directly after the "Upgrade to 4.4" heading, so it documented a 4.5 deprecation under 4.4. Placed next to the related Column mutator notes. Same fix as on the doctrine#7490 branch, where the note originates. Mention the connection's TypeProvider in UnknownColumnType The message told users to register the type with Type::addType(), which does not help a connection that has its own TypeProvider: such a connection does not see globally registered types, so following the advice led nowhere. Also normalises Foo#bar() to Foo::bar(); that notation appeared nowhere else in src/. Deprecate the static Type methods They all operate on the process-wide registry, which behaves unexpectedly once a connection has its own type provider: a type registered with Type::addType() is invisible to that connection, and Type::getType() resolves against the global registry rather than the connection's. Nothing signalled that, so the failure surfaced later as an unrelated UnknownColumnType. All seven now carry an @deprecated docblock and a runtime trigger. getTypeRegistry() and getType() use triggerIfCalledFromOutside, because Configuration::getTypeProvider(), AbstractPlatform and the deprecated Column::getType() call them internally; that keeps the supported default path silent and avoids reporting one user call twice. Verified that each static fires exactly once, that Column::getType() still reports once rather than twice, and that a plain connection stays silent through insert and schema introspection. UnknownColumnType no longer recommends Type::addType(), which this change deprecates and which would not have fixed the error for a connection with its own provider. DBAL 5 will have no static type provider.
GromNaN
added a commit
to GromNaN/dbal
that referenced
this pull request
Aug 19, 2026
…instance-based lookups All internal type resolution (Connection, Statement, AbstractPlatform, SchemaManagers, MetadataProviders) now goes through Configuration::getTypeRegistry() instead of the global Type::getType() / Type::hasType() / Type::getTypesMap() static methods. Table receives an optional Configuration so addColumn() uses the instance registry when available, falling back to Type::getType() for user code without a Configuration. ColumnEditor::setTypeName() similarly falls back to Type::getType() for user code; internal callers (MetadataProviders) now use setType() with the configuration registry. Deprecate `Column::getType()` in favor of `Column::getTypeName()` `Column::getType()` returns a `Type` instance. In DBAL 4 the canonical identifier of a type is its name, not its class or instance: `Type::getName()` was removed in favor of `TypeRegistry::lookupName()`, and consumers that only need the name (ORM `DatabaseDriver`, RSM, schema comparison, reverse engineering, dumps to cache) end up doing a useless instance -> name round-trip via the global static registry. Expose the type name directly on `Column`: - `Column::setTypeName(string): self` and `Column::getTypeName(): string` (throws `TypesException` if the name cannot be resolved). `_typeName` is the source of truth. - `Column::setType(Type)` deprecated (still populates `_typeName` eagerly so unregistered types now fail early instead of silently). - `Column::getType()` deprecated. - `AbstractPlatform::getType(Column)` protected helper introduced as the single call site for `Type::getType()`, so a future `TypeRegistry` injection has one hook. Migrated `OraclePlatform`, `PostgreSQLPlatform`, `DB2Platform` and `PostgreSQLSchemaManager` off `Column::getType()`. - `ColumnDiff::hasTypeChanged()` now compares type *names* instead of instance classes. - Tests updated to construct columns via `setTypeName()`; two comparator tests that only made sense under class-based identity (`clone Type`, `overrideType`) collapsed into a single name-based equivalence test. Document per-connection type registries in UPGRADE.md Covers Configuration::get/setTypeRegistry(), the fallback to the global singleton for connections that do not set one, and the deliberate isolation from Type::addType(). Also notes two things that are easy to trip over: new TypeRegistry() is now pre-populated with the built-in types, and mocking Configuration requires stubbing getTypeRegistry() because TypeRegistry is final. Introduce the TypeProvider interface, addressing review feedback Configuration now exposes get/setTypeProvider() typed against the new Doctrine\DBAL\Types\TypeProvider instead of the final TypeRegistry, so the type source can be extended or stubbed. The ORM testsuite previously had to instantiate a real registry and touch unrelated tests because the final class could not be doubled. The interface extends PSR-11 ContainerInterface and Traversable, since a type registry is a container of types that callers may also enumerate. get() is redeclared to narrow the return type to Type; without that, every call site would degrade to mixed. register() and override() stay off the interface, so Type::getTypeRegistry() keeps returning the concrete class for Type::addType(). Because interface inheritance is resolved eagerly, psr/container moves back to a hard requirement. getMap() is replaced by iteration: TypeRegistry implements IteratorAggregate with a generator that yields from each source in turn rather than merging them, so iteration allocates nothing extra and stopping early leaves the remaining types uninstantiated. Also from the review: - Drop the unset() in get()'s finally. It was redundant, since $instances is checked first and shadows the service ID, and being in finally it also ran on failure: a transient container error permanently dropped the type, so has() flipped to false and a retry reported an unknown type instead of retrying. - Deprecate TypeRegistry::lookupName() and Type::lookupName(). They cannot be removed yet because the deprecated Column::setType(), ColumnEditor::setType() and ORM's TypedExpression branch still need to derive a name from an instance. Both go in 5.0, along with the one-instance-one-name restriction. - Add a runtime deprecation to Column::getType(). It uses triggerIfCalledFromOutside because toArray() calls it internally when $skipType is false, and that path already triggers its own deprecation. Remove a stray blank line in UPGRADE.md Stop extending ContainerInterface in TypeProvider Extending PSR-11 made psr/container a hard requirement, because interface inheritance is resolved eagerly. That is not worth it yet: nothing in DBAL consumes a TypeProvider as a container, and the interface can still be widened later without breaking implementors. psr/container therefore returns to require-dev. It stays a soft dependency: TypeRegistry still accepts a container and catches ContainerExceptionInterface, but those are parameter and catch positions, which PHP only resolves when a container is actually passed. Verified by running the array-based path with an autoloader that fails on any Psr\Container\* lookup. Move the Column::getType() upgrade note to the 4.5 section It was inserted directly after the "Upgrade to 4.4" heading, so it documented a 4.5 deprecation under 4.4. Placed next to the related Column mutator notes. Same fix as on the doctrine#7490 branch, where the note originates. Mention the connection's TypeProvider in UnknownColumnType The message told users to register the type with Type::addType(), which does not help a connection that has its own TypeProvider: such a connection does not see globally registered types, so following the advice led nowhere. Also normalises Foo#bar() to Foo::bar(); that notation appeared nowhere else in src/. Deprecate the static Type methods They all operate on the process-wide registry, which behaves unexpectedly once a connection has its own type provider: a type registered with Type::addType() is invisible to that connection, and Type::getType() resolves against the global registry rather than the connection's. Nothing signalled that, so the failure surfaced later as an unrelated UnknownColumnType. All seven now carry an @deprecated docblock and a runtime trigger. getTypeRegistry() and getType() use triggerIfCalledFromOutside, because Configuration::getTypeProvider(), AbstractPlatform and the deprecated Column::getType() call them internally; that keeps the supported default path silent and avoids reporting one user call twice. Verified that each static fires exactly once, that Column::getType() still reports once rather than twice, and that a plain connection stays silent through insert and schema introspection. UnknownColumnType no longer recommends Type::addType(), which this change deprecates and which would not have fixed the error for a connection with its own provider. DBAL 5 will have no static type provider.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #7342 (removing static
Type::*calls).Motivation
Column::getType(): Typepredates DBAL 4. SinceType::getName()was removed in favor ofTypeRegistry::lookupName(), callers that only need the name of a column's type (ORMDatabaseDriver, RSM, schema comparison, reverse engineering, cache dumps) end up doing an instance -> name round-trip through the global static registry:Two static
Type::*calls to obtain somethingColumnconceptually already knows.Changes
Column::setTypeName(string): self/Column::getTypeName(): string(throwsTypesExceptionif the name cannot be resolved). Internal_typeNameis now the source of truth.Column::setType(Type)deprecated (still populates_typeNameeagerly, so unregisteredTypeinstances now fail loudly at construction instead of silently later).Column::getType()deprecated.AbstractPlatform::getType(Column): Typeprotected helper introduced as the single hook whereType::getType()is called; futureTypeRegistryinjection has one place to land.OraclePlatform,PostgreSQLPlatform,DB2PlatformandPostgreSQLSchemaManagermigrated offColumn::getType().ColumnDiff::hasTypeChanged()compares type names instead of instance classes.Migration
Before:
After: