From bef6c143150fab5e2f7d4bc29ca6702ba0ab19c4 Mon Sep 17 00:00:00 2001 From: "mattiasj@client-10-129-10-147.upp.off.mysql.com" <> Date: Thu, 8 May 2008 09:41:22 +0200 Subject: [PATCH 1/2] Bug#32575 - Parse error of stmt with extended comments on slave side Problem was that mysql_create_view did not remove all comments characters when writing to binlog, resulting in parse error of stmt on slave side. Solution was to use the recreated select clause and add a generated CHECK OPTION clause if needed. --- mysql-test/r/rpl_sp.result | 2 +- mysql-test/r/rpl_view.result | 18 ++++++++++++++++-- mysql-test/t/rpl_view.test | 18 ++++++++++++++++++ sql/sql_view.cc | 8 +++++--- 4 files changed, 40 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/rpl_sp.result b/mysql-test/r/rpl_sp.result index 0fe1b4b908e..78b0f73b9cf 100644 --- a/mysql-test/r/rpl_sp.result +++ b/mysql-test/r/rpl_sp.result @@ -499,7 +499,7 @@ fetch c into var; close c; return var; end -master-bin.000001 # Query 1 # use `test`; CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select 1 as a +master-bin.000001 # Query 1 # use `test`; CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select 1 AS `a` master-bin.000001 # Query 1 # use `test`; create table t1 (a int) master-bin.000001 # Query 1 # use `test`; insert into t1 (a) values (f1()) master-bin.000001 # Query 1 # use `test`; drop view v1 diff --git a/mysql-test/r/rpl_view.result b/mysql-test/r/rpl_view.result index be7ed6e8c2a..addaba8c379 100644 --- a/mysql-test/r/rpl_view.result +++ b/mysql-test/r/rpl_view.result @@ -47,11 +47,11 @@ show binlog events limit 1,100; Log_name Pos Event_type Server_id End_log_pos Info slave-bin.000001 # Query 1 # use `test`; create table t1 (a int) slave-bin.000001 # Query 1 # use `test`; insert into t1 values (1) -slave-bin.000001 # Query 1 # use `test`; CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select a from t1 +slave-bin.000001 # Query 1 # use `test`; CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `test`.`t1`.`a` AS `a` from `test`.`t1` slave-bin.000001 # Query 1 # use `test`; insert into v1 values (2) slave-bin.000001 # Query 1 # use `test`; update v1 set a=3 where a=1 slave-bin.000001 # Query 1 # use `test`; delete from v1 where a=2 -slave-bin.000001 # Query 1 # use `test`; ALTER ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select a as b from t1 +slave-bin.000001 # Query 1 # use `test`; ALTER ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `test`.`t1`.`a` AS `b` from `test`.`t1` slave-bin.000001 # Query 1 # use `test`; drop view v1 slave-bin.000001 # Query 1 # use `test`; drop table t1 @@ -112,4 +112,18 @@ CREATE VIEW v1 AS SELECT * FROM t1; ERROR 42S01: Table 'v1' already exists DROP VIEW v1; DROP TABLE t1; +CREATE TABLE t1 (a INT); +# create view as output from mysqldump 10.11 (5.0.62) +/*!50001 CREATE ALGORITHM=UNDEFINED */ +/*!50013 DEFINER=`root`@`localhost` SQL SECURITY DEFINER */ +/*!50001 VIEW `v1` AS select `t1`.`a` AS `a` from `t1` where (`t1`.`a` < 3) */ +/*!50002 WITH CASCADED CHECK OPTION */; +SHOW CREATE VIEW v1; +View Create View +v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a` from `t1` where (`t1`.`a` < 3) WITH CASCADED CHECK OPTION +SHOW CREATE VIEW v1; +View Create View +v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a` from `t1` where (`t1`.`a` < 3) WITH CASCADED CHECK OPTION +DROP VIEW v1; +DROP TABLE t1; End of 5.0 tests diff --git a/mysql-test/t/rpl_view.test b/mysql-test/t/rpl_view.test index 21748586130..44ef0c3e1eb 100644 --- a/mysql-test/t/rpl_view.test +++ b/mysql-test/t/rpl_view.test @@ -161,4 +161,22 @@ DROP VIEW v1; DROP TABLE t1; sync_slave_with_master; +# +# Bug#32575 Parse error of stmt with extended comments on slave side +# Verify that 'CREATE VIEW' with comments is properly logged to binlog +connection master; +CREATE TABLE t1 (a INT); +--echo # create view as output from mysqldump 10.11 (5.0.62) +/*!50001 CREATE ALGORITHM=UNDEFINED */ +/*!50013 DEFINER=`root`@`localhost` SQL SECURITY DEFINER */ +/*!50001 VIEW `v1` AS select `t1`.`a` AS `a` from `t1` where (`t1`.`a` < 3) */ +/*!50002 WITH CASCADED CHECK OPTION */; +SHOW CREATE VIEW v1; +sync_slave_with_master; +SHOW CREATE VIEW v1; +connection master; +DROP VIEW v1; +DROP TABLE t1; +sync_slave_with_master; + --echo End of 5.0 tests diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 4c8e6e80c41..de92d6dc3b9 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -649,7 +649,11 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views, buff.append(')'); } buff.append(STRING_WITH_LEN(" AS ")); - buff.append(views->source.str, views->source.length); + buff.append(views->query.str, views->query.length); + if (views->with_check == VIEW_CHECK_LOCAL) + buff.append(STRING_WITH_LEN(" WITH LOCAL CHECK OPTION")); + else if (views->with_check == VIEW_CHECK_CASCADED) + buff.append(STRING_WITH_LEN(" WITH CASCADED CHECK OPTION")); Query_log_event qinfo(thd, buff.ptr(), buff.length(), 0, FALSE); mysql_bin_log.write(&qinfo); @@ -926,8 +930,6 @@ loop_out: } DBUG_RETURN(0); err: - view->query.str= NULL; - view->query.length= 0; view->md5.str= NULL; view->md5.length= 0; DBUG_RETURN(error); From 1e7be565e20100b5be68fe0476b5276362b0de73 Mon Sep 17 00:00:00 2001 From: "gshchepa/uchum@host.loc" <> Date: Mon, 12 May 2008 21:01:13 +0500 Subject: [PATCH 2/2] Fixed bug #36055: mysql_upgrade doesn't really 'upgrade' tables The REPAIR TABLE ... USE_FRM query silently corrupts data of tables with old .FRM file version. The mysql_upgrade client program or the REPAIR TABLE query (without the USE_FRM clause) can't prevent this trouble, because in the common case they don't upgrade .FRM file to compatible structure. 1. Evaluation of the REPAIR TABLE ... USE_FRM query has been modified to reject such tables with the message: "Failed repairing incompatible .FRM file". 2. REPAIR TABLE query (without USE_FRM clause) evaluation has been modified to upgrade .FRM files to current version. 3. CHECK TABLE ... FOR UPGRADE query evaluation has been modified to return error status when .FRM file has incompatible version. 4. mysql_upgrade and mysqlcheck client programs call CHECK TABLE FOR UPGRADE and REPAIR TABLE queries, so their behaviors have been changed too to upgrade .FRM files with incompatible version numbers. --- mysql-test/r/repair.result | 36 +++++++++++++++++++++++++++++++ mysql-test/std_data/bug36055.MYD | Bin 0 -> 10 bytes mysql-test/std_data/bug36055.MYI | Bin 0 -> 1024 bytes mysql-test/std_data/bug36055.frm | Bin 0 -> 8556 bytes mysql-test/t/repair.test | 30 ++++++++++++++++++++++++++ sql/handler.cc | 2 ++ sql/sql_table.cc | 7 ++++++ 7 files changed, 75 insertions(+) create mode 100644 mysql-test/std_data/bug36055.MYD create mode 100644 mysql-test/std_data/bug36055.MYI create mode 100644 mysql-test/std_data/bug36055.frm diff --git a/mysql-test/r/repair.result b/mysql-test/r/repair.result index e0548233b86..c59a5300e64 100644 --- a/mysql-test/r/repair.result +++ b/mysql-test/r/repair.result @@ -115,3 +115,39 @@ SET myisam_repair_threads=@@global.myisam_repair_threads; SET myisam_sort_buffer_size=@@global.myisam_sort_buffer_size; DROP TABLE t1; End of 4.1 tests +# Test with a saved table from 4.1 +SHOW TABLE STATUS LIKE 't1'; +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment +t1 MyISAM 9 Fixed 2 5 10 21474836479 1024 0 NULL # # NULL latin1_swedish_ci NULL +SELECT * FROM t1; +id +1 +2 +# Run CHECK TABLE, it should indicate table need a REPAIR TABLE +CHECK TABLE t1 FOR UPGRADE; +Table Op Msg_type Msg_text +test.t1 check error Table upgrade required. Please do "REPAIR TABLE `t1`" to fix it! +# REPAIR old table USE_FRM should fail +REPAIR TABLE t1 USE_FRM; +Table Op Msg_type Msg_text +t1 repair error Failed reparing incompatible .FRM file +# Run REPAIR TABLE to upgrade .frm file +REPAIR TABLE t1; +Table Op Msg_type Msg_text +test.t1 repair status OK +SHOW TABLE STATUS LIKE 't1'; +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment +t1 MyISAM 10 Fixed 2 7 14 1970324836974591 1024 0 NULL # # NULL latin1_swedish_ci NULL +SELECT * FROM t1; +id +1 +2 +REPAIR TABLE t1 USE_FRM; +Table Op Msg_type Msg_text +test.t1 repair warning Number of rows changed from 0 to 2 +test.t1 repair status OK +SELECT * FROM t1; +id +1 +2 +DROP TABLE t1; diff --git a/mysql-test/std_data/bug36055.MYD b/mysql-test/std_data/bug36055.MYD new file mode 100644 index 0000000000000000000000000000000000000000..4932a077113422a51094903375c0a546ada42c39 GIT binary patch literal 10 Qcmey%$iTqxmkCG!01oZ}{r~^~ literal 0 HcmV?d00001 diff --git a/mysql-test/std_data/bug36055.MYI b/mysql-test/std_data/bug36055.MYI new file mode 100644 index 0000000000000000000000000000000000000000..531c505c1028795e70995dec6d30e2c800b59b67 GIT binary patch literal 1024 zcmezOkDZZ$fl-NJ149ZBg8>Jal>86jF)%@C7{&A-3LpY3FmWyz12=8r0F>i{$^-3% z01wg6D`9L9jm}4wgRtRtVoITkumZWrSOmxi`-g=Yt`Oo~I2X)-x{U?h@2ILqd7~jP H#6ti8q+1cs literal 0 HcmV?d00001 diff --git a/mysql-test/std_data/bug36055.frm b/mysql-test/std_data/bug36055.frm new file mode 100644 index 0000000000000000000000000000000000000000..11c9cb31dade18c5b2f5cfda4af970146f357818 GIT binary patch literal 8556 zcmeI&F%H5o429w6q?KA_VL&V_U75<%b8v_*l{f?^Cm0C=Dhu6O>G$HqN}}Xjk|mds->frm_version != FRM_VER_TRUE_VARCHAR) + return HA_ADMIN_NEEDS_ALTER; return check_for_upgrade(check_opt); } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 9e1a8151e3a..f1de63892d5 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2118,6 +2118,13 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list, const char **ext= table->file->bas_ext(); MY_STAT stat_info; + if (table->s->frm_version != FRM_VER_TRUE_VARCHAR) + { + error= send_check_errmsg(thd, table_list, "repair", + "Failed reparing incompatible .FRM file"); + goto end; + } + /* Check if this is a table type that stores index and data separately, like ISAM or MyISAM. We assume fixed order of engine file name