diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/ha_partition.cc | 2 | ||||
-rw-r--r-- | sql/item_subselect.cc | 2 | ||||
-rw-r--r-- | sql/mysqld.h | 3 | ||||
-rw-r--r-- | sql/service_wsrep.cc | 12 | ||||
-rw-r--r-- | sql/sql_delete.cc | 65 | ||||
-rw-r--r-- | sql/sql_derived.cc | 10 | ||||
-rw-r--r-- | sql/sql_lex.h | 2 | ||||
-rw-r--r-- | sql/sql_parse.cc | 7 | ||||
-rw-r--r-- | sql/sql_select.cc | 68 | ||||
-rw-r--r-- | sql/sql_string.h | 6 | ||||
-rw-r--r-- | sql/sql_union.cc | 16 | ||||
-rw-r--r-- | sql/sql_update.cc | 29 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 2 | ||||
-rw-r--r-- | sql/table.cc | 2 | ||||
-rw-r--r-- | sql/table.h | 4 |
15 files changed, 142 insertions, 88 deletions
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index e4ab4cb68f5..d40913c21d1 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -4539,7 +4539,7 @@ int ha_partition::delete_row(const uchar *buf) or last historical partition, but DELETE HISTORY can delete from any historical partition. So, skip the check in this case. */ - if (!thd->lex->vers_conditions.is_set()) // if not DELETE HISTORY + if (!thd->lex->vers_conditions.delete_history) { uint32 part_id; error= get_part_for_buf(buf, m_rec0, m_part_info, &part_id); diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index ea6a9910e1f..2d3ea388cc5 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -125,7 +125,7 @@ void Item_subselect::init(st_select_lex *select_lex, NO_MATTER : outer_select->parsing_place); if (unit->is_unit_op() && - (unit->first_select()->next_select() or unit->fake_select_lex)) + (unit->first_select()->next_select() || unit->fake_select_lex)) engine= new subselect_union_engine(unit, result, this); else engine= new subselect_single_select_engine(select_lex, result, this); diff --git a/sql/mysqld.h b/sql/mysqld.h index a518b6f34cd..eb92b5999ca 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -185,7 +185,8 @@ enum vers_system_time_t SYSTEM_TIME_AS_OF, SYSTEM_TIME_FROM_TO, SYSTEM_TIME_BETWEEN, - SYSTEM_TIME_BEFORE, + SYSTEM_TIME_BEFORE, // used for DELETE HISTORY ... BEFORE + SYSTEM_TIME_HISTORY, // used for DELETE HISTORY SYSTEM_TIME_ALL }; diff --git a/sql/service_wsrep.cc b/sql/service_wsrep.cc index 204d671d53b..b24f3cb511a 100644 --- a/sql/service_wsrep.cc +++ b/sql/service_wsrep.cc @@ -112,7 +112,17 @@ extern "C" my_bool wsrep_get_debug() extern "C" my_bool wsrep_thd_is_local(const THD *thd) { - return thd->wsrep_cs().mode() == wsrep::client_state::m_local; + /* + async replication IO and background threads have nothing to replicate in the cluster, + marking them as non-local here to prevent write set population and replication + + async replication SQL thread, applies client transactions from mariadb master + and will be replicated into cluster + */ + return ( + thd->system_thread != SYSTEM_THREAD_SLAVE_BACKGROUND && + thd->system_thread != SYSTEM_THREAD_SLAVE_IO && + thd->wsrep_cs().mode() == wsrep::client_state::m_local); } extern "C" my_bool wsrep_thd_is_applying(const THD *thd) diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index b12312041bd..29d6904f7f9 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -214,19 +214,11 @@ bool Update_plan::save_explain_data_intern(MEM_ROOT *mem_root, static bool record_should_be_deleted(THD *thd, TABLE *table, SQL_SELECT *sel, Explain_delete *explain, bool truncate_history) { - bool check_delete= true; - - if (table->versioned()) - { - bool historical= !table->vers_end_field()->is_max(); - check_delete= truncate_history ? historical : !historical; - } - explain->tracker.on_record_read(); thd->inc_examined_row_count(1); if (table->vfield) (void) table->update_virtual_fields(table->file, VCOL_UPDATE_FOR_DELETE); - if (check_delete && (!sel || sel->skip_record(thd) > 0)) + if (!sel || sel->skip_record(thd) > 0) { explain->tracker.on_record_after_where(); return true; @@ -340,30 +332,8 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, THD_STAGE_INFO(thd, stage_init_update); - bool delete_history= table_list->vers_conditions.is_set(); - if (delete_history) - { - DBUG_ASSERT(!table_list->period_conditions.is_set()); - - if (table_list->is_view_or_derived()) - { - my_error(ER_IT_IS_A_VIEW, MYF(0), table_list->table_name.str); - DBUG_RETURN(true); - } - - DBUG_ASSERT(table_list->table); - DBUG_ASSERT(!conds || thd->stmt_arena->is_stmt_execute()); - - // conds could be cached from previous SP call - if (!conds) - { - if (select_lex->vers_setup_conds(thd, table_list)) - DBUG_RETURN(TRUE); - - conds= table_list->on_expr; - table_list->on_expr= NULL; - } - } + const bool delete_history= table_list->vers_conditions.delete_history; + DBUG_ASSERT(!(delete_history && table_list->period_conditions.is_set())); if (thd->lex->handle_list_of_derived(table_list, DT_MERGE_FOR_INSERT)) DBUG_RETURN(TRUE); @@ -1015,15 +985,11 @@ int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds, select_lex->leaf_tables, FALSE, DELETE_ACL, SELECT_ACL, TRUE)) DBUG_RETURN(TRUE); - if (table_list->vers_conditions.is_set()) + + if (table_list->vers_conditions.is_set() && table_list->is_view_or_derived()) { - if (table_list->is_view()) - { - my_error(ER_IT_IS_A_VIEW, MYF(0), table_list->table_name.str); - DBUG_RETURN(true); - } - if (select_lex->vers_setup_conds(thd, table_list)) - DBUG_RETURN(true); + my_error(ER_IT_IS_A_VIEW, MYF(0), table_list->table_name.str); + DBUG_RETURN(true); } if (table_list->has_period()) @@ -1034,11 +1000,19 @@ int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds, DBUG_RETURN(true); } - *conds= select_lex->period_setup_conds(thd, table_list, *conds); - if (!*conds) + if (select_lex->period_setup_conds(thd, table_list)) DBUG_RETURN(true); } + DBUG_ASSERT(table_list->table); + // conds could be cached from previous SP call + DBUG_ASSERT(!table_list->vers_conditions.is_set() || + !*conds || thd->stmt_arena->is_stmt_execute()); + if (select_lex->vers_setup_conds(thd, table_list)) + DBUG_RETURN(TRUE); + + *conds= select_lex->where; + if (setup_returning_fields(thd, table_list) || setup_conds(thd, table_list, select_lex->leaf_tables, conds) || setup_ftfuncs(select_lex)) @@ -1332,11 +1306,6 @@ int multi_delete::send_data(List<Item> &values) if (table->status & (STATUS_NULL_ROW | STATUS_DELETED)) continue; - if (table->versioned() && !table->vers_end_field()->is_max()) - { - continue; - } - table->file->position(table->record[0]); found++; diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index f4eaa43e8ab..09f8acc536c 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -723,7 +723,17 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived) !(derived->is_multitable() && (thd->lex->sql_command == SQLCOM_UPDATE_MULTI || thd->lex->sql_command == SQLCOM_DELETE_MULTI)))) + { + /* + System versioned tables may still require to get versioning conditions + (when updating view). See vers_setup_conds(). + */ + if (!unit->prepared && + derived->table->versioned() && + (res= unit->prepare(derived, derived->derived_result, 0))) + goto exit; DBUG_RETURN(FALSE); + } /* prevent name resolving out of derived table */ for (SELECT_LEX *sl= first_select; sl; sl= sl->next_select()) diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 0c3108e8ebe..ad041f20275 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -1316,7 +1316,7 @@ public: /* push new Item_field into item_list */ bool vers_push_field(THD *thd, TABLE_LIST *table, const LEX_CSTRING field_name); - Item* period_setup_conds(THD *thd, TABLE_LIST *table, Item *where); + int period_setup_conds(THD *thd, TABLE_LIST *table); void init_query(); void init_select(); st_select_lex_unit* master_unit() { return (st_select_lex_unit*) master; } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 62cf4674241..7f33f288ce3 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4789,8 +4789,10 @@ mysql_execute_command(THD *thd) { result= new (thd->mem_root) multi_delete(thd, aux_tables, lex->table_count); - if (unlikely(result)) + if (likely(result)) { + if (unlikely(select_lex->vers_setup_conds(thd, aux_tables))) + goto multi_delete_error; res= mysql_select(thd, select_lex->get_table_list(), select_lex->item_list, @@ -4811,6 +4813,7 @@ mysql_execute_command(THD *thd) if (lex->describe || lex->analyze_stmt) res= thd->lex->explain->send_explain(thd); } + multi_delete_error: delete result; } } @@ -9683,7 +9686,7 @@ bool update_precheck(THD *thd, TABLE_LIST *tables) bool delete_precheck(THD *thd, TABLE_LIST *tables) { DBUG_ENTER("delete_precheck"); - if (tables->vers_conditions.is_set()) + if (tables->vers_conditions.delete_history) { if (check_one_table_access(thd, DELETE_HISTORY_ACL, tables)) DBUG_RETURN(TRUE); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 3b55179f0b3..e925715e20d 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -723,6 +723,7 @@ bool vers_select_conds_t::init_from_sysvar(THD *thd) { vers_asof_timestamp_t &in= thd->variables.vers_asof_timestamp; type= (vers_system_time_t) in.type; + delete_history= false; start.unit= VERS_TIMESTAMP; if (type != SYSTEM_TIME_UNSPECIFIED && type != SYSTEM_TIME_ALL) { @@ -755,6 +756,7 @@ void vers_select_conds_t::print(String *str, enum_query_type query_type) const end.print(str, query_type, STRING_WITH_LEN(" AND ")); break; case SYSTEM_TIME_BEFORE: + case SYSTEM_TIME_HISTORY: DBUG_ASSERT(0); break; case SYSTEM_TIME_ALL: @@ -790,10 +792,15 @@ Item* period_get_condition(THD *thd, TABLE_LIST *table, SELECT_LEX *select, switch (conds->type) { case SYSTEM_TIME_UNSPECIFIED: + case SYSTEM_TIME_HISTORY: thd->variables.time_zone->gmt_sec_to_TIME(&max_time, TIMESTAMP_MAX_VALUE); max_time.second_part= TIME_MAX_SECOND_PART; curr= newx Item_datetime_literal(thd, &max_time, TIME_SECOND_PART_DIGITS); - cond1= newx Item_func_eq(thd, conds->field_end, curr); + if (conds->type == SYSTEM_TIME_UNSPECIFIED) + cond1= newx Item_func_eq(thd, conds->field_end, curr); + else + cond1= newx Item_func_lt(thd, conds->field_end, curr); + break; break; case SYSTEM_TIME_AS_OF: cond1= newx Item_func_le(thd, conds->field_start, conds->start.item); @@ -837,8 +844,13 @@ Item* period_get_condition(THD *thd, TABLE_LIST *table, SELECT_LEX *select, switch (conds->type) { case SYSTEM_TIME_UNSPECIFIED: + case SYSTEM_TIME_HISTORY: curr= newx Item_int(thd, ULONGLONG_MAX); - cond1= newx Item_func_eq(thd, conds->field_end, curr); + if (conds->type == SYSTEM_TIME_UNSPECIFIED) + cond1= newx Item_func_eq(thd, conds->field_end, curr); + else + cond1= newx Item_func_lt(thd, conds->field_end, curr); + break; DBUG_ASSERT(!conds->start.item); DBUG_ASSERT(!conds->end.item); break; @@ -881,12 +893,12 @@ bool skip_setup_conds(THD *thd) || thd->lex->is_view_context_analysis(); } -Item* SELECT_LEX::period_setup_conds(THD *thd, TABLE_LIST *tables, Item *where) +int SELECT_LEX::period_setup_conds(THD *thd, TABLE_LIST *tables) { DBUG_ENTER("SELECT_LEX::period_setup_conds"); if (skip_setup_conds(thd)) - DBUG_RETURN(where); + DBUG_RETURN(0); Query_arena backup; Query_arena *arena= thd->activate_stmt_arena_if_needed(&backup); @@ -904,19 +916,19 @@ Item* SELECT_LEX::period_setup_conds(THD *thd, TABLE_LIST *tables, Item *where) my_error(ER_PERIOD_NOT_FOUND, MYF(0), conds.name.str); if (arena) thd->restore_active_arena(arena, &backup); - DBUG_RETURN(NULL); + DBUG_RETURN(-1); } conds.period= &table->table->s->period; result= and_items(thd, result, period_get_condition(thd, table, this, &conds, true)); } - result= and_items(thd, where, result); + where= and_items(thd, where, result); if (arena) thd->restore_active_arena(arena, &backup); - DBUG_RETURN(result); + DBUG_RETURN(0); } int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables) @@ -968,9 +980,22 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables) } } + bool is_select= false; + switch (thd->lex->sql_command) + { + case SQLCOM_SELECT: + case SQLCOM_INSERT_SELECT: + case SQLCOM_REPLACE_SELECT: + case SQLCOM_DELETE_MULTI: + case SQLCOM_UPDATE_MULTI: + is_select= true; + default: + break; + } + for (TABLE_LIST *table= tables; table; table= table->next_local) { - if (!table->table || !table->table->versioned()) + if (!table->table || table->is_view() || !table->table->versioned()) continue; vers_select_conds_t &vers_conditions= table->vers_conditions; @@ -1000,7 +1025,7 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables) } // propagate system_time from sysvar - if (!vers_conditions.is_set()) + if (!vers_conditions.is_set() && is_select) { if (vers_conditions.init_from_sysvar(thd)) DBUG_RETURN(-1); @@ -1016,7 +1041,7 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables) bool timestamps_only= table->table->versioned(VERS_TIMESTAMP); - if (vers_conditions.is_set()) + if (vers_conditions.is_set() && vers_conditions.type != SYSTEM_TIME_HISTORY) { thd->where= "FOR SYSTEM_TIME"; /* TODO: do resolve fix_length_and_dec(), fix_fields(). This requires @@ -1036,10 +1061,21 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables) vers_conditions.period = &table->table->s->vers; Item *cond= period_get_condition(thd, table, this, &vers_conditions, timestamps_only); - if (cond) + if (is_select) table->on_expr= and_items(thd, table->on_expr, cond); - table->vers_conditions.type= SYSTEM_TIME_ALL; + else + { + if (join) + { + where= and_items(thd, join->conds, cond); + join->conds= where; + } + else + where= and_items(thd, where, cond); + table->where= and_items(thd, table->where, cond); + } + table->vers_conditions.type= SYSTEM_TIME_ALL; } // for (table= tables; ...) DBUG_RETURN(0); @@ -21209,11 +21245,12 @@ int join_init_read_record(JOIN_TAB *tab) */ if (tab->distinct && tab->remove_duplicates()) // Remove duplicates. return 1; - if (tab->filesort && tab->sort_table()) // Sort table. - return 1; tab->build_range_rowid_filter_if_needed(); + if (tab->filesort && tab->sort_table()) // Sort table. + return 1; + DBUG_EXECUTE_IF("kill_join_init_read_record", tab->join->thd->set_killed(KILL_QUERY);); if (tab->select && tab->select->quick && tab->select->quick->reset()) @@ -21273,6 +21310,9 @@ JOIN_TAB::sort_table() JOIN::ordered_index_order_by : JOIN::ordered_index_group_by)); rc= create_sort_index(join->thd, join, this, NULL); + /* Disactivate rowid filter if it was used when creating sort index */ + if (rowid_filter) + table->file->rowid_filter_is_active= false; return (rc != 0); } diff --git a/sql/sql_string.h b/sql/sql_string.h index 8ced35657e8..317adc13909 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, 2018, MariaDB Corporation. + Copyright (c) 2008, 2019, 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 @@ -169,6 +169,10 @@ public: { swap_variables(CHARSET_INFO*, m_charset, other.m_charset); } + bool same_encoding(const Charset &other) const + { + return !strcmp(m_charset->csname, other.m_charset->csname); + } /* Collation name without the character set name. For example, in case of "latin1_swedish_ci", diff --git a/sql/sql_union.cc b/sql/sql_union.cc index ece5a84b1c3..d5d43e56875 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -1459,9 +1459,21 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg, if (sl->tvc->prepare(thd, sl, tmp_result, this)) goto err; } - else if (prepare_join(thd, first_sl, tmp_result, additional_options, + else + { + if (prepare_join(thd, first_sl, tmp_result, additional_options, is_union_select)) - goto err; + goto err; + + if (derived_arg && derived_arg->table && + derived_arg->derived_type == VIEW_ALGORITHM_MERGE && + derived_arg->table->versioned()) + { + /* Got versioning conditions (see vers_setup_conds()), need to update + derived_arg. */ + derived_arg->where= first_sl->where; + } + } types= first_sl->item_list; goto cont; } diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 26dfe5e40a2..739febf5e87 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -959,11 +959,6 @@ update_begin: THD_STAGE_INFO(thd, stage_updating); while (!(error=info.read_record()) && !thd->killed) { - if (table->versioned() && !table->vers_end_field()->is_max()) - { - continue; - } - explain->tracker.on_record_read(); thd->inc_examined_row_count(1); if (!select || select->skip_record(thd) > 0) @@ -1372,12 +1367,18 @@ bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list, thd->lex->allow_sum_func.clear_all(); - if (table_list->has_period()) - { - *conds= select_lex->period_setup_conds(thd, table_list, *conds); - if (!*conds) + if (table_list->has_period() && + select_lex->period_setup_conds(thd, table_list)) DBUG_RETURN(true); - } + + DBUG_ASSERT(table_list->table); + // conds could be cached from previous SP call + DBUG_ASSERT(!table_list->vers_conditions.is_set() || + !*conds || thd->stmt_arena->is_stmt_execute()); + if (select_lex->vers_setup_conds(thd, table_list)) + DBUG_RETURN(TRUE); + + *conds= select_lex->where; /* We do not call DT_MERGE_FOR_INSERT because it has no sense for simple @@ -1899,6 +1900,9 @@ bool mysql_multi_update(THD *thd, TABLE_LIST *table_list, List<Item> *fields, thd->abort_on_warning= !ignore && thd->is_strict_mode(); List<Item> total_list; + if (select_lex->vers_setup_conds(thd, table_list)) + DBUG_RETURN(1); + res= mysql_select(thd, table_list, total_list, conds, select_lex->order_list.elements, @@ -2458,11 +2462,6 @@ int multi_update::send_data(List<Item> ¬_used_values) if (table->status & (STATUS_NULL_ROW | STATUS_UPDATED)) continue; - if (table->versioned() && !table->vers_end_field()->is_max()) - { - continue; - } - if (table == table_to_update) { /* diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 2657586cc42..fee02f78792 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -13030,7 +13030,7 @@ delete: opt_delete_system_time: /* empty */ { - Lex->vers_conditions.init(SYSTEM_TIME_ALL); + Lex->vers_conditions.init(SYSTEM_TIME_HISTORY); } | BEFORE_SYM SYSTEM_TIME_SYM history_point { diff --git a/sql/table.cc b/sql/table.cc index 7ed5121a9c6..2b1bb16ef24 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -9647,6 +9647,8 @@ bool vers_select_conds_t::eq(const vers_select_conds_t &conds) const return true; case SYSTEM_TIME_BEFORE: break; + case SYSTEM_TIME_HISTORY: + break; case SYSTEM_TIME_AS_OF: return start.eq(conds.start); case SYSTEM_TIME_FROM_TO: diff --git a/sql/table.h b/sql/table.h index 043341db608..0c6917e7b62 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1859,6 +1859,7 @@ struct vers_select_conds_t { vers_system_time_t type; bool used:1; + bool delete_history:1; Vers_history_point start; Vers_history_point end; Lex_ident name; @@ -1872,6 +1873,7 @@ struct vers_select_conds_t { type= SYSTEM_TIME_UNSPECIFIED; used= false; + delete_history= false; start.empty(); end.empty(); } @@ -1883,6 +1885,8 @@ struct vers_select_conds_t { type= _type; used= false; + delete_history= (type == SYSTEM_TIME_HISTORY || + type == SYSTEM_TIME_BEFORE); start= _start; end= _end; name= _name; |