Problem/Motivation
When field creation via GUI is failed, you may have in your DB unused table(s).
Steps to reproduce
The simplest way to imitate/reproduce the case is:
- in your DB create a dummy table with name field_revision_field_sample;
- open admin/structure/types/manage/page/fields , try to add field field_sample with text type;
As a result you will have newly created table field_data_field_sample in your database which not belongs to any field.
Proposed resolution
Similar to action of updating field, we enclose tables creation in transaction, either manual or provided by DB. See field_sql_storage_field_storage_update_field().
Remaining tasks
Update the patch, taking into account the review in #8
Review
User interface changes
API changes
Data model changes
Release notes snippet
Comments
Comment #1
rbogdan commentedPatch work correctly and fix problem with DB unused tables. Need tests.
Comment #2
dpovshed commented@rbogdan, thank you for your review.
The test is attached. Test class placed in currently existed relevant file.
Comment #3
ygerasimov commentedFormatting indent issue.
I can't see reason to have separate method fieldUIAddNewIfledFail().
Here are attached rerolled patch with changes.
14 days to next Drupal core point release.
Comment #4
franzthere WERE no exceptions
Does this issue affects D7 as well?
Comment #5
ygerasimov commented@franz thank you for review. Yes, this issue affects D7 as well. Here is rerolled patch.
Comment #6
franzSo I'll add the tag. Let's wait for test results now.
Comment #7
dpovshed commentedThank you Yuriy for your review and modifications!
I believe with the latest version of the patch in comment #5 we can set the status to "Reviewed an tested"
Comment #8
catchWe introduced transactions for a reason, we should not try to manually rollback operations for databases that don't support it. Wrapping this in a transaction seems fine, but not the emulation.
Comment #9
dpovshed commented@catch, in the function field_sql_storage_field_storage_update_field() community code already using the same approach - we check for DDL transaction support, and do the work manually if DB can't help us.
My version of ..._create_... function based on this mechanism in ...update... function.
What is your suggestion here - do you think that we shall remove manual rollback from both code fragment?
Comment #10
mgiffordThis still a concern in D8? Unassigned issue too.
Comment #11
pieterdcI guess it's still a concern in Drupal 8. I'm sure it's still a concern in Drupal 7.
We're facing a SchemaObjectExistsException 'Table @name already exists.'
Looking at the latest patch, and having that use case in mind, it doesn't make sense to (re)throw the exception - which says the table already exists - because the code just deleted that table. So, I suggest, if it's specifically that exception type, then don't throw $e. What do you think?
I also checked #1551132: When trying to create a table that already exists but is empty, recreate the table rather than throwing a DatabaseSchemaObjectExistsException but I like the approach from this issue more.
Comment #14
pieterdcForget my complaint against (re)throwing the exception. Looking at the patch once more made it clear to me that the code rolls back / drops the tables that got successfully created before the table that failed creating. Throwing an exception for that failure makes sense of course.
Comment #26
larowlanWe need to test if this is still an issue on Drupal 9
Comment #28
quietone commentedI tested this on Drupal 10.1.x, standard install using the steps in the Issue Summary. I was able to reproduce the problem. The error I get when trying to add a field 'sample' to a page is
The website encountered an unexpected error. Please try again later.
The patch needs to be updated, with #8 in mind.
Comment #30
quietone commentedComment #31
mgiffordHow would one create this without modifying the database? How does this crop up, without doing something that 99% of site builders don't do?