Commit 4f721196 authored by sergefp@mysql.com's avatar sergefp@mysql.com

Post-merge fixes

parent 30b3c3bf
...@@ -274,7 +274,7 @@ class SEL_TREE :public Sql_alloc ...@@ -274,7 +274,7 @@ class SEL_TREE :public Sql_alloc
public: public:
enum Type { IMPOSSIBLE, ALWAYS, MAYBE, KEY, KEY_SMALLER } type; enum Type { IMPOSSIBLE, ALWAYS, MAYBE, KEY, KEY_SMALLER } type;
SEL_TREE(enum Type type_arg) :type(type_arg) {} SEL_TREE(enum Type type_arg) :type(type_arg) {}
SEL_TREE() :type(KEY), keys_map(0) { bzero((char*) keys,sizeof(keys));} SEL_TREE() :type(KEY) { keys_map.clear_all(); bzero((char*) keys,sizeof(keys));}
SEL_ARG *keys[MAX_KEY]; SEL_ARG *keys[MAX_KEY];
key_map keys_map; /* bitmask of non-NULL elements in keys */ key_map keys_map; /* bitmask of non-NULL elements in keys */
List<SEL_IMERGE> merges; /* possible ways to read rows using index_merge */ List<SEL_IMERGE> merges; /* possible ways to read rows using index_merge */
...@@ -314,9 +314,10 @@ static int get_quick_select_params(SEL_TREE *tree, PARAM& param, ...@@ -314,9 +314,10 @@ static int get_quick_select_params(SEL_TREE *tree, PARAM& param,
ha_rows* records, ha_rows* records,
SEL_ARG*** key_to_read); SEL_ARG*** key_to_read);
#ifndef DBUG_OFF #ifndef DBUG_OFF
void print_quick_sel_imerge(QUICK_INDEX_MERGE_SELECT *quick, static void print_quick_sel_imerge(QUICK_INDEX_MERGE_SELECT *quick,
const key_map *needed_reg);
void print_quick_sel_range(QUICK_RANGE_SELECT *quick,
const key_map *needed_reg); const key_map *needed_reg);
void print_quick_sel_range(QUICK_RANGE_SELECT *quick, const key_map *needed_reg);
#endif #endif
static SEL_TREE *tree_and(PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2); static SEL_TREE *tree_and(PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2);
...@@ -661,7 +662,7 @@ int QUICK_INDEX_MERGE_SELECT::init() ...@@ -661,7 +662,7 @@ int QUICK_INDEX_MERGE_SELECT::init()
int error; int error;
cur_quick_it.rewind(); cur_quick_it.rewind();
cur_quick_select= cur_quick_it++; cur_quick_select= cur_quick_it++;
if (error= index_merge.init(head)) if ((error= index_merge.init(head)))
return error; return error;
return cur_quick_select->init(); return cur_quick_select->init();
} }
...@@ -876,7 +877,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, ...@@ -876,7 +877,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
uint basflag; uint basflag;
uint idx; uint idx;
double scan_time; double scan_time;
QUICK_INDEX_MERGE_SELECT *quick_imerge; QUICK_INDEX_MERGE_SELECT *quick_imerge= NULL;
DBUG_ENTER("test_quick_select"); DBUG_ENTER("test_quick_select");
DBUG_PRINT("enter",("keys_to_use: %lu prev_tables: %lu const_tables: %lu", DBUG_PRINT("enter",("keys_to_use: %lu prev_tables: %lu const_tables: %lu",
keys_to_use.to_ulonglong(), (ulong) prev_tables, keys_to_use.to_ulonglong(), (ulong) prev_tables,
...@@ -1058,10 +1059,10 @@ imerge_fail:; ...@@ -1058,10 +1059,10 @@ imerge_fail:;
records= min_imerge_records; records= min_imerge_records;
/* ok, got minimal imerge, *min_imerge, with cost min_imerge_cost */ /* ok, got minimal imerge, *min_imerge, with cost min_imerge_cost */
if (head->used_keys) if (!head->used_keys.is_clear_all())
{ {
/* check if "ALL" +"using index" read would be faster */ /* check if "ALL" +"using index" read would be faster */
int key_for_use= find_shortest_key(head, head->used_keys); int key_for_use= find_shortest_key(head, &head->used_keys);
ha_rows total_table_records= (0 == head->file->records)? 1 : ha_rows total_table_records= (0 == head->file->records)? 1 :
head->file->records; head->file->records;
uint keys_per_block= (head->file->block_size/2/ uint keys_per_block= (head->file->block_size/2/
...@@ -1216,12 +1217,10 @@ static int get_quick_select_params(SEL_TREE *tree, PARAM& param, ...@@ -1216,12 +1217,10 @@ static int get_quick_select_params(SEL_TREE *tree, PARAM& param,
(*key)->maybe_flag) (*key)->maybe_flag)
needed_reg.set_bit(keynr); needed_reg.set_bit(keynr);
key_map usable_keys = index_read_can_be_used? bool read_index_only= index_read_can_be_used? head->used_keys.is_set(keynr): false;
(head->used_keys & ((key_map) 1 << keynr)) : 0;
found_records=check_quick_select(&param, idx, *key); found_records=check_quick_select(&param, idx, *key);
if (found_records != HA_POS_ERROR && found_records > 2 && if (found_records != HA_POS_ERROR && found_records > 2 &&
usable_keys && read_index_only &&
(head->file->index_flags(keynr) & HA_KEY_READ_ONLY)) (head->file->index_flags(keynr) & HA_KEY_READ_ONLY))
{ {
/* /*
...@@ -1439,7 +1438,7 @@ get_mm_parts(PARAM *param, Field *field, Item_func::Functype type, ...@@ -1439,7 +1438,7 @@ get_mm_parts(PARAM *param, Field *field, Item_func::Functype type,
} }
sel_arg->part=(uchar) key_part->part; sel_arg->part=(uchar) key_part->part;
tree->keys[key_part->key]=sel_add(tree->keys[key_part->key],sel_arg); tree->keys[key_part->key]=sel_add(tree->keys[key_part->key],sel_arg);
tree->keys_map |= 1 << key_part->key; tree->keys_map.set_bit(key_part->key);
} }
} }
...@@ -1712,8 +1711,8 @@ tree_and(PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2) ...@@ -1712,8 +1711,8 @@ tree_and(PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2)
DBUG_RETURN(tree1); DBUG_RETURN(tree1);
} }
bool trees_have_key = false; key_map result_keys;
key_map result_keys= 0; result_keys.clear_all();
/* Join the trees key per key */ /* Join the trees key per key */
SEL_ARG **key1,**key2,**end; SEL_ARG **key1,**key2,**end;
for (key1= tree1->keys,key2= tree2->keys,end=key1+param->keys ; for (key1= tree1->keys,key2= tree2->keys,end=key1+param->keys ;
...@@ -1722,7 +1721,6 @@ tree_and(PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2) ...@@ -1722,7 +1721,6 @@ tree_and(PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2)
uint flag=0; uint flag=0;
if (*key1 || *key2) if (*key1 || *key2)
{ {
trees_have_key = true;
if (*key1 && !(*key1)->simple_key()) if (*key1 && !(*key1)->simple_key())
flag|=CLONE_KEY1_MAYBE; flag|=CLONE_KEY1_MAYBE;
if (*key2 && !(*key2)->simple_key()) if (*key2 && !(*key2)->simple_key())
...@@ -1733,7 +1731,7 @@ tree_and(PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2) ...@@ -1733,7 +1731,7 @@ tree_and(PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2)
tree1->type= SEL_TREE::IMPOSSIBLE; tree1->type= SEL_TREE::IMPOSSIBLE;
DBUG_RETURN(tree1); DBUG_RETURN(tree1);
} }
result_keys |= 1 << (key1 - tree1->keys); result_keys.set_bit(key1 - tree1->keys);
#ifdef EXTRA_DEBUG #ifdef EXTRA_DEBUG
(*key1)->test_use_count(*key1); (*key1)->test_use_count(*key1);
#endif #endif
...@@ -1741,7 +1739,7 @@ tree_and(PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2) ...@@ -1741,7 +1739,7 @@ tree_and(PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2)
} }
tree1->keys_map= result_keys; tree1->keys_map= result_keys;
/* dispose index_merge if there is a "range" option */ /* dispose index_merge if there is a "range" option */
if (trees_have_key) if (!result_keys.is_clear_all())
{ {
tree1->merges.empty(); tree1->merges.empty();
DBUG_RETURN(tree1); DBUG_RETURN(tree1);
...@@ -1749,7 +1747,6 @@ tree_and(PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2) ...@@ -1749,7 +1747,6 @@ tree_and(PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2)
/* ok, both trees are index_merge trees */ /* ok, both trees are index_merge trees */
imerge_list_and_list(&tree1->merges, &tree2->merges); imerge_list_and_list(&tree1->merges, &tree2->merges);
DBUG_RETURN(tree1); DBUG_RETURN(tree1);
} }
...@@ -1760,17 +1757,18 @@ tree_and(PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2) ...@@ -1760,17 +1757,18 @@ tree_and(PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2)
bool sel_trees_can_be_ored(SEL_TREE *tree1, SEL_TREE *tree2, PARAM* param) bool sel_trees_can_be_ored(SEL_TREE *tree1, SEL_TREE *tree2, PARAM* param)
{ {
key_map common_keys= tree1->keys_map & tree2->keys_map; key_map common_keys= tree1->keys_map;
common_keys.intersect(tree2->keys_map);
DBUG_ENTER("sel_trees_can_be_ored"); DBUG_ENTER("sel_trees_can_be_ored");
if (!common_keys) if (common_keys.is_clear_all())
DBUG_RETURN(false); DBUG_RETURN(false);
/* trees have a common key, check if they refer to same key part */ /* trees have a common key, check if they refer to same key part */
SEL_ARG **key1,**key2; SEL_ARG **key1,**key2;
for (uint key_no=0; key_no < param->keys; key_no++, common_keys= common_keys >> 1) for (uint key_no=0; key_no < param->keys; key_no++)
{ {
if (common_keys & 1) if (common_keys.is_set(key_no))
{ {
key1= tree1->keys + key_no; key1= tree1->keys + key_no;
key2= tree2->keys + key_no; key2= tree2->keys + key_no;
...@@ -1799,7 +1797,8 @@ tree_or(PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2) ...@@ -1799,7 +1797,8 @@ tree_or(PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2)
DBUG_RETURN(tree2); DBUG_RETURN(tree2);
SEL_TREE *result= 0; SEL_TREE *result= 0;
key_map result_keys= 0; key_map result_keys;
result_keys.clear_all();
if (sel_trees_can_be_ored(tree1, tree2, param)) if (sel_trees_can_be_ored(tree1, tree2, param))
{ {
/* Join the trees key per key */ /* Join the trees key per key */
...@@ -1811,7 +1810,7 @@ tree_or(PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2) ...@@ -1811,7 +1810,7 @@ tree_or(PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2)
if (*key1) if (*key1)
{ {
result=tree1; // Added to tree1 result=tree1; // Added to tree1
result_keys |= 1 << (key1 - tree1->keys); result_keys.set_bit(key1 - tree1->keys);
#ifdef EXTRA_DEBUG #ifdef EXTRA_DEBUG
(*key1)->test_use_count(*key1); (*key1)->test_use_count(*key1);
#endif #endif
...@@ -1901,7 +1900,6 @@ and_all_keys(SEL_ARG *key1,SEL_ARG *key2,uint clone_flag) ...@@ -1901,7 +1900,6 @@ and_all_keys(SEL_ARG *key1,SEL_ARG *key2,uint clone_flag)
} }
static SEL_ARG * static SEL_ARG *
key_and(SEL_ARG *key1,SEL_ARG *key2,uint clone_flag) key_and(SEL_ARG *key1,SEL_ARG *key2,uint clone_flag)
{ {
...@@ -3675,7 +3673,7 @@ print_key(KEY_PART *key_part,const char *key,uint used_length) ...@@ -3675,7 +3673,7 @@ print_key(KEY_PART *key_part,const char *key,uint used_length)
} }
} }
void print_quick_sel_imerge(QUICK_INDEX_MERGE_SELECT *quick, static void print_quick_sel_imerge(QUICK_INDEX_MERGE_SELECT *quick,
const key_map *needed_reg) const key_map *needed_reg)
{ {
DBUG_ENTER("print_param"); DBUG_ENTER("print_param");
...@@ -3691,7 +3689,7 @@ void print_quick_sel_imerge(QUICK_INDEX_MERGE_SELECT *quick, ...@@ -3691,7 +3689,7 @@ void print_quick_sel_imerge(QUICK_INDEX_MERGE_SELECT *quick,
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
static void print_quick_sel_range(QUICK_RANGE_SELECT *quick,const key_map *needed_reg) void print_quick_sel_range(QUICK_RANGE_SELECT *quick,const key_map *needed_reg)
{ {
QUICK_RANGE *range; QUICK_RANGE *range;
char buf[MAX_KEY/8+1]; char buf[MAX_KEY/8+1];
......
...@@ -118,7 +118,7 @@ public: ...@@ -118,7 +118,7 @@ public:
byte *record; byte *record;
protected: protected:
friend void print_quick_sel_range(QUICK_RANGE_SELECT *quick, friend void print_quick_sel_range(QUICK_RANGE_SELECT *quick,
key_map needed_reg); const key_map* needed_reg);
friend QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table, friend QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table,
struct st_table_ref *ref); struct st_table_ref *ref);
friend bool get_quick_keys(struct st_qsel_param *param, friend bool get_quick_keys(struct st_qsel_param *param,
......
...@@ -311,7 +311,7 @@ void copy_fields(TMP_TABLE_PARAM *param); ...@@ -311,7 +311,7 @@ void copy_fields(TMP_TABLE_PARAM *param);
void copy_funcs(Item **func_ptr); void copy_funcs(Item **func_ptr);
bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param, bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
int error, bool ignore_last_dupp_error); int error, bool ignore_last_dupp_error);
uint find_shortest_key(TABLE *table, key_map usable_keys); uint find_shortest_key(TABLE *table, const key_map *usable_keys);
/* functions from opt_sum.cc */ /* functions from opt_sum.cc */
int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds); int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds);
......
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