Closed (fixed)
Project:
Drupal core
Version:
8.1.x-dev
Component:
field_ui.module
Priority:
Critical
Category:
Bug report
Assigned:
Unassigned
Issue tags:
Reporter:
Created:
1 Sep 2011 at 14:49 UTC
Updated:
18 Jul 2017 at 00:17 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #1
Bojhan commentedThis is not major, the lack of a message. There are many other cases in Drupal where we dont provide a warning, although it changes existing data.
Comment #2
bryancasler commentedIf the person changes it back to three do the values re-appear?
Comment #3
droplet commented@animelion
only change value = data still there
changing + edit node = loss data
Comment #4
bryancasler commentedI'm wondering what will happen in my case. I have a image field, set to unlimited entries.
People upload photos to this field and then using the insert module they add them to their body.
Now if I reduce the allowed values to 1 and they edit->save their post the other image field entries will be lost. Does this also mean the original images uploaded in those entries will be removed? Or will it be just the entries themselves? Because if the images are removed then this will also "break" the body content they have created.
Sorry if this is too tangential, I'd be happy to open a new issue if you think it is.
Comment #5
droplet commented@animelion,
Images still show on body in your case because that's directly link to images. (Insert module)
(but.. may cause some unexpected side effect. I'm not sure what is it now)
update more info about this issue:
after re-save the node
- files left on files system
- DB's file_managed / file_usage table still have records
Comment #6
swentel commentedThis is really major.
The easiest way is to remove the save button when we know there's data. Question is if our API's also should enforce this or not.
Comment #8
jhedstromWe already display a big warning (even though it doesn't prevent actually changing the number of stored values).
Is that not sufficient here? Seems at least this could be 'normal'.
Comment #9
jonathanshawA possible simple solution that would allow downgrading this issue to normal:
change the warning message to say "There is data for this field in the database. Changing field settings may cause loss of data."
Comment #10
swentel commentedI think this still deserves to be major though, data loss is bad. Will have a look at it during the sprint.
Comment #11
swentel commentedTest fail patch
Comment #12
swentel commentedComment #13
swentel commentedComment #16
swentel commentedComment #17
swentel commentedAnd the fix.
Comment #18
swentel commentedThe function getHighestDelta() was lying, so changed that, Interdiff is against #17
Comment #19
swentel commentedFix the placeholdr
Comment #21
amateescu commentedHere's a small review :)
Gets.. :)
Missing empty line.
What's up with the extra 'TRUE' param?
We could inline this to:
How about tweaking the error message a bit to something like:
"This field already contains data so a cardinality lower than @delta can not be set."
I mean.. it would be nice to tell the user why they can't change this to a lower value.
Comment #22
swentel commented1. fixed
2. fixed
3. doh - copy paste, fixed
4. done
5. good suggestion
- edit - cleaned up the tests too.
Comment #25
swentel commentedComment #26
yched commentedWondering whether Mongo storage will be able to support getHighestDelta() :-)
Comment #27
yched commentedAnd also, even with the SQL storage, if the query will scale large datasets ?
Comment #28
swentel commentedWell, I think mongo has the same problem with countFieldData() :)
Hmm, good point. From Mysql.
MySQL uses indexes for these operations:
To find the MIN() or MAX() value for a specific indexed column key_col. This is optimized by a preprocessor that checks whether you are using WHERE key_part_N = constant on all key parts that occur before key_col in the index. In this case, MySQL does a single key lookup for each MIN() or MAX() expression and replaces it with a constant.
There's no direct index on delta, but it's using the revision_id since that is part of the primary key, so I guess we're probably fine?
Also, changing the cardinality when you already have a lot of data won't be a day to day operation I presume.
Comment #29
yched commentedNot sure about the SQL reasoning in #28 - according to the SQL explanation (which is what could be expected), an index can be used for queries like
SELECT MIN(index_part2), MAX(index_part2) FROM tbl WHERE index_part1=10;(i.e all index parts before the column used for MAX are fixed by constants)
Thus, for a query like
SELECT max(delta) FROM node__bodywithout fixing any other column (we're looking at all revisions on all entities), the only possible index would have to be an index directly on delta ? Without this, I can't see how the query could avoid scanning all rows ?
(side note : shared tables can only hold one delta by definition, so I don't think a query is needed in that case ?)
Comment #30
yched commentedMore genrally - yeah, tough issue...
Other thoughts :
- forbidding the delta lowering altogether could be very frustrating. Some entity somewhere (guess which one...) has more deltas, so you're screwed ? (and if that's in an old revision you cannot even edit, same thing ?). Maybe it's not really worse than than the stuff we currently forbid if hasData(), not sure...
- with CMI deployment in D8, such checks on the current content of the db are awkward anyway, since, if that check is performed on form validation only and not on actual config change, that still leaves the case where you make the change on your dev site with a possibly smaller database, and then deploy it on prod (which is going to be pretty common IMO). That argument also applies to the stuff we currently allow based on hasData() (changing some storage settings), but our case here is even more fragile (more chances that the change would be allowed on the dev db but forbidden on the prod db). In other words, there's always a gap we can't really fill :-/
- one confusing thing with our current keeping the old overflowing deltas untouched in the db until next time the entity is saved, is that the values still match with Views queries or EntityQueries (and when you actually load the entity its content doesn't match anymore)
Alternatively, what if :
- We allow the config change, and mark all corresponding deltas as deleted = 1 for proper "deletion" in the purge process (that still requires a "WHERE delta > N" query that would require a dedicated index...). That would mean changing the algorithm for purge (currently only looks at fields or storages that have been deleted completely).
- Maybe warn the user / add a confirmation step if he sets the delta to a lower value than the current max. Not sure about that, since that's still prone to the "apply on dev db / deploy on prod" drawback. So maybe always warn if he lowered the delta (existing data or not) ? Or just some alarming #description on the delta dropdown in the form ?
Also: this definitely is an issue (a complex one), but I'm not sure we have to rush a fix pre-RC ? :-) This data drop has been there since the beginnings of CCK, and I don't think I have seen lots of complains ? Not saying this wouldn't need fixing, of course...
Comment #31
swentel commentedNo rush indeed, and very good points, will let them sink a bit :)
Comment #32
jcnventuraThis patch slightly improves #22 by adding form validation before submit, and a #description informing the user beforehand that he can't set it to less than highest delta.
But indeed the problem remains that there's no easy solutions to this. I think that the config apply is probably not solvable at all, and it's probably a larger problem where this is just a sub-set. If you truncate the field data table, you're allowed to edit all field settings (even the ones disabled by hasData())and then exported to live and ruin all data. My proposal would be to move that scenario (TRUNCATE table + field config edit + config export + config import) to a separate issue.
On this issue, we should deal on preventing data loss via the UI, and for this I see some solutions:
Personally, I would vote for 2, due to simplicity, and the ability to add a few more values to a field, if deemed necessary.
Comment #34
jcnventuraToo much time with D7 lately. This should fix the validation test error, as this is now validated using the HTML minimum. Also changed to short array syntax.
Comment #36
jcnventuraDefinitively need to run these tests locally before updating the patch.
Comment #37
berdirshared storage fields do not have delta. That means you can just return 0 here?
At the same time, it is not possible to change cardinality for such a field, so calling it for that doesn't really make sense in the first place.
This would need to be added to the interface for FieldStorageConfig too.. or we just leave it out and the single place that needs it calls it directly?
Comment #38
duaelfrWe ran into this issue during an internal sprint @Happyculture.
What we think is, like @yched said, that the functionnality of being able to reduce the cardinality is more interesting than the risk of data loss. If the field data were dropped at the moment the field storage settings were changed, it wouldn't be the same, but currently that only occurs when an existing entity having values than the cardinality is saved.
What we might do is the ask for confirmation only when some fields have more values than the new cardinality.
Our 2 cts :)
Comment #39
imiksuCleaning up drupalcampfi tags.
Comment #41
xjmComment #42
xjmThe committers discussed this with the entity and field API maintainers, and we agreed to upgrade this issue to critical because it causes data loss (even though it is rare).
Comment #43
mradcliffeThe proposed resolution would continue to limit the flexibility for site builders. As a site builder I prefer to have as much flexibility as possible so that I am not locked in once I click Save on a field.
The good thing is that at least the patch in #34 would allow a contrib module to reverse this behavior and provide a warning instead.
Comment #44
amateescu commentedYou are not locked in when you create a field, only when you add some content in that field.
Comment #45
mradcliffeYou're right. But I still prefer it when Drupal does not lock a site builder out after content is created, and at least the behavior can be reverted in contrib at the very least.
Comment #46
catch@mradcliffe it would only prevent you from reducing the cardinality to the point where you'd lose data. We could potentially show the offending entities too.
Comment #47
catchNow that #2384459: Add entity query condition for delta in EFQ is in 8.2.x this is unblocked.
I think we should go ahead and fix this issue using the entity query delta support here in 8.2.x
We can then evaluate both issues for 8.1.x - I moved the other one down to 8.1.x and postponed it on this.
Comment #48
berdirThis is a new patch that uses the new entity query functionality.
It provides less value to the user, we can't set it upfront as the client side form validation. To make up for it, we can give the user an idea of how many entities there are.
Also extend the tests a bit to check for the format plural strings and make sure we can set it to the highest delta but not below.
No interdiff since it has almost nothing in common with the previous patch.
Comment #51
berdirWe must not run that query for new fields.
Comment #53
yched commentedI'm neither for nor against the patch, just wanted to remind a comment made earlier, that this approach could allow a cardinality change on a dev site with fewer content, and then let it be deployed on prod, where it might have been rejected if done directly on the prod backend UI because the prod site has more content.
If the data loss that currently happens when cardinality gets lowered is considered critical, the patch here is more a partial safeguard than a fix. There can still be data loss, depending on the site instance on which the config change is attempted.
Comment #54
berdir@yched: So you're neutral? How swiss of you ;) Yeah. I guess we could look into config sync validators if we think this is important enough. But I'd only consider that if those are capable of only doing the check if we can see that it changed, otherwise it would be a lot of queries all the time.
#2384459: Add entity query condition for delta in EFQ is not yet in 8.1.x, so obviously the tests can't work there.. added one more check to avoid the query for new entities, running the test with 8.2.x for now.
Comment #55
catchOpened #2726415: Add configuration sync validation. Like the approach here, but moving it out of form validation would be good for cases like the one yched mentions.
Comment #56
swentel commentedLooks good to me, only one nitpick, can be fixed on commit.
then = than
Comment #57
arlinsandbulte commentedONLY fixed swentel's nitpick.
No other changes to the diff file.
Comment #59
catchFixed this phpcs nit on commit to 8.2.x
Moving back to 8.1.x.
Unpostponed #2384459: Add entity query condition for delta in EFQ. But now this issue gets to be postponed on that!
Comment #60
bzrudi71 commentedManagedFieldsTest is broken on PostgreSQL since commit.
Please see PG testrunner
[18-May-2016 19:09:15 Australia/Sydney] Uncaught PHP Exception Drupal\Core\Database\DatabaseExceptionWrapper: "SQLSTATE[22P02]: Invalid text representation: 7 ERROR: invalid input syntax for integer: "number"Comment #61
berdirLooks like this can happen when cardinality is set to number, then the actual number is in a separate field.
Should be a pretty easy fix, we just need to check that above, put the actual cardinality in $cardinality and use that.
Also means we should extend the test with one case that uses that as that wouldn't work right now.
Moving back to 8.2.x for that, we're blocked on 8.1.x anyway.
Comment #63
catchReverted in 8.2.x
Comment #64
xjm@alexpott, @catch, @effulgentsia, @Cottser, @webchick, and I agreed this issue remains critical because of the data loss.
Comment #65
xjm(Removing outdated beta eval.)
Comment #66
berdirActually, we already test that and cardinality *is* the number.. except when no number is provided. So just making sure that we don't run the query then.
Comment #67
amateescu commentedLooks good to me.
Comment #69
catchCommitted 2486f10 and pushed to 8.2.x. Thanks!
Back to RTBC against 8.1.x again.
Comment #71
catchComment #73
berdirI think testbot got confused with the minor version, re-uploading a the patch for 8.1.x.
Comment #75
catchI can't reproduce the failures locally, so sent for re-test.
Comment #77
berdirWell, #2384459: Add entity query condition for delta in EFQ is not in yet :)
Comment #78
berdirNo longer blocked.
Comment #80
berdirNow the other patch was actually pushed, patches are green now.
Comment #81
alexpottThis is a reroll of a patch already in 8.2.x - looks great - thanks @Berdir
Comment #82
alexpottCommitted 3280164 and pushed to 8.1.x. Thanks!
Comment #84
cilefen commented#2760279: Reloading edit form can cause accidental data deletion
Comment #86
xjmPosted this followup: #2895124: Field storage settings give a scary red warning that they can't be changed when the cardinality is the only thing with restrictions