diff --git a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php index b81f7054326..24f46508e3a 100644 --- a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php +++ b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php @@ -906,7 +906,9 @@ class SqlContentEntityStorageSchema implements DynamicallyFieldableEntityStorage $schema = array( 'description' => "The data table for $entity_type_id entities.", 'primary key' => array($id_key, $entity_type->getKey('langcode')), - 'indexes' => array(), + 'indexes' => array( + $entity_type_id . '__id__default_langcode__langcode' => array($id_key, $entity_type->getKey('default_langcode'), $entity_type->getKey('langcode')), + ), 'foreign keys' => array( $entity_type_id => array( 'table' => $this->storage->getBaseTable(), @@ -942,7 +944,9 @@ class SqlContentEntityStorageSchema implements DynamicallyFieldableEntityStorage $schema = array( 'description' => "The revision data table for $entity_type_id entities.", 'primary key' => array($revision_key, $entity_type->getKey('langcode')), - 'indexes' => array(), + 'indexes' => array( + $entity_type_id . '__id__default_langcode__langcode' => array($id_key, $entity_type->getKey('default_langcode'), $entity_type->getKey('langcode')), + ), 'foreign keys' => array( $entity_type_id => array( 'table' => $this->storage->getBaseTable(), @@ -1017,6 +1021,9 @@ class SqlContentEntityStorageSchema implements DynamicallyFieldableEntityStorage * A partial schema array for the base table. */ protected function processDataTable(ContentEntityTypeInterface $entity_type, array &$schema) { + // Marking the respective fields as NOT NULL makes the indexes more + // performant. + $schema['fields'][$entity_type->getKey('default_langcode')]['not null'] = TRUE; } /** @@ -1031,6 +1038,9 @@ class SqlContentEntityStorageSchema implements DynamicallyFieldableEntityStorage * A partial schema array for the base table. */ protected function processRevisionDataTable(ContentEntityTypeInterface $entity_type, array &$schema) { + // Marking the respective fields as NOT NULL makes the indexes more + // performant. + $schema['fields'][$entity_type->getKey('default_langcode')]['not null'] = TRUE; } /** diff --git a/core/modules/node/src/NodeStorageSchema.php b/core/modules/node/src/NodeStorageSchema.php index 320f797305b..4423a5ad92c 100644 --- a/core/modules/node/src/NodeStorageSchema.php +++ b/core/modules/node/src/NodeStorageSchema.php @@ -22,22 +22,12 @@ class NodeStorageSchema extends SqlContentEntityStorageSchema { protected function getEntitySchema(ContentEntityTypeInterface $entity_type, $reset = FALSE) { $schema = parent::getEntitySchema($entity_type, $reset); - // Marking the respective fields as NOT NULL makes the indexes more - // performant. - $schema['node_field_data']['fields']['default_langcode']['not null'] = TRUE; - $schema['node_field_revision']['fields']['default_langcode']['not null'] = TRUE; - $schema['node_field_data']['indexes'] += array( - 'node__default_langcode' => array('default_langcode'), 'node__frontpage' => array('promote', 'status', 'sticky', 'created'), 'node__status_type' => array('status', 'type', 'nid'), 'node__title_type' => array('title', array('type', 4)), ); - $schema['node_field_revision']['indexes'] += array( - 'node__default_langcode' => array('default_langcode'), - ); - return $schema; } @@ -73,7 +63,6 @@ class NodeStorageSchema extends SqlContentEntityStorageSchema { case 'changed': case 'created': - case 'langcode': // @todo Revisit index definitions: // https://www.drupal.org/node/2015277. $this->addSharedTableFieldIndex($storage_definition, $schema, TRUE); @@ -81,14 +70,6 @@ class NodeStorageSchema extends SqlContentEntityStorageSchema { } } - if ($table_name == 'node_field_revision') { - switch ($field_name) { - case 'langcode': - $this->addSharedTableFieldIndex($storage_definition, $schema, TRUE); - break; - } - } - return $schema; } diff --git a/core/modules/system/src/Tests/Entity/Update/SqlContentEntityStorageSchemaIndexTest.php b/core/modules/system/src/Tests/Entity/Update/SqlContentEntityStorageSchemaIndexTest.php new file mode 100644 index 00000000000..527c32348bf --- /dev/null +++ b/core/modules/system/src/Tests/Entity/Update/SqlContentEntityStorageSchemaIndexTest.php @@ -0,0 +1,42 @@ +databaseDumpFiles = [ + __DIR__ . '/../../../../tests/fixtures/update/drupal-8.bare.standard.php.gz', + ]; + parent::setUp(); + } + + /** + * Test for the new index. + */ + public function testIndex() { + $this->assertTrue(db_index_exists('node_field_data', 'node__default_langcode'), 'Index node__default_langcode exists prior to running updates.'); + $this->assertFalse(db_index_exists('node_field_data', 'node__id__default_langcode__langcode'), 'Index node__id__default_langcode__langcode does not exist prior to running updates.'); + $this->assertFalse(db_index_exists('users_field_data', 'user__id__default_langcode__langcode'), 'Index users__id__default_langcode__langcode does not exist prior to running updates.'); + $this->runUpdates(); + $this->assertFalse(db_index_exists('node_field_data', 'node__default_langcode'), 'Index node__default_langcode properly removed.'); + $this->assertTrue(db_index_exists('node_field_data', 'node__id__default_langcode__langcode'), 'Index node__id__default_langcode__langcode properly created on the node_field_data table.'); + $this->assertTrue(db_index_exists('users_field_data', 'user__id__default_langcode__langcode'), 'Index users__id__default_langcode__langcode properly created on the user_field_data table.'); + } + +} diff --git a/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageSchemaTest.php b/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageSchemaTest.php index e67b8e6a875..9b6f0e2d759 100644 --- a/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageSchemaTest.php +++ b/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageSchemaTest.php @@ -502,6 +502,15 @@ class SqlContentEntityStorageSchemaTest extends UnitTestCase { ), )); + $this->setUpStorageDefinition('default_langcode', array( + 'columns' => array( + 'value' => array( + 'type' => 'int', + 'size' => 'tiny', + ), + ), + )); + $expected = array( 'entity_test' => array( 'description' => 'The base table for entity_test entities.', @@ -531,10 +540,21 @@ class SqlContentEntityStorageSchemaTest extends UnitTestCase { 'type' => 'varchar', 'not null' => TRUE, ), + 'default_langcode' => array( + 'type' => 'int', + 'size' => 'tiny', + 'not null' => true, + ), ), 'primary key' => array('id', 'langcode'), 'unique keys' => array(), - 'indexes' => array(), + 'indexes' => array( + 'entity_test__id__default_langcode__langcode' => array( + 0 => 'id', + 1 => 'default_langcode', + 2 => 'langcode', + ), + ), 'foreign keys' => array( 'entity_test' => array( 'table' => 'entity_test', @@ -547,7 +567,9 @@ class SqlContentEntityStorageSchemaTest extends UnitTestCase { $this->setUpStorageSchema($expected); $table_mapping = new DefaultTableMapping($this->entityType, $this->storageDefinitions); - $table_mapping->setFieldNames('entity_test', array_keys($this->storageDefinitions)); + $non_data_fields = array_keys($this->storageDefinitions); + unset($non_data_fields[array_search('default_langcode', $non_data_fields)]); + $table_mapping->setFieldNames('entity_test', $non_data_fields); $table_mapping->setFieldNames('entity_test_field_data', array_keys($this->storageDefinitions)); $this->storage->expects($this->any()) @@ -604,6 +626,14 @@ class SqlContentEntityStorageSchemaTest extends UnitTestCase { ), ), )); + $this->setUpStorageDefinition('default_langcode', array( + 'columns' => array( + 'value' => array( + 'type' => 'int', + 'size' => 'tiny', + ), + ), + )); $expected = array( 'entity_test' => array( @@ -677,11 +707,21 @@ class SqlContentEntityStorageSchemaTest extends UnitTestCase { 'type' => 'varchar', 'not null' => TRUE, ), + 'default_langcode' => array( + 'type' => 'int', + 'size' => 'tiny', + 'not null' => true, + ), ), 'primary key' => array('id', 'langcode'), 'unique keys' => array(), 'indexes' => array( 'entity_test__revision_id' => array('revision_id'), + 'entity_test__id__default_langcode__langcode' => array( + 0 => 'id', + 1 => 'default_langcode', + 2 => 'langcode', + ), ), 'foreign keys' => array( 'entity_test' => array( @@ -705,10 +745,21 @@ class SqlContentEntityStorageSchemaTest extends UnitTestCase { 'type' => 'varchar', 'not null' => TRUE, ), + 'default_langcode' => array( + 'type' => 'int', + 'size' => 'tiny', + 'not null' => true, + ), ), 'primary key' => array('revision_id', 'langcode'), 'unique keys' => array(), - 'indexes' => array(), + 'indexes' => array( + 'entity_test__id__default_langcode__langcode' => array( + 0 => 'id', + 1 => 'default_langcode', + 2 => 'langcode', + ), + ), 'foreign keys' => array( 'entity_test' => array( 'table' => 'entity_test', @@ -725,8 +776,10 @@ class SqlContentEntityStorageSchemaTest extends UnitTestCase { $this->setUpStorageSchema($expected); $table_mapping = new DefaultTableMapping($this->entityType, $this->storageDefinitions); - $table_mapping->setFieldNames('entity_test', array_keys($this->storageDefinitions)); - $table_mapping->setFieldNames('entity_test_revision', array_keys($this->storageDefinitions)); + $non_data_fields = array_keys($this->storageDefinitions); + unset($non_data_fields[array_search('default_langcode', $non_data_fields)]); + $table_mapping->setFieldNames('entity_test', $non_data_fields); + $table_mapping->setFieldNames('entity_test_revision', $non_data_fields); $table_mapping->setFieldNames('entity_test_field_data', array_keys($this->storageDefinitions)); $table_mapping->setFieldNames('entity_test_revision_field_data', array_keys($this->storageDefinitions));