the DBA module looks extremely cool and useful, thanks for creating it!
i'm trying to get automated backups working with it, and i've run into what appears to be a bug. i'm not sure if it's the DBA module itself, or the fact that my site is running MySQL 5.0.18 (which has caused problems for a number of other drupal modules, since MySQL 5.0.12 changed their supported syntax for a number of things, and that broke a bunch of older SQL syntax, especially JOIN statements).
my problem comes when i try to restore a DB dump from 1 test site into another. i used the DBA module on 1 site, call it test1, and dumped all tables to a file. i uploaded that file to test2's filesystem, and tried to run mysql to load all the schemas and data into test2. when i try that, i get the following:
ERROR 1067 (42000) at line 1020: Invalid default value for 'nid'
looking at line 1020 of the dump file, i find the CREATE TABLE statements for the "queue" table (which is empty in the test1 site). the faulty lines are:
nid int(10) unsigned NOT NULL default '',
uid int(10) unsigned NOT NULL default '',
if i manually edit these to be:
nid int(10) unsigned NOT NULL,
uid int(10) unsigned NOT NULL,
then a) it's no longer trying to use an empty string as the default value for an int field, b) the lines match the "CREATE TABLE queue" statements from the database/database.mysql file in the main 4.6.5 drupal distribution, and c) the attempt to restore the DB from this backup works. (well, almost, there's another faulty line in the "sessions" table, same basic error):
CREATE TABLE sessions (
uid int(10) unsigned NOT NULL default '',
once i change these 3 faulty lines to not specify an empty string as the default for an int field, the whole restore process works fine. it seems that something the DBA module is doing to dump these tables is screwing this up. any ideas? i'm still relatively new to drupal and SQL in general, so i'm not sure how long it'd take me to try to track this down and submit a patch. perhaps someone more knowledgeable about the DBA module could isolate the source of the trouble more quickly. please let me know if there's any additional info i can provide to help track this down.
once again, thanks for the great module! i can already see this will be immensely helpful for me to view tables more easily while trying to customize various modules. the automated backups will be great, too, once i can get the restore fully functional...
thanks!
-derek
| Comment | File | Size | Author |
|---|---|---|---|
| #7 | dba.module_3.patch | 2.52 KB | jeremy |
| #5 | dba_backup_numeric_field_default.patch_0.txt | 908 bytes | eaton |
| #4 | dba_backup_numeric_field_default.patch.txt | 907 bytes | dww |
Comments
Comment #1
jeremy commentedI'm looking at this issue in 4.7, but I'm unable to duplicate. The queue table is gone, but the sessions table still exists. When I do a backup, I see a valid default value (exactly what is seen from "describe sessions"):
Granted, this doesn't match database.mysql, but we're working from a "describe" and in MySQL 4 "describe sessions" returns the following:
(note that uid has a default of '0')
Can you (or anyone running MySQL 5.x) post the output from 'describe sessions'? I want to see if there are any differences in the output between MySQL 4 and MySQL 5.
Comment #2
dwwgreat suggestion to look at the table in the DB. it's definitely wrong...
here's the output of the sessions table on my 4.7 test site, which is using MySQL 5.0.16:
here's the output from my live 4.6 site's sessions table (also MySQL 5.0.16):
looking at both on another test site (on my laptop) running MySQL 4.1.18, the schema agrees exactly with what you previously posted. so, somehow, the default for uid is getting lost in MySQL 5.0, but still works in 4.0. weird! any suggestions on where to debug from here?
it still seems like a bug in the dba module that it's writing out a default value of an empty string for a field without a default (especially if the field is an unsigned int). but something more fundamental also seems broken here... i'm not really sure where to look next. let me know if i can be of any further assisstance tracking this down, if you want me to test anything in MySQL 5, etc.
thanks!
-derek
Comment #3
jeremy commentedIt looks like in 4.x if you declared NOT NULL you also had to specify a default, and if you didn't it was added for you. It looks like in 5.x if you declare NOT NULL you no longer have to specify a default.
The session creation script begins as follows (from database.mysql):
With a 4.x database, describe shows a default uid of 0. In a 5.x database, describe doesn't show a default. 5.x seems more correct to me.
In any case, the real bug is in the dba module, as it's detecting a default when there isn't one. I've not got time to look at this now, but will shortly. (If you want to look yourself, look in function dba_backup_table(), that's where we backup the schema and the data...)
Comment #4
dwwIn any case, the real bug is in the dba module, as it's detecting a default when there isn't one
i finally had a chance to look at this closely, and it seems the "real" bug might be in MySQL itself. :( here's what my debugging found...
basically, all the DESCRIBE output from above is still true. however, when we're in
dba_backup_table()and we're trying to create the right DB schema, MySQL is returning misleading things that are confusing our code. :( in particular, i added a bunch of debugging watchdog messages when we're dealing with$row['Default']and it's not pretty. :(for the integer uid field, the row we get back from db_fetch_row() from our DESCRIBE query is as follows:
array ( 'Field' => 'uid', 'Type' => 'int(10) unsigned', 'Null' => 'NO', 'Key' => 'MUL', 'Default' => '', 'Extra' => '', )since it's an int field, MySQL is treating the default as 0 (easily verifiable if you insert a row into the table without specifying a uid), but it's returning the default as an empty string. :( this of course causes havoc for our code that's trying to handle real empty strings as defaults for string fields.
a few interesting (but ultimately, not going to solve our problems) things to read:
http://sql-info.de/mysql/gotchas.html#1_1
http://bugs.mysql.com/bug.php?id=21618
the only thing i can think of to handle this problem is to use logic where if Default is an empty string, and NULL isn't YES, then we should check the Type and if it's any of the possible numeric types, we leave off specifying an empty string as the default. seems like a hack, but i can't see any way to get around it if MySQL is going to return '' for the default in this case, not 0 (which is what it's actually using) or NULL (if you didn't specify in your schema). :(
the attached patch seems to work, but it makes me feel dirty. ;) i decided not to just append a
default '0'in this case (which is what MySQL is really doing), and instead just left the case completely blank with a big comment about why. alternatively, we could combine thiselse ifclause with the final one, but that made the line so long it was harder to read and i don't think putting them together buys us anything in terms of speed or clarity.let me know what you think. i'd like to apply this to all 3 branches (4.6, 4.7 and HEAD) if you agree this isn't a completely insane workaround for buggy MySQL behavior.
thanks,
-derek
Comment #5
eaton commentedPatch applied but choked on a syntax error -- just a missing parenthesis. Fixed and re-rolled.
Comment #6
jeremy commentedI think we can greatly simplify dba_backup_table() by getting rid of all the custom code to build the CREATE statement, and just call SHOW CREATE TABLE instead. I obviously wasn't aware of that function when I originally wrote the dba module.
Comment #7
jeremy commentedPlease test backups with the attached patch, let me know if that solves your problem and doesn't break anything else. It should be a big improvement.
Comment #8
jeremy commentedI've gone ahead and committed my patch and rolled a new release to include your other fix allowing buttons to work.
Comment #9
dwwsweet, thanks!
-derek
p.s. today is my 1-year anniversary from when i created my drupal.org account. ;)
Comment #10
(not verified) commented