mirror of
https://github.com/MariaDB/server.git
synced 2026-05-15 11:27:39 +02:00
Merge branch '10.2' into 10.3
This commit is contained in:
commit
6190a02f35
80 changed files with 2384 additions and 222 deletions
10
sql/field.cc
10
sql/field.cc
|
|
@ -6288,6 +6288,7 @@ bool Field_timef::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
|
|||
int Field_year::store(const char *from, size_t len,CHARSET_INFO *cs)
|
||||
{
|
||||
ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
|
||||
THD *thd= get_thd();
|
||||
char *end;
|
||||
int error;
|
||||
longlong nr= cs->cset->strntoull10rnd(cs, from, len, 0, &end, &error);
|
||||
|
|
@ -6299,7 +6300,14 @@ int Field_year::store(const char *from, size_t len,CHARSET_INFO *cs)
|
|||
set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
return 1;
|
||||
}
|
||||
if (get_thd()->count_cuted_fields > CHECK_FIELD_EXPRESSION &&
|
||||
|
||||
if (thd->count_cuted_fields <= CHECK_FIELD_EXPRESSION && error == MY_ERRNO_EDOM)
|
||||
{
|
||||
*ptr= 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (thd->count_cuted_fields > CHECK_FIELD_EXPRESSION &&
|
||||
(error= check_int(cs, from, len, end, error)))
|
||||
{
|
||||
if (unlikely(error == 1) /* empty or incorrect string */)
|
||||
|
|
|
|||
|
|
@ -5402,8 +5402,7 @@ int ha_partition::index_init(uint inx, bool sorted)
|
|||
do
|
||||
{
|
||||
for (i= 0; i < (*key_info)->user_defined_key_parts; i++)
|
||||
bitmap_set_bit(table->read_set,
|
||||
(*key_info)->key_part[i].field->field_index);
|
||||
(*key_info)->key_part[i].field->register_field_in_read_map();
|
||||
} while (*(++key_info));
|
||||
}
|
||||
for (i= bitmap_get_first_set(&m_part_info->read_partitions);
|
||||
|
|
|
|||
|
|
@ -5880,13 +5880,15 @@ public:
|
|||
|
||||
class Item_default_value : public Item_field
|
||||
{
|
||||
bool vcol_assignment_ok;
|
||||
void calculate();
|
||||
public:
|
||||
Item *arg;
|
||||
Field *cached_field;
|
||||
Item_default_value(THD *thd, Name_resolution_context *context_arg, Item *a)
|
||||
Item_default_value(THD *thd, Name_resolution_context *context_arg, Item *a,
|
||||
bool vcol_assignment_arg)
|
||||
:Item_field(thd, context_arg, (const char *)NULL, (const char *)NULL,
|
||||
&null_clex_str),
|
||||
&null_clex_str), vcol_assignment_ok(vcol_assignment_arg),
|
||||
arg(a), cached_field(NULL) {}
|
||||
enum Type type() const { return DEFAULT_VALUE_ITEM; }
|
||||
bool eq(const Item *item, bool binary_cmp) const;
|
||||
|
|
@ -5923,6 +5925,7 @@ public:
|
|||
if (field && field->default_value)
|
||||
field->default_value->expr->update_used_tables();
|
||||
}
|
||||
bool vcol_assignment_allowed_value() const { return vcol_assignment_ok; }
|
||||
Field *get_tmp_table_field() { return 0; }
|
||||
Item *get_tmp_table_item(THD *thd) { return this; }
|
||||
Item_field *field_for_view_update() { return 0; }
|
||||
|
|
|
|||
|
|
@ -467,7 +467,7 @@ void key_unpack(String *to, TABLE *table, KEY *key)
|
|||
|
||||
bool is_key_used(TABLE *table, uint idx, const MY_BITMAP *fields)
|
||||
{
|
||||
table->mark_columns_used_by_index(idx, &table->tmp_set);
|
||||
table->mark_index_columns(idx, &table->tmp_set);
|
||||
return bitmap_is_overlapping(&table->tmp_set, fields);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2634,7 +2634,6 @@ end:
|
|||
my_error(ER_INVALID_ROLE, MYF(0), rolename);
|
||||
break;
|
||||
case 1:
|
||||
StringBuffer<1024> c_usr;
|
||||
LEX_CSTRING role_lex;
|
||||
/* First, check if current user can see mysql database. */
|
||||
bool read_access= !check_access(thd, SELECT_ACL, "mysql", NULL, NULL, 1, 1);
|
||||
|
|
@ -2655,11 +2654,9 @@ end:
|
|||
NULL) == -1))
|
||||
{
|
||||
/* Role is not granted but current user can see the role */
|
||||
c_usr.append(user, strlen(user));
|
||||
c_usr.append('@');
|
||||
c_usr.append(host, strlen(host));
|
||||
my_printf_error(ER_INVALID_ROLE, "User %`s has not been granted role %`s",
|
||||
MYF(0), c_usr.c_ptr(), rolename);
|
||||
my_printf_error(ER_INVALID_ROLE, "User %`s@%`s has not been granted role %`s",
|
||||
MYF(0), thd->security_ctx->priv_user,
|
||||
thd->security_ctx->priv_host, rolename);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -859,7 +859,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
|||
enum enum_field_types type= (*field_ptr)->type();
|
||||
if (type < MYSQL_TYPE_MEDIUM_BLOB ||
|
||||
type > MYSQL_TYPE_BLOB)
|
||||
bitmap_set_bit(tab->read_set, fields);
|
||||
tab->field[fields]->register_field_in_read_map();
|
||||
else
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_NO_EIS_FOR_FIELD,
|
||||
|
|
@ -887,7 +887,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
|||
enum enum_field_types type= tab->field[pos]->type();
|
||||
if (type < MYSQL_TYPE_MEDIUM_BLOB ||
|
||||
type > MYSQL_TYPE_BLOB)
|
||||
bitmap_set_bit(tab->read_set, pos);
|
||||
tab->field[pos]->register_field_in_read_map();
|
||||
else
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_NO_EIS_FOR_FIELD,
|
||||
|
|
|
|||
|
|
@ -6120,7 +6120,7 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
|
|||
TABLE *table= field_to_set->table;
|
||||
DBUG_ASSERT(table);
|
||||
if (thd->column_usage == MARK_COLUMNS_READ)
|
||||
bitmap_set_bit(table->read_set, field_to_set->field_index);
|
||||
field_to_set->register_field_in_read_map();
|
||||
else
|
||||
bitmap_set_bit(table->write_set, field_to_set->field_index);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6960,8 +6960,8 @@ void THD::binlog_prepare_row_images(TABLE *table)
|
|||
{
|
||||
case BINLOG_ROW_IMAGE_MINIMAL:
|
||||
/* MINIMAL: Mark only PK */
|
||||
table->mark_columns_used_by_index(table->s->primary_key,
|
||||
&table->tmp_set);
|
||||
table->mark_index_columns(table->s->primary_key,
|
||||
&table->tmp_set);
|
||||
break;
|
||||
case BINLOG_ROW_IMAGE_NOBLOB:
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1027,6 +1027,7 @@ st_select_lex_unit *With_element::clone_parsed_spec(LEX *old_lex,
|
|||
|
||||
bool parse_status= false;
|
||||
st_select_lex *with_select;
|
||||
st_select_lex *last_clone_select;
|
||||
|
||||
char save_end= unparsed_spec.str[unparsed_spec.length];
|
||||
const_cast<char*>(unparsed_spec.str)[unparsed_spec.length]= '\0';
|
||||
|
|
@ -1114,11 +1115,6 @@ st_select_lex_unit *With_element::clone_parsed_spec(LEX *old_lex,
|
|||
lex->unit.include_down(with_table->select_lex);
|
||||
lex->unit.set_slave(with_select);
|
||||
lex->unit.cloned_from= spec;
|
||||
old_lex->all_selects_list=
|
||||
(st_select_lex*) (lex->all_selects_list->
|
||||
insert_chain_before(
|
||||
(st_select_lex_node **) &(old_lex->all_selects_list),
|
||||
with_select));
|
||||
|
||||
/*
|
||||
Now all references to the CTE defined outside of the cloned specification
|
||||
|
|
@ -1134,6 +1130,15 @@ st_select_lex_unit *With_element::clone_parsed_spec(LEX *old_lex,
|
|||
goto err;
|
||||
}
|
||||
|
||||
last_clone_select= lex->all_selects_list;
|
||||
while (last_clone_select->next_select_in_list())
|
||||
last_clone_select= last_clone_select->next_select_in_list();
|
||||
old_lex->all_selects_list=
|
||||
(st_select_lex*) (lex->all_selects_list->
|
||||
insert_chain_before(
|
||||
(st_select_lex_node **) &(old_lex->all_selects_list),
|
||||
last_clone_select));
|
||||
|
||||
lex->sphead= NULL; // in order not to delete lex->sphead
|
||||
lex_end(lex);
|
||||
err:
|
||||
|
|
@ -1271,6 +1276,7 @@ bool With_element::is_anchor(st_select_lex *sel)
|
|||
With_element *st_select_lex::find_table_def_in_with_clauses(TABLE_LIST *table)
|
||||
{
|
||||
With_element *found= NULL;
|
||||
With_clause *containing_with_clause= NULL;
|
||||
st_select_lex_unit *master_unit;
|
||||
st_select_lex *outer_sl;
|
||||
for (st_select_lex *sl= this; sl; sl= outer_sl)
|
||||
|
|
@ -1283,6 +1289,7 @@ With_element *st_select_lex::find_table_def_in_with_clauses(TABLE_LIST *table)
|
|||
*/
|
||||
With_clause *attached_with_clause= sl->get_with_clause();
|
||||
if (attached_with_clause &&
|
||||
attached_with_clause != containing_with_clause &&
|
||||
(found= attached_with_clause->find_table_def(table, NULL)))
|
||||
break;
|
||||
master_unit= sl->master_unit();
|
||||
|
|
@ -1290,7 +1297,7 @@ With_element *st_select_lex::find_table_def_in_with_clauses(TABLE_LIST *table)
|
|||
With_element *with_elem= sl->get_with_element();
|
||||
if (with_elem)
|
||||
{
|
||||
With_clause *containing_with_clause= with_elem->get_owner();
|
||||
containing_with_clause= with_elem->get_owner();
|
||||
With_element *barrier= containing_with_clause->with_recursive ?
|
||||
NULL : with_elem;
|
||||
if ((found= containing_with_clause->find_table_def(table, barrier)))
|
||||
|
|
|
|||
|
|
@ -4525,8 +4525,17 @@ select_create::prepare(List<Item> &_values, SELECT_LEX_UNIT *u)
|
|||
DEBUG_SYNC(thd,"create_table_select_before_check_if_exists");
|
||||
|
||||
if (!(table= create_table_from_items(thd, &values, &extra_lock, hook_ptr)))
|
||||
{
|
||||
if (create_info->or_replace())
|
||||
{
|
||||
/* Original table was deleted. We have to log it */
|
||||
log_drop_table(thd, &create_table->db, &create_table->table_name,
|
||||
thd->lex->tmp_table());
|
||||
}
|
||||
|
||||
/* abort() deletes table */
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
|
||||
if (create_info->tmp_table())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1619,7 +1619,12 @@ static int mysql_test_select(Prepared_statement *stmt,
|
|||
if (!lex->describe && !thd->lex->analyze_stmt && !stmt->is_sql_prepare())
|
||||
{
|
||||
/* Make copy of item list, as change_columns may change it */
|
||||
List<Item> fields(lex->select_lex.item_list);
|
||||
SELECT_LEX_UNIT* master_unit= unit->first_select()->master_unit();
|
||||
bool is_union_op=
|
||||
master_unit->is_unit_op() || master_unit->fake_select_lex;
|
||||
|
||||
List<Item> fields(is_union_op ? unit->item_list :
|
||||
lex->select_lex.item_list);
|
||||
|
||||
/* Change columns if a procedure like analyse() */
|
||||
if (unit->last_procedure && unit->last_procedure->change_columns(thd, fields))
|
||||
|
|
|
|||
|
|
@ -1537,7 +1537,7 @@ int JOIN::init_join_caches()
|
|||
if (table->file->keyread_enabled())
|
||||
{
|
||||
if (!(table->file->index_flags(table->file->keyread, 0, 1) & HA_CLUSTERED_INDEX))
|
||||
table->mark_columns_used_by_index(table->file->keyread, table->read_set);
|
||||
table->mark_index_columns(table->file->keyread, table->read_set);
|
||||
}
|
||||
else if ((tab->read_first_record == join_read_first ||
|
||||
tab->read_first_record == join_read_last) &&
|
||||
|
|
@ -8539,7 +8539,9 @@ static
|
|||
double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s,
|
||||
table_map rem_tables)
|
||||
{
|
||||
uint16 ref_keyuse_steps[MAX_REF_PARTS - 1];
|
||||
uint16 ref_keyuse_steps_buf[MAX_REF_PARTS];
|
||||
uint ref_keyuse_size= MAX_REF_PARTS;
|
||||
uint16 *ref_keyuse_steps= ref_keyuse_steps_buf;
|
||||
Field *field;
|
||||
TABLE *table= s->table;
|
||||
MY_BITMAP *read_set= table->read_set;
|
||||
|
|
@ -8686,6 +8688,29 @@ double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s,
|
|||
}
|
||||
if (keyparts > 1)
|
||||
{
|
||||
/*
|
||||
Prepare to set ref_keyuse_steps[keyparts-2]: resize the array
|
||||
if it is not large enough
|
||||
*/
|
||||
if (keyparts - 2 >= ref_keyuse_size)
|
||||
{
|
||||
uint new_size= MY_MAX(ref_keyuse_size*2, keyparts);
|
||||
void *new_buf;
|
||||
if (!(new_buf= my_malloc(sizeof(*ref_keyuse_steps)*new_size,
|
||||
MYF(0))))
|
||||
{
|
||||
sel= 1.0; // As if no selectivity was computed
|
||||
goto exit;
|
||||
}
|
||||
memcpy(new_buf, ref_keyuse_steps,
|
||||
sizeof(*ref_keyuse_steps)*ref_keyuse_size);
|
||||
if (ref_keyuse_steps != ref_keyuse_steps_buf)
|
||||
my_free(ref_keyuse_steps);
|
||||
|
||||
ref_keyuse_steps= (uint16*)new_buf;
|
||||
ref_keyuse_size= new_size;
|
||||
}
|
||||
|
||||
ref_keyuse_steps[keyparts-2]= (uint16)(keyuse - prev_ref_keyuse);
|
||||
prev_ref_keyuse= keyuse;
|
||||
}
|
||||
|
|
@ -8740,7 +8765,9 @@ double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s,
|
|||
|
||||
sel*= table_multi_eq_cond_selectivity(join, idx, s, rem_tables,
|
||||
keyparts, ref_keyuse_steps);
|
||||
|
||||
exit:
|
||||
if (ref_keyuse_steps != ref_keyuse_steps_buf)
|
||||
my_free(ref_keyuse_steps);
|
||||
return sel;
|
||||
}
|
||||
|
||||
|
|
@ -22881,6 +22908,12 @@ check_reverse_order:
|
|||
if (select->quick == save_quick)
|
||||
save_quick= 0; // make_reverse() consumed it
|
||||
select->set_quick(tmp);
|
||||
/* Cancel "Range checked for each record" */
|
||||
if (tab->use_quick == 2)
|
||||
{
|
||||
tab->use_quick= 1;
|
||||
tab->read_first_record= join_init_read_record;
|
||||
}
|
||||
}
|
||||
else if (tab->type != JT_NEXT && tab->type != JT_REF_OR_NULL &&
|
||||
tab->ref.key >= 0 && tab->ref.key_parts <= used_key_parts)
|
||||
|
|
@ -22893,6 +22926,12 @@ check_reverse_order:
|
|||
*/
|
||||
tab->read_first_record= join_read_last_key;
|
||||
tab->read_record.read_record_func= join_read_prev_same;
|
||||
/* Cancel "Range checked for each record" */
|
||||
if (tab->use_quick == 2)
|
||||
{
|
||||
tab->use_quick= 1;
|
||||
tab->read_first_record= join_init_read_record;
|
||||
}
|
||||
/*
|
||||
Cancel Pushed Index Condition, as it doesn't work for reverse scans.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include "filesort.h" // filesort_free_buffers
|
||||
#include "sql_view.h"
|
||||
#include "sql_cte.h"
|
||||
#include "item_windowfunc.h"
|
||||
|
||||
bool mysql_union(THD *thd, LEX *lex, select_result *result,
|
||||
SELECT_LEX_UNIT *unit, ulong setup_tables_done_option)
|
||||
|
|
@ -1875,7 +1876,8 @@ bool st_select_lex_unit::cleanup()
|
|||
{
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
if (with_element && with_element->is_recursive && union_result)
|
||||
if (with_element && with_element->is_recursive && union_result &&
|
||||
with_element->rec_outer_references)
|
||||
{
|
||||
select_union_recursive *result= with_element->rec_result;
|
||||
if (++result->cleanup_count == with_element->rec_outer_references)
|
||||
|
|
@ -2044,6 +2046,29 @@ static void cleanup_order(ORDER *order)
|
|||
}
|
||||
|
||||
|
||||
static void cleanup_window_funcs(List<Item_window_func> &win_funcs)
|
||||
{
|
||||
List_iterator_fast<Item_window_func> it(win_funcs);
|
||||
Item_window_func *win_func;
|
||||
while ((win_func= it++))
|
||||
{
|
||||
Window_spec *win_spec= win_func->window_spec;
|
||||
if (!win_spec)
|
||||
continue;
|
||||
if (win_spec->save_partition_list)
|
||||
{
|
||||
win_spec->partition_list= win_spec->save_partition_list;
|
||||
win_spec->save_partition_list= NULL;
|
||||
}
|
||||
if (win_spec->save_order_list)
|
||||
{
|
||||
win_spec->order_list= win_spec->save_order_list;
|
||||
win_spec->save_order_list= NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool st_select_lex::cleanup()
|
||||
{
|
||||
bool error= FALSE;
|
||||
|
|
@ -2053,6 +2078,8 @@ bool st_select_lex::cleanup()
|
|||
cleanup_order(group_list.first);
|
||||
cleanup_ftfuncs(this);
|
||||
|
||||
cleanup_window_funcs(window_funcs);
|
||||
|
||||
if (join)
|
||||
{
|
||||
List_iterator<TABLE_LIST> ti(leaf_tables);
|
||||
|
|
@ -2079,7 +2106,8 @@ bool st_select_lex::cleanup()
|
|||
for (SELECT_LEX_UNIT *lex_unit= first_inner_unit(); lex_unit ;
|
||||
lex_unit= lex_unit->next_unit())
|
||||
{
|
||||
if (lex_unit->with_element && lex_unit->with_element->is_recursive)
|
||||
if (lex_unit->with_element && lex_unit->with_element->is_recursive &&
|
||||
lex_unit->with_element->rec_outer_references)
|
||||
continue;
|
||||
error= (bool) ((uint) error | (uint) lex_unit->cleanup());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -244,7 +244,7 @@ static void prepare_record_for_error_message(int error, TABLE *table)
|
|||
|
||||
/* Create unique_map with all fields used by that index. */
|
||||
my_bitmap_init(&unique_map, unique_map_buf, table->s->fields, FALSE);
|
||||
table->mark_columns_used_by_index(keynr, &unique_map);
|
||||
table->mark_index_columns(keynr, &unique_map);
|
||||
|
||||
/* Subtract read_set and write_set. */
|
||||
bitmap_subtract(&unique_map, table->read_set);
|
||||
|
|
|
|||
|
|
@ -592,9 +592,15 @@ int compare_window_funcs_by_window_specs(Item_window_func *win_func1,
|
|||
Let's use only one of the lists.
|
||||
*/
|
||||
if (!win_spec1->name() && win_spec2->name())
|
||||
{
|
||||
win_spec1->save_partition_list= win_spec1->partition_list;
|
||||
win_spec1->partition_list= win_spec2->partition_list;
|
||||
}
|
||||
else
|
||||
{
|
||||
win_spec2->save_partition_list= win_spec2->partition_list;
|
||||
win_spec2->partition_list= win_spec1->partition_list;
|
||||
}
|
||||
|
||||
cmp= compare_order_lists(win_spec1->order_list,
|
||||
win_spec2->order_list);
|
||||
|
|
@ -607,9 +613,15 @@ int compare_window_funcs_by_window_specs(Item_window_func *win_func1,
|
|||
Let's use only one of the lists.
|
||||
*/
|
||||
if (!win_spec1->name() && win_spec2->name())
|
||||
{
|
||||
win_spec1->save_order_list= win_spec2->order_list;
|
||||
win_spec1->order_list= win_spec2->order_list;
|
||||
}
|
||||
else
|
||||
{
|
||||
win_spec1->save_order_list= win_spec2->order_list;
|
||||
win_spec2->order_list= win_spec1->order_list;
|
||||
}
|
||||
|
||||
cmp= compare_window_frames(win_spec1->window_frame,
|
||||
win_spec2->window_frame);
|
||||
|
|
|
|||
|
|
@ -111,8 +111,10 @@ class Window_spec : public Sql_alloc
|
|||
LEX_CSTRING *window_ref;
|
||||
|
||||
SQL_I_List<ORDER> *partition_list;
|
||||
SQL_I_List<ORDER> *save_partition_list;
|
||||
|
||||
SQL_I_List<ORDER> *order_list;
|
||||
SQL_I_List<ORDER> *save_order_list;
|
||||
|
||||
Window_frame *window_frame;
|
||||
|
||||
|
|
@ -123,7 +125,8 @@ class Window_spec : public Sql_alloc
|
|||
SQL_I_List<ORDER> *ord_list,
|
||||
Window_frame *win_frame)
|
||||
: window_names_are_checked(false), window_ref(win_ref),
|
||||
partition_list(part_list), order_list(ord_list),
|
||||
partition_list(part_list), save_partition_list(NULL),
|
||||
order_list(ord_list), save_order_list(NULL),
|
||||
window_frame(win_frame), referenced_win_spec(NULL) {}
|
||||
|
||||
virtual const char *name() { return NULL; }
|
||||
|
|
|
|||
|
|
@ -1937,7 +1937,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
|
|||
table_wild simple_expr column_default_non_parenthesized_expr udf_expr
|
||||
primary_expr string_factor_expr mysql_concatenation_expr
|
||||
select_sublist_qualified_asterisk
|
||||
expr_or_default set_expr_or_default
|
||||
expr_or_ignore expr_or_ignore_or_default set_expr_or_default
|
||||
geometry_function signed_literal expr_or_literal
|
||||
sp_opt_default
|
||||
simple_ident_nospvar
|
||||
|
|
@ -2426,7 +2426,7 @@ execute_var_list:
|
|||
;
|
||||
|
||||
execute_var_ident:
|
||||
expr_or_default
|
||||
expr_or_ignore_or_default
|
||||
{
|
||||
if (unlikely(Lex->prepared_stmt_params.push_back($1,
|
||||
thd->mem_root)))
|
||||
|
|
@ -10354,7 +10354,7 @@ column_default_non_parenthesized_expr:
|
|||
if (unlikely(il))
|
||||
my_yyabort_error((ER_WRONG_COLUMN_NAME, MYF(0), il->my_name()->str));
|
||||
$$= new (thd->mem_root) Item_default_value(thd, Lex->current_context(),
|
||||
$3);
|
||||
$3, 0);
|
||||
if (unlikely($$ == NULL))
|
||||
MYSQL_YYABORT;
|
||||
Lex->default_used= TRUE;
|
||||
|
|
@ -13592,7 +13592,7 @@ ident_eq_list:
|
|||
;
|
||||
|
||||
ident_eq_value:
|
||||
simple_ident_nospvar equal expr_or_default
|
||||
simple_ident_nospvar equal expr_or_ignore_or_default
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
if (unlikely(lex->field_list.push_back($1, thd->mem_root)) ||
|
||||
|
|
@ -13662,12 +13662,12 @@ opt_values_with_names:
|
|||
;
|
||||
|
||||
values:
|
||||
values ',' expr_or_default
|
||||
values ',' expr_or_ignore_or_default
|
||||
{
|
||||
if (unlikely(Lex->insert_list->push_back($3, thd->mem_root)))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| expr_or_default
|
||||
| expr_or_ignore_or_default
|
||||
{
|
||||
if (unlikely(Lex->insert_list->push_back($1, thd->mem_root)))
|
||||
MYSQL_YYABORT;
|
||||
|
|
@ -13675,7 +13675,7 @@ values:
|
|||
;
|
||||
|
||||
values_with_names:
|
||||
values_with_names ',' remember_name expr_or_default remember_end
|
||||
values_with_names ',' remember_name expr_or_ignore_or_default remember_end
|
||||
{
|
||||
if (unlikely(Lex->insert_list->push_back($4, thd->mem_root)))
|
||||
MYSQL_YYABORT;
|
||||
|
|
@ -13683,7 +13683,7 @@ values_with_names:
|
|||
if (!$4->name.str || $4->name.str == item_empty_name)
|
||||
$4->set_name(thd, $3, (uint) ($5 - $3), thd->charset());
|
||||
}
|
||||
| remember_name expr_or_default remember_end
|
||||
| remember_name expr_or_ignore_or_default remember_end
|
||||
{
|
||||
if (unlikely(Lex->insert_list->push_back($2, thd->mem_root)))
|
||||
MYSQL_YYABORT;
|
||||
|
|
@ -13693,14 +13693,8 @@ values_with_names:
|
|||
}
|
||||
;
|
||||
|
||||
expr_or_default:
|
||||
expr_or_ignore:
|
||||
expr { $$= $1;}
|
||||
| DEFAULT
|
||||
{
|
||||
$$= new (thd->mem_root) Item_default_specification(thd);
|
||||
if (unlikely($$ == NULL))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| IGNORE_SYM
|
||||
{
|
||||
$$= new (thd->mem_root) Item_ignore_specification(thd);
|
||||
|
|
@ -13709,6 +13703,16 @@ expr_or_default:
|
|||
}
|
||||
;
|
||||
|
||||
expr_or_ignore_or_default:
|
||||
expr_or_ignore { $$= $1;}
|
||||
| DEFAULT
|
||||
{
|
||||
$$= new (thd->mem_root) Item_default_specification(thd);
|
||||
if (unlikely($$ == NULL))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
;
|
||||
|
||||
opt_insert_update:
|
||||
/* empty */
|
||||
| ON DUPLICATE_SYM { Lex->duplicates= DUP_UPDATE; }
|
||||
|
|
@ -13765,10 +13769,16 @@ update_list:
|
|||
;
|
||||
|
||||
update_elem:
|
||||
simple_ident_nospvar equal expr_or_default
|
||||
simple_ident_nospvar equal DEFAULT
|
||||
{
|
||||
if (unlikely(add_item_to_list(thd, $1)) ||
|
||||
unlikely(add_value_to_list(thd, $3)))
|
||||
Item *def= new (thd->mem_root) Item_default_value(thd,
|
||||
Lex->current_context(), $1, 1);
|
||||
if (!def || add_item_to_list(thd, $1) || add_value_to_list(thd, def))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| simple_ident_nospvar equal expr_or_ignore
|
||||
{
|
||||
if (add_item_to_list(thd, $1) || add_value_to_list(thd, $3))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
;
|
||||
|
|
@ -13779,7 +13789,7 @@ insert_update_list:
|
|||
;
|
||||
|
||||
insert_update_elem:
|
||||
simple_ident_nospvar equal expr_or_default
|
||||
simple_ident_nospvar equal expr_or_ignore_or_default
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
if (unlikely(lex->update_list.push_back($1, thd->mem_root)) ||
|
||||
|
|
@ -15046,7 +15056,7 @@ load_data_set_list:
|
|||
;
|
||||
|
||||
load_data_set_elem:
|
||||
simple_ident_nospvar equal remember_name expr_or_default remember_end
|
||||
simple_ident_nospvar equal remember_name expr_or_ignore_or_default remember_end
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
if (unlikely(lex->update_list.push_back($1, thd->mem_root)) ||
|
||||
|
|
|
|||
|
|
@ -1338,7 +1338,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
|
|||
table_wild simple_expr column_default_non_parenthesized_expr udf_expr
|
||||
primary_expr string_factor_expr mysql_concatenation_expr
|
||||
select_sublist_qualified_asterisk
|
||||
expr_or_default set_expr_or_default
|
||||
expr_or_ignore expr_or_ignore_or_default set_expr_or_default
|
||||
geometry_function signed_literal expr_or_literal
|
||||
sp_opt_default
|
||||
simple_ident_nospvar
|
||||
|
|
@ -1848,7 +1848,7 @@ execute_var_list:
|
|||
;
|
||||
|
||||
execute_var_ident:
|
||||
expr_or_default
|
||||
expr_or_ignore_or_default
|
||||
{
|
||||
if (unlikely(Lex->prepared_stmt_params.push_back($1,
|
||||
thd->mem_root)))
|
||||
|
|
@ -10293,7 +10293,7 @@ column_default_non_parenthesized_expr:
|
|||
if (unlikely(il))
|
||||
my_yyabort_error((ER_WRONG_COLUMN_NAME, MYF(0), il->my_name()->str));
|
||||
$$= new (thd->mem_root) Item_default_value(thd, Lex->current_context(),
|
||||
$3);
|
||||
$3, 0);
|
||||
if (unlikely($$ == NULL))
|
||||
MYSQL_YYABORT;
|
||||
Lex->default_used= TRUE;
|
||||
|
|
@ -13546,7 +13546,7 @@ ident_eq_list:
|
|||
;
|
||||
|
||||
ident_eq_value:
|
||||
simple_ident_nospvar equal expr_or_default
|
||||
simple_ident_nospvar equal expr_or_ignore_or_default
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
if (unlikely(lex->field_list.push_back($1, thd->mem_root)) ||
|
||||
|
|
@ -13616,12 +13616,12 @@ opt_values_with_names:
|
|||
;
|
||||
|
||||
values:
|
||||
values ',' expr_or_default
|
||||
values ',' expr_or_ignore_or_default
|
||||
{
|
||||
if (unlikely(Lex->insert_list->push_back($3, thd->mem_root)))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| expr_or_default
|
||||
| expr_or_ignore_or_default
|
||||
{
|
||||
if (unlikely(Lex->insert_list->push_back($1, thd->mem_root)))
|
||||
MYSQL_YYABORT;
|
||||
|
|
@ -13629,7 +13629,7 @@ values:
|
|||
;
|
||||
|
||||
values_with_names:
|
||||
values_with_names ',' remember_name expr_or_default remember_end
|
||||
values_with_names ',' remember_name expr_or_ignore_or_default remember_end
|
||||
{
|
||||
if (unlikely(Lex->insert_list->push_back($4, thd->mem_root)))
|
||||
MYSQL_YYABORT;
|
||||
|
|
@ -13637,7 +13637,7 @@ values_with_names:
|
|||
if (!$4->name.str || $4->name.str == item_empty_name)
|
||||
$4->set_name(thd, $3, (uint) ($5 - $3), thd->charset());
|
||||
}
|
||||
| remember_name expr_or_default remember_end
|
||||
| remember_name expr_or_ignore_or_default remember_end
|
||||
{
|
||||
if (unlikely(Lex->insert_list->push_back($2, thd->mem_root)))
|
||||
MYSQL_YYABORT;
|
||||
|
|
@ -13647,14 +13647,8 @@ values_with_names:
|
|||
}
|
||||
;
|
||||
|
||||
expr_or_default:
|
||||
expr_or_ignore:
|
||||
expr { $$= $1;}
|
||||
| DEFAULT
|
||||
{
|
||||
$$= new (thd->mem_root) Item_default_specification(thd);
|
||||
if (unlikely($$ == NULL))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| IGNORE_SYM
|
||||
{
|
||||
$$= new (thd->mem_root) Item_ignore_specification(thd);
|
||||
|
|
@ -13663,6 +13657,16 @@ expr_or_default:
|
|||
}
|
||||
;
|
||||
|
||||
expr_or_ignore_or_default:
|
||||
expr_or_ignore { $$= $1;}
|
||||
| DEFAULT
|
||||
{
|
||||
$$= new (thd->mem_root) Item_default_specification(thd);
|
||||
if (unlikely($$ == NULL))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
;
|
||||
|
||||
opt_insert_update:
|
||||
/* empty */
|
||||
| ON DUPLICATE_SYM { Lex->duplicates= DUP_UPDATE; }
|
||||
|
|
@ -13719,10 +13723,16 @@ update_list:
|
|||
;
|
||||
|
||||
update_elem:
|
||||
simple_ident_nospvar equal expr_or_default
|
||||
simple_ident_nospvar equal DEFAULT
|
||||
{
|
||||
if (unlikely(add_item_to_list(thd, $1)) ||
|
||||
unlikely(add_value_to_list(thd, $3)))
|
||||
Item *def= new (thd->mem_root) Item_default_value(thd,
|
||||
Lex->current_context(), $1, 1);
|
||||
if (!def || add_item_to_list(thd, $1) || add_value_to_list(thd, def))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| simple_ident_nospvar equal expr_or_ignore
|
||||
{
|
||||
if (add_item_to_list(thd, $1) || add_value_to_list(thd, $3))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
;
|
||||
|
|
@ -13733,7 +13743,7 @@ insert_update_list:
|
|||
;
|
||||
|
||||
insert_update_elem:
|
||||
simple_ident_nospvar equal expr_or_default
|
||||
simple_ident_nospvar equal expr_or_ignore_or_default
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
if (unlikely(lex->update_list.push_back($1, thd->mem_root)) ||
|
||||
|
|
@ -15006,7 +15016,7 @@ load_data_set_list:
|
|||
;
|
||||
|
||||
load_data_set_elem:
|
||||
simple_ident_nospvar equal remember_name expr_or_default remember_end
|
||||
simple_ident_nospvar equal remember_name expr_or_ignore_or_default remember_end
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
if (unlikely(lex->update_list.push_back($1, thd->mem_root)) ||
|
||||
|
|
|
|||
49
sql/table.cc
49
sql/table.cc
|
|
@ -6448,7 +6448,7 @@ void TABLE::prepare_for_position()
|
|||
if ((file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) &&
|
||||
s->primary_key < MAX_KEY)
|
||||
{
|
||||
mark_columns_used_by_index_no_reset(s->primary_key, read_set);
|
||||
mark_index_columns_for_read(s->primary_key);
|
||||
/* signal change */
|
||||
file->column_bitmaps_signal();
|
||||
}
|
||||
|
|
@ -6464,7 +6464,7 @@ MY_BITMAP *TABLE::prepare_for_keyread(uint index, MY_BITMAP *map)
|
|||
file->ha_start_keyread(index);
|
||||
if (map != read_set || !(file->index_flags(index, 0, 1) & HA_CLUSTERED_INDEX))
|
||||
{
|
||||
mark_columns_used_by_index(index, map);
|
||||
mark_index_columns(index, map);
|
||||
column_bitmaps_set(map);
|
||||
}
|
||||
DBUG_RETURN(backup);
|
||||
|
|
@ -6475,12 +6475,12 @@ MY_BITMAP *TABLE::prepare_for_keyread(uint index, MY_BITMAP *map)
|
|||
Mark that only fields from one key is used. Useful before keyread.
|
||||
*/
|
||||
|
||||
void TABLE::mark_columns_used_by_index(uint index, MY_BITMAP *bitmap)
|
||||
void TABLE::mark_index_columns(uint index, MY_BITMAP *bitmap)
|
||||
{
|
||||
DBUG_ENTER("TABLE::mark_columns_used_by_index");
|
||||
DBUG_ENTER("TABLE::mark_index_columns");
|
||||
|
||||
bitmap_clear_all(bitmap);
|
||||
mark_columns_used_by_index_no_reset(index, bitmap);
|
||||
mark_index_columns_no_reset(index, bitmap);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
|
@ -6504,23 +6504,36 @@ void TABLE::restore_column_maps_after_keyread(MY_BITMAP *backup)
|
|||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
static void do_mark_index_columns(TABLE *table, uint index,
|
||||
MY_BITMAP *bitmap, bool read)
|
||||
{
|
||||
KEY_PART_INFO *key_part= table->key_info[index].key_part;
|
||||
uint key_parts= table->key_info[index].user_defined_key_parts;
|
||||
for (uint k= 0; k < key_parts; k++)
|
||||
if (read)
|
||||
key_part[k].field->register_field_in_read_map();
|
||||
else
|
||||
bitmap_set_bit(bitmap, key_part[k].fieldnr-1);
|
||||
if (table->file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX &&
|
||||
table->s->primary_key != MAX_KEY && table->s->primary_key != index)
|
||||
do_mark_index_columns(table, table->s->primary_key, bitmap, read);
|
||||
|
||||
}
|
||||
/*
|
||||
mark columns used by key, but don't reset other fields
|
||||
*/
|
||||
|
||||
void TABLE::mark_columns_used_by_index_no_reset(uint index, MY_BITMAP *bitmap)
|
||||
inline void TABLE::mark_index_columns_no_reset(uint index, MY_BITMAP *bitmap)
|
||||
{
|
||||
KEY_PART_INFO *key_part= key_info[index].key_part;
|
||||
KEY_PART_INFO *key_part_end= (key_part + key_info[index].user_defined_key_parts);
|
||||
for (;key_part != key_part_end; key_part++)
|
||||
bitmap_set_bit(bitmap, key_part->fieldnr-1);
|
||||
if (file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX &&
|
||||
s->primary_key != MAX_KEY && s->primary_key != index)
|
||||
mark_columns_used_by_index_no_reset(s->primary_key, bitmap);
|
||||
do_mark_index_columns(this, index, bitmap, false);
|
||||
}
|
||||
|
||||
|
||||
inline void TABLE::mark_index_columns_for_read(uint index)
|
||||
{
|
||||
do_mark_index_columns(this, index, read_set, true);
|
||||
}
|
||||
|
||||
/*
|
||||
Mark auto-increment fields as used fields in both read and write maps
|
||||
|
||||
|
|
@ -6539,7 +6552,7 @@ void TABLE::mark_auto_increment_column()
|
|||
bitmap_set_bit(read_set, found_next_number_field->field_index);
|
||||
bitmap_set_bit(write_set, found_next_number_field->field_index);
|
||||
if (s->next_number_keypart)
|
||||
mark_columns_used_by_index_no_reset(s->next_number_index, read_set);
|
||||
mark_index_columns_for_read(s->next_number_index);
|
||||
file->column_bitmaps_signal();
|
||||
}
|
||||
|
||||
|
|
@ -6595,7 +6608,7 @@ void TABLE::mark_columns_needed_for_delete()
|
|||
file->use_hidden_primary_key();
|
||||
else
|
||||
{
|
||||
mark_columns_used_by_index_no_reset(s->primary_key, read_set);
|
||||
mark_index_columns_for_read(s->primary_key);
|
||||
need_signal= true;
|
||||
}
|
||||
}
|
||||
|
|
@ -6688,7 +6701,7 @@ void TABLE::mark_columns_needed_for_update()
|
|||
file->use_hidden_primary_key();
|
||||
else
|
||||
{
|
||||
mark_columns_used_by_index_no_reset(s->primary_key, read_set);
|
||||
mark_index_columns_for_read(s->primary_key);
|
||||
need_signal= true;
|
||||
}
|
||||
}
|
||||
|
|
@ -6848,7 +6861,7 @@ void TABLE::mark_columns_per_binlog_row_image()
|
|||
if ((my_field->flags & PRI_KEY_FLAG) ||
|
||||
(my_field->type() != MYSQL_TYPE_BLOB))
|
||||
{
|
||||
bitmap_set_bit(read_set, my_field->field_index);
|
||||
my_field->register_field_in_read_map();
|
||||
bitmap_set_bit(rpl_write_set, my_field->field_index);
|
||||
}
|
||||
}
|
||||
|
|
@ -6860,7 +6873,7 @@ void TABLE::mark_columns_per_binlog_row_image()
|
|||
We don't need to mark the primary key in the rpl_write_set as the
|
||||
binary log will include all columns read anyway.
|
||||
*/
|
||||
mark_columns_used_by_index_no_reset(s->primary_key, read_set);
|
||||
mark_index_columns_for_read(s->primary_key);
|
||||
if (versioned())
|
||||
{
|
||||
// TODO: After MDEV-18432 we don't pass history rows, so remove this:
|
||||
|
|
|
|||
|
|
@ -1459,8 +1459,9 @@ public:
|
|||
MY_BITMAP *prepare_for_keyread(uint index, MY_BITMAP *map);
|
||||
MY_BITMAP *prepare_for_keyread(uint index)
|
||||
{ return prepare_for_keyread(index, &tmp_set); }
|
||||
void mark_columns_used_by_index(uint index, MY_BITMAP *map);
|
||||
void mark_columns_used_by_index_no_reset(uint index, MY_BITMAP *map);
|
||||
void mark_index_columns(uint index, MY_BITMAP *bitmap);
|
||||
void mark_index_columns_no_reset(uint index, MY_BITMAP *bitmap);
|
||||
void mark_index_columns_for_read(uint index);
|
||||
void restore_column_maps_after_keyread(MY_BITMAP *backup);
|
||||
void mark_auto_increment_column(void);
|
||||
void mark_columns_needed_for_update(void);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue