Commit caff9cac authored by Thomas Seiber's avatar Thomas Seiber
Browse files

Issue #3227268 by drunken monkey, Driskell: Fixed inconsistent collation in Database backend.

parent 35281817
Loading
Loading
Loading
Loading
+2 −0
Changes for CHANGELOG.txt: 2 added lines, 0 removed lines.
Original line number Diff line number Diff line
Search API 1.x, dev (xxxx-xx-xx):
---------------------------------
- #3227268 by drunken monkey, Driskell: Fixed inconsistent collation in
  Database backend.
- #3196990 by nguerrier, ekes, drunken monkey, hswong3i: Fixed wrong query and
  cache type on Search API views.
- #3258802 by drunken monkey: Fixed errors when indexing fields with unknown
+6 −0
Changes for modules/search_api_db/src/DatabaseCompatibility/MySql.php: 6 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -24,6 +24,12 @@ class MySql extends GenericDatabase {
    $collation = $type === 'text' ? 'utf8mb4_bin' : 'utf8_general_ci';
    try {
      $this->database->query("ALTER TABLE {{$table}} CONVERT TO CHARACTER SET '$charset' COLLATE '$collation'");
      // Even for text tables, we need the "item_id" column to have the same
      // collation as everywhere else. Otherwise, this can slow down search
      // queries significantly.
      if ($type === 'text') {
        $this->database->query("ALTER TABLE {{$table}} MODIFY item_id VARCHAR(150) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci'");
      }
    }
    catch (\PDOException $e) {
      $class = get_class($e);
+29 −0
Changes for modules/search_api_db/tests/src/Kernel/BackendTest.php: 29 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -151,6 +151,7 @@ class BackendTest extends BackendTestBase {
    $this->regressionTest3199355();
    $this->regressionTest3225675();
    $this->regressionTest3258802();
    $this->regressionTest3227268();
  }

  /**
@@ -955,6 +956,34 @@ class BackendTest extends BackendTestBase {
    $this->disableModules(['search_api_test']);
  }

  /**
   * Tests whether the text table's "item_id" column has the correct collation.
   *
   * This check is only active on MySQL.
   *
   * @see https://www.drupal.org/node/3227268
   *
   * @see \Drupal\search_api_db\DatabaseCompatibility\MySql::alterNewTable()
   */
  protected function regressionTest3227268(): void {
    $database = \Drupal::database();
    if ($database->driver() !== 'mysql') {
      return;
    }
    $db_info = $this->getIndexDbInfo();
    $text_table = $db_info['field_tables']['body']['table'];
    $this->assertTrue(\Drupal::database()->schema()->tableExists($text_table));
    $sql = "SHOW FULL COLUMNS FROM {{$text_table}}";
    $collations = [];
    foreach ($database->query($sql) as $row) {
      $collations[$row->Field] = $row->Collation;
    }
    // Unfortunately, it's not consistent whether the database will report the
    // collation as "utf8_general_ci" or "utf8mb3_general_ci".
    $this->assertContains($collations['item_id'], ['utf8mb3_general_ci', 'utf8_general_ci']);
    $this->assertEquals('utf8mb4_bin', $collations['word']);
  }

  /**
   * {@inheritdoc}
   */