#332002: MergeQuery should refuse to execute if there are no key fields. From: Damien Tournoud Those queries make no sense because they essentially mean "if any row exist in the table, replace with the fields I indicate". --- includes/database/mysql/query.inc | 6 ++++++ includes/database/query.inc | 5 +++++ modules/aggregator/aggregator.module | 4 ++-- modules/statistics/statistics.module | 13 ++++++------- 4 files changed, 19 insertions(+), 9 deletions(-) diff --git includes/database/mysql/query.inc includes/database/mysql/query.inc index b23eefc..f46bec1 100644 --- includes/database/mysql/query.inc +++ includes/database/mysql/query.inc @@ -76,6 +76,12 @@ class InsertQuery_mysql extends InsertQuery { class MergeQuery_mysql extends MergeQuery { public function execute() { + + // A merge query without any key field is invalid. + if (count($this->keyFields) == 0) { + throw new PDOException("You need to specify key fields before executing a merge query"); + } + // Set defaults. if ($this->updateFields) { $update_fields = $this->updateFields; diff --git includes/database/query.inc includes/database/query.inc index 5ecc8ce..6531685 100644 --- includes/database/query.inc +++ includes/database/query.inc @@ -629,6 +629,11 @@ class MergeQuery extends Query { public function execute() { + // A merge query without any key field is invalid. + if (count($this->keyFields) == 0) { + throw new PDOException("You need to specify key fields before executing a merge query"); + } + // In the degenerate case of this query type, we have to run multiple // queries as there is no universal single-query mechanism that will work. // Our degenerate case is not designed for performance efficiency but diff --git modules/aggregator/aggregator.module modules/aggregator/aggregator.module index 81e2b45..3f6d602 100644 --- modules/aggregator/aggregator.module +++ modules/aggregator/aggregator.module @@ -477,8 +477,8 @@ function aggregator_save_feed($edit) { foreach ($edit['category'] as $cid => $value) { if ($value) { db_merge('aggregator_category_feed') + ->key(array('fid', $edit['fid'])) ->fields(array( - 'fid' => $edit['fid'], 'cid' => $cid, )) ->execute(); @@ -936,9 +936,9 @@ function aggregator_save_item($edit) { $result = db_query('SELECT cid FROM {aggregator_category_feed} WHERE fid = :fid', array(':fid' => $edit['fid'])); foreach ($result as $category) { db_merge('aggregator_category_item') + ->key(array('iid' => $edit['iid'])) ->fields(array( 'cid' => $category->cid, - 'iid' => $edit['iid'], )) ->execute(); } diff --git modules/statistics/statistics.module modules/statistics/statistics.module index 9d4632f..4b28bd2 100644 --- modules/statistics/statistics.module +++ modules/statistics/statistics.module @@ -51,14 +51,13 @@ function statistics_exit() { // We are counting content views. if ((arg(0) == 'node') && is_numeric(arg(1)) && arg(2) == '') { // A node has been viewed, so update the node's counters. - $fields = array( - 'daycount' => 1, - 'totalcount' => 1, - 'nid' => arg(1), - 'timestamp' => REQUEST_TIME, - ); db_merge('node_counter') - ->fields($fields) + ->key(array('nid' => arg(1))) + ->fields(array( + 'daycount' => 1, + 'totalcount' => 1, + 'timestamp' => REQUEST_TIME, + )) ->expression('daycount', 'daycount + 1') ->expression('totalcount', 'totalcount + 1') ->execute();