@@ -5958,6 +5958,34 @@ static SEL_TREE *get_func_mm_tree(RANGE_OPT_PARAM *param, Item_func *cond_func,
59585958 {
59595959 new_interval->min_value = last_val->max_value ;
59605960 new_interval->min_flag = NEAR_MIN;
5961+
5962+ /*
5963+ If the interval is over a partial keypart, the
5964+ interval must be "c_{i-1} <= X < c_i" instead of
5965+ "c_{i-1} < X < c_i". Reason:
5966+
5967+ Consider a table with a column "my_col VARCHAR(3)",
5968+ and an index with definition
5969+ "INDEX my_idx my_col(1)". If the table contains rows
5970+ with my_col values "f" and "foo", the index will not
5971+ distinguish the two rows.
5972+
5973+ Note that tree_or() below will effectively merge
5974+ this range with the range created for c_{i-1} and
5975+ we'll eventually end up with only one range:
5976+ "NULL < X".
5977+
5978+ Partitioning indexes are never partial.
5979+ */
5980+ if (param->using_real_indexes )
5981+ {
5982+ const KEY key=
5983+ param->table ->key_info [param->real_keynr [idx]];
5984+ const KEY_PART_INFO *kpi= key.key_part + new_interval->part ;
5985+
5986+ if (kpi->key_part_flag & HA_PART_KEY_SEG)
5987+ new_interval->min_flag = 0 ;
5988+ }
59615989 }
59625990 }
59635991 /*
@@ -6798,6 +6826,7 @@ get_mm_leaf(RANGE_OPT_PARAM *param, Item *conf_func, Field *field,
67986826
67996827 if (key_part->image_type == Field::itMBR)
68006828 {
6829+ // @todo: use is_spatial_operator() instead?
68016830 switch (type) {
68026831 case Item_func::SP_EQUALS_FUNC:
68036832 case Item_func::SP_DISJOINT_FUNC:
0 commit comments