diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2021-04-14 12:32:27 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2021-04-14 12:32:27 +0300 |
commit | d2e2d32933823623fa3598c8e2b8a5a322e435bb (patch) | |
tree | 4a0094ff26be1e985281ef008433ce1493b58ae7 /sql | |
parent | 72e0601d11ac40a27ce071cba8626612bc625e3c (diff) | |
parent | 6c3e860cbf36831c118f6ea183acbbeb3c889bed (diff) | |
download | mariadb-git-d2e2d32933823623fa3598c8e2b8a5a322e435bb.tar.gz |
Merge 10.5 into 10.6
Diffstat (limited to 'sql')
-rw-r--r-- | sql/handler.cc | 25 | ||||
-rw-r--r-- | sql/item.cc | 33 | ||||
-rw-r--r-- | sql/item.h | 3 | ||||
-rw-r--r-- | sql/item_cmpfunc.h | 6 | ||||
-rw-r--r-- | sql/item_subselect.h | 3 | ||||
-rw-r--r-- | sql/opt_range.cc | 70 | ||||
-rw-r--r-- | sql/spatial.cc | 22 | ||||
-rw-r--r-- | sql/sql_base.cc | 2 | ||||
-rw-r--r-- | sql/sql_lex.cc | 10 | ||||
-rw-r--r-- | sql/sql_lex.h | 3 | ||||
-rw-r--r-- | sql/sql_parse.cc | 14 | ||||
-rw-r--r-- | sql/sql_prepare.cc | 9 | ||||
-rw-r--r-- | sql/sql_select.cc | 13 | ||||
-rw-r--r-- | sql/sql_table.cc | 5 | ||||
-rw-r--r-- | sql/sql_update.cc | 37 | ||||
-rw-r--r-- | sql/wsrep_trans_observer.h | 4 |
16 files changed, 173 insertions, 86 deletions
diff --git a/sql/handler.cc b/sql/handler.cc index b312635c8ee..985d3c9cc83 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -3546,25 +3546,27 @@ int handler::update_auto_increment() DBUG_RETURN(0); } - // ALTER TABLE ... ADD COLUMN ... AUTO_INCREMENT - if (thd->lex->sql_command == SQLCOM_ALTER_TABLE) + if (table->versioned()) { - if (table->versioned()) + Field *end= table->vers_end_field(); + DBUG_ASSERT(end); + bitmap_set_bit(table->read_set, end->field_index); + if (!end->is_max()) { - Field *end= table->vers_end_field(); - DBUG_ASSERT(end); - bitmap_set_bit(table->read_set, end->field_index); - if (!end->is_max()) + if (thd->lex->sql_command == SQLCOM_ALTER_TABLE) { if (!table->next_number_field->real_maybe_null()) DBUG_RETURN(HA_ERR_UNSUPPORTED); table->next_number_field->set_null(); - DBUG_RETURN(0); } + DBUG_RETURN(0); } - table->next_number_field->set_notnull(); } + // ALTER TABLE ... ADD COLUMN ... AUTO_INCREMENT + if (thd->lex->sql_command == SQLCOM_ALTER_TABLE) + table->next_number_field->set_notnull(); + if ((nr= next_insert_id) >= auto_inc_interval_for_cur_row.maximum()) { /* next_insert_id is beyond what is reserved, so we reserve more. */ @@ -8023,6 +8025,11 @@ bool Vers_parse_info::fix_alter_info(THD *thd, Alter_info *alter_info, { if (f->flags & VERS_SYSTEM_FIELD) { + if (!table->versioned()) + { + my_error(ER_VERS_NOT_VERSIONED, MYF(0), table->s->table_name.str); + return true; + } my_error(ER_VERS_DUPLICATE_ROW_START_END, MYF(0), f->flags & VERS_SYS_START_FLAG ? "START" : "END", f->field_name.str); return true; diff --git a/sql/item.cc b/sql/item.cc index 3dbe3badadf..1d13fee58ed 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -5051,13 +5051,19 @@ bool Item_ref_null_helper::get_date(THD *thd, MYSQL_TIME *ltime, @param resolved_item item which was resolved in outer SELECT(for warning) @param mark_item item which should be marked (can be differ in case of substitution) + @param suppress_warning_output flag specifying whether to suppress output of + a warning message */ static bool mark_as_dependent(THD *thd, SELECT_LEX *last, SELECT_LEX *current, Item_ident *resolved_item, - Item_ident *mark_item) + Item_ident *mark_item, + bool suppress_warning_output) { DBUG_ENTER("mark_as_dependent"); + DBUG_PRINT("info", ("current select: %d (%p) last: %d (%p)", + current->select_number, current, + (last ? last->select_number : 0), last)); /* store pointer on SELECT_LEX from which item is dependent */ if (mark_item && mark_item->can_be_depended) @@ -5068,7 +5074,7 @@ static bool mark_as_dependent(THD *thd, SELECT_LEX *last, SELECT_LEX *current, if (current->mark_as_dependent(thd, last, /** resolved_item psergey-thu **/ mark_item)) DBUG_RETURN(TRUE); - if (thd->lex->describe & DESCRIBE_EXTENDED) + if ((thd->lex->describe & DESCRIBE_EXTENDED) && !suppress_warning_output) { const char *db_name= (resolved_item->db_name.str ? resolved_item->db_name.str : ""); @@ -5097,6 +5103,8 @@ static bool mark_as_dependent(THD *thd, SELECT_LEX *last, SELECT_LEX *current, @param found_item Item which was found during resolving (if resolved identifier belongs to VIEW) @param resolved_item Identifier which was resolved + @param suppress_warning_output flag specifying whether to suppress output of + a warning message @note We have to mark all items between current_sel (including) and @@ -5109,7 +5117,8 @@ static bool mark_as_dependent(THD *thd, SELECT_LEX *last, SELECT_LEX *current, void mark_select_range_as_dependent(THD *thd, SELECT_LEX *last_select, SELECT_LEX *current_sel, Field *found_field, Item *found_item, - Item_ident *resolved_item) + Item_ident *resolved_item, + bool suppress_warning_output) { /* Go from current SELECT to SELECT where field was resolved (it @@ -5144,7 +5153,7 @@ void mark_select_range_as_dependent(THD *thd, SELECT_LEX *last_select, found_field->table->map; prev_subselect_item->const_item_cache= 0; mark_as_dependent(thd, last_select, current_sel, resolved_item, - dependent); + dependent, suppress_warning_output); } @@ -5610,7 +5619,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) context->select_lex, this, ((ref_type == REF_ITEM || ref_type == FIELD_ITEM) ? - (Item_ident*) (*reference) : 0)); + (Item_ident*) (*reference) : 0), false); return 0; } } @@ -5622,7 +5631,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) context->select_lex, this, ((ref_type == REF_ITEM || ref_type == FIELD_ITEM) ? (Item_ident*) (*reference) : - 0)); + 0), false); if (thd->lex->in_sum_func && thd->lex->in_sum_func->nest_level >= select->nest_level) { @@ -5736,7 +5745,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) set_max_sum_func_level(thd, select); mark_as_dependent(thd, last_checked_context->select_lex, context->select_lex, rf, - rf); + rf, false); return 0; } @@ -5749,7 +5758,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) set_max_sum_func_level(thd, select); mark_as_dependent(thd, last_checked_context->select_lex, context->select_lex, - this, (Item_ident*)*reference); + this, (Item_ident*)*reference, false); if (last_checked_context->select_lex->having_fix_field) { Item_ref *rf; @@ -7723,7 +7732,7 @@ public: if (tbl->table == item->field->table) { if (sel != current_select) - mark_as_dependent(thd, sel, current_select, item, item); + mark_as_dependent(thd, sel, current_select, item, item, false); return; } } @@ -7919,7 +7928,7 @@ bool Item_ref::fix_fields(THD *thd, Item **reference) ((refer_type == REF_ITEM || refer_type == FIELD_ITEM) ? (Item_ident*) (*reference) : - 0)); + 0), false); /* view reference found, we substituted it instead of this Item, so can quit @@ -7969,7 +7978,7 @@ bool Item_ref::fix_fields(THD *thd, Item **reference) goto error; thd->change_item_tree(reference, fld); mark_as_dependent(thd, last_checked_context->select_lex, - current_sel, fld, fld); + current_sel, fld, fld, false); /* A reference is resolved to a nest level that's outer or the same as the nest level of the enclosing set function : adjust the value of @@ -7992,7 +8001,7 @@ bool Item_ref::fix_fields(THD *thd, Item **reference) /* Should be checked in resolve_ref_in_select_and_group(). */ DBUG_ASSERT(*ref && (*ref)->is_fixed()); mark_as_dependent(thd, last_checked_context->select_lex, - context->select_lex, this, this); + context->select_lex, this, this, false); /* A reference is resolved to a nest level that's outer or the same as the nest level of the enclosing set function : adjust the value of diff --git a/sql/item.h b/sql/item.h index a1c288ab1f0..9b7f2cc68e9 100644 --- a/sql/item.h +++ b/sql/item.h @@ -7394,7 +7394,8 @@ void mark_select_range_as_dependent(THD *thd, st_select_lex *last_select, st_select_lex *current_sel, Field *found_field, Item *found_item, - Item_ident *resolved_item); + Item_ident *resolved_item, + bool suppress_warning_output); extern Cached_item *new_Cached_item(THD *thd, Item *item, bool pass_through_ref); diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 46412fe8ad6..aa7269ab95a 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -838,11 +838,7 @@ class Item_func_ne :public Item_bool_rowready_func2 { protected: SEL_TREE *get_func_mm_tree(RANGE_OPT_PARAM *param, - Field *field, Item *value) - { - DBUG_ENTER("Item_func_ne::get_func_mm_tree"); - DBUG_RETURN(get_ne_mm_tree(param, field, value, value)); - } + Field *field, Item *value); public: Item_func_ne(THD *thd, Item *a, Item *b): Item_bool_rowready_func2(thd, a, b) {} diff --git a/sql/item_subselect.h b/sql/item_subselect.h index 1089249c048..1f1c3454a55 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -291,7 +291,8 @@ public: friend bool Item_ref::fix_fields(THD *, Item **); friend void mark_select_range_as_dependent(THD*, st_select_lex*, st_select_lex*, - Field*, Item*, Item_ident*); + Field*, Item*, Item_ident*, + bool); friend bool convert_join_subqueries_to_semijoins(JOIN *join); }; diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 2dc9b183623..0ecba16730b 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -461,6 +461,7 @@ void print_range_for_non_indexed_field(String *out, Field *field, static void print_min_range_operator(String *out, const ha_rkey_function flag); static void print_max_range_operator(String *out, const ha_rkey_function flag); +static bool is_field_an_unique_index(RANGE_OPT_PARAM *param, Field *field); /* SEL_IMERGE is a list of possible ways to do index merge, i.e. it is @@ -7721,6 +7722,21 @@ SEL_TREE *Item_bool_func::get_ne_mm_tree(RANGE_OPT_PARAM *param, } +SEL_TREE *Item_func_ne::get_func_mm_tree(RANGE_OPT_PARAM *param, + Field *field, Item *value) +{ + DBUG_ENTER("Item_func_ne::get_func_mm_tree"); + /* + If this condition is a "col1<>...", where there is a UNIQUE KEY(col1), + do not construct a SEL_TREE from it. A condition that excludes just one + row in the table is not selective (unless there are only a few rows) + */ + if (is_field_an_unique_index(param, field)) + DBUG_RETURN(NULL); + DBUG_RETURN(get_ne_mm_tree(param, field, value, value)); +} + + SEL_TREE *Item_func_between::get_func_mm_tree(RANGE_OPT_PARAM *param, Field *field, Item *value) { @@ -7819,28 +7835,16 @@ SEL_TREE *Item_func_in::get_func_mm_tree(RANGE_OPT_PARAM *param, DBUG_RETURN(0); /* - If this is "unique_key NOT IN (...)", do not consider it sargable (for - any index, not just the unique one). The logic is as follows: + if this is a "col1 NOT IN (...)", and there is a UNIQUE KEY(col1), do + not constuct a SEL_TREE from it. The rationale is as follows: - if there are only a few constants, this condition is not selective (unless the table is also very small in which case we won't gain anything) - - If there are a lot of constants, the overhead of building and + - if there are a lot of constants, the overhead of building and processing enormous range list is not worth it. */ - if (param->using_real_indexes) - { - key_map::Iterator it(field->key_start); - uint key_no; - while ((key_no= it++) != key_map::Iterator::BITMAP_END) - { - KEY *key_info= &field->table->key_info[key_no]; - if (key_info->user_defined_key_parts == 1 && - (key_info->flags & HA_NOSAME)) - { - DBUG_RETURN(0); - } - } - } + if (is_field_an_unique_index(param, field)) + DBUG_RETURN(0); /* Get a SEL_TREE for "(-inf|NULL) < X < c_0" interval. */ uint i=0; @@ -8540,6 +8544,38 @@ SEL_TREE *Item_equal::get_mm_tree(RANGE_OPT_PARAM *param, Item **cond_ptr) } +/* + @brief + Check if there is an one-segment unique key that matches the field exactly + + @detail + In the future we could also add "almost unique" indexes where any value is + present only in a few rows (but necessarily exactly one row) +*/ +static bool is_field_an_unique_index(RANGE_OPT_PARAM *param, Field *field) +{ + DBUG_ENTER("is_field_an_unique_index"); + + // The check for using_real_indexes is there because of the heuristics + // this function is used for. + if (param->using_real_indexes) + { + key_map::Iterator it(field->key_start); + uint key_no; + while ((key_no= it++) != key_map::Iterator::BITMAP_END) + { + KEY *key_info= &field->table->key_info[key_no]; + if (key_info->user_defined_key_parts == 1 && + (key_info->flags & HA_NOSAME)) + { + DBUG_RETURN(true); + } + } + } + DBUG_RETURN(false); +} + + SEL_TREE * Item_bool_func::get_mm_parts(RANGE_OPT_PARAM *param, Field *field, Item_func::Functype type, Item *value) diff --git a/sql/spatial.cc b/sql/spatial.cc index 7a3286dae1c..13fff34df21 100644 --- a/sql/spatial.cc +++ b/sql/spatial.cc @@ -1,6 +1,6 @@ /* Copyright (c) 2002, 2013, Oracle and/or its affiliates. - Copyright (c) 2011, 2020, MariaDB Corporation. + Copyright (c) 2011, 2021, 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 @@ -1075,7 +1075,7 @@ double Gis_point::calculate_haversine(const Geometry *g, int *error) { DBUG_ASSERT(sphere_radius > 0); - double x1r, x2r, y1r, y2r, dlong, dlat, res; + double x1r, x2r, y1r, y2r; // This check is done only for optimization purposes where we know it will // be one and only one point in Multipoint @@ -1092,31 +1092,39 @@ double Gis_point::calculate_haversine(const Geometry *g, Geometry *gg= Geometry::construct(&gbuff, point_temp, point_size-1); DBUG_ASSERT(gg); if (static_cast<Gis_point *>(gg)->get_xy_radian(&x2r, &y2r)) + { DBUG_ASSERT(0); + return -1; + } } else { if (static_cast<const Gis_point *>(g)->get_xy_radian(&x2r, &y2r)) + { DBUG_ASSERT(0); + return -1; + } } if (this->get_xy_radian(&x1r, &y1r)) + { DBUG_ASSERT(0); + return -1; + } // Check boundary conditions: longitude[-180,180] if (!((x2r >= -M_PI && x2r <= M_PI) && (x1r >= -M_PI && x1r <= M_PI))) { *error=1; return -1; } - // Check boundary conditions: lattitude[-90,90] + // Check boundary conditions: latitude[-90,90] if (!((y2r >= -M_PI/2 && y2r <= M_PI/2) && (y1r >= -M_PI/2 && y1r <= M_PI/2))) { *error=-1; return -1; } - dlat= sin((y2r - y1r)/2)*sin((y2r - y1r)/2); - dlong= sin((x2r - x1r)/2)*sin((x2r - x1r)/2); - res= 2*sphere_radius*asin((sqrt(dlat + cos(y1r)*cos(y2r)*dlong))); - return res; + double dlat= sin((y2r - y1r)/2)*sin((y2r - y1r)/2); + double dlong= sin((x2r - x1r)/2)*sin((x2r - x1r)/2); + return 2*sphere_radius*asin((sqrt(dlat + cos(y1r)*cos(y2r)*dlong))); } diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 35f45cfed21..9a4dea3a216 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -6433,7 +6433,7 @@ find_field_in_tables(THD *thd, Item_ident *item, if (!all_merged && current_sel != last_select) { mark_select_range_as_dependent(thd, last_select, current_sel, - found, *ref, item); + found, *ref, item, true); } } return found; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index a06aa4df988..1dbeff69cb5 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -3347,7 +3347,7 @@ void st_select_lex_unit::exclude_tree() */ bool st_select_lex::mark_as_dependent(THD *thd, st_select_lex *last, - Item *dependency) + Item_ident *dependency) { DBUG_ASSERT(this != last); @@ -3355,10 +3355,14 @@ bool st_select_lex::mark_as_dependent(THD *thd, st_select_lex *last, /* Mark all selects from resolved to 1 before select where was found table as depended (of select where was found table) + + We move by name resolution context, bacause during merge can some select + be excleded from SELECT tree */ - SELECT_LEX *s= this; + Name_resolution_context *c= &this->context; do { + SELECT_LEX *s= c->select_lex; if (!(s->uncacheable & UNCACHEABLE_DEPENDENT_GENERATED)) { // Select is dependent of outer select @@ -3380,7 +3384,7 @@ bool st_select_lex::mark_as_dependent(THD *thd, st_select_lex *last, if (subquery_expr && subquery_expr->mark_as_dependent(thd, last, dependency)) return TRUE; - } while ((s= s->outer_select()) != last && s != 0); + } while ((c= c->outer_context) != NULL && (c->select_lex != last)); is_correlated= TRUE; master_unit()->item->is_correlated= TRUE; return FALSE; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 02f5b357c50..7e3a1152d0b 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -1383,7 +1383,8 @@ public: } inline bool is_subquery_function() { return master_unit()->item != 0; } - bool mark_as_dependent(THD *thd, st_select_lex *last, Item *dependency); + bool mark_as_dependent(THD *thd, st_select_lex *last, + Item_ident *dependency); void set_braces(bool value) { diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 9abd12761e5..3f0e71c747f 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1670,7 +1670,9 @@ dispatch_command_return dispatch_command(enum enum_server_command command, THD * if (unlikely(thd->security_ctx->password_expired && command != COM_QUERY && command != COM_PING && - command != COM_QUIT)) + command != COM_QUIT && + command != COM_STMT_PREPARE && + command != COM_STMT_EXECUTE)) { my_error(ER_MUST_CHANGE_PASSWORD, MYF(0)); goto dispatch_end; @@ -3456,7 +3458,10 @@ mysql_execute_command(THD *thd) first_table->for_insert_data); if (thd->security_ctx->password_expired && - lex->sql_command != SQLCOM_SET_OPTION) + lex->sql_command != SQLCOM_SET_OPTION && + lex->sql_command != SQLCOM_PREPARE && + lex->sql_command != SQLCOM_EXECUTE && + lex->sql_command != SQLCOM_DEALLOCATE_PREPARE) { my_error(ER_MUST_CHANGE_PASSWORD, MYF(0)); DBUG_RETURN(1); @@ -3748,7 +3753,8 @@ mysql_execute_command(THD *thd) thd->transaction->stmt.mark_trans_did_ddl(); #ifdef WITH_WSREP /* Clean up the previous transaction on implicit commit */ - if (wsrep_thd_is_local(thd) && wsrep_after_statement(thd)) + if (WSREP_NNULL(thd) && wsrep_thd_is_local(thd) && + wsrep_after_statement(thd)) { goto error; } @@ -3827,7 +3833,7 @@ mysql_execute_command(THD *thd) Do not start transaction for stored procedures, it will be handled internally in SP processing. */ - if (WSREP(thd) && + if (WSREP_NNULL(thd) && wsrep_thd_is_local(thd) && lex->sql_command != SQLCOM_BEGIN && lex->sql_command != SQLCOM_CALL && diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 24e0d8abf27..f825a951de0 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -4251,6 +4251,15 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len) thd->is_error() || init_param_array(this)); + if (thd->security_ctx->password_expired && + lex->sql_command != SQLCOM_SET_OPTION) + { + thd->restore_backup_statement(this, &stmt_backup); + thd->restore_active_arena(this, &stmt_backup); + thd->stmt_arena= old_stmt_arena; + my_error(ER_MUST_CHANGE_PASSWORD, MYF(0)); + DBUG_RETURN(true); + } lex->set_trg_event_type_for_tables(); /* diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 56a7ac6eb80..dacd636985a 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -13662,18 +13662,21 @@ ha_rows JOIN_TAB::get_examined_rows() bool JOIN_TAB::preread_init() { TABLE_LIST *derived= table->pos_in_table_list; + DBUG_ENTER("JOIN_TAB::preread_init"); + if (!derived || !derived->is_materialized_derived()) { preread_init_done= TRUE; - return FALSE; + DBUG_RETURN(FALSE); } /* Materialize derived table/view. */ if ((!derived->get_unit()->executed || derived->is_recursive_with_table() || derived->get_unit()->uncacheable) && - mysql_handle_single_derived(join->thd->lex, derived, DT_CREATE | DT_FILL)) - return TRUE; + mysql_handle_single_derived(join->thd->lex, + derived, DT_CREATE | DT_FILL)) + DBUG_RETURN(TRUE); if (!(derived->get_unit()->uncacheable & UNCACHEABLE_DEPENDENT) || derived->is_nonrecursive_derived_with_rec_ref()) @@ -13691,9 +13694,9 @@ bool JOIN_TAB::preread_init() /* init ftfuns for just initialized derived table */ if (table->fulltext_searched) if (init_ftfuncs(join->thd, join->select_lex, MY_TEST(join->order))) - return TRUE; + DBUG_RETURN(TRUE); - return FALSE; + DBUG_RETURN(FALSE); } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index ac9c39383c0..9869de4ba5e 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -8908,6 +8908,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, long_hash_key= true; } const char *dropped_key_part= NULL; + bool user_keyparts= false; // some user-defined keyparts left KEY_PART_INFO *key_part= key_info->key_part; key_parts.empty(); uint key_parts_nr= key_info->user_defined_key_parts; @@ -8987,6 +8988,8 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, key_parts.push_back(new (thd->mem_root) Key_part_spec(&cfield->field_name, key_part_length, true), thd->mem_root); + if (cfield->invisible < INVISIBLE_SYSTEM) + user_keyparts= true; } if (table->s->tmp_table == NO_TMP_TABLE) { @@ -9033,7 +9036,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, key_type= Key::PRIMARY; else key_type= Key::UNIQUE; - if (dropped_key_part) + if (dropped_key_part && user_keyparts) { my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), dropped_key_part); if (long_hash_key) diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 35ceeeff43a..79b1166338a 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2016, Oracle and/or its affiliates. - Copyright (c) 2011, 2020, MariaDB + Copyright (c) 2011, 2021, 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 @@ -2490,10 +2490,10 @@ int multi_update::send_data(List<Item> ¬_used_values) { TABLE_LIST *cur_table; DBUG_ENTER("multi_update::send_data"); - int error= 0; for (cur_table= update_tables; cur_table; cur_table= cur_table->next_local) { + int error= 0; TABLE *table= cur_table->table; uint offset= cur_table->shared; /* @@ -2563,21 +2563,7 @@ int multi_update::send_data(List<Item> ¬_used_values) updated--; if (!ignore || table->file->is_fatal_error(error, HA_CHECK_ALL)) - { -error: - /* - If (ignore && error == is ignorable) we don't have to - do anything; otherwise... - */ - myf flags= 0; - - if (table->file->is_fatal_error(error, HA_CHECK_ALL)) - flags|= ME_FATAL; /* Other handler errors are fatal */ - - prepare_record_for_error_message(error, table); - table->file->print_error(error,MYF(flags)); - DBUG_RETURN(1); - } + goto error; } else { @@ -2653,7 +2639,22 @@ error: } } } - } + continue; +error: + DBUG_ASSERT(error > 0); + /* + If (ignore && error == is ignorable) we don't have to + do anything; otherwise... + */ + myf flags= 0; + + if (table->file->is_fatal_error(error, HA_CHECK_ALL)) + flags|= ME_FATAL; /* Other handler errors are fatal */ + + prepare_record_for_error_message(error, table); + table->file->print_error(error,MYF(flags)); + DBUG_RETURN(1); + } // for (cur_table) DBUG_RETURN(0); } diff --git a/sql/wsrep_trans_observer.h b/sql/wsrep_trans_observer.h index 1f6576093cb..942363d9886 100644 --- a/sql/wsrep_trans_observer.h +++ b/sql/wsrep_trans_observer.h @@ -439,8 +439,10 @@ static inline void wsrep_after_apply(THD* thd) static inline void wsrep_open(THD* thd) { DBUG_ENTER("wsrep_open"); - if (WSREP_PROVIDER_EXISTS) + if (WSREP_ON_) { + /* WSREP_PROVIDER_EXISTS_ cannot be set if WSREP_ON_ is not set */ + DBUG_ASSERT(WSREP_PROVIDER_EXISTS_); thd->wsrep_cs().open(wsrep::client_id(thd->thread_id)); thd->wsrep_cs().debug_log_level(wsrep_debug); if (!thd->wsrep_applier && thd->variables.wsrep_trx_fragment_size) |