mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
Merge 10.6 into 10.10
The MDEV-29693 conflict resolution is from Monty, as well as is a bug fix where ANALYZE TABLE wrongly built histograms for single-column PRIMARY KEY. Also includes a fix for safe_malloc error reporting. Other things: - Copied main.log_slow from 10.4 to avoid mtr issue Disabled test: - spider/bugfix.mdev_27239 because we started to get +Error 1429 Unable to connect to foreign data source: localhost -Error 1158 Got an error reading communication packets - main.delayed - Bug#54332 Deadlock with two connections doing LOCK TABLE+INSERT DELAYED This part is disabled for now as it fails randomly with different warnings/errors (no corruption).
This commit is contained in:
111
sql/opt_range.cc
111
sql/opt_range.cc
@@ -725,7 +725,8 @@ int SEL_IMERGE::or_sel_tree_with_checks(RANGE_OPT_PARAM *param,
|
||||
|
||||
result_keys.set_bit(key_no);
|
||||
#ifdef EXTRA_DEBUG
|
||||
if (param->alloced_sel_args < SEL_ARG::MAX_SEL_ARGS)
|
||||
if (param->alloced_sel_args <
|
||||
param->thd->variables.optimizer_max_sel_args)
|
||||
{
|
||||
key1= result->keys[key_no];
|
||||
(key1)->test_use_count(key1);
|
||||
@@ -2055,7 +2056,7 @@ SEL_ARG *SEL_ARG::clone(RANGE_OPT_PARAM *param, SEL_ARG *new_parent,
|
||||
SEL_ARG *tmp;
|
||||
|
||||
/* Bail out if we have already generated too many SEL_ARGs */
|
||||
if (++param->alloced_sel_args > MAX_SEL_ARGS)
|
||||
if (++param->alloced_sel_args > param->thd->variables.optimizer_max_sel_args)
|
||||
return 0;
|
||||
|
||||
if (type != KEY_RANGE)
|
||||
@@ -2682,7 +2683,8 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
|
||||
ha_rows limit, bool force_quick_range,
|
||||
bool ordered_output,
|
||||
bool remove_false_parts_of_where,
|
||||
bool only_single_index_range_scan)
|
||||
bool only_single_index_range_scan,
|
||||
bool suppress_unusable_key_notes)
|
||||
{
|
||||
uint idx;
|
||||
double scan_time;
|
||||
@@ -2757,6 +2759,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
|
||||
DBUG_RETURN(0); // Fatal error flag is set
|
||||
|
||||
/* set up parameter that is passed to all functions */
|
||||
bzero((void*) ¶m, sizeof(param));
|
||||
param.thd= thd;
|
||||
param.baseflag= head->file->ha_table_flags();
|
||||
param.prev_tables=prev_tables | const_tables;
|
||||
@@ -2773,6 +2776,9 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
|
||||
param.max_key_parts= 0;
|
||||
param.remove_false_where_parts= remove_false_parts_of_where;
|
||||
param.force_default_mrr= ordered_output;
|
||||
param.note_unusable_keys= (!suppress_unusable_key_notes &&
|
||||
thd->give_notes_for_unusable_keys());
|
||||
|
||||
param.possible_keys.clear_all();
|
||||
|
||||
thd->no_errors=1; // Don't warn about NULL
|
||||
@@ -2895,7 +2901,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
|
||||
if (notnull_cond_tree)
|
||||
tree= tree_and(¶m, tree, notnull_cond_tree);
|
||||
if (thd->trace_started() &&
|
||||
param.alloced_sel_args >= SEL_ARG::MAX_SEL_ARGS)
|
||||
param.alloced_sel_args >= thd->variables.optimizer_max_sel_args)
|
||||
{
|
||||
Json_writer_object wrapper(thd);
|
||||
Json_writer_object obj(thd, "sel_arg_alloc_limit_hit");
|
||||
@@ -3950,6 +3956,7 @@ bool prune_partitions(THD *thd, TABLE *table, Item *pprune_cond)
|
||||
prune_param.part_info= part_info;
|
||||
init_sql_alloc(key_memory_quick_range_select_root, &alloc,
|
||||
thd->variables.range_alloc_block_size, 0, MYF(MY_THREAD_SPECIFIC));
|
||||
bzero((void*) range_par, sizeof(*range_par));
|
||||
range_par->mem_root= &alloc;
|
||||
range_par->old_root= thd->mem_root;
|
||||
|
||||
@@ -3975,6 +3982,7 @@ bool prune_partitions(THD *thd, TABLE *table, Item *pprune_cond)
|
||||
range_par->remove_jump_scans= FALSE;
|
||||
range_par->real_keynr[0]= 0;
|
||||
range_par->alloced_sel_args= 0;
|
||||
range_par->note_unusable_keys= 0;
|
||||
|
||||
thd->no_errors=1; // Don't warn about NULL
|
||||
thd->mem_root=&alloc;
|
||||
@@ -8729,14 +8737,21 @@ Item_func_like::get_mm_leaf(RANGE_OPT_PARAM *param,
|
||||
if (key_part->image_type != Field::itRAW)
|
||||
DBUG_RETURN(0);
|
||||
|
||||
uint keynr= param->real_keynr[key_part->key];
|
||||
if (param->using_real_indexes &&
|
||||
!field->optimize_range(param->real_keynr[key_part->key],
|
||||
key_part->part))
|
||||
!field->optimize_range(keynr, key_part->part))
|
||||
DBUG_RETURN(0);
|
||||
|
||||
if (field->result_type() == STRING_RESULT &&
|
||||
field->charset() != compare_collation())
|
||||
{
|
||||
if (param->note_unusable_keys)
|
||||
field->raise_note_cannot_use_key_part(param->thd, keynr, key_part->part,
|
||||
func_name_cstring(), value,
|
||||
Data_type_compatibility::
|
||||
INCOMPATIBLE_COLLATION);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
StringBuffer<MAX_FIELD_WIDTH> tmp(value->collation.collation);
|
||||
String *res;
|
||||
@@ -8747,7 +8762,14 @@ Item_func_like::get_mm_leaf(RANGE_OPT_PARAM *param,
|
||||
if (field->cmp_type() != STRING_RESULT ||
|
||||
field->type_handler() == &type_handler_enum ||
|
||||
field->type_handler() == &type_handler_set)
|
||||
{
|
||||
if (param->note_unusable_keys)
|
||||
field->raise_note_cannot_use_key_part(param->thd, keynr, key_part->part,
|
||||
func_name_cstring(), value,
|
||||
Data_type_compatibility::
|
||||
INCOMPATIBLE_DATA_TYPE);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
/*
|
||||
TODO:
|
||||
@@ -8827,19 +8849,44 @@ Item_bool_func::get_mm_leaf(RANGE_OPT_PARAM *param,
|
||||
}
|
||||
|
||||
|
||||
bool Field::can_optimize_scalar_range(const RANGE_OPT_PARAM *param,
|
||||
const KEY_PART *key_part,
|
||||
const Item_bool_func *cond,
|
||||
scalar_comparison_op op,
|
||||
const Item *value) const
|
||||
Data_type_compatibility
|
||||
Field::can_optimize_scalar_range(const RANGE_OPT_PARAM *param,
|
||||
const KEY_PART *key_part,
|
||||
const Item_bool_func *cond,
|
||||
scalar_comparison_op op,
|
||||
Item *value) const
|
||||
{
|
||||
bool is_eq_func= op == SCALAR_CMP_EQ || op == SCALAR_CMP_EQUAL;
|
||||
if ((param->using_real_indexes &&
|
||||
!optimize_range(param->real_keynr[key_part->key],
|
||||
key_part->part) && !is_eq_func) ||
|
||||
!can_optimize_range(cond, value, is_eq_func))
|
||||
return false;
|
||||
return true;
|
||||
uint keynr= param->real_keynr[key_part->key];
|
||||
if (param->using_real_indexes &&
|
||||
!optimize_range(keynr, key_part->part) && !is_eq_func)
|
||||
return Data_type_compatibility::INCOMPATIBLE_DATA_TYPE;
|
||||
Data_type_compatibility compat= can_optimize_range(cond, value, is_eq_func);
|
||||
if (compat == Data_type_compatibility::OK)
|
||||
return compat;
|
||||
/*
|
||||
Raise a note that the index part could not be used.
|
||||
|
||||
TODO: Perhaps we also need to raise a similar note when
|
||||
a partition could not be used (when using_real_indexes==false).
|
||||
*/
|
||||
if (param->using_real_indexes && param->note_unusable_keys)
|
||||
{
|
||||
DBUG_ASSERT(keynr < table->s->keys);
|
||||
/*
|
||||
Here "cond" can be any sargable predicate, e.g.:
|
||||
1. field=value (and other scalar comparison predicates: <, <=, <=>, =>, >)
|
||||
2. field [NOT] BETWEEN value1 AND value2
|
||||
3. field [NOT] IN (value1, value2...)
|
||||
Don't print the entire "cond" as in case of BETWEEN and IN
|
||||
it would list all values.
|
||||
Let's only print the current field/value pair.
|
||||
*/
|
||||
raise_note_cannot_use_key_part(param->thd, keynr, key_part->part,
|
||||
scalar_comparison_op_to_lex_cstring(op),
|
||||
value, compat);
|
||||
}
|
||||
return compat;
|
||||
}
|
||||
|
||||
|
||||
@@ -8879,7 +8926,8 @@ SEL_ARG *Field_num::get_mm_leaf(RANGE_OPT_PARAM *prm, KEY_PART *key_part,
|
||||
scalar_comparison_op op, Item *value)
|
||||
{
|
||||
DBUG_ENTER("Field_num::get_mm_leaf");
|
||||
if (!can_optimize_scalar_range(prm, key_part, cond, op, value))
|
||||
if (can_optimize_scalar_range(prm, key_part, cond, op, value) !=
|
||||
Data_type_compatibility::OK)
|
||||
DBUG_RETURN(0);
|
||||
int err= value->save_in_field_no_warnings(this, 1);
|
||||
if ((op != SCALAR_CMP_EQUAL && is_real_null()) || err < 0)
|
||||
@@ -8895,7 +8943,8 @@ SEL_ARG *Field_temporal::get_mm_leaf(RANGE_OPT_PARAM *prm, KEY_PART *key_part,
|
||||
scalar_comparison_op op, Item *value)
|
||||
{
|
||||
DBUG_ENTER("Field_temporal::get_mm_leaf");
|
||||
if (!can_optimize_scalar_range(prm, key_part, cond, op, value))
|
||||
if (can_optimize_scalar_range(prm, key_part, cond, op, value) !=
|
||||
Data_type_compatibility::OK)
|
||||
DBUG_RETURN(0);
|
||||
int err= value->save_in_field_no_warnings(this, 1);
|
||||
if ((op != SCALAR_CMP_EQUAL && is_real_null()) || err < 0)
|
||||
@@ -8913,7 +8962,8 @@ SEL_ARG *Field_date_common::get_mm_leaf(RANGE_OPT_PARAM *prm,
|
||||
Item *value)
|
||||
{
|
||||
DBUG_ENTER("Field_date_common::get_mm_leaf");
|
||||
if (!can_optimize_scalar_range(prm, key_part, cond, op, value))
|
||||
if (can_optimize_scalar_range(prm, key_part, cond, op, value) !=
|
||||
Data_type_compatibility::OK)
|
||||
DBUG_RETURN(0);
|
||||
int err= value->save_in_field_no_warnings(this, 1);
|
||||
if ((op != SCALAR_CMP_EQUAL && is_real_null()) || err < 0)
|
||||
@@ -8955,7 +9005,8 @@ SEL_ARG *Field_str::get_mm_leaf(RANGE_OPT_PARAM *prm, KEY_PART *key_part,
|
||||
scalar_comparison_op op, Item *value)
|
||||
{
|
||||
DBUG_ENTER("Field_str::get_mm_leaf");
|
||||
if (!can_optimize_scalar_range(prm, key_part, cond, op, value))
|
||||
if (can_optimize_scalar_range(prm, key_part, cond, op, value) !=
|
||||
Data_type_compatibility::OK)
|
||||
DBUG_RETURN(0);
|
||||
int err= value->save_in_field_no_warnings(this, 1);
|
||||
if ((op != SCALAR_CMP_EQUAL && is_real_null()) || err < 0)
|
||||
@@ -8976,7 +9027,8 @@ SEL_ARG *Field::get_mm_leaf_int(RANGE_OPT_PARAM *prm, KEY_PART *key_part,
|
||||
bool unsigned_field)
|
||||
{
|
||||
DBUG_ENTER("Field::get_mm_leaf_int");
|
||||
if (!can_optimize_scalar_range(prm, key_part, cond, op, value))
|
||||
if (can_optimize_scalar_range(prm, key_part, cond, op, value) !=
|
||||
Data_type_compatibility::OK)
|
||||
DBUG_RETURN(0);
|
||||
int err= value->save_in_field_no_warnings(this, 1);
|
||||
if ((op != SCALAR_CMP_EQUAL && is_real_null()) || err < 0)
|
||||
@@ -9244,7 +9296,8 @@ int and_range_trees(RANGE_OPT_PARAM *param, SEL_TREE *tree1, SEL_TREE *tree2,
|
||||
}
|
||||
result_keys.set_bit(key_no);
|
||||
#ifdef EXTRA_DEBUG
|
||||
if (param->alloced_sel_args < SEL_ARG::MAX_SEL_ARGS)
|
||||
if (param->alloced_sel_args <
|
||||
param->thd->variables.optimizer_max_sel_args)
|
||||
key->test_use_count(key);
|
||||
#endif
|
||||
}
|
||||
@@ -9897,7 +9950,8 @@ and_all_keys(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2,
|
||||
key1->weight+= (tmp? tmp->weight: 0) - old_weight;
|
||||
if (use_count)
|
||||
next->increment_use_count(use_count);
|
||||
if (param->alloced_sel_args > SEL_ARG::MAX_SEL_ARGS)
|
||||
if (param->alloced_sel_args >
|
||||
param->thd->variables.optimizer_max_sel_args)
|
||||
break;
|
||||
}
|
||||
else
|
||||
@@ -14466,13 +14520,16 @@ check_group_min_max_predicates(Item *cond, Item_field *min_max_arg_item,
|
||||
Field *field= min_max_arg_item->field;
|
||||
if (!args[2]) // this is a binary function
|
||||
{
|
||||
if (!field->can_optimize_group_min_max(bool_func, args[1]))
|
||||
if (field->can_optimize_group_min_max(bool_func, args[1]) !=
|
||||
Data_type_compatibility::OK)
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
else // this is BETWEEN
|
||||
{
|
||||
if (!field->can_optimize_group_min_max(bool_func, args[1]) ||
|
||||
!field->can_optimize_group_min_max(bool_func, args[2]))
|
||||
if (field->can_optimize_group_min_max(bool_func, args[1]) !=
|
||||
Data_type_compatibility::OK ||
|
||||
field->can_optimize_group_min_max(bool_func, args[2]) !=
|
||||
Data_type_compatibility::OK)
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user