Over the last couple of months I have been doing a lot of work with CCK and found that each field is inserted/updated/deleted or select is done once for every single field.
see my report http://groups.drupal.org/node/10052 and see what I have done.
Here is the patch which fixes this, and is actually faster than the implementation for Drupal 6 for multiple fields (ie fields that have multiple values per node)
Here at Lonely Planet we have have put this patch through it's paces, are now looking to a wider look at it, and some comments.
This has been originally developed in 1.6-1 and I have ported the required core of these changes to 5.x-1.x-dev and did some tests.
It would be really good if these gets into 1.7
| Comment | File | Size | Author |
|---|---|---|---|
| #40 | cck-tablewrite.patch | 8.91 KB | gordon |
| #33 | cck-tablewrite.patch | 8.91 KB | gordon |
| #32 | _cck-tablewrite.patch | 8.8 KB | stijndm |
| #28 | cck-tablewrite.patch | 8.88 KB | gordon |
| #24 | cck-tablewrite.patch | 8.92 KB | gordon |
Comments
Comment #1
brst t commentedGreat idea. Very interested. Might have a conflict with another module I'm running? Or because it's 5.x.1.6-1 ?
Received this upon submitting a fairly generic cck node after applying this patch.
Relevant to this particular content type and instance, I'm using comment_upload and have a node_reference field and just before this patch, applied the cck_panels.patch (which is fantastic! and fantastically timed, too!)
Other cck related modules installed comment_cck and cck_field_perms used with other contetn types but not used with this slighter one. No errors prior to adding the new content.
Comment #2
gordon commentedI have taken a look and because you have more than 1 patch in your version of cck and it is against 1.6 it is very hard to test.
Can you please send an export of the content type that is giving the error and then I can create test it.
I actually built this with the panels patch in question so I know the 2 work together.
Gordon.
Comment #3
yched commentedGreat work, Gordon - here are a few remarks from a cursory look at the patch :
- The patch replaces content_field()'s 'load' / 'insert' / ... ops, so it seems it should also remove the current ones ?
Besides, I'd rather have this structured like current CCK D6, with _content_field_invoke_default() left untouched, only calling a new content_storage() function which does the storage-related ops.
D5 version content_field() would then be left with no actual ops in it, but this would keep the structure consistent with D6 (and D4.7), and make maintaining branches easier on us.
- CCK D6 pre-computes and caches some of the needed information (which fields in which tables...) in _content_type_info(). Not sure how this maps to your patch, but this might be worth investigating.
- CCK allows field modules to opt-out of default db storage, and manage it themselves in their own implementations of hook_field('load' / 'insert' / ...) - I think Eaton's Amazon field is one of those. The convention for this is fields that declare no columns ($db_info['columns'] is empty) opt out of CCK's storage. Could you ensure the patch doesn't break this ? (maybe it's OK as is, just want to make sure)
I'll be (mainly) AFK for the next 10 days or so. I intend to make a 5.x-1.7 shortly after my return (1.6 is about 8 months old, we've waited long enough).
It would be great to include this patch, but since it impacts the most critical part of CCK, it needs to be 200% tested and approved (and the absence of field CRUD API in the D5 branch means we don't have simpletests...). So releasing 1.7 without it is also OK by me - this patch on itself would legitimate a 1.8 release as soon as it's ready. We need to release more often anyway :-)
Comment #4
fp commentedsubscribing
Comment #5
brst t commentedNoting here as I did in my email to you, Gordon:
The error I received, while referencing changes from this patch, may also be due to conflict with other modules I forgot to mention before (og_user_roles, comment_cck, or even that one I'm not really using - og_content_type_admin). When I get the chance, I'll try it out again w/o these and see what happens.
Oh, and the error didn't prevent any operations, it was just reported upon submission of a new or edited form.
.. and did I mention my great appreciation for that cck_panels.patch? I think I did, but it's worth mentioning again.
Comment #6
lachlan commentedIf one attempts to insert a node that does not contain values for all fields, it will fail to insert the data—I noticed this when my nodes were being created, but my actual data wasn't inserted.
The code in the original patch adds columns to the query regardless of whether the node has values for said columns, but only adds data for those columns if the corresponding fields exist in the node. Hence, you'll end up with twelve columns and twelve format directives after VALUES, but only six values given as arguments to the query.
I have fixed this by only adding the column to the query if the node has that field; if I am wrong, however, in doing this, then of course feel free to correct me.
Comment #7
scb commentedsubscribing
Comment #8
Leeteq commentedSubscribing.
Comment #9
gordon commentedNow that 1.7 has been released I went back and started playing with my patch for cck.
I have restructured it so that it similar to how it is implemented in Drupal 6. I was thinking of backporting this from D6, but it would mean that I would have to do all the schema api as well.
I also fixed the issue so that it will handle NULL values, and should fix the problem raised by #6, but like cck normally it does expect all the records. So updates will rewrite missing in the db to NULL on an update.
Also I was going to remove all the duplicated code from content_field() but once I had removed all the code, there was no content_field() left. So I put it back, as some modules like imagefield call content_field() directly.
Also to help up get this in much easier, I am going to be back porting the crud file and the test cases, which will mean I will also need to add the content_alter_schema() as well.
This will make testing and future enhancement of cck for D5 much easier. Also we would be able to easily back port new tests to D5
Comment #10
gordon commentedI have done some more work on this today, and I have back ported all the tests and the crud file from Drupal 6. This will give us a method of testing this patch, and I hope that we could roll these following patches into 1.8 as well.
You will need the patches from the following 3 issues.
http://drupal.org/node/254507 => Backport of helpers for CCK tests => SimpleTest, Code, normal, patch (code needs review)
http://drupal.org/node/254508 => Backport of the crud file from D6 Version => Content Construction Kit (CCK), content.module, normal, patch (code needs review)
http://drupal.org/node/254509 => Backport of CCK tests from Drupal 6 version. => Content Construction Kit (CCK), content.module, normal, patch (code needs review)
This should help us test this patch much faster.
Also with the crud update, Lonely Planet uses this a lot to move changes to cck around between systems and it works really well.
Thanks
Gordon
Comment #11
socialnicheguru commentedsubscribing
Comment #12
sunsubscribing
@gordon: FYI: Project issue numbers (ex. #12345: How do I log in as admin?) turn into links automatically.
Comment #13
spencersundell commentedSubscribing.
Comment #14
bjaspan commentedsubscribe
Comment #15
karens commented@gordon, I'm trying to sort out which patches I need for this. The patch on this page seems to duplicate some of the ones you linked to. Do I still need this patch, or just the ones in #10?
Comment #16
karens commentedAlso, the patches are huge complicated beasts, hard to evaluate :( but I agree it would be great to have more consistency between CCK 5 and CCK 6 to make it easier to maintain :) and it would be really great to get tests into CCK 5 :), so a +1 from me on looking at this.
My thought right now, if I can sort out the answer to my previous question, is to go ahead and get this all applied in the dev release so others can help test it, and the simple tests should also help ensure we're not breaking things. One of the reasons for releasing a new official release of CCK last week was so we have a stable version with all the previous fixes before we start messing with this one.
Comment #17
gordon commented@KarenS To test this you should apply all the patches in 10, and then run the tests. This will run the tests against the old version of the loader/saver.
Then apply the patch from 9 and rerun the tests and they will be running against the new loader/saver
Comment #18
christefano commentedsubscribing
Comment #19
nicolash commentedsubscribe
Comment #20
stijndm commentedI applied patch 9 an got the following errors after submitting (or updating) content:
The first warning concerns a multiple link field with optional title.
The second and third concern an optional image field allowing multiple values.
The last two concern an audio field allowing multiple values.
These three fields are all optional (and allow multiple values) and were left empty on submitting. If I fill out any one with at least one value the error is gone.
Comment #21
gordon commentedFirstly Thanks soooo much for testing this.
I have taken a look at it and I was not handling the NOT NULL 100% correctly. I have fixed this and it should be working now.
Thanks. Please test again.
Comment #22
gordon commentedtry adding patch again.
Comment #23
gordon commentedComment #24
gordon commentedI found another problem with the handling of NULL fields.
Comment #25
stijndm commentedNo problem for testing this patch. We can all benfit from it.
I tried out both of your last patches and got a new error when submitting or editing content.
Fatal error: [] operator not supported for strings in /Users/stijn/Sites/_testserver/flagey/sites/all/modules/cck/content.module on line 662On line 662 is
$insert['placeholders'][$delta][] = '%d';Comment #26
stijndm commentedIf I roll back line 661
foreach ($insert['placeholders'] as $delta => $value) {to that of path #9
foreach ($insert['values'] as $delta => $value) {the code executes, but I get the same errors for my image and audio fields as in #20
Comment #27
gordon commentedCan you give me a link to the cck field module that you are using so that I can install it to test.
Thanks.
Comment #28
gordon commentedActually I think I found it.
Comment #29
gordon commentedComment #30
spjsche commentedsubscribe
Comment #32
stijndm commentedHi gordon. Thanks for the latest patch. That fixed the php error I was getting, but I was still getting Invalid argument errors (on submitting content) from my comment 20.
The modules I am using that cause these problems are imagefield.module and mediafield.module
http://drupal.org/project/mediafield
http://drupal.org/project/imagefield
It started to dawn on me that you put all data in an array and then you output the queries in a loop. But because these fields are empty no array is created. Wich was causing the invalid argument in
foreach ($insert['placeholders'] as $delta => $value)So I added an if statement to check if $insert['placeholders'] is an array before creating the queries. This seems to work fine.
Now nothing happens with these fields, as it should, when they are left empty. If one or more value(s) is added everything sits in aan array en the querie is added.
There might be a better way to do this? An earlier check? I hope this doesn't break support on other modules. I am going to try it out on different types of testing sites later today and see what happens.
Comment #33
gordon commentedI actually took a better look at it and with way it was handling completely missing fields it was not handling the individual columns correctly.
Give this patch ago.
Comment #34
stijndm commentedI tried out your last patch and this does solve the problem of the invalid argument. But a new problem (minor) has shown up.
After updating an item and removing the added images and audio files the record in the database is replaced with an empty one, while the old record containing the information of the image/audiofile should be deleted.
If I use my patch the image records are deleted correctly but not the audio ones. So this might be more mediafiled.module related?
Comment #35
stijndm commentedSame when creating a new item and leaving these fields blank. Empty records are added to the database. This could clutter the database and make it larger than necessary.
Comment #36
gordon commentedYes I know that this does this, but this is actually how CCK stores data. If there are no rows in a multiple field it will add 1 blank row as a place holder so that when the node is loaded it will populate the node correctly.
Comment #37
stijndm commentedthis wasn't happening before. I have some specific code to execute and write in my template when there is a value for audio of images. When submitting using the last patch the html is always printed even though there are no images/audio files because of the blank row. This does not happen when using the normal cck file.
I just checked the database of the live site wich uses the unpatched version of cck. Apparently some field do add a blank row to the database, but these are only the fields that are part of the cck package. The imagefield and mediafield don't insert empty rows on creation.
However, when updating an item that contains images or audio, de records for images are deleted and those for audio are replaced by an empty row.
So the standard behaviour of
cck + imagefield: when empty no rows are added to the database (or records are deleted on update)
cck+ audiofield (mediafield): when empty on creation no rows are added to the database, after updating ande deleteing a file the rows in the database are replaced by an empty row.
Something in your patch is overriding this behaviour by always inserting empty rows. Wich seems to be standard cck behaviour. (I'd prefer no rows were added but this is another issue all together).
Considering the above:
You latest patch (comment 33) seems to work fine and enforces standard cck behaviour
My patch (comment 32) also seems to work fine and respects the standard behaviour of imagefield.module and mediafield.module
I guess your patch is the safer bet when it comes to themeing and compatibility with cck.
Comment #38
Leeteq commentedRef. #36:
Can't this be dealt with by some logic that identifies empty fields and then takes care of leaving them empty at the moment of populating the form? This seems to have the potential for performance improvement too.
Comment #39
stijndm commentedI think I found another bug in this one. I will do my best to describe the problem.
I have a multilingual site running using internationalization (i18n). I have a custom contenttype with imagefield. It is a single value required field. Display is done with imagecache, although after the tests I have done I al pretty sure this has nothing to do with it.
The problem is with updating nodes that share the same image.
The workflow:
I create a new node with the required image in say English. Then I translate the nodes vie the translation menu, so for each language the content of the fields is copied. I am now using the same image in all my translated nodes.
After doing all this I realize I want to use a different image. I now have to change the image for each translated node. (I could activate the synchronize module that comes with i18n, which would automatically change the value for all the connected nodes. But it is experimental and broke some other more importent features we need.)
When uploading a new image in one of the nodes the original image is removed, and I assume some rows in the database are removed/replaced/edited. Sadly the image is also removed from the server, although it is still being used by other nodes (but this is default imagefield behaviour apparently).
The problem is when I go to the next node, one of the translated nodes, and upload the new image everything breaks after submission. The image is entered in the database files table but somehow isn't connected in the right way to the node. The returns and empty. Yet something is still in the database because when you go and edit the node again the image is not loaded correctly giving the impression that there is no image attached. Yet the field says that if I upload a new image the old one will be replaced and I can save the node with the required field apparently empty, getting no error.
If I role back the patch and use the default cck content.module everything works fine. New images are added correctly. Something is going wrong in this patch during update.
Comment #40
gordon commentedHere is an update of the patch for the latest versions
Comment #41
cgjohnson commentedI have the latest version of Drupal (6.6) and CCK, imagefield, filefield and imagecache. Using php 5.2.1, site5 host.
I get this error when I create a node and do not add an image (image is not required in my CCK content entry form):
user warning: Column 'field_images_fid' cannot be null query: INSERT INTO content_field_images (vid, nid, delta, field_images_fid, field_images_list, field_images_data) VALUES (589, 589, 0, NULL, NULL, NULL) in /home/MYSITE/public_html/sites/all/modules/cck/content.module on line 1199.
Any ideas why this is? Any solution? I can't let our editors see this error every time they upload content. Before upgrade to D6 this all worked like a charm.
thanks.
Comment #42
yched commentedcgjohnson - How is this even remotely related to the current thread ?
Please search imagefield issue queue about that, this has been reported before - maybe even fixed since then.
Comment #43
karens commentedThe D5 version is no longer being supported. Sorry.