summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/handler.cc25
-rw-r--r--sql/item.cc33
-rw-r--r--sql/item.h3
-rw-r--r--sql/item_cmpfunc.h6
-rw-r--r--sql/item_subselect.h3
-rw-r--r--sql/opt_range.cc70
-rw-r--r--sql/spatial.cc22
-rw-r--r--sql/sql_base.cc2
-rw-r--r--sql/sql_lex.cc10
-rw-r--r--sql/sql_lex.h3
-rw-r--r--sql/sql_parse.cc14
-rw-r--r--sql/sql_prepare.cc9
-rw-r--r--sql/sql_select.cc13
-rw-r--r--sql/sql_table.cc5
-rw-r--r--sql/sql_update.cc37
-rw-r--r--sql/wsrep_trans_observer.h4
16 files changed, 173 insertions, 86 deletions
diff --git a/sql/handler.cc b/sql/handler.cc
index 7e3b46cab04..c6031e252a6 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. */
@@ -8021,6 +8023,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 f1657b51bf3..9ec8781bc30 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 87970ee11b4..85318c60ec3 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -6407,7 +6407,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 02652dd095c..ce5f78b84ad 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -3344,7 +3344,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);
@@ -3352,10 +3352,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
@@ -3377,7 +3381,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 c475c6d3385..846d6b9a822 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -1378,7 +1378,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 e8aa92aa52c..0e2b80beb78 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1663,7 +1663,9 @@ bool dispatch_command(enum enum_server_command command, THD *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;
@@ -3530,7 +3532,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);
@@ -3822,7 +3827,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;
}
@@ -3896,7 +3902,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 314966fbf00..3f28f818acc 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -4238,6 +4238,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 27092f2b663..e87c1a989cd 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -13638,18 +13638,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())
@@ -13667,9 +13670,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 f1e1b6517d8..99070bcd89c 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -8833,6 +8833,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;
@@ -8912,6 +8913,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)
{
@@ -8957,7 +8960,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> &not_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> &not_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)