diff options
author | Igor Babaev <igor@askmonty.org> | 2011-10-28 04:07:11 -0700 |
---|---|---|
committer | Igor Babaev <igor@askmonty.org> | 2011-10-28 04:07:11 -0700 |
commit | 4b4dfd57f570b25c87133f16ead3bd83e6c8f73b (patch) | |
tree | 1367ad13b5cc800dc9e1d436e0c5ff44da92cd73 /sql | |
parent | 2162704829a08b3ebd41e2cdf6a6b5f7ea6bcc6d (diff) | |
parent | adc1f2f4c939c15ad5efd37633332560456cd4fd (diff) | |
download | mariadb-git-4b4dfd57f570b25c87133f16ead3bd83e6c8f73b.tar.gz |
Merge.
Diffstat (limited to 'sql')
-rw-r--r-- | sql/filesort.cc | 11 | ||||
-rw-r--r-- | sql/handler.h | 2 | ||||
-rw-r--r-- | sql/opt_index_cond_pushdown.cc | 65 |
3 files changed, 45 insertions, 33 deletions
diff --git a/sql/filesort.cc b/sql/filesort.cc index da275c1c14f..15020b56e52 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -546,12 +546,11 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select, /* Temporary set for register_used_fields and register_field_in_read_map */ sort_form->read_set= &sort_form->tmp_set; register_used_fields(param); - if (select && select->cond) - select->cond->walk(&Item::register_field_in_read_map, 1, - (uchar*) sort_form); - if (select && select->pre_idx_push_select_cond) - select->pre_idx_push_select_cond->walk(&Item::register_field_in_read_map, - 1, (uchar*) sort_form); + Item *sort_cond= !select ? + 0 : !select->pre_idx_push_select_cond ? + select->cond : select->pre_idx_push_select_cond; + if (sort_cond) + sort_cond->walk(&Item::register_field_in_read_map, 1, (uchar*) sort_form); sort_form->column_bitmaps_set(&sort_form->tmp_set, &sort_form->tmp_set, &sort_form->tmp_set); diff --git a/sql/handler.h b/sql/handler.h index ce10872867a..46f5beb45d2 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1723,6 +1723,7 @@ public: DBUG_ENTER("ha_rnd_init"); DBUG_ASSERT(inited==NONE || (inited==RND && scan)); inited= (result= rnd_init(scan)) ? NONE: RND; + end_range= NULL; DBUG_RETURN(result); } int ha_rnd_end() @@ -1730,6 +1731,7 @@ public: DBUG_ENTER("ha_rnd_end"); DBUG_ASSERT(inited==RND); inited=NONE; + end_range= NULL; DBUG_RETURN(rnd_end()); } int ha_rnd_init_with_error(bool scan) __attribute__ ((warn_unused_result)); diff --git a/sql/opt_index_cond_pushdown.cc b/sql/opt_index_cond_pushdown.cc index e0a2d3b1f30..639ceedf693 100644 --- a/sql/opt_index_cond_pushdown.cc +++ b/sql/opt_index_cond_pushdown.cc @@ -83,15 +83,44 @@ bool uses_index_fields_only(Item *item, TABLE *tbl, uint keyno, case Item::FIELD_ITEM: { Item_field *item_field= (Item_field*)item; - if (item_field->field->table != tbl) + Field *field= item_field->field; + if (field->table != tbl) return TRUE; /* The below is probably a repetition - the first part checks the other two, but let's play it safe: */ - return item_field->field->part_of_key.is_set(keyno) && - item_field->field->type() != MYSQL_TYPE_GEOMETRY && - item_field->field->type() != MYSQL_TYPE_BLOB; + if(!field->part_of_key.is_set(keyno) || + field->type() == MYSQL_TYPE_GEOMETRY || + field->type() == MYSQL_TYPE_BLOB) + return FALSE; + KEY *key_info= tbl->key_info + keyno; + KEY_PART_INFO *key_part= key_info->key_part; + KEY_PART_INFO *key_part_end= key_part + key_info->key_parts; + for ( ; key_part < key_part_end; key_part++) + { + if (field->eq(key_part->field)) + return !(key_part->key_part_flag & HA_PART_KEY_SEG); + } + if ((tbl->file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) && + tbl->s->primary_key != MAX_KEY && + tbl->s->primary_key != keyno) + { + key_info= tbl->key_info + tbl->s->primary_key; + key_part= key_info->key_part; + key_part_end= key_part + key_info->key_parts; + for ( ; key_part < key_part_end; key_part++) + { + /* + It does not make sense to use the fact that the engine can read in + a full field if the key if the index is built only over a part + of this field. + */ + if (field->eq(key_part->field)) + return !(key_part->key_part_flag & HA_PART_KEY_SEG); + } + } + return FALSE; } case Item::REF_ITEM: return uses_index_fields_only(item->real_item(), tbl, keyno, @@ -288,30 +317,12 @@ void push_index_cond(JOIN_TAB *tab, uint keyno) { DBUG_ENTER("push_index_cond"); Item *idx_cond; - bool do_index_cond_pushdown= - ((tab->table->file->index_flags(keyno, 0, 1) & - HA_DO_INDEX_COND_PUSHDOWN) && - optimizer_flag(tab->join->thd, OPTIMIZER_SWITCH_INDEX_COND_PUSHDOWN)); - - /* - Do not try index condition pushdown on indexes which have partially-covered - columns. Unpacking from a column prefix into index tuple is not a supported - operation in some engines, see e.g. MySQL BUG#42991. - TODO: a better solution would be not to consider partially-covered columns - as parts of the index and still produce/check index condition for - fully-covered index columns. - */ - KEY *key_info= tab->table->key_info + keyno; - for (uint kp= 0; kp < key_info->key_parts; kp++) - { - if ((key_info->key_part[kp].key_part_flag & HA_PART_KEY_SEG)) - { - do_index_cond_pushdown= FALSE; - break; - } - } - if (do_index_cond_pushdown) + if ((tab->table->file->index_flags(keyno, 0, 1) & + HA_DO_INDEX_COND_PUSHDOWN) && + optimizer_flag(tab->join->thd, OPTIMIZER_SWITCH_INDEX_COND_PUSHDOWN) && + tab->join->thd->lex->sql_command != SQLCOM_UPDATE_MULTI && + tab->join->thd->lex->sql_command != SQLCOM_DELETE_MULTI) { DBUG_EXECUTE("where", print_where(tab->select_cond, "full cond", QT_ORDINARY);); |