Merge 10.3 into 10.4

This commit is contained in:
Marko Mäkelä 2021-04-14 10:33:59 +03:00
commit 5008171b05
115 changed files with 1750 additions and 573 deletions

View file

@ -3343,25 +3343,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. */
@ -7614,6 +7616,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;

View file

@ -4978,13 +4978,19 @@ bool Item_ref_null_helper::get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuz
@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)
@ -4995,7 +5001,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 ?
resolved_item->db_name : "");
@ -5024,6 +5030,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
@ -5037,7 +5045,8 @@ 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
@ -5072,7 +5081,7 @@ void mark_select_range_as_dependent(THD *thd,
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);
}
}
@ -5539,7 +5548,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;
}
}
@ -5551,7 +5560,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)
{
@ -5665,7 +5674,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;
}
@ -5678,7 +5687,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;
@ -7649,7 +7658,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;
}
}
@ -7845,7 +7854,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
@ -7895,7 +7904,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
@ -7918,7 +7927,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

View file

@ -7400,7 +7400,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);

View file

@ -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);
};

View file

@ -1,6 +1,6 @@
/*
Copyright (c) 2002, 2013, Oracle and/or its affiliates.
Copyright (c) 2011, 2013, Monty Program Ab.
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
@ -1050,7 +1050,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
@ -1067,31 +1067,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)));
}

View file

@ -6486,7 +6486,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;

View file

@ -2806,7 +2806,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);
@ -2814,10 +2814,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
@ -2839,7 +2843,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;
this->master_unit()->item->is_correlated= TRUE;
return FALSE;

View file

@ -1336,7 +1336,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)
{

View file

@ -13545,10 +13545,12 @@ 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. */
@ -13557,7 +13559,7 @@ bool JOIN_TAB::preread_init()
derived->get_unit()->uncacheable) &&
mysql_handle_single_derived(join->thd->lex,
derived, DT_CREATE | DT_FILL))
return TRUE;
DBUG_RETURN(TRUE);
if (!(derived->get_unit()->uncacheable & UNCACHEABLE_DEPENDENT) ||
derived->is_nonrecursive_derived_with_rec_ref())
@ -13575,9 +13577,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);
}

View file

@ -8451,6 +8451,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();
bool delete_index_stat= FALSE;
@ -8526,6 +8527,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)
{
@ -8571,7 +8574,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)

View file

@ -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
@ -2489,10 +2489,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;
/*
@ -2562,21 +2562,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);
}