From a8b8544a03f56a6a2c6357a7ea137cbb17a6372b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Thu, 4 Jun 2015 13:00:53 +0300 Subject: [PATCH 1/8] MDEV-7906: InnoDB: Failing assertion: prebuilt->sql_stat_start || trx->state == 1 on concurrent multi-table update Analysis: Problem is that SQL-layer calls handler API after storage engine has already returned error state. InnoDB does internal rollback when it notices transaction error (e.g. lock wait timeout, deadlock, etc.) and after this transaction is not naturally in correct state to continue. Fix: Do not continue fetch operations if transaction is not started. --- storage/innobase/handler/ha_innodb.cc | 6 +++++- storage/xtradb/handler/ha_innodb.cc | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index a7854af7014..401a14e62da 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -93,7 +93,6 @@ extern "C" { #include "ibuf0ibuf.h" enum_tx_isolation thd_get_trx_isolation(const THD* thd); - } #include "ha_innodb.h" @@ -6299,6 +6298,11 @@ ha_innobase::general_fetch( DBUG_ENTER("general_fetch"); + /* If transaction is not startted do not continue, instead return a error code. */ + if(!(prebuilt->sql_stat_start || (prebuilt->trx && prebuilt->trx->conc_state == 1))) { + DBUG_RETURN(HA_ERR_END_OF_FILE); + } + ut_a(prebuilt->trx == thd_to_trx(user_thd)); innodb_srv_conc_enter_innodb(prebuilt->trx); diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index ac883e9ee6b..5034e7e70e1 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -102,7 +102,6 @@ extern "C" { #include "ibuf0ibuf.h" enum_tx_isolation thd_get_trx_isolation(const THD* thd); - } #include "ha_innodb.h" @@ -7327,6 +7326,11 @@ ha_innobase::general_fetch( DBUG_ENTER("general_fetch"); + /* If transaction is not startted do not continue, instead return a error code. */ + if(!(prebuilt->sql_stat_start || (prebuilt->trx && prebuilt->trx->state == 1))) { + DBUG_RETURN(HA_ERR_END_OF_FILE); + } + if (UNIV_UNLIKELY(share->ib_table->is_corrupt && srv_pass_corrupt_table <= 1)) { DBUG_RETURN(HA_ERR_CRASHED); From 9da8a8f94690704e069b2cc99218384b6bbbd95a Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Thu, 4 Jun 2015 18:49:12 +0400 Subject: [PATCH 2/8] MDEV-7269 mysqlbinlog Don't know how to handle column type=0 meta=0 (0000)# MDEV-8267 Add /*old*/ comment into I_S.COLUMN_TYPE for old DECIMAL --- mysql-test/r/type_decimal.result | 21 ++++++ mysql-test/std_data/old_decimal/t1dec102.MYD | 1 + mysql-test/std_data/old_decimal/t1dec102.MYI | Bin 0 -> 1024 bytes mysql-test/std_data/old_decimal/t1dec102.frm | Bin 0 -> 8554 bytes .../binlog/r/binlog_mysqlbinlog_row.result | 65 ++++++++++++++++++ .../binlog/t/binlog_mysqlbinlog_row.test | 13 +++- mysql-test/t/type_decimal.test | 24 +++++++ sql/field.cc | 2 +- sql/log_event.cc | 6 ++ 9 files changed, 130 insertions(+), 2 deletions(-) create mode 100644 mysql-test/std_data/old_decimal/t1dec102.MYD create mode 100644 mysql-test/std_data/old_decimal/t1dec102.MYI create mode 100644 mysql-test/std_data/old_decimal/t1dec102.frm diff --git a/mysql-test/r/type_decimal.result b/mysql-test/r/type_decimal.result index f8649f030bb..cde8816dee4 100644 --- a/mysql-test/r/type_decimal.result +++ b/mysql-test/r/type_decimal.result @@ -994,3 +994,24 @@ GROUP BY t2.col0 WHERE CONCAT(t1.col1, CAST(subq.col0 AS DECIMAL)); 1 DROP TABLE t1, t2; +# +# Start of 5.5 tests +# +# +# MDEV-8267 Add /*old*/ comment into I_S.COLUMN_TYPE for old DECIMAL +# +SHOW CREATE TABLE t1dec102; +Table Create Table +t1dec102 CREATE TABLE `t1dec102` ( + `a` decimal(10,2)/*old*/ DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SHOW COLUMNS FROM t1dec102; +Field Type Null Key Default Extra +a decimal(10,2)/*old*/ YES NULL +SELECT COLUMN_NAME, DATA_TYPE, COLUMN_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='t1dec102'; +COLUMN_NAME DATA_TYPE COLUMN_TYPE +a decimal decimal(10,2)/*old*/ +DROP TABLE t1dec102; +# +# End of 5.5 tests +# diff --git a/mysql-test/std_data/old_decimal/t1dec102.MYD b/mysql-test/std_data/old_decimal/t1dec102.MYD new file mode 100644 index 00000000000..59e43854d4a --- /dev/null +++ b/mysql-test/std_data/old_decimal/t1dec102.MYD @@ -0,0 +1 @@ +ý 123.45ý 123.46ý 123.47 \ No newline at end of file diff --git a/mysql-test/std_data/old_decimal/t1dec102.MYI b/mysql-test/std_data/old_decimal/t1dec102.MYI new file mode 100644 index 0000000000000000000000000000000000000000..e0b2d4a003c290c0b3c3eb30ecfbb9170c833c11 GIT binary patch literal 1024 zcmezOkDZZ$fl-NJ149ZBg8>Jal>86jF)%}E7{&Y_3LpY3FmZJl12=8|2q-5Bl?U1j z0igvddN4MKM&~2TLD+CRF{MyNc!6AGECS>+ft0Wyd@H;bTs5Y%T1fMX}_`U%i6Y* zPA26j>a@ihHA`cyF<_TrkosL8O#~1?009ILKmY**5I_I{1Q7T?0aw{JRr)3Qmg7Qz zAbTT9tm*}4}%FWN$^;YCt VjWv8y?J3En>NzhFpC`&x^aeZy5BUH9 literal 0 HcmV?d00001 diff --git a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row.result b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row.result index fc22085496d..469e670ae9d 100644 --- a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row.result +++ b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row.result @@ -327,6 +327,18 @@ INSERT INTO t2 SET a=1; INSERT INTO t2 SET b=1; UPDATE t1, t2 SET t1.a=10, t2.a=20; DROP TABLE t1,t2; +INSERT INTO t1dec102 VALUES (-999.99); +INSERT INTO t1dec102 VALUES (0); +INSERT INTO t1dec102 VALUES (999.99); +SELECT * FROM t1dec102 ORDER BY a; +a +-999.99 +0.00 +123.45 +123.46 +123.47 +999.99 +DROP TABLE t1dec102; flush logs; /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; @@ -4131,6 +4143,59 @@ SET TIMESTAMP=1000000000/*!*/; DROP TABLE `t1`,`t2` /* generated by server */ /*!*/; # at # +#010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +BEGIN +/*!*/; +# at # +# at # +#010909 4:46:40 server id 1 end_log_pos # Table_map: `test`.`t1dec102` mapped to number # +#010909 4:46:40 server id 1 end_log_pos # Write_rows: table id # flags: STMT_END_F +### INSERT INTO `test`.`t1dec102` +### SET +### @1=!! Old DECIMAL (mysql-4.1 or earlier). Not enough metadata to display the value. # at # +#010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +#010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +BEGIN +/*!*/; +# at # +# at # +#010909 4:46:40 server id 1 end_log_pos # Table_map: `test`.`t1dec102` mapped to number # +#010909 4:46:40 server id 1 end_log_pos # Write_rows: table id # flags: STMT_END_F +### INSERT INTO `test`.`t1dec102` +### SET +### @1=!! Old DECIMAL (mysql-4.1 or earlier). Not enough metadata to display the value. # at # +#010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +#010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +BEGIN +/*!*/; +# at # +# at # +#010909 4:46:40 server id 1 end_log_pos # Table_map: `test`.`t1dec102` mapped to number # +#010909 4:46:40 server id 1 end_log_pos # Write_rows: table id # flags: STMT_END_F +### INSERT INTO `test`.`t1dec102` +### SET +### @1=!! Old DECIMAL (mysql-4.1 or earlier). Not enough metadata to display the value. # at # +#010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +#010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +DROP TABLE `t1dec102` /* generated by server */ +/*!*/; +# at # #010909 4:46:40 server id 1 end_log_pos # Rotate to master-bin.000002 pos: 4 DELIMITER ; # End of log file diff --git a/mysql-test/suite/binlog/t/binlog_mysqlbinlog_row.test b/mysql-test/suite/binlog/t/binlog_mysqlbinlog_row.test index 9b41c63d195..9609a9af384 100644 --- a/mysql-test/suite/binlog/t/binlog_mysqlbinlog_row.test +++ b/mysql-test/suite/binlog/t/binlog_mysqlbinlog_row.test @@ -438,9 +438,20 @@ INSERT INTO t2 SET b=1; UPDATE t1, t2 SET t1.a=10, t2.a=20; DROP TABLE t1,t2; +let $MYSQLD_DATADIR= `select @@datadir`; + +--copy_file std_data/old_decimal/t1dec102.frm $MYSQLD_DATADIR/test/t1dec102.frm +--copy_file std_data/old_decimal/t1dec102.MYD $MYSQLD_DATADIR/test/t1dec102.MYD +--copy_file std_data/old_decimal/t1dec102.MYI $MYSQLD_DATADIR/test/t1dec102.MYI + +INSERT INTO t1dec102 VALUES (-999.99); +INSERT INTO t1dec102 VALUES (0); +INSERT INTO t1dec102 VALUES (999.99); +SELECT * FROM t1dec102 ORDER BY a; +DROP TABLE t1dec102; + flush logs; -let $MYSQLD_DATADIR= `select @@datadir`; --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR --replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/ /exec_time=[0-9]*/exec_time=#/ /end_log_pos [0-9]*/end_log_pos #/ /# at [0-9]*/# at #/ /thread_id=[0-9]*/thread_id=#/ /table id [0-9]*/table id #/ /mapped to number [0-9]*/mapped to number #/ /server v [^ ]*/server v #.##.##/ /(@[0-9]*=[0-9]*[.][0-9]{1,3})[0-9e+-]*[^ ]*(.*(FLOAT|DOUBLE).*[*].)/\1...\2/ --exec $MYSQL_BINLOG --base64-output=decode-rows -v -v $MYSQLD_DATADIR/master-bin.000001 diff --git a/mysql-test/t/type_decimal.test b/mysql-test/t/type_decimal.test index 1d4ef345747..659e75270ca 100644 --- a/mysql-test/t/type_decimal.test +++ b/mysql-test/t/type_decimal.test @@ -583,3 +583,27 @@ JOIN WHERE CONCAT(t1.col1, CAST(subq.col0 AS DECIMAL)); DROP TABLE t1, t2; + + +--echo # +--echo # Start of 5.5 tests +--echo # + +--echo # +--echo # MDEV-8267 Add /*old*/ comment into I_S.COLUMN_TYPE for old DECIMAL +--echo # + +let $MYSQLD_DATADIR= `select @@datadir`; + +--copy_file std_data/old_decimal/t1dec102.frm $MYSQLD_DATADIR/test/t1dec102.frm +--copy_file std_data/old_decimal/t1dec102.MYD $MYSQLD_DATADIR/test/t1dec102.MYD +--copy_file std_data/old_decimal/t1dec102.MYI $MYSQLD_DATADIR/test/t1dec102.MYI + +SHOW CREATE TABLE t1dec102; +SHOW COLUMNS FROM t1dec102; +SELECT COLUMN_NAME, DATA_TYPE, COLUMN_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='t1dec102'; +DROP TABLE t1dec102; + +--echo # +--echo # End of 5.5 tests +--echo # diff --git a/sql/field.cc b/sql/field.cc index 52a490921b8..68daba3922d 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -2483,7 +2483,7 @@ void Field_decimal::sql_type(String &res) const if (dec) tmp--; res.length(cs->cset->snprintf(cs,(char*) res.ptr(),res.alloced_length(), - "decimal(%d,%d)",tmp,dec)); + "decimal(%d,%d)/*old*/",tmp,dec)); add_zerofill_and_unsigned(res); } diff --git a/sql/log_event.cc b/sql/log_event.cc index d04ac1e1a44..e63884eaeab 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -2192,6 +2192,12 @@ log_event_print_value(IO_CACHE *file, const uchar *ptr, my_snprintf(typestr, typestr_length, "STRING(%d)", length); return my_b_write_quoted_with_length(file, ptr, length); + case MYSQL_TYPE_DECIMAL: + my_b_printf(file, + "!! Old DECIMAL (mysql-4.1 or earlier). " + "Not enough metadata to display the value. "); + break; + default: { char tmp[5]; From 08fa02cf227a632ed787357357d6116b72c6d5e6 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Thu, 4 Jun 2015 18:51:30 +0400 Subject: [PATCH 3/8] Some MYD files (e.g. in mysql-test/std_data) could erroneously be treated by git as text files. Marking all MyISAM files as binary in .gitattributes: (*.frm, *.MYD, *.MYI) --- .gitattributes | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitattributes b/.gitattributes index 60b9a3481aa..342dad5646b 100644 --- a/.gitattributes +++ b/.gitattributes @@ -16,6 +16,9 @@ # Denote all files that are truly binary and should not be modified. *.png binary *.jpg binary +*.frm binary +*.MYD binary +*.MYI binary *.c diff=cpp *.h diff=cpp From a477cd175476b26e5bc0090b580e9b590b17e29a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vicen=C8=9Biu=20Ciorbaru?= Date: Wed, 3 Jun 2015 23:31:05 +0300 Subject: [PATCH 4/8] MDEV-6500: Stale data returned after TRUNCATE PARTITION operation When truncating a table's partition, we also need to invalidate the query cache for it. --- mysql-test/r/truncate-stale-6500.result | 33 +++++++++++++++++++++++++ mysql-test/t/truncate-stale-6500.test | 32 ++++++++++++++++++++++++ sql/sql_partition_admin.cc | 11 +++++++-- 3 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 mysql-test/r/truncate-stale-6500.result create mode 100644 mysql-test/t/truncate-stale-6500.test diff --git a/mysql-test/r/truncate-stale-6500.result b/mysql-test/r/truncate-stale-6500.result new file mode 100644 index 00000000000..b6222716953 --- /dev/null +++ b/mysql-test/r/truncate-stale-6500.result @@ -0,0 +1,33 @@ +SET GLOBAL query_cache_size=1024*1024*8; +CREATE TABLE `test` ( +`uniqueId` INT NOT NULL, +`partitionId` INT NOT NULL, +PRIMARY KEY (`uniqueId`,`partitionId`) +) ENGINE=InnoDB PARTITION BY LIST (partitionId) ( +PARTITION p01 VALUES IN (1), +PARTITION p02 VALUES IN (2) +); +INSERT INTO `test`(`uniqueId`,`partitionId`) VALUES(407237055, 2); +SELECT * FROM `test`; +uniqueId partitionId +407237055 2 +#Confirms 1 row in partition 'p02' +SELECT TABLE_NAME, PARTITION_NAME, TABLE_ROWS FROM information_schema.PARTITIONS where TABLE_NAME = 'test'; +TABLE_NAME PARTITION_NAME TABLE_ROWS +test p01 0 +test p02 1 +ALTER TABLE `test` TRUNCATE PARTITION `p02`; +#Confirms no more rows in partition 'p02' +SELECT TABLE_NAME, PARTITION_NAME, TABLE_ROWS FROM information_schema.PARTITIONS where TABLE_NAME = 'test'; +TABLE_NAME PARTITION_NAME TABLE_ROWS +test p01 0 +test p02 0 +#Before the patch, this returned the previously existing values. +SELECT * FROM `test`; +uniqueId partitionId +SELECT SQL_CACHE * FROM `test`; +uniqueId partitionId +SELECT SQL_NO_CACHE * FROM `test`; +uniqueId partitionId +DROP TABLE test; +SET GLOBAL query_cache_size=DEFAULT; diff --git a/mysql-test/t/truncate-stale-6500.test b/mysql-test/t/truncate-stale-6500.test new file mode 100644 index 00000000000..47dffb1966d --- /dev/null +++ b/mysql-test/t/truncate-stale-6500.test @@ -0,0 +1,32 @@ +--source include/have_innodb.inc +--source include/have_partition.inc + +SET GLOBAL query_cache_size=1024*1024*8; +CREATE TABLE `test` ( + `uniqueId` INT NOT NULL, + `partitionId` INT NOT NULL, + PRIMARY KEY (`uniqueId`,`partitionId`) +) ENGINE=InnoDB PARTITION BY LIST (partitionId) ( + PARTITION p01 VALUES IN (1), + PARTITION p02 VALUES IN (2) +); + + +INSERT INTO `test`(`uniqueId`,`partitionId`) VALUES(407237055, 2); + +SELECT * FROM `test`; + +--echo #Confirms 1 row in partition 'p02' +SELECT TABLE_NAME, PARTITION_NAME, TABLE_ROWS FROM information_schema.PARTITIONS where TABLE_NAME = 'test'; +ALTER TABLE `test` TRUNCATE PARTITION `p02`; + +--echo #Confirms no more rows in partition 'p02' +SELECT TABLE_NAME, PARTITION_NAME, TABLE_ROWS FROM information_schema.PARTITIONS where TABLE_NAME = 'test'; + +--echo #Before the patch, this returned the previously existing values. +SELECT * FROM `test`; +SELECT SQL_CACHE * FROM `test`; +SELECT SQL_NO_CACHE * FROM `test`; + +DROP TABLE test; +SET GLOBAL query_cache_size=DEFAULT; diff --git a/sql/sql_partition_admin.cc b/sql/sql_partition_admin.cc index a03dcc5c16e..a104676a3ff 100644 --- a/sql/sql_partition_admin.cc +++ b/sql/sql_partition_admin.cc @@ -174,9 +174,16 @@ bool Alter_table_truncate_partition_statement::execute(THD *thd) log. The exception is a unimplemented truncate method or failure before any call to handler::truncate() is done. Also, it is logged in statement format, regardless of the binlog format. + + Since we've changed data within the table, we also have to invalidate + the query cache for it. */ - if (error != HA_ERR_WRONG_COMMAND && binlog_stmt) - error|= write_bin_log(thd, !error, thd->query(), thd->query_length()); + if (error != HA_ERR_WRONG_COMMAND) + { + query_cache_invalidate3(thd, first_table, FALSE); + if (binlog_stmt) + error|= write_bin_log(thd, !error, thd->query(), thd->query_length()); + } /* A locked table ticket was upgraded to a exclusive lock. After the From 1ff423dfc089058d10945e728028f89c8b37b32f Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Thu, 4 Jun 2015 21:12:29 +0400 Subject: [PATCH 5/8] MDEV-8243 configure defines to empty string, not 1 --- config.h.cmake | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/config.h.cmake b/config.h.cmake index 34f77dba050..73dc918bc3c 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -203,7 +203,7 @@ #cmakedefine HAVE_MADVISE 1 #cmakedefine HAVE_DECL_MADVISE 1 #cmakedefine HAVE_DECL_TGOTO 1 -#cmakedefine HAVE_DECL_MHA_MAPSIZE_VA +#cmakedefine HAVE_DECL_MHA_MAPSIZE_VA 1 #cmakedefine HAVE_MALLINFO 1 #cmakedefine HAVE_MEMCPY 1 #cmakedefine HAVE_MEMMOVE 1 @@ -396,7 +396,7 @@ #cmakedefine SOCKET_SIZE_TYPE @SOCKET_SIZE_TYPE@ -#cmakedefine HAVE_MBSTATE_T +#cmakedefine HAVE_MBSTATE_T 1 #define MAX_INDEXES 64 @@ -431,15 +431,15 @@ #cmakedefine HAVE_WCTYPE_H 1 #cmakedefine HAVE_WCHAR_H 1 #cmakedefine HAVE_LANGINFO_H 1 -#cmakedefine HAVE_MBRLEN -#cmakedefine HAVE_MBSCMP -#cmakedefine HAVE_MBSRTOWCS -#cmakedefine HAVE_WCRTOMB -#cmakedefine HAVE_MBRTOWC -#cmakedefine HAVE_WCSCOLL -#cmakedefine HAVE_WCSDUP -#cmakedefine HAVE_WCWIDTH -#cmakedefine HAVE_WCTYPE +#cmakedefine HAVE_MBRLEN 1 +#cmakedefine HAVE_MBSCMP 1 +#cmakedefine HAVE_MBSRTOWCS 1 +#cmakedefine HAVE_WCRTOMB 1 +#cmakedefine HAVE_MBRTOWC 1 +#cmakedefine HAVE_WCSCOLL 1 +#cmakedefine HAVE_WCSDUP 1 +#cmakedefine HAVE_WCWIDTH 1 +#cmakedefine HAVE_WCTYPE 1 #cmakedefine HAVE_ISWLOWER 1 #cmakedefine HAVE_ISWUPPER 1 #cmakedefine HAVE_TOWLOWER 1 @@ -453,7 +453,7 @@ #cmakedefine HAVE_STRCASECMP 1 #cmakedefine HAVE_STRNCASECMP 1 #cmakedefine HAVE_STRDUP 1 -#cmakedefine HAVE_LANGINFO_CODESET +#cmakedefine HAVE_LANGINFO_CODESET 1 #cmakedefine HAVE_TCGETATTR 1 #cmakedefine HAVE_FLOCKFILE 1 From af2256ff72c21a63ca0d786fa161386202a0150a Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Wed, 3 Jun 2015 13:59:58 +0400 Subject: [PATCH 6/8] MDEV-7207 - ALTER VIEW does not change ALGORITM Fixed that ALTER VIEW ALGORITHM=UNDEFINED behaved as if algorithm was not specified. --- mysql-test/r/view.result | 18 ++++++++++++++++++ mysql-test/t/view.test | 13 +++++++++++++ sql/sql_view.cc | 2 +- sql/sql_yacc.yy | 2 +- sql/table.h | 2 ++ 5 files changed, 35 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index ee9779a2c23..cbacb2c1ef8 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -5411,6 +5411,24 @@ create view v2 as select t2.* from (t2 left join v1 using (id)); update t3 left join v2 using (id) set flag=flag+1; drop view v2, v1; drop table t1, t2, t3; +# +# MDEV-7207 - ALTER VIEW does not change ALGORITM +# +create table t1 (a int, b int); +create algorithm=temptable view v2 (c) as select b+1 from t1; +show create view v2; +View Create View character_set_client collation_connection +v2 CREATE ALGORITHM=TEMPTABLE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select (`t1`.`b` + 1) AS `c` from `t1` latin1 latin1_swedish_ci +alter algorithm=undefined view v2 (c) as select b+1 from t1; +show create view v2; +View Create View character_set_client collation_connection +v2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select (`t1`.`b` + 1) AS `c` from `t1` latin1 latin1_swedish_ci +alter algorithm=merge view v2 (c) as select b+1 from t1; +show create view v2; +View Create View character_set_client collation_connection +v2 CREATE ALGORITHM=MERGE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select (`t1`.`b` + 1) AS `c` from `t1` latin1 latin1_swedish_ci +drop view v2; +drop table t1; # ----------------------------------------------------------------- # -- End of 5.5 tests. # ----------------------------------------------------------------- diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index b96799215fe..0432db0ba31 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -5367,6 +5367,19 @@ update t3 left join v2 using (id) set flag=flag+1; drop view v2, v1; drop table t1, t2, t3; +--echo # +--echo # MDEV-7207 - ALTER VIEW does not change ALGORITM +--echo # +create table t1 (a int, b int); +create algorithm=temptable view v2 (c) as select b+1 from t1; +show create view v2; +alter algorithm=undefined view v2 (c) as select b+1 from t1; +show create view v2; +alter algorithm=merge view v2 (c) as select b+1 from t1; +show create view v2; +drop view v2; +drop table t1; + --echo # ----------------------------------------------------------------- --echo # -- End of 5.5 tests. --echo # ----------------------------------------------------------------- diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 47b238715ac..255f876e02a 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -228,7 +228,7 @@ fill_defined_view_parts (THD *thd, TABLE_LIST *view) view->definer.user= decoy.definer.user; lex->definer= &view->definer; } - if (lex->create_view_algorithm == DTYPE_ALGORITHM_UNDEFINED) + if (lex->create_view_algorithm == VIEW_ALGORITHM_INHERIT) lex->create_view_algorithm= (uint8) decoy.algorithm; if (lex->create_view_suid == VIEW_SUID_DEFAULT) lex->create_view_suid= decoy.view_suid ? diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 5b2f10b278c..ec246ae8079 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -6552,7 +6552,7 @@ alter: my_error(ER_SP_BADSTATEMENT, MYF(0), "ALTER VIEW"); MYSQL_YYABORT; } - lex->create_view_algorithm= DTYPE_ALGORITHM_UNDEFINED; + lex->create_view_algorithm= VIEW_ALGORITHM_INHERIT; lex->create_view_mode= VIEW_ALTER; } view_tail diff --git a/sql/table.h b/sql/table.h index 832445486ab..17fdd4aba15 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1446,6 +1446,8 @@ typedef struct st_schema_table #define DT_PHASES_MATERIALIZE (DT_COMMON | DT_MATERIALIZE) #define VIEW_ALGORITHM_UNDEFINED 0 +/* Special value for ALTER VIEW: inherit original algorithm. */ +#define VIEW_ALGORITHM_INHERIT DTYPE_VIEW #define VIEW_ALGORITHM_MERGE (DTYPE_VIEW | DTYPE_MERGE) #define VIEW_ALGORITHM_TMPTABLE (DTYPE_VIEW | DTYPE_MATERIALIZE) From b611ac06a736a5d8d4fcf0d81316343745d4113d Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Wed, 3 Jun 2015 14:30:09 +0400 Subject: [PATCH 7/8] MDEV-6236 - [PATCH] mysql_tzinfo_to_sql may produce invalid SQL Factory timezone is supposed "For companies who don't want to put time zone specification in their installation procedures. When users run date, they'll get the message. Also useful for the "comp.sources" version." This "message" is exposed as timezone abbreviation, which is supposed to be short and thus may cause generated INSERT statements to fail. Do not attempt to load Factory timezone. --- mysql-test/r/mysql_tzinfo_to_sql_symlink.result | 9 +++++++++ mysql-test/t/mysql_tzinfo_to_sql_symlink.test | 11 +++++++++++ sql/tztime.cc | 3 ++- 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/mysql_tzinfo_to_sql_symlink.result b/mysql-test/r/mysql_tzinfo_to_sql_symlink.result index dda732937ee..f127e756987 100644 --- a/mysql-test/r/mysql_tzinfo_to_sql_symlink.result +++ b/mysql-test/r/mysql_tzinfo_to_sql_symlink.result @@ -60,3 +60,12 @@ INSERT INTO time_zone_transition_type (Time_zone_id, Transition_type_id, Offset, # TRUNCATE TABLE time_zone_leap_second; ALTER TABLE time_zone_leap_second ORDER BY Transition_time; +# +# MDEV-6236 - [PATCH] mysql_tzinfo_to_sql may produce invalid SQL +# +TRUNCATE TABLE time_zone; +TRUNCATE TABLE time_zone_name; +TRUNCATE TABLE time_zone_transition; +TRUNCATE TABLE time_zone_transition_type; +ALTER TABLE time_zone_transition ORDER BY Time_zone_id, Transition_time; +ALTER TABLE time_zone_transition_type ORDER BY Time_zone_id, Transition_type_id; diff --git a/mysql-test/t/mysql_tzinfo_to_sql_symlink.test b/mysql-test/t/mysql_tzinfo_to_sql_symlink.test index 1ba4e91be3c..8ca82b87e30 100644 --- a/mysql-test/t/mysql_tzinfo_to_sql_symlink.test +++ b/mysql-test/t/mysql_tzinfo_to_sql_symlink.test @@ -37,3 +37,14 @@ # --exec rm -rf $MYSQLTEST_VARDIR/zoneinfo + +--echo # +--echo # MDEV-6236 - [PATCH] mysql_tzinfo_to_sql may produce invalid SQL +--echo # +--exec mkdir $MYSQLTEST_VARDIR/zoneinfo +--copy_file std_data/zoneinfo/GMT $MYSQLTEST_VARDIR/zoneinfo/Factory + +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +--exec $MYSQL_TZINFO_TO_SQL $MYSQLTEST_VARDIR/zoneinfo 2>&1 + +--exec rm -rf $MYSQLTEST_VARDIR/zoneinfo diff --git a/sql/tztime.cc b/sql/tztime.cc index da23d6fc8c2..079611504cc 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -2521,7 +2521,8 @@ scan_tz_dir(char * name_end, uint symlink_recursion_level, uint verbose) for (i= 0; i < cur_dir->number_off_files; i++) { - if (cur_dir->dir_entry[i].name[0] != '.') + if (cur_dir->dir_entry[i].name[0] != '.' && + strcmp(cur_dir->dir_entry[i].name, "Factory")) { name_end_tmp= strmake(name_end, cur_dir->dir_entry[i].name, FN_REFLEN - (name_end - fullname)); From a2bb9d263993783923ba8fc83d5b9ddd36dbe09d Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Thu, 4 Jun 2015 16:04:05 +0400 Subject: [PATCH 8/8] MDEV-7505 - Too large scale in DECIMAL dynamic column getter crashes mysqld Server may crash if sanity checks of COLUMN_GET() fail. COLUMN_GET() description generator expects parent CAST item, which may not have been created due to failure of sanity checks. Then further attempt to report an error may crash the server. Fixed COLUMN_GET() description generator to handle such case. --- mysql-test/r/dyncol.result | 6 ++++++ mysql-test/t/dyncol.test | 6 ++++++ sql/item_strfunc.cc | 10 ++++++++++ 3 files changed, 22 insertions(+) diff --git a/mysql-test/r/dyncol.result b/mysql-test/r/dyncol.result index aacb5363717..ca6908f449c 100644 --- a/mysql-test/r/dyncol.result +++ b/mysql-test/r/dyncol.result @@ -1444,3 +1444,9 @@ column_get(column_create(1, "18446744073709552001" as char), 1 as int) Warnings: Warning 1918 Encountered illegal value '18446744073709552001' when converting to INT Note 1105 Cast to signed converted positive out-of-range integer to it's negative complement +# +# MDEV-7505 - Too large scale in DECIMAL dynamic column getter crashes +# mysqld +# +SELECT COLUMN_GET(`x`, 'y' AS DECIMAL(5,34)); +ERROR 42000: Too big scale 34 specified for ''y''. Maximum is 30. diff --git a/mysql-test/t/dyncol.test b/mysql-test/t/dyncol.test index 68e10a5fffe..f0d9467420a 100644 --- a/mysql-test/t/dyncol.test +++ b/mysql-test/t/dyncol.test @@ -643,3 +643,9 @@ SELECT # select column_get(column_create(1, "18446744073709552001" as char), 1 as int); +--echo # +--echo # MDEV-7505 - Too large scale in DECIMAL dynamic column getter crashes +--echo # mysqld +--echo # +--error ER_TOO_BIG_SCALE +SELECT COLUMN_GET(`x`, 'y' AS DECIMAL(5,34)); diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index eedf1499403..aca66fc29e0 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -4467,6 +4467,16 @@ null: void Item_dyncol_get::print(String *str, enum_query_type query_type) { + /* + Parent cast doesn't exist yet, only print dynamic column name. This happens + when called from create_func_cast() / wrong_precision_error(). + */ + if (!str->length()) + { + args[1]->print(str, query_type); + return; + } + /* see create_func_dyncol_get */ DBUG_ASSERT(str->length() >= 5); DBUG_ASSERT(strncmp(str->ptr() + str->length() - 5, "cast(", 5) == 0);