summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--includes/database/mysql/query.inc6
-rw-r--r--includes/database/query.inc17
-rw-r--r--modules/simpletest/tests/database_test.test52
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() {