From 4535a81446937fcdea7cce218d65d8ce28459793 Mon Sep 17 00:00:00 2001
From: catch <catch@35733.no-reply.drupal.org>
Date: Thu, 14 Mar 2013 10:36:35 +0000
Subject: [PATCH] Issue #1839998 by wiifm, mcm.guaba, Josh Waihi: Fixed
 TruncateQuery implemented as 'DELETE FROM' in MySQL and SQLite, but not
 PostgreSQL, causing nefarious table locking.

---
 .../Core/Database/Driver/mysql/Truncate.php      | 16 +---------------
 .../Core/Database/Driver/sqlite/Truncate.php     |  2 +-
 core/lib/Drupal/Core/Database/Query/Truncate.php | 12 +++++++++++-
 3 files changed, 13 insertions(+), 17 deletions(-)

diff --git a/core/lib/Drupal/Core/Database/Driver/mysql/Truncate.php b/core/lib/Drupal/Core/Database/Driver/mysql/Truncate.php
index d0adfad10f2b..c7d7a36ca0ee 100644
--- a/core/lib/Drupal/Core/Database/Driver/mysql/Truncate.php
+++ b/core/lib/Drupal/Core/Database/Driver/mysql/Truncate.php
@@ -9,18 +9,4 @@
 
 use Drupal\Core\Database\Query\Truncate as QueryTruncate;
 
-class Truncate extends QueryTruncate {
-  public function __toString() {
-    // TRUNCATE is actually a DDL statement on MySQL, and DDL statements are
-    // not transactional, and result in an implicit COMMIT. When we are in a
-    // transaction, fallback to the slower, but transactional, DELETE.
-    if ($this->connection->inTransaction()) {
-      // Create a comment string to prepend to the query.
-      $comments = $this->connection->makeComment($this->comments);
-      return $comments . 'DELETE FROM {' . $this->connection->escapeTable($this->table) . '}';
-    }
-    else {
-      return parent::__toString();
-    }
-  }
-}
+class Truncate extends QueryTruncate { }
diff --git a/core/lib/Drupal/Core/Database/Driver/sqlite/Truncate.php b/core/lib/Drupal/Core/Database/Driver/sqlite/Truncate.php
index bc635404447f..d06d27ebb705 100644
--- a/core/lib/Drupal/Core/Database/Driver/sqlite/Truncate.php
+++ b/core/lib/Drupal/Core/Database/Driver/sqlite/Truncate.php
@@ -22,4 +22,4 @@ public function __toString() {
 
     return $comments . 'DELETE FROM {' . $this->connection->escapeTable($this->table) . '} ';
   }
-}
\ No newline at end of file
+}
diff --git a/core/lib/Drupal/Core/Database/Query/Truncate.php b/core/lib/Drupal/Core/Database/Query/Truncate.php
index 263acf50ab60..ea67dad60a34 100644
--- a/core/lib/Drupal/Core/Database/Query/Truncate.php
+++ b/core/lib/Drupal/Core/Database/Query/Truncate.php
@@ -73,6 +73,16 @@ public function __toString() {
     // Create a sanitized comment string to prepend to the query.
     $comments = $this->connection->makeComment($this->comments);
 
-    return $comments . 'TRUNCATE {' . $this->connection->escapeTable($this->table) . '} ';
+    // In most cases, TRUNCATE is not a transaction safe statement as it is a
+    // DDL statement which results in an implicit COMMIT. When we are in a
+    // transaction, fallback to the slower, but transactional, DELETE.
+    // PostgreSQL also locks the entire table for a TRUNCATE strongly reducing
+    // the concurrency with other transactions.
+    if ($this->connection->inTransaction()) {
+      return $comments . 'DELETE FROM {' . $this->connection->escapeTable($this->table) . '}';
+    }
+    else {
+      return $comments . 'TRUNCATE {' . $this->connection->escapeTable($this->table) . '} ';
+    }
   }
 }
-- 
GitLab