Problem/Motivation

In #1314214: MySQL driver does not support full UTF-8 (emojis, asian symbols, mathematical symbols), the MySQL schema class added the ability to normalize index length. However, this only works when the table is first created. When calling Schema::addIndex(), indexes do not get normalized. Furthermore, the code calling Schema::addIndex() should not attempt to perform the work of Schema::getNormalizedIndexes(), since that implementation is MySQL-specific.

This will be an issue for the automatic entity schema update system when new indexes are added that should be normalized in MySQL. In SqlContentEntityStorageSchema::onEntityUpdateType:

      // Create new indexes and unique keys.
      $entity_schema = $this->getEntitySchema($entity_type, TRUE);
      foreach ($this->getEntitySchemaData($entity_type, $entity_schema) as $table_name => $schema) {
        if (!empty($schema['indexes'])) {
          foreach ($schema['indexes'] as $name => $specifier) {
            $schema_handler->addIndex($table_name, $name, $specifier);
          }
        }

will throw an uncaught exception if the index is too long in MySQL (for instance, see #2507201-3: Upgrade path for MySQL switch to multibyte UTF8)

Proposed resolution

  • Expand the Schema::addIndex() method to get the full table schema as 4th argument

Alternative proposal which have been out:

  • Replace $fields with $spec: This makes it less obvious for code to update AND it makes the code really hard to read because the index fields are not directly visible
  • Add a new method Schema::addNormalizedIndex() which takes $table, $index_index_name, $spec (Same problems as before)

Remaining tasks

Commit.

User interface changes

None.

API changes

New required table schema:

Before

    db_add_index('test_table', 'test_field', array('test_field'));

After

    db_add_index('test_table', 'test_field', array('test_field'), $table_specification);

Data model changes

None.

CommentFileSizeAuthor
#105 2537928.104.patch25.43 KBalexpott
#105 103-104-interdiff.txt1.83 KBalexpott
#103 2537928-103.patch24.65 KBdawehner
#99 2537928-97.patch21.28 KBdawehner
#99 interdiff.txt5.2 KBdawehner
#99 2537928-test.patch5.2 KBdawehner
#98 2537928.97.patch19.45 KBalexpott
#98 95-97-interdiff.txt2.98 KBalexpott
#96 2537928.95.patch17.78 KBalexpott
#96 90-95-interdiff.txt4.23 KBalexpott
#90 76-90.interdiff.txt1020 byteswebflo
#90 2537928.90.patch14.41 KBwebflo
#89 76-88.interdiff.txt1018 byteswebflo
#88 2537928.88.patch14.41 KBwebflo
#76 2537928.76.patch14.11 KBalexpott
#76 71-76-interdiff.txt3.13 KBalexpott
#71 interdiff-70-71.txt1.06 KBstefan.r
#71 2537928-71.patch15.33 KBstefan.r
#70 interdiff-65-70.txt2.47 KBstefan.r
#70 2537928-70.patch15.28 KBstefan.r
#65 interdiff-61-65.txt3.83 KBstefan.r
#65 2537928-65.patch15.23 KBstefan.r
#61 interdiff.txt1.72 KBdawehner
#61 2537928-61.patch13.25 KBdawehner
#58 interdiff.txt749 bytesdawehner
#58 2537928-58.patch13.38 KBdawehner
#57 interdiff.txt4.5 KBdawehner
#57 2537928-57.patch13.16 KBdawehner
#49 2537928-49.patch13.72 KBstefan.r
#49 interdiff-44-49.txt1.33 KBstefan.r
#46 interdiff-32-44.txt17.94 KBstefan.r
#44 interdiff.txt847 bytesdawehner
#44 2537928-44.patch13.73 KBdawehner
#42 2537928-42.patch12.9 KBdawehner
#33 index-normalization-2537928-32.patch13.15 KBjhedstrom
#33 interdiff.txt3.66 KBjhedstrom
#29 interdiff-25-29.txt2.02 KBstefan.r
#29 2537928-29.patch12.28 KBstefan.r
#25 interdiff-22-25.txt1.63 KBstefan.r
#25 2537928-25.patch10.22 KBstefan.r
#22 2537928-22.patch9.37 KBstefan.r
#22 interdiff-21-22.txt795 bytesstefan.r
#21 2537928-21.patch9.47 KBstefan.r
#21 interdiff-17-21.txt3.57 KBstefan.r
#17 2537928-17.patch8.82 KBstefan.r
#6 index-normalization-2537928-06.patch4.52 KBjhedstrom
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

stefan.r’s picture

What other use cases can we think of where this is potentially a problem, is this isolated to yet to be developed contrib modules?

If as far as core is concerned the problem only shows up in onEntityUpdateType() I wonder if we actually need to be normalizing in addIndex() or whether it would be enough to just update onEntityUpdateType() to do $indexes = getNormalizedIndexes($schema);

Otherwise catching the exception with a more helpful error message might be another possible solution.

jhedstrom’s picture

$indexes = getNormalizedIndexes($schema) this is protected though, and currently MySQL-specific. We could add that method to the other drivers and have the current implementation in sqlite and pgsql do nothing.

jhedstrom’s picture

What other use cases can we think of where this is potentially a problem?

I would think anytime a new index needs to be added to an existing table, this would be a potential issue. The current implementation is MySQL-specific, so callers should not attempt to shorted indexes themselves.

jhedstrom’s picture

Issue summary: View changes

Updating IS with approach from #2.

stefan.r’s picture

Hmm OK so doing this in onEntityUpdateType would still be a bit ugly given the index normalization is likely to remain mysql-specific.

In order to do the normalization in addIndex() we'd need to have the full table schema somehow (not just the index specification).

jhedstrom’s picture

Status: Active » Needs review
FileSize
4.52 KB

This does seem a bit ugly. However, it would allow sqlite or pgsql to adjust indexes in the future if need be (they do have some finite length from what I can tell, it just seems much larger than mysql).

jhedstrom’s picture

Issue summary: View changes
stefan.r’s picture

Yes that should work. Still, as you mentioned we may run into the same problem elsewhere, any time contrib/custom/core code were to call addIndex() directly it'd also need to call getNormalizedIndexes().

So it could be good to either mention that in the docblock for addIndex(), or maybe we could deprecate addIndex() and add an addNormalizedIndex() method that takes the full table spec as a parameter, what do you think?

jhedstrom’s picture

Assigned: Unassigned » jhedstrom

I like adding addNormalizedIndex and marking addIndex deprecated. It would be really nice if we could keep addIndex as the name in the long run though. Perhaps deprecate `addIndex` for 8.0, then remove in 8.1, then mark addNormalizedIndex deprecated and re-add addIndex in 8.2?

jhedstrom’s picture

Or the new method could just be addIndexes()

Status: Needs review » Needs work

The last submitted patch, 6: index-normalization-2537928-06.patch, failed testing.

stefan.r’s picture

I could go with either... if it's just addIndexes() maybe we could still deprecate addIndex().

catch’s picture

Issue tags: +D8 upgrade path
catch’s picture

Priority: Major » Critical

Bumping to critical - this means fatal errors on some entity auto-updates, and they're also fatal errors which the current testbot configuration doesn't catch because it has long index support enabled, so they won't necessarily be caught when writing/testing the updates.

dawehner’s picture

+++ b/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php
@@ -294,19 +294,13 @@ protected function createKeysSql($spec) {
+    $indexes = isset($spec['indexes']) ? $spec['indexes'] : [];

+++ b/core/lib/Drupal/Core/Database/Schema.php
@@ -422,6 +422,19 @@ public function fieldExists($table, $column) {
+  public function getNormalizedIndexes($spec) {

Sounds like this could us ethe parent method

jhedstrom’s picture

Issue summary: View changes

Updating the IS to reflect more recent direction.

stefan.r’s picture

Status: Needs work » Needs review
FileSize
8.82 KB

Just a draft of a patch, anyone feel free to work further on this

Status: Needs review » Needs work

The last submitted patch, 17: 2537928-17.patch, failed testing.

jhedstrom’s picture

Assigned: jhedstrom » Unassigned
+++ b/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php
@@ -497,6 +497,21 @@ public function addIndex($table, $name, $fields) {
+

+++ b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php
@@ -1303,8 +1303,9 @@ protected function updateDedicatedTableSchema(FieldStorageDefinitionInterface $s
+          $mock_schema = ['indexes' => [$real_name => $real_columns]];

This won't give MySQL everything it needs--can we just copy $schema and then set $schema_copy['indexes'][$name] = $real_columns?

catch’s picture

Issue tags: +Triaged D8 critical

We discussed this on the 8.x critical triage call with webchick, xjm, alexbronstein and alexpott and all agreed that it's release blocking - due to fatal errors for straightforward updates that would have worked as table creations, and also the unpredictability between environments.

Adding triaged tag.

stefan.r’s picture

FileSize
3.57 KB
9.47 KB
stefan.r’s picture

Status: Needs work » Needs review
FileSize
795 bytes
9.37 KB
dawehner’s picture

+++ b/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php
@@ -497,6 +497,21 @@ public function addIndex($table, $name, $fields) {
+      throw new SchemaIndexNotInSpecException(t("The index @name doesn't exist in the @table table specification.", array('@table' => $table, '@name' => $name)));
...
+      throw new SchemaObjectDoesNotExistException(t("Cannot add index @name to table @table: table doesn't exist.", array('@table' => $table, '@name' => $name)));
...
+      throw new SchemaObjectExistsException(t("Cannot add index @name to table @table: index already exists.", array('@table' => $table, '@name' => $name)));

Quick note: we don't translate exceptions ... is there a reason why we can't share all the common code between the implementations?

stefan.r’s picture

opened #2538814: Do not use t() in exceptions for that.

I guess we could share the exception code, would you suggest a separate method? Something like validateNormalizedIndexes($indexes, $table, $name)

stefan.r’s picture

jhedstrom’s picture

+++ b/core/lib/Drupal/Core/Database/Schema.php
@@ -418,10 +418,48 @@ public function fieldExists($table, $column) {
+   * @deprecated in Drupal 8.0.x-dev and will be removed before Drupal 9.0.0.

As an aside, by 9.0.0, we could reclaim the addIndex() name and simply change the arguments.

+++ b/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php
@@ -497,6 +497,21 @@ public function addIndex($table, $name, $fields) {
+      throw new SchemaIndexNotInSpecException(t("The index @name doesn't exist in the @table table specification.", array('@table' => $table, '@name' => $name)));

+++ b/core/lib/Drupal/Core/Database/Driver/pgsql/Schema.php
@@ -649,6 +649,22 @@ public function addIndex($table, $name, $fields) {
+      throw new SchemaIndexNotInSpecException(t("The index @name doesn't exist in the @table table specification.", array('@table' => $table, '@name' => $name)));

This exception doesn't exist yet from what I can tell.

The last submitted patch, 22: 2537928-22.patch, failed testing.

dawehner’s picture

@stefan.r
Well there is no reason to introduce new ones.

stefan.r’s picture

Added test & exception

The last submitted patch, 25: 2537928-25.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 29: 2537928-29.patch, failed testing.

jhedstrom’s picture

Assigned: Unassigned » jhedstrom

Working on fixing the failing tests.

jhedstrom’s picture

This should address the remaining failing tests.

jhedstrom’s picture

jhedstrom’s picture

Since contrib drivers are going to need updating anyway, thoughts on just changing the arguments to addIndex()?

stefan.r’s picture

Yes, if we think we can make an exception to the API freeze here, addIndex() does make more sense as a method name.

The worry would be that maintainers forget to upgrade their modules but considering the number of D8 modules is currently manageable maybe we could grep through all existing contrib modules (both now and before D8 release) and personally chase the maintainers? Which contrib modules currently call this method, is it limited to database drivers?

Also if we do change the 3rd parameter we'd need to do some slightly stricter checking of the 3rd argument so we can distinguish between a table spec and a list of index fields and throw a specific exception in case someone still uses $fields instead of $spec.

jhedstrom’s picture

Issue summary: View changes

Updating IS to reflect #35 and #36.

dawehner’s picture

So to be clear, I think naming it addIndex() is the right thing to do, given that this is what people expect to exist.

The current signature of the patch looks like the following:

add(normalized)Index($table, $name, $fields)

What about doing the following:

addIndex($table, $name, $fields, array $full_table_spec)

This makes it a) really clear how your index looks like while reading the code. This is not really the case IMHO with the current proposed API.
On top of it b) existing calls to that method will break immediately which is IMHO both okay (given we solve a critical) but at the same time makes it really visible, so contrib/custom code can be adapted. With that signature I would suggest merging in the index fields into the full table spec, so you don't need to specify it twice.

Curious why we can't take into account #23 beside laziness :)

stefan.r’s picture

sounds fine to me, do we have an idea about which contrib modules call addIndex() so we know what exactly we're breaking?

dawehner’s picture

sounds fine to me, do we have an idea about which contrib modules call addIndex() so we know what exactly we're breaking?

I bet the only common usecase are in hook_update_N() functions.

dawehner’s picture

Cool, let me give that a quick try.

dawehner’s picture

  1. Expanded the test coverage a bit for the exceptions
  2. Refactored the exception throwing logic into its own method. There I also removed the t() function from the exception itself. This really is just old code we are dealing with.
  3. Changed the API as written above
  4. Once done 3) I realized that the new exception will never be thrown on a real life, because the schema::addIndex implementations will take care of it, so I removed that again.

Status: Needs review » Needs work

The last submitted patch, 42: 2537928-42.patch, failed testing.

dawehner’s picture

Status: Needs work » Needs review
FileSize
13.73 KB
847 bytes

Let's fix the failures.

dawehner’s picture

Issue summary: View changes

Updated the issue summary

stefan.r’s picture

FileSize
17.94 KB

Nice work, patch looks good! This will probably need a change record?

dawehner’s picture

Here is one.

dawehner’s picture

Issue summary: View changes

Updated the IS

stefan.r’s picture

dawehner’s picture

+1 Thank you stefan.r

So I think we just need someone who RTBCs this patch.

benjy’s picture

Patch looks OK, one small thing:

+++ b/core/includes/database.inc
@@ -654,9 +654,11 @@ function db_drop_unique_key($table, $name) {
+ * @param array $spec
+ *   A table specification.
...
+function db_add_index($table, $name, $fields, array $spec) {

We don't normally use abbreviated variable names?

stefan.r’s picture

If we decide to unabbreviate that we may want to update the following too as they use the abbreviated name $spec as well:

Schema::createKeysSql(),
Schema::createFieldSql(),
Schema::addField(),
Schema::getNormalizedIndexes()
Schema::changeField()
db_add_field()
db_change_field()

dawehner’s picture

If we decide to unabbreviate that we may want to update the following too as they use the abbreviated name $spec as well:

Yeah this is why I think this is fine. Spec is now also not a horrible name for a specification.

jhedstrom’s picture

+1 for RTBC here. Very glad we are keeping addIndex() :)

benjy’s picture

Status: Needs review » Reviewed & tested by the community

OK, +1 from me.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work

SchemaTest passes in both mysql and pgsql. But pgsql is broken cause...

  protected function _createKeys($table, $new_keys) {
    if (isset($new_keys['primary key'])) {
      $this->addPrimaryKey($table, $new_keys['primary key']);
    }
    if (isset($new_keys['unique keys'])) {
      foreach ($new_keys['unique keys'] as $name => $fields) {
        $this->addUniqueKey($table, $name, $fields);
      }
    }
    if (isset($new_keys['indexes'])) {
      foreach ($new_keys['indexes'] as $name => $fields) {
        $this->addIndex($table, $name, $fields);
      }
    }
  }

in core/lib/Drupal/Core/Database/Driver/pgsql/Schema.php the call to addIndex is broken.

+++ b/core/lib/Drupal/Core/Database/Schema.php
@@ -413,13 +413,55 @@ public function fieldExists($table, $column) {
+  /**
+   * Validates whether the index is valid.
+   *
+   * This method ensures that the table exists and that there is no index with
+   * the same name yet.
+   *
+   * @param string $table
+   *   The name of the table the index will be added to.
+   * @param string $name
+   *   The name of the index.
+   *
+   * @throws \Drupal\Core\Database\SchemaObjectDoesNotExistException
+   *   If the specified table doesn't exist.
+   * @throws \Drupal\Core\Database\SchemaObjectExistsException
+   *   If the specified table already has an index by that name.
+   */
+  protected function validateIndex($table, $name) {
+    if (!$this->tableExists($table)) {
+      throw new SchemaObjectDoesNotExistException("Cannot add index '$name' to table '$table': table doesn't exist.");
+    }
+    if ($this->indexExists($table, $name)) {
+      throw new SchemaObjectExistsException("Cannot add index '$name' to table '$table': index already exists.");
+    }
+  }

Adding this unnecessary for the fix. I think we don't need to do this. Less change is nice.

dawehner’s picture

Status: Needs work » Needs review
Issue tags: +D8 Accelerate
FileSize
13.16 KB
4.5 KB

There we go.

dawehner’s picture

FileSize
13.38 KB
749 bytes

Let's add some comment.

The last submitted patch, 57: 2537928-57.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 58: 2537928-58.patch, failed testing.

dawehner’s picture

jibran’s picture

Status: Needs review » Reviewed & tested by the community

#56 is addressed so back to RTBC.

alexpott’s picture

Assigned: Unassigned » Crell
Issue tags: +Needs subsystem maintainer review

I've asked @Crell to have a look as sub system maintainer.

Crell’s picture

Status: Reviewed & tested by the community » Needs work

Thanks for the tag, Alex!

  1. +++ b/core/includes/database.inc
    @@ -654,9 +654,11 @@ function db_drop_unique_key($table, $name) {
    + * @param array $spec
    + *   A table specification.
    

    Specification of what table? $table's specfication? That's unclear.

  2. +++ b/core/lib/Drupal/Core/Database/Schema.php
    @@ -413,13 +413,29 @@ public function fieldExists($table, $column) {
    +   * @param array $spec
    +   *   A table specification, which is used in order to be able to ensure that
    +   *   the index length is not too long.
        *
        * @throws \Drupal\Core\Database\SchemaObjectDoesNotExistException
        *   If the specified table doesn't exist.
        * @throws \Drupal\Core\Database\SchemaObjectExistsException
        *   If the specified table already has an index by that name.
        */
    -  abstract public function addIndex($table, $name, $fields);
    +  abstract public function addIndex($table, $name, $fields, array $spec);
    

    I talked through this in IRC with dawehner and catch. I am very skeptical about the DX of requiring the full table definition to be passed in each time, as there's no common place to get that information. It requires out-of-band data, retrieved from... somewhere context sensitive. Could be hook_schema(), could be derived from somewhere like Entity API or cache API if it's a dynamic table... you have to "just know" where to get this big array from. That's the terrible DX we've been trying to move away from.

    Unfortunately, the only alternative we could come up with is to add schema introspection to the DB API, so that it could return a table spec of a table in the database already. Then the schema object could just look at the table itself and know what it needs to do. That, however, is a not currently a feature of the Database API and is a heck of a lot of work to add, in part "because MySQL". *sigh* That is out of scope at this time.

    So if we're going to move forward here, we should:

    1) Do a much better job of documenting where to get the value of $spec. Even if that's just "depending on the use case it could be from X, or Y, or Z". Give developers some sort of indication of how to use this method.

    2) Leave a @todo on the method that if we ever do manage to add schema introspection later then the $spec array can be removed entirely.

    3) catch pointed out in IRC that $spec technically doesn't need to be the full table, just the fields that are being used by the index. Any others are irrelevant. I am torn on if we should say that or not; it could make it easier to use if someone is adding a field and then an index on it, since they're almost guaranteed to have the spec for that field handy already, but it could also add complications as you're passing in a table definition that is not a full table definition but works anyway, and unstructured inputs lead to fun-to-find bugs. Open to thoughts on this point.

stefan.r’s picture

Status: Needs work » Needs review
FileSize
15.23 KB
3.83 KB
dawehner’s picture

  1. +++ b/core/includes/database.inc
    @@ -907,16 +905,22 @@
     function db_add_index($table, $name, $fields) {
    -  return Database::getConnection()->schema()->addIndex($table, $name, $fields);
    +  return Database::getConnection()->schema()->addIndex($table, $name, $fields, $spec);
     }
    

    Mh, that can't work ... you need to add $spect to db_add_index as well

  2. +++ b/core/lib/Drupal/Core/Database/Schema.php
    @@ -414,13 +414,48 @@
    +   *   SqlContentEntityStorageSchema::getDedicatedTableSchema() and ¶
    

    empty whitespace

+++ b/core/lib/Drupal/Core/Database/Schema.php
@@ -413,13 +413,64 @@ public function fieldExists($table, $column) {
+   *   To prevent human error, it is recommended to pass in the complete table
+   *   specification. However, in the edge case of the complete table specification
+   *   not being available, we can pass in a partial definition containing only
+   *   the fields that apply to the index:

+1

Crell’s picture

  1. +++ b/core/includes/database.inc
    @@ -654,11 +654,9 @@
    - * @param array $spec
    - *   A table specification.
      */
    -function db_add_index($table, $name, $fields, array $spec) {
    -  return Database::getConnection()->schema()->addIndex($table, $name, $fields, $spec);
    +function db_add_index($table, $name, $fields) {
    +  return Database::getConnection()->schema()->addIndex($table, $name, $fields);
    

    Why undo this change? db_add_index() is deprecated but it still needs to work.

  2. +++ b/core/lib/Drupal/Core/Database/Schema.php
    @@ -414,13 +414,48 @@
    +   *   handler listed in the entity class definition (see
    +   *   SqlContentEntityStorageSchema::getDedicatedTableSchema() and ¶
    +   *   SqlContentEntityStorageSchema::getSharedTableFieldSchema().
    

    Nit: Stray whitespace at the end of line 423.

The revised comment looks good to me otherwise.

Status: Needs review » Needs work

The last submitted patch, 65: 2537928-65.patch, failed testing.

stefan.r’s picture

Hmm that was an oversight, $spec was in the docblock and inside the function but not in the parameters.

stefan.r’s picture

stefan.r’s picture

The last submitted patch, 70: 2537928-70.patch, failed testing.

Crell’s picture

Status: Needs review » Reviewed & tested by the community

Thanks, stefan.r! Back up to RTBC for Alex.

dawehner’s picture

Assigned: Crell » Unassigned

Removing the assignment

alexpott’s picture

Status: Reviewed & tested by the community » Needs work

This introduces SQLite regressions. Drupal\system\Tests\Entity\FieldSqlStorageTest fails on SQLite with an exception after applying this patch.

alexpott’s picture

We can just make less change. Also I don't think we need to pollute the base Schema namespace with getNormalisedIndexes until we have a use case.

Gábor Hojtsy’s picture

Seems to be failing less on SQLite :) More on PostreSQL :(

alexpott’s picture

@Gábor Hojtsy the problem is the postgres and sqlite Drupalci runs are not stable (or passing) - so manual testing is required :(

Local test runs for me:

SQLite

Drupal\field\Tests\Number\NumberFieldTest fails on HEAD and PATCH
Drupal\image\Tests\ImageEffectsTest passes on HEAD and PATCH
Drupal\page_cache\Tests\PageCacheTest passes on HEAD and PATCH
Drupal\toolbar\Tests\ToolbarAdminMenuTest passes on HEAD and PATCH
Drupal\views_ui\Tests\NewViewConfigSchemaTest passes on HEAD and PATCH

No regression for SQLite

PostgreSQL

@todo

stefan.r’s picture

Just from a manual review the current fails seem unlikely to be caused by this patch.

As apparently drupalci for pgsql/sqlite is not stable, could anyone run the patch vs HEAD on pgsql/sqlite locally?

alexpott’s picture

Postgres

The suspicious tests are:

  • Drupal\node\Tests\Views\RevisionRelationshipsTest
  • Drupal\views\Tests\Handler\FieldFieldTest

All the rest are DrupalCI set issues due to the clear down of a previous test or file system

Drupal\node\Tests\Views\RevisionRelationshipsTest fails on HEAD and PATCH
Drupal\views\Tests\Handler\FieldFieldTest fails on HEAD and PATCH

No regression for Postgres

bzrudi71’s picture

@alexpott, Yep, both tests fail since some days and are not related to this issue. (as seen on PG-Bot) I think it's just another missing order by problem. So no showstopper for this issue :)

stefan.r’s picture

interdiff in #76 looks good and no regressions, so +1 from me

alexpott’s picture

dawehner’s picture

Status: Needs review » Reviewed & tested by the community

So the patch is green again.

Doing less in order to fix an issue is often a great idea

Gábor Hojtsy’s picture

Issue summary: View changes

Updated the change notice draft significantly to make it easier to understand: https://www.drupal.org/node/2540310/revisions/view/8715856/8725758

Updating issue summary too.

neclimdul’s picture

+1, thanks guys!

jhedstrom’s picture

Just one more +1 here. Patch is working wonderfully on a beta 7 upgrade!

webflo’s picture

Status: Reviewed & tested by the community » Needs review
FileSize
14.41 KB

We have to pass along the fields schema information to addIndex because the MySQL Driver needs the information to perform normalization on long indexes.

webflo’s picture

FileSize
1018 bytes

And the interdiff ...

webflo’s picture

Sorry uploaded the wrong patch. Ignore #88.

The last submitted patch, 88: 2537928.88.patch, failed testing.

dawehner’s picture

Status: Needs review » Reviewed & tested by the community

Good catch!

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs tests

For #90

Gábor Hojtsy’s picture

BTW the fails in #90 on DrupalCI are to be expected:

Drupal\Core\Installer\Exception\InstallerException: PHP: 5.4.39

Your PHP installation is too old. Drupal requires at least PHP 5.5.9. in install_display_requirements() (line 2292 of /var/www/html/core/includes/install.core.inc). install_display_requirements(Array, Array)
dawehner’s picture

Trying to write some unit test for #90 atm.

alexpott’s picture

Status: Needs work » Needs review
FileSize
4.23 KB
17.78 KB

Here are some tests. Found another bug introduce my this patch in the entity auto updater.

alexpott’s picture

Drupal\system\Tests\Entity\EntityDefinitionUpdateTest still passes on both pgsql and sqlite.

alexpott’s picture

Let's throw an exception if we don;t have the field spec.

dawehner’s picture

Wrote a unit test in the meantime.

The last submitted patch, 98: 2537928.97.patch, failed testing.

The last submitted patch, 99: 2537928-test.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 99: 2537928-97.patch, failed testing.

dawehner’s picture

Status: Needs work » Needs review
FileSize
24.65 KB

My patch lacked of #96

Status: Needs review » Needs work

The last submitted patch, 103: 2537928-103.patch, failed testing.

alexpott’s picture

Throwing the exception found another bug.

Crell’s picture

+++ b/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php
@@ -323,6 +327,9 @@ protected function getNormalizedIndexes($spec) {
+          throw new SchemaException("MySQL needs the '$field_name' field specification in order to normalize the '$index_name' index");

We've usually been using sprintf() in these cases. I looked at the string and tried to figure out if we were going to interpolate that variable or not, and got very confused. :-)

I'm otherwise satisfied with this patch. Queuing for SQLite and Pgsql just to be on the safe side.

alexpott’s picture

I looked at the string and tried to figure out if we were going to interpolate that variable or not, and got very confused. :-)

We have no standards on how to concatenate variables in an exception message. sprintf() is totally unnecessary, PHP is very good constructing strings from variables and hard coded strings - let's use the language features. An added bonus is that it reads way better - you actually have to think less. Especially when the number of variables increases.

dawehner’s picture

Status: Needs review » Reviewed & tested by the community
+++ b/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php
@@ -323,6 +327,9 @@ protected function getNormalizedIndexes($spec) {
+        else {
+          throw new SchemaException("MySQL needs the '$field_name' field specification in order to normalize the '$index_name' index");
+        }

I'm curious here, why do we not use an assertion? On runtime vs. development time this will never be different. Either code passes it along or not. I still try to wrap my head around the right usecases of assertions though

catch’s picture

Status: Reviewed & tested by the community » Fixed

So I also think that could be an assertion but seems like good material for a follow-up.

Committed/pushed to 8.0.x, thanks!

  • catch committed d066c9f on 8.0.x
    Issue #2537928 by stefan.r, dawehner, alexpott, webflo, jhedstrom: MySQL...
stefan.r’s picture

Gábor Hojtsy’s picture

Published change record at https://www.drupal.org/node/2540310

Dave Reid’s picture

Oof, providing the full spec is likely going to be painful in contrib module update hooks, but I understand why.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.