| Project: | Link |
| Version: | 6.x-2.5 |
| Component: | Code |
| Category: | bug report |
| Priority: | critical |
| Assigned: | jcfiala |
| Status: | closed (fixed) |
Issue Summary
With CCK 6.x-2.0-rc9 on Drupal 6.4, I receive the following error when trying to create or update a node for a content type with a links field (with multiple values) when the field URL is not filled out:
user warning: Column 'field_other_links_url' cannot be null query: INSERT INTO content_field_other_links (vid, nid, delta, field_other_links_url, field_other_links_title, field_other_links_attributes) VALUES (2403, 2403, 0, NULL, NULL, NULL) in /test/www/drupal/sites/all/modules/cck/content.module on line 1126.
The node is still created and updated correctly.
I was receiving this error with text fields as well, but the Text module's 6001 update (copied below for reference) changes its columns to accept NULL values (and sets existing blank values to NULL), which fixed it for text fields. The error remains with Link fields due to the _url column not allowing NULL values.
Interestingly, the error only occurs when the URL is empty. If the URL is filled in but the link's Title is not, there is no error shown, even though the _title column doesn't allow NULL values, either.
<?php
/**
* Set all columns to accept NULL values and set empty string values in the
* database to NULL.
*
* Leaving it up to module developers to handle conversion of numbers to
* NULL values, since there are times when zeros are valid data and times
* when they should be NULL.
*
*/
function text_update_6001() {
if ($abort = content_check_update('text')) {
return $abort;
}
$ret = array();
drupal_load('module', 'content');
// Get the latest cache values and schema.
content_clear_type_cache(TRUE, TRUE);
include_once('./'. drupal_get_path('module', 'content') .'/content.install');
$types = content_types_install();
foreach ($types as $type_name => $fields) {
foreach ($fields as $field) {
switch ($field['type']) {
case 'text':
$db_info = content_database_info($field);
$table = $db_info['table'];
foreach ($db_info['columns'] as $column => $attributes) {
$attributes['not null'] = FALSE;
$column = $attributes['column'];
db_change_field($ret, $table, $column, $column, $attributes);
// TODO: errors on text/blob columns: no default value allowed (!)
db_field_set_no_default($ret, $table, $column);
if ($attributes['type'] == 'varchar' || $attributes['type'] == 'text
') {
$ret[] = update_sql("UPDATE {". $table ."} SET ". $column ." = NUL
L WHERE ". $column ." = ''");
}
else {
// TODO: replace format = 0 with format = NULL ?? Is this right ?
$ret[] = update_sql("UPDATE {". $table ."} SET ". $column ." = NUL
L WHERE ". $column ." = 0");
}
}
break;
}
}
}
return $ret;
}
?>
Comments
#1
I am seeing a variation of this problem. I have my content type and link field only accepting urls. But, when I try to save the node, it bombs with a watchdog error saying the link title is NULL -- but I'm not accepting titles for this link field! Somehow the code is passing NULL values and not being accepted down the line. Latest Drupal 6 and CCK, link.
#2
After further review, I can see that the problem is the NOT NULL field definition. I had upgraded from DP5 and the field default was still set to NOT NULL. The update code should be amended to fix this problem as outlined above. Newly created fields don't have this problem.
#3
Precisely the same problem as lutegrass, also after upgrade from D5. Could you fix this please - many people will still need upgrading CCK Link from D5. Thanks!
#4
Here's a PHP snippet to update existing database columns. I'm running Drupal 6.6, CCK 6.x-2.0, and Link 6.x-2.5. Make sure Link is enabled before proceeding.
This is adapted from the Text module's function mentioned above. It has not been tested very much, so please use caution and back up your database first. I ran a previous version of this and it worked, but I made some changes afterwords... So let me know if this one works for you!
<?php
//-- Update all CCK "Link" fields to accept NULL values.
//-- Adapted from text_update_6001() in text.install
include_once('./'. drupal_get_path('module', 'content') .'/content.install');
drupal_load('module', 'content');
// Get the latest cache values and schema.
content_clear_type_cache(TRUE, TRUE);
$types = content_types_install();
if (!empty($types)) {
$sandbox['fields'] = array();
foreach ($types as $type_name => $fields) {
foreach ($fields as $field) {
if ($field['type'] == 'link') {
$sandbox['fields'][] = $field;
}
}
}
if (!empty($sandbox['fields'])) {
$sandbox['visited'] = array();
$ret = array();
foreach ($sandbox['fields'] as $progress => $field) {
$sandbox['progress'] = $progress;
// We only want to process a field once -- if we hit it a second time,
// that means it's its own table and it should have already been updated.
if (!in_array($field['field_name'], $sandbox['visited'])) {
$db_info = content_database_info($field);
$table = $db_info['table'];
foreach ($db_info['columns'] as $column => $attributes) {
$attributes['not null'] = FALSE;
$column = $attributes['column'];
db_change_field($ret, $table, $column, $column, $attributes);
// TODO: errors on text/blob columns: no default value allowed (!)
db_field_set_no_default($ret, $table, $column);
if ($attributes['type'] == 'varchar' || $attributes['type'] == 'text') {
$ret[] = update_sql("UPDATE {". $table ."} SET ". $column ." = NULL WHERE ". $column ." = ''");
}
else {
// TODO: replace format = 0 with format = NULL ?? Is this right ?
$ret[] = update_sql("UPDATE {". $table ."} SET ". $column ." = NULL WHERE ". $column ." = 0");
}
}
$sandbox['visited'][] = $field['field_name'];
drupal_set_message("Field {$table}.{$field['field_name']} converted.");
}
}
}
}
?>
#5
Also experiencing the same error after upgrading from D5.
#6
I confirm the error as well on my D6 site. manually editing the database to allow Null values fixed the problem.
#7
I also confirm this bug. I think this is a issue with CCK in general, I have this problem with other CCK field types.
As mentioned in #6 manually editing the database to allow Null values fixed the problem.
introfini
#8
Should this issue be transferred to CCK?
#9
I think it should. In my debugging I trace the problem to content.module (CCK).
introfini
#10
hello,
It seems this problem is being fixed in the modules, not in CCK. I think this is the same problem in imagefield: http://cvs.drupal.org/viewvc.py/drupal/contributions/modules/imagefield/...
introfini
#11
I agree, this should be fixed in Link module. Ironically I'm the one that fixed it in ImageField, and ImageField is the reason why I no longer have time to work on Link (this module is now officially abandoned). Anyone interested #304906: Link needs a new maintainer?
#12
Yes, I'm seeing the same error after a 5.x to 6.x upgrade. I also saw the same problem with Imagefield, and upgrading to a more recent version of the imagefield module (along with running update.php) solved the problem for Imagefield.
#13
Heh, sometimes it's just not easy to turn your back on 3 years of module maintenance. ;-)
Here's an update function which should solve this problem. Starting in Drupal 6, CCK started instituting that NULL values should be set for empty records, however the Drupal 5 version of Link stored empty strings, and its columns were all set to "NOT NULL".
This update fixes the upgrade path from Drupal 5 to Drupal 6, and should fix any existing Drupal 6 sites that have already upgraded.
#14
Thanks for coming out of hiding to help us lost souls. I applied the patch and ran update.php and it worked like a charm. Hopefully you or the new maintainer can get this committed.
thanks a lot, ian
#15
fletch11, did you run update.php? Since it's nothing but an update function it needs to be run in order to correct the database schema.
#16
thanks - I just ran it since as I pressed the save button I remembered I forgot something... thanks for the fast response.
ian
#17
The patch didn't install correctly for me (maybe it was my error). The error I got said:
1 out of 1 hunk FAILED -- saving rejects to file link.install.rej
The steps I followed were:
1) I copied link_null_values_update.patch into my sites/all/modules/link directory
2) I ran patch < link_null_values_update.patch
3) I got the error above
It appears that the patch is attempting to add lines in the link.install file after the lines:
}
return array();
}
The last 3 lines in my link.install file (link 6.x-2.5) are:
function link_update_last_removed() {
return 1;
}
So, maybe the patch couldn't figure out where it was supposed to go?
I then cut and pasted the patch code (deleteing the +) into the end of link.install, ran update.php, and everything seems to work okay (so far).
Is this okay?
Thanks.
#18
Patch in #13 solves the problem.
Re-rolling just to include new line at the end.
#19
Also solved for me. Please commit this one, I think it's ready.
#20
Yes, it works. Please commit.
#21
I had this same problem happen to me on a site we were upgrading as well. I'll work to get this into 6.x-2.6.
#22
Okay, I'm testing the patch - it's a pain to test, because I've basically got to set up a drupal 5 site with cck & link, and then upgrade it to 6, have the problem, and then run the patch to fix it. :)
#23
The patch worked fine for me too, and I've committed the change to cvs successfully. It will be in the next release.
#24
Automatically closed -- issue fixed for 2 weeks with no activity.