From f69cc26757733724254ee37aec5a092f520d230f Mon Sep 17 00:00:00 2001 From: Varun Gupta Date: Thu, 27 Aug 2020 17:34:12 +0530 Subject: MDEV-23596: Assertion `tab->ref.use_count' failed in join_read_key_unlock_row The issue here was that the query was using ORDER BY LIMIT optimzation where the access method was changed from EQ_REF access to an index scan (index that would resolve the ORDER BY clause). But the parameter READ_RECORD::unlock_row was not reset to rr_unlock_row, which is used when the access method is not EQ_REF access. --- sql/sql_select.cc | 3 +++ 1 file changed, 3 insertions(+) (limited to 'sql') diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 4c6e87e4f27..e2e87bb1a86 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -21601,6 +21601,9 @@ check_reverse_order: else if (select && select->quick) select->quick->need_sorted_output(); + tab->read_record.unlock_row= (tab->type == JT_EQ_REF) ? + join_read_key_unlock_row : rr_unlock_row; + } // QEP has been modified /* -- cgit v1.2.1 From c710c450e3a5654244fffaabcb4ba5af2dd24dd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Fri, 28 Aug 2020 16:40:12 +0300 Subject: MDEV-21578 : CREATE OR REPLACE TRIGGER in Galera cluster not replicating While doing TOI buffer OR REPLACE option was not added to replicated string. --- sql/wsrep_mysqld.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index f95ef168a23..d392d1c2a61 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -2924,7 +2924,12 @@ static int wsrep_create_trigger_query(THD *thd, uchar** buf, size_t* buf_len) definer_host.length= 0; } - stmt_query.append(STRING_WITH_LEN("CREATE ")); + const LEX_STRING command[3]= + {{ C_STRING_WITH_LEN("CREATE ") }, + { C_STRING_WITH_LEN("ALTER ") }, + { C_STRING_WITH_LEN("CREATE OR REPLACE ") }}; + stmt_query.append(command[thd->lex->create_view_mode].str, + command[thd->lex->create_view_mode].length); append_definer(thd, &stmt_query, &definer_user, &definer_host); -- cgit v1.2.1 From 9bb17ecf4352e0ba009d6afb9260d291ed70fa4c Mon Sep 17 00:00:00 2001 From: Eugene Kosov Date: Mon, 31 Aug 2020 13:01:57 +0300 Subject: fix clang build FAILED: sql/CMakeFiles/sql.dir/sql_test.cc.o /home/kevgs/bin/clang++ -DHAVE_CONFIG_H -DHAVE_EVENT_SCHEDULER -DHAVE_POOL_OF_THREADS -DMYSQL_SERVER -D_FILE_OFFSET_BITS=64 -Iinclude -I../include -I../sql -Ipcre -I../pcre -I../zlib -Izlib -I../extra/yassl/include -I../extra/yassl/taocrypt/include -Isql -I../wsrep -O2 -fdiagnostics-color=always -fno-omit-frame-pointer -gsplit-dwarf -march=native -mtune=native -fPIC -fno-rtti -g -DENABLED_DEBUG_SYNC -ggdb3 -DSAFE_MUTEX -Wall -Wdeclaration-after-statement -Wextra -Wformat-security -Wno-init-self -Wno-null-conversion -Wno-unused-parameter -Wno-unused-private-field -Woverloaded-virtual -Wvla -Wwrite-strings -Werror -DHAVE_YASSL -DYASSL_PREFIX -DHAVE_OPENSSL -DMULTI_THREADED -MD -MT sql/CMakeFiles/sql.dir/sql_test.cc.o -MF sql/CMakeFiles/sql.dir/sql_test.cc.o.d -o sql/CMakeFiles/sql.dir/sql_test.cc.o -c ../sql/sql_test.cc ../sql/sql_test.cc:390:20: error: '::' and '*' tokens forming pointer to member type are separated by whitespace [-Werror,-Wcompound-token-split-by-space] Item* (List:: *dbug_list_item_elem_ptr)(int)= &List::elem; ~~^~ ../sql/sql_test.cc:391:32: error: '::' and '*' tokens forming pointer to member type are separated by whitespace [-Werror,-Wcompound-token-split-by-space] Item_equal* (List:: *dbug_list_item_equal_elem_ptr)(int)= ~~^~ ../sql/sql_test.cc:393:32: error: '::' and '*' tokens forming pointer to member type are separated by whitespace [-Werror,-Wcompound-token-split-by-space] TABLE_LIST* (List:: *dbug_list_table_list_elem_ptr)(int) = ~~^~ 3 errors generated. --- sql/sql_test.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/sql_test.cc b/sql/sql_test.cc index db52ce0aea1..4e68ec2ec2e 100644 --- a/sql/sql_test.cc +++ b/sql/sql_test.cc @@ -387,10 +387,10 @@ void print_sjm(SJ_MATERIALIZATION_INFO *sjm) /* Debugging help: force List<...>::elem function not be removed as unused. */ -Item* (List:: *dbug_list_item_elem_ptr)(int)= &List::elem; -Item_equal* (List:: *dbug_list_item_equal_elem_ptr)(int)= +Item* (List::*dbug_list_item_elem_ptr)(int)= &List::elem; +Item_equal* (List::*dbug_list_item_equal_elem_ptr)(int)= &List::elem; -TABLE_LIST* (List:: *dbug_list_table_list_elem_ptr)(int) = +TABLE_LIST* (List::*dbug_list_table_list_elem_ptr)(int) = &List::elem; #endif -- cgit v1.2.1 From 6112a0f93d137b9754bc04449873311784e0edd9 Mon Sep 17 00:00:00 2001 From: Andrei Elkin Date: Tue, 11 Aug 2020 21:45:09 +0300 Subject: MDEV-16372 ER_BASE64_DECODE_ERROR upon replaying binary log via mysqlbinlog --verbose (This commit is exclusively for 10.2 branch. Do not merge it to 10.3) In case of a pattern of non-STMT_END-marked Rows-log-event (A) followed by a STMT_END marked one (B) mysqlbinlog mixes up the base64 encoded rows events with their pseudo sql representation produced by the verbose option: BINLOG ' base64 encoded data for A ### verbose section for A base64 encoded data for B ### verbose section for B '/*!*/; In effect the produced BINLOG '...' query is not valid and is rejected with the error. Examples of this way malformed BINLOG could have been found in binlog_row_annotate.result that gets corrected with the patch. The issue is fixed with introduction an auxiliary IO_CACHE to hold on the verbose comments until the terminal STMT_END event is found. The new cache is emptied out after two pre-existing ones are done at that time. The correctly produced output now for the above case is as the following: BINLOG ' base64 encoded data for A base64 encoded data for B '/*!*/; ### verbose section for A ### verbose section for B Thanks to Alexey Midenkov for the problem recognition and attempt to tackle, and to Venkatesh Duggirala who produced a patch for the upstream whose idea is exploited here, as well as to MDEV-23077 reporter LukeXwang who also contributed a piece of a patch aiming at this issue. --- sql/log_event.cc | 38 +++++++++++++++----------------------- sql/log_event.h | 6 ++++-- sql/log_event_old.cc | 8 ++++++++ 3 files changed, 27 insertions(+), 25 deletions(-) (limited to 'sql') diff --git a/sql/log_event.cc b/sql/log_event.cc index 26c9cb6f9cb..e21a18273b3 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -3579,7 +3579,7 @@ void Log_event::print_base64(IO_CACHE* file, #ifdef WHEN_FLASHBACK_REVIEW_READY ev->need_flashback_review= need_flashback_review; if (print_event_info->verbose) - ev->print_verbose(file, print_event_info); + ev->print_verbose(&print_event_info->tail_cache, print_event_info); else { IO_CACHE tmp_cache; @@ -3589,18 +3589,7 @@ void Log_event::print_base64(IO_CACHE* file, } #else if (print_event_info->verbose) - { - /* - Verbose event printout can't start before encoded data - got enquoted. This is done at this point though multi-row - statement remain vulnerable. - TODO: fix MDEV-10362 to remove this workaround. - */ - if (print_event_info->base64_output_mode != - BASE64_OUTPUT_DECODE_ROWS) - my_b_printf(file, "'%s\n", print_event_info->delimiter); - ev->print_verbose(file, print_event_info); - } + ev->print_verbose(&print_event_info->tail_cache, print_event_info); #endif delete ev; } @@ -11538,11 +11527,8 @@ void copy_cache_to_string_wrapped(IO_CACHE *cache, str_tmp.length= sprintf(str_tmp.str, fmt_frag, 1); ret.append(&str_tmp); ret.append(cache, uint32(cache->end_of_file - (cache_size/2 + 1))); - if (!is_verbose) - { - str_tmp.length= sprintf(str_tmp.str, fmt_delim, delimiter); - ret.append(&str_tmp); - } + str_tmp.length= sprintf(str_tmp.str, fmt_delim, delimiter); + ret.append(&str_tmp); str_tmp.length= sprintf(str_tmp.str, "BINLOG @binlog_fragment_0, @binlog_fragment_1%s\n", delimiter); ret.append(&str_tmp); @@ -11552,11 +11538,8 @@ void copy_cache_to_string_wrapped(IO_CACHE *cache, str_tmp.length= sprintf(str_tmp.str, str_binlog); ret.append(&str_tmp); ret.append(cache, (uint32) cache->end_of_file); - if (!is_verbose) - { - str_tmp.length= sprintf(str_tmp.str, fmt_delim, delimiter); - ret.append(&str_tmp); - } + str_tmp.length= sprintf(str_tmp.str, fmt_delim, delimiter); + ret.append(&str_tmp); } to->length= ret.length(); @@ -11605,6 +11588,7 @@ void Rows_log_event::print_helper(FILE *file, { IO_CACHE *const head= &print_event_info->head_cache; IO_CACHE *const body= &print_event_info->body_cache; + IO_CACHE *const tail= &print_event_info->tail_cache; #ifdef WHEN_FLASHBACK_REVIEW_READY IO_CACHE *const sql= &print_event_info->review_sql_cache; #endif @@ -11646,6 +11630,13 @@ void Rows_log_event::print_helper(FILE *file, print_event_info->verbose); output_buf.append(&tmp_str); my_free(tmp_str.str); + if (copy_event_cache_to_string_and_reinit(tail, &tmp_str)) + { + tail->error= -1; + return; + } + output_buf.append(&tmp_str); + my_free(tmp_str.str); } } #endif @@ -14316,6 +14307,7 @@ st_print_event_info::st_print_event_info() myf const flags = MYF(MY_WME | MY_NABP); open_cached_file(&head_cache, NULL, NULL, 0, flags); open_cached_file(&body_cache, NULL, NULL, 0, flags); + open_cached_file(&tail_cache, NULL, NULL, 0, flags); #ifdef WHEN_FLASHBACK_REVIEW_READY open_cached_file(&review_sql_cache, NULL, NULL, 0, flags); #endif diff --git a/sql/log_event.h b/sql/log_event.h index 1fae201057f..3fc44a9669f 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -848,18 +848,19 @@ typedef struct st_print_event_info ~st_print_event_info() { close_cached_file(&head_cache); close_cached_file(&body_cache); + close_cached_file(&tail_cache); #ifdef WHEN_FLASHBACK_REVIEW_READY close_cached_file(&review_sql_cache); #endif } bool init_ok() /* tells if construction was successful */ - { return my_b_inited(&head_cache) && my_b_inited(&body_cache) + { return my_b_inited(&head_cache) && my_b_inited(&body_cache) && + my_b_inited(&tail_cache) #ifdef WHEN_FLASHBACK_REVIEW_READY && my_b_inited(&review_sql_cache) #endif ; } - /* Settings on how to print the events */ bool short_form; enum_base64_output_mode base64_output_mode; @@ -885,6 +886,7 @@ typedef struct st_print_event_info */ IO_CACHE head_cache; IO_CACHE body_cache; + IO_CACHE tail_cache; #ifdef WHEN_FLASHBACK_REVIEW_READY /* Storing the SQL for reviewing */ IO_CACHE review_sql_cache; diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc index b655d510bd5..2de316a4c55 100644 --- a/sql/log_event_old.cc +++ b/sql/log_event_old.cc @@ -1859,6 +1859,7 @@ void Old_rows_log_event::print_helper(FILE *file, { IO_CACHE *const head= &print_event_info->head_cache; IO_CACHE *const body= &print_event_info->body_cache; + IO_CACHE *const tail= &print_event_info->tail_cache; bool do_print_encoded= print_event_info->base64_output_mode != BASE64_OUTPUT_DECODE_ROWS && !print_event_info->short_form; @@ -1890,6 +1891,13 @@ void Old_rows_log_event::print_helper(FILE *file, print_event_info->verbose); output_buf.append(&tmp_str); my_free(tmp_str.str); + if (copy_event_cache_to_string_and_reinit(tail, &tmp_str)) + { + tail->error= -1; + return; + } + output_buf.append(&tmp_str); + my_free(tmp_str.str); } } #endif -- cgit v1.2.1 From caa35f8e25ce22d6b4f4c377970354cf582c7f41 Mon Sep 17 00:00:00 2001 From: Andrei Elkin Date: Tue, 11 Aug 2020 21:45:09 +0300 Subject: MDEV-16372 ER_BASE64_DECODE_ERROR upon replaying binary log via mysqlbinlog --verbose (This commit is for 10.3 and upper branches) In case of a pattern of non-STMT_END-marked Rows-log-event (A) followed by a STMT_END marked one (B) mysqlbinlog mixes up the base64 encoded rows events with their pseudo sql representation produced by the verbose option: BINLOG ' base64 encoded data for A ### verbose section for A base64 encoded data for B ### verbose section for B '/*!*/; In effect the produced BINLOG '...' query is not valid and is rejected with the error. Examples of this way malformed BINLOG could have been found in binlog_row_annotate.result that gets corrected with the patch. The issue is fixed with introduction an auxiliary IO_CACHE to hold on the verbose comments until the terminal STMT_END event is found. The new cache is emptied out after two pre-existing ones are done at that time. The correctly produced output now for the above case is as the following: BINLOG ' base64 encoded data for A base64 encoded data for B '/*!*/; ### verbose section for A ### verbose section for B Thanks to Alexey Midenkov for the problem recognition and attempt to tackle, and to Venkatesh Duggirala who produced a patch for the upstream whose idea is exploited here, as well as to MDEV-23077 reporter LukeXwang who also contributed a piece of a patch aiming at this issue. --- sql/log_event.cc | 37 ++++++++++++++----------------------- sql/log_event.h | 2 ++ sql/log_event_old.cc | 6 ++++-- 3 files changed, 20 insertions(+), 25 deletions(-) (limited to 'sql') diff --git a/sql/log_event.cc b/sql/log_event.cc index 4432a51b010..1e382cab55f 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -3875,7 +3875,7 @@ bool Log_event::print_base64(IO_CACHE* file, ev->need_flashback_review= need_flashback_review; if (print_event_info->verbose) { - if (ev->print_verbose(file, print_event_info)) + if (ev->print_verbose(&print_event_info->tail_cache, print_event_info)) goto err; } else @@ -3899,22 +3899,9 @@ bool Log_event::print_base64(IO_CACHE* file, } #else if (print_event_info->verbose) - { - /* - Verbose event printout can't start before encoded data - got enquoted. This is done at this point though multi-row - statement remain vulnerable. - TODO: fix MDEV-10362 to remove this workaround. - */ - if (print_event_info->base64_output_mode != - BASE64_OUTPUT_DECODE_ROWS) - my_b_printf(file, "'%s\n", print_event_info->delimiter); - error= ev->print_verbose(file, print_event_info); - } + error= ev->print_verbose(&print_event_info->tail_cache, print_event_info); else - { ev->count_row_events(print_event_info); - } #endif delete ev; if (unlikely(error)) @@ -11992,7 +11979,7 @@ bool copy_cache_to_file_wrapped(IO_CACHE *body, FILE *file, bool do_wrap, const char *delimiter, - bool is_verbose) + bool is_verbose /*TODO: remove */) { const my_off_t cache_size= my_b_tell(body); @@ -12025,8 +12012,7 @@ bool copy_cache_to_file_wrapped(IO_CACHE *body, my_fprintf(file, fmt_frag, 1); if (my_b_copy_to_file(body, file, SIZE_T_MAX)) goto err; - if (!is_verbose) - my_fprintf(file, fmt_delim, delimiter); + my_fprintf(file, fmt_delim, delimiter); my_fprintf(file, fmt_binlog2, delimiter); } @@ -12035,8 +12021,7 @@ bool copy_cache_to_file_wrapped(IO_CACHE *body, my_fprintf(file, str_binlog); if (my_b_copy_to_file(body, file, SIZE_T_MAX)) goto err; - if (!is_verbose) - my_fprintf(file, fmt_delim, delimiter); + my_fprintf(file, fmt_delim, delimiter); } reinit_io_cache(body, WRITE_CACHE, 0, FALSE, TRUE); @@ -12122,7 +12107,6 @@ bool copy_cache_to_string_wrapped(IO_CACHE *cache, goto err; str += (add_to_len= uint32(cache->end_of_file - (cache_size/2 + 1))); to->length += add_to_len; - if (!is_verbose) { str += (add_to_len= sprintf(str , fmt_delim, delimiter)); to->length += add_to_len; @@ -12138,7 +12122,6 @@ bool copy_cache_to_string_wrapped(IO_CACHE *cache, goto err; str += cache->end_of_file; to->length += (size_t)cache->end_of_file; - if (!is_verbose) to->length += sprintf(str , fmt_delim, delimiter); } @@ -12186,6 +12169,7 @@ bool Rows_log_event::print_helper(FILE *file, { IO_CACHE *const head= &print_event_info->head_cache; IO_CACHE *const body= &print_event_info->body_cache; + IO_CACHE *const tail= &print_event_info->tail_cache; #ifdef WHEN_FLASHBACK_REVIEW_READY IO_CACHE *const sql= &print_event_info->review_sql_cache; #endif @@ -12216,7 +12200,8 @@ bool Rows_log_event::print_helper(FILE *file, if (copy_event_cache_to_file_and_reinit(head, file) || copy_cache_to_file_wrapped(body, file, do_print_encoded, print_event_info->delimiter, - print_event_info->verbose)) + print_event_info->verbose) || + copy_event_cache_to_file_and_reinit(tail, file)) goto err; } else @@ -12234,6 +12219,11 @@ bool Rows_log_event::print_helper(FILE *file, return 1; output_buf.append(tmp_str.str, tmp_str.length); my_free(tmp_str.str); + if (copy_event_cache_to_string_and_reinit(tail, &tmp_str)) + return 1; + output_buf.append(tmp_str.str, tmp_str.length); + my_free(tmp_str.str); + #ifdef WHEN_FLASHBACK_REVIEW_READY if (copy_event_cache_to_string_and_reinit(sql, &tmp_str)) return 1; @@ -15056,6 +15046,7 @@ st_print_event_info::st_print_event_info() base64_output_mode=BASE64_OUTPUT_UNSPEC; open_cached_file(&head_cache, NULL, NULL, 0, flags); open_cached_file(&body_cache, NULL, NULL, 0, flags); + open_cached_file(&tail_cache, NULL, NULL, 0, flags); #ifdef WHEN_FLASHBACK_REVIEW_READY open_cached_file(&review_sql_cache, NULL, NULL, 0, flags); #endif diff --git a/sql/log_event.h b/sql/log_event.h index b9514e874e8..8a342cb5cd3 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -889,6 +889,7 @@ typedef struct st_print_event_info */ IO_CACHE head_cache; IO_CACHE body_cache; + IO_CACHE tail_cache; #ifdef WHEN_FLASHBACK_REVIEW_READY /* Storing the SQL for reviewing */ IO_CACHE review_sql_cache; @@ -899,6 +900,7 @@ typedef struct st_print_event_info ~st_print_event_info() { close_cached_file(&head_cache); close_cached_file(&body_cache); + close_cached_file(&tail_cache); #ifdef WHEN_FLASHBACK_REVIEW_READY close_cached_file(&review_sql_cache); #endif diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc index 8ec823d3d64..c71a1f39e28 100644 --- a/sql/log_event_old.cc +++ b/sql/log_event_old.cc @@ -1848,6 +1848,7 @@ bool Old_rows_log_event::print_helper(FILE *file, { IO_CACHE *const head= &print_event_info->head_cache; IO_CACHE *const body= &print_event_info->body_cache; + IO_CACHE *const tail= &print_event_info->tail_cache; bool do_print_encoded= print_event_info->base64_output_mode != BASE64_OUTPUT_DECODE_ROWS && print_event_info->base64_output_mode != BASE64_OUTPUT_NEVER && @@ -1867,8 +1868,9 @@ bool Old_rows_log_event::print_helper(FILE *file, { if (copy_event_cache_to_file_and_reinit(head, file) || copy_cache_to_file_wrapped(body, file, do_print_encoded, - print_event_info->delimiter, - print_event_info->verbose)) + print_event_info->delimiter, + print_event_info->verbose) || + copy_event_cache_to_file_and_reinit(tail, file)) goto err; } return 0; -- cgit v1.2.1 From feac078f15c0be6c0592d74d20cb65b8f5ad2f85 Mon Sep 17 00:00:00 2001 From: Andrei Elkin Date: Tue, 11 Aug 2020 21:45:09 +0300 Subject: MDEV-16372 ER_BASE64_DECODE_ERROR upon replaying binary log via mysqlbinlog --verbose (This commit is exclusively for 10.1 branch, do not merge it to upper ones) In case of a pattern of non-STMT_END-marked Rows-log-event (A) followed by a STMT_END marked one (B) mysqlbinlog mixes up the base64 encoded rows events with their pseudo sql representation produced by the verbose option: BINLOG ' base64 encoded data for A ### verbose section for A base64 encoded data for B ### verbose section for B '/*!*/; In effect the produced BINLOG '...' query is not valid and is rejected with the error. Examples of this way malformed BINLOG could have been found in binlog_row_annotate.result that gets corrected with the patch. The issue is fixed with introduction an auxiliary IO_CACHE to hold on the verbose comments until the terminal STMT_END event is found. The new cache is emptied out after two pre-existing ones are done at that time. The correctly produced output now for the above case is as the following: BINLOG ' base64 encoded data for A base64 encoded data for B '/*!*/; ### verbose section for A ### verbose section for B Thanks to Alexey Midenkov for the problem recognition and attempt to tackle, Venkatesh Duggirala who produced a patch for the upstream whose idea is exploited here, as well as to MDEV-23077 reporter LukeXwang who also contributed a piece of a patch aiming at this issue. Extra: mysqlbinlog_row_minimal refined to not produce mutable numeric values into the result file. --- sql/log_event.cc | 11 +++++++++-- sql/log_event.h | 6 +++++- sql/log_event_old.cc | 6 ++++++ 3 files changed, 20 insertions(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/log_event.cc b/sql/log_event.cc index a1a442df43f..4d7bb1726ed 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -2865,10 +2865,10 @@ void Log_event::print_base64(IO_CACHE* file, default: break; } - + if (ev) { - ev->print_verbose(file, print_event_info); + ev->print_verbose(&print_event_info->tail_cache, print_event_info); delete ev; } } @@ -10671,6 +10671,7 @@ void Rows_log_event::print_helper(FILE *file, { IO_CACHE *const head= &print_event_info->head_cache; IO_CACHE *const body= &print_event_info->body_cache; + IO_CACHE *const tail= &print_event_info->tail_cache; bool do_print_encoded= print_event_info->base64_output_mode != BASE64_OUTPUT_DECODE_ROWS && !print_event_info->short_form; @@ -10694,6 +10695,11 @@ void Rows_log_event::print_helper(FILE *file, } copy_cache_to_file_wrapped(file, body, do_print_encoded, print_event_info->delimiter); + if (copy_event_cache_to_file_and_reinit(tail, file)) + { + tail->error= -1; + return; + } } } #endif @@ -13220,6 +13226,7 @@ st_print_event_info::st_print_event_info() myf const flags = MYF(MY_WME | MY_NABP); open_cached_file(&head_cache, NULL, NULL, 0, flags); open_cached_file(&body_cache, NULL, NULL, 0, flags); + open_cached_file(&tail_cache, NULL, NULL, 0, flags); } #endif diff --git a/sql/log_event.h b/sql/log_event.h index bdac9f2e581..58e1281c179 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -781,9 +781,12 @@ typedef struct st_print_event_info ~st_print_event_info() { close_cached_file(&head_cache); close_cached_file(&body_cache); + close_cached_file(&tail_cache); } bool init_ok() /* tells if construction was successful */ - { return my_b_inited(&head_cache) && my_b_inited(&body_cache); } + { return my_b_inited(&head_cache) && + my_b_inited(&body_cache) && + my_b_inited(&tail_cache); } /* Settings on how to print the events */ @@ -811,6 +814,7 @@ typedef struct st_print_event_info */ IO_CACHE head_cache; IO_CACHE body_cache; + IO_CACHE tail_cache; } PRINT_EVENT_INFO; #endif diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc index 0a4d7227dfb..8f4f6c296c4 100644 --- a/sql/log_event_old.cc +++ b/sql/log_event_old.cc @@ -1856,6 +1856,7 @@ void Old_rows_log_event::print_helper(FILE *file, { IO_CACHE *const head= &print_event_info->head_cache; IO_CACHE *const body= &print_event_info->body_cache; + IO_CACHE *const tail= &print_event_info->tail_cache; bool do_print_encoded= print_event_info->base64_output_mode != BASE64_OUTPUT_DECODE_ROWS && !print_event_info->short_form; @@ -1879,6 +1880,11 @@ void Old_rows_log_event::print_helper(FILE *file, } copy_cache_to_file_wrapped(file, body, do_print_encoded, print_event_info->delimiter); + if (copy_event_cache_to_file_and_reinit(tail, file)) + { + tail->error= -1; + return; + } } } #endif -- cgit v1.2.1 From 97db6c15ea3e83a21df137c222dbd5a40fbe7c82 Mon Sep 17 00:00:00 2001 From: Nikita Malyavin Date: Tue, 11 Aug 2020 00:38:32 +1000 Subject: MDEV-20618 Assertion failed in row_upd_sec_index_entry Add a proper error handling of innobase_get_computed_value results in row_upd_store_row/row_upd_store_v_row. Also add an assertion in row_vers_build_clust_v_col to fail during row purge. Add one more assertion in row_sel_sec_rec_is_for_clust_rec for possible future catches. --- sql/sql_insert.cc | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'sql') diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index ec784bc6df4..0c50a251d26 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1748,15 +1748,13 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) } if (table->vfield) { - my_bool abort_on_warning= thd->abort_on_warning; /* We have not yet called update_virtual_fields(VOL_UPDATE_FOR_READ) in handler methods for the just read row in record[1]. */ table->move_fields(table->field, table->record[1], table->record[0]); - thd->abort_on_warning= 0; - table->update_virtual_fields(table->file, VCOL_UPDATE_FOR_REPLACE); - thd->abort_on_warning= abort_on_warning; + if (table->update_virtual_fields(table->file, VCOL_UPDATE_FOR_REPLACE)) + goto err; table->move_fields(table->field, table->record[0], table->record[1]); } if (info->handle_duplicates == DUP_UPDATE) -- cgit v1.2.1 From 4a165f37114eafc0cced25dfea80b3f3bccc2fbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 31 Aug 2020 16:48:28 +0300 Subject: Fix GCC 10.2.0 -Og -Wmaybe-uninitialized --- sql/opt_range.cc | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'sql') diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 6a5f1c9f750..e933d2af355 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -7555,13 +7555,15 @@ SEL_TREE *Item_bool_func::get_full_func_mm_tree(RANGE_OPT_PARAM *param, table_map param_comp= ~(param->prev_tables | param->read_tables | param->current_table); #ifdef HAVE_SPATIAL - Field::geometry_type sav_geom_type; - const bool geometry= field_item->field->type() == MYSQL_TYPE_GEOMETRY; - if (geometry) + Field::geometry_type sav_geom_type= Field::GEOM_GEOMETRY, *geom_type= + field_item->field->type() == MYSQL_TYPE_GEOMETRY + ? &(static_cast(field_item->field))->geom_type + : NULL; + if (geom_type) { - sav_geom_type= ((Field_geom*) field_item->field)->geom_type; + sav_geom_type= *geom_type; /* We have to be able to store all sorts of spatial features here */ - ((Field_geom*) field_item->field)->geom_type= Field::GEOM_GEOMETRY; + *geom_type= Field::GEOM_GEOMETRY; } #endif /*HAVE_SPATIAL*/ @@ -7592,9 +7594,9 @@ SEL_TREE *Item_bool_func::get_full_func_mm_tree(RANGE_OPT_PARAM *param, } #ifdef HAVE_SPATIAL - if (geometry) + if (geom_type) { - ((Field_geom*) field_item->field)->geom_type= sav_geom_type; + *geom_type= sav_geom_type; } #endif /*HAVE_SPATIAL*/ DBUG_RETURN(ftree); -- cgit v1.2.1 From cd36bc01a5f1c1cd126cdd0668c6049cc78be40a Mon Sep 17 00:00:00 2001 From: Sujatha Date: Wed, 26 Aug 2020 16:25:28 +0530 Subject: MDEV-23534: SIGSEGV in sf_malloc_usable_size/my_free on SET GLOBAL REPLICATE_DO_TABLE Backporting fixes for: MDEV-22317: SIGSEGV in my_free/delete_dynamic in optimized builds (ARIA) Backported following commits from: 10.5.3 commit 77e1b0c39771f47bb2602530b8d1e584ac1d3731 -- Post push fix. commit 2e6b21be4a8d0bf094da288cadff866f1bb38062 MDEV-22059: MSAN report at replicate_ignore_table_grant Backported following commits from: 10.5.4 commit 840fb495ce2c0c00b20f2a9ba44b6fcc20c56118 --- sql/rpl_filter.cc | 52 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 14 deletions(-) (limited to 'sql') diff --git a/sql/rpl_filter.cc b/sql/rpl_filter.cc index 366902c1f26..0d5d9ffeea8 100644 --- a/sql/rpl_filter.cc +++ b/sql/rpl_filter.cc @@ -349,14 +349,20 @@ Rpl_filter::set_do_table(const char* table_spec) int status; if (do_table_inited) - my_hash_reset(&do_table); + { + my_hash_free(&do_table); + do_table_inited= 0; + } status= parse_filter_rule(table_spec, &Rpl_filter::add_do_table); - if (!do_table.records) + if (do_table_inited && status) { - my_hash_free(&do_table); - do_table_inited= 0; + if (!do_table.records) + { + my_hash_free(&do_table); + do_table_inited= 0; + } } return status; @@ -369,14 +375,20 @@ Rpl_filter::set_ignore_table(const char* table_spec) int status; if (ignore_table_inited) - my_hash_reset(&ignore_table); + { + my_hash_free(&ignore_table); + ignore_table_inited= 0; + } status= parse_filter_rule(table_spec, &Rpl_filter::add_ignore_table); - if (!ignore_table.records) + if (ignore_table_inited && status) { - my_hash_free(&ignore_table); - ignore_table_inited= 0; + if (!ignore_table.records) + { + my_hash_free(&ignore_table); + ignore_table_inited= 0; + } } return status; @@ -411,14 +423,20 @@ Rpl_filter::set_wild_do_table(const char* table_spec) int status; if (wild_do_table_inited) + { free_string_array(&wild_do_table); + wild_do_table_inited= 0; + } status= parse_filter_rule(table_spec, &Rpl_filter::add_wild_do_table); - if (!wild_do_table.elements) + if (wild_do_table_inited && status) { - delete_dynamic(&wild_do_table); - wild_do_table_inited= 0; + if (!wild_do_table.elements) + { + delete_dynamic(&wild_do_table); + wild_do_table_inited= 0; + } } return status; @@ -431,14 +449,20 @@ Rpl_filter::set_wild_ignore_table(const char* table_spec) int status; if (wild_ignore_table_inited) + { free_string_array(&wild_ignore_table); + wild_ignore_table_inited= 0; + } status= parse_filter_rule(table_spec, &Rpl_filter::add_wild_ignore_table); - if (!wild_ignore_table.elements) + if (wild_ignore_table_inited && status) { - delete_dynamic(&wild_ignore_table); - wild_ignore_table_inited= 0; + if (!wild_ignore_table.elements) + { + delete_dynamic(&wild_ignore_table); + wild_ignore_table_inited= 0; + } } return status; -- cgit v1.2.1 From a256070e7d94fdd1d63a4823c638ff5c76ca9c73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 3 Sep 2020 08:41:47 +0300 Subject: MDEV-7110 follow-up fix: Do not pass NULL as nonnull parameter Passing a null pointer to the "%s" argument of a printf-like function is undefined behaviour. In the GNU libc implementation of the printf() family of functions, it happens to work. GCC 10.2.0 would diagnose this with -Wformat-overflow -Og. In -fsanitize=undefined (WITH_UBSAN=ON) builds, a runtime error would be generated. In some other builds, GCC 8 or later might infer that the parameter is nonnull and optimize away further checks whether the parameter is null, leading to SIGSEGV. --- sql/mysqld.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 6a5162e2f03..8d00b5af948 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3974,7 +3974,8 @@ rpl_make_log_name(const char *opt, const char *ext) { DBUG_ENTER("rpl_make_log_name"); - DBUG_PRINT("enter", ("opt: %s, def: %s, ext: %s", opt, def, ext)); + DBUG_PRINT("enter", ("opt: %s, def: %s, ext: %s", opt ? opt : "(null)", + def, ext)); char buff[FN_REFLEN]; const char *base= opt ? opt : def; unsigned int options= -- cgit v1.2.1 From 94a520ddbe39ae97de1135d98699cf2674e6b77e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 3 Sep 2020 09:05:56 +0300 Subject: MDEV-22387: Do not pass null pointer to some memcpy() Passing a null pointer to a nonnull argument is not only undefined behaviour, but it also grants the compiler the permission to optimize away further checks whether the pointer is null. GCC -O2 at least starting with version 8 may do that, potentially causing SIGSEGV. These problems were caught in a WITH_UBSAN=ON build with the Bug#7024 test in main.view. --- sql/debug_sync.cc | 4 +++- sql/net_serv.cc | 5 +++-- sql/sql_string.h | 5 +++-- 3 files changed, 9 insertions(+), 5 deletions(-) (limited to 'sql') diff --git a/sql/debug_sync.cc b/sql/debug_sync.cc index 591ce5800a8..79f3a241907 100644 --- a/sql/debug_sync.cc +++ b/sql/debug_sync.cc @@ -1,4 +1,5 @@ /* Copyright (c) 2009, 2013, Oracle and/or its affiliates. + Copyright (c) 2013, 2020, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -319,7 +320,8 @@ static char *debug_sync_bmove_len(char *to, char *to_end, DBUG_ASSERT(to_end); DBUG_ASSERT(!length || from); set_if_smaller(length, (size_t) (to_end - to)); - memcpy(to, from, length); + if (length) + memcpy(to, from, length); return (to + length); } diff --git a/sql/net_serv.cc b/sql/net_serv.cc index ea5e4353c83..22eee6297c9 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2016, Oracle and/or its affiliates. - Copyright (c) 2012, 2017, MariaDB Corporation + Copyright (c) 2012, 2020, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -577,7 +577,8 @@ net_write_buff(NET *net, const uchar *packet, ulong len) return net_real_write(net, packet, len) ? 1 : 0; /* Send out rest of the blocks as full sized blocks */ } - memcpy((char*) net->write_pos,packet,len); + if (len) + memcpy((char*) net->write_pos,packet,len); net->write_pos+= len; return 0; } diff --git a/sql/sql_string.h b/sql/sql_string.h index 6fd3d7a10db..fe756fe1cdf 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -3,7 +3,7 @@ /* Copyright (c) 2000, 2013, Oracle and/or its affiliates. - Copyright (c) 2008, 2013, Monty Program Ab. + Copyright (c) 2008, 2020, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -512,7 +512,8 @@ public: } void q_append(const char *data, uint32 data_len) { - memcpy(Ptr + str_length, data, data_len); + if (data_len) + memcpy(Ptr + str_length, data, data_len); str_length += data_len; } -- cgit v1.2.1 From 33ae1616e01b564d03c507769564d37c582783cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Thu, 3 Sep 2020 14:10:42 +0300 Subject: MDEV-21578 : CREATE OR REPLACE TRIGGER in Galera cluster not replicating In 10.3 OR REPLACE trigger option is part of create_info. --- sql/wsrep_mysqld.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index 20f2cd99edd..de234770788 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -2900,11 +2900,14 @@ static int wsrep_create_trigger_query(THD *thd, uchar** buf, size_t* buf_len) definer_host.length= 0; } - const LEX_CSTRING command[3]= + const LEX_CSTRING command[2]= {{ C_STRING_WITH_LEN("CREATE ") }, - { C_STRING_WITH_LEN("ALTER ") }, { C_STRING_WITH_LEN("CREATE OR REPLACE ") }}; - stmt_query.append(command[thd->lex->create_view->mode]); + + if (thd->lex->create_info.or_replace()) + stmt_query.append(command[1]); + else + stmt_query.append(command[0]); append_definer(thd, &stmt_query, &definer_user, &definer_host); -- cgit v1.2.1