addColum() fails when revision table is missing

Created on 17 April 2024, 8 months ago
Updated 22 April 2024, 8 months ago

Problem/Motivation

For entities? (I have tested with commerce store) where the table mapping (getDedicatedTableNames()) returns a revision table but the table does not exist in the database, the addColumn() function fails on module update (column is added but the schema is not updated since exception is thrown when revision table is missing). When disabling the throwing of exception the field is installed correctly. see CustomFieldUpdateManager line 192-216.

Steps to reproduce

Install commerce and custom_field.
Create custom field for store.
Create custom module.
Enable module.
Add module update with addColumn function according to documentation β†’
Run update.php

Proposed resolution

I found a core issue that could possibly be part of the cause. see Issue 3113639 β†’

Remaining tasks

User interface changes

API changes

Data model changes

πŸ› Bug report
Status

Fixed

Version

3.0

Component

Code

Created by

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @bandana
  • This unfortunately also seems to wipe the entire field table since the existing data is never restored when the exception is thrown.

  • πŸ‡ΊπŸ‡ΈUnited States apmsooner

    Thanks for the report. Were you able to capture any specific errors? I can try to reproduce this and see if i can come up with a solution but this is a really odd issue that the table exists but it sorta doesn't really....

  • πŸ‡ΊπŸ‡ΈUnited States apmsooner

    I dont quite understand why a revision table name exists when the the entity is not revisionable, but this addition allowed me to get the update to go through. I had to manually delete the column though in the db from the original fail as it still got saved. Just the revision table stuff is all kinds of odd so we can skip over it like this:

        $is_revisionable = $storage instanceof RevisionableInterface;
        foreach ($table_names as $table_name) {
          $field_exists = $schema->fieldExists($table_name, $column_name);
          $table_exists = $schema->tableExists($table_name);
    
          if ($table_name === $entity_type_id . '_revision__' . $field_name && !$is_revisionable) {
            continue;
          }
    

    I'll have to test this more for a proper patch as there are also similar issues on the removeColumn().

  • πŸ‡ΊπŸ‡ΈUnited States apmsooner

    This patch should resolve the issue. Please report back. FYI, The test is failing because a new flag that got introduced I believe is expected to be set when updating storage schema but its not yet clear to me how to set that in the service. Anyhow, its working consistently now on the commerce_store entity when i tested for both add/remove columns.

  • Status changed to Needs review 8 months ago
  • πŸ‡ΊπŸ‡ΈUnited States apmsooner
  • Thanks for the quick feedback! The patch works for custom field set to commerce_store (both addColumn and removeColumn, both with and without field data) but if I try to run the addColumn function for a node entity with data set for the field it now skips altering the revision table and therefore throws the sql exception that field storage for fields with data cannot be changed.
    Checking the RevisionableInterface for entity storage (line 198 with patch) seems to not work for NodeStorage. I am not sure about the storage for other entities.

  • Checking if an entity is revisionable by
    $is_revisionable = $storage->getEntityType()->isRevisionable();
    seems to work both for commerce_store and node entity at least.

    Regarding the setting the flag according to the issue you linked, I guess that would make it a bit less resource intensive when wiping the tables that have data in them if there are a lot of rows. Instead of extracting all data into an array and then re-adding it to the table after alteration it should be possible to just add/remove the column in the db and the entity storage without handling any data.

  • πŸ‡ΊπŸ‡ΈUnited States apmsooner

    Thanks for update. There seems to be some major inconsistencies with this revision table depending on entity type issue that I'm not yet sure how to completely account for. Back to the drawing board i guess for now until i can figure something out.

  • πŸ‡ΊπŸ‡ΈUnited States apmsooner

    This updated patch is working for me on both entity types for add/remove columns. I may revise some more to simplify it but its at least processing through and returning the correct results while preserving the existing data.

  • πŸ‡ΊπŸ‡ΈUnited States apmsooner

    The unit test passes now also so I know the node entity is working. I don't have a test built in for the commerce_store entity situation but it is definitely working for me locally.

  • This is great! I have now tried it with the node, commerce_store, commerce_product, commerce_order and taxonomy_term entities and it works with all of them.

  • Pipeline finished with Skipped
    8 months ago
    #151640
  • Status changed to Fixed 8 months ago
  • πŸ‡ΊπŸ‡ΈUnited States apmsooner

    Thanks for all the help with testing the patches. I will get a new release out soon!

  • Status changed to Fixed 8 months ago
  • πŸ‡ΊπŸ‡ΈUnited States apmsooner
Production build 0.71.5 2024