3528
3449
my_qsort(ror_scan_mark, ror_scans_end-ror_scan_mark, sizeof(ROR_SCAN_INFO*),
3529
3450
(qsort_cmp)cmp_ror_scan_info_covering);
3531
DBUG_EXECUTE("info", print_ror_scans_arr(param->table,
3452
print_ror_scans_arr(param->table,
3532
3453
"remaining scans",
3533
ror_scan_mark, ror_scans_end););
3454
ror_scan_mark, ror_scans_end);
3535
3456
/* I=I-first(I) */
3536
3457
total_cost += (*ror_scan_mark)->index_read_cost;
3537
3458
records += (*ror_scan_mark)->records;
3538
DBUG_PRINT("info", ("Adding scan on %s",
3539
param->table->key_info[(*ror_scan_mark)->keynr].name));
3540
3459
if (total_cost > read_time)
3542
3461
/* F=F-covered by first(I) */
3543
3462
bitmap_union(covered_fields, &(*ror_scan_mark)->covered_fields);
3544
3463
all_covered= bitmap_is_subset(¶m->needed_fields, covered_fields);
3545
3464
} while ((++ror_scan_mark < ror_scans_end) && !all_covered);
3547
3466
if (!all_covered || (ror_scan_mark - tree->ror_scans) == 1)
3551
3470
Ok, [tree->ror_scans .. ror_scan) holds covering index_intersection with
3552
3471
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,
3473
print_ror_scans_arr(param->table,
3556
3474
"creating covering ROR-intersect",
3557
tree->ror_scans, ror_scan_mark););
3475
tree->ror_scans, ror_scan_mark);
3559
3477
/* Add priority queue use cost. */
3560
3478
total_cost += rows2double(records)*
3561
3479
log((double)(ror_scan_mark - tree->ror_scans)) /
3562
3480
(TIME_FOR_COMPARE_ROWID * M_LN2);
3563
DBUG_PRINT("info", ("Covering ROR-intersect full cost: %g", total_cost));
3565
3482
if (total_cost > read_time)
3568
3485
TRP_ROR_INTERSECT *trp;
3569
3486
if (!(trp= new (param->mem_root) TRP_ROR_INTERSECT))
3571
3488
uint best_num= (ror_scan_mark - tree->ror_scans);
3572
3489
if (!(trp->first_scan= (ROR_SCAN_INFO**)alloc_root(param->mem_root,
3573
3490
sizeof(ROR_SCAN_INFO*)*
3576
3493
memcpy(trp->first_scan, tree->ror_scans, best_num*sizeof(ROR_SCAN_INFO*));
3577
3494
trp->last_scan= trp->first_scan + best_num;
3578
3495
trp->is_covering= true;
9937
9785
if (!tmp.length())
9938
9786
tmp.append(STRING_WITH_LEN("(empty)"));
9939
DBUG_PRINT("info", ("ROR key scans (%s): %s", msg, tmp.ptr()));
9944
/*****************************************************************************
9945
** Print a quick range for debugging
9947
** This should be changed to use a String to store each row instead
9948
** of locking the DEBUG stream !
9949
*****************************************************************************/
9952
print_key(KEY_PART *key_part, const uchar *key, uint used_length)
9955
const uchar *key_end= key+used_length;
9956
String tmp(buff,sizeof(buff),&my_charset_bin);
9958
TABLE *table= key_part->field->table;
9959
my_bitmap_map *old_write_set, *old_read_set;
9960
old_write_set= dbug_tmp_use_all_columns(table, table->write_set);
9961
old_read_set= dbug_tmp_use_all_columns(table, table->read_set);
9963
for (; key < key_end; key+=store_length, key_part++)
9965
Field *field= key_part->field;
9966
store_length= key_part->store_length;
9968
if (field->real_maybe_null())
9972
fwrite("NULL",sizeof(char),4,DBUG_FILE);
9975
key++; // Skip null byte
9978
field->set_key_image(key, key_part->length);
9979
field->val_str(&tmp);
9980
fwrite(tmp.ptr(),sizeof(char),tmp.length(),DBUG_FILE);
9981
if (key+store_length < key_end)
9982
fputc('/',DBUG_FILE);
9984
dbug_tmp_restore_column_map(table->write_set, old_write_set);
9985
dbug_tmp_restore_column_map(table->read_set, old_read_set);
9989
static void print_quick(QUICK_SELECT_I *quick, const key_map *needed_reg)
9991
char buf[MAX_KEY/8+1];
9993
my_bitmap_map *old_read_map, *old_write_map;
9994
DBUG_ENTER("print_quick");
10000
old_read_map= dbug_tmp_use_all_columns(table, table->read_set);
10001
old_write_map= dbug_tmp_use_all_columns(table, table->write_set);
10002
quick->dbug_dump(0, true);
10003
dbug_tmp_restore_column_map(table->read_set, old_read_map);
10004
dbug_tmp_restore_column_map(table->write_set, old_write_map);
10006
fprintf(DBUG_FILE,"other_keys: 0x%s:\n", needed_reg->print(buf));
10013
void QUICK_RANGE_SELECT::dbug_dump(int indent, bool verbose)
10015
/* purecov: begin inspected */
10016
fprintf(DBUG_FILE, "%*squick range select, key %s, length: %d\n",
10017
indent, "", head->key_info[index].name, max_used_key_length);
10021
QUICK_RANGE *range;
10022
QUICK_RANGE **pr= (QUICK_RANGE**)ranges.buffer;
10023
QUICK_RANGE **end_range= pr + ranges.elements;
10024
for (; pr != end_range; ++pr)
10026
fprintf(DBUG_FILE, "%*s", indent + 2, "");
10028
if (!(range->flag & NO_MIN_RANGE))
10030
print_key(key_parts, range->min_key, range->min_length);
10031
if (range->flag & NEAR_MIN)
10032
fputs(" < ",DBUG_FILE);
10034
fputs(" <= ",DBUG_FILE);
10036
fputs("X",DBUG_FILE);
10038
if (!(range->flag & NO_MAX_RANGE))
10040
if (range->flag & NEAR_MAX)
10041
fputs(" < ",DBUG_FILE);
10043
fputs(" <= ",DBUG_FILE);
10044
print_key(key_parts, range->max_key, range->max_length);
10046
fputs("\n",DBUG_FILE);
10052
void QUICK_INDEX_MERGE_SELECT::dbug_dump(int indent, bool verbose)
10054
List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
10055
QUICK_RANGE_SELECT *quick;
10056
fprintf(DBUG_FILE, "%*squick index_merge select\n", indent, "");
10057
fprintf(DBUG_FILE, "%*smerged scans {\n", indent, "");
10058
while ((quick= it++))
10059
quick->dbug_dump(indent+2, verbose);
10060
if (pk_quick_select)
10062
fprintf(DBUG_FILE, "%*sclustered PK quick:\n", indent, "");
10063
pk_quick_select->dbug_dump(indent+2, verbose);
10065
fprintf(DBUG_FILE, "%*s}\n", indent, "");
10068
void QUICK_ROR_INTERSECT_SELECT::dbug_dump(int indent, bool verbose)
10070
List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
10071
QUICK_RANGE_SELECT *quick;
10072
fprintf(DBUG_FILE, "%*squick ROR-intersect select, %scovering\n",
10073
indent, "", need_to_fetch_row? "":"non-");
10074
fprintf(DBUG_FILE, "%*smerged scans {\n", indent, "");
10075
while ((quick= it++))
10076
quick->dbug_dump(indent+2, verbose);
10079
fprintf(DBUG_FILE, "%*sclustered PK quick:\n", indent, "");
10080
cpk_quick->dbug_dump(indent+2, verbose);
10082
fprintf(DBUG_FILE, "%*s}\n", indent, "");
10085
void QUICK_ROR_UNION_SELECT::dbug_dump(int indent, bool verbose)
10087
List_iterator_fast<QUICK_SELECT_I> it(quick_selects);
10088
QUICK_SELECT_I *quick;
10089
fprintf(DBUG_FILE, "%*squick ROR-union select\n", indent, "");
10090
fprintf(DBUG_FILE, "%*smerged scans {\n", indent, "");
10091
while ((quick= it++))
10092
quick->dbug_dump(indent+2, verbose);
10093
fprintf(DBUG_FILE, "%*s}\n", indent, "");
10098
Print quick select information to DBUG_FILE.
10101
QUICK_GROUP_MIN_MAX_SELECT::dbug_dump()
10102
indent Indentation offset
10103
verbose If true show more detailed output.
10106
Print the contents of this quick select to DBUG_FILE. The method also
10107
calls dbug_dump() for the used quick select if any.
10110
Caller is responsible for locking DBUG_FILE before this call and unlocking
10117
void QUICK_GROUP_MIN_MAX_SELECT::dbug_dump(int indent, bool verbose)
10120
"%*squick_group_min_max_select: index %s (%d), length: %d\n",
10121
indent, "", index_info->name, index, max_used_key_length);
10122
if (key_infix_len > 0)
10124
fprintf(DBUG_FILE, "%*susing key_infix with length %d:\n",
10125
indent, "", key_infix_len);
10127
if (quick_prefix_select)
10129
fprintf(DBUG_FILE, "%*susing quick_range_select:\n", indent, "");
10130
quick_prefix_select->dbug_dump(indent + 2, verbose);
10132
if (min_max_ranges.elements > 0)
10134
fprintf(DBUG_FILE, "%*susing %d quick_ranges for MIN/MAX:\n",
10135
indent, "", min_max_ranges.elements);
10140
#endif /* NOT_USED */
10142
9790
/*****************************************************************************
10143
9791
** Instantiate templates