diff options
author | Igor Babaev <igor@askmonty.org> | 2017-10-06 00:08:36 -0700 |
---|---|---|
committer | Igor Babaev <igor@askmonty.org> | 2017-10-06 00:08:36 -0700 |
commit | dbeffabc83ed01112e09d7e782d44f044cfcb691 (patch) | |
tree | 96e46e4f8728a38ee25e1ae72a4bfc05e9ae3ecd /sql/opt_range.cc | |
parent | e6862cf1ff3ab11189f5d312055eccb56212a300 (diff) | |
download | mariadb-git-dbeffabc83ed01112e09d7e782d44f044cfcb691.tar.gz |
Fixed the bug mdev-11574.
Do not build an index merge of two indexes when one index is
an infix of the other index.
Diffstat (limited to 'sql/opt_range.cc')
-rw-r--r-- | sql/opt_range.cc | 39 |
1 files changed, 31 insertions, 8 deletions
diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 3563058282b..7b29e8b2b7b 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -8991,6 +8991,34 @@ bool sel_trees_can_be_ored(RANGE_OPT_PARAM* param, } /* + Check whether the key parts inf_init..inf_end-1 of one index can compose + an infix for the key parts key_init..key_end-1 of another index +*/ + +static +bool is_key_infix(KEY_PART *key_init, KEY_PART *key_end, + KEY_PART *inf_init, KEY_PART *inf_end) +{ + KEY_PART *key_part, *inf_part; + for (key_part= key_init; key_part < key_end; key_part++) + { + if (key_part->field->eq(inf_init->field)) + break; + } + if (key_part == key_end) + return false; + for (key_part++, inf_part= inf_init + 1; + key_part < key_end && inf_part < inf_end; + key_part++, inf_part++) + { + if (!key_part->field->eq(inf_part->field)) + return false; + } + return inf_part == inf_end; +} + + +/* Check whether range parts of two trees must be ored for some indexes SYNOPSIS @@ -9046,14 +9074,9 @@ bool sel_trees_must_be_ored(RANGE_OPT_PARAM* param, KEY_PART *key2_init= param->key[idx2]+tree2->keys[idx2]->part; KEY_PART *key2_end= param->key[idx2]+tree2->keys[idx2]->max_part_no; - KEY_PART *part1, *part2; - for (part1= key1_init, part2= key2_init; - part1 < key1_end && part2 < key2_end; - part1++, part2++) - { - if (!part1->field->eq(part2->field)) - DBUG_RETURN(FALSE); - } + if (!is_key_infix(key1_init, key1_end, key2_init, key2_end) && + !is_key_infix(key2_init, key2_end, key1_init, key1_end)) + DBUG_RETURN(FALSE); } } |