diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2019-08-29 08:41:53 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2019-08-29 12:00:12 +0300 |
commit | 1a3c36595320bd4cf94ba5ab6c5127129269af67 (patch) | |
tree | 72954842785e24025db2b2638940251993142989 | |
parent | e41eb044f19e3ee9b881344565924dd6b9d20e1a (diff) | |
parent | 5e9b34191e395ced03fbbbe6aedc07b0a7293984 (diff) | |
download | mariadb-git-1a3c36595320bd4cf94ba5ab6c5127129269af67.tar.gz |
Merge 10.2 into 10.3
25 files changed, 637 insertions, 91 deletions
diff --git a/cmake/build_configurations/mysql_release.cmake b/cmake/build_configurations/mysql_release.cmake index 995621e0abe..f77907481a4 100644 --- a/cmake/build_configurations/mysql_release.cmake +++ b/cmake/build_configurations/mysql_release.cmake @@ -121,6 +121,7 @@ ENDIF() IF(UNIX) SET(WITH_EXTRA_CHARSETS all CACHE STRING "") + SET(PLUGIN_AUTH_PAM YES) IF(CMAKE_SYSTEM_NAME STREQUAL "Linux") IF(NOT IGNORE_AIO_CHECK) diff --git a/cmake/cpack_rpm.cmake b/cmake/cpack_rpm.cmake index f846684896d..696d55cea69 100644 --- a/cmake/cpack_rpm.cmake +++ b/cmake/cpack_rpm.cmake @@ -37,7 +37,8 @@ IF(CMAKE_VERSION VERSION_LESS "3.6.0") SET(CPACK_PACKAGE_FILE_NAME "${CPACK_RPM_PACKAGE_NAME}-${VERSION}-${RPM}-${CMAKE_SYSTEM_PROCESSOR}") ELSE() SET(CPACK_RPM_FILE_NAME "RPM-DEFAULT") - SET(CPACK_RPM_DEBUGINFO_PACKAGE ON CACHE INTERNAL "") + OPTION(CPACK_RPM_DEBUGINFO_PACKAGE "" ON) + MARK_AS_ADVANCED(CPACK_RPM_DEBUGINFO_PACKAGE) ENDIF() SET(CPACK_RPM_PACKAGE_RELEASE "1%{?dist}") diff --git a/include/my_time.h b/include/my_time.h index e18e6eb1259..7c8f3ce909b 100644 --- a/include/my_time.h +++ b/include/my_time.h @@ -120,7 +120,7 @@ longlong number_to_datetime(longlong nr, ulong sec_part, MYSQL_TIME *time_res, static inline longlong double_to_datetime(double nr, MYSQL_TIME *ltime, ulonglong flags, int *cut) { - if (nr < 0 || nr > LONGLONG_MAX) + if (nr < 0 || nr > (double)LONGLONG_MAX) nr= (double)LONGLONG_MAX; return number_to_datetime((longlong) floor(nr), (ulong)((nr-floor(nr))*TIME_SECOND_PART_FACTOR), diff --git a/mysql-test/main/constraints.result b/mysql-test/main/constraints.result index 0b7577dd3ac..24f8417d313 100644 --- a/mysql-test/main/constraints.result +++ b/mysql-test/main/constraints.result @@ -129,6 +129,61 @@ t CREATE TABLE `t` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP table test.t; SET @@SQL_MODE=@OLD_SQL_MODE; +# +# MDEV-16932 - ASAN heap-use-after-free in my_charlen_utf8 / +# my_well_formed_char_length_utf8 on 2nd execution of SP with +# ALTER trying to add bad CHECK +# +CREATE TABLE t1 (a INT); +CREATE PROCEDURE sp() ALTER TABLE t1 ADD CONSTRAINT CHECK (b > 0); +CALL sp; +ERROR 42S22: Unknown column 'b' in 'CHECK' +CALL sp; +ERROR 42S22: Unknown column 'b' in 'CHECK' +CALL sp; +ERROR 42S22: Unknown column 'b' in 'CHECK' +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +alter table t1 add column b int; +CALL sp; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL, + CONSTRAINT `CONSTRAINT_1` CHECK (`b` > 0) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +CALL sp; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL, + CONSTRAINT `CONSTRAINT_1` CHECK (`b` > 0), + CONSTRAINT `CONSTRAINT_2` CHECK (`b` > 0) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP PROCEDURE sp; +DROP TABLE t1; +CREATE TABLE t1 (a INT); +CREATE PROCEDURE sp() ALTER TABLE t1 ADD CONSTRAINT CHECK (b > 0); +CALL sp; +ERROR 42S22: Unknown column 'b' in 'CHECK' +alter table t1 add column b int, add constraint check (b < 10); +CALL sp; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL, + CONSTRAINT `CONSTRAINT_1` CHECK (`b` < 10), + CONSTRAINT `CONSTRAINT_2` CHECK (`b` > 0) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP PROCEDURE sp; +DROP TABLE t1; +# End of 10.2 tests create table t1 (a int check (a>10)) select 100 as 'a'; show create table t1; Table Create Table diff --git a/mysql-test/main/constraints.test b/mysql-test/main/constraints.test index d7a5b41d708..2f4dadcee9d 100644 --- a/mysql-test/main/constraints.test +++ b/mysql-test/main/constraints.test @@ -116,6 +116,43 @@ SHOW CREATE TABLE t; DROP table test.t; SET @@SQL_MODE=@OLD_SQL_MODE; +--echo # +--echo # MDEV-16932 - ASAN heap-use-after-free in my_charlen_utf8 / +--echo # my_well_formed_char_length_utf8 on 2nd execution of SP with +--echo # ALTER trying to add bad CHECK +--echo # + +CREATE TABLE t1 (a INT); +CREATE PROCEDURE sp() ALTER TABLE t1 ADD CONSTRAINT CHECK (b > 0); +--error ER_BAD_FIELD_ERROR +CALL sp; +--error ER_BAD_FIELD_ERROR +CALL sp; +--error ER_BAD_FIELD_ERROR +CALL sp; +show create table t1; +alter table t1 add column b int; +CALL sp; +show create table t1; +CALL sp; +show create table t1; +# Cleanup +DROP PROCEDURE sp; +DROP TABLE t1; + +CREATE TABLE t1 (a INT); +CREATE PROCEDURE sp() ALTER TABLE t1 ADD CONSTRAINT CHECK (b > 0); +--error ER_BAD_FIELD_ERROR +CALL sp; +alter table t1 add column b int, add constraint check (b < 10); +CALL sp; +show create table t1; +# Cleanup +DROP PROCEDURE sp; +DROP TABLE t1; + +--echo # End of 10.2 tests + # # Check that we don't lose constraints as part of CREATE ... SELECT # diff --git a/mysql-test/main/type_date.result b/mysql-test/main/type_date.result index 4b5a0ad63a0..b5225a591ce 100644 --- a/mysql-test/main/type_date.result +++ b/mysql-test/main/type_date.result @@ -872,12 +872,14 @@ SELECT group_concat(d1/(CASE 'b' WHEN 'j' THEN 'c' END)) FROM v1 GROUP BY greatest(pk, 0, d2); group_concat(d1/(CASE 'b' WHEN 'j' THEN 'c' END)) NULL +NULL Warnings: Warning 1292 Incorrect datetime value: '1' for column `test`.`t1`.`pk` at row 1 Warning 1292 Incorrect datetime value: '2' for column `test`.`t1`.`pk` at row 1 Warning 1292 Incorrect datetime value: '1' for column `test`.`t1`.`pk` at row 1 Warning 1292 Incorrect datetime value: '1' for column `test`.`t1`.`pk` at row 1 Warning 1292 Incorrect datetime value: '2' for column `test`.`t1`.`pk` at row 2 +Warning 1292 Incorrect datetime value: '2' for column `test`.`t1`.`pk` at row 2 CREATE TABLE t2 AS SELECT greatest(pk, 0, d2) AS c1 FROM t1 LIMIT 0; SHOW CREATE TABLE t2; Table Create Table @@ -888,6 +890,37 @@ DROP TABLE t2; DROP VIEW v1; DROP TABLE t1; # +# MDEV-19699 Server crashes in Item_null_result::field_type upon SELECT with ROLLUP on constant table +# +CREATE TABLE t1 (d DATE) ENGINE=MyISAM; +INSERT INTO t1 VALUES ('1999-11-04'); +SELECT d FROM t1 GROUP BY d WITH ROLLUP HAVING d > '1990-01-01'; +d +1999-11-04 +DROP TABLE t1; +# +# MDEV-20431 GREATEST(int_col,date_col) returns wrong results in a view +# +CREATE TABLE t1 (pk INT NOT NULL, d DATE NOT NULL); +CREATE VIEW v1 AS SELECT * FROM t1; +INSERT INTO t1 VALUES (1,'2018-06-22'),(2,'2018-07-11'); +SELECT GREATEST(pk, d) FROM t1; +GREATEST(pk, d) +2018-06-22 +2018-07-11 +Warnings: +Warning 1292 Incorrect datetime value: '1' for column `test`.`t1`.`pk` at row 1 +Warning 1292 Incorrect datetime value: '2' for column `test`.`t1`.`pk` at row 2 +SELECT GREATEST(pk, d) FROM v1; +GREATEST(pk, d) +2018-06-22 +2018-07-11 +Warnings: +Warning 1292 Incorrect datetime value: '1' for column `test`.`t1`.`pk` at row 1 +Warning 1292 Incorrect datetime value: '2' for column `test`.`t1`.`pk` at row 2 +DROP VIEW v1; +DROP TABLE t1; +# # End of 10.1 tests # # diff --git a/mysql-test/main/type_date.test b/mysql-test/main/type_date.test index befee57183d..834fad65d4d 100644 --- a/mysql-test/main/type_date.test +++ b/mysql-test/main/type_date.test @@ -606,6 +606,30 @@ DROP TABLE t2; DROP VIEW v1; DROP TABLE t1; + +--echo # +--echo # MDEV-19699 Server crashes in Item_null_result::field_type upon SELECT with ROLLUP on constant table +--echo # + +CREATE TABLE t1 (d DATE) ENGINE=MyISAM; +INSERT INTO t1 VALUES ('1999-11-04'); +SELECT d FROM t1 GROUP BY d WITH ROLLUP HAVING d > '1990-01-01'; +DROP TABLE t1; + + +--echo # +--echo # MDEV-20431 GREATEST(int_col,date_col) returns wrong results in a view +--echo # + +CREATE TABLE t1 (pk INT NOT NULL, d DATE NOT NULL); +CREATE VIEW v1 AS SELECT * FROM t1; +INSERT INTO t1 VALUES (1,'2018-06-22'),(2,'2018-07-11'); +SELECT GREATEST(pk, d) FROM t1; +SELECT GREATEST(pk, d) FROM v1; +DROP VIEW v1; +DROP TABLE t1; + + --echo # --echo # End of 10.1 tests --echo # diff --git a/mysql-test/main/type_datetime.result b/mysql-test/main/type_datetime.result index 923d6a3783c..a7a9eece0da 100644 --- a/mysql-test/main/type_datetime.result +++ b/mysql-test/main/type_datetime.result @@ -1167,6 +1167,37 @@ INSERT INTO t2 SELECT * FROM t1; DROP TABLE t1, t2; SET SQL_MODE=DEFAULT; # +# MDEV-19699 Server crashes in Item_null_result::field_type upon SELECT with ROLLUP on constant table +# +CREATE TABLE t1 (d DATETIME) ENGINE=MyISAM; +INSERT INTO t1 VALUES ('1999-11-04'); +SELECT d FROM t1 GROUP BY d WITH ROLLUP HAVING d > '1990-01-01'; +d +1999-11-04 00:00:00 +DROP TABLE t1; +# +# MDEV-20431 GREATEST(int_col,date_col) returns wrong results in a view +# +CREATE TABLE t1 (pk INT NOT NULL, d DATETIME NOT NULL); +CREATE VIEW v1 AS SELECT * FROM t1; +INSERT INTO t1 VALUES (1,'2018-06-22 00:00:00'),(2,'2018-07-11 00:00:00'); +SELECT GREATEST(pk, d) FROM t1; +GREATEST(pk, d) +2018-06-22 00:00:00 +2018-07-11 00:00:00 +Warnings: +Warning 1292 Incorrect datetime value: '1' for column `test`.`t1`.`pk` at row 1 +Warning 1292 Incorrect datetime value: '2' for column `test`.`t1`.`pk` at row 2 +SELECT GREATEST(pk, d) FROM v1; +GREATEST(pk, d) +2018-06-22 00:00:00 +2018-07-11 00:00:00 +Warnings: +Warning 1292 Incorrect datetime value: '1' for column `test`.`t1`.`pk` at row 1 +Warning 1292 Incorrect datetime value: '2' for column `test`.`t1`.`pk` at row 2 +DROP VIEW v1; +DROP TABLE t1; +# # End of 10.1 tests # # diff --git a/mysql-test/main/type_datetime.test b/mysql-test/main/type_datetime.test index baf85187099..2445925cb80 100644 --- a/mysql-test/main/type_datetime.test +++ b/mysql-test/main/type_datetime.test @@ -725,6 +725,29 @@ SET SQL_MODE=DEFAULT; --echo # +--echo # MDEV-19699 Server crashes in Item_null_result::field_type upon SELECT with ROLLUP on constant table +--echo # + +CREATE TABLE t1 (d DATETIME) ENGINE=MyISAM; +INSERT INTO t1 VALUES ('1999-11-04'); +SELECT d FROM t1 GROUP BY d WITH ROLLUP HAVING d > '1990-01-01'; +DROP TABLE t1; + + +--echo # +--echo # MDEV-20431 GREATEST(int_col,date_col) returns wrong results in a view +--echo # + +CREATE TABLE t1 (pk INT NOT NULL, d DATETIME NOT NULL); +CREATE VIEW v1 AS SELECT * FROM t1; +INSERT INTO t1 VALUES (1,'2018-06-22 00:00:00'),(2,'2018-07-11 00:00:00'); +SELECT GREATEST(pk, d) FROM t1; +SELECT GREATEST(pk, d) FROM v1; +DROP VIEW v1; +DROP TABLE t1; + + +--echo # --echo # End of 10.1 tests --echo # diff --git a/mysql-test/suite/binlog/include/drop_temp_table.test b/mysql-test/suite/binlog/include/drop_temp_table.test index 9139ac76017..7c95195eadc 100644 --- a/mysql-test/suite/binlog/include/drop_temp_table.test +++ b/mysql-test/suite/binlog/include/drop_temp_table.test @@ -150,16 +150,16 @@ RESET MASTER; --echo # Test case for DROP query. --connection default -CREATE TABLE t1 (a INT) ENGINE=INNODB; +CREATE TABLE t2 (a INT) ENGINE=INNODB; --connection con1 -CREATE TEMPORARY TABLE t1 (b BLOB) ENGINE=INNODB; +CREATE TEMPORARY TABLE t2 (b BLOB) ENGINE=INNODB; --connection default -DROP TABLE t1; +DROP TABLE t2; --connection con1 -DROP TABLE t1; +DROP TABLE t2; --connection default --exec $MYSQL_BINLOG --force-if-open $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/bug28642318.sql diff --git a/mysql-test/suite/binlog/r/binlog_row_drop_tmp_tbl.result b/mysql-test/suite/binlog/r/binlog_row_drop_tmp_tbl.result index 60596be480f..10744956995 100644 --- a/mysql-test/suite/binlog/r/binlog_row_drop_tmp_tbl.result +++ b/mysql-test/suite/binlog/r/binlog_row_drop_tmp_tbl.result @@ -88,13 +88,13 @@ DROP TABLE IF EXISTS t1; RESET MASTER; # Test case for DROP query. connection default; -CREATE TABLE t1 (a INT) ENGINE=INNODB; +CREATE TABLE t2 (a INT) ENGINE=INNODB; connection con1; -CREATE TEMPORARY TABLE t1 (b BLOB) ENGINE=INNODB; +CREATE TEMPORARY TABLE t2 (b BLOB) ENGINE=INNODB; connection default; -DROP TABLE t1; +DROP TABLE t2; connection con1; -DROP TABLE t1; +DROP TABLE t2; connection default; # DROP table query fails with unknown table error without patch. # Clean up diff --git a/mysql-test/suite/binlog/r/binlog_stm_drop_tmp_tbl.result b/mysql-test/suite/binlog/r/binlog_stm_drop_tmp_tbl.result index ae7852be9e3..99305abf175 100644 --- a/mysql-test/suite/binlog/r/binlog_stm_drop_tmp_tbl.result +++ b/mysql-test/suite/binlog/r/binlog_stm_drop_tmp_tbl.result @@ -116,13 +116,13 @@ DROP TABLE IF EXISTS t1; RESET MASTER; # Test case for DROP query. connection default; -CREATE TABLE t1 (a INT) ENGINE=INNODB; +CREATE TABLE t2 (a INT) ENGINE=INNODB; connection con1; -CREATE TEMPORARY TABLE t1 (b BLOB) ENGINE=INNODB; +CREATE TEMPORARY TABLE t2 (b BLOB) ENGINE=INNODB; connection default; -DROP TABLE t1; +DROP TABLE t2; connection con1; -DROP TABLE t1; +DROP TABLE t2; connection default; # DROP table query fails with unknown table error without patch. # Clean up diff --git a/mysql-test/suite/innodb/r/innodb-read-view.result b/mysql-test/suite/innodb/r/innodb-read-view.result index eb48a5ab661..e01d8a110e6 100644 --- a/mysql-test/suite/innodb/r/innodb-read-view.result +++ b/mysql-test/suite/innodb/r/innodb-read-view.result @@ -196,7 +196,6 @@ DROP TABLE t2; # Bug 21433768: NON-REPEATABLE READ WITH REPEATABLE READ ISOLATION # connect con1,localhost,root,,; -# connection con1 CREATE TABLE t1(col1 INT PRIMARY KEY, col2 INT) ENGINE = InnoDB; INSERT INTO t1 values (1, 0), (2, 0); SELECT * FROM t1 ORDER BY col1; @@ -208,7 +207,6 @@ UPDATE t1 SET col2 = 100; SET DEBUG_SYNC = 'after_trx_committed_in_memory SIGNAL s1 WAIT_FOR s2'; COMMIT;; connection default; -# connection default SET DEBUG_SYNC = 'now WAIT_FOR s1'; UPDATE t1 SET col2 = col2 + 10 where col1 = 1; COMMIT; @@ -218,10 +216,7 @@ col1 col2 2 100 SET DEBUG_SYNC = 'now SIGNAL s2'; connection con1; -# connection con1 -# reap COMMIT for con1 -connection default; -# connection default disconnect con1; +connection default; DROP TABLE t1; SET DEBUG_SYNC= 'RESET'; diff --git a/mysql-test/suite/innodb/t/innodb-read-view.test b/mysql-test/suite/innodb/t/innodb-read-view.test index ec4026d10c6..425cbeb08c8 100644 --- a/mysql-test/suite/innodb/t/innodb-read-view.test +++ b/mysql-test/suite/innodb/t/innodb-read-view.test @@ -1,5 +1,6 @@ # DEBUG_SYNC must be compiled in. --source include/have_debug_sync.inc +--source include/have_debug.inc # We need to test the use case: # a. Create a transaction T1 that will be promoted to RW. @@ -176,7 +177,6 @@ DROP TABLE t2; --echo # --connect (con1,localhost,root,,) ---echo # connection con1 CREATE TABLE t1(col1 INT PRIMARY KEY, col2 INT) ENGINE = InnoDB; INSERT INTO t1 values (1, 0), (2, 0); @@ -188,7 +188,6 @@ SET DEBUG_SYNC = 'after_trx_committed_in_memory SIGNAL s1 WAIT_FOR s2'; --send COMMIT; connection default; ---echo # connection default SET DEBUG_SYNC = 'now WAIT_FOR s1'; UPDATE t1 SET col2 = col2 + 10 where col1 = 1; COMMIT; @@ -197,18 +196,13 @@ SELECT * FROM t1 ORDER BY col1; SET DEBUG_SYNC = 'now SIGNAL s2'; connection con1; ---echo # connection con1 ---echo # reap COMMIT for con1 reap; +disconnect con1; connection default; ---echo # connection default -disconnect con1; DROP TABLE t1; # Clean up resources used in this test case. ---disable_warnings SET DEBUG_SYNC= 'RESET'; ---enable_warnings --source include/wait_until_count_sessions.inc diff --git a/scripts/wsrep_sst_common.sh b/scripts/wsrep_sst_common.sh index b1b586868df..16607470f2c 100755 --- a/scripts/wsrep_sst_common.sh +++ b/scripts/wsrep_sst_common.sh @@ -166,7 +166,11 @@ case "$1" in shift while [ $# -gt 0 ]; do option=${1%%=*} - if [ "$option" != "--defaults-file" ]; then + if [[ "$option" != "--defaults-file" && \ + "$option" != "--defaults-extra-file" && \ + "$option" != "--defaults-group-suffix" && \ + "$option" != "--port" && \ + "$option" != "--socket" ]]; then value=${1#*=} case "$option" in '--innodb-data-home-dir') @@ -193,7 +197,7 @@ case "$1" in if [ -z "$original_cmd" ]; then original_cmd="$1" else - original_cmd+=" $1" + original_cmd="$original_cmd $1" fi fi shift @@ -249,7 +253,15 @@ else MY_PRINT_DEFAULTS=my_print_defaults fi -readonly WSREP_SST_OPT_CONF="$WSREP_SST_OPT_DEFAULT $WSREP_SST_OPT_EXTRA_DEFAULT $WSREP_SST_OPT_SUFFIX_DEFAULT" +wsrep_defaults="$WSREP_SST_OPT_DEFAULT" +if [ -n "$wsrep_defaults" ]; then + wsrep_defaults="$wsrep_defaults " +fi +wsrep_defaults="$wsrep_defaults$WSREP_SST_OPT_EXTRA_DEFAULT" +if [ -n "$wsrep_defaults" ]; then + wsrep_defaults="$wsrep_defaults " +fi +readonly WSREP_SST_OPT_CONF="$wsrep_defaults$WSREP_SST_OPT_SUFFIX_DEFAULT" readonly MY_PRINT_DEFAULTS="$MY_PRINT_DEFAULTS $WSREP_SST_OPT_CONF" wsrep_auth_not_set() diff --git a/scripts/wsrep_sst_mariabackup.sh b/scripts/wsrep_sst_mariabackup.sh index 8e7b742d9ee..36deeff779d 100644 --- a/scripts/wsrep_sst_mariabackup.sh +++ b/scripts/wsrep_sst_mariabackup.sh @@ -60,7 +60,7 @@ rebuild=0 rebuildcmd="" payload=0 pvformat="-F '%N => Rate:%r Avg:%a Elapsed:%t %e Bytes: %b %p' " -pvopts="-f -i 10 -N $WSREP_SST_OPT_ROLE " +pvopts="-f -i 10 -N $WSREP_SST_OPT_ROLE " STATDIR="" uextra=0 disver="" @@ -130,7 +130,7 @@ get_keys() if [[ $encrypt -eq 0 ]];then if $MY_PRINT_DEFAULTS xtrabackup | grep -q encrypt;then - wsrep_log_error "Unexpected option combination. SST may fail. Refer to http://www.percona.com/doc/percona-xtradb-cluster/manual/xtrabackup_sst.html " + wsrep_log_error "Unexpected option combination. SST may fail. Refer to http://www.percona.com/doc/percona-xtradb-cluster/manual/xtrabackup_sst.html" fi return fi @@ -464,7 +464,7 @@ cleanup_donor() if [[ -n ${XTRABACKUP_PID:-} ]];then if check_pid $XTRABACKUP_PID then - wsrep_log_error "xtrabackup process is still running. Killing... " + wsrep_log_error "xtrabackup process is still running. Killing..." kill_xtrabackup fi @@ -566,7 +566,7 @@ check_extra() # Xtrabackup works only locally. # Hence, setting host to 127.0.0.1 unconditionally. wsrep_log_info "SST through extra_port $eport" - INNOEXTRA+=" --host=127.0.0.1 --port=$eport " + INNOEXTRA+=" --host=127.0.0.1 --port=$eport" use_socket=0 else wsrep_log_error "Extra port $eport null, failing" @@ -576,8 +576,8 @@ check_extra() wsrep_log_info "Thread pool not set, ignore the option use_extra" fi fi - if [[ $use_socket -eq 1 ]] && [[ -n "${WSREP_SST_OPT_SOCKET}" ]];then - INNOEXTRA+=" --socket=${WSREP_SST_OPT_SOCKET}" + if [[ $use_socket -eq 1 ]] && [[ -n "$WSREP_SST_OPT_SOCKET" ]];then + INNOEXTRA+=" --socket=$WSREP_SST_OPT_SOCKET" fi } @@ -743,8 +743,8 @@ if [[ $ssyslog -eq 1 ]];then logger -p daemon.info -t ${ssystag}wsrep-sst-$WSREP_SST_OPT_ROLE "$@" } - INNOAPPLY="${INNOBACKUPEX_BIN} --innobackupex $disver $iapts \$INNOEXTRA --apply-log \$rebuildcmd \${DATA} 2>&1 | logger -p daemon.err -t ${ssystag}innobackupex-apply " - INNOMOVE="${INNOBACKUPEX_BIN} --innobackupex ${WSREP_SST_OPT_CONF} $disver $impts --move-back --force-non-empty-directories \${DATA} 2>&1 | logger -p daemon.err -t ${ssystag}innobackupex-move " + INNOAPPLY="${INNOBACKUPEX_BIN} --innobackupex $disver $iapts \$INNOEXTRA --apply-log \$rebuildcmd \${DATA} 2>&1 | logger -p daemon.err -t ${ssystag}innobackupex-apply" + INNOMOVE="${INNOBACKUPEX_BIN} --innobackupex ${WSREP_SST_OPT_CONF} $disver $impts --move-back --force-non-empty-directories \${DATA} 2>&1 | logger -p daemon.err -t ${ssystag}innobackupex-move" INNOBACKUP="${INNOBACKUPEX_BIN} --innobackupex ${WSREP_SST_OPT_CONF} $disver $iopts \$tmpopts \$INNOEXTRA --galera-info --stream=\$sfmt \$itmpdir 2> >(logger -p daemon.err -t ${ssystag}innobackupex-backup)" fi @@ -832,7 +832,7 @@ then -z $(parse_cnf --mysqld tmpdir "") && \ -z $(parse_cnf xtrabackup tmpdir "") ]]; then xtmpdir=$(mktemp -d) - tmpopts=" --tmpdir=$xtmpdir " + tmpopts=" --tmpdir=$xtmpdir" wsrep_log_info "Using $xtmpdir as xtrabackup temporary directory" fi @@ -854,13 +854,12 @@ then get_keys if [[ $encrypt -eq 1 ]];then if [[ -n $ekey ]];then - INNOEXTRA+=" --encrypt=$ealgo --encrypt-key=$ekey " + INNOEXTRA+=" --encrypt=$ealgo --encrypt-key=$ekey" else - INNOEXTRA+=" --encrypt=$ealgo --encrypt-key-file=$ekeyfile " + INNOEXTRA+=" --encrypt=$ealgo --encrypt-key-file=$ekeyfile" fi fi - check_extra wsrep_log_info "Streaming GTID file before SST" @@ -881,7 +880,6 @@ then tcmd=" $scomp | $tcmd " fi - send_donor $DATA "${stagemsg}-gtid" tcmd="$ttcmd" @@ -1049,7 +1047,7 @@ then tempdir=$LOG_BIN_ARG if [ -z "$tempdir" ]; then - tempdir=$(parse_cnf mysqld$WSREP_SST_OPT_SUFFIX_VALUE log-bin "") + tempdir=$(parse_cnf mysqld$WSREP_SST_OPT_SUFFIX_VALUE log-bin "") fi if [ -z "$tempdir" ]; then tempdir=$(parse_cnf --mysqld log-bin "") diff --git a/sql/field.h b/sql/field.h index 39bd10af525..67e20c5a1b4 100644 --- a/sql/field.h +++ b/sql/field.h @@ -561,6 +561,7 @@ public: /* Flag indicating that the field is physically stored in the database */ bool stored_in_db; bool utf8; /* Already in utf8 */ + bool automatic_name; Item *expr; LEX_CSTRING name; /* Name of constraint */ /* see VCOL_* (VCOL_FIELD_REF, ...) */ @@ -570,7 +571,7 @@ public: : vcol_type((enum_vcol_info_type)VCOL_TYPE_NONE), field_type((enum enum_field_types)MYSQL_TYPE_VIRTUAL), in_partitioning_expr(FALSE), stored_in_db(FALSE), - utf8(TRUE), expr(NULL), flags(0) + utf8(TRUE), automatic_name(FALSE), expr(NULL), flags(0) { name.str= NULL; name.length= 0; diff --git a/sql/item.cc b/sql/item.cc index 9e13a5f0804..f6b4fd01636 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -4020,6 +4020,20 @@ my_decimal *Item_null::val_decimal(my_decimal *decimal_value) } +longlong Item_null::val_datetime_packed() +{ + null_value= true; + return 0; +} + + +longlong Item_null::val_time_packed() +{ + null_value= true; + return 0; +} + + bool Item_null::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) { // following assert is redundant, because fixed=1 assigned in constructor @@ -8387,6 +8401,24 @@ bool Item_ref::get_date(MYSQL_TIME *ltime,ulonglong fuzzydate) } +longlong Item_ref::val_datetime_packed() +{ + DBUG_ASSERT(fixed); + longlong tmp= (*ref)->val_datetime_packed(); + null_value= (*ref)->null_value; + return tmp; +} + + +longlong Item_ref::val_time_packed() +{ + DBUG_ASSERT(fixed); + longlong tmp= (*ref)->val_time_packed(); + null_value= (*ref)->null_value; + return tmp; +} + + my_decimal *Item_ref::val_decimal(my_decimal *decimal_value) { my_decimal *val= (*ref)->val_decimal_result(decimal_value); diff --git a/sql/item.h b/sql/item.h index 649799e3ce4..d472c0d358e 100644 --- a/sql/item.h +++ b/sql/item.h @@ -3242,6 +3242,8 @@ public: String *val_str(String *str); my_decimal *val_decimal(my_decimal *); bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate); + longlong val_datetime_packed(); + longlong val_time_packed(); int save_in_field(Field *field, bool no_conversions); int save_safe_in_field(Field *field); bool send(Protocol *protocol, st_value *buffer); @@ -4811,6 +4813,8 @@ public: String *val_str(String* tmp); bool is_null(); bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate); + longlong val_datetime_packed(); + longlong val_time_packed(); double val_result(); longlong val_int_result(); String *str_result(String* tmp); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 55e84cbfeb5..644bba9051f 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -66,7 +66,7 @@ const char *primary_key_name="PRIMARY"; static int check_if_keyname_exists(const char *name,KEY *start, KEY *end); static char *make_unique_key_name(THD *thd, const char *field_name, KEY *start, KEY *end); -static void make_unique_constraint_name(THD *thd, LEX_CSTRING *name, +static bool make_unique_constraint_name(THD *thd, LEX_CSTRING *name, List<Virtual_column_info> *vcol, uint *nr); static const @@ -83,6 +83,8 @@ static int copy_data_between_tables(THD *thd, TABLE *from,TABLE *to, static int mysql_prepare_create_table(THD *, HA_CREATE_INFO *, Alter_info *, uint *, handler *, KEY **, uint *, int); static uint blob_length_by_type(enum_field_types type); +static bool fix_constraints_names(THD *thd, List<Virtual_column_info> + *check_constraint_list); /** @brief Helper function for explain_filename @@ -4220,15 +4222,13 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, /* Check table level constraints */ create_info->check_constraint_list= &alter_info->check_constraint_list; { - uint nr= 1; List_iterator_fast<Virtual_column_info> c_it(alter_info->check_constraint_list); Virtual_column_info *check; while ((check= c_it++)) { - if (!check->name.length) - make_unique_constraint_name(thd, &check->name, - &alter_info->check_constraint_list, - &nr); + if (!check->name.length || check->automatic_name) + continue; + { /* Check that there's no repeating constraint names. */ List_iterator_fast<Virtual_column_info> @@ -4784,6 +4784,9 @@ int create_table_impl(THD *thd, DBUG_PRINT("enter", ("db: '%s' table: '%s' tmp: %d path: %s", db->str, table_name->str, internal_tmp_table, path)); + if (fix_constraints_names(thd, &alter_info->check_constraint_list)) + DBUG_RETURN(1); + if (thd->variables.sql_mode & MODE_NO_DIR_IN_CREATE) { if (create_info->data_file_name) @@ -5308,7 +5311,7 @@ make_unique_key_name(THD *thd, const char *field_name,KEY *start,KEY *end) Make an unique name for constraints without a name */ -static void make_unique_constraint_name(THD *thd, LEX_CSTRING *name, +static bool make_unique_constraint_name(THD *thd, LEX_CSTRING *name, List<Virtual_column_info> *vcol, uint *nr) { @@ -5331,9 +5334,10 @@ static void make_unique_constraint_name(THD *thd, LEX_CSTRING *name, { name->length= (size_t) (real_end - buff); name->str= thd->strmake(buff, name->length); - return; + return (name->str == NULL); } } + return FALSE; } /** @@ -5960,10 +5964,11 @@ static bool is_candidate_key(KEY *key) from the list if existing found. RETURN VALUES - NONE + TRUE error + FALSE OK */ -static void +static bool handle_if_exists_options(THD *thd, TABLE *table, Alter_info *alter_info) { Field **f_ptr; @@ -6403,6 +6408,7 @@ remove_key: Virtual_column_info *check; TABLE_SHARE *share= table->s; uint c; + while ((check=it++)) { if (!(check->flags & Alter_info::CHECK_CONSTRAINT_IF_NOT_EXISTS) && @@ -6430,10 +6436,44 @@ remove_key: } } - DBUG_VOID_RETURN; + DBUG_RETURN(FALSE); } +static bool fix_constraints_names(THD *thd, List<Virtual_column_info> + *check_constraint_list) +{ + List_iterator<Virtual_column_info> it((*check_constraint_list)); + Virtual_column_info *check; + uint nr= 1; + DBUG_ENTER("fix_constraints_names"); + if (!check_constraint_list) + DBUG_RETURN(FALSE); + // Prevent accessing freed memory during generating unique names + while ((check=it++)) + { + if (check->automatic_name) + { + check->name.str= NULL; + check->name.length= 0; + } + } + it.rewind(); + // Generate unique names if needed + while ((check=it++)) + { + if (!check->name.length) + { + check->automatic_name= TRUE; + if (make_unique_constraint_name(thd, &check->name, + check_constraint_list, + &nr)) + DBUG_RETURN(TRUE); + } + } + DBUG_RETURN(FALSE); +} + /** Get Create_field object for newly created table by field index. @@ -9430,7 +9470,10 @@ do_continue:; } } - handle_if_exists_options(thd, table, alter_info); + if (handle_if_exists_options(thd, table, alter_info) || + fix_constraints_names(thd, &alter_info->check_constraint_list)) + DBUG_RETURN(true); + /* Look if we have to do anything at all. diff --git a/sql/wsrep_sst.cc b/sql/wsrep_sst.cc index 8079ebaf563..714df35de8b 100644 --- a/sql/wsrep_sst.cc +++ b/sql/wsrep_sst.cc @@ -16,6 +16,7 @@ #include "mariadb.h" #include "wsrep_sst.h" #include <inttypes.h> +#include <ctype.h> #include <mysqld.h> #include <m_ctype.h> #include <strfunc.h> @@ -429,7 +430,31 @@ static char* my_fgets (char* buf, size_t buf_len, FILE* stream) } /* - Generate opt_binlog_opt_val for sst_donate_other(), sst_prepare_other(). + Generate "name 'value'" string. +*/ +static char* generate_name_value(const char* name, const char* value) +{ + size_t name_len= strlen(name); + size_t value_len= strlen(value); + char* buf= + (char*) my_malloc((name_len + value_len + 5) * sizeof(char), MYF(0)); + if (buf) + { + char* ref= buf; + *ref++ = ' '; + memcpy(ref, name, name_len * sizeof(char)); + ref += name_len; + *ref++ = ' '; + *ref++ = '\''; + memcpy(ref, value, value_len * sizeof(char)); + ref += value_len; + *ref++ = '\''; + *ref = 0; + } + return buf; +} +/* + Generate binlog option string for sst_donate_other(), sst_prepare_other(). Returns zero on success, negative error code otherwise. @@ -445,7 +470,9 @@ static int generate_binlog_opt_val(char** ret) { assert(opt_bin_logname); *ret= strcmp(opt_bin_logname, "0") ? - my_strdup(opt_bin_logname, MYF(0)) : my_strdup("", MYF(0)); + generate_name_value(WSREP_SST_OPT_BINLOG, + opt_bin_logname) : + my_strdup("", MYF(0)); } else { @@ -461,7 +488,9 @@ static int generate_binlog_index_opt_val(char** ret) *ret= NULL; if (opt_binlog_index_name) { *ret= strcmp(opt_binlog_index_name, "0") ? - my_strdup(opt_binlog_index_name, MYF(0)) : my_strdup("", MYF(0)); + generate_name_value(WSREP_SST_OPT_BINLOG_INDEX, + opt_binlog_index_name) : + my_strdup("", MYF(0)); } else { @@ -658,7 +687,86 @@ static size_t estimate_cmd_len (bool* extra_args) { for (int i = 1; i < orig_argc; i++) { - cmd_len += strlen(orig_argv[i]); + const char* arg= orig_argv[i]; + size_t n= strlen(arg); + if (n == 0) continue; + cmd_len += n; + bool quotation= false; + char c; + while ((c = *arg++) != 0) + { + /* A whitespace or a single quote requires double quotation marks: */ + if (isspace(c) || c == '\'') + { + quotation= true; + } + /* + If the equals symbol is encountered, then we need to separately + process the right side: + */ + else if (c == '=') + { + /* Perhaps we need to quote the left part of the argument: */ + if (quotation) + { + cmd_len += 2; + /* + Reset the quotation flag, since now the status for + the right side of the expression will be saved here: + */ + quotation= false; + } + while ((c = *arg++) != 0) + { + /* + A whitespace or a single quote requires double + quotation marks: + */ + if (isspace(c) || c == '\'') + { + quotation= true; + } + /* + Double quotation mark or backslash symbol requires backslash + prefixing: + */ +#ifdef __WIN__ + else if (c == '"' || c == '\\') +#else + /* + The dollar symbol is used to substitute a variable, therefore + it also requires escaping: + */ + else if (c == '"' || c == '\\' || c == '$') +#endif + { + cmd_len++; + } + } + break; + } + /* + Double quotation mark or backslash symbol requires backslash + prefixing: + */ +#ifdef __WIN__ + else if (c == '"' || c == '\\') +#else + /* + The dollar symbol is used to substitute a variable, therefore + it also requires escaping: + */ + else if (c == '"' || c == '\\' || c == '$') +#endif + { + cmd_len++; + } + } + /* Perhaps we need to quote the entire argument or its right part: */ + if (quotation) + { + cmd_len += 2; + } } extra = true; cmd_len += strlen(WSREP_SST_OPT_MYSQLD); @@ -686,10 +794,171 @@ static void copy_orig_argv (char* cmd_str) for (int i = 1; i < orig_argc; i++) { char* arg= orig_argv[i]; - *cmd_str++ = ' '; n = strlen(arg); - memcpy(cmd_str, arg, n * sizeof(char)); - cmd_str += n; + if (n == 0) continue; + *cmd_str++ = ' '; + bool quotation= false; + bool plain= true; + char *arg_scan= arg; + char c; + while ((c = *arg_scan++) != 0) + { + /* A whitespace or a single quote requires double quotation marks: */ + if (isspace(c) || c == '\'') + { + quotation= true; + } + /* + If the equals symbol is encountered, then we need to separately + process the right side: + */ + else if (c == '=') + { + /* Calculate length of the Left part of the argument: */ + size_t m = (size_t) (arg_scan - arg) - 1; + if (m) + { + /* Perhaps we need to quote the left part of the argument: */ + if (quotation) + { + *cmd_str++ = '"'; + } + /* + If there were special characters inside, then we can use + the fast memcpy function: + */ + if (plain) + { + memcpy(cmd_str, arg, m * sizeof(char)); + cmd_str += m; + /* Left part of the argument has already been processed: */ + n -= m; + arg += m; + } + /* Otherwise we need to prefix individual characters: */ + else + { + n -= m; + while (m) + { + c = *arg++; +#ifdef __WIN__ + if (c == '"' || c == '\\') +#else + if (c == '"' || c == '\\' || c == '$') +#endif + { + *cmd_str++ = '\\'; + } + *cmd_str++ = c; + m--; + } + /* + Reset the plain string flag, since now the status for + the right side of the expression will be saved here: + */ + plain= true; + } + /* Perhaps we need to quote the left part of the argument: */ + if (quotation) + { + *cmd_str++ = '"'; + /* + Reset the quotation flag, since now the status for + the right side of the expression will be saved here: + */ + quotation= false; + } + } + /* Copy equals symbol: */ + *cmd_str++ = '='; + arg++; + n--; + /* Let's deal with the left side of the expression: */ + while ((c = *arg_scan++) != 0) + { + /* + A whitespace or a single quote requires double + quotation marks: + */ + if (isspace(c) || c == '\'') + { + quotation= true; + } + /* + Double quotation mark or backslash symbol requires backslash + prefixing: + */ +#ifdef __WIN__ + else if (c == '"' || c == '\\') +#else + /* + The dollar symbol is used to substitute a variable, therefore + it also requires escaping: + */ + else if (c == '"' || c == '\\' || c == '$') +#endif + { + plain= false; + } + } + break; + } + /* + Double quotation mark or backslash symbol requires backslash + prefixing: + */ +#ifdef __WIN__ + else if (c == '"' || c == '\\') +#else + /* + The dollar symbol is used to substitute a variable, therefore + it also requires escaping: + */ + else if (c == '"' || c == '\\' || c == '$') +#endif + { + plain= false; + } + } + if (n) + { + /* Perhaps we need to quote the entire argument or its right part: */ + if (quotation) + { + *cmd_str++ = '"'; + } + /* + If there were no special characters inside, then we can use + the fast memcpy function: + */ + if (plain) + { + memcpy(cmd_str, arg, n * sizeof(char)); + cmd_str += n; + } + /* Otherwise we need to prefix individual characters: */ + else + { + while ((c = *arg++) != 0) + { +#ifdef __WIN__ + if (c == '"' || c == '\\') +#else + if (c == '"' || c == '\\' || c == '$') +#endif + { + *cmd_str++ = '\\'; + } + *cmd_str++ = c; + } + } + /* Perhaps we need to quote the entire argument or its right part: */ + if (quotation) + { + *cmd_str++ = '"'; + } + } } /* Add a terminating null character (not counted in the length, @@ -716,8 +985,6 @@ static ssize_t sst_prepare_other (const char* method, return -ENOMEM; } - const char* binlog_opt= ""; - const char* binlog_index_opt= ""; char* binlog_opt_val= NULL; char* binlog_index_opt_val= NULL; @@ -735,9 +1002,6 @@ static ssize_t sst_prepare_other (const char* method, ret); } - if (strlen(binlog_opt_val)) binlog_opt= WSREP_SST_OPT_BINLOG; - if (strlen(binlog_index_opt_val)) binlog_index_opt= WSREP_SST_OPT_BINLOG_INDEX; - make_wsrep_defaults_file(); ret= snprintf (cmd_str(), cmd_len, @@ -745,14 +1009,14 @@ static ssize_t sst_prepare_other (const char* method, WSREP_SST_OPT_ROLE " 'joiner' " WSREP_SST_OPT_ADDR " '%s' " WSREP_SST_OPT_DATA " '%s' " - " %s " + "%s" WSREP_SST_OPT_PARENT " '%d'" - " %s '%s'" - " %s '%s'", + "%s" + "%s", method, addr_in, mysql_real_data_home, wsrep_defaults_file, - (int)getpid(), binlog_opt, binlog_opt_val, - binlog_index_opt, binlog_index_opt_val); + (int)getpid(), + binlog_opt_val, binlog_index_opt_val); my_free(binlog_opt_val); my_free(binlog_index_opt_val); @@ -1058,7 +1322,7 @@ static int sst_donate_mysqldump (const char* addr, WSREP_SST_OPT_PORT " '%d' " WSREP_SST_OPT_LPORT " '%u' " WSREP_SST_OPT_SOCKET " '%s' " - " %s " + "%s" WSREP_SST_OPT_GTID " '%s:%lld' " WSREP_SST_OPT_GTID_DOMAIN_ID " '%d'" "%s", @@ -1406,7 +1670,6 @@ static int sst_donate_other (const char* method, return -ENOMEM; } - const char* binlog_opt= ""; char* binlog_opt_val= NULL; int ret; @@ -1415,7 +1678,6 @@ static int sst_donate_other (const char* method, WSREP_ERROR("sst_donate_other(): generate_binlog_opt_val() failed: %d",ret); return ret; } - if (strlen(binlog_opt_val)) binlog_opt= WSREP_SST_OPT_BINLOG; make_wsrep_defaults_file(); @@ -1425,15 +1687,15 @@ static int sst_donate_other (const char* method, WSREP_SST_OPT_ADDR " '%s' " WSREP_SST_OPT_SOCKET " '%s' " WSREP_SST_OPT_DATA " '%s' " - " %s " - " %s '%s' " + "%s" WSREP_SST_OPT_GTID " '%s:%lld' " WSREP_SST_OPT_GTID_DOMAIN_ID " '%d'" + "%s" "%s", method, addr, mysqld_unix_port, mysql_real_data_home, wsrep_defaults_file, - binlog_opt, binlog_opt_val, uuid, (long long) seqno, wsrep_gtid_domain_id, + binlog_opt_val, bypass ? " " WSREP_SST_OPT_BYPASS : ""); my_free(binlog_opt_val); diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index b58db399a05..a8a5e245513 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -1315,7 +1315,7 @@ char *ha_connect::GetRealString(PCSZ s) { char *sv; - if (IsPartitioned() && s && partname && *partname) { + if (IsPartitioned() && s && *partname) { sv= (char*)PlugSubAlloc(xp->g, NULL, 0); sprintf(sv, s, partname); PlugSubAlloc(xp->g, NULL, strlen(sv) + 1); diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index cfc8acbfb2f..666c74cba74 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -1221,9 +1221,7 @@ lock_sec_rec_some_has_impl( /* Some transaction may have an implicit x-lock on the record only if the max trx id for the page >= min trx id for the trx list, or - database recovery is running. We do not write the changes of a page - max trx id to the log, and therefore during recovery, this value - for a page may be incorrect. */ + database recovery is running. */ if (max_trx_id < trx_sys.get_min_trx_id()) { diff --git a/storage/perfschema/pfs_instr.cc b/storage/perfschema/pfs_instr.cc index b6736cf3102..f90c6475f22 100644 --- a/storage/perfschema/pfs_instr.cc +++ b/storage/perfschema/pfs_instr.cc @@ -1265,7 +1265,6 @@ find_or_create_file(PFS_thread *thread, PFS_file_class *klass, char dirbuffer[FN_REFLEN]; size_t dirlen; const char *normalized_filename; - int normalized_length; dirlen= dirname_length(safe_filename); if (dirlen == 0) @@ -1296,7 +1295,7 @@ find_or_create_file(PFS_thread *thread, PFS_file_class *klass, *buf_end= '\0'; normalized_filename= buffer; - normalized_length= (int)strlen(normalized_filename); + uint normalized_length= static_cast<uint>(strlen(normalized_filename)); PFS_file **entry; uint retry_count= 0; @@ -1345,7 +1344,7 @@ search: pfs->m_class= klass; pfs->m_enabled= klass->m_enabled && flag_global_instrumentation; pfs->m_timed= klass->m_timed; - strncpy(pfs->m_filename, normalized_filename, normalized_length); + strncpy(pfs->m_filename, normalized_filename, normalized_length + 1); pfs->m_filename[normalized_length]= '\0'; pfs->m_filename_length= normalized_length; pfs->m_file_stat.m_open_count= 1; diff --git a/storage/sphinx/ha_sphinx.cc b/storage/sphinx/ha_sphinx.cc index 90409213843..13a46d495fe 100644 --- a/storage/sphinx/ha_sphinx.cc +++ b/storage/sphinx/ha_sphinx.cc @@ -2292,7 +2292,8 @@ int ha_sphinx::HandleMysqlError ( MYSQL * pConn, int iErrCode ) CSphSEThreadTable * pTable = GetTls (); if ( pTable ) { - strncpy ( pTable->m_tStats.m_sLastMessage, mysql_error ( pConn ), sizeof ( pTable->m_tStats.m_sLastMessage ) ); + strncpy ( pTable->m_tStats.m_sLastMessage, mysql_error ( pConn ), sizeof pTable->m_tStats.m_sLastMessage - 1 ); + pTable->m_tStats.m_sLastMessage[sizeof pTable->m_tStats.m_sLastMessage - 1] = '\0'; pTable->m_tStats.m_bLastError = true; } @@ -2559,7 +2560,8 @@ bool ha_sphinx::UnpackSchema () CSphSEThreadTable * pTable = GetTls (); if ( pTable ) { - strncpy ( pTable->m_tStats.m_sLastMessage, sMessage, sizeof(pTable->m_tStats.m_sLastMessage) ); + strncpy ( pTable->m_tStats.m_sLastMessage, sMessage, sizeof pTable->m_tStats.m_sLastMessage - 1 ); + pTable->m_tStats.m_sLastMessage[sizeof pTable->m_tStats.m_sLastMessage - 1] = '\0'; pTable->m_tStats.m_bLastError = ( uStatus==SEARCHD_ERROR ); } @@ -2983,7 +2985,8 @@ int ha_sphinx::index_read ( byte * buf, const byte * key, uint key_len, enum ha_ SPH_RET ( HA_ERR_END_OF_FILE ); } - strncpy ( pTable->m_tStats.m_sLastMessage, sMessage, sizeof(pTable->m_tStats.m_sLastMessage) ); + strncpy ( pTable->m_tStats.m_sLastMessage, sMessage, sizeof pTable->m_tStats.m_sLastMessage - 1 ); + pTable->m_tStats.m_sLastMessage[sizeof pTable->m_tStats.m_sLastMessage - 1] = '\0'; SafeDeleteArray ( sMessage ); if ( uRespStatus!=SEARCHD_WARNING ) |