Commit 73c43ee9 authored by Sergei Petrunia's avatar Sergei Petrunia

MDEV-24739: Assertion `root->weight >= ...' failed in SEL_ARG::tree_delete

Also update the SEL_ARG graph weight in:
- sel_add()
- SEL_ARG::clone()

Make key_{and,or}_with_limit() to also verify weight for the arguments
(There is no single point to verify SEL_ARG graphs constructed from
conditions that are not AND-OR formulas, so we hope that those are
connected with AND/OR and do it here).
parent a70a47f2
...@@ -214,3 +214,14 @@ left(@json, 1500) ...@@ -214,3 +214,14 @@ left(@json, 1500)
set optimizer_max_sel_arg_weight= @tmp9750_weight; set optimizer_max_sel_arg_weight= @tmp9750_weight;
set optimizer_trace=@tmp_9750; set optimizer_trace=@tmp_9750;
drop table t1; drop table t1;
#
# MDEV-24739: Assertion `root->weight >= ...' failed in SEL_ARG::tree_delete
#
SELECT *
FROM mysql.help_relation
WHERE NOT (help_topic_id != 8 AND help_keyword_id != 0 OR help_keyword_id = 2 OR help_topic_id < 1900);
help_topic_id help_keyword_id
SELECT *
FROM mysql.help_relation ignore index (help_topic_id)
WHERE (help_topic_id = 8 OR help_keyword_id = 0) AND help_keyword_id != 2 AND help_topic_id >= 1900;
help_topic_id help_keyword_id
...@@ -96,4 +96,17 @@ select left(@json, 1500); ...@@ -96,4 +96,17 @@ select left(@json, 1500);
set optimizer_max_sel_arg_weight= @tmp9750_weight; set optimizer_max_sel_arg_weight= @tmp9750_weight;
set optimizer_trace=@tmp_9750; set optimizer_trace=@tmp_9750;
drop table t1; drop table t1;
--echo #
--echo # MDEV-24739: Assertion `root->weight >= ...' failed in SEL_ARG::tree_delete
--echo #
SELECT *
FROM mysql.help_relation
WHERE NOT (help_topic_id != 8 AND help_keyword_id != 0 OR help_keyword_id = 2 OR help_topic_id < 1900);
SELECT *
FROM mysql.help_relation ignore index (help_topic_id)
WHERE (help_topic_id = 8 OR help_keyword_id = 0) AND help_keyword_id != 2 AND help_topic_id >= 1900;
...@@ -2079,6 +2079,7 @@ SEL_ARG *SEL_ARG::clone(RANGE_OPT_PARAM *param, SEL_ARG *new_parent, ...@@ -2079,6 +2079,7 @@ SEL_ARG *SEL_ARG::clone(RANGE_OPT_PARAM *param, SEL_ARG *new_parent,
tmp->color= color; tmp->color= color;
tmp->elements= this->elements; tmp->elements= this->elements;
tmp->max_part_no= max_part_no; tmp->max_part_no= max_part_no;
tmp->weight= weight;
return tmp; return tmp;
} }
...@@ -9035,6 +9036,19 @@ SEL_ARG *Field::stored_field_make_mm_leaf_exact(RANGE_OPT_PARAM *param, ...@@ -9035,6 +9036,19 @@ SEL_ARG *Field::stored_field_make_mm_leaf_exact(RANGE_OPT_PARAM *param,
** KEY_RANGE: Condition uses a key ** KEY_RANGE: Condition uses a key
******************************************************************************/ ******************************************************************************/
/*
Update weights for SEL_ARG graph that is connected only via next_key_part
(and not left/right) links
*/
static uint update_weight_for_single_arg(SEL_ARG *arg)
{
if (arg->next_key_part)
return (arg->weight= 1 + update_weight_for_single_arg(arg->next_key_part));
else
return (arg->weight= 1);
}
/* /*
Add a new key test to a key when scanning through all keys Add a new key test to a key when scanning through all keys
This will never be called for same key parts. This will never be called for same key parts.
...@@ -9067,6 +9081,8 @@ sel_add(SEL_ARG *key1,SEL_ARG *key2) ...@@ -9067,6 +9081,8 @@ sel_add(SEL_ARG *key1,SEL_ARG *key2)
} }
} }
*key_link=key1 ? key1 : key2; *key_link=key1 ? key1 : key2;
update_weight_for_single_arg(root);
return root; return root;
} }
...@@ -10020,6 +10036,13 @@ static ...@@ -10020,6 +10036,13 @@ static
SEL_ARG *key_or_with_limit(RANGE_OPT_PARAM *param, uint keyno, SEL_ARG *key_or_with_limit(RANGE_OPT_PARAM *param, uint keyno,
SEL_ARG *key1, SEL_ARG *key2) SEL_ARG *key1, SEL_ARG *key2)
{ {
#ifndef DBUG_OFF
if (key1)
key1->verify_weight();
if (key2)
key2->verify_weight();
#endif
SEL_ARG *res= key_or(param, key1, key2); SEL_ARG *res= key_or(param, key1, key2);
res= enforce_sel_arg_weight_limit(param, keyno, res); res= enforce_sel_arg_weight_limit(param, keyno, res);
#ifndef DBUG_OFF #ifndef DBUG_OFF
...@@ -10034,6 +10057,12 @@ static ...@@ -10034,6 +10057,12 @@ static
SEL_ARG *key_and_with_limit(RANGE_OPT_PARAM *param, uint keyno, SEL_ARG *key_and_with_limit(RANGE_OPT_PARAM *param, uint keyno,
SEL_ARG *key1, SEL_ARG *key2, uint clone_flag) SEL_ARG *key1, SEL_ARG *key2, uint clone_flag)
{ {
#ifndef DBUG_OFF
if (key1)
key1->verify_weight();
if (key2)
key2->verify_weight();
#endif
SEL_ARG *res= key_and(param, key1, key2, clone_flag); SEL_ARG *res= key_and(param, key1, key2, clone_flag);
res= enforce_sel_arg_weight_limit(param, keyno, res); res= enforce_sel_arg_weight_limit(param, keyno, res);
#ifndef DBUG_OFF #ifndef DBUG_OFF
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment