When field definitions are altered sometimes field data must be dropped. For example, if a field was created with multiple values and that field has been used to actually create multiple values in nodes, and the field definition is then changed to no longer hold multiple values, all but the zero value in the nodes will be dropped. There is no way around that, those extra values can't be stored in the new field definition. CCK makes that change by altering the tables to remove table columns or copy the zero values from a separate field table into the content table, depending on the exact change that is made. Either way, the extra values will disappear.

We've talked before about the fact that we ought to be warning people when they make such a change that it will impact their data, and we now have a warning message on the field settings screen.

We've also talked about the fact that we should be doing node_save() on all the affected node instead of dropping the data via SQL. We couldn't do that in the past with no way to do batch updates, because of timeout problems. We hoped to fix that in D6 by using batching when fields are altered to individually do a node_save on each before we alter the table structure.

However, we're run into problems doing this. The biggest, and so far insurmountable, problem is that we are introducing an API in this version so you can alter field definitions pro grammatically, and combining batch processing and programmatic field changes just won't work.

Yched and I discussed this at length on IRC and finally decided we just have to remove the batch processing for now, which will take us back to the way that things worked in D5, the database will be altered as needed without doing a node_save() on each node.

This will not be a problem in most cases, only in those cases where the change in the field definition would result in the loss of data. In all other cases, the node's data is unchanged, so there is no need for a node_save().

I'm in the process of altering the code to remove the batching from content_schema_alter. I'm going to keep the batch process in there so we can continue to try to find a way to get it working, just unhook it from content_schema_alter() so it isn't running automatically.

I also factored out a part of that process into a new function that could be useful for making programmatic changes to nodes. It's called content_field_replace() and it allows you to pass in an array of field names and values that you want those fields updated to. You pass in only the field values you want changed, all others will be preserved. That function will update the node with your values, do whatever cleanup is needed, and then do a node_save() on the node.

I'll be committing this shortly.

Comments

karens’s picture

Status: Active » Fixed

OK, this has been committed. Content_alter_schema() no longer tries to update the nodes or do any batch operations, it just (for now) executes content_db_alter().

I moved the batching processing to content_alter_fields(), which does what content_alter_schema used to do, but it's not tied into the API so it won't run unless specifically called. That way we still have a batching operation that we can use within the UI, once we make whatever changes are needed to get it working right and figure out how to incorporate it.

Anonymous’s picture

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for two weeks with no activity.