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