Commit a1730316 authored by alexpott's avatar alexpott

Issue #2561129 by plach, alexpott, catch: Composite indexes are not correctly...

Issue #2561129 by plach, alexpott, catch: Composite indexes are not correctly deleted/re-created when updating a field storage definition
parent 6d4b0ae8
......@@ -588,13 +588,28 @@ public function indexExists($table, $name) {
/**
* Helper function: check if a constraint (PK, FK, UK) exists.
*
* @param $table
* @param string $table
* The name of the table.
* @param $name
* The name of the constraint (typically 'pkey' or '[constraint]_key').
* @param string $name
* The name of the constraint (typically 'pkey' or '[constraint]__key').
*
* @return bool
* TRUE if the constraint exists, FALSE otherwise.
*/
public function constraintExists($table, $name) {
$constraint_name = $this->ensureIdentifiersLength($table, $name);
// ::ensureIdentifiersLength() expects three parameters, although not
// explicitly stated in its signature, thus we split our constraint name in
// a proper name and a suffix.
if ($name == 'pkey') {
$suffix = $name;
$name = '';
}
else {
$pos = strrpos($name, '__');
$suffix = substr($name, $pos + 2);
$name = substr($name, 0, $pos);
}
$constraint_name = $this->ensureIdentifiersLength($table, $name, $suffix);
// Remove leading and trailing quotes because the index name is in a WHERE
// clause and not used as an identifier.
$constraint_name = str_replace('"', '', $constraint_name);
......
......@@ -509,6 +509,18 @@ public function testEntityIndexCreateDeleteWithoutData() {
// Run the update and ensure the index is deleted.
$this->entityDefinitionUpdateManager->applyUpdates();
$this->assertFalse($this->database->schema()->indexExists('entity_test_update', 'entity_test_update__new_index'), 'Index deleted.');
// Test that composite indexes are handled correctly when dropping and
// re-creating one of their columns.
$this->addEntityIndex();
$this->entityDefinitionUpdateManager->applyUpdates();
$storage_definition = $this->entityDefinitionUpdateManager->getFieldStorageDefinition('name', 'entity_test_update');
$this->entityDefinitionUpdateManager->updateFieldStorageDefinition($storage_definition);
$this->assertTrue($this->database->schema()->indexExists('entity_test_update', 'entity_test_update__new_index'), 'Index created.');
$this->entityDefinitionUpdateManager->uninstallFieldStorageDefinition($storage_definition);
$this->assertFalse($this->database->schema()->indexExists('entity_test_update', 'entity_test_update__new_index'), 'Index deleted.');
$this->entityDefinitionUpdateManager->installFieldStorageDefinition('name', 'entity_test_update', 'entity_test', $storage_definition);
$this->assertTrue($this->database->schema()->indexExists('entity_test_update', 'entity_test_update__new_index'), 'Index created again.');
}
/**
......
<?php
/**
* @file
* Contains \Drupal\Tests\Core\Database\Driver\pgsql\PostgresqlSchemaTest.
*/
namespace Drupal\Tests\Core\Database\Driver\pgsql;
use Drupal\Core\Database\Driver\pgsql\Schema;
use Drupal\Tests\UnitTestCase;
/**
* @coversDefaultClass \Drupal\Core\Database\Driver\pgsql\Schema
* @group Database
*/
class PostgresqlSchemaTest extends UnitTestCase {
/**
* The PostgreSql DB connection.
*
* @var \PHPUnit_Framework_MockObject_MockObject|\Drupal\Core\Database\Driver\pgsql\Connection
*/
protected $connection;
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->connection = $this->getMockBuilder('\Drupal\Core\Database\Driver\pgsql\Connection')
->disableOriginalConstructor()
->getMock();
}
/**
* Tests whether the actual constraint name is correctly computed.
*
* @param string $table_name
* The table name the constrained column belongs to.
* @param string $name
* The constraint name.
* @param string $expected
* The expected computed constraint name.
*
* @covers ::constraintExists
* @dataProvider providerComputedConstraintName
*/
public function testComputedConstraintName($table_name, $name, $expected) {
$max_identifier_length = 63;
$schema = new Schema($this->connection);
$statement = $this->getMock('\Drupal\Core\Database\StatementInterface');
$statement->expects($this->any())
->method('fetchField')
->willReturn($max_identifier_length);
$this->connection->expects($this->any())
->method('query')
->willReturn($statement);
$this->connection->expects($this->at(2))
->method('query')
->with("SELECT 1 FROM pg_constraint WHERE conname = '$expected'")
->willReturn($this->getMock('\Drupal\Core\Database\StatementInterface'));
$schema->constraintExists($table_name, $name);
}
/**
* Data provider for ::testComputedConstraintName().
*/
public function providerComputedConstraintName() {
return [
['user_field_data', 'pkey', 'user_field_data____pkey'],
['user_field_data', 'name__key', 'user_field_data__name__key'],
['user_field_data', 'a_veeeery_veery_very_super_long_field_name__key', 'drupal_BGGYAXgbqlAF1rMOyFTdZGj9zIMXZtSvEjMAKZ9wGIk_key'],
];
}
}
......@@ -1395,7 +1395,6 @@ public function setUpStorageDefinition($field_name, array $schema) {
* ::onEntityTypeUpdate
*/
public function testonEntityTypeUpdateWithNewIndex() {
$entity_type_id = 'entity_test';
$this->entityType = $original_entity_type = new ContentEntityType(array(
'id' => 'entity_test',
'entity_keys' => array('id' => 'id'),
......@@ -1465,6 +1464,9 @@ public function testonEntityTypeUpdateWithNewIndex() {
->method('dropIndex')
->with('entity_test', 'entity_test__removed_field');
$this->dbSchemaHandler->expects($this->atLeastOnce())
->method('fieldExists')
->willReturn(TRUE);
$this->dbSchemaHandler->expects($this->atLeastOnce())
->method('addIndex')
->with('entity_test', 'entity_test__b588603cb9', [['long_index_name', 10]], $this->callback(function($actual_value) use ($expected) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment