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

rbogdan’s picture

Patch work correctly and fix problem with DB unused tables. Need tests.

dpovshed’s picture

@rbogdan, thank you for your review.

The test is attached. Test class placed in currently existed relevant file.

ygerasimov’s picture

+++ b/core/modules/field/modules/field_sql_storage/field_sql_storage.moduleundefined
@@ -212,8 +212,31 @@ function _field_sql_storage_schema($field) {
-    db_create_table($name, $table);
+    try {
+        db_create_table($name, $table);
+        $created_tables[] = $name;
+      }
+      catch (Exception $e) {
+        // We have to remove already created tables.
+        if (Database::getConnection()->supportsTransactionalDDL()) {
+          $transaction->rollback();
+        }
+        else {
+          foreach ($created_tables as $name) {
+            db_drop_table($name);
+          }
+        }
+        throw $e;
+      }

Formatting indent issue.

+++ b/core/modules/field_ui/field_ui.testundefined
@@ -727,3 +727,80 @@ class FieldUIAlterTestCase extends DrupalWebTestCase {
+  function testCreateFieldFailureCleanup() {
+    // Create a test field.
+    $this->fieldUIAddNewFieldFail('admin/structure/types/manage/' . $this->hyphen_type);

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.

franz’s picture

Status: Needs review » Needs work
+++ b/core/modules/field_ui/field_ui.admin.inc
@@ -863,7 +863,8 @@ function field_ui_field_overview_form_submit($form, &$form_state) {
+    // It is true only if there was no exceptions.

there WERE no exceptions

Does this issue affects D7 as well?

ygerasimov’s picture

Status: Needs work » Needs review
StatusFileSize
new5.07 KB

@franz thank you for review. Yes, this issue affects D7 as well. Here is rerolled patch.

franz’s picture

Issue tags: +Needs backport to D7

So I'll add the tag. Let's wait for test results now.

dpovshed’s picture

Status: Needs review » Reviewed & tested by the community

Thank 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"

catch’s picture

Status: Reviewed & tested by the community » Needs work

We 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.

dpovshed’s picture

we should not try to manually rollback operations for databases that don't support it

@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?

mgifford’s picture

Version: 8.0.x-dev » 8.1.x-dev
Assigned: dpovshed » Unassigned
Issue summary: View changes

This still a concern in D8? Unassigned issue too.

pieterdc’s picture

I 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.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.0-beta1 was released on March 2, 2016, which means new developments and disruptive changes should now be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.0-beta1 was released on August 3, 2016, which means new developments and disruptive changes should now be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

pieterdc’s picture

Forget 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.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.0-alpha1 will be released the week of January 30, 2017, which means new developments and disruptive changes should now be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

larowlan’s picture

Status: Needs work » Postponed (maintainer needs more info)
Issue tags: +Needs manual testing, +Bug Smash Initiative

We need to test if this is still an issue on Drupal 9

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

quietone’s picture

Issue summary: View changes
Status: Postponed (maintainer needs more info) » Needs work

I 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.

Drupal\Core\Database\DatabaseExceptionWrapper: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'field_sample_value' in 'where clause': SELECT 1 AS "expression" FROM "node_revision__field_sample" "t" WHERE "field_sample_value" IS NOT NULL LIMIT 1 OFFSET 0; Array ( ) in Drupal\Core\Entity\Sql\SqlContentEntityStorage->countFieldData() (line 1787 of core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php).

The patch needs to be updated, with #8 in mind.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

quietone’s picture

mgifford’s picture

How would one create this without modifying the database? How does this crop up, without doing something that 99% of site builders don't do?

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.