diff --git a/dynamic_entity_reference.install b/dynamic_entity_reference.install index f531f8a..da423c4 100644 --- a/dynamic_entity_reference.install +++ b/dynamic_entity_reference.install @@ -127,7 +127,7 @@ function dynamic_entity_reference_update_8201() { /** * Create index on all target_id_int fields. * - * By creating the index, joins on this column will be sped up significantly. + * By creating the index, joins on this column will be speed up significantly. */ function dynamic_entity_reference_update_8202() { $schema = \Drupal::database()->schema(); @@ -149,11 +149,13 @@ function dynamic_entity_reference_update_8202() { try { $table = $table_mapping->getFieldTableName($field_name); $column = $table_mapping->getFieldColumnName($field_storage_definition, 'target_id_int'); + $index_column = $table_mapping->getFieldColumnName($field_storage_definition, 'target_type'); } catch (SqlContentEntityStorageException $e) { // Custom storage? Broken site? No matter what, if there is no table // or column, there's little we can do. continue; } + $schema_info = $field_storage_definition->getSchema(); if ($schema->fieldExists($table, $column)) { $spec = [ 'fields' => [ @@ -161,11 +163,12 @@ function dynamic_entity_reference_update_8202() { 'type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE, - ] + ], + $index_column => $schema_info['columns']['target_type'] ] ]; if (!$schema->indexExists($table, $column)) { - $schema->addIndex($table, $column, [$column], $spec); + $schema->addIndex($table, $column, [$column, $index_column], $spec); } } } diff --git a/src/EventSubscriber/FieldStorageSubscriber.php b/src/EventSubscriber/FieldStorageSubscriber.php index 72d29ba..0951d07 100644 --- a/src/EventSubscriber/FieldStorageSubscriber.php +++ b/src/EventSubscriber/FieldStorageSubscriber.php @@ -128,6 +128,7 @@ class FieldStorageSubscriber implements EventSubscriberInterface { } $entity_type = $this->entityTypeManager->getDefinition($entity_type_id); $tables = []; + $index_columns = []; // If we know which field is being created / updated check whether it is // DER. if ($storage instanceof SqlEntityStorageInterface && !empty($der_fields[$entity_type_id])) { @@ -141,6 +142,7 @@ class FieldStorageSubscriber implements EventSubscriberInterface { try { $table = $mapping->getFieldTableName($field_name); $column = $mapping->getFieldColumnName($storage_definitions[$field_name], 'target_id'); + $index_column = $mapping->getFieldColumnName($storage_definitions[$field_name], 'target_type'); } catch (SqlContentEntityStorageException $e) { // Custom storage? Broken site? No matter what, if there is no table @@ -148,6 +150,11 @@ class FieldStorageSubscriber implements EventSubscriberInterface { continue; } $tables[$table][] = $column; + + $schema_info = $storage_definitions[$field_name]->getSchema(); + $index_columns[$table] = [ + $index_column => $schema_info['columns']['target_type'] + ]; if ($entity_type->isRevisionable() && ($storage_definitions[$field_name]->isRevisionable())) { try { if ($mapping->requiresDedicatedTableStorage($storage_definitions[$field_name])) { @@ -166,7 +173,7 @@ class FieldStorageSubscriber implements EventSubscriberInterface { } $new = []; foreach ($tables as $table => $columns) { - $new[$table] = $this->intColumnHandler->create($table, $columns); + $new[$table] = $this->intColumnHandler->create($table, $columns, $index_columns[$table]); } foreach (array_filter($new) as $table => $columns) { // reset($columns) is one of the new int columns. The trigger will fill diff --git a/src/Storage/IntColumnHandler.php b/src/Storage/IntColumnHandler.php index 3d008ef..4fac340 100644 --- a/src/Storage/IntColumnHandler.php +++ b/src/Storage/IntColumnHandler.php @@ -56,7 +56,7 @@ abstract class IntColumnHandler implements IntColumnHandlerInterface { /** * {@inheritdoc} */ - public function create($table, array $columns) { + public function create($table, array $columns, array $index_columns = []) { $schema = $this->connection->schema(); // The integer column specification. $spec = [ @@ -78,14 +78,21 @@ abstract class IntColumnHandler implements IntColumnHandlerInterface { $column_int = $column . '_int'; // Make sure the integer columns exist. if (!$schema->fieldExists($table, $column_int)) { + $index_fields = [$column_int]; $full_spec = [ 'fields' => [ - $column_int => $spec + $column_int => $spec, ] ]; + + if (!empty($index_columns)) { + $full_spec['fields'] = array_merge($full_spec['fields'], $index_columns); + $index_fields = array_merge($index_fields, array_keys($index_columns)); + } + $new[] = $column_int; $schema->addField($table, $column_int, $spec); - $schema->addIndex($table, $column_int, [$column_int], $full_spec); + $schema->addIndex($table, $column_int, $index_fields, $full_spec); } // This is the heart of this function: before an UPDATE/INSERT, set the // value of the integer column to the integer value of the string column. diff --git a/src/Storage/IntColumnHandlerInterface.php b/src/Storage/IntColumnHandlerInterface.php index c91db36..2be10d7 100644 --- a/src/Storage/IntColumnHandlerInterface.php +++ b/src/Storage/IntColumnHandlerInterface.php @@ -14,10 +14,12 @@ interface IntColumnHandlerInterface { * The non-prefix table to operate on. * @param array $columns * The DER target_id columns. + * @param array $index_columns + * Table columns that should be added to the index that is created for the new _int column. * * @return array * The list of new target_id_int columns. */ - public function create($table, array $columns); + public function create($table, array $columns, array $index_columns = []); } diff --git a/src/Storage/IntColumnHandlerPostgreSQL.php b/src/Storage/IntColumnHandlerPostgreSQL.php index 6d36521..9993116 100644 --- a/src/Storage/IntColumnHandlerPostgreSQL.php +++ b/src/Storage/IntColumnHandlerPostgreSQL.php @@ -29,7 +29,7 @@ class IntColumnHandlerPostgreSQL implements IntColumnHandlerInterface { /** * {@inheritdoc} */ - public function create($table, array $columns) { + public function create($table, array $columns, array $index_columns = []) { $schema = $this->connection->schema(); if (!IntColumnHandler::allColumnsExist($schema, $table, $columns)) { return []; @@ -47,7 +47,19 @@ class IntColumnHandlerPostgreSQL implements IntColumnHandlerInterface { if (!$schema->fieldExists($table, $column_int)) { $this->createTriggerFunction($table, $column, $column_int); $this->createTrigger($table, $column, $column_int); + + $index_fields = [$column_int]; + $full_spec = [ + 'fields' => [ + $column_int => $spec, + ] + ]; + if (!empty($index_columns)) { + $full_spec['fields'] = array_merge($full_spec['fields'], $index_columns); + $index_fields = array_merge($index_fields, array_keys($index_columns)); + } $schema->addField($table, $column_int, $spec); + $schema->addIndex($table, $column_int, $index_fields, $full_spec); $new[] = $column_int; } }