View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0007856 | OXID eShop (all versions) | 4.01. Database handling | public | 2025-11-20 12:33 | 2025-11-20 12:33 |
| Reporter | [email protected] | Assigned To | |||
| Priority | normal | Severity | minor | Reproducibility | always |
| Status | new | Resolution | open | ||
| Summary | 0007856: ENUM not supported by DBAL | ||||
| Description | # OXID eShop 7.x: ENUM Type Compatibility Issue with Doctrine DBAL Migrations ## Problem Description OXID eShop 7.x uses Doctrine DBAL for database schema management and migrations. However, when creating custom migrations that need to introspect the existing database schema, the migration system fails with the following error: ``` Unknown database type enum requested, Doctrine\DBAL\Platforms\MySQL57Platform may not support it. ``` This occurs because: 1. OXID core database tables contain MySQL ENUM columns 2. Doctrine DBAL does not natively support the ENUM type 3. When migrations use `Schema::hasTable()` or any schema introspection, Doctrine reads the entire database schema 4. Upon encountering ENUM columns, Doctrine throws an exception because it cannot map the ENUM type to a Doctrine type ## OXID Core Tables with ENUM Fields The following OXID eShop core tables contain ENUM columns: ### oxdelivery - `OXADDSUMTYPE` - enum('%','abs') - `OXDELTYPE` - enum('a','s','w','p') ### oxdiscount - `OXADDSUMTYPE` - enum('%','abs','itm') ### oxpayments - `OXADDSUMTYPE` - enum('abs','%') ### oxratings - `OXTYPE` - enum('oxarticle','oxrecommlist') ### oxremark - `OXTYPE` - enum('o','r','n','c') ### oxreviews - `OXTYPE` - enum('oxarticle','oxrecommlist') ### oxseo - `OXTYPE` - enum('static','oxarticle','oxcategory','oxvendor','oxcontent','dynamic','oxmanufacturer') **Note:** All corresponding OXID view tables (oxv_*) also inherit these ENUM columns. ## Impact on Module Development This issue prevents module developers from creating migrations that: - Check if tables exist before creating them (`$schema->hasTable()`) - Perform any schema introspection operations - Use standard Doctrine DBAL schema comparison features - Create migrations in a defensive way (checking before modifying) ### Example Failing Migration ```php public function up(Schema $schema): void { // This will fail if ANY table in the database has ENUM columns if (!$schema->hasTable('my_custom_table')) { $table = $schema->createTable('my_custom_table'); // ... table definition } } ``` The error occurs even though the migration doesn't touch any ENUM columns - simply reading the schema to check table existence triggers the exception. ## Current Workarounds Developers currently must use one of these suboptimal workarounds: ### 1. Register ENUM mapping in each migration ```php private function registerEnumMapping(): void { $platform = $this->connection->getDatabasePlatform(); if (!$platform->hasDoctrineTypeMappingFor('enum')) { $platform->registerDoctrineTypeMapping('enum', 'string'); } } public function preUp(Schema $schema): void { parent::preUp($schema); $this->registerEnumMapping(); } ``` ### 2. Create custom base migration class Extend `AbstractMigration` with ENUM handling for all module migrations. ### 3. Avoid schema introspection Don't use `$schema->hasTable()` or similar methods - use raw SQL queries instead. ## Proposed Solution The OXID eShop migration infrastructure should automatically register the ENUM type mapping before executing any migrations. ### Implementation Location File: `vendor/oxid-esales/oxideshop-doctrine-migration-wrapper/src/migrations-db.php` This file provides the database connection configuration to Doctrine Migrations. It should also register custom type mappings. ### Suggested Fix Modify `migrations-db.php` to register ENUM mapping after connection is established: ```php <?php declare(strict_types=1); namespace OxidEsales\DoctrineMigrationWrapper; use Doctrine\DBAL\DriverManager; use OxidEsales\Facts\Facts; $facts = new Facts(); $connectionParams = [ 'dbname' => $facts->getDatabaseName(), 'user' => $facts->getDatabaseUserName(), 'password' => $facts->getDatabasePassword(), 'host' => $facts->getDatabaseHost(), 'port' => $facts->getDatabasePort(), 'driver' => $facts->getDatabaseDriver(), 'charset' => 'utf8', 'driverOptions' => [ \PDO::MYSQL_ATTR_INIT_COMMAND => 'SET @@SESSION.sql_mode=\'\'' ] ]; // Create connection and register ENUM type mapping $connection = DriverManager::getConnection($connectionParams); $platform = $connection->getDatabasePlatform(); // Register ENUM as string type for MySQL compatibility if (method_exists($platform, 'registerDoctrineTypeMapping')) { if (!$platform->hasDoctrineTypeMappingFor('enum')) { $platform->registerDoctrineTypeMapping('enum', 'string'); } } return $connection; ``` Alternatively, add a bootstrap mechanism that allows projects to register custom type mappings. ## Alternative: Long-term Solution Consider migrating OXID core tables away from ENUM types to VARCHAR columns with appropriate constraints or validation. ENUMs are: - Not supported by Doctrine DBAL - Less flexible (adding values requires ALTER TABLE) - Database-specific (not portable) - Cannot be easily extended by modules Converting to VARCHAR would: - Eliminate the Doctrine DBAL compatibility issue - Follow Doctrine best practices - Allow easier schema migrations - Be more compatible with modern ORM patterns ## Environment - OXID eShop: 7.3.x Enterprise Edition - PHP: 8.2+ - Doctrine DBAL: 3.x (via oxideshop-doctrine-migration-wrapper) - MySQL: 5.7/8.0/MariaDB ## References - Doctrine DBAL Type System: https://www.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/types.html - Custom Mapping Types: https://www.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/types.html#custom-mapping-types | ||||
| Steps To Reproduce | Create migration: <?php declare(strict_types=1); namespace Opal\OpalPDFDocuments\Migrations; use Doctrine\DBAL\Schema\Schema; use Doctrine\Migrations\AbstractMigration; /** * Minimal migration to reproduce ENUM type compatibility issue. * * This migration will FAIL with: * "Unknown database type enum requested, Doctrine\DBAL\Platforms\MySQL57Platform may not support it." * * The error occurs when Doctrine reads the existing database schema * and encounters ENUM columns in OXID core tables (oxdelivery, oxpayments, etc.). */ final class Version20251120000001 extends AbstractMigration { public function getDescription(): string { return 'Test migration to reproduce ENUM type error - simply checks if a table exists'; } public function up(Schema $schema): void { // This simple check will fail because Doctrine reads ALL tables in the schema // and chokes on ENUM columns in oxdelivery, oxpayments, oxdiscount, etc. if (!$schema->hasTable('test_enum_issue')) { $table = $schema->createTable('test_enum_issue'); $table->addColumn('id', 'integer', ['autoincrement' => true]); $table->addColumn('test', 'string', ['length' => 255]); $table->setPrimaryKey(['id']); } } public function down(Schema $schema): void { if ($schema->hasTable('test_enum_issue')) { $schema->dropTable('test_enum_issue'); } } } run migration | ||||
| Tags | No tags attached. | ||||
| Theme | Not defined | ||||
| Browser | Not defined | ||||
| PHP Version | 8.1 | ||||
| Database Version | MySQL 5.7 | ||||