diff --git a/src/Db/Adapter/AbstractAdapter.php b/src/Db/Adapter/AbstractAdapter.php index 3bb4a81b..556a6078 100644 --- a/src/Db/Adapter/AbstractAdapter.php +++ b/src/Db/Adapter/AbstractAdapter.php @@ -745,7 +745,7 @@ protected function getUpsertClause(?InsertMode $mode, ?array $updateColumns, ?ar return ''; } - if ($conflictColumns !== null) { + if ($conflictColumns !== null && $conflictColumns !== []) { trigger_error( 'The $conflictColumns parameter is ignored by MySQL. ' . 'MySQL\'s ON DUPLICATE KEY UPDATE applies to all unique constraints on the table.', diff --git a/tests/TestCase/Db/Adapter/MysqlAdapterTest.php b/tests/TestCase/Db/Adapter/MysqlAdapterTest.php index aeee6316..9b0e0510 100644 --- a/tests/TestCase/Db/Adapter/MysqlAdapterTest.php +++ b/tests/TestCase/Db/Adapter/MysqlAdapterTest.php @@ -3080,6 +3080,38 @@ public function testInsertOrUpdateModeResetsAfterSave() ])->save(); } + public function testInsertOrUpdateWithEmptyConflictColumnsDoesNotWarn() + { + $table = new Table('currencies', [], $this->adapter); + $table->addColumn('code', 'string', ['limit' => 3]) + ->addColumn('rate', 'decimal', ['precision' => 10, 'scale' => 4]) + ->addIndex('code', ['unique' => true]) + ->create(); + + $warning = null; + set_error_handler(function (int $errno, string $errstr) use (&$warning) { + $warning = $errstr; + + return true; + }, E_USER_WARNING); + + try { + $table->insertOrUpdate([ + ['code' => 'USD', 'rate' => 1.0000], + ['code' => 'EUR', 'rate' => 0.9000], + ], ['rate'], [])->save(); + } finally { + restore_error_handler(); + } + + $this->assertNull($warning, 'Empty conflictColumns should not trigger a warning for MySQL'); + + $rows = $this->adapter->fetchAll('SELECT * FROM currencies ORDER BY code'); + $this->assertCount(2, $rows); + $this->assertEquals('0.9000', $rows[0]['rate']); + $this->assertEquals('1.0000', $rows[1]['rate']); + } + public function testCreateTableWithRangeColumnsPartitioning() { // MySQL requires RANGE COLUMNS for DATE columns