diff --git a/.gitignore b/.gitignore index c26767717c621..9af0e967db756 100644 --- a/.gitignore +++ b/.gitignore @@ -340,6 +340,7 @@ x86/ build/ bld/ [Bb]in/ +/cmake-build-debug/ [Oo]bj/ # Roslyn cache directories @@ -521,4 +522,5 @@ compile_commands.json # Visual Studio Code workspace .vscode/ +/.idea/ .cache/clangd diff --git a/client/mysql.cc b/client/mysql.cc index 21060013c7515..31b56441f23ec 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -1683,11 +1683,14 @@ static struct my_option my_long_options[] = &opt_default_auth, &opt_default_auth, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"binary-mode", 0, - "By default, ASCII '\\0' is disallowed and '\\r\\n' is translated to '\\n'. " - "This switch turns off both features, and also turns off parsing of all client" - "commands except \\C and DELIMITER, in non-interactive mode (for input " - "piped to mysql or loaded using the 'source' command). This is necessary " - "when processing output from mysqlbinlog that may contain blobs.", + "Binary mode allows certain character sequences to be processed as data " + "that would otherwise be treated with a special meaning by the parser. " + "Specifically, this switch turns off parsing of all client commands except " + "\\C and DELIMITER in non-interactive mode (i.e., when binary mode is " + "combined with either 1) piped input, 2) the --batch mysql option, or 3) " + "the 'source' command). Also, in binary mode, occurrences of '\\r\\n' and " + "ASCII '\\0' are preserved within strings, whereas by default, '\\r\\n' is " + "translated to '\\n' and '\\0' is disallowed in user input.", &opt_binary_mode, &opt_binary_mode, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; diff --git a/include/ft_global.h b/include/ft_global.h index 725363c3aa8bb..9f2d52610ba86 100644 --- a/include/ft_global.h +++ b/include/ft_global.h @@ -90,7 +90,8 @@ void ft_free_stopwords(void); FT_INFO *ft_init_search(uint,void *, uint, uchar *, size_t, CHARSET_INFO *, uchar *); -my_bool ft_boolean_check_syntax_string(const uchar *); +my_bool ft_boolean_check_syntax_string(const uchar *, size_t length, + CHARSET_INFO *cs); /* Internal symbols for fulltext between maria and MyISAM */ diff --git a/include/my_context.h b/include/my_context.h index ea0e3496887ff..45d2a7d7ffa02 100644 --- a/include/my_context.h +++ b/include/my_context.h @@ -52,6 +52,9 @@ struct my_context { #ifdef MY_CONTEXT_USE_UCONTEXT +#if defined(__APPLE__) && !defined(_XOPEN_SOURCE) +#define _XOPEN_SOURCE +#endif #include struct my_context { diff --git a/include/my_global.h b/include/my_global.h index b96a04f45665a..9eb12ee003bd6 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -164,7 +164,7 @@ # if defined(__i386__) || defined(__ppc__) # define SIZEOF_CHARP 4 # define SIZEOF_LONG 4 -# elif defined(__x86_64__) || defined(__ppc64__) +# elif defined(__x86_64__) || defined(__ppc64__) || defined(__aarch64__) # define SIZEOF_CHARP 8 # define SIZEOF_LONG 8 # else diff --git a/man/mysql.1 b/man/mysql.1 index 888deb7871194..3ae8fdf9d6943 100644 --- a/man/mysql.1 +++ b/man/mysql.1 @@ -206,7 +206,14 @@ option\&. .\" binary-mode option: mysql \fB\-\-binary\-mode\fR .sp -By default, ASCII '\e0' is disallowed and '\er\en' is translated to '\en'\&. This switch turns off both features, and also turns off parsing of all client commands except \eC and DELIMITER, in non-interactive mode (for input piped to mysql or loaded using the 'source' command)\&. This is necessary when processing output from mysqlbinlog that may contain blobs\&. +Binary mode allows certain character sequences to be processed as data that +would otherwise be treated with a special meaning by the parser\&. +Specifically, this switch turns off parsing of all client commands except \eC +and DELIMITER in non-interactive mode (i\&.e\&., when binary mode is combined +with either 1) piped input, 2) the --batch mysql option, or 3) the 'source' +command)\&. Also, in binary mode, occurrences of '\er\en' and ASCII '\e0' are +preserved within strings, whereas by default, '\er\en' is translated to '\en' +and '\e0' is disallowed in user input\&. .RE .sp .RS 4 diff --git a/mysql-test/main/ctype_utf16_def.result b/mysql-test/main/ctype_utf16_def.result index 98b6f7d913de9..b5827d45619a7 100644 --- a/mysql-test/main/ctype_utf16_def.result +++ b/mysql-test/main/ctype_utf16_def.result @@ -8,3 +8,8 @@ character_set_server utf16 SHOW VARIABLES LIKE 'ft_stopword_file'; Variable_name Value ft_stopword_file (built-in) +# +# MDEV-23269 SIGSEGV in ft_boolean_check_syntax_string on setting ft_boolean_syntax +# +SET GLOBAL ft_boolean_syntax='+ -><()~*:""&|'; +SET GLOBAL ft_boolean_syntax=DEFAULT; diff --git a/mysql-test/main/ctype_utf16_def.test b/mysql-test/main/ctype_utf16_def.test index 0829cd53285a8..c6de842f618ff 100644 --- a/mysql-test/main/ctype_utf16_def.test +++ b/mysql-test/main/ctype_utf16_def.test @@ -7,3 +7,10 @@ call mtr.add_suppression("'utf16' can not be used as client character set"); SHOW VARIABLES LIKE 'collation_server'; SHOW VARIABLES LIKE 'character_set_server'; SHOW VARIABLES LIKE 'ft_stopword_file'; + +--echo # +--echo # MDEV-23269 SIGSEGV in ft_boolean_check_syntax_string on setting ft_boolean_syntax +--echo # + +SET GLOBAL ft_boolean_syntax='+ -><()~*:""&|'; +SET GLOBAL ft_boolean_syntax=DEFAULT; diff --git a/mysql-test/main/ctype_utf32_def.opt b/mysql-test/main/ctype_utf32_def.opt new file mode 100644 index 0000000000000..3b0880cbff3a8 --- /dev/null +++ b/mysql-test/main/ctype_utf32_def.opt @@ -0,0 +1 @@ +--character-set-server=utf32,latin1 --collation-server=utf32_general_ci diff --git a/mysql-test/main/ctype_utf32_def.result b/mysql-test/main/ctype_utf32_def.result new file mode 100644 index 0000000000000..611072eb75b4b --- /dev/null +++ b/mysql-test/main/ctype_utf32_def.result @@ -0,0 +1,6 @@ +call mtr.add_suppression("'utf32' can not be used as client character set"); +# +# MDEV-23269 SIGSEGV in ft_boolean_check_syntax_string on setting ft_boolean_syntax +# +SET GLOBAL ft_boolean_syntax='+ -><()~*:""&|'; +SET GLOBAL ft_boolean_syntax=DEFAULT; diff --git a/mysql-test/main/ctype_utf32_def.test b/mysql-test/main/ctype_utf32_def.test new file mode 100644 index 0000000000000..e23f96052d3fe --- /dev/null +++ b/mysql-test/main/ctype_utf32_def.test @@ -0,0 +1,9 @@ +--source include/have_utf32.inc +call mtr.add_suppression("'utf32' can not be used as client character set"); + +--echo # +--echo # MDEV-23269 SIGSEGV in ft_boolean_check_syntax_string on setting ft_boolean_syntax +--echo # + +SET GLOBAL ft_boolean_syntax='+ -><()~*:""&|'; +SET GLOBAL ft_boolean_syntax=DEFAULT; diff --git a/mysql-test/main/default.result b/mysql-test/main/default.result index f5ee1474b94c2..596853804065e 100644 --- a/mysql-test/main/default.result +++ b/mysql-test/main/default.result @@ -3389,6 +3389,14 @@ CREATE OR REPLACE TABLE t1(i int); ALTER TABLE t1 ADD b CHAR(255) DEFAULT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`; ERROR 42S22: Unknown column 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' in 'DEFAULT' DROP TABLE t1; +# +# MDEV-18278 Misleading error message in error log upon failed table creation +# +create table t1 (a int as (a)); +ERROR 01000: Expression for field `a` is referring to uninitialized field `a` +show warnings; +Level Code Message +Error 4029 Expression for field `a` is referring to uninitialized field `a` # end of 10.2 test # # MDEV-22703 DEFAULT() on a BLOB column can overwrite the default @@ -3405,3 +3413,4 @@ length(DEFAULT(h)) 25 INSERT INTO t1 () VALUES (); drop table t1; +# end of 10.3 test diff --git a/mysql-test/main/default.test b/mysql-test/main/default.test index c0561deac67a4..bcd6ef7a9fb5b 100644 --- a/mysql-test/main/default.test +++ b/mysql-test/main/default.test @@ -2109,6 +2109,13 @@ CREATE OR REPLACE TABLE t1(i int); ALTER TABLE t1 ADD b CHAR(255) DEFAULT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`; DROP TABLE t1; +--echo # +--echo # MDEV-18278 Misleading error message in error log upon failed table creation +--echo # +--error ER_EXPRESSION_REFERS_TO_UNINIT_FIELD +create table t1 (a int as (a)); +show warnings; + --echo # end of 10.2 test --echo # @@ -2126,3 +2133,5 @@ SELECT DEFAULT(h) FROM t1; SELECT length(DEFAULT(h)) FROM t1; INSERT INTO t1 () VALUES (); drop table t1; + +--echo # end of 10.3 test diff --git a/mysql-test/main/delayed_blob.opt b/mysql-test/main/delayed_blob.opt new file mode 100644 index 0000000000000..e442a822046aa --- /dev/null +++ b/mysql-test/main/delayed_blob.opt @@ -0,0 +1 @@ +--init_connect="set @a='something unique to have MTR start a dedicated mariadbd for this test and shutdown it after the test'" diff --git a/mysql-test/main/delayed_blob.result b/mysql-test/main/delayed_blob.result new file mode 100644 index 0000000000000..caa2e3ae5fe12 --- /dev/null +++ b/mysql-test/main/delayed_blob.result @@ -0,0 +1,17 @@ +# +# MDEV-25925 Warning: Memory not freed: 32 on INSERT DELAYED +# +SET sql_mode='TRADITIONAL'; +CREATE TABLE t1 (c BLOB) ENGINE=MyISAM; +INSERT DELAYED INTO t1 VALUES (''||''); +ERROR 22007: Truncated incorrect DOUBLE value: '' +DROP TABLE t1; +SET sql_mode=DEFAULT; +# +# MDEV-24467 Memory not freed after failed INSERT DELAYED +# +CREATE TABLE t1 (a VARCHAR(1)) ENGINE=MyISAM; +ALTER TABLE t1 ADD b BLOB DEFAULT 'x'; +INSERT DELAYED INTO t1 (a) VALUES ('foo'); +ERROR 22001: Data too long for column 'a' at row 1 +DROP TABLE t1; diff --git a/mysql-test/main/delayed_blob.test b/mysql-test/main/delayed_blob.test new file mode 100644 index 0000000000000..bf3e01a88253b --- /dev/null +++ b/mysql-test/main/delayed_blob.test @@ -0,0 +1,21 @@ +--echo # +--echo # MDEV-25925 Warning: Memory not freed: 32 on INSERT DELAYED +--echo # + +SET sql_mode='TRADITIONAL'; +CREATE TABLE t1 (c BLOB) ENGINE=MyISAM; +--error ER_TRUNCATED_WRONG_VALUE +INSERT DELAYED INTO t1 VALUES (''||''); +DROP TABLE t1; +SET sql_mode=DEFAULT; + + +--echo # +--echo # MDEV-24467 Memory not freed after failed INSERT DELAYED +--echo # + +CREATE TABLE t1 (a VARCHAR(1)) ENGINE=MyISAM; +ALTER TABLE t1 ADD b BLOB DEFAULT 'x'; +--error ER_DATA_TOO_LONG +INSERT DELAYED INTO t1 (a) VALUES ('foo'); +DROP TABLE t1; diff --git a/mysql-test/main/func_str.result b/mysql-test/main/func_str.result index eccec315a4517..23ec1724d59e5 100644 --- a/mysql-test/main/func_str.result +++ b/mysql-test/main/func_str.result @@ -5014,6 +5014,18 @@ DROP TABLE t1; # End of 10.1 tests # # +# Start of 10.2 tests +# +# +# MDEV-24742 Server crashes in Charset::numchars / String::numchars +# +SELECT NULL IN (RIGHT(AES_ENCRYPT('foo','bar'), LAST_INSERT_ID()), 'qux'); +NULL IN (RIGHT(AES_ENCRYPT('foo','bar'), LAST_INSERT_ID()), 'qux') +NULL +# +# End of 10.2 tests +# +# # Start of 10.3 tests # # diff --git a/mysql-test/main/func_str.test b/mysql-test/main/func_str.test index 8f8628f714274..b65cc98ff5a43 100644 --- a/mysql-test/main/func_str.test +++ b/mysql-test/main/func_str.test @@ -1987,6 +1987,22 @@ DROP TABLE t1; --echo # +--echo # +--echo # Start of 10.2 tests +--echo # + +--echo # +--echo # MDEV-24742 Server crashes in Charset::numchars / String::numchars +--echo # + +SELECT NULL IN (RIGHT(AES_ENCRYPT('foo','bar'), LAST_INSERT_ID()), 'qux'); + + +--echo # +--echo # End of 10.2 tests +--echo # + + --echo # --echo # Start of 10.3 tests --echo # diff --git a/mysql-test/suite/innodb/r/mdev-14846.result b/mysql-test/suite/innodb/r/mdev-14846.result new file mode 100644 index 0000000000000..219bd718febe9 --- /dev/null +++ b/mysql-test/suite/innodb/r/mdev-14846.result @@ -0,0 +1,52 @@ +CREATE TABLE t1 ( +pk INT, +f1 VARCHAR(10) NOT NULL, +f2 VARCHAR(10) NULL, +f3 INT UNSIGNED NULL, +KEY (f1), +PRIMARY KEY (pk) +) ENGINE=InnoDB; +CREATE OR REPLACE ALGORITHM=MERGE VIEW v4 AS SELECT * FROM t1; +INSERT INTO t1 VALUES (1,'k','g',6),(2,'y','r',0),(3,'t','q',1),(4,'a','r',NULL),(5,'z','t',NULL); +CREATE TABLE t2 (f VARCHAR(10) NULL) ENGINE=InnoDB; +INSERT INTO t2 VALUES (NULL),('g'),('e'),('g'); +CREATE TABLE t3 ( +f1 VARCHAR(10) NOT NULL, +f2 VARCHAR(10) NULL, +f3 INT UNSIGNED NULL +) ENGINE=InnoDB; +INSERT INTO t3 VALUES ('k','n',9),('y','b',8),('m','w',6); +CREATE TABLE t4 (f INT NULL) ENGINE=InnoDB; +INSERT INTO t4 VALUES (8),(9); +UPDATE t1 SET t1.pk = -109 WHERE t1.f1 IN ( SELECT 'a' FROM t4 WHERE f >= 1 ); +SET DEBUG_SYNC='now SIGNAL con1_dml'; +connect con1,localhost,root,,test; +SET DEBUG_SYNC='now WAIT_FOR con1_dml'; +begin; +SELECT * FROM t1 for update; +pk f1 f2 f3 +-109 a r NULL +1 k g 6 +2 y r 0 +3 t q 1 +5 z t NULL +SET DEBUG_SYNC='now SIGNAL default_dml'; +connection default; +SET DEBUG_SYNC='now WAIT_FOR default_dml'; +UPDATE t3 AS alias1 LEFT JOIN t3 AS alias2 ON ( alias1.f1 <> alias1.f2 ) SET alias1.f3 = 59 WHERE ( EXISTS ( SELECT t1.f3 FROM t1 WHERE t1.f1 = alias1.f1 ) ) OR alias2.f1 = 'h'; +connect con2,localhost,root,,test; +set debug_sync='now WAIT_FOR default_dml'; +SET DEBUG_SYNC='now SIGNAL con1_dml2'; +disconnect con2; +connection con1; +SET DEBUG_SYNC='now WAIT_FOR con1_dml2'; +UPDATE v4, t1 SET t1.pk = 76 WHERE t1.f2 IN ( SELECT t2.f FROM t2 INNER JOIN t3 ); +connection default; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +connection con1; +COMMIT; +disconnect con1; +connection default; +DROP VIEW v4; +DROP TABLE t1, t2, t3, t4; +set debug_sync= reset; diff --git a/mysql-test/suite/innodb/t/mdev-14846.opt b/mysql-test/suite/innodb/t/mdev-14846.opt new file mode 100644 index 0000000000000..c8fe05613901a --- /dev/null +++ b/mysql-test/suite/innodb/t/mdev-14846.opt @@ -0,0 +1 @@ +--loose-innodb_lock_waits diff --git a/mysql-test/suite/innodb/t/mdev-14846.test b/mysql-test/suite/innodb/t/mdev-14846.test new file mode 100644 index 0000000000000..adcefecd52f25 --- /dev/null +++ b/mysql-test/suite/innodb/t/mdev-14846.test @@ -0,0 +1,70 @@ +--source include/have_innodb.inc +--source include/count_sessions.inc +--source include/have_debug_sync.inc + +CREATE TABLE t1 ( + pk INT, + f1 VARCHAR(10) NOT NULL, + f2 VARCHAR(10) NULL, + f3 INT UNSIGNED NULL, + KEY (f1), + PRIMARY KEY (pk) +) ENGINE=InnoDB; + +CREATE OR REPLACE ALGORITHM=MERGE VIEW v4 AS SELECT * FROM t1; +INSERT INTO t1 VALUES (1,'k','g',6),(2,'y','r',0),(3,'t','q',1),(4,'a','r',NULL),(5,'z','t',NULL); + +CREATE TABLE t2 (f VARCHAR(10) NULL) ENGINE=InnoDB; +INSERT INTO t2 VALUES (NULL),('g'),('e'),('g'); + +CREATE TABLE t3 ( + f1 VARCHAR(10) NOT NULL, + f2 VARCHAR(10) NULL, + f3 INT UNSIGNED NULL +) ENGINE=InnoDB; + +INSERT INTO t3 VALUES ('k','n',9),('y','b',8),('m','w',6); + +CREATE TABLE t4 (f INT NULL) ENGINE=InnoDB; +INSERT INTO t4 VALUES (8),(9); +UPDATE t1 SET t1.pk = -109 WHERE t1.f1 IN ( SELECT 'a' FROM t4 WHERE f >= 1 ); +SET DEBUG_SYNC='now SIGNAL con1_dml'; + +--connect (con1,localhost,root,,test) +SET DEBUG_SYNC='now WAIT_FOR con1_dml'; +begin; +SELECT * FROM t1 for update; # Holds x lock of all records in the table t1 +SET DEBUG_SYNC='now SIGNAL default_dml'; + +--connection default +SET DEBUG_SYNC='now WAIT_FOR default_dml'; +--send UPDATE t3 AS alias1 LEFT JOIN t3 AS alias2 ON ( alias1.f1 <> alias1.f2 ) SET alias1.f3 = 59 WHERE ( EXISTS ( SELECT t1.f3 FROM t1 WHERE t1.f1 = alias1.f1 ) ) OR alias2.f1 = 'h' +# It holds the lock of all record in t3 and tries to acquire record lock for the table t1. + +--connect (con2,localhost,root,,test) +set debug_sync='now WAIT_FOR default_dml'; +let $wait_condition= +select count(*) > 0 from information_schema.innodb_lock_waits; +--source include/wait_condition.inc +SET DEBUG_SYNC='now SIGNAL con1_dml2'; +disconnect con2; + +# Cleanup +--connection con1 +SET DEBUG_SYNC='now WAIT_FOR con1_dml2'; +UPDATE v4, t1 SET t1.pk = 76 WHERE t1.f2 IN ( SELECT t2.f FROM t2 INNER JOIN t3 ); +# It holds the record lock on table t1 and tries to acquire record lock on t3. +# leads to deadlock (con1 trx is waiting for default trx and vice versa) + +--connection default +--error ER_LOCK_DEADLOCK +--reap + +connection con1; +COMMIT; +disconnect con1; + +--connection default +DROP VIEW v4; +DROP TABLE t1, t2, t3, t4; +set debug_sync= reset; diff --git a/mysql-test/suite/plugins/r/feedback_plugin_send.result b/mysql-test/suite/plugins/r/feedback_plugin_send.result index 70dfbcb62dc31..fec42f577adf6 100644 --- a/mysql-test/suite/plugins/r/feedback_plugin_send.result +++ b/mysql-test/suite/plugins/r/feedback_plugin_send.result @@ -24,6 +24,22 @@ VARIABLE_VALUE>0 VARIABLE_NAME 1 Collation used latin1_swedish_ci 1 Collation used utf8_bin 1 Collation used utf8_general_ci +prepare stmt from "SELECT VARIABLE_VALUE>0, VARIABLE_NAME FROM INFORMATION_SCHEMA.FEEDBACK WHERE VARIABLE_NAME LIKE 'Collation used %' ORDER BY VARIABLE_NAME"; +execute stmt; +VARIABLE_VALUE>0 VARIABLE_NAME +1 Collation used binary +1 Collation used latin1_bin +1 Collation used latin1_swedish_ci +1 Collation used utf8_bin +1 Collation used utf8_general_ci +execute stmt; +VARIABLE_VALUE>0 VARIABLE_NAME +1 Collation used binary +1 Collation used latin1_bin +1 Collation used latin1_swedish_ci +1 Collation used utf8_bin +1 Collation used utf8_general_ci +deallocate prepare stmt; set global sql_mode=ONLY_FULL_GROUP_BY; -6: feedback plugin: report to 'http://mariadb.org/feedback_plugin/post' was sent -6: feedback plugin: server replied 'ok' +feedback plugin: report to 'http://mariadb.org/feedback_plugin/post' was sent +feedback plugin: server replied 'ok' diff --git a/mysql-test/suite/plugins/t/feedback_plugin_send.test b/mysql-test/suite/plugins/t/feedback_plugin_send.test index b28f9d4cb38d4..0ea1814ec29d2 100644 --- a/mysql-test/suite/plugins/t/feedback_plugin_send.test +++ b/mysql-test/suite/plugins/t/feedback_plugin_send.test @@ -38,6 +38,6 @@ perl; while ($_=) { $logg{$&}++ if /feedback plugin:.*/; } - print "$logg{$_}: $_\n" for sort keys %logg; + print "$_\n" for sort keys %logg; close LOG; EOF diff --git a/mysys/my_context.c b/mysys/my_context.c index 5423f59d19bd9..4153927d3353c 100644 --- a/mysys/my_context.c +++ b/mysys/my_context.c @@ -29,6 +29,10 @@ #endif #ifdef MY_CONTEXT_USE_UCONTEXT +#ifdef __APPLE__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif /* The makecontext() only allows to pass integers into the created context :-( We want to pass pointers, so we do it this kinda hackish way. @@ -154,6 +158,9 @@ my_context_destroy(struct my_context *c) DBUG_FREE_CODE_STATE(&c->dbug_state); } +#ifdef __APPLE__ +#pragma GCC diagnostic pop +#endif #endif /* MY_CONTEXT_USE_UCONTEXT */ diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 361feb9055deb..4591fb7801e71 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -359,6 +359,8 @@ String *Item_aes_crypt::val_str(String *str2) rkey, AES_KEY_LENGTH / 8, 0, 0)) { str2->length((uint) aes_length); + DBUG_ASSERT(collation.collation == &my_charset_bin); + str2->set_charset(&my_charset_bin); return str2; } } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index f53bb9f7451ec..a00b3004cc113 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -9808,7 +9808,9 @@ static int get_options(int *argc_ptr, char ***argv_ptr) if (global_system_variables.low_priority_updates) thr_upgraded_concurrent_insert_lock= TL_WRITE_LOW_PRIORITY; - if (ft_boolean_check_syntax_string((uchar*) ft_boolean_syntax)) + if (ft_boolean_check_syntax_string((uchar*) ft_boolean_syntax, + strlen(ft_boolean_syntax), + system_charset_info)) { sql_print_error("Invalid ft-boolean-syntax string: %s\n", ft_boolean_syntax); diff --git a/sql/sql_explain.h b/sql/sql_explain.h index 97fe07572cf8a..73b9eb1943529 100644 --- a/sql/sql_explain.h +++ b/sql/sql_explain.h @@ -121,11 +121,13 @@ class Explain_node : public Sql_alloc */ enum explain_connection_type connection_type; +protected: /* A node may have children nodes. When a node's explain structure is created, children nodes may not yet have QPFs. This is why we store ids. */ Dynamic_array children; +public: void add_child(int select_no) { children.append(select_no); diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index f8b91df794147..201567c085355 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1266,7 +1266,18 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, abort: #ifndef EMBEDDED_LIBRARY if (lock_type == TL_WRITE_DELAYED) + { end_delayed_insert(thd); + /* + In case of an error (e.g. data truncation), the data type specific data + in fields (e.g. Field_blob::value) was not taken over + by the delayed writer thread. All fields in table_list->table + will be freed by free_root() soon. We need to free the specific + data before free_root() to avoid a memory leak. + */ + for (Field **ptr= table_list->table->field ; *ptr ; ptr++) + (*ptr)->free(); + } #endif if (table != NULL) table->file->ha_release_auto_increment(); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index e44ba4b59e113..c943de1139401 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -19996,26 +19996,33 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab, will be re-evaluated again. It could be fixed, but, probably, it's not worth doing now. */ - if (tab->select_cond && !tab->select_cond->val_int()) + if (tab->select_cond) { - /* The condition attached to table tab is false */ - if (tab == join_tab) - { - found= 0; - if (not_exists_opt_is_applicable) - DBUG_RETURN(NESTED_LOOP_NO_MORE_ROWS); - } - else + const longlong res= tab->select_cond->val_int(); + if (join->thd->is_error()) + DBUG_RETURN(NESTED_LOOP_ERROR); + + if (!res) { - /* - Set a return point if rejected predicate is attached - not to the last table of the current nest level. - */ - join->return_tab= tab; - if (not_exists_opt_is_applicable) - DBUG_RETURN(NESTED_LOOP_NO_MORE_ROWS); + /* The condition attached to table tab is false */ + if (tab == join_tab) + { + found= 0; + if (not_exists_opt_is_applicable) + DBUG_RETURN(NESTED_LOOP_NO_MORE_ROWS); + } else - DBUG_RETURN(NESTED_LOOP_OK); + { + /* + Set a return point if rejected predicate is attached + not to the last table of the current nest level. + */ + join->return_tab= tab; + if (not_exists_opt_is_applicable) + DBUG_RETURN(NESTED_LOOP_NO_MORE_ROWS); + else + DBUG_RETURN(NESTED_LOOP_OK); + } } } } diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index f873fd224fcf7..86d02fe11c5f5 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -1095,7 +1095,9 @@ static Sys_var_ulong Sys_flush_time( static bool check_ftb_syntax(sys_var *self, THD *thd, set_var *var) { return ft_boolean_check_syntax_string((uchar*) - (var->save_result.string_value.str)); + (var->save_result.string_value.str), + var->save_result.string_value.length, + self->charset(thd)); } static bool query_cache_flush(sys_var *self, THD *thd, enum_var_type type) { diff --git a/sql/table.cc b/sql/table.cc index 0bef0fc29a1ba..e4501870a2b80 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1167,7 +1167,10 @@ bool parse_vcol_defs(THD *thd, MEM_ROOT *mem_root, TABLE *table, if (check_vcol_forward_refs(field, field->vcol_info, 0) || check_vcol_forward_refs(field, field->check_constraint, 1) || check_vcol_forward_refs(field, field->default_value, 0)) + { + *error_reported= true; goto end; + } } res=0; diff --git a/storage/connect/bsonudf.cpp b/storage/connect/bsonudf.cpp index 0c7112ee15f9e..771e72b8dbd34 100644 --- a/storage/connect/bsonudf.cpp +++ b/storage/connect/bsonudf.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include "bsonudf.h" @@ -621,7 +622,7 @@ PVAL BJNX::GetCalcValue(PGLOBAL g, PBVAL bap, int n) { // For calculated arrays, a local Value must be used int lng = 0; - short type, prec = 0; + short type = 0, prec = 0; bool b = n < Nod - 1; PVAL valp; PBVAL vlp, vp; @@ -690,7 +691,7 @@ PVAL BJNX::GetCalcValue(PGLOBAL g, PBVAL bap, int n) break; default: - break; + DBUG_ASSERT(!"Implement new op type support."); } // endswitch Op return valp = AllocateValue(g, type, lng, prec); @@ -4978,7 +4979,7 @@ char *bbin_array_add(UDF_INIT *initid, UDF_ARGS *args, char *result, uint n = 2; int* x = GetIntArgPtr(g, args, n); BJNX bnx(g, NULL, TYPE_STRING); - PBVAL jarp, top, jvp = NULL; + PBVAL jarp = NULL, top = NULL, jvp = NULL; PBVAL jsp = bnx.MakeValue(args, 0, true, &top); if (bnx.CheckPath(g, args, jsp, jvp, 2)) @@ -5611,7 +5612,7 @@ char *bbin_object_values(UDF_INIT *initid, UDF_ARGS *args, char *result, if (!bsp) { if (!CheckMemory(g, initid, args, 1, true, true)) { BJNX bnx(g); - PBVAL top, jarp; + PBVAL top, jarp = NULL; PBVAL jvp = bnx.MakeValue(args, 0, true, &top); if (jvp->Type == TYPE_JOB) { diff --git a/storage/connect/inihandl.cpp b/storage/connect/inihandl.cpp index 8e79aeac7ef89..7d8741ebfa34c 100644 --- a/storage/connect/inihandl.cpp +++ b/storage/connect/inihandl.cpp @@ -193,17 +193,17 @@ static void PROFILE_Save( FILE *file, PROFILESECTION *section ) secno++; } - for (key = section->key; key; key = key->next) - if (key->name && key->name[0]) { + for (key= section->key; key; key= key->next) { + if (key->name[0]) { fprintf(file, "%s", SVP(key->name)); if (key->value) fprintf(file, "=%s", SVP(key->value)); fprintf(file, "\n"); - } // endif key->name - - } // endfor section + } // endif key->name + } + } // endfor section } // end of PROFILE_Save diff --git a/storage/connect/tabbson.cpp b/storage/connect/tabbson.cpp index 3b1f1c84d1a81..a7c561318c783 100644 --- a/storage/connect/tabbson.cpp +++ b/storage/connect/tabbson.cpp @@ -871,7 +871,7 @@ PBVAL BCUTIL::MakeBson(PGLOBAL g, PBVAL jsp, int n) /***********************************************************************/ PBVAL BCUTIL::GetRowValue(PGLOBAL g, PBVAL row, int i) { - int nod = Cp->Nod, n = nod - 1; + int nod = Cp->Nod; JNODE *nodes = Cp->Nodes; PBVAL arp; PBVAL bvp = NULL; diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc index 72fbf1393000e..e2a40b06ba42d 100644 --- a/storage/innobase/log/log0log.cc +++ b/storage/innobase/log/log0log.cc @@ -800,13 +800,9 @@ log_write_buf( /** Flush the recently written changes to the log file. and invoke log_mutex_enter(). */ -static -void -log_write_flush_to_disk_low() +static void log_write_flush_to_disk_low() { - /* FIXME: This is not holding log_sys.mutex while - calling os_event_set()! */ - ut_a(log_sys.n_pending_flushes == 1); /* No other threads here */ + ut_a(log_sys.n_pending_flushes); bool do_flush = srv_file_flush_method != SRV_O_DSYNC; @@ -814,7 +810,6 @@ log_write_flush_to_disk_low() fil_flush(SRV_LOG_SPACE_FIRST_ID); } - log_mutex_enter(); if (do_flush) { log_sys.flushed_to_disk_lsn = log_sys.current_flush_lsn; @@ -1128,7 +1123,7 @@ ATTRIBUTE_COLD void log_write_and_flush() /* Code adapted from log_write_flush_to_disk_low() */ - ut_a(log_sys.n_pending_flushes == 1); /* No other threads here */ + ut_a(log_sys.n_pending_flushes); if (srv_file_flush_method != SRV_O_DSYNC) fil_flush(SRV_LOG_SPACE_FIRST_ID); diff --git a/storage/myisam/ft_parser.c b/storage/myisam/ft_parser.c index b400990d93462..bc50301fab249 100644 --- a/storage/myisam/ft_parser.c +++ b/storage/myisam/ft_parser.c @@ -78,18 +78,25 @@ FT_WORD * ft_linearize(TREE *wtree, MEM_ROOT *mem_root) DBUG_RETURN(wlist); } -my_bool ft_boolean_check_syntax_string(const uchar *str) +my_bool ft_boolean_check_syntax_string(const uchar *str, size_t length, + CHARSET_INFO *cs) { uint i, j; + if (cs->mbminlen != 1) + { + DBUG_ASSERT(0); + return 1; + } + if (!str || - (strlen((char*) str)+1 != sizeof(DEFAULT_FTB_SYNTAX)) || + (length + 1 != sizeof(DEFAULT_FTB_SYNTAX)) || (str[0] != ' ' && str[1] != ' ')) return 1; for (i=0; i 127 || my_isalnum(default_charset_info, str[i])) + if ((unsigned char)(str[i]) > 127 || my_isalnum(cs, str[i])) return 1; for (j=0; j