758
758
TRP_GROUP_MIN_MAX *get_best_group_min_max(PARAM *param, SEL_TREE *tree);
761
760
static void print_sel_tree(PARAM *param, SEL_TREE *tree, key_map *tree_map,
762
761
const char *msg);
763
762
static void print_ror_scans_arr(TABLE *table, const char *msg,
764
763
struct st_ror_scan_info **start,
765
764
struct st_ror_scan_info **end);
766
765
static void print_quick(QUICK_SELECT_I *quick, const key_map *needed_reg);
769
767
static SEL_TREE *tree_and(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2);
770
768
static SEL_TREE *tree_or(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2);
1015
1013
SQL_SELECT *select;
1016
DBUG_ENTER("make_select");
1020
1017
if (!conds && !allow_null_cond)
1022
1019
if (!(select= new SQL_SELECT))
1024
1021
*error= 1; // out of memory
1025
DBUG_RETURN(0); /* purecov: inspected */
1022
return(0); /* purecov: inspected */
1027
1024
select->read_tables=read_tables;
1028
1025
select->const_tables=const_tables;
1117
1111
bitmap_init(&column_bitmap, bitmap, head->s->fields, false);
1122
1116
int QUICK_RANGE_SELECT::init()
1124
DBUG_ENTER("QUICK_RANGE_SELECT::init");
1126
1118
if (file->inited != handler::NONE)
1127
1119
file->ha_index_or_rnd_end();
1128
DBUG_RETURN(file->ha_index_init(index, 1));
1120
return(file->ha_index_init(index, 1));
1174
1163
:pk_quick_select(NULL), thd(thd_param)
1176
DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::QUICK_INDEX_MERGE_SELECT");
1177
1165
index= MAX_KEY;
1179
1167
bzero(&read_record, sizeof(read_record));
1180
1168
init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0);
1184
1172
int QUICK_INDEX_MERGE_SELECT::init()
1186
DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::init");
1190
1177
int QUICK_INDEX_MERGE_SELECT::reset()
1192
DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::reset");
1193
DBUG_RETURN(read_keys_and_merge());
1179
return(read_keys_and_merge());
1213
1199
List_iterator_fast<QUICK_RANGE_SELECT> quick_it(quick_selects);
1214
1200
QUICK_RANGE_SELECT* quick;
1215
DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::~QUICK_INDEX_MERGE_SELECT");
1216
1201
quick_it.rewind();
1217
1202
while ((quick= quick_it++))
1218
1203
quick->file= NULL;
1219
1204
quick_selects.delete_elements();
1220
1205
delete pk_quick_select;
1221
1206
free_root(&alloc,MYF(0));
1287
1271
handler *save_file= file, *org_file;
1289
DBUG_ENTER("QUICK_RANGE_SELECT::init_ror_merged_scan");
1291
1274
in_ror_merged_scan= 1;
1292
1275
if (reuse_handler)
1294
DBUG_PRINT("info", ("Reusing handler 0x%lx", (long) file));
1295
1277
if (init() || reset())
1299
1281
head->column_bitmaps_set(&column_bitmap, &column_bitmap);
1381
1363
List_iterator_fast<QUICK_RANGE_SELECT> quick_it(quick_selects);
1382
1364
QUICK_RANGE_SELECT* quick;
1383
DBUG_ENTER("QUICK_ROR_INTERSECT_SELECT::init_ror_merged_scan");
1385
1366
/* Initialize all merged "children" quick selects */
1386
DBUG_ASSERT(!need_to_fetch_row || reuse_handler);
1367
assert(!need_to_fetch_row || reuse_handler);
1387
1368
if (!need_to_fetch_row && reuse_handler)
1389
1370
quick= quick_it++;
1394
1375
if (quick->init_ror_merged_scan(true))
1396
1377
quick->file->extra(HA_EXTRA_KEYREAD_PRESERVE_FIELDS);
1398
1379
while ((quick= quick_it++))
1400
1381
if (quick->init_ror_merged_scan(false))
1402
1383
quick->file->extra(HA_EXTRA_KEYREAD_PRESERVE_FIELDS);
1403
1384
/* All merged scans share the same record buffer in intersection. */
1404
1385
quick->record= head->record[0];
1460
1439
QUICK_ROR_INTERSECT_SELECT::~QUICK_ROR_INTERSECT_SELECT()
1462
DBUG_ENTER("QUICK_ROR_INTERSECT_SELECT::~QUICK_ROR_INTERSECT_SELECT");
1463
1441
quick_selects.delete_elements();
1464
1442
delete cpk_quick;
1465
1443
free_root(&alloc,MYF(0));
1466
1444
if (need_to_fetch_row && head->file->inited != handler::NONE)
1467
1445
head->file->ha_rnd_end();
1495
1473
int QUICK_ROR_UNION_SELECT::init()
1497
DBUG_ENTER("QUICK_ROR_UNION_SELECT::init");
1498
1475
if (init_queue(&queue, quick_selects.elements, 0,
1499
1476
false , QUICK_ROR_UNION_SELECT::queue_cmp,
1502
1479
bzero(&queue, sizeof(QUEUE));
1506
1483
if (!(cur_rowid= (uchar*) alloc_root(&alloc, 2*head->file->ref_length)))
1508
1485
prev_rowid= cur_rowid + head->file->ref_length;
1594
1569
QUICK_ROR_UNION_SELECT::~QUICK_ROR_UNION_SELECT()
1596
DBUG_ENTER("QUICK_ROR_UNION_SELECT::~QUICK_ROR_UNION_SELECT");
1597
1571
delete_queue(&queue);
1598
1572
quick_selects.delete_elements();
1599
1573
if (head->file->inited != handler::NONE)
1600
1574
head->file->ha_rnd_end();
1601
1575
free_root(&alloc,MYF(0));
1952
1926
bool retrieve_full_rows __attribute__((__unused__)),
1953
1927
MEM_ROOT *parent_alloc)
1955
DBUG_ENTER("TRP_RANGE::make_quick");
1956
1929
QUICK_RANGE_SELECT *quick;
1957
1930
if ((quick= get_quick_select(param, key_idx, key, mrr_flags, mrr_buf_size,
1958
1931
parent_alloc)))
2187
2160
double scan_time;
2188
DBUG_ENTER("SQL_SELECT::test_quick_select");
2189
DBUG_PRINT("enter",("keys_to_use: %lu prev_tables: %lu const_tables: %lu",
2190
(ulong) keys_to_use.to_ulonglong(), (ulong) prev_tables,
2191
(ulong) const_tables));
2192
DBUG_PRINT("info", ("records: %lu", (ulong) head->file->stats.records));
2195
2163
needed_reg.clear_all();
2196
2164
quick_keys.clear_all();
2197
2165
if (keys_to_use.is_clear_all())
2199
2167
records= head->file->stats.records;
2201
2169
records++; /* purecov: inspected */
2206
2174
if (limit < records)
2207
2175
read_time= (double) records + scan_time + 1; // Force to use index
2208
2176
else if (read_time <= 2.0 && !force_quick_range)
2209
DBUG_RETURN(0); /* No need for quick select */
2211
DBUG_PRINT("info",("Time to scan table: %g", read_time));
2177
return(0); /* No need for quick select */
2213
2179
keys_to_use.intersect(head->keys_in_use_for_query);
2214
2180
if (!keys_to_use.is_clear_all())
2291
2257
param.table->file->index_only_read_time(key_for_use,
2292
2258
rows2double(records)) +
2293
2259
(double) records / TIME_FOR_COMPARE;
2294
DBUG_PRINT("info", ("'all'+'using index' scan will be using key %d, "
2295
"read time %g", key_for_use, key_read_time));
2296
2260
if (key_read_time < read_time)
2297
2261
read_time= key_read_time;
2388
2352
/* Try creating index_merge/ROR-union scan. */
2389
2353
SEL_IMERGE *imerge;
2390
2354
TABLE_READ_PLAN *best_conj_trp= NULL, *new_conj_trp;
2391
DBUG_PRINT("info",("No range reads possible,"
2392
" trying to construct index_merge"));
2393
2355
List_iterator_fast<SEL_IMERGE> it(tree->merges);
2394
2356
while ((imerge= it++))
2425
2387
thd->no_errors=0;
2428
DBUG_EXECUTE("info", print_quick(quick, &needed_reg););
2390
print_quick(quick, &needed_reg);
2431
2393
Assume that if the user is using 'limit' we will only need to scan
2432
2394
limit rows if we are using a key
2434
DBUG_RETURN(records ? test(quick) : -1);
2396
return(records ? test(quick) : -1);
2522
2484
double roru_index_costs;
2523
2485
ha_rows roru_total_records;
2524
2486
double roru_intersect_part= 1.0;
2525
DBUG_ENTER("get_best_disjunct_quick");
2526
DBUG_PRINT("info", ("Full table scan cost: %g", read_time));
2528
2488
if (!(range_scans= (TRP_RANGE**)alloc_root(param->mem_root,
2529
2489
sizeof(TRP_RANGE*)*
2530
2490
n_child_scans)))
2533
2493
Collect best 'range' scan for each of disjuncts, and, while doing so,
2534
2494
analyze possibility of ROR scans. Also calculate some values needed by
2538
2498
ptree != imerge->trees_next;
2539
2499
ptree++, cur_child++)
2541
DBUG_EXECUTE("info", print_sel_tree(param, *ptree, &(*ptree)->keys_map,
2542
"tree in SEL_IMERGE"););
2501
print_sel_tree(param, *ptree, &(*ptree)->keys_map, "tree in SEL_IMERGE");
2543
2502
if (!(*cur_child= get_key_scans_params(param, *ptree, true, false, read_time)))
2624
2578
Unique::get_use_cost(param->imerge_cost_buff, (uint)non_cpk_scan_records,
2625
2579
param->table->file->ref_length,
2626
2580
param->thd->variables.sortbuff_size);
2627
DBUG_PRINT("info",("index_merge total cost: %g (wanted: less then %g)",
2628
imerge_cost, read_time));
2629
2581
if (imerge_cost < read_time)
2631
2583
if ((imerge_trp= new (param->mem_root)TRP_INDEX_MERGE))
2805
2754
if (!(bitmap_buf= (my_bitmap_map*) alloc_root(param->mem_root,
2806
2755
param->fields_bitmap_size)))
2809
2758
if (bitmap_init(&ror_scan->covered_fields, bitmap_buf,
2810
2759
param->table->s->fields, false))
2812
2761
bitmap_clear_all(&ror_scan->covered_fields);
2814
2763
KEY_PART_INFO *key_part= param->table->key_info[keynr].key_part;
3058
3007
max_range.key= key_val;
3059
3008
max_range.flag= HA_READ_AFTER_KEY;
3060
3009
ha_rows prev_records= info->param->table->file->stats.records;
3061
DBUG_ENTER("ror_scan_selectivity");
3063
3011
for (sel_arg= scan->sel_arg; sel_arg;
3064
3012
sel_arg= sel_arg->next_key_part)
3066
DBUG_PRINT("info",("sel_arg step"));
3067
3014
cur_covered= test(bitmap_is_set(&info->covered_fields,
3068
3015
key_part[sel_arg->part].fieldnr-1));
3069
3016
if (cur_covered != prev_covered)
3109
3055
double tmp= rows2double(info->param->table->quick_rows[scan->keynr]) /
3110
3056
rows2double(prev_records);
3111
DBUG_PRINT("info", ("Selectivity multiplier: %g", tmp));
3112
3057
selectivity_mult *= tmp;
3114
DBUG_PRINT("info", ("Returning multiplier: %g", selectivity_mult));
3115
DBUG_RETURN(selectivity_mult);
3059
return(selectivity_mult);
3158
3102
double selectivity_mult= 1.0;
3160
DBUG_ENTER("ror_intersect_add");
3161
DBUG_PRINT("info", ("Current out_rows= %g", info->out_rows));
3162
DBUG_PRINT("info", ("Adding scan on %s",
3163
info->param->table->key_info[ror_scan->keynr].name));
3164
DBUG_PRINT("info", ("is_cpk_scan: %d",is_cpk_scan));
3166
3104
selectivity_mult = ror_scan_selectivity(info, ror_scan);
3167
3105
if (selectivity_mult == 1.0)
3169
3107
/* Don't add this scan if it doesn't improve selectivity. */
3170
DBUG_PRINT("info", ("The scan doesn't improve selectivity."));
3174
3111
info->out_rows *= selectivity_mult;
3191
3128
if (!info->is_covering && bitmap_is_subset(&info->param->needed_fields,
3192
3129
&info->covered_fields))
3194
DBUG_PRINT("info", ("ROR-intersect is covering now"));
3195
3131
info->is_covering= true;
3199
3135
info->total_cost= info->index_scan_costs;
3200
DBUG_PRINT("info", ("info->total_cost: %g", info->total_cost));
3201
3136
if (!info->is_covering)
3203
3138
COST_VECT sweep_cost;
3206
3141
get_sweep_read_cost(info->param->table, double2rows(info->out_rows),
3207
3142
is_interrupted, &sweep_cost);
3208
3143
info->total_cost += sweep_cost.total_cost();
3209
DBUG_PRINT("info", ("info->total_cost= %g", info->total_cost));
3211
DBUG_PRINT("info", ("New out_rows: %g", info->out_rows));
3212
DBUG_PRINT("info", ("New cost: %g, %scovering", info->total_cost,
3213
info->is_covering?"" : "non-"));
3326
3256
tree->ror_scans_end= cur_ror_scan;
3327
DBUG_EXECUTE("info",print_ror_scans_arr(param->table, "original",
3257
print_ror_scans_arr(param->table, "original",
3328
3258
tree->ror_scans,
3329
tree->ror_scans_end););
3259
tree->ror_scans_end);
3331
3261
Ok, [ror_scans, ror_scans_end) is array of ptrs to initialized
3332
3262
ROR_SCAN_INFO's.
3335
3265
my_qsort(tree->ror_scans, tree->n_ror_scans, sizeof(ROR_SCAN_INFO*),
3336
3266
(qsort_cmp)cmp_ror_scan_info);
3337
DBUG_EXECUTE("info",print_ror_scans_arr(param->table, "ordered",
3267
print_ror_scans_arr(param->table, "ordered",
3338
3268
tree->ror_scans,
3339
tree->ror_scans_end););
3269
tree->ror_scans_end);
3341
3271
ROR_SCAN_INFO **intersect_scans; /* ROR scans used in index intersection */
3342
3272
ROR_SCAN_INFO **intersect_scans_end;
3379
3309
if (intersect_scans_best == intersect_scans)
3381
DBUG_PRINT("info", ("None of scans increase selectivity"));
3385
DBUG_EXECUTE("info",print_ror_scans_arr(param->table,
3314
print_ror_scans_arr(param->table,
3386
3315
"best ROR-intersection",
3387
3316
intersect_scans,
3388
intersect_scans_best););
3317
intersect_scans_best);
3390
3319
*are_all_covering= intersect->is_covering;
3391
3320
uint best_num= intersect_scans_best - intersect_scans;
3411
3340
if (min_cost < read_time && (cpk_scan_used || best_num > 1))
3413
3342
if (!(trp= new (param->mem_root) TRP_ROR_INTERSECT))
3415
3344
if (!(trp->first_scan=
3416
3345
(ROR_SCAN_INFO**)alloc_root(param->mem_root,
3417
3346
sizeof(ROR_SCAN_INFO*)*best_num)))
3419
3348
memcpy(trp->first_scan, intersect_scans, best_num*sizeof(ROR_SCAN_INFO*));
3420
3349
trp->last_scan= trp->first_scan + best_num;
3421
3350
trp->is_covering= intersect_best->is_covering;
3497
3422
if (!covered_fields->bitmap ||
3498
3423
bitmap_init(covered_fields, covered_fields->bitmap,
3499
3424
param->table->s->fields, false))
3501
3426
bitmap_clear_all(covered_fields);
3503
3428
double total_cost= 0.0f;
3504
3429
ha_rows records=0;
3505
3430
bool all_covered;
3507
DBUG_PRINT("info", ("Building covering ROR-intersection"));
3508
DBUG_EXECUTE("info", print_ror_scans_arr(param->table,
3432
print_ror_scans_arr(param->table,
3509
3433
"building covering ROR-I",
3510
ror_scan_mark, ror_scans_end););
3434
ror_scan_mark, ror_scans_end);
3528
3452
my_qsort(ror_scan_mark, ror_scans_end-ror_scan_mark, sizeof(ROR_SCAN_INFO*),
3529
3453
(qsort_cmp)cmp_ror_scan_info_covering);
3531
DBUG_EXECUTE("info", print_ror_scans_arr(param->table,
3455
print_ror_scans_arr(param->table,
3532
3456
"remaining scans",
3533
ror_scan_mark, ror_scans_end););
3457
ror_scan_mark, ror_scans_end);
3535
3459
/* I=I-first(I) */
3536
3460
total_cost += (*ror_scan_mark)->index_read_cost;
3537
3461
records += (*ror_scan_mark)->records;
3538
DBUG_PRINT("info", ("Adding scan on %s",
3539
param->table->key_info[(*ror_scan_mark)->keynr].name));
3540
3462
if (total_cost > read_time)
3542
3464
/* F=F-covered by first(I) */
3543
3465
bitmap_union(covered_fields, &(*ror_scan_mark)->covered_fields);
3544
3466
all_covered= bitmap_is_subset(¶m->needed_fields, covered_fields);
3545
3467
} while ((++ror_scan_mark < ror_scans_end) && !all_covered);
3547
3469
if (!all_covered || (ror_scan_mark - tree->ror_scans) == 1)
3551
3473
Ok, [tree->ror_scans .. ror_scan) holds covering index_intersection with
3552
3474
cost total_cost.
3554
DBUG_PRINT("info", ("Covering ROR-intersect scans cost: %g", total_cost));
3555
DBUG_EXECUTE("info", print_ror_scans_arr(param->table,
3476
print_ror_scans_arr(param->table,
3556
3477
"creating covering ROR-intersect",
3557
tree->ror_scans, ror_scan_mark););
3478
tree->ror_scans, ror_scan_mark);
3559
3480
/* Add priority queue use cost. */
3560
3481
total_cost += rows2double(records)*
3561
3482
log((double)(ror_scan_mark - tree->ror_scans)) /
3562
3483
(TIME_FOR_COMPARE_ROWID * M_LN2);
3563
DBUG_PRINT("info", ("Covering ROR-intersect full cost: %g", total_cost));
3565
3485
if (total_cost > read_time)
3568
3488
TRP_ROR_INTERSECT *trp;
3569
3489
if (!(trp= new (param->mem_root) TRP_ROR_INTERSECT))
3571
3491
uint best_num= (ror_scan_mark - tree->ror_scans);
3572
3492
if (!(trp->first_scan= (ROR_SCAN_INFO**)alloc_root(param->mem_root,
3573
3493
sizeof(ROR_SCAN_INFO*)*
3576
3496
memcpy(trp->first_scan, tree->ror_scans, best_num*sizeof(ROR_SCAN_INFO*));
3577
3497
trp->last_scan= trp->first_scan + best_num;
3578
3498
trp->is_covering= true;
3624
3541
ha_rows best_records= 0;
3625
3542
uint best_mrr_flags= 0, best_buf_size= 0;
3626
3543
TRP_RANGE* read_plan= NULL;
3627
DBUG_ENTER("get_key_scans_params");
3629
3545
Note that there may be trees that have type SEL_TREE::KEY but contain no
3630
3546
key reads at all, e.g. tree for expression "key1 is not null" where key1
3631
3547
is defined as "not null".
3633
DBUG_EXECUTE("info", print_sel_tree(param, tree, &tree->keys_map,
3549
print_sel_tree(param, tree, &tree->keys_map, "tree scans");
3635
3550
tree->ror_scans_map.clear_all();
3636
3551
tree->n_ror_scans= 0;
3637
3552
for (idx= 0,key=tree->keys, end=key+param->keys; key != end; key++,idx++)
3673
DBUG_EXECUTE("info", print_sel_tree(param, tree, &tree->ror_scans_map,
3588
print_sel_tree(param, tree, &tree->ror_scans_map, "ROR scans");
3675
3589
if (key_to_read)
3677
3591
idx= key_to_read - tree->keys;
3682
3596
read_plan->is_ror= tree->ror_scans_map.is_set(idx);
3683
3597
read_plan->read_cost= read_time;
3684
3598
read_plan->mrr_buf_size= best_buf_size;
3686
("Returning range plan for key %s, cost %g, records %lu",
3687
param->table->key_info[param->real_keynr[idx]].name,
3688
read_plan->read_cost, (ulong) read_plan->records));
3692
DBUG_PRINT("info", ("No 'range' table read plan found"));
3694
DBUG_RETURN(read_plan);
3738
3645
parent_alloc)))
3740
DBUG_EXECUTE("info", print_ror_scans_arr(param->table,
3647
print_ror_scans_arr(param->table,
3741
3648
"creating ROR-intersect",
3742
first_scan, last_scan););
3649
first_scan, last_scan);
3743
3650
alloc= parent_alloc? parent_alloc: &quick_intrsect->alloc;
3744
3651
for (; first_scan != last_scan;++first_scan)
4212
4115
SEL_TREE *new_tree=get_mm_tree(param,item);
4213
4116
if (param->thd->is_fatal_error ||
4214
4117
param->alloced_sel_args > SEL_ARG::MAX_SEL_ARGS)
4215
DBUG_RETURN(0); // out of memory
4118
return(0); // out of memory
4216
4119
tree=tree_and(param,tree,new_tree);
4217
4120
if (tree && tree->type == SEL_TREE::IMPOSSIBLE)
4229
4132
SEL_TREE *new_tree=get_mm_tree(param,item);
4231
DBUG_RETURN(0); // out of memory
4134
return(0); // out of memory
4232
4135
tree=tree_or(param,tree,new_tree);
4233
4136
if (!tree || tree->type == SEL_TREE::ALWAYS)
4240
4143
/* Here when simple cond */
4241
4144
if (cond->const_item())
4262
4165
ref_tables= cond->used_tables();
4263
4166
if ((ref_tables & param->current_table) ||
4264
4167
(ref_tables & ~(param->prev_tables | param->read_tables)))
4266
DBUG_RETURN(new SEL_TREE(SEL_TREE::MAYBE));
4169
return(new SEL_TREE(SEL_TREE::MAYBE));
4269
4172
Item_func *cond_func= (Item_func*) cond;
4313
4216
Item_func_in *func=(Item_func_in*) cond_func;
4314
4217
if (func->key_item()->real_item()->type() != Item::FIELD_ITEM)
4316
4219
field_item= (Item_field*) (func->key_item()->real_item());
4317
4220
ftree= get_full_func_mm_tree(param, cond_func, field_item, NULL, inv);
4367
4270
Item_result cmp_type __attribute__((__unused__)))
4369
DBUG_ENTER("get_mm_parts");
4370
4272
if (field->table != param->table)
4373
4275
KEY_PART *key_part = param->key_parts;
4374
4276
KEY_PART *end = param->key_parts_end;
4375
4277
SEL_TREE *tree=0;
4377
4279
value->used_tables() & ~(param->prev_tables | param->read_tables))
4379
4281
for (; key_part != end ; key_part++)
4381
4283
if (field->eq(key_part->field))
4383
4285
SEL_ARG *sel_arg=0;
4384
4286
if (!tree && !(tree=new SEL_TREE()))
4385
DBUG_RETURN(0); // OOM
4386
4288
if (!value || !(value->used_tables() & ~param->read_tables))
4388
4290
sel_arg=get_mm_leaf(param,cond_func,
4392
4294
if (sel_arg->type == SEL_ARG::IMPOSSIBLE)
4394
4296
tree->type=SEL_TREE::IMPOSSIBLE;
4400
4302
// This key may be used later
4401
4303
if (!(sel_arg= new SEL_ARG(SEL_ARG::MAYBE_KEY)))
4402
DBUG_RETURN(0); // OOM
4404
4306
sel_arg->part=(uchar) key_part->part;
4405
4307
tree->keys[key_part->key]=sel_add(tree->keys[key_part->key],sel_arg);
4778
4679
static SEL_TREE *
4779
4680
tree_and(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2)
4781
DBUG_ENTER("tree_and");
4786
4686
if (tree1->type == SEL_TREE::IMPOSSIBLE || tree2->type == SEL_TREE::ALWAYS)
4788
4688
if (tree2->type == SEL_TREE::IMPOSSIBLE || tree1->type == SEL_TREE::ALWAYS)
4790
4690
if (tree1->type == SEL_TREE::MAYBE)
4792
4692
if (tree2->type == SEL_TREE::KEY)
4793
4693
tree2->type=SEL_TREE::KEY_SMALLER;
4796
4696
if (tree2->type == SEL_TREE::MAYBE)
4798
4698
tree1->type=SEL_TREE::KEY_SMALLER;
4801
4701
key_map result_keys;
4802
4702
result_keys.clear_all();
4952
4851
static SEL_TREE *
4953
4852
tree_or(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2)
4955
DBUG_ENTER("tree_or");
4956
4854
if (!tree1 || !tree2)
4958
4856
if (tree1->type == SEL_TREE::IMPOSSIBLE || tree2->type == SEL_TREE::ALWAYS)
4960
4858
if (tree2->type == SEL_TREE::IMPOSSIBLE || tree1->type == SEL_TREE::ALWAYS)
4962
4860
if (tree1->type == SEL_TREE::MAYBE)
4963
DBUG_RETURN(tree1); // Can't use this
4861
return(tree1); // Can't use this
4964
4862
if (tree2->type == SEL_TREE::MAYBE)
4967
4865
SEL_TREE *result= 0;
4968
4866
key_map result_keys;
4998
4896
bool no_trees= remove_nonrange_trees(param, tree1);
4999
4897
no_trees= no_trees || remove_nonrange_trees(param, tree2);
5001
DBUG_RETURN(new SEL_TREE(SEL_TREE::ALWAYS));
4899
return(new SEL_TREE(SEL_TREE::ALWAYS));
5003
4901
SEL_IMERGE *merge;
5004
4902
/* both trees are "range" trees, produce new index merge structure */
5024
4922
swap_variables(SEL_TREE*, tree1, tree2);
5026
4924
if (param->remove_jump_scans && remove_nonrange_trees(param, tree2))
5027
DBUG_RETURN(new SEL_TREE(SEL_TREE::ALWAYS));
4925
return(new SEL_TREE(SEL_TREE::ALWAYS));
5028
4926
/* add tree2 to tree1->merges, checking if it collapses to ALWAYS */
5029
4927
if (imerge_list_or_tree(param, &tree1->merges, tree2))
5030
4928
result= new SEL_TREE(SEL_TREE::ALWAYS);
5646
5543
if (root == &null_element)
5647
DBUG_RETURN(0); // Maybe root later
5544
return(0); // Maybe root later
5648
5545
if (remove_color == BLACK)
5649
5546
root=rb_delete_fixup(root,nod,fix_par);
5650
5547
test_rb_tree(root,root->parent);
6280
6177
handler *file= param->table->file;
6282
6179
uint keynr= param->real_keynr[idx];
6283
DBUG_ENTER("check_quick_select");
6285
6181
/* Handle cases when we don't have a valid non-empty list of range */
6287
DBUG_RETURN(HA_POS_ERROR);
6183
return(HA_POS_ERROR);
6288
6184
if (tree->type == SEL_ARG::IMPOSSIBLE)
6290
6186
if (tree->type != SEL_ARG::KEY_RANGE || tree->part != 0)
6291
DBUG_RETURN(HA_POS_ERROR);
6187
return(HA_POS_ERROR);
6293
6189
seq.keyno= idx;
6294
6190
seq.real_keyno= keynr;
6832
6726
Unique *unique;
6833
6727
handler *file= head->file;
6834
DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::read_keys_and_merge");
6836
6729
file->extra(HA_EXTRA_KEYREAD);
6837
6730
head->prepare_for_position();
6839
6732
cur_quick_it.rewind();
6840
6733
cur_quick= cur_quick_it++;
6841
DBUG_ASSERT(cur_quick != 0);
6734
assert(cur_quick != 0);
6844
6737
We reuse the same instance of handler so we need to call both init and
6847
6740
if (cur_quick->init() || cur_quick->reset())
6850
6743
unique= new Unique(refpos_order_cmp, (void *)file,
6851
6744
file->ref_length,
6852
6745
thd->variables.sortbuff_size);
6857
6750
while ((result= cur_quick->get_next()) == HA_ERR_END_OF_FILE)
7103
6992
uchar *mrange_buff;
7105
6994
HANDLER_BUFFER empty_buf;
7106
DBUG_ENTER("QUICK_RANGE_SELECT::reset");
7107
6995
last_range= NULL;
7108
6996
cur_range= (QUICK_RANGE**) ranges.buffer;
7110
6998
if (file->inited == handler::NONE && (error= file->ha_index_init(index,1)))
7113
7001
/* Allocate buffer if we need one but haven't allocated it yet */
7114
7002
if (mrr_buf_size && !mrr_buf_desc)
7355
7240
if (last_range)
7357
7242
/* Read the next record in the same range with prefix after cur_prefix. */
7358
DBUG_ASSERT(cur_prefix != 0);
7243
assert(cur_prefix != 0);
7359
7244
result= file->index_read_map(record, cur_prefix, keypart_map,
7360
7245
HA_READ_AFTER_KEY);
7361
7246
if (result || (file->compare_key(file->end_range) <= 0))
7362
DBUG_RETURN(result);
7365
7250
uint count= ranges.elements - (cur_range - (QUICK_RANGE**) ranges.buffer);
7479
7364
int QUICK_SELECT_DESC::get_next()
7481
DBUG_ENTER("QUICK_SELECT_DESC::get_next");
7483
7366
/* The max key is handled as follows:
7484
7367
* - if there is NO_MAX_RANGE, start at the end and move backwards
7485
7368
* - if it is an EQ_RANGE, which means that max key covers the entire
7505
7388
if (cmp_prev(*rev_it.ref()) == 0)
7508
7391
else if (result != HA_ERR_END_OF_FILE)
7509
DBUG_RETURN(result);
7512
7395
if (!(last_range= rev_it++))
7513
DBUG_RETURN(HA_ERR_END_OF_FILE); // All ranges used
7396
return(HA_ERR_END_OF_FILE); // All ranges used
7515
7398
if (last_range->flag & NO_MAX_RANGE) // Read last record
7517
7400
int local_error;
7518
7401
if ((local_error=file->index_last(record)))
7519
DBUG_RETURN(local_error); // Empty table
7402
return(local_error); // Empty table
7520
7403
if (cmp_prev(last_range) == 0)
7522
7405
last_range= 0; // No match; go to next range
7534
DBUG_ASSERT(last_range->flag & NEAR_MAX ||
7417
assert(last_range->flag & NEAR_MAX ||
7535
7418
range_reads_after_key(last_range));
7536
7419
result=file->index_read_map(record, last_range->max_key,
7537
7420
last_range->max_keypart_map,
7975
7858
ORDER *tmp_group;
7977
7860
Item_field *item_field;
7978
DBUG_ENTER("get_best_group_min_max");
7980
7862
/* Perform few 'cheap' tests whether this access method is applicable. */
7982
DBUG_RETURN(NULL); /* This is not a select statement. */
7864
return(NULL); /* This is not a select statement. */
7983
7865
if ((join->tables != 1) || /* The query must reference one table. */
7984
7866
((!join->group_list) && /* Neither GROUP BY nor a DISTINCT query. */
7985
7867
(!join->select_distinct)) ||
7986
7868
(join->select_lex->olap == ROLLUP_TYPE)) /* Check (B3) for ROLLUP */
7988
7870
if (table->s->keys == 0) /* There are no indexes to use. */
7991
7873
/* Analyze the query in more detail. */
7992
7874
List_iterator<Item> select_items_it(join->fields_list);
7994
7876
/* Check (SA1,SA4) and store the only MIN/MAX argument - the C attribute.*/
7995
7877
if (join->make_sum_func_list(join->all_fields, join->fields_list, 1))
7997
7879
if (join->sum_funcs[0])
7999
7881
Item_sum *min_max_item;
8118
8000
first Item? If so, then why? What is the array for?
8120
8002
/* Above we already checked that all group items are fields. */
8121
DBUG_ASSERT((*tmp_group->item)->type() == Item::FIELD_ITEM);
8003
assert((*tmp_group->item)->type() == Item::FIELD_ITEM);
8122
8004
Item_field *group_field= (Item_field *) (*tmp_group->item);
8123
8005
if (group_field->field->eq(cur_part->field))
8321
8203
cur_group_prefix_len= 0;
8323
8205
if (!index_info) /* No usable index found. */
8326
8208
/* Check (SA3) for the where clause. */
8327
8209
if (join->conds && min_max_arg_item &&
8328
8210
!check_group_min_max_predicates(join->conds, min_max_arg_item,
8329
8211
(index_info->flags & HA_SPATIAL) ?
8330
8212
Field::itMBR : Field::itRAW))
8333
8215
/* The query passes all tests, so construct a new TRP object. */
8334
8216
read_plan= new (param->mem_root)
8344
8226
if (tree && read_plan->quick_prefix_records == 0)
8347
8229
read_plan->read_cost= best_read_cost;
8348
8230
read_plan->records= best_records;
8351
("Returning group min/max plan: cost: %g, records: %lu",
8352
read_plan->read_cost, (ulong) read_plan->records));
8355
DBUG_RETURN(read_plan);
8382
8260
check_group_min_max_predicates(COND *cond, Item_field *min_max_arg_item,
8383
8261
Field::imagetype image_type)
8385
DBUG_ENTER("check_group_min_max_predicates");
8386
DBUG_ASSERT(cond && min_max_arg_item);
8263
assert(cond && min_max_arg_item);
8388
8265
cond= cond->real_item();
8389
8266
Item::Type cond_type= cond->type();
8390
8267
if (cond_type == Item::COND_ITEM) /* 'AND' or 'OR' */
8392
DBUG_PRINT("info", ("Analyzing: %s", ((Item_func*) cond)->func_name()));
8393
8269
List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
8394
8270
Item *and_or_arg;
8395
8271
while ((and_or_arg= li++))
8397
8273
if (!check_group_min_max_predicates(and_or_arg, min_max_arg_item,
8413
8289
if (cond_type == Item::SUBSELECT_ITEM)
8416
8292
/* We presume that at this point there are no other Items than functions. */
8417
DBUG_ASSERT(cond_type == Item::FUNC_ITEM);
8293
assert(cond_type == Item::FUNC_ITEM);
8419
8295
/* Test if cond references only group-by or non-group fields. */
8420
8296
Item_func *pred= (Item_func*) cond;
8421
8297
Item **arguments= pred->arguments();
8423
DBUG_PRINT("info", ("Analyzing: %s", pred->func_name()));
8424
8299
for (uint arg_idx= 0; arg_idx < pred->argument_count (); arg_idx++)
8426
8301
cur_arg= arguments[arg_idx]->real_item();
8427
DBUG_PRINT("info", ("cur_arg: %s", cur_arg->full_name()));
8428
8302
if (cur_arg->type() == Item::FIELD_ITEM)
8430
8304
if (min_max_arg_item->eq(cur_arg, 1))
8472
8346
(args[1]->result_type() != STRING_RESULT &&
8473
8347
min_max_arg_item->field->cmp_type() != args[1]->result_type())))
8477
8351
else if (cur_arg->type() == Item::FUNC_ITEM)
8479
8353
if (!check_group_min_max_predicates(cur_arg, min_max_arg_item,
8483
8357
else if (cur_arg->const_item())
8795
8668
*read_cost= io_cost + cpu_cost;
8796
8669
*records= num_groups;
8799
("table rows: %lu keys/block: %u keys/group: %u result rows: %lu blocks: %u",
8800
(ulong)table_records, keys_per_block, keys_per_group,
8801
(ulong) *records, num_blocks));
8840
8707
read_cost, records, key_infix_len,
8841
8708
key_infix, parent_alloc);
8845
8712
if (quick->init())
8851
8718
if (range_tree)
8853
DBUG_ASSERT(quick_prefix_records > 0);
8720
assert(quick_prefix_records > 0);
8854
8721
if (quick_prefix_records == HA_POS_ERROR)
8855
8722
quick->quick_prefix_select= NULL; /* Can't construct a quick select. */
9248
9114
int QUICK_GROUP_MIN_MAX_SELECT::reset(void)
9251
DBUG_ENTER("QUICK_GROUP_MIN_MAX_SELECT::reset");
9253
9118
file->extra(HA_EXTRA_KEYREAD); /* We need only the key attributes */
9254
9119
if ((result= file->ha_index_init(index,1)))
9255
DBUG_RETURN(result);
9256
9121
if (quick_prefix_select && quick_prefix_select->reset())
9258
9123
result= file->index_last(record);
9259
9124
if (result == HA_ERR_END_OF_FILE)
9261
9126
/* Save the prefix of the last group. */
9262
9127
key_copy(last_prefix, record, index_info, group_prefix_len);
9518
9378
int QUICK_GROUP_MIN_MAX_SELECT::next_prefix()
9521
DBUG_ENTER("QUICK_GROUP_MIN_MAX_SELECT::next_prefix");
9523
9382
if (quick_prefix_select)
9525
9384
uchar *cur_prefix= seen_first_key ? group_prefix : NULL;
9526
9385
if ((result= quick_prefix_select->get_next_prefix(group_prefix_len,
9527
9386
make_prev_keypart_map(group_key_parts), cur_prefix)))
9528
DBUG_RETURN(result);
9529
9388
seen_first_key= true;
9885
9744
used_lengths->append(buf, length);
9891
9747
static void print_sel_tree(PARAM *param, SEL_TREE *tree, key_map *tree_map,
9892
9748
const char *msg)
9894
9750
SEL_ARG **key,**end;
9896
9752
char buff[1024];
9897
DBUG_ENTER("print_sel_tree");
9899
9754
String tmp(buff,sizeof(buff),&my_charset_bin);