Description:
The mysql_fix_privilege_tables script errors out on servers with a strict mode set.
The offending part is that the creation of the proc table tries to set a default value for the sql_mode and body columns.
This example is really weird, because it fails when the mode is STRICT_TRANS_TABLES, but the table created is myisam (although the server default is innodb - is the sql for the create table parsed before the engine is assigned?).
My argument here is that:
1. none of our scripts should fail with the default installation my.ini file on windows (nor strict mode since many customers run it).
2. It shouldn't fail with STRICT_TRANS_TABLES when it works with '' as a SQL_MODE if the table is not a transactional engine (such as MyISAM).
How to repeat:
mysql> set sql_mode = 'STRICT_TRANS_TABLES';
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE IF NOT EXISTS proc (
-> db char(64) collate utf8_bin DEFAULT '' NOT NULL,
-> name char(64) DEFAULT '' NOT NULL,
-> type enum('FUNCTION','PROCEDURE') NOT NULL,
-> specific_name char(64) DEFAULT '' NOT NULL,
-> language enum('SQL') DEFAULT 'SQL' NOT NULL,
-> sql_data_access enum('CONTAINS_SQL',
-> 'NO_SQL',
-> 'READS_SQL_DATA',
-> 'MODIFIES_SQL_DATA'
-> ) DEFAULT 'CONTAINS_SQL' NOT NULL,
-> is_deterministic enum('YES','NO') DEFAULT 'NO' NOT NULL,
-> security_type enum('INVOKER','DEFINER') DEFAULT 'DEFINER' NOT NULL,
-> param_list blob DEFAULT '' NOT NULL,
-> returns char(64) DEFAULT '' NOT NULL,
-> body longblob DEFAULT '' NOT NULL,
-> definer char(77) collate utf8_bin DEFAULT '' NOT NULL,
-> created timestamp,
-> modified timestamp,
-> sql_mode set(
-> 'REAL_AS_FLOAT',
-> 'PIPES_AS_CONCAT',
-> 'ANSI_QUOTES',
-> 'IGNORE_SPACE',
-> 'NOT_USED',
-> 'ONLY_FULL_GROUP_BY',
-> 'NO_UNSIGNED_SUBTRACTION',
-> 'NO_DIR_IN_CREATE',
'POSTGRESQL',
'ORACLE',
'MSSQL',
'DB2',
'MAXDB',
'NO_KEY_OPTIONS',
'NO_TABLE_OPTIONS',
'NO_FIELD_OPTIONS',
'MYSQL323',
'MYSQL40',
'ANSI',
'NO_AUTO_VALUE_ON_ZERO',
'NO_BACKSLASH_ESCAPES',
'STRICT_TRANS_TABLES',
'STRICT_ALL_TABLES',
'NO_ZERO_IN_DATE',
'NO_ZERO_DATE',
'INVALID_DATES',
'ERROR_FOR_DIVISION_BY_ZERO',
'TRADITIONAL',
'NO_AUTO_CREATE_USER',
'HIGH_NOT_PRECEDENCE'
) DEFAULT '' NOT NULL,
comment char(64) collate comment c -> 'POSTGRESQL',
-> 'ORACLE',
-> 'MSSQL',
-> 'DB2',
-> 'MAXDB',
-> 'NO_KEY_OPTIONS',
-> 'NO_TABLE_OPTIONS',
-> 'NO_FIELD_OPTIONS',
-> 'MYSQL323',
-> 'MYSQL40',
-> 'ANSI',
-> 'NO_AUTO_VALUE_ON_ZERO',
-> 'NO_BACKSLASH_ESCAPES',
-> 'STRICT_TRANS_TABLES',
-> 'STRICT_ALL_TABLES',
-> 'NO_ZERO_IN_DATE',
-> 'NO_ZERO_DATE',
-> 'INVALID_DATES',
-> 'ERROR_FOR_DIVISION_BY_ZERO',
-> 'TRADITIONAL',
-> 'NO_AUTO_CREATE_USER',
-> 'HIGH_NOT_PRECEDENCE'
-> ) DEFAULT '' NOT NULL,
-> comment char(64) collate comment char(64) collate ARY KEY (db,name,type)
-> ) engine=MyISAM
-> character set utf8
-> comment='Stored Procedures';
ERROR 1101 (42000): BLOB/TEXT column 'param_list' can't have a default value
mysql> SET SQL_MODE = '';
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE IF NOT EXISTS proc (
-> db char(64) collate utf8_bin DEFAULT '' NOT NULL,
-> name char(64) DEFAULT '' NOT NULL,
-> type enum('FUNCTION','PROCEDURE') NOT NULL,
-> specific_name char(64) DEFAULT '' NOT NULL,
-> language enum('SQL') DEFAULT 'SQL' NOT NULL,
-> sql_data_access enum('CONTAINS_SQL',
-> 'NO_SQL',
-> 'READS_SQL_DATA',
-> 'MODIFIES_SQL_DATA'
-> ) DEFAULT 'CONTAINS_SQL' NOT NULL,
-> is_deterministic enum('YES','NO') DEFAULT 'NO' NOT NULL,
-> security_type enum('INVOKER','DEFINER') DEFAULT 'DEFINER' NOT NULL,
-> param_list blob DEFAULT '' NOT NULL,
-> returns char(64) DEFAULT '' NOT NULL,
-> body longblob DEFAULT '' NOT NULL,
-> definer char(77) collate utf8_bin DEFAULT '' NOT NULL,
-> created timestamp,
-> modified timestamp,
-> sql_mode set(
-> 'REAL_AS_FLOAT',
-> 'PIPES_AS_CONCAT',
-> 'ANSI_QUOTES',
-> 'IGNORE_SPACE',
-> 'NOT_USED',
-> 'ONLY_FULL_GROUP_BY',
-> 'NO_UNSIGNED_SUBTRACTION',
-> 'NO_DIR_IN_CREATE',
-> 'POSTGRESQL',
-> 'ORACLE',
-> 'MSSQL',
-> 'DB2',
-> 'MAXDB',
-> 'NO_KEY_OPTIONS',
-> 'NO_TABLE_OPTIONS',
-> 'NO_FIELD_OPTIONS',
-> 'MYSQL323',
-> 'MYSQL40',
-> 'ANSI',
-> 'NO_AUTO_VALUE_ON_ZERO',
-> 'NO_BACKSLASH_ESCAPES',
-> 'STRICT_TRANS_TABLES',
-> 'STRICT_ALL_TABLES',
-> 'NO_ZERO_IN_DATE',
-> 'NO_ZERO_DATE',
-> 'INVALID_DATES',
-> 'ERROR_FOR_DIVISION_BY_ZERO',
-> 'TRADITIONAL',
-> 'NO_AUTO_CREATE_USER',
-> 'HIGH_NOT_PRECEDENCE'
-> ) DEFAULT '' NOT NULL,
-> comment char(64) collate utf8_bin DEFAULT '' NOT NULL,
-> PRIMARY KEY (db,name,type)
-> ) engine=MyISAM
-> character set utf8
-> comment='Stored Procedures';
Query OK, 0 rows affected, 2 warnings (0.00 sec)
mysql> show warnings;
+---------+------+----------------------------------------------------------+
| Level | Code | Message |
+---------+------+----------------------------------------------------------+
| Warning | 1101 | BLOB/TEXT column 'param_list' can't have a default value |
| Warning | 1101 | BLOB/TEXT column 'body' can't have a default value |
+---------+------+----------------------------------------------------------+
2 rows in set (0.00 sec)
Suggested fix:
In addition to fixing this bug, a full testcase using the full mysql_fix_privile_tables under different sql_modes should be added to the test suite, since this has been broken before ( http://bugs.mysql.com/bug.php?id=15760 )