Remove some usage of Check_level_instant_set and Sql_mode_save

The reason for the removal are:
- Generates more code
  - Storing and retreving THD
  - Causes extra code and daata to be generated to handle possible throw
    exceptions (which never happens in MariaDB code)
- Uses more stack space

Other things:
- Changed convert_const_to_int() to use item->save_in_field_no_warnings(),
  which made the code shorter and simpler.
- Removed not needed code in Sp_handler::sp_create_routine()
- Added thd as argument to store_key.copy() to make function simpler
- Added thd as argument to some subselect* constructor that inherites
  from Item_subselect.
This commit is contained in:
Monty 2021-01-30 14:03:23 +02:00 committed by Sergei Golubchik
parent d754d3d951
commit 08bc062e3c
9 changed files with 71 additions and 47 deletions

View File

@ -4419,7 +4419,7 @@ int ha_partition::write_row(const uchar * buf)
bool have_auto_increment= table->next_number_field && buf == table->record[0];
MY_BITMAP *old_map;
THD *thd= ha_thd();
Sql_mode_save sms(thd);
sql_mode_t org_sql_mode= thd->variables.sql_mode;
bool saved_auto_inc_field_not_null= table->auto_increment_field_not_null;
DBUG_ENTER("ha_partition::write_row");
DBUG_PRINT("enter", ("partition this: %p", this));
@ -4485,6 +4485,7 @@ int ha_partition::write_row(const uchar * buf)
exit:
table->auto_increment_field_not_null= saved_auto_inc_field_not_null;
thd->variables.sql_mode= org_sql_mode;
DBUG_RETURN(error);
}

View File

@ -1454,16 +1454,23 @@ int Item::save_in_field_no_warnings(Field *field, bool no_conversions)
int res;
TABLE *table= field->table;
THD *thd= table->in_use;
Check_level_instant_set check_level_save(thd, CHECK_FIELD_IGNORE);
Sql_mode_save sms(thd);
enum_check_fields org_count_cuted_fields= thd->count_cuted_fields;
sql_mode_t org_sql_mode= thd->variables.sql_mode;
MY_BITMAP *old_map= dbug_tmp_use_all_columns(table, &table->write_set);
thd->variables.sql_mode&= ~(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE);
thd->variables.sql_mode|= MODE_INVALID_DATES;
MY_BITMAP *old_map= dbug_tmp_use_all_columns(table, &table->write_set);
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
res= save_in_field(field, no_conversions);
thd->count_cuted_fields= org_count_cuted_fields;
thd->variables.sql_mode= org_sql_mode;
dbug_tmp_restore_column_map(&table->write_set, old_map);
return res;
}
#ifndef DBUG_OFF
static inline
void mark_unsupported_func(const char *where, const char *processor_name)

View File

@ -321,29 +321,25 @@ static bool convert_const_to_int(THD *thd, Item_field *field_item,
if ((*item)->can_eval_in_optimize())
{
TABLE *table= field->table;
Sql_mode_save sql_mode(thd);
Check_level_instant_set check_level_save(thd, CHECK_FIELD_IGNORE);
MY_BITMAP *old_maps[2] = { NULL, NULL };
ulonglong UNINIT_VAR(orig_field_val); /* original field value if valid */
bool save_field_value;
/* table->read_set may not be set if we come here from a CREATE TABLE */
if (table && table->read_set)
dbug_tmp_use_all_columns(table, old_maps,
&table->read_set, &table->write_set);
/* For comparison purposes allow invalid dates like 2000-01-32 */
thd->variables.sql_mode= (thd->variables.sql_mode & ~MODE_NO_ZERO_DATE) |
MODE_INVALID_DATES;
/*
Store the value of the field/constant because the call to save_in_field
below overrides that value. Don't save field value if no data has been
read yet.
*/
bool save_field_value= (field_item->const_item() ||
!(field->table->status & STATUS_NO_RECORD));
save_field_value= (field_item->const_item() ||
!(field->table->status & STATUS_NO_RECORD));
if (save_field_value)
orig_field_val= field->val_int();
if (!(*item)->save_in_field(field, 1) && !field->is_null())
if (!(*item)->save_in_field_no_warnings(field, 1) && !field->is_null())
{
int field_cmp= 0;
// If item is a decimal value, we must reject it if it was truncated.

View File

@ -821,9 +821,9 @@ bool Item_subselect::walk(Item_processor processor, bool walk_subquery,
bool Item_subselect::exec()
{
subselect_engine *org_engine= engine;
DBUG_ENTER("Item_subselect::exec");
DBUG_ASSERT(fixed());
DBUG_ASSERT(thd);
DBUG_EXECUTE_IF("Item_subselect",
Item::Print print(this,
@ -999,6 +999,8 @@ bool Item_in_subselect::exec()
{
DBUG_ENTER("Item_in_subselect::exec");
DBUG_ASSERT(fixed());
DBUG_ASSERT(thd);
/*
Initialize the cache of the left predicate operand. This has to be done as
late as now, because Cached_item directly contains a resolved field (not
@ -4005,11 +4007,10 @@ int join_read_next_same_or_null(READ_RECORD *info);
int subselect_single_select_engine::exec()
{
DBUG_ENTER("subselect_single_select_engine::exec");
char const *save_where= thd->where;
SELECT_LEX *save_select= thd->lex->current_select;
thd->lex->current_select= select_lex;
DBUG_ENTER("subselect_single_select_engine::exec");
if (join->optimization_state == JOIN::NOT_OPTIMIZED)
{
@ -4219,7 +4220,7 @@ bool subselect_uniquesubquery_engine::copy_ref_key(bool skip_constants)
enum store_key::store_key_result store_res;
if (skip_constants && (*copy)->store_key_is_const())
continue;
store_res= (*copy)->copy();
store_res= (*copy)->copy(thd);
tab->ref.key_err= store_res;
if (store_res == store_key::STORE_KEY_FATAL)
@ -4271,6 +4272,7 @@ int subselect_uniquesubquery_engine::exec()
table->status= 0;
Item_in_subselect *in_subs= item->get_IN_subquery();
DBUG_ASSERT(in_subs);
DBUG_ASSERT(thd);
if (!tab->preread_init_done && tab->preread_init())
DBUG_RETURN(1);
@ -4431,6 +4433,7 @@ int subselect_indexsubquery_engine::exec()
bool null_finding= 0;
TABLE *table= tab->table;
Item_in_subselect *in_subs= item->get_IN_subquery();
DBUG_ASSERT(thd);
in_subs->value= 0;
empty_result_set= TRUE;
@ -5650,7 +5653,6 @@ int subselect_hash_sj_engine::exec()
SELECT_LEX *save_select= thd->lex->current_select;
subselect_partial_match_engine *pm_engine= NULL;
int res= 0;
DBUG_ENTER("subselect_hash_sj_engine::exec");
/*
@ -5757,7 +5759,8 @@ int subselect_hash_sj_engine::exec()
{
pm_engine=
(new (thd->mem_root)
subselect_rowid_merge_engine((subselect_uniquesubquery_engine*)
subselect_rowid_merge_engine(thd,
(subselect_uniquesubquery_engine*)
lookup_engine, tmp_table,
count_pm_keys,
has_covering_null_row,
@ -5771,9 +5774,10 @@ int subselect_hash_sj_engine::exec()
init(nn_key_parts, &partial_match_key_parts))
{
/*
The call to init() would fail if there was not enough memory to allocate
all buffers for the rowid merge strategy. In this case revert to table
scanning which doesn't need any big buffers.
The call to init() would fail if there was not enough memory
to allocate all buffers for the rowid merge strategy. In
this case revert to table scanning which doesn't need any
big buffers.
*/
delete pm_engine;
pm_engine= NULL;
@ -5785,7 +5789,8 @@ int subselect_hash_sj_engine::exec()
{
if (!(pm_engine=
(new (thd->mem_root)
subselect_table_scan_engine((subselect_uniquesubquery_engine*)
subselect_table_scan_engine(thd,
(subselect_uniquesubquery_engine*)
lookup_engine, tmp_table,
item, result,
semi_join_conds->argument_list(),
@ -6255,6 +6260,7 @@ void Ordered_key::print(String *str)
subselect_partial_match_engine::subselect_partial_match_engine(
THD *thd_arg,
subselect_uniquesubquery_engine *engine_arg,
TABLE *tmp_table_arg, Item_subselect *item_arg,
select_result_interceptor *result_arg,
@ -6268,13 +6274,16 @@ subselect_partial_match_engine::subselect_partial_match_engine(
has_covering_null_row(has_covering_null_row_arg),
has_covering_null_columns(has_covering_null_columns_arg),
count_columns_with_nulls(count_columns_with_nulls_arg)
{}
{
thd= thd_arg;
}
int subselect_partial_match_engine::exec()
{
Item_in_subselect *item_in= item->get_IN_subquery();
int lookup_res;
DBUG_ASSERT(thd);
DBUG_ASSERT(!(item_in->left_expr_has_null() &&
item_in->is_top_level_item()));
@ -6877,6 +6886,7 @@ end:
subselect_table_scan_engine::subselect_table_scan_engine(
THD *thd,
subselect_uniquesubquery_engine *engine_arg,
TABLE *tmp_table_arg,
Item_subselect *item_arg,
@ -6885,7 +6895,7 @@ subselect_table_scan_engine::subselect_table_scan_engine(
bool has_covering_null_row_arg,
bool has_covering_null_columns_arg,
uint count_columns_with_nulls_arg)
:subselect_partial_match_engine(engine_arg, tmp_table_arg, item_arg,
:subselect_partial_match_engine(thd, engine_arg, tmp_table_arg, item_arg,
result_arg, equi_join_conds_arg,
has_covering_null_row_arg,
has_covering_null_columns_arg,

View File

@ -991,7 +991,10 @@ public:
subselect_uniquesubquery_engine(THD *thd_arg, st_join_table *tab_arg,
Item_in_subselect *subs, Item *where)
:subselect_engine(subs, 0), tab(tab_arg), cond(where)
{ DBUG_ASSERT(subs); }
{
thd= thd_arg;
DBUG_ASSERT(subs);
}
~subselect_uniquesubquery_engine();
void cleanup();
int prepare(THD *);
@ -1408,7 +1411,8 @@ protected:
protected:
virtual bool partial_match()= 0;
public:
subselect_partial_match_engine(subselect_uniquesubquery_engine *engine_arg,
subselect_partial_match_engine(THD *thd,
subselect_uniquesubquery_engine *engine_arg,
TABLE *tmp_table_arg, Item_subselect *item_arg,
select_result_interceptor *result_arg,
List<Item> *equi_join_conds_arg,
@ -1502,7 +1506,8 @@ protected:
bool exists_complementing_null_row(MY_BITMAP *keys_to_complement);
bool partial_match();
public:
subselect_rowid_merge_engine(subselect_uniquesubquery_engine *engine_arg,
subselect_rowid_merge_engine(THD *thd,
subselect_uniquesubquery_engine *engine_arg,
TABLE *tmp_table_arg, uint merge_keys_count_arg,
bool has_covering_null_row_arg,
bool has_covering_null_columns_arg,
@ -1510,7 +1515,7 @@ public:
Item_subselect *item_arg,
select_result_interceptor *result_arg,
List<Item> *equi_join_conds_arg)
:subselect_partial_match_engine(engine_arg, tmp_table_arg,
:subselect_partial_match_engine(thd, engine_arg, tmp_table_arg,
item_arg, result_arg, equi_join_conds_arg,
has_covering_null_row_arg,
has_covering_null_columns_arg,
@ -1529,7 +1534,8 @@ class subselect_table_scan_engine: public subselect_partial_match_engine
protected:
bool partial_match();
public:
subselect_table_scan_engine(subselect_uniquesubquery_engine *engine_arg,
subselect_table_scan_engine(THD *thd,
subselect_uniquesubquery_engine *engine_arg,
TABLE *tmp_table_arg, Item_subselect *item_arg,
select_result_interceptor *result_arg,
List<Item> *equi_join_conds_arg,

View File

@ -1205,10 +1205,9 @@ Sp_handler::sp_create_routine(THD *thd, const sp_head *sp) const
TABLE *table;
char definer_buf[USER_HOST_BUFF_SIZE];
LEX_CSTRING definer;
sql_mode_t saved_mode= thd->variables.sql_mode;
sql_mode_t org_sql_mode= thd->variables.sql_mode;
enum_check_fields org_count_cuted_fields= thd->count_cuted_fields;
CHARSET_INFO *db_cs= get_default_db_collation(thd, sp->m_db.str);
bool store_failed= FALSE;
DBUG_ENTER("sp_create_routine");
DBUG_PRINT("enter", ("type: %s name: %.*s",
@ -1241,8 +1240,7 @@ Sp_handler::sp_create_routine(THD *thd, const sp_head *sp) const
/* Reset sql_mode during data dictionary operations. */
thd->variables.sql_mode= 0;
Check_level_instant_set check_level_save(thd, CHECK_FIELD_WARN);
thd->count_cuted_fields= CHECK_FIELD_WARN;
if (!(table= open_proc_table_for_update(thd)))
{
@ -1390,7 +1388,7 @@ Sp_handler::sp_create_routine(THD *thd, const sp_head *sp) const
store_failed= store_failed ||
table->field[MYSQL_PROC_FIELD_SQL_MODE]->
store((longlong)saved_mode, TRUE);
store((longlong) org_sql_mode, TRUE);
if (sp->comment().str)
{
@ -1478,13 +1476,13 @@ log:
sp->chistics(),
thd->lex->definer[0],
thd->lex->create_info,
saved_mode))
org_sql_mode))
{
my_error(ER_OUT_OF_RESOURCES, MYF(0));
goto done;
}
/* restore sql_mode when binloging */
thd->variables.sql_mode= saved_mode;
thd->variables.sql_mode= org_sql_mode;
/* Such a statement can always go directly to binlog, no trans cache */
if (thd->binlog_query(THD::STMT_QUERY_TYPE,
log_query.ptr(), log_query.length(),
@ -1493,12 +1491,12 @@ log:
my_error(ER_ERROR_ON_WRITE, MYF(0), "binary log", -1);
goto done;
}
thd->variables.sql_mode= 0;
}
ret= FALSE;
done:
thd->variables.sql_mode= saved_mode;
thd->variables.sql_mode= org_sql_mode;
thd->count_cuted_fields= org_count_cuted_fields;
DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
DBUG_RETURN(ret);
}

View File

@ -11039,7 +11039,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j,
FALSE);
if (unlikely(thd->is_fatal_error))
DBUG_RETURN(TRUE);
tmp.copy();
tmp.copy(thd);
j->ref.const_ref_part_map |= key_part_map(1) << i ;
}
else
@ -24592,18 +24592,20 @@ cmp_buffer_with_ref(THD *thd, TABLE *table, TABLE_REF *tab_ref)
bool
cp_buffer_from_ref(THD *thd, TABLE *table, TABLE_REF *ref)
{
Check_level_instant_set check_level_save(thd, CHECK_FIELD_IGNORE);
enum_check_fields org_count_cuted_fields= thd->count_cuted_fields;
MY_BITMAP *old_map= dbug_tmp_use_all_columns(table, &table->write_set);
bool result= 0;
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
for (store_key **copy=ref->key_copy ; *copy ; copy++)
{
if ((*copy)->copy() & 1)
if ((*copy)->copy(thd) & 1)
{
result= 1;
break;
}
}
thd->count_cuted_fields= org_count_cuted_fields;
dbug_tmp_restore_column_map(&table->write_set, old_map);
return result;
}

View File

@ -1930,15 +1930,17 @@ public:
@details this function makes sure truncation warnings when preparing the
key buffers don't end up as errors (because of an enclosing INSERT/UPDATE).
*/
enum store_key_result copy()
enum store_key_result copy(THD *thd)
{
enum store_key_result result;
THD *thd= to_field->table->in_use;
Check_level_instant_set check_level_save(thd, CHECK_FIELD_IGNORE);
Sql_mode_save sql_mode(thd);
enum_check_fields org_count_cuted_fields= thd->count_cuted_fields;
sql_mode_t org_sql_mode= thd->variables.sql_mode;
thd->variables.sql_mode&= ~(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE);
thd->variables.sql_mode|= MODE_INVALID_DATES;
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
result= copy_inner();
thd->count_cuted_fields= org_count_cuted_fields;
thd->variables.sql_mode= org_sql_mode;
return result;
}

View File

@ -9712,10 +9712,12 @@ do_continue:;
Set the truncated column values of thd as warning
for alter table.
*/
Check_level_instant_set check_level_save(thd, CHECK_FIELD_WARN);
enum_check_fields org_count_cuted_fields= thd->count_cuted_fields;
thd->count_cuted_fields= CHECK_FIELD_WARN;
int res= mysql_inplace_alter_table(thd, table_list, table, &altered_table,
&ha_alter_info,
&target_mdl_request, &alter_ctx);
thd->count_cuted_fields= org_count_cuted_fields;
my_free(const_cast<uchar*>(frm.str));
if (res)