From 85c8d56b843e059cfcfea2ec51d7dd3899e55058 Mon Sep 17 00:00:00 2001 From: mscherer Date: Fri, 22 May 2026 05:09:15 +0200 Subject: [PATCH] Quote constraint name in MySQL DROP FOREIGN KEY statement The MySQL adapter built `DROP FOREIGN KEY ` without quoting the constraint identifier. That produces invalid SQL whenever the constraint name is not a bare identifier, e.g. names containing whitespace, or the numeric names ("1", "2", ...) that MariaDB 12 auto-assigns to foreign keys created without an explicit name. Quote the identifier via quoteColumnName(), matching the Postgres and SQL Server adapters, which already quote the dropped constraint name. --- src/Db/Adapter/MysqlAdapter.php | 2 +- .../TestCase/Db/Adapter/MysqlAdapterTest.php | 26 +++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/Db/Adapter/MysqlAdapter.php b/src/Db/Adapter/MysqlAdapter.php index f98148f7..3ebceb9e 100644 --- a/src/Db/Adapter/MysqlAdapter.php +++ b/src/Db/Adapter/MysqlAdapter.php @@ -1061,7 +1061,7 @@ protected function getDropForeignKeyInstructions(string $tableName, string $cons { $alter = sprintf( 'DROP FOREIGN KEY %s', - $constraint, + $this->quoteColumnName($constraint), ); return new AlterInstructions([$alter]); diff --git a/tests/TestCase/Db/Adapter/MysqlAdapterTest.php b/tests/TestCase/Db/Adapter/MysqlAdapterTest.php index 25649d50..7d26ca95 100644 --- a/tests/TestCase/Db/Adapter/MysqlAdapterTest.php +++ b/tests/TestCase/Db/Adapter/MysqlAdapterTest.php @@ -1848,6 +1848,32 @@ public function testDropForeignKeyWithIdenticalMultipleColumns(): void $this->assertFalse($this->adapter->hasForeignKey($table->getName(), [], 'ref_table_fk_2')); } + public function testDropForeignKeyWithNameContainingWhitespace(): void + { + $refTable = new Table('ref_table', [], $this->adapter); + $refTable->addColumn('field1', 'string')->save(); + + $table = new Table('table', [], $this->adapter); + $key = (new ForeignKey()) + ->setName('ref table fk') + ->setColumns(['ref_table_id']) + ->setReferencedTable('ref_table') + ->setReferencedColumns(['id']); + $table + ->addColumn('ref_table_id', 'integer', ['signed' => false]) + ->addForeignKey($key) + ->save(); + + $this->assertTrue($this->adapter->hasForeignKey($table->getName(), [], 'ref table fk')); + + // The constraint name must be quoted in the DROP statement, otherwise + // names with whitespace (or numeric names auto-assigned by MariaDB 12) + // produce invalid SQL. + $this->adapter->dropForeignKey($table->getName(), [], 'ref table fk'); + + $this->assertFalse($this->adapter->hasForeignKey($table->getName(), [], 'ref table fk')); + } + public static function nonExistentForeignKeyColumnsProvider(): array { return [