From de7f4baeaf9555db01a0684a2434046ed38b05b0 Mon Sep 17 00:00:00 2001
From: webchick <webchick@24967.no-reply.drupal.org>
Date: Wed, 23 Jan 2013 19:41:48 -0800
Subject: [PATCH] Issue #1266572 by znerol: Fixed Workaround in
 UpdateQuery_sqlite() for affected rows count causes certain updates to be
 suppressed.

---
 .../Core/Database/Driver/sqlite/Update.php    | 29 ++-----------------
 .../system/Tests/Database/UpdateTest.php      | 14 +++++++++
 2 files changed, 17 insertions(+), 26 deletions(-)

diff --git a/core/lib/Drupal/Core/Database/Driver/sqlite/Update.php b/core/lib/Drupal/Core/Database/Driver/sqlite/Update.php
index 38d8d5c4112c..b6c2bdfa8a57 100644
--- a/core/lib/Drupal/Core/Database/Driver/sqlite/Update.php
+++ b/core/lib/Drupal/Core/Database/Driver/sqlite/Update.php
@@ -19,41 +19,18 @@
  * we don't select those rows.
  *
  * A query like this one:
- *   UPDATE test SET name = 'newname' WHERE tid = 1
+ *   UPDATE test SET col1 = 'newcol1', col2 = 'newcol2' WHERE tid = 1
  * will become:
- *   UPDATE test SET name = 'newname' WHERE tid = 1 AND name <> 'newname'
+ *   UPDATE test SET col1 = 'newcol1', col2 = 'newcol2' WHERE tid = 1 AND (col1 <> 'newcol1' OR col2 <> 'newcol2')
  */
 class Update extends QueryUpdate {
-  /**
-   * Helper function that removes the fields that are already in a condition.
-   *
-   * @param $fields
-   *   The fields.
-   * @param QueryConditionInterface $condition
-   *   A database condition.
-   */
-  protected function removeFieldsInCondition(&$fields, ConditionInterface $condition) {
-    foreach ($condition->conditions() as $child_condition) {
-      if (isset($child_condition['field'])) {
-        if ($child_condition['field'] instanceof ConditionInterface) {
-          $this->removeFieldsInCondition($fields, $child_condition['field']);
-        }
-        else {
-          unset($fields[$child_condition['field']]);
-        }
-      }
-    }
-  }
-
   public function execute() {
     if (!empty($this->queryOptions['sqlite_return_matched_rows'])) {
       return parent::execute();
     }
 
-    // Get the fields used in the update query, and remove those that are already
-    // in the condition.
+    // Get the fields used in the update query.
     $fields = $this->expressionFields + $this->fields;
-    $this->removeFieldsInCondition($fields, $this->condition);
 
     // Add the inverse of the fields to the condition.
     $condition = new Condition('OR');
diff --git a/core/modules/system/lib/Drupal/system/Tests/Database/UpdateTest.php b/core/modules/system/lib/Drupal/system/Tests/Database/UpdateTest.php
index c5acd786c9cd..a4a45f67db3d 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Database/UpdateTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Database/UpdateTest.php
@@ -125,4 +125,18 @@ function testExpressionUpdate() {
       ->execute();
     $this->assertIdentical($num_rows, 3, 'Number of affected rows are returned.');
   }
+
+  /**
+   * Confirm that we can update the primary key of a record successfully.
+   */
+  function testPrimaryKeyUpdate() {
+    $num_updated = db_update('test')
+      ->fields(array('id' => 42, 'name' => 'John'))
+      ->condition('id', 1)
+      ->execute();
+    $this->assertIdentical($num_updated, 1, t('Updated 1 record.'));
+
+    $saved_name= db_query('SELECT name FROM {test} WHERE id = :id', array(':id' => 42))->fetchField();
+    $this->assertIdentical($saved_name, 'John', t('Updated primary key successfully.'));
+  }
 }
-- 
GitLab