diff options
-rw-r--r-- | includes/database/mysql/query.inc | 6 | ||||
-rw-r--r-- | includes/database/query.inc | 17 | ||||
-rw-r--r-- | modules/simpletest/tests/database_test.test | 52 |
3 files changed, 68 insertions, 7 deletions
diff --git a/includes/database/mysql/query.inc b/includes/database/mysql/query.inc index 751137602..d5cb36505 100644 --- a/includes/database/mysql/query.inc +++ b/includes/database/mysql/query.inc @@ -143,6 +143,12 @@ class MergeQuery_mysql extends MergeQuery { } } + // If the merge query has no fields to update, add the first key as an + // update field so the query will not fail if a duplicate key is found. + if (!$update_fields && !$this->expressionFields) { + $update_fields = array_slice($this->keyFields, 0, 1, TRUE); + } + $insert_fields = $this->insertFields + $this->keyFields; $query = "INSERT INTO {" . $this->table . '} (' . implode(', ', array_keys($insert_fields)) . ') VALUES '; diff --git a/includes/database/query.inc b/includes/database/query.inc index 9f8c1b991..7186c5a6a 100644 --- a/includes/database/query.inc +++ b/includes/database/query.inc @@ -676,14 +676,17 @@ class MergeQuery extends Query { unset($update_fields[$exclude_field]); } } - $update = $this->connection->update($this->table, $this->queryOptions)->fields($update_fields); - foreach ($this->keyFields as $field => $value) { - $update->condition($field, $value); - } - foreach ($this->expressionFields as $field => $expression) { - $update->expression($field, $expression['expression'], $expression['arguments']); + if ($update_fields || $this->expressionFields) { + // Only run the update if there are no fields or expressions to update. + $update = $this->connection->update($this->table, $this->queryOptions)->fields($update_fields); + foreach ($this->keyFields as $field => $value) { + $update->condition($field, $value); + } + foreach ($this->expressionFields as $field => $expression) { + $update->expression($field, $expression['expression'], $expression['arguments']); + } + $update->execute(); } - $update->execute(); } else { // If there is no existing record, run an insert query. diff --git a/modules/simpletest/tests/database_test.test b/modules/simpletest/tests/database_test.test index 1fa4667f6..faaeb01ab 100644 --- a/modules/simpletest/tests/database_test.test +++ b/modules/simpletest/tests/database_test.test @@ -959,6 +959,58 @@ class DatabaseMergeTestCase extends DatabaseTestCase { } /** + * Test that we can merge-insert without any update fields. + */ + function testMergeInsertWithoutUpdate() { + $num_records_before = db_query("SELECT COUNT(*) FROM {test_people}")->fetchField(); + + db_merge('test_people') + ->key(array('job' => 'Presenter')) + ->execute(); + + $num_records_after = db_query("SELECT COUNT(*) FROM {test_people}")->fetchField(); + $this->assertEqual($num_records_before + 1, $num_records_after, t('Merge inserted properly.')); + + $person = db_query("SELECT * FROM {test_people} WHERE job = :job", array(':job' => 'Presenter'))->fetch(); + $this->assertEqual($person->name, '', t('Name set correctly.')); + $this->assertEqual($person->age, 0, t('Age set correctly.')); + $this->assertEqual($person->job, 'Presenter', t('Job set correctly.')); + } + + /** + * Confirm that we can merge-update without any update fields. + */ + function testMergeUpdateWithoutUpdate() { + $num_records_before = db_query("SELECT COUNT(*) FROM {test_people}")->fetchField(); + + db_merge('test_people') + ->key(array('job' => 'Speaker')) + ->execute(); + + $num_records_after = db_query("SELECT COUNT(*) FROM {test_people}")->fetchField(); + $this->assertEqual($num_records_before, $num_records_after, t('Merge skipped properly.')); + + $person = db_query("SELECT * FROM {test_people} WHERE job = :job", array(':job' => 'Speaker'))->fetch(); + $this->assertEqual($person->name, 'Meredith', t('Name skipped correctly.')); + $this->assertEqual($person->age, 30, t('Age skipped correctly.')); + $this->assertEqual($person->job, 'Speaker', t('Job skipped correctly.')); + + db_merge('test_people') + ->key(array('job' => 'Speaker')) + ->fields(array('age' => 31)) + ->updateExcept(array('age')) + ->execute(); + + $num_records_after = db_query("SELECT COUNT(*) FROM {test_people}")->fetchField(); + $this->assertEqual($num_records_before, $num_records_after, t('Merge skipped properly.')); + + $person = db_query("SELECT * FROM {test_people} WHERE job = :job", array(':job' => 'Speaker'))->fetch(); + $this->assertEqual($person->name, 'Meredith', t('Name skipped correctly.')); + $this->assertEqual($person->age, 30, t('Age skipped correctly.')); + $this->assertEqual($person->job, 'Speaker', t('Job skipped correctly.')); + } + + /** * Test that an invalid merge query throws an exception like it is supposed to. */ function testInvalidMerge() { |