Issue #2999569 by mondrake, Hardik_Patel_12, ravi.shankar, vsujeetkumar, mrinalini9, daffie: MySql driver throws a generic DatabaseExceptionWrapper for integrity violation at insertion when column has no default
parent
a32afce132
commit
bacf782e30
|
@ -3,6 +3,7 @@
|
|||
namespace Drupal\Core\Database\Driver\mysql;
|
||||
|
||||
use Drupal\Core\Database\DatabaseAccessDeniedException;
|
||||
use Drupal\Core\Database\IntegrityConstraintViolationException;
|
||||
use Drupal\Core\Database\DatabaseExceptionWrapper;
|
||||
|
||||
use Drupal\Core\Database\Database;
|
||||
|
@ -87,6 +88,24 @@ class Connection extends DatabaseConnection {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function handleQueryException(\PDOException $e, $query, array $args = [], $options = []) {
|
||||
// In case of attempted INSERT of a record with an undefined column and no
|
||||
// default value indicated in schema, MySql returns a 1364 error code.
|
||||
// Throw an IntegrityConstraintViolationException here like the other
|
||||
// drivers do, to avoid the parent class to throw a generic
|
||||
// DatabaseExceptionWrapper instead.
|
||||
if (!empty($e->errorInfo[1]) && $e->errorInfo[1] === 1364) {
|
||||
$query_string = ($query instanceof StatementInterface) ? $query->getQueryString() : $query;
|
||||
$message = $e->getMessage() . ": " . $query_string . "; " . print_r($args, TRUE);
|
||||
throw new IntegrityConstraintViolationException($message, is_int($e->getCode()) ? $e->getCode() : 0, $e);
|
||||
}
|
||||
|
||||
parent::handleQueryException($e, $query, $args, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace Drupal\KernelTests\Core\Database;
|
||||
|
||||
use Drupal\Core\Database\IntegrityConstraintViolationException;
|
||||
|
||||
/**
|
||||
* Tests the insert builder.
|
||||
*
|
||||
|
@ -208,4 +210,26 @@ class InsertTest extends DatabaseTestBase {
|
|||
$this->assertEquals('Update value 2', $saved_value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests insertion integrity violation with no default value for a column.
|
||||
*/
|
||||
public function testInsertIntegrityViolation() {
|
||||
// Remove the default from the 'age' column, so that inserting a record
|
||||
// without its value specified will lead to integrity failure.
|
||||
$this->connection->schema()->changeField('test', 'age', 'age', [
|
||||
'description' => "The person's age",
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
]);
|
||||
|
||||
// Try inserting a record that misses the value for the 'age' column,
|
||||
// should raise an IntegrityConstraintViolationException.
|
||||
$this->expectException(IntegrityConstraintViolationException::class);
|
||||
$this->connection->insert('test')
|
||||
->fields(['name'])
|
||||
->values(['name' => 'Elvis'])
|
||||
->execute();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ namespace Drupal\KernelTests\Core\Entity;
|
|||
|
||||
use Drupal\Component\Plugin\Exception\PluginNotFoundException;
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\Core\Database\DatabaseExceptionWrapper;
|
||||
use Drupal\Core\Database\IntegrityConstraintViolationException;
|
||||
use Drupal\Core\Entity\ContentEntityType;
|
||||
use Drupal\Core\Entity\EntityStorageException;
|
||||
|
@ -482,19 +481,13 @@ class EntityDefinitionUpdateTest extends EntityKernelTestBase {
|
|||
->execute();
|
||||
$this->fail($message);
|
||||
}
|
||||
catch (\RuntimeException $e) {
|
||||
if ($e instanceof DatabaseExceptionWrapper || $e instanceof IntegrityConstraintViolationException) {
|
||||
// Now provide a value for the 'not null' column. This is expected to
|
||||
// succeed.
|
||||
$values['new_bundle_field_shape'] = $this->randomString();
|
||||
$this->database->insert('entity_test_update__new_bundle_field')
|
||||
->fields($values)
|
||||
->execute();
|
||||
}
|
||||
else {
|
||||
// Keep throwing it.
|
||||
throw $e;
|
||||
}
|
||||
catch (IntegrityConstraintViolationException $e) {
|
||||
// Now provide a value for the 'not null' column. This is expected to
|
||||
// succeed.
|
||||
$values['new_bundle_field_shape'] = $this->randomString();
|
||||
$this->database->insert('entity_test_update__new_bundle_field')
|
||||
->fields($values)
|
||||
->execute();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue