diff options
author | Nikita Malyavin <nikitamalyavin@gmail.com> | 2021-05-05 23:03:01 +0300 |
---|---|---|
committer | Nikita Malyavin <nikitamalyavin@gmail.com> | 2021-05-05 23:03:01 +0300 |
commit | 509e4990af4d99e9d3c790eabe1c1705ae910b55 (patch) | |
tree | 02d4ca9409711baef3ec163adc402f2c380df7c8 /sql | |
parent | 0cc811c633d1fe5290b10fa49fad0a4b889383fa (diff) | |
parent | 4f143a88bcb36e94e9edba8a3c5b4a350dcd9bf9 (diff) | |
download | mariadb-git-509e4990af4d99e9d3c790eabe1c1705ae910b55.tar.gz |
Merge branch bb-10.3-release into bb-10.4-release
Diffstat (limited to 'sql')
-rw-r--r-- | sql/field.h | 5 | ||||
-rw-r--r-- | sql/item_create.cc | 15 | ||||
-rw-r--r-- | sql/item_create.h | 1 | ||||
-rw-r--r-- | sql/item_vers.cc | 16 | ||||
-rw-r--r-- | sql/item_vers.h | 30 | ||||
-rw-r--r-- | sql/log_event.cc | 17 | ||||
-rw-r--r-- | sql/log_event.h | 13 | ||||
-rw-r--r-- | sql/sp_head.h | 2 | ||||
-rw-r--r-- | sql/sql_acl.cc | 6 | ||||
-rw-r--r-- | sql/sql_base.cc | 3 | ||||
-rw-r--r-- | sql/sql_class.cc | 2 | ||||
-rw-r--r-- | sql/sql_class.h | 4 | ||||
-rw-r--r-- | sql/sql_derived.cc | 6 | ||||
-rw-r--r-- | sql/sql_insert.cc | 5 | ||||
-rw-r--r-- | sql/sql_lex.cc | 74 | ||||
-rw-r--r-- | sql/sql_lex.h | 4 | ||||
-rw-r--r-- | sql/sql_prepare.cc | 16 | ||||
-rw-r--r-- | sql/sql_repl.cc | 31 | ||||
-rw-r--r-- | sql/sql_select.cc | 11 | ||||
-rw-r--r-- | sql/sql_select.h | 6 | ||||
-rw-r--r-- | sql/sql_show.cc | 2 | ||||
-rw-r--r-- | sql/sql_table.cc | 10 | ||||
-rw-r--r-- | sql/sql_udf.cc | 6 | ||||
-rw-r--r-- | sql/sql_update.cc | 5 |
24 files changed, 207 insertions, 83 deletions
diff --git a/sql/field.h b/sql/field.h index 421d6bddb2d..477c64727b3 100644 --- a/sql/field.h +++ b/sql/field.h @@ -988,8 +988,9 @@ public: virtual void reset_fields() {} const uchar *ptr_in_record(const uchar *record) const { - my_ptrdiff_t l_offset= (my_ptrdiff_t) (record - table->record[0]); - return ptr + l_offset; + my_ptrdiff_t l_offset= (my_ptrdiff_t) (ptr - table->record[0]); + DBUG_ASSERT(l_offset >= 0 && table->s->rec_buff_length - l_offset > 0); + return record + l_offset; } virtual int set_default(); diff --git a/sql/item_create.cc b/sql/item_create.cc index a80781259ca..ffc90e16b8f 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -7584,6 +7584,21 @@ int item_create_append(Native_func_registry array[]) DBUG_RETURN(0); } +int item_create_remove(Native_func_registry array[]) +{ + Native_func_registry *func; + + DBUG_ENTER("item_create_remove"); + + for (func= array; func->builder != NULL; func++) + { + if (my_hash_delete(& native_functions_hash, (uchar*) func)) + DBUG_RETURN(1); + } + + DBUG_RETURN(0); +} + /* Empty the hash table for native functions. Note: this code is not thread safe, and is intended to be used at server diff --git a/sql/item_create.h b/sql/item_create.h index 5890e8ad057..bb129a14d40 100644 --- a/sql/item_create.h +++ b/sql/item_create.h @@ -199,6 +199,7 @@ struct Native_func_registry int item_create_init(); int item_create_append(Native_func_registry array[]); +int item_create_remove(Native_func_registry array[]); void item_create_cleanup(); Item *create_func_dyncol_create(THD *thd, List<DYNCALL_CREATE_DEF> &list); diff --git a/sql/item_vers.cc b/sql/item_vers.cc index c8f1c793895..792c434b8c3 100644 --- a/sql/item_vers.cc +++ b/sql/item_vers.cc @@ -26,6 +26,22 @@ #include "tztime.h" #include "item.h" +bool Item_func_history::val_bool() +{ + Item_field *f= static_cast<Item_field *>(args[0]); + DBUG_ASSERT(f->fixed); + DBUG_ASSERT(f->field->flags & VERS_SYS_END_FLAG); + return !f->field->is_max(); +} + +void Item_func_history::print(String *str, enum_query_type query_type) +{ + str->append(func_name()); + str->append('('); + args[0]->print(str, query_type); + str->append(')'); +} + Item_func_trt_ts::Item_func_trt_ts(THD *thd, Item* a, TR_table::field_id_t _trt_field) : Item_datetimefunc(thd, a), trt_field(_trt_field) diff --git a/sql/item_vers.h b/sql/item_vers.h index a42b5a033f2..0799d04a0bc 100644 --- a/sql/item_vers.h +++ b/sql/item_vers.h @@ -22,6 +22,36 @@ #pragma interface /* gcc class implementation */ #endif +class Item_func_history: public Item_bool_func +{ +public: + /* + @param a Item_field for row_end system field + */ + Item_func_history(THD *thd, Item *a): Item_bool_func(thd, a) + { + DBUG_ASSERT(a->type() == Item::FIELD_ITEM); + } + + virtual bool val_bool(); + virtual longlong val_int() + { + return (val_bool() ? 1 : 0); + } + bool fix_length_and_dec() + { + maybe_null= 0; + null_value= 0; + decimals= 0; + max_length= 1; + return FALSE; + } + virtual const char* func_name() const { return "is_history"; } + virtual void print(String *str, enum_query_type query_type); + Item *get_copy(THD *thd) + { return get_item_copy<Item_func_history>(thd, this); } +}; + class Item_func_trt_ts: public Item_datetimefunc { TR_table::field_id_t trt_field; diff --git a/sql/log_event.cc b/sql/log_event.cc index 337de3508ed..349e35488e2 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -15143,14 +15143,23 @@ bool copy_event_cache_to_file_and_reinit(IO_CACHE *cache, FILE *file) } #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) -Heartbeat_log_event::Heartbeat_log_event(const char* buf, uint event_len, +Heartbeat_log_event::Heartbeat_log_event(const char* buf, ulong event_len, const Format_description_log_event* description_event) :Log_event(buf, description_event) { uint8 header_size= description_event->common_header_len; - ident_len = event_len - header_size; - set_if_smaller(ident_len,FN_REFLEN-1); - log_ident= buf + header_size; + if (log_pos == 0) + { + log_pos= uint8korr(buf + header_size); + log_ident= buf + header_size + HB_SUB_HEADER_LEN; + ident_len= event_len - (header_size + HB_SUB_HEADER_LEN); + } + else + { + log_ident= buf + header_size; + ident_len = event_len - header_size; + } + } #endif diff --git a/sql/log_event.h b/sql/log_event.h index 49e244f1151..5719bb99a68 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -570,6 +570,14 @@ class String; #define MARIA_SLAVE_CAPABILITY_MINE MARIA_SLAVE_CAPABILITY_GTID +/* + When the size of 'log_pos' within Heartbeat_log_event exceeds UINT32_MAX it + cannot be accommodated in common_header, as 'log_pos' is of 4 bytes size. In + such cases, sub_header, of size 8 bytes will hold larger 'log_pos' value. +*/ +#define HB_SUB_HEADER_LEN 8 + + /** @enum Log_event_type @@ -5214,12 +5222,13 @@ bool copy_cache_to_file_wrapped(IO_CACHE *body, class Heartbeat_log_event: public Log_event { public: - Heartbeat_log_event(const char* buf, uint event_len, + uint8 hb_flags; + Heartbeat_log_event(const char* buf, ulong event_len, const Format_description_log_event* description_event); Log_event_type get_type_code() { return HEARTBEAT_LOG_EVENT; } bool is_valid() const { - return (log_ident != NULL && + return (log_ident != NULL && ident_len <= FN_REFLEN-1 && log_pos >= BIN_LOG_HEADER_SIZE); } const char * get_log_ident() { return log_ident; } diff --git a/sql/sp_head.h b/sql/sp_head.h index 6cf4610c466..500446c5e16 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -109,7 +109,7 @@ public: bool use_explicit_name) : Database_qualified_name(db, name), m_explicit_name(use_explicit_name) { - if (lower_case_table_names && m_db.str) + if (lower_case_table_names && m_db.length) m_db.length= my_casedn_str(files_charset_info, (char*) m_db.str); } diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 96f1b87d5d7..70607a0cf8e 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -2068,7 +2068,11 @@ static bool validate_password(THD *thd, const LEX_CSTRING &user, else { if (!thd->slave_thread && - strict_password_validation && has_validation_plugins()) + strict_password_validation && has_validation_plugins() +#ifdef WITH_WSREP + && !thd->wsrep_applier +#endif + ) { my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--strict-password-validation"); return true; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index cc6ecda9327..f4d9272eca1 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -5372,7 +5372,6 @@ bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables, uint flags, uint counter; MDL_savepoint mdl_savepoint= thd->mdl_context.mdl_savepoint(); DBUG_ENTER("open_normal_and_derived_tables"); - DBUG_ASSERT(!thd->fill_derived_tables()); if (open_tables(thd, &tables, &counter, flags, &prelocking_strategy) || mysql_handle_derived(thd->lex, dt_phases)) goto end; @@ -5430,7 +5429,7 @@ bool open_tables_only_view_structure(THD *thd, TABLE_LIST *table_list, MYSQL_OPEN_GET_NEW_TABLE | (can_deadlock ? MYSQL_OPEN_FAIL_ON_MDL_CONFLICT : 0)), - DT_INIT | DT_PREPARE | DT_CREATE)); + DT_INIT | DT_PREPARE)); /* Restore old value of sql_command back as it is being looked at in process_table() function. diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 093a94f44f8..0d61a38e918 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -4753,7 +4753,7 @@ TABLE *open_purge_table(THD *thd, const char *db, size_t dblen, DBUG_ASSERT(thd->open_tables == NULL); DBUG_ASSERT(thd->locked_tables_mode < LTM_PRELOCKED); - Open_table_context ot_ctx(thd, 0); + Open_table_context ot_ctx(thd, MYSQL_OPEN_IGNORE_FLUSH); TABLE_LIST *tl= (TABLE_LIST*)thd->alloc(sizeof(TABLE_LIST)); LEX_CSTRING db_name= {db, dblen }; LEX_CSTRING table_name= { tb, tblen }; diff --git a/sql/sql_class.h b/sql/sql_class.h index eb9ea535862..8edc6225d73 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -3655,10 +3655,6 @@ public: give_protection_error(); return TRUE; } - inline bool fill_derived_tables() - { - return !stmt_arena->is_stmt_prepare() && !lex->only_view_structure(); - } inline bool fill_information_schema_tables() { return !stmt_arena->is_stmt_prepare(); diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 132872c4a9e..fc01dcdc750 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -73,7 +73,6 @@ bool mysql_handle_derived(LEX *lex, uint phases) { bool res= FALSE; - THD *thd= lex->thd; DBUG_ENTER("mysql_handle_derived"); DBUG_PRINT("enter", ("phases: 0x%x", phases)); if (!lex->derived_tables) @@ -88,8 +87,6 @@ mysql_handle_derived(LEX *lex, uint phases) break; if (!(phases & phase_flag)) continue; - if (phase_flag >= DT_CREATE && !thd->fill_derived_tables()) - break; for (SELECT_LEX *sl= lex->all_selects_list; sl && !res; @@ -173,7 +170,6 @@ bool mysql_handle_single_derived(LEX *lex, TABLE_LIST *derived, uint phases) { bool res= FALSE; - THD *thd= lex->thd; uint8 allowed_phases= (derived->is_merged_derived() ? DT_PHASES_MERGE : DT_PHASES_MATERIALIZE); DBUG_ENTER("mysql_handle_single_derived"); @@ -200,8 +196,6 @@ mysql_handle_single_derived(LEX *lex, TABLE_LIST *derived, uint phases) if (phase_flag != DT_PREPARE && !(allowed_phases & phase_flag)) continue; - if (phase_flag >= DT_CREATE && !thd->fill_derived_tables()) - break; if ((res= (*processors[phase])(lex->thd, lex, derived))) break; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index c969725bea4..820a305059f 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1820,9 +1820,10 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) in handler methods for the just read row in record[1]. */ table->move_fields(table->field, table->record[1], table->record[0]); - if (table->update_virtual_fields(table->file, VCOL_UPDATE_FOR_REPLACE)) - goto err; + int verr = table->update_virtual_fields(table->file, VCOL_UPDATE_FOR_REPLACE); table->move_fields(table->field, table->record[0], table->record[1]); + if (verr) + goto err; } if (info->handle_duplicates == DUP_UPDATE) { diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 5937c43c95d..386d179322e 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -788,15 +788,15 @@ void lex_end(LEX *lex) DBUG_ENTER("lex_end"); DBUG_PRINT("enter", ("lex: %p", lex)); - lex_end_stage1(lex); - lex_end_stage2(lex); + lex_unlock_plugins(lex); + lex_end_nops(lex); DBUG_VOID_RETURN; } -void lex_end_stage1(LEX *lex) +void lex_unlock_plugins(LEX *lex) { - DBUG_ENTER("lex_end_stage1"); + DBUG_ENTER("lex_unlock_plugins"); /* release used plugins */ if (lex->plugins.elements) /* No function call and no mutex if no plugins. */ @@ -805,33 +805,23 @@ void lex_end_stage1(LEX *lex) lex->plugins.elements); } reset_dynamic(&lex->plugins); - - if (lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_PREPARE) - { - /* - Don't delete lex->sphead, it'll be needed for EXECUTE. - Note that of all statements that populate lex->sphead - only SQLCOM_COMPOUND can be PREPAREd - */ - DBUG_ASSERT(lex->sphead == 0 || lex->sql_command == SQLCOM_COMPOUND); - } - else - { - sp_head::destroy(lex->sphead); - lex->sphead= NULL; - } - DBUG_VOID_RETURN; } /* + Don't delete lex->sphead, it'll be needed for EXECUTE. + Note that of all statements that populate lex->sphead + only SQLCOM_COMPOUND can be PREPAREd + MASTER INFO parameters (or state) is normally cleared towards the end of a statement. But in case of PS, the state needs to be preserved during its lifetime and should only be cleared on PS close or deallocation. */ -void lex_end_stage2(LEX *lex) +void lex_end_nops(LEX *lex) { - DBUG_ENTER("lex_end_stage2"); + DBUG_ENTER("lex_end_nops"); + sp_head::destroy(lex->sphead); + lex->sphead= NULL; /* Reset LEX_MASTER_INFO */ lex->mi.reset(lex->sql_command == SQLCOM_CHANGE_MASTER); @@ -2234,6 +2224,11 @@ int Lex_input_stream::scan_ident_middle(THD *thd, Lex_ident_cli_st *str, yySkip(); // next state does a unget } + yyUnget(); // ptr points now after last token char + str->set_ident(m_tok_start, length, is_8bit); + m_cpp_text_start= m_cpp_tok_start; + m_cpp_text_end= m_cpp_text_start + length; + /* Note: "SELECT _bla AS 'alias'" _bla should be considered as a IDENT if charset haven't been found. @@ -2243,28 +2238,17 @@ int Lex_input_stream::scan_ident_middle(THD *thd, Lex_ident_cli_st *str, DBUG_ASSERT(length > 0); if (resolve_introducer && m_tok_start[0] == '_') { - - yyUnget(); // ptr points now after last token char - str->set_ident(m_tok_start, length, false); - - m_cpp_text_start= m_cpp_tok_start; - m_cpp_text_end= m_cpp_text_start + length; - body_utf8_append(m_cpp_text_start, m_cpp_tok_start + length); ErrConvString csname(str->str + 1, str->length - 1, &my_charset_bin); CHARSET_INFO *cs= get_charset_by_csname(csname.ptr(), MY_CS_PRIMARY, MYF(0)); if (cs) { + body_utf8_append(m_cpp_text_start, m_cpp_tok_start + length); *introducer= cs; return UNDERSCORE_CHARSET; } - return IDENT; } - yyUnget(); // ptr points now after last token char - str->set_ident(m_tok_start, length, is_8bit); - m_cpp_text_start= m_cpp_tok_start; - m_cpp_text_end= m_cpp_text_start + length; body_utf8_append(m_cpp_text_start); body_utf8_append_ident(thd, str, m_cpp_text_end); return is_8bit ? IDENT_QUOTED : IDENT; @@ -5761,13 +5745,33 @@ void LEX::sp_variable_declarations_init(THD *thd, int nvars) bool LEX::sp_variable_declarations_set_default(THD *thd, int nvars, Item *dflt_value_item) { - if (!dflt_value_item && + bool has_default_clause= dflt_value_item != NULL; + if (!has_default_clause && unlikely(!(dflt_value_item= new (thd->mem_root) Item_null(thd)))) return true; + sp_variable *first_spvar = NULL; + for (uint i= 0 ; i < (uint) nvars ; i++) { sp_variable *spvar= spcont->get_last_context_variable((uint) nvars - 1 - i); + + if (i == 0) { + first_spvar = spvar; + } else if (has_default_clause) { + Item_splocal *item = + new (thd->mem_root) + Item_splocal(thd, &sp_rcontext_handler_local, + &first_spvar->name, first_spvar->offset, + first_spvar->type_handler(), 0, 0); + if (item == NULL) + return true; // OOM +#ifndef DBUG_OFF + item->m_sp = sphead; +#endif + dflt_value_item = item; + } + bool last= i + 1 == (uint) nvars; spvar->default_value= dflt_value_item; /* The last instruction is responsible for freeing LEX. */ diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 466b23b3f94..2389b23e08e 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -4833,8 +4833,8 @@ extern void lex_init(void); extern void lex_free(void); extern void lex_start(THD *thd); extern void lex_end(LEX *lex); -extern void lex_end_stage1(LEX *lex); -extern void lex_end_stage2(LEX *lex); +extern void lex_end_nops(LEX *lex); +extern void lex_unlock_plugins(LEX *lex); void end_lex_with_single_table(THD *thd, TABLE *table, LEX *old_lex); int init_lex_with_single_table(THD *thd, TABLE *table, LEX *lex); extern int MYSQLlex(union YYSTYPE *yylval, THD *thd); diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index f0b8fc7309e..8d094a09165 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1608,7 +1608,7 @@ static int mysql_test_select(Prepared_statement *stmt, } if (open_normal_and_derived_tables(thd, tables, MYSQL_OPEN_FORCE_SHARED_MDL, - DT_INIT | DT_PREPARE | DT_CREATE)) + DT_INIT | DT_PREPARE)) goto error; thd->lex->used_tables= 0; // Updated by setup_fields @@ -1670,7 +1670,7 @@ static bool mysql_test_do_fields(Prepared_statement *stmt, DBUG_RETURN(TRUE); if (open_normal_and_derived_tables(thd, tables, MYSQL_OPEN_FORCE_SHARED_MDL, - DT_INIT | DT_PREPARE | DT_CREATE)) + DT_INIT | DT_PREPARE)) DBUG_RETURN(TRUE); DBUG_RETURN(setup_fields(thd, Ref_ptr_array(), *values, COLUMNS_READ, 0, NULL, 0)); @@ -1702,7 +1702,7 @@ static bool mysql_test_set_fields(Prepared_statement *stmt, if ((tables && check_table_access(thd, SELECT_ACL, tables, FALSE, UINT_MAX, FALSE)) || open_normal_and_derived_tables(thd, tables, MYSQL_OPEN_FORCE_SHARED_MDL, - DT_INIT | DT_PREPARE | DT_CREATE)) + DT_INIT | DT_PREPARE)) goto error; while ((var= it++)) @@ -1866,7 +1866,7 @@ static bool mysql_test_create_table(Prepared_statement *stmt) if (open_normal_and_derived_tables(stmt->thd, lex->query_tables, MYSQL_OPEN_FORCE_SHARED_MDL, - DT_INIT | DT_PREPARE | DT_CREATE)) + DT_INIT | DT_PREPARE)) DBUG_RETURN(TRUE); select_lex->context.resolve_in_select_list= TRUE; @@ -4308,8 +4308,10 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len) thd->release_transactional_locks(); } - /* Preserve CHANGE MASTER attributes */ - lex_end_stage1(lex); + /* Preserve locked plugins for SET */ + if (lex->sql_command != SQLCOM_SET_OPTION) + lex_unlock_plugins(lex); + cleanup_stmt(); thd->restore_backup_statement(this, &stmt_backup); thd->stmt_arena= old_stmt_arena; @@ -5141,7 +5143,7 @@ void Prepared_statement::deallocate_immediate() status_var_increment(thd->status_var.com_stmt_close); /* It should now be safe to reset CHANGE MASTER parameters */ - lex_end_stage2(lex); + lex_end(lex); } diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 6a6cfb2aa5f..841ff561502 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -33,6 +33,7 @@ #include "semisync_slave.h" #include "mysys_err.h" + enum enum_gtid_until_state { GTID_UNTIL_NOT_DONE, GTID_UNTIL_STOP_AFTER_STANDALONE, @@ -817,7 +818,7 @@ get_slave_until_gtid(THD *thd, String *out_str) @param event_coordinates binlog file name and position of the last real event master sent from binlog - @note + @note Among three essential pieces of heartbeat data Log_event::when is computed locally. The error to send is serious and should force terminating @@ -831,6 +832,8 @@ static int send_heartbeat_event(binlog_send_info *info, DBUG_ENTER("send_heartbeat_event"); ulong ev_offset; + char sub_header_buf[HB_SUB_HEADER_LEN]; + bool sub_header_in_use=false; if (reset_transmit_packet(info, info->flags, &ev_offset, &info->errmsg)) DBUG_RETURN(1); @@ -851,18 +854,38 @@ static int send_heartbeat_event(binlog_send_info *info, size_t event_len = ident_len + LOG_EVENT_HEADER_LEN + (do_checksum ? BINLOG_CHECKSUM_LEN : 0); int4store(header + SERVER_ID_OFFSET, global_system_variables.server_id); + DBUG_EXECUTE_IF("simulate_pos_4G", + { + const_cast<event_coordinates *>(coord)->pos= (UINT_MAX32 + (ulong)1); + DBUG_SET("-d, simulate_pos_4G"); + };); + if (coord->pos <= UINT_MAX32) + { + int4store(header + LOG_POS_OFFSET, coord->pos); // log_pos + } + else + { + // Set common_header.log_pos=0 to indicate its overflow + int4store(header + LOG_POS_OFFSET, 0); + sub_header_in_use= true; + int8store(sub_header_buf, coord->pos); + event_len+= HB_SUB_HEADER_LEN; + } + int4store(header + EVENT_LEN_OFFSET, event_len); int2store(header + FLAGS_OFFSET, 0); - int4store(header + LOG_POS_OFFSET, coord->pos); // log_pos - packet->append(header, sizeof(header)); - packet->append(p, ident_len); // log_file_name + if (sub_header_in_use) + packet->append(sub_header_buf, sizeof(sub_header_buf)); + packet->append(p, ident_len); // log_file_name if (do_checksum) { char b[BINLOG_CHECKSUM_LEN]; ha_checksum crc= my_checksum(0, (uchar*) header, sizeof(header)); + if (sub_header_in_use) + crc= my_checksum(crc, (uchar*) sub_header_buf, sizeof(sub_header_buf)); crc= my_checksum(crc, (uchar*) p, ident_len); int4store(b, crc); packet->append(b, sizeof(b)); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 52abaf29d05..12d0a9e824e 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -852,7 +852,8 @@ Item* period_get_condition(THD *thd, TABLE_LIST *table, SELECT_LEX *select, cond3= newx Item_func_le(thd, conds->start.item, conds->end.item); break; case SYSTEM_TIME_BEFORE: - cond1= newx Item_func_lt(thd, conds->field_end, conds->start.item); + cond1= newx Item_func_history(thd, conds->field_end); + cond2= newx Item_func_lt(thd, conds->field_end, conds->start.item); break; default: DBUG_ASSERT(0); @@ -905,7 +906,8 @@ Item* period_get_condition(THD *thd, TABLE_LIST *table, SELECT_LEX *select, cond3= newx Item_func_le(thd, conds->start.item, conds->end.item); break; case SYSTEM_TIME_BEFORE: - cond1= newx Item_func_trt_trx_sees(thd, trx_id0, conds->field_end); + cond1= newx Item_func_history(thd, conds->field_end); + cond2= newx Item_func_trt_trx_sees(thd, trx_id0, conds->field_end); break; default: DBUG_ASSERT(0); @@ -10748,6 +10750,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, j->ref.disable_cache= FALSE; j->ref.null_ref_part= NO_REF_PART; j->ref.const_ref_part_map= 0; + j->ref.uses_splitting= FALSE; keyuse=org_keyuse; store_key **ref_key= j->ref.key_copy; @@ -10796,6 +10799,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, j->ref.null_rejecting|= (key_part_map)1 << i; keyuse_uses_no_tables= keyuse_uses_no_tables && !keyuse->used_tables; + j->ref.uses_splitting |= (keyuse->validity_ref != NULL); /* We don't want to compute heavy expressions in EXPLAIN, an example would select * from t1 where t1.key=(select thats very heavy); @@ -23266,7 +23270,8 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, todo: why does JT_REF_OR_NULL mean filesort? We could find another index that satisfies the ordering. I would just set ref_key=MAX_KEY here... */ - if (tab->type == JT_REF_OR_NULL || tab->type == JT_FT) + if (tab->type == JT_REF_OR_NULL || tab->type == JT_FT || + tab->ref.uses_splitting) goto use_filesort; } else if (select && select->quick) // Range found by opt_range diff --git a/sql/sql_select.h b/sql/sql_select.h index d21d1bcc305..8d65a6183a0 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -178,6 +178,12 @@ typedef struct st_table_ref */ bool disable_cache; + /* + If true, this ref access was constructed from equalities generated by + LATERAL DERIVED (aka GROUP BY splitting) optimization + */ + bool uses_splitting; + bool tmp_table_index_lookup_init(THD *thd, KEY *tmp_key, Item_iterator &it, bool value, uint skip= 0); bool is_access_triggered(); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 6f0c9761b6c..7b5b2c8bf89 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1571,7 +1571,7 @@ mysqld_list_fields(THD *thd, TABLE_LIST *table_list, const char *wild) if (open_normal_and_derived_tables(thd, table_list, MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL, - DT_INIT | DT_PREPARE | DT_CREATE)) + DT_INIT | DT_PREPARE)) DBUG_VOID_RETURN; table= table_list->table; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 0249ae68cc3..8fe1f34256c 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -5839,11 +5839,18 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, /* Ensure that we have an exclusive lock on target table if we are creating non-temporary table. + If we're creating non-temporary table, then either + - there is an exclusive lock on the table + or + - there was CREATE IF EXIST, and the table was not created + (it existed), and was previously locked */ DBUG_ASSERT((create_info->tmp_table()) || thd->mdl_context.is_lock_owner(MDL_key::TABLE, table->db.str, table->table_name.str, - MDL_EXCLUSIVE)); + MDL_EXCLUSIVE) || + (thd->locked_tables_mode && pos_in_locked_tables && + create_info->if_not_exists())); } DEBUG_SYNC(thd, "create_table_like_before_binlog"); @@ -7867,6 +7874,7 @@ static bool mysql_inplace_alter_table(THD *thd, { goto rollback; } + DEBUG_SYNC(thd, "alter_table_inplace_after_commit"); } close_all_tables_for_name(thd, table->s, diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index 3f7289fdca2..400a8ae8c30 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -197,7 +197,7 @@ void udf_init() DBUG_PRINT("info",("init udf record")); LEX_CSTRING name; name.str=get_field(&mem, table->field[0]); - name.length = (uint) strlen(name.str); + name.length = (uint) safe_strlen(name.str); char *dl_name= get_field(&mem, table->field[2]); bool new_dl=0; Item_udftype udftype=UDFTYPE_FUNCTION; @@ -211,12 +211,12 @@ void udf_init() On windows we must check both FN_LIBCHAR and '/'. */ - if (check_valid_path(dl_name, strlen(dl_name)) || + if (!name.str || !dl_name || check_valid_path(dl_name, strlen(dl_name)) || check_string_char_length(&name, 0, NAME_CHAR_LEN, system_charset_info, 1)) { sql_print_error("Invalid row in mysql.func table for function '%.64s'", - name.str); + safe_str(name.str)); continue; } diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 41ea52ef3c3..85db99f3a62 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -1710,8 +1710,9 @@ bool Multiupdate_prelocking_strategy::handle_end(THD *thd) call in setup_tables()). */ - if (setup_tables(thd, &select_lex->context, &select_lex->top_join_list, - table_list, select_lex->leaf_tables, FALSE, TRUE)) + if (setup_tables_and_check_access(thd, &select_lex->context, + &select_lex->top_join_list, table_list, select_lex->leaf_tables, + FALSE, UPDATE_ACL, SELECT_ACL, TRUE)) DBUG_RETURN(1); List<Item> *fields= &lex->first_select_lex()->item_list; |