Below is the list of changes that have just been committed into a local
6.0 repository of rafal. When rafal does a push these changes
will be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2008-03-26 11:46:18+01:00, rafal@quant.(none) +4 -0
BUG#33571 (Backup: restore failure if sql_mode=ansi)
This patch modifies object services methods so that sql_mode is locally changed to
default when operations which depend on it are executed. These operations are
obtaining the serialization string (format of SHOW CREATE output depends on sql_mode)
and "executing" an object (syntax of CREATE statement depends on sql_mode).
mysql-test/r/backup.result@stripped, 2008-03-26 11:46:12+01:00, rafal@quant.(none) +86 -0
Updated results.
mysql-test/t/backup.test@stripped, 2008-03-26 11:46:12+01:00, rafal@quant.(none) +63 -0
Add tests checking how BACKUP/RESTORE work when sql_mode is changed.
sql/si_objects.cc@stripped, 2008-03-26 11:46:12+01:00, rafal@quant.(none) +24 -36
Rename *::serialize() -> *::do_serialize() and *::execute() -> *::do_execute().
sql/si_objects.h@stripped, 2008-03-26 11:46:12+01:00, rafal@quant.(none) +36 -2
Move implementations of serialzie() and execute() operations to new primitives Obj::do_serialize()
and Obj::do_execute(). Modify Obj::execute() and Obj::serialzie() methods so that they set
sql_mode to default during execution of the primitives.
diff -Nrup a/mysql-test/r/backup.result b/mysql-test/r/backup.result
--- a/mysql-test/r/backup.result 2008-01-30 23:28:04 +01:00
+++ b/mysql-test/r/backup.result 2008-03-26 11:46:12 +01:00
@@ -437,4 +437,90 @@ Running the client:
Chuck@linux:~> mysql -uroot -p
Enter password:
+SET sql_mode=ansi;
+SHOW VARIABLES LIKE 'sql_mode';
+Variable_name Value
+sql_mode REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ANSI
+DROP DATABASE bup_default;
+RESTORE FROM 'bup_default.bak';
+backup_id
+#
+SHOW VARIABLES LIKE 'sql_mode';
+Variable_name Value
+sql_mode REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ANSI
+SHOW TABLES IN bup_default;
+Tables_in_bup_default
+t1
+t1_blob
+t2
+wide
+SHOW CREATE TABLE bup_default.t1;
+Table Create Table
+t1 CREATE TABLE "t1" (
+ "a" int(11) DEFAULT NULL
+)
+SELECT * FROM bup_default.t1;
+a
+1
+2
+3
+4
+SELECT * FROM bup_default.t2;
+a
+1
+2
+3
+4
+SELECT COUNT(*) FROM bup_default.t1_blob;
+COUNT(*)
+2
+SELECT COUNT(*) FROM bup_default.wide;
+COUNT(*)
+1
+BACKUP DATABASE bup_default TO 'bup_default.bak';
+backup_id
+#
+SHOW VARIABLES LIKE 'sql_mode';
+Variable_name Value
+sql_mode REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ANSI
+SET sql_mode='';
+SHOW VARIABLES LIKE 'sql_mode';
+Variable_name Value
+sql_mode
+DROP DATABASE bup_default;
+RESTORE FROM 'bup_default.bak';
+backup_id
+#
+SHOW VARIABLES LIKE 'sql_mode';
+Variable_name Value
+sql_mode
+SHOW TABLES IN bup_default;
+Tables_in_bup_default
+t1
+t1_blob
+t2
+wide
+SHOW CREATE TABLE bup_default.t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+SELECT * FROM bup_default.t1;
+a
+1
+2
+3
+4
+SELECT * FROM bup_default.t2;
+a
+1
+2
+3
+4
+SELECT COUNT(*) FROM bup_default.t1_blob;
+COUNT(*)
+2
+SELECT COUNT(*) FROM bup_default.wide;
+COUNT(*)
+1
DROP DATABASE IF EXISTS bup_default;
diff -Nrup a/mysql-test/t/backup.test b/mysql-test/t/backup.test
--- a/mysql-test/t/backup.test 2008-01-30 23:28:04 +01:00
+++ b/mysql-test/t/backup.test 2008-03-26 11:46:12 +01:00
@@ -329,6 +329,69 @@ SELECT COUNT(*) FROM bup_default.t1_blob
SELECT COUNT(*) FROM bup_default.wide;
--query_vertical SELECT * FROM bup_default.wide;
+#
+# Test that backup/restore operations work correctly regardless of the
+# current setting of sql_mode (BUG#33571)
+#
+
+# Change sql_mode to ANSI and see if it is possible to restore and backup
+# a database with non-default sql_mode.
+
+SET sql_mode=ansi;
+SHOW VARIABLES LIKE 'sql_mode';
+
+DROP DATABASE bup_default;
+
+--replace_column 1 #
+RESTORE FROM 'bup_default.bak';
+
+# See that sql_mode was not modified by RESTORE operation.
+
+SHOW VARIABLES LIKE 'sql_mode';
+
+# Check that database was restored.
+
+SHOW TABLES IN bup_default;
+SHOW CREATE TABLE bup_default.t1;
+SELECT * FROM bup_default.t1;
+SELECT * FROM bup_default.t2;
+SELECT COUNT(*) FROM bup_default.t1_blob;
+SELECT COUNT(*) FROM bup_default.wide;
+
+--remove_file $MYSQLTEST_VARDIR/master-data/bup_default.bak
+--replace_column 1 #
+BACKUP DATABASE bup_default TO 'bup_default.bak';
+
+# See that sql_mode was not modified by BACKUP operation.
+
+SHOW VARIABLES LIKE 'sql_mode';
+
+
+# We have backed up a database when sql_mode was ANSI. Change
+# the mode back to default and see that we can correctly restore.
+
+SET sql_mode='';
+SHOW VARIABLES LIKE 'sql_mode';
+
+DROP DATABASE bup_default;
+
+--replace_column 1 #
+RESTORE FROM 'bup_default.bak';
+
+# See that sql_mode was not modified by RESTORE operation.
+
+SHOW VARIABLES LIKE 'sql_mode';
+
+# Check that database was restored.
+
+SHOW TABLES IN bup_default;
+SHOW CREATE TABLE bup_default.t1;
+SELECT * FROM bup_default.t1;
+SELECT * FROM bup_default.t2;
+SELECT COUNT(*) FROM bup_default.t1_blob;
+SELECT COUNT(*) FROM bup_default.wide;
+
+
--disable_warnings
DROP DATABASE IF EXISTS bup_default;
--enable_warnings
diff -Nrup a/sql/si_objects.cc b/sql/si_objects.cc
--- a/sql/si_objects.cc 2008-03-17 13:38:16 +01:00
+++ b/sql/si_objects.cc 2008-03-26 11:46:12 +01:00
@@ -456,13 +456,9 @@ public:
DatabaseObj(const String *db_name);
public:
- virtual bool serialize(THD *thd, String *serialization);
-
virtual bool materialize(uint serialization_version,
const String *serialization);
- virtual bool execute(THD *thd);
-
const String* get_name()
{ return &m_db_name; }
@@ -476,6 +472,8 @@ private:
String m_db_name;
bool drop(THD *thd);
+ virtual bool do_serialize(THD *thd, String *serialization);
+ virtual bool do_execute(THD *thd);
private:
// These attributes are to be used only for materialization.
@@ -498,13 +496,9 @@ public:
bool table_is_view);
public:
- virtual bool serialize(THD *thd, String *serialization);
-
virtual bool materialize(uint serialization_version,
const String *serialization);
- virtual bool execute(THD *thd);
-
const String* get_name()
{ return &m_table_name; }
@@ -520,6 +514,8 @@ private:
bool m_table_is_view;
bool drop(THD *thd);
+ virtual bool do_serialize(THD *thd, String *serialization);
+ virtual bool do_execute(THD *thd);
private:
// These attributes are to be used only for materialization.
@@ -545,13 +541,9 @@ public:
const String *trigger_name);
public:
- virtual bool serialize(THD *thd, String *serialization);
-
virtual bool materialize(uint serialization_version,
const String *serialization);
- virtual bool execute(THD *thd);
-
const String* get_name()
{ return &m_trigger_name; }
@@ -566,6 +558,8 @@ private:
String m_trigger_name;
bool drop(THD *thd);
+ virtual bool do_serialize(THD *thd, String *serialization);
+ virtual bool do_execute(THD *thd);
private:
// These attributes are to be used only for materialization.
@@ -587,13 +581,9 @@ public:
const String *stored_proc_name);
public:
- virtual bool serialize(THD *thd, String *serialization);
-
virtual bool materialize(uint serialization_version,
const String *serialization);
- virtual bool execute(THD *thd);
-
const String* get_name()
{ return &m_stored_proc_name; }
@@ -608,6 +598,8 @@ private:
String m_stored_proc_name;
bool drop(THD *thd);
+ virtual bool do_serialize(THD *thd, String *serialization);
+ virtual bool do_execute(THD *thd);
private:
// These attributes are to be used only for materialization.
@@ -629,13 +621,9 @@ public:
const String *stored_func_name);
public:
- virtual bool serialize(THD *thd, String *serialization);
-
virtual bool materialize(uint serialization_version,
const String *serialization);
- virtual bool execute(THD *thd);
-
const String* get_name()
{ return &m_stored_func_name; }
@@ -650,6 +638,8 @@ private:
String m_stored_func_name;
bool drop(THD *thd);
+ virtual bool do_serialize(THD *thd, String *serialization);
+ virtual bool do_execute(THD *thd);
private:
// These attributes are to be used only for materialization.
@@ -671,13 +661,9 @@ public:
const String *event_name);
public:
- virtual bool serialize(THD *thd, String *serialization);
-
virtual bool materialize(uint serialization_version,
const String *serialization);
- virtual bool execute(THD *thd);
-
const String* get_name()
{ return &m_event_name; }
@@ -692,6 +678,8 @@ private:
String m_event_name;
bool drop(THD *thd);
+ virtual bool do_serialize(THD *thd, String *serialization);
+ virtual bool do_execute(THD *thd);
private:
// These attributes are to be used only for materialization.
@@ -1481,7 +1469,7 @@ DatabaseObj::DatabaseObj(const String *d
@retval FALSE on success
@retval TRUE on error
*/
-bool DatabaseObj::serialize(THD *thd, String *serialization)
+bool DatabaseObj::do_serialize(THD *thd, String *serialization)
{
HA_CREATE_INFO create;
DBUG_ENTER("DatabaseObj::serialize()");
@@ -1553,7 +1541,7 @@ bool DatabaseObj::materialize(uint seria
@retval FALSE on success
@retval TRUE on error
*/
-bool DatabaseObj::execute(THD *thd)
+bool DatabaseObj::do_execute(THD *thd)
{
DBUG_ENTER("DatabaseObj::execute()");
drop(thd);
@@ -1624,7 +1612,7 @@ bool TableObj::serialize_view(THD *thd,
@retval FALSE on success
@retval TRUE on error
*/
-bool TableObj::serialize(THD *thd, String *serialization)
+bool TableObj::do_serialize(THD *thd, String *serialization)
{
bool ret= 0;
LEX_STRING tname, dbname;
@@ -1718,7 +1706,7 @@ bool TableObj::materialize(uint serializ
@retval FALSE on success
@retval TRUE on error
*/
-bool TableObj::execute(THD *thd)
+bool TableObj::do_execute(THD *thd)
{
DBUG_ENTER("TableObj::execute()");
drop(thd);
@@ -1781,7 +1769,7 @@ TriggerObj::TriggerObj(const String *db_
@retval FALSE on success
@retval TRUE on error
*/
-bool TriggerObj::serialize(THD *thd, String *serialization)
+bool TriggerObj::do_serialize(THD *thd, String *serialization)
{
bool ret= false;
uint num_tables;
@@ -1907,7 +1895,7 @@ bool TriggerObj::materialize(uint serial
@retval FALSE on success
@retval TRUE on error
*/
-bool TriggerObj::execute(THD *thd)
+bool TriggerObj::do_execute(THD *thd)
{
DBUG_ENTER("TriggerObj::execute()");
drop(thd);
@@ -1969,7 +1957,7 @@ StoredProcObj::StoredProcObj(const Strin
@returns Error status.
*/
-bool StoredProcObj::serialize(THD *thd, String *serialization)
+bool StoredProcObj::do_serialize(THD *thd, String *serialization)
{
bool ret= false;
DBUG_ENTER("StoredProcObj::serialize()");
@@ -2015,7 +2003,7 @@ bool StoredProcObj::materialize(uint ser
@retval FALSE on success
@retval TRUE on error
*/
-bool StoredProcObj::execute(THD *thd)
+bool StoredProcObj::do_execute(THD *thd)
{
DBUG_ENTER("StoredProcObj::execute()");
drop(thd);
@@ -2079,7 +2067,7 @@ StoredFuncObj::StoredFuncObj(const Strin
@retval FALSE on success
@retval TRUE on error
*/
-bool StoredFuncObj::serialize(THD *thd, String *serialization)
+bool StoredFuncObj::do_serialize(THD *thd, String *serialization)
{
bool ret= false;
DBUG_ENTER("StoredFuncObj::serialize()");
@@ -2125,7 +2113,7 @@ bool StoredFuncObj::materialize(uint ser
@retval FALSE on success
@retval TRUE on error
*/
-bool StoredFuncObj::execute(THD *thd)
+bool StoredFuncObj::do_execute(THD *thd)
{
DBUG_ENTER("StoredFuncObj::execute()");
drop(thd);
@@ -2189,7 +2177,7 @@ EventObj::EventObj(const String *db_name
@retval FALSE on success
@retval TRUE on error
*/
-bool EventObj::serialize(THD *thd, String *serialization)
+bool EventObj::do_serialize(THD *thd, String *serialization)
{
bool ret= false;
Open_tables_state open_tables_backup;
@@ -2291,7 +2279,7 @@ bool EventObj::materialize(uint serializ
@retval FALSE on success
@retval TRUE on error
*/
-bool EventObj::execute(THD *thd)
+bool EventObj::do_execute(THD *thd)
{
DBUG_ENTER("EventObj::execute()");
drop(thd);
diff -Nrup a/sql/si_objects.h b/sql/si_objects.h
--- a/sql/si_objects.h 2008-01-31 16:15:25 +01:00
+++ b/sql/si_objects.h 2008-03-26 11:46:12 +01:00
@@ -40,7 +40,7 @@ class Obj { public:
@retval FALSE on success.
@retval TRUE on error.
*/
- virtual bool serialize(THD *thd, String *serialialization) = 0;
+ virtual bool serialize(THD *thd, String *serialialization);
/**
@@ -66,13 +66,14 @@ class Obj { public:
@retval FALSE on success.
@retval TRUE on error.
*/
- virtual bool execute(THD *thd) = 0;
+ virtual bool execute(THD *thd);
public:
virtual ~Obj()
{ }
private:
+
/**
Read the object state from a given buffer and restores object state to
the point, where it can be executed.
@@ -87,6 +88,13 @@ private:
virtual bool materialize(uint serialization_version,
const String *serialialization) = 0;
+
+ /// Primitive implementing @c serialize() method.
+ virtual bool do_serialize(THD *thd, String *serialialization) = 0;
+
+ /// Primitive implementing @c execute() method.
+ virtual bool do_execute(THD *thd) = 0;
+
/**
Drop the object.
@@ -134,6 +142,32 @@ private:
const String *);
};
+
+inline
+bool Obj::execute(THD *thd)
+{
+ ulong saved_sql_mode= thd->variables.sql_mode;
+ thd->variables.sql_mode= 0;
+
+ bool ret= do_execute(thd);
+
+ thd->variables.sql_mode= saved_sql_mode;
+
+ return ret;
+}
+
+inline
+bool Obj::serialize(THD *thd, String *serialization)
+{
+ ulong saved_sql_mode= thd->variables.sql_mode;
+ thd->variables.sql_mode= 0;
+
+ bool ret= do_serialize(thd, serialization);
+
+ thd->variables.sql_mode= saved_sql_mode;
+
+ return ret;
+}
///////////////////////////////////////////////////////////////////////////