@@ -256,20 +256,28 @@ class SEL_TREE :public Sql_alloc
256
256
(type == SEL_TREE::IMPOSSIBLE)
257
257
*/
258
258
enum Type { IMPOSSIBLE, ALWAYS, MAYBE, KEY, KEY_SMALLER } type;
259
- SEL_TREE (enum Type type_arg) :type(type_arg) {}
260
- SEL_TREE () :type(KEY)
259
+
260
+ SEL_TREE (enum Type type_arg, MEM_ROOT *root, size_t num_keys)
261
+ : type(type_arg), keys(root, num_keys), n_ror_scans(0 )
261
262
{
262
263
keys_map.clear_all ();
263
- bzero ((char *) keys,sizeof (keys));
264
264
}
265
+
266
+ SEL_TREE (MEM_ROOT *root, size_t num_keys) :
267
+ type (KEY), keys(root, num_keys), n_ror_scans(0 )
268
+ {
269
+ keys_map.clear_all ();
270
+ }
271
+
265
272
SEL_TREE (SEL_TREE *arg, bool without_merges, RANGE_OPT_PARAM *param);
266
273
/*
267
274
Note: there may exist SEL_TREE objects with sel_tree->type=KEY and
268
275
keys[i]=0 for all i. (SergeyP: it is not clear whether there is any
269
276
merit in range analyzer functions (e.g. get_mm_parts) returning a
270
277
pointer to such SEL_TREE instead of NULL)
271
278
*/
272
- SEL_ARG *keys[MAX_KEY];
279
+ Mem_root_array<SEL_ARG *, true > keys;
280
+
273
281
key_map keys_map; /* bitmask of non-NULL elements in keys */
274
282
275
283
/*
@@ -579,7 +587,7 @@ int SEL_IMERGE::and_sel_tree(RANGE_OPT_PARAM *param, SEL_TREE *tree,
579
587
{
580
588
SEL_TREE *res_or_tree= 0 ;
581
589
SEL_TREE *and_tree= 0 ;
582
- if (!(res_or_tree= new SEL_TREE ()) ||
590
+ if (!(res_or_tree= new SEL_TREE (param-> mem_root , param-> keys )) ||
583
591
!(and_tree= new SEL_TREE (tree, TRUE , param)))
584
592
return (-1 );
585
593
if (!and_range_trees (param, *or_tree, and_tree, res_or_tree))
@@ -788,7 +796,10 @@ int SEL_IMERGE::or_sel_imerge_with_checks(RANGE_OPT_PARAM *param,
788
796
*/
789
797
790
798
SEL_TREE::SEL_TREE (SEL_TREE *arg, bool without_merges,
791
- RANGE_OPT_PARAM *param): Sql_alloc()
799
+ RANGE_OPT_PARAM *param)
800
+ : Sql_alloc(),
801
+ keys(param->mem_root, param->keys),
802
+ n_ror_scans(0 )
792
803
{
793
804
keys_map= arg->keys_map ;
794
805
type= arg->type ;
@@ -3020,9 +3031,7 @@ bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item **cond)
3020
3031
PARAM param;
3021
3032
MEM_ROOT alloc;
3022
3033
SEL_TREE *tree;
3023
- SEL_ARG **key, **end;
3024
3034
double rows;
3025
- uint idx= 0 ;
3026
3035
3027
3036
init_sql_alloc (&alloc, thd->variables .range_alloc_block_size , 0 ,
3028
3037
MYF (MY_THREAD_SPECIFIC));
@@ -3067,22 +3076,23 @@ bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item **cond)
3067
3076
goto free_alloc;
3068
3077
}
3069
3078
3070
- for (key= tree-> keys , end= key + param.keys ; key != end; key++, idx++)
3079
+ for (uint idx= 0 ; idx < param.keys ; idx++)
3071
3080
{
3072
- if (*key)
3081
+ SEL_ARG *key= tree->keys [idx];
3082
+ if (key)
3073
3083
{
3074
- if ((* key) ->type == SEL_ARG::IMPOSSIBLE)
3084
+ if (key->type == SEL_ARG::IMPOSSIBLE)
3075
3085
{
3076
3086
rows= 0 ;
3077
3087
table->reginfo .impossible_range = 1 ;
3078
3088
goto free_alloc;
3079
3089
}
3080
3090
else
3081
3091
{
3082
- rows= records_in_column_ranges (¶m, idx, * key);
3092
+ rows= records_in_column_ranges (¶m, idx, key);
3083
3093
if (rows != HA_POS_ERROR)
3084
- (* key) ->field ->cond_selectivity = rows/table_records;
3085
- }
3094
+ key->field ->cond_selectivity = rows/table_records;
3095
+ }
3086
3096
}
3087
3097
}
3088
3098
@@ -4947,8 +4957,8 @@ TABLE_READ_PLAN *merge_same_index_scans(PARAM *param, SEL_IMERGE *imerge,
4947
4957
{
4948
4958
SEL_TREE **changed_tree= imerge->trees +(*tree_idx_ptr-1 );
4949
4959
SEL_ARG *key= (*changed_tree)->keys [key_idx];
4950
- bzero ((*changed_tree) ->keys ,
4951
- sizeof (( *changed_tree)->keys [0 ])*param-> keys ) ;
4960
+ for (uint i= 0 ; i < param ->keys ; i++)
4961
+ ( *changed_tree)->keys [i]= NULL ;
4952
4962
(*changed_tree)->keys_map .clear_all ();
4953
4963
if (key)
4954
4964
key->incr_refs ();
@@ -6725,8 +6735,8 @@ static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
6725
6735
bool update_tbl_stats,
6726
6736
double read_time)
6727
6737
{
6728
- uint idx;
6729
- SEL_ARG **key,**end, ** key_to_read= NULL ;
6738
+ uint idx, best_idx ;
6739
+ SEL_ARG *key_to_read= NULL ;
6730
6740
ha_rows UNINIT_VAR (best_records); /* protected by key_to_read */
6731
6741
uint UNINIT_VAR (best_mrr_flags), /* protected by key_to_read */
6732
6742
UNINIT_VAR (best_buf_size); /* protected by key_to_read */
@@ -6749,24 +6759,25 @@ static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
6749
6759
sizeof (INDEX_SCAN_INFO *) * param->keys );
6750
6760
}
6751
6761
tree->index_scans_end = tree->index_scans ;
6752
- for (idx= 0 ,key=tree-> keys , end=key+ param->keys ; key != end; key++, idx++)
6762
+ for (idx= 0 ; idx < param->keys ; idx++)
6753
6763
{
6754
- if (*key)
6764
+ SEL_ARG *key= tree->keys [idx];
6765
+ if (key)
6755
6766
{
6756
6767
ha_rows found_records;
6757
6768
Cost_estimate cost;
6758
6769
double found_read_time;
6759
6770
uint mrr_flags, buf_size;
6760
6771
INDEX_SCAN_INFO *index_scan;
6761
6772
uint keynr= param->real_keynr [idx];
6762
- if ((* key) ->type == SEL_ARG::MAYBE_KEY ||
6763
- (* key) ->maybe_flag )
6773
+ if (key->type == SEL_ARG::MAYBE_KEY ||
6774
+ key->maybe_flag )
6764
6775
param->needed_reg ->set_bit (keynr);
6765
6776
6766
6777
bool read_index_only= index_read_must_be_used ? TRUE :
6767
6778
(bool ) param->table ->covering_keys .is_set (keynr);
6768
6779
6769
- found_records= check_quick_select (param, idx, read_index_only, * key,
6780
+ found_records= check_quick_select (param, idx, read_index_only, key,
6770
6781
update_tbl_stats, &mrr_flags,
6771
6782
&buf_size, &cost);
6772
6783
@@ -6780,7 +6791,7 @@ static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
6780
6791
index_scan->used_key_parts = param->max_key_part +1 ;
6781
6792
index_scan->range_count = param->range_count ;
6782
6793
index_scan->records = found_records;
6783
- index_scan->sel_arg = * key;
6794
+ index_scan->sel_arg = key;
6784
6795
*tree->index_scans_end ++= index_scan;
6785
6796
}
6786
6797
if ((found_records != HA_POS_ERROR) && param->is_ror_scan )
@@ -6794,6 +6805,7 @@ static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
6794
6805
read_time= found_read_time;
6795
6806
best_records= found_records;
6796
6807
key_to_read= key;
6808
+ best_idx= idx;
6797
6809
best_mrr_flags= mrr_flags;
6798
6810
best_buf_size= buf_size;
6799
6811
}
@@ -6804,17 +6816,16 @@ static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
6804
6816
" ROR scans" ););
6805
6817
if (key_to_read)
6806
6818
{
6807
- idx= key_to_read - tree->keys ;
6808
- if ((read_plan= new (param->mem_root ) TRP_RANGE (*key_to_read, idx,
6819
+ if ((read_plan= new (param->mem_root ) TRP_RANGE (key_to_read, best_idx,
6809
6820
best_mrr_flags)))
6810
6821
{
6811
6822
read_plan->records = best_records;
6812
- read_plan->is_ror = tree->ror_scans_map .is_set (idx );
6823
+ read_plan->is_ror = tree->ror_scans_map .is_set (best_idx );
6813
6824
read_plan->read_cost = read_time;
6814
6825
read_plan->mrr_buf_size = best_buf_size;
6815
6826
DBUG_PRINT (" info" ,
6816
6827
(" Returning range plan for key %s, cost %g, records %lu" ,
6817
- param->table ->key_info [param->real_keynr [idx ]].name ,
6828
+ param->table ->key_info [param->real_keynr [best_idx ]].name ,
6818
6829
read_plan->read_cost , (ulong) read_plan->records ));
6819
6830
}
6820
6831
}
@@ -7442,9 +7453,11 @@ SEL_TREE *Item::get_mm_tree_for_const(RANGE_OPT_PARAM *param)
7442
7453
MEM_ROOT *tmp_root= param->mem_root ;
7443
7454
param->thd ->mem_root = param->old_root ;
7444
7455
SEL_TREE *tree;
7445
- tree= val_int () ? new (tmp_root) SEL_TREE (SEL_TREE::ALWAYS) :
7446
- new (tmp_root) SEL_TREE ( SEL_TREE::IMPOSSIBLE) ;
7456
+
7457
+ const SEL_TREE::Type type= val_int ()? SEL_TREE::ALWAYS: SEL_TREE::IMPOSSIBLE;
7447
7458
param->thd ->mem_root = tmp_root;
7459
+
7460
+ tree= new (tmp_root) SEL_TREE (type, tmp_root, param->keys );
7448
7461
DBUG_RETURN (tree);
7449
7462
}
7450
7463
@@ -7470,7 +7483,8 @@ SEL_TREE *Item::get_mm_tree(RANGE_OPT_PARAM *param, Item **cond_ptr)
7470
7483
if ((ref_tables & param->current_table ) ||
7471
7484
(ref_tables & ~(param->prev_tables | param->read_tables )))
7472
7485
DBUG_RETURN (0 );
7473
- DBUG_RETURN (new SEL_TREE (SEL_TREE::MAYBE));
7486
+ DBUG_RETURN (new (param->mem_root ) SEL_TREE (SEL_TREE::MAYBE, param->mem_root ,
7487
+ param->keys ));
7474
7488
}
7475
7489
7476
7490
@@ -7588,7 +7602,8 @@ Item_bool_func::get_mm_parts(RANGE_OPT_PARAM *param, Field *field,
7588
7602
if (field->eq (key_part->field ))
7589
7603
{
7590
7604
SEL_ARG *sel_arg=0 ;
7591
- if (!tree && !(tree=new (param->thd ->mem_root ) SEL_TREE ()))
7605
+ if (!tree && !(tree=new (param->thd ->mem_root ) SEL_TREE (param->mem_root ,
7606
+ param->keys )))
7592
7607
DBUG_RETURN (0 ); // OOM
7593
7608
if (!value || !(value_used_tables & ~param->read_tables ))
7594
7609
{
@@ -8551,7 +8566,7 @@ tree_or(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2)
8551
8566
imerge[0 ]= new SEL_IMERGE (tree1->merges .head (), 0 , param);
8552
8567
}
8553
8568
bool no_imerge_from_ranges= FALSE ;
8554
- if (!(result= new SEL_TREE ()))
8569
+ if (!(result= new (param-> mem_root ) SEL_TREE (param-> mem_root , param-> keys )))
8555
8570
DBUG_RETURN (result);
8556
8571
8557
8572
/* Build the range part of the tree for the formula (1) */
@@ -14382,16 +14397,12 @@ void QUICK_GROUP_MIN_MAX_SELECT::add_keys_and_lengths(String *key_names,
14382
14397
static void print_sel_tree (PARAM *param, SEL_TREE *tree, key_map *tree_map,
14383
14398
const char *msg)
14384
14399
{
14385
- SEL_ARG **key,**end;
14386
- int idx;
14387
14400
char buff[1024 ];
14388
14401
DBUG_ENTER (" print_sel_tree" );
14389
14402
14390
14403
String tmp (buff,sizeof (buff),&my_charset_bin);
14391
14404
tmp.length (0 );
14392
- for (idx= 0 ,key=tree->keys , end=key+param->keys ;
14393
- key != end ;
14394
- key++,idx++)
14405
+ for (uint idx= 0 ; idx < param->keys ; idx++)
14395
14406
{
14396
14407
if (tree_map->is_set (idx))
14397
14408
{
0 commit comments