diff --git a/core/lib/Drupal/Core/Database/Query/Merge.php b/core/lib/Drupal/Core/Database/Query/Merge.php index ee0406a..3d1b16c 100644 --- a/core/lib/Drupal/Core/Database/Query/Merge.php +++ b/core/lib/Drupal/Core/Database/Query/Merge.php @@ -403,42 +403,53 @@ public function __toString() { } public function execute() { - if (!count($this->condition)) { - throw new InvalidMergeQueryException(t('Invalid merge query: no conditions')); - } - $select = $this->connection->select($this->conditionTable) - ->condition($this->condition); - $select->addExpression('1'); - if (!$select->execute()->fetchField()) { - try { - $insert = $this->connection->insert($this->table)->fields($this->insertFields); - if ($this->defaultFields) { - $insert->useDefaults($this->defaultFields); + try { + if (!count($this->condition)) { + throw new InvalidMergeQueryException(t('Invalid merge query: no conditions')); + } + $select = $this->connection->select($this->conditionTable) + ->condition($this->condition); + $select->addExpression('1'); + if (!$select->execute()->fetchField()) { + try { + $insert = $this->connection->insert($this->table)->fields($this->insertFields); + if ($this->defaultFields) { + $insert->useDefaults($this->defaultFields); + } + $insert->execute(); + return self::STATUS_INSERT; + } + catch (IntegrityConstraintViolationException $e) { + // The insert query failed, maybe it's because a racing insert query + // beat us in inserting the same row. Retry the select query, if it + // returns a row, ignore the error and continue with the update + // query below. + if (!$select->execute()->fetchField()) { + throw $e; + } } - $insert->execute(); - return self::STATUS_INSERT; } - catch (IntegrityConstraintViolationException $e) { - // The insert query failed, maybe it's because a racing insert query - // beat us in inserting the same row. Retry the select query, if it - // returns a row, ignore the error and continue with the update - // query below. - if (!$select->execute()->fetchField()) { - throw $e; + if ($this->needsUpdate) { + $update = $this->connection->update($this->table) + ->fields($this->updateFields) + ->condition($this->condition); + if ($this->expressionFields) { + foreach ($this->expressionFields as $field => $data) { + $update->expression($field, $data['expression'], $data['arguments']); + } } + $update->execute(); + return self::STATUS_UPDATE; } } - if ($this->needsUpdate) { - $update = $this->connection->update($this->table) - ->fields($this->updateFields) - ->condition($this->condition); - if ($this->expressionFields) { - foreach ($this->expressionFields as $field => $data) { - $update->expression($field, $data['expression'], $data['arguments']); - } + catch (\Exception $e) { + // If throw_exception is not set at all, we assume that exceptions are wanted + if (!isset($this->queryOptions['throw_exception']) || $this->queryOptions['throw_exception']) { + throw $e; } - $update->execute(); - return self::STATUS_UPDATE; + else { + return NULL; + } } } } diff --git a/core/lib/Drupal/Core/Database/Query/Select.php b/core/lib/Drupal/Core/Database/Query/Select.php index 1bfe9a0..e5eeaf2 100644 --- a/core/lib/Drupal/Core/Database/Query/Select.php +++ b/core/lib/Drupal/Core/Database/Query/Select.php @@ -589,7 +589,7 @@ public function groupBy($field) { public function countQuery() { $count = $this->prepareCountQuery(); - $query = $this->connection->select($count); + $query = $this->connection->select($count, NULL, $this->queryOptions); $query->addExpression('COUNT(*)'); return $query; diff --git a/core/modules/system/lib/Drupal/system/Tests/Database/MergeTest.php b/core/modules/system/lib/Drupal/system/Tests/Database/MergeTest.php index d5d6909..987035d 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Database/MergeTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Database/MergeTest.php @@ -208,6 +208,23 @@ function testMergeUpdateWithoutUpdate() { */ function testInvalidMerge() { try { + // This query should die because there is no key field specified, + // but without exception, because of 'throw_exception' option. + $options['throw_exception'] = FALSE; + db_merge('test_people', $options) + ->fields(array( + 'age' => 31, + 'name' => 'Tiffany', + )) + ->execute(); + $this->pass('$options[\'throw_exception\'] is FALSE, no InvalidMergeQueryException thrown.'); + } + catch (InvalidMergeQueryException $e) { + $this->fail('$options[\'throw_exception\'] is FALSE, but InvalidMergeQueryException thrown for invalid query.'); + return; + } + + try { // This query should die because there is no key field specified. db_merge('test_people') ->fields(array( diff --git a/core/modules/system/lib/Drupal/system/Tests/Database/SelectTest.php b/core/modules/system/lib/Drupal/system/Tests/Database/SelectTest.php index 85787b8..6e157ee 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Database/SelectTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Database/SelectTest.php @@ -376,4 +376,39 @@ function testSelectDuplicateAlias() { $alias2 = $query->addField('t', 'age', 'the_alias'); $this->assertNotIdentical($alias1, $alias2, 'Duplicate aliases are renamed.'); } + + /** + * Tests that an invalid merge query throws an exception. + */ + function testInvalidSelectCount() { + try { + // This query should die because table doesn't exists, + // but without exception, because of 'throw_exception' option. + $options['throw_exception'] = FALSE; + db_select('some_table_that_doesnt_exist', 't', $options) + ->fields('t') + ->countQuery() + ->execute(); + + $this->pass('$options[\'throw_exception\'] is FALSE, no Exception thrown.'); + } + catch (\Exception $e) { + $this->fail('$options[\'throw_exception\'] is FALSE, but Exception thrown for invalid query.'); + return; + } + + try { + // This query should die because table doesn't exists, + db_select('some_table_that_doesnt_exist', 't') + ->fields('t') + ->countQuery() + ->execute(); + } + catch (\Exception $e) { + $this->pass('Exception thrown for invalid query.'); + return; + } + $this->fail('No Exception thrown'); + } + }