Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
If a node type has a field and the node type is deleted, the field is not deleted. Attempts to add a field with the same machine name to another node type fails with:
Add new field: the field name field_test8 already exists.
Comment | File | Size | Author |
---|---|---|---|
#33 | field_delete_instance-915906-33.patch | 6.49 KB | yched |
#30 | field_delete_instance-915906-30.patch | 6.5 KB | yched |
#29 | field_delete_instance-915906-29.patch | 6.5 KB | yched |
#28 | field_delete_instance-915906-28.patch | 7.35 KB | yched |
#23 | field_delete_instance-915906-23.patch | 6.4 KB | yched |
Comments
Comment #1
moshe weitzman CreditAttribution: moshe weitzman commentedThis may be by design but for now i will just demote priority. see http://drupal.org/node/45111
Comment #2
jbrown CreditAttribution: jbrown commentedNo - it's definitely not by design. If a node type with fields is deleted, then the database is left in an inconsistent state that cannot be resolved by the user interface.
Fields affected by this problem enter a strange zombie state where they do not appear under 'Add existing field', but cannot be added under 'Add new field'.
This is at least a major - not being able add a field to a content type is a 'significant repercussion'.
My patch patch means that deleting a content type is now the same as deleting the fields manually then deleting the content type.
Comment #3
arlinsandbulte CreditAttribution: arlinsandbulte commentedCouple questions:
What happens when deleting a node that uses a field shared with other content types?
How does D6 handle this now?
Comment #4
jbrown CreditAttribution: jbrown commentedThe problem only occurs when deleting the last node type that has the field.
D6 doesn't have any of this stuff.
Comment #5
jbrown CreditAttribution: jbrown commentedComment #6
moshe weitzman CreditAttribution: moshe weitzman commentedDeleting a content type can leave thousands of nodes in "a strange zombie state". It has been so since always. IMO this still is not Major.
Comment #7
jbrown CreditAttribution: jbrown commented#6 That analogy doesn't make any sense. Core doesn't attempt to solve that problem.
This issue is about something that core is supposed to do, but does not always.
It is caused because node_type_delete() => field_attach_delete_bundle() does not delete the field as it should if it deletes the last instance. field_ui_field_delete_form_submit() does it correctly.
My patch improves field_delete_instance() so it always deletes the field if it deletes that last instance.
Comment #8
jbrown CreditAttribution: jbrown commentedI wrote a test.
Comment #9
jbrown CreditAttribution: jbrown commentedWhitespace fixes.
Comment #10
sun.core CreditAttribution: sun.core commentedNo need for those separate private functions. Let's incorporate that code into the primary API functions, please.
Powered by Dreditor.
Comment #11
yched CreditAttribution: yched commentedAgreed with sun. That was the approach identified in #838022: Deleting a content type leaves orphaned fields (older, but there's a patch here, so marking the other one as duplicate).
Comment #12
jbrown CreditAttribution: jbrown commentedI'm not sure I agree.
Both field_delete_field() and field_delete_instance() need to be able to delete instances and fields.
I created the helper functions _field_delete_field() and _field_delete_instance() so there would not be code duplicatation.
These helper functions should be private because when called in isolation they leave the database in an inconsistent state (what this patch is designed to prevent).
Comment #13
jbrown CreditAttribution: jbrown commented#9: fields-are-not-deleted.patch queued for re-testing.
Comment #14
yched CreditAttribution: yched commented_field_delete_field() / field_delete_field() is utterly confusing.
I don't see why the attached patch wouldn't do the job ?
Comment #16
marcvangendSubscribe, also running into this problem.
Comment #17
yched CreditAttribution: yched commentedwe need clear the field_info cache before fetching the $field from field_info_field().
Comment #18
moshe weitzman CreditAttribution: moshe weitzman commentedlooks perfectly sane.
Comment #20
yched CreditAttribution: yched commentedI'll get back at this after RC1
Comment #21
jbrown CreditAttribution: jbrown commentedI don't think we should have an API that can leave the database in an inconsistent state.
Comment #22
yched CreditAttribution: yched commentedpatch failures in #17 were caused by field_delete_field() first calling field_delete_instance() on each instance, which in turn calls field_delete_field() when deleting the last instance.
jbrown's #21 solves that by splitting field_delete_field() and field_delete_instance() in two functions each, introducing field_delete_field_record() and field_delete_instance_record() functions. Fixes the tests, but obfuscates the code flow, and we really don't want to clutter the API namespace with functions that, in addition, do not correspond to any action we want to promote to the API.
I'll post an updated patch asap.
Comment #23
yched CreditAttribution: yched commentedSo, issue summary :
- Contrary to CCK, Field API cleanly separates $field and $instance - and that is great. The CRUD APIs for fields and instances are separated and (to a large extent) independent. API wise, you can have a field without instances (yet, or anymore). field_delete_instance() currently doesn't clean orphaned fields, and that was a conscious design choice.
- To keep UX reasonable, Field UI, though, doesn't present the two separate notions. You manipulate (create, reuse, delete) *instances*, and fields are silently created and deleted accordingly. This is all for the best IMO, and won't change now anyway.
Consequence : as far as Field UI is concerned, a field without instances doesn't exist - it's not visible anywhere in the UI, you can't do anything with it (delete it completely, or create a new instance). It only bites you when you want to create a new field with the same name : 'a field with the same name already exists'. --> so-called 'zombie' field.
It's only a problem if the field was created by Field UI originally and thus lies in the 'field_' namespace. Other fields just don't bug you, you can't clash with them.
- Field UI makes sure none of its UI action leads to a lone field without instances : when deleting the last instance, it deletes the field as well.
Problem : there's another way to delete instances in the UI : deleting a node type - or a more generally a bundle. Field UI doesn't control that, this just triggers an API call to field_attach_delete_bundle(), which does a series of field_delete_instance(). If a field wasn't used anywhere else, it stays around with no instance.
Solution : field_delete_instance() needs to be able to garbage collect the corresponding field if it gets orphaned. We need this behavior to be optional, because :
- field_delete_field() already calls field_delete_instance(), and we need to avoid infinite loops
- it makes sense to keep the ability to programmatically delete and create instances without caring about order (i.e having to take care of not deleting the last instance before trying to add new ones). I'm notably thinking of Features having to perform complex create / delete instances when doing a revert.
Attached patch just does :
Comment #24
yched CreditAttribution: yched commentedComment #25
yched CreditAttribution: yched commentedAs a side effect, the changes in field_purge_batch() fix #566048: Attempt to purge a field that still has instances.
Comment #26
moshe weitzman CreditAttribution: moshe weitzman commentedLooks straightforward. Well done.
Comment #27
webchickSorry, but I am completely turned around by all the negatives in that sentence. Can we explain what *true* does instead?
Also, are the tests here sufficient, or should they be expanded? #23 describes two separate code paths: one for programmatic fields and one for fields created and managed through field UI. I would've expected more hunks to be added in this patch (I'm only reading the diff, though...)
Comment #28
yched CreditAttribution: yched commentedReworded the PHPdoc :
About tests :
Field deletion through Field UI is already tested in FieldUIManageFieldsTestCase::testDeleteField(), and that test stays the same (thus doesn't appear in the diff).
The 'garbage collect orphan fields' behavior in field_delete_field() is tested in FieldInstanceCrudTestCase::testDeleteFieldInstance(), and as a side effect in FieldBulkDeleteTestCase::testPurgeField().
Comment #29
yched CreditAttribution: yched commentedOops, error while rolling the patch.
Comment #30
yched CreditAttribution: yched commentedFix double full stop at the end of a comment.
Comment #31
Damien Tournoud CreditAttribution: Damien Tournoud commentedThe approach looks really sane. RTBC from me if the test bot comes back green.
Comment #32
StuartJNCC CreditAttribution: StuartJNCC commentedI still found the "FALSE" part of the comment hard to read. I stumbled over "without non-deleted instances".
Nit-picks: Double space after "TRUE,", no space before "Defaults", "responsability" should be "responsibility".
How about:
Comment #33
yched CreditAttribution: yched commentedComment #34
yched CreditAttribution: yched commented#33: field_delete_instance-915906-33.patch queued for re-testing.
Comment #35
yched CreditAttribution: yched commentedStill green. Assuming wording has been fixed, bumping back to webchick.
Comment #36
hgurol CreditAttribution: hgurol commented#33: field_delete_instance-915906-33.patch queued for re-testing.
Comment #37
webchickOk, so before:
Create a content type called 'boom' with a field called 'bang'. Delete content type 'boom' which, presumably, takes field 'bang' with it. Create another content type called 'pow' with field called 'bang'. Get an error that the 'bang' field already exists.
Now:
Create a content type called 'yowza' with a field called 'shazam'. Delete content type 'yowza' which, presumably, takes field 'shazam' with it. Create another content type called 'magic' with a field called 'shazam'. Field UI lets you go on your merry way.
Very nice. That property description makes a lot more sense now, too.
Committed to HEAD. Thanks!
Comment #39
knalstaaf CreditAttribution: knalstaaf commentedStill getting this error with the patch applied:
Btw: when applying the patch I got this message:
I left it there and re-uploaded the field-folder to (root)/modules, with no result.
Comment #40
marcvangendYour error message seems unrelated to the patch. Also, the patch has already been committed, so if you're using a recent version (later than December 15, 2010) you do not need to apply the patch.
Comment #41
wickwood CreditAttribution: wickwood commentedI'm using Drupal 7.17 and still have the original problem as state in this issue. Is the issue only corrected in 7.x-dev version of Drupal? I would have thought that since the patch was committed by WebChick in #37 in December of 2010 that this would be in the stable release by now.
I don't know how to check to see if it is in the stable Drupal 7.17 release so that I might discover if this is an issue being caused by a some contrib module I'm using.
Any advice on how I might track this down would be greatly appreciated!
Thanks for your help in Advance!
Steve
P.S. I assume if this is still a problem in the stable releases of Drupal than the issue should also be reopened, but I'll leave that to someone else to decide.
Comment #42
wickwood CreditAttribution: wickwood commentedI think I figured out what was going wrong for me as posted in #41. I was trying to remove a Term Reference but the Taxonomy still existed. Once I deleted the Taxonomy, the field also was removed.
This particular Taxonomy, if I remember correctly, was created by the WP Blog Module which I had disabled and uninstalled.
So most likely my issue was related to poor clean up by the contributed module.
Steve