function SchemaTest::testIndexLength

Same name and namespace in other branches
  1. 9 core/modules/mysql/tests/src/Kernel/mysql/SchemaTest.php \Drupal\Tests\mysql\Kernel\mysql\SchemaTest::testIndexLength()
  2. 8.9.x core/tests/Drupal/KernelTests/Core/Database/SchemaTest.php \Drupal\KernelTests\Core\Database\SchemaTest::testIndexLength()
  3. 10 core/modules/mysql/tests/src/Kernel/mysql/SchemaTest.php \Drupal\Tests\mysql\Kernel\mysql\SchemaTest::testIndexLength()

Tests that indexes on string fields are limited to 191 characters on MySQL.

See also

\Drupal\mysql\Driver\Database\mysql\Schema::getNormalizedIndexes()

File

core/modules/mysql/tests/src/Kernel/mysql/SchemaTest.php, line 74

Class

SchemaTest
Tests schema API for the MySQL driver.

Namespace

Drupal\Tests\mysql\Kernel\mysql

Code

public function testIndexLength() : void {
  $table_specification = [
    'fields' => [
      'id' => [
        'type' => 'int',
        'default' => NULL,
      ],
      'test_field_text' => [
        'type' => 'text',
        'not null' => TRUE,
      ],
      'test_field_string_long' => [
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
      ],
      'test_field_string_ascii_long' => [
        'type' => 'varchar_ascii',
        'length' => 255,
      ],
      'test_field_string_short' => [
        'type' => 'varchar',
        'length' => 128,
        'not null' => TRUE,
      ],
    ],
    'indexes' => [
      'test_regular' => [
        'test_field_text',
        'test_field_string_long',
        'test_field_string_ascii_long',
        'test_field_string_short',
      ],
      'test_length' => [
        [
          'test_field_text',
          128,
        ],
        [
          'test_field_string_long',
          128,
        ],
        [
          'test_field_string_ascii_long',
          128,
        ],
        [
          'test_field_string_short',
          128,
        ],
      ],
      'test_mixed' => [
        [
          'test_field_text',
          200,
        ],
        'test_field_string_long',
        [
          'test_field_string_ascii_long',
          200,
        ],
        'test_field_string_short',
      ],
    ],
  ];
  $this->schema
    ->createTable('test_table_index_length', $table_specification);
  // Ensure expected exception thrown when adding index with missing info.
  $expected_exception_message = "MySQL needs the 'test_field_text' field specification in order to normalize the 'test_regular' index";
  $missing_field_spec = $table_specification;
  unset($missing_field_spec['fields']['test_field_text']);
  try {
    $this->schema
      ->addIndex('test_table_index_length', 'test_separate', [
      [
        'test_field_text',
        200,
      ],
    ], $missing_field_spec);
    $this->fail('SchemaException not thrown when adding index with missing information.');
  } catch (SchemaException $e) {
    $this->assertEquals($expected_exception_message, $e->getMessage());
  }
  // Add a separate index.
  $this->schema
    ->addIndex('test_table_index_length', 'test_separate', [
    [
      'test_field_text',
      200,
    ],
  ], $table_specification);
  $table_specification_with_new_index = $table_specification;
  $table_specification_with_new_index['indexes']['test_separate'] = [
    [
      'test_field_text',
      200,
    ],
  ];
  // Ensure that the exceptions of addIndex are thrown as expected.
  try {
    $this->schema
      ->addIndex('test_table_index_length', 'test_separate', [
      [
        'test_field_text',
        200,
      ],
    ], $table_specification);
    $this->fail('\\Drupal\\Core\\Database\\SchemaObjectExistsException exception missed.');
  } catch (SchemaObjectExistsException) {
    // Expected exception; just continue testing.
  }
  try {
    $this->schema
      ->addIndex('test_table_non_existing', 'test_separate', [
      [
        'test_field_text',
        200,
      ],
    ], $table_specification);
    $this->fail('\\Drupal\\Core\\Database\\SchemaObjectDoesNotExistException exception missed.');
  } catch (SchemaObjectDoesNotExistException) {
    // Expected exception; just continue testing.
  }
  // Get index information.
  $results = $this->connection
    ->query('SHOW INDEX FROM {test_table_index_length}');
  $expected_lengths = [
    'test_regular' => [
      'test_field_text' => 191,
      'test_field_string_long' => 191,
      'test_field_string_ascii_long' => NULL,
      'test_field_string_short' => NULL,
    ],
    'test_length' => [
      'test_field_text' => 128,
      'test_field_string_long' => 128,
      'test_field_string_ascii_long' => 128,
      'test_field_string_short' => NULL,
    ],
    'test_mixed' => [
      'test_field_text' => 191,
      'test_field_string_long' => 191,
      'test_field_string_ascii_long' => 200,
      'test_field_string_short' => NULL,
    ],
    'test_separate' => [
      'test_field_text' => 191,
    ],
  ];
  // Count the number of columns defined in the indexes.
  $column_count = 0;
  foreach ($table_specification_with_new_index['indexes'] as $index) {
    $column_count += count($index);
  }
  $test_count = 0;
  foreach ($results as $result) {
    $this->assertEquals($expected_lengths[$result->Key_name][$result->Column_name], $result->Sub_part, 'Index length matches expected value.');
    $test_count++;
  }
  $this->assertEquals($column_count, $test_count, 'Number of tests matches expected value.');
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.