summaryrefslogtreecommitdiff
path: root/includes
diff options
context:
space:
mode:
authorDavid Rothstein <drothstein@gmail.com>2013-08-05 04:24:31 -0400
committerDavid Rothstein <drothstein@gmail.com>2013-08-05 04:24:31 -0400
commit2df0b841f5a6794ff961033ff21f6d3d7a181b2b (patch)
tree5627a46e6a6c1d7a57851338dbd84814043cc5f0 /includes
parentc2a570914a0c259d7d9d34776b25788c01be5ab1 (diff)
downloadbrdo-2df0b841f5a6794ff961033ff21f6d3d7a181b2b.tar.gz
brdo-2df0b841f5a6794ff961033ff21f6d3d7a181b2b.tar.bz2
Issue #1839998 by wiifm, mcm.guaba, Josh Waihi, dcam: Fixed TruncateQuery implemented as 'DELETE FROM' in MySQL and SQLite, but not PostgreSQL, causing nefarious table locking.
Diffstat (limited to 'includes')
-rw-r--r--includes/database/mysql/query.inc16
-rw-r--r--includes/database/query.inc34
2 files changed, 23 insertions, 27 deletions
diff --git a/includes/database/mysql/query.inc b/includes/database/mysql/query.inc
index 2609aba0c..fa698d90c 100644
--- a/includes/database/mysql/query.inc
+++ b/includes/database/mysql/query.inc
@@ -86,21 +86,7 @@ class InsertQuery_mysql extends InsertQuery {
}
}
-class TruncateQuery_mysql extends TruncateQuery {
- 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 TruncateQuery_mysql extends TruncateQuery { }
/**
* @} End of "addtogroup database".
diff --git a/includes/database/query.inc b/includes/database/query.inc
index 8beeef1e8..66495273e 100644
--- a/includes/database/query.inc
+++ b/includes/database/query.inc
@@ -83,7 +83,7 @@ interface QueryConditionInterface {
/**
* Sets a condition that the specified subquery returns values.
- *
+ *
* @param SelectQueryInterface $select
* The subquery that must contain results.
*
@@ -91,10 +91,10 @@ interface QueryConditionInterface {
* The called object.
*/
public function exists(SelectQueryInterface $select);
-
+
/**
* Sets a condition that the specified subquery returns no values.
- *
+ *
* @param SelectQueryInterface $select
* The subquery that must not contain results.
*
@@ -102,7 +102,7 @@ interface QueryConditionInterface {
* The called object.
*/
public function notExists(SelectQueryInterface $select);
-
+
/**
* Gets a complete list of all conditions in this conditional clause.
*
@@ -283,14 +283,14 @@ abstract class Query implements QueryPlaceholderInterface {
/**
* The target of the connection object.
- *
+ *
* @var string
*/
protected $connectionTarget;
/**
* The key of the connection object.
- *
+ *
* @var string
*/
protected $connectionKey;
@@ -804,7 +804,7 @@ class DeleteQuery extends Query implements QueryConditionInterface {
$this->condition->notExists($select);
return $this;
}
-
+
/**
* Implements QueryConditionInterface::conditions().
*/
@@ -942,7 +942,17 @@ class TruncateQuery extends Query {
// 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) . '} ';
+ }
}
}
@@ -1053,7 +1063,7 @@ class UpdateQuery extends Query implements QueryConditionInterface {
$this->condition->notExists($select);
return $this;
}
-
+
/**
* Implements QueryConditionInterface::conditions().
*/
@@ -1545,7 +1555,7 @@ class MergeQuery extends Query implements QueryConditionInterface {
$this->condition->notExists($select);
return $this;
}
-
+
/**
* Implements QueryConditionInterface::conditions().
*/
@@ -1762,14 +1772,14 @@ class DatabaseCondition implements QueryConditionInterface, Countable {
public function exists(SelectQueryInterface $select) {
return $this->condition('', $select, 'EXISTS');
}
-
+
/**
* Implements QueryConditionInterface::notExists().
*/
public function notExists(SelectQueryInterface $select) {
return $this->condition('', $select, 'NOT EXISTS');
}
-
+
/**
* Implements QueryConditionInterface::conditions().
*/