230
class RANGE_OPT_PARAM;
232
A construction block of the SEL_ARG-graph.
234
The following description only covers graphs of SEL_ARG objects with
235
sel_arg->type==KEY_RANGE:
237
One SEL_ARG object represents an "elementary interval" in form
239
min_value <=? table.keypartX <=? max_value
241
The interval is a non-empty interval of any kind: with[out] minimum/maximum
242
bound, [half]open/closed, single-point interval, etc.
244
1. SEL_ARG GRAPH STRUCTURE
246
SEL_ARG objects are linked together in a graph. The meaning of the graph
247
is better demostrated by an example:
252
| part=1 $ part=2 $ part=3
254
| +-------+ $ +-------+ $ +--------+
255
| | kp1<1 |--$-->| kp2=5 |--$-->| kp3=10 |
256
| +-------+ $ +-------+ $ +--------+
262
\->| kp1=2 |--$--------------$-+
263
+-------+ $ $ | +--------+
265
+-------+ $ $ | +--------+
266
| kp1=3 |--$--------------$-+ |
267
+-------+ $ $ +--------+
271
The entire graph is partitioned into "interval lists".
273
An interval list is a sequence of ordered disjoint intervals over the same
274
key part. SEL_ARG are linked via "next" and "prev" pointers. Additionally,
275
all intervals in the list form an RB-tree, linked via left/right/parent
276
pointers. The RB-tree root SEL_ARG object will be further called "root of the
279
In the example pic, there are 4 interval lists:
280
"kp<1 OR kp1=2 OR kp1=3", "kp2=5", "kp3=10 OR kp3=12", "kp3=11 OR kp3=13".
281
The vertical lines represent SEL_ARG::next/prev pointers.
283
In an interval list, each member X may have SEL_ARG::next_key_part pointer
284
pointing to the root of another interval list Y. The pointed interval list
285
must cover a key part with greater number (i.e. Y->part > X->part).
287
In the example pic, the next_key_part pointers are represented by
290
2. SEL_ARG GRAPH SEMANTICS
292
It represents a condition in a special form (we don't have a name for it ATM)
293
The SEL_ARG::next/prev is "OR", and next_key_part is "AND".
295
For example, the picture represents the condition in form:
296
(kp1 < 1 AND kp2=5 AND (kp3=10 OR kp3=12)) OR
297
(kp1=2 AND (kp3=11 OR kp3=14)) OR
298
(kp1=3 AND (kp3=11 OR kp3=14))
303
Use get_mm_tree() to construct SEL_ARG graph from WHERE condition.
304
Then walk the SEL_ARG graph and get a list of dijsoint ordered key
305
intervals (i.e. intervals in form
307
(constA1, .., const1_K) < (keypart1,.., keypartK) < (constB1, .., constB_K)
309
Those intervals can be used to access the index. The uses are in:
310
- check_quick_select() - Walk the SEL_ARG graph and find an estimate of
311
how many table records are contained within all
313
- get_quick_select() - Walk the SEL_ARG, materialize the key intervals,
314
and create QUICK_RANGE_SELECT object that will
315
read records within these intervals.
317
4. SPACE COMPLEXITY NOTES
319
SEL_ARG graph is a representation of an ordered disjoint sequence of
320
intervals over the ordered set of index tuple values.
322
For multi-part keys, one can construct a WHERE expression such that its
323
list of intervals will be of combinatorial size. Here is an example:
325
(keypart1 IN (1,2, ..., n1)) AND
326
(keypart2 IN (1,2, ..., n2)) AND
327
(keypart3 IN (1,2, ..., n3))
329
For this WHERE clause the list of intervals will have n1*n2*n3 intervals
332
(keypart1, keypart2, keypart3) = (k1, k2, k3), where 1 <= k{i} <= n{i}
334
SEL_ARG graph structure aims to reduce the amount of required space by
335
"sharing" the elementary intervals when possible (the pic at the
336
beginning of this comment has examples of such sharing). The sharing may
337
prevent combinatorial blowup:
339
There are WHERE clauses that have combinatorial-size interval lists but
340
will be represented by a compact SEL_ARG graph.
342
(keypartN IN (1,2, ..., n1)) AND
344
(keypart2 IN (1,2, ..., n2)) AND
345
(keypart1 IN (1,2, ..., n3))
347
but not in all cases:
349
- There are WHERE clauses that do have a compact SEL_ARG-graph
350
representation but get_mm_tree() and its callees will construct a
351
graph of combinatorial size.
353
(keypart1 IN (1,2, ..., n1)) AND
354
(keypart2 IN (1,2, ..., n2)) AND
356
(keypartN IN (1,2, ..., n3))
358
- There are WHERE clauses for which the minimal possible SEL_ARG graph
359
representation will have combinatorial size.
361
By induction: Let's take any interval on some keypart in the middle:
365
Then let's AND it with this interval 'structure' from preceding and
368
(kp14=c1 AND kp16=c3) OR keypart14=c2) (*)
370
We will obtain this SEL_ARG graph:
374
+---------+ $ +---------+ $ +---------+
375
| kp14=c1 |--$-->| kp15=c0 |--$-->| kp16=c3 |
376
+---------+ $ +---------+ $ +---------+
378
+---------+ $ +---------+ $
379
| kp14=c2 |--$-->| kp15=c0 | $
380
+---------+ $ +---------+ $
383
Note that we had to duplicate "kp15=c0" and there was no way to avoid
385
The induction step: AND the obtained expression with another "wrapping"
387
When the process ends because of the limit on max. number of keyparts
390
WHERE clause length is O(3*#max_keyparts)
391
SEL_ARG graph size is O(2^(#max_keyparts/2))
393
(it is also possible to construct a case where instead of 2 in 2^n we
394
have a bigger constant, e.g. 4, and get a graph with 4^(31/2)= 2^31
397
We avoid consuming too much memory by setting a limit on the number of
398
SEL_ARG object we can construct during one range analysis invocation.
401
class SEL_ARG :public Sql_alloc
404
uint8_t min_flag,max_flag,maybe_flag;
405
uint8_t part; // Which key part
408
Number of children of this element in the RB-tree, plus 1 for this
413
Valid only for elements which are RB-tree roots: Number of times this
414
RB-tree is referred to (it is referred by SEL_ARG::next_key_part or by
415
SEL_TREE::keys[i] or by a temporary SEL_ARG* variable)
420
unsigned char *min_value,*max_value; // Pointer to range
423
eq_tree() requires that left == right == 0 if the type is MAYBE_KEY.
425
SEL_ARG *left,*right; /* R-B tree children */
426
SEL_ARG *next,*prev; /* Links for bi-directional interval list */
427
SEL_ARG *parent; /* R-B tree parent */
428
SEL_ARG *next_key_part;
429
enum leaf_color { BLACK,RED } color;
430
enum Type { IMPOSSIBLE, MAYBE, MAYBE_KEY, KEY_RANGE } type;
432
enum { MAX_SEL_ARGS = 16000 };
436
SEL_ARG(Field *,const unsigned char *, const unsigned char *);
437
SEL_ARG(Field *field, uint8_t part, unsigned char *min_value, unsigned char *max_value,
438
uint8_t min_flag, uint8_t max_flag, uint8_t maybe_flag);
439
SEL_ARG(enum Type type_arg)
440
:min_flag(0),elements(1),use_count(1),left(0),right(0),next_key_part(0),
441
color(BLACK), type(type_arg)
443
inline bool is_same(SEL_ARG *arg)
445
if (type != arg->type || part != arg->part)
447
if (type != KEY_RANGE)
449
return cmp_min_to_min(arg) == 0 && cmp_max_to_max(arg) == 0;
451
inline void merge_flags(SEL_ARG *arg) { maybe_flag|=arg->maybe_flag; }
452
inline void maybe_smaller() { maybe_flag=1; }
453
/* Return true iff it's a single-point null interval */
454
inline bool is_null_interval() { return maybe_null && max_value[0] == 1; }
455
inline int cmp_min_to_min(SEL_ARG* arg)
457
return sel_cmp(field,min_value, arg->min_value, min_flag, arg->min_flag);
459
inline int cmp_min_to_max(SEL_ARG* arg)
461
return sel_cmp(field,min_value, arg->max_value, min_flag, arg->max_flag);
463
inline int cmp_max_to_max(SEL_ARG* arg)
465
return sel_cmp(field,max_value, arg->max_value, max_flag, arg->max_flag);
467
inline int cmp_max_to_min(SEL_ARG* arg)
469
return sel_cmp(field,max_value, arg->min_value, max_flag, arg->min_flag);
471
SEL_ARG *clone_and(SEL_ARG* arg)
472
{ // Get overlapping range
473
unsigned char *new_min,*new_max;
474
uint8_t flag_min,flag_max;
475
if (cmp_min_to_min(arg) >= 0)
477
new_min=min_value; flag_min=min_flag;
481
new_min=arg->min_value; flag_min=arg->min_flag;
483
if (cmp_max_to_max(arg) <= 0)
485
new_max=max_value; flag_max=max_flag;
489
new_max=arg->max_value; flag_max=arg->max_flag;
491
return new SEL_ARG(field, part, new_min, new_max, flag_min, flag_max,
492
test(maybe_flag && arg->maybe_flag));
494
SEL_ARG *clone_first(SEL_ARG *arg)
495
{ // min <= X < arg->min
496
return new SEL_ARG(field,part, min_value, arg->min_value,
497
min_flag, arg->min_flag & NEAR_MIN ? 0 : NEAR_MAX,
498
maybe_flag | arg->maybe_flag);
500
SEL_ARG *clone_last(SEL_ARG *arg)
501
{ // min <= X <= key_max
502
return new SEL_ARG(field, part, min_value, arg->max_value,
503
min_flag, arg->max_flag, maybe_flag | arg->maybe_flag);
505
SEL_ARG *clone(RANGE_OPT_PARAM *param, SEL_ARG *new_parent, SEL_ARG **next);
507
bool copy_min(SEL_ARG* arg)
508
{ // Get overlapping range
509
if (cmp_min_to_min(arg) > 0)
511
min_value=arg->min_value; min_flag=arg->min_flag;
512
if ((max_flag & (NO_MAX_RANGE | NO_MIN_RANGE)) ==
513
(NO_MAX_RANGE | NO_MIN_RANGE))
514
return 1; // Full range
516
maybe_flag|=arg->maybe_flag;
519
bool copy_max(SEL_ARG* arg)
520
{ // Get overlapping range
521
if (cmp_max_to_max(arg) <= 0)
523
max_value=arg->max_value; max_flag=arg->max_flag;
524
if ((max_flag & (NO_MAX_RANGE | NO_MIN_RANGE)) ==
525
(NO_MAX_RANGE | NO_MIN_RANGE))
526
return 1; // Full range
528
maybe_flag|=arg->maybe_flag;
532
void copy_min_to_min(SEL_ARG *arg)
534
min_value=arg->min_value; min_flag=arg->min_flag;
536
void copy_min_to_max(SEL_ARG *arg)
538
max_value=arg->min_value;
539
max_flag=arg->min_flag & NEAR_MIN ? 0 : NEAR_MAX;
541
void copy_max_to_min(SEL_ARG *arg)
543
min_value=arg->max_value;
544
min_flag=arg->max_flag & NEAR_MAX ? 0 : NEAR_MIN;
546
/* returns a number of keypart values (0 or 1) appended to the key buffer */
547
int store_min(uint32_t length, unsigned char **min_key,uint32_t min_key_flag)
549
/* "(kp1 > c1) AND (kp2 OP c2) AND ..." -> (kp1 > c1) */
550
if ((!(min_flag & NO_MIN_RANGE) &&
551
!(min_key_flag & (NO_MIN_RANGE | NEAR_MIN))))
553
if (maybe_null && *min_value)
556
memset(*min_key+1, 0, length-1);
559
memcpy(*min_key,min_value,length);
565
/* returns a number of keypart values (0 or 1) appended to the key buffer */
566
int store_max(uint32_t length, unsigned char **max_key, uint32_t max_key_flag)
568
if (!(max_flag & NO_MAX_RANGE) &&
569
!(max_key_flag & (NO_MAX_RANGE | NEAR_MAX)))
571
if (maybe_null && *max_value)
574
memset(*max_key+1, 0, length-1);
577
memcpy(*max_key,max_value,length);
584
/* returns a number of keypart values appended to the key buffer */
585
int store_min_key(KEY_PART *key, unsigned char **range_key, uint32_t *range_key_flag)
587
SEL_ARG *key_tree= first();
588
uint32_t res= key_tree->store_min(key[key_tree->part].store_length,
589
range_key, *range_key_flag);
590
*range_key_flag|= key_tree->min_flag;
592
if (key_tree->next_key_part &&
593
key_tree->next_key_part->part == key_tree->part+1 &&
594
!(*range_key_flag & (NO_MIN_RANGE | NEAR_MIN)) &&
595
key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
596
res+= key_tree->next_key_part->store_min_key(key, range_key,
601
/* returns a number of keypart values appended to the key buffer */
602
int store_max_key(KEY_PART *key, unsigned char **range_key, uint32_t *range_key_flag)
604
SEL_ARG *key_tree= last();
605
uint32_t res=key_tree->store_max(key[key_tree->part].store_length,
606
range_key, *range_key_flag);
607
(*range_key_flag)|= key_tree->max_flag;
608
if (key_tree->next_key_part &&
609
key_tree->next_key_part->part == key_tree->part+1 &&
610
!(*range_key_flag & (NO_MAX_RANGE | NEAR_MAX)) &&
611
key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
612
res+= key_tree->next_key_part->store_max_key(key, range_key,
617
SEL_ARG *insert(SEL_ARG *key);
618
SEL_ARG *tree_delete(SEL_ARG *key);
619
SEL_ARG *find_range(SEL_ARG *key);
620
SEL_ARG *rb_insert(SEL_ARG *leaf);
621
friend SEL_ARG *rb_delete_fixup(SEL_ARG *root,SEL_ARG *key, SEL_ARG *par);
623
friend int test_rb_tree(SEL_ARG *element,SEL_ARG *parent);
624
void test_use_count(SEL_ARG *root);
629
inline bool simple_key()
631
return !next_key_part && elements == 1;
633
void increment_use_count(long count)
637
next_key_part->use_count+=count;
638
count*= (next_key_part->use_count-count);
639
for (SEL_ARG *pos=next_key_part->first(); pos ; pos=pos->next)
640
if (pos->next_key_part)
641
pos->increment_use_count(count);
646
for (SEL_ARG *pos=first(); pos ; pos=pos->next)
647
if (pos->next_key_part)
649
pos->next_key_part->use_count--;
650
pos->next_key_part->free_tree();
654
inline SEL_ARG **parent_ptr()
656
return parent->left == this ? &parent->left : &parent->right;
661
Check if this SEL_ARG object represents a single-point interval
667
Check if this SEL_ARG object (not tree) represents a single-point
668
interval, i.e. if it represents a "keypart = const" or
672
true This SEL_ARG object represents a singlepoint interval
676
bool is_singlepoint()
679
Check for NEAR_MIN ("strictly less") and NO_MIN_RANGE (-inf < field)
680
flags, and the same for right edge.
682
if (min_flag || max_flag)
684
unsigned char *min_val= min_value;
685
unsigned char *max_val= max_value;
689
/* First byte is a NULL value indicator */
690
if (*min_val != *max_val)
694
return true; /* This "x IS NULL" */
698
return !field->key_cmp(min_val, max_val);
700
SEL_ARG *clone_tree(RANGE_OPT_PARAM *param);
703
227
class SEL_IMERGE;
818
284
struct st_ror_scan_info;
820
static SEL_TREE * get_mm_parts(RANGE_OPT_PARAM *param,COND *cond_func,Field *field,
821
Item_func::Functype type,Item *value,
822
Item_result cmp_type);
823
static SEL_ARG *get_mm_leaf(RANGE_OPT_PARAM *param,COND *cond_func,Field *field,
825
Item_func::Functype type,Item *value);
826
static SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param,COND *cond);
828
static bool is_key_scan_ror(PARAM *param, uint32_t keynr, uint8_t nparts);
829
static ha_rows check_quick_select(PARAM *param, uint32_t idx, bool index_only,
830
SEL_ARG *tree, bool update_tbl_stats,
831
uint32_t *mrr_flags, uint32_t *bufsize,
286
static SEL_TREE * get_mm_parts(optimizer::RangeParameter *param,
289
Item_func::Functype type,
291
Item_result cmp_type);
293
static optimizer::SEL_ARG *get_mm_leaf(optimizer::RangeParameter *param,
297
Item_func::Functype type,
300
static SEL_TREE *get_mm_tree(optimizer::RangeParameter *param, COND *cond);
302
static bool is_key_scan_ror(optimizer::Parameter *param, uint32_t keynr, uint8_t nparts);
304
static ha_rows check_quick_select(optimizer::Parameter *param,
307
optimizer::SEL_ARG *tree,
308
bool update_tbl_stats,
832
311
COST_VECT *cost);
834
static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
313
static TRP_RANGE *get_key_scans_params(optimizer::Parameter *param,
835
315
bool index_read_must_be_used,
836
316
bool update_tbl_stats,
837
317
double read_time);
839
TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree,
320
TRP_ROR_INTERSECT *get_best_ror_intersect(const optimizer::Parameter *param,
840
322
double read_time,
841
323
bool *are_all_covering);
843
TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param,
326
TRP_ROR_INTERSECT *get_best_covering_ror_intersect(optimizer::Parameter *param,
845
328
double read_time);
847
TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
331
TABLE_READ_PLAN *get_best_disjunct_quick(optimizer::Parameter *param,
848
333
double read_time);
850
TRP_GROUP_MIN_MAX *get_best_group_min_max(PARAM *param, SEL_TREE *tree);
336
TRP_GROUP_MIN_MAX *get_best_group_min_max(optimizer::Parameter *param, SEL_TREE *tree);
852
static void print_sel_tree(PARAM *param, SEL_TREE *tree, key_map *tree_map,
338
static void print_sel_tree(optimizer::Parameter *param,
853
341
const char *msg);
854
static void print_ror_scans_arr(Table *table, const char *msg,
343
static void print_ror_scans_arr(Table *table,
855
345
struct st_ror_scan_info **start,
856
346
struct st_ror_scan_info **end);
858
static SEL_TREE *tree_and(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2);
859
static SEL_TREE *tree_or(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2);
860
static SEL_ARG *sel_add(SEL_ARG *key1,SEL_ARG *key2);
861
static SEL_ARG *key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2);
862
static SEL_ARG *key_and(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2,
863
uint32_t clone_flag);
864
static bool get_range(SEL_ARG **e1,SEL_ARG **e2,SEL_ARG *root1);
866
static bool eq_tree(SEL_ARG* a,SEL_ARG *b);
868
static SEL_ARG null_element(SEL_ARG::IMPOSSIBLE);
869
static bool null_part_in_key(KEY_PART *key_part, const unsigned char *key,
348
static SEL_TREE *tree_and(optimizer::RangeParameter *param, SEL_TREE *tree1, SEL_TREE *tree2);
350
static SEL_TREE *tree_or(optimizer::RangeParameter *param, SEL_TREE *tree1, SEL_TREE *tree2);
352
static optimizer::SEL_ARG *sel_add(optimizer::SEL_ARG *key1, optimizer::SEL_ARG *key2);
354
static optimizer::SEL_ARG *key_or(optimizer::RangeParameter *param, optimizer::SEL_ARG *key1, optimizer::SEL_ARG *key2);
356
static optimizer::SEL_ARG *key_and(optimizer::RangeParameter *param,
357
optimizer::SEL_ARG *key1,
358
optimizer::SEL_ARG *key2,
359
uint32_t clone_flag);
361
static bool get_range(optimizer::SEL_ARG **e1, optimizer::SEL_ARG **e2, optimizer::SEL_ARG *root1);
363
static bool eq_tree(optimizer::SEL_ARG* a, optimizer::SEL_ARG *b);
365
optimizer::SEL_ARG drizzled::optimizer::null_element(optimizer::SEL_ARG::IMPOSSIBLE);
367
static bool null_part_in_key(KEY_PART *key_part,
368
const unsigned char *key,
870
369
uint32_t length);
871
bool sel_trees_can_be_ored(SEL_TREE *tree1, SEL_TREE *tree2, RANGE_OPT_PARAM* param);
371
bool sel_trees_can_be_ored(SEL_TREE *tree1, SEL_TREE *tree2, optimizer::RangeParameter *param);
1172
bool optimizer::SQL_SELECT::skip_record()
670
bool optimizer::SqlSelect::skip_record()
1174
672
return cond ? cond->val_int() == 0 : 0;
1178
optimizer::QUICK_SELECT_I::QUICK_SELECT_I()
676
optimizer::QuickSelectInterface::QuickSelectInterface()
1180
678
max_used_key_length(0),
1181
679
used_key_parts(0)
1184
optimizer::QUICK_RANGE_SELECT::QUICK_RANGE_SELECT(Session *session,
1188
MEM_ROOT *parent_alloc,
1196
my_bitmap_map *bitmap= NULL;
1198
in_ror_merged_scan= 0;
1202
key_part_info= head->key_info[index].key_part;
1203
my_init_dynamic_array(&ranges, sizeof(optimizer::QUICK_RANGE*), 16, 16);
1205
/* 'session' is not accessible in QUICK_RANGE_SELECT::reset(). */
1206
mrr_buf_size= session->variables.read_rnd_buff_size;
1209
if (!no_alloc && !parent_alloc)
1211
// Allocates everything through the internal memroot
1212
init_sql_alloc(&alloc, session->variables.range_alloc_block_size, 0);
1213
session->mem_root= &alloc;
1216
memset(&alloc, 0, sizeof(alloc));
1217
cursor= head->cursor;
1218
record= head->record[0];
1219
save_read_set= head->read_set;
1220
save_write_set= head->write_set;
1222
/* Allocate a bitmap for used columns. Using sql_alloc instead of malloc
1223
simply as a "fix" to the MySQL 6.0 code that also free()s it at the
1224
same time we destroy the mem_root.
1227
bitmap= reinterpret_cast<my_bitmap_map*>(sql_alloc(head->s->column_bitmap_size));
1230
column_bitmap.setBitmap(NULL);
1235
column_bitmap.init(bitmap, head->s->fields);
1240
int optimizer::QUICK_RANGE_SELECT::init()
1242
if (cursor->inited != Cursor::NONE)
1243
cursor->ha_index_or_rnd_end();
1244
return (cursor->ha_index_init(index, 1));
1248
void optimizer::QUICK_RANGE_SELECT::range_end()
1250
if (cursor->inited != Cursor::NONE)
1251
cursor->ha_index_or_rnd_end();
1255
optimizer::QUICK_RANGE_SELECT::~QUICK_RANGE_SELECT()
1259
/* cursor is NULL for CPK scan on covering ROR-intersection */
1266
cursor->extra(HA_EXTRA_NO_KEYREAD);
1270
cursor->ha_external_lock(current_session, F_UNLCK);
1275
delete_dynamic(&ranges); /* ranges are allocated in alloc */
1276
free_root(&alloc,MYF(0));
1278
head->column_bitmaps_set(save_read_set, save_write_set);
1279
assert(mrr_buf_desc == NULL);
1287
optimizer::QUICK_INDEX_MERGE_SELECT::QUICK_INDEX_MERGE_SELECT(Session *session_param,
1290
pk_quick_select(NULL),
1291
session(session_param)
1295
memset(&read_record, 0, sizeof(read_record));
1296
init_sql_alloc(&alloc, session->variables.range_alloc_block_size, 0);
1300
int optimizer::QUICK_INDEX_MERGE_SELECT::init()
1305
int optimizer::QUICK_INDEX_MERGE_SELECT::reset()
1307
return (read_keys_and_merge());
1311
optimizer::QUICK_INDEX_MERGE_SELECT::push_quick_back(optimizer::QUICK_RANGE_SELECT *quick_sel_range)
1314
Save quick_select that does scan on clustered primary key as it will be
1315
processed separately.
1317
if (head->cursor->primary_key_is_clustered() &&
1318
quick_sel_range->index == head->s->primary_key)
1320
pk_quick_select= quick_sel_range;
1324
return quick_selects.push_back(quick_sel_range);
1329
optimizer::QUICK_INDEX_MERGE_SELECT::~QUICK_INDEX_MERGE_SELECT()
1331
List_iterator_fast<optimizer::QUICK_RANGE_SELECT> quick_it(quick_selects);
1332
optimizer::QUICK_RANGE_SELECT* quick;
1334
while ((quick= quick_it++))
1336
quick->cursor= NULL;
1338
quick_selects.delete_elements();
1339
delete pk_quick_select;
1340
free_root(&alloc,MYF(0));
1345
684
optimizer::QUICK_ROR_INTERSECT_SELECT::QUICK_ROR_INTERSECT_SELECT(Session *session_param,
1347
686
bool retrieve_full_rows,
1348
687
MEM_ROOT *parent_alloc)
1351
session(session_param),
690
session(session_param),
1352
691
need_to_fetch_row(retrieve_full_rows),
1353
692
scans_inited(false)
1749
optimizer::QUICK_RANGE::QUICK_RANGE()
1755
flag(NO_MIN_RANGE | NO_MAX_RANGE),
1760
SEL_ARG::SEL_ARG(SEL_ARG &arg) :Sql_alloc()
1763
min_flag=arg.min_flag;
1764
max_flag=arg.max_flag;
1765
maybe_flag=arg.maybe_flag;
1766
maybe_null=arg.maybe_null;
1769
min_value=arg.min_value;
1770
max_value=arg.max_value;
1771
next_key_part=arg.next_key_part;
1772
use_count=1; elements=1;
1776
inline void SEL_ARG::make_root()
1778
left=right= &null_element;
1781
use_count=0; elements=1;
1784
SEL_ARG::SEL_ARG(Field *f,const unsigned char *min_value_arg,
1785
const unsigned char *max_value_arg)
1786
:min_flag(0), max_flag(0), maybe_flag(0), maybe_null(f->real_maybe_null()),
1787
elements(1), use_count(1), field(f), min_value((unsigned char*) min_value_arg),
1788
max_value((unsigned char*) max_value_arg), next(0),prev(0),
1789
next_key_part(0),color(BLACK),type(KEY_RANGE)
1791
left=right= &null_element;
1794
SEL_ARG::SEL_ARG(Field *field_,uint8_t part_,
1795
unsigned char *min_value_, unsigned char *max_value_,
1796
uint8_t min_flag_,uint8_t max_flag_,uint8_t maybe_flag_)
1797
:min_flag(min_flag_),max_flag(max_flag_),maybe_flag(maybe_flag_),
1798
part(part_),maybe_null(field_->real_maybe_null()), elements(1),use_count(1),
1799
field(field_), min_value(min_value_), max_value(max_value_),
1800
next(0),prev(0),next_key_part(0),color(BLACK),type(KEY_RANGE)
1802
left=right= &null_element;
1805
SEL_ARG *SEL_ARG::clone(RANGE_OPT_PARAM *param, SEL_ARG *new_parent,
1810
/* Bail out if we have already generated too many SEL_ARGs */
1811
if (++param->alloced_sel_args > MAX_SEL_ARGS)
1814
if (type != KEY_RANGE)
1816
if (!(tmp= new (param->mem_root) SEL_ARG(type)))
1817
return 0; // out of memory
1818
tmp->prev= *next_arg; // Link into next/prev chain
1819
(*next_arg)->next=tmp;
1824
if (!(tmp= new (param->mem_root) SEL_ARG(field,part, min_value,max_value,
1825
min_flag, max_flag, maybe_flag)))
1827
tmp->parent=new_parent;
1828
tmp->next_key_part=next_key_part;
1829
if (left != &null_element)
1830
if (!(tmp->left=left->clone(param, tmp, next_arg)))
1833
tmp->prev= *next_arg; // Link into next/prev chain
1834
(*next_arg)->next=tmp;
1837
if (right != &null_element)
1838
if (!(tmp->right= right->clone(param, tmp, next_arg)))
1841
increment_use_count(1);
1843
tmp->elements= this->elements;
1847
SEL_ARG *SEL_ARG::first()
1849
SEL_ARG *next_arg=this;
1850
if (!next_arg->left)
1851
return 0; // MAYBE_KEY
1852
while (next_arg->left != &null_element)
1853
next_arg=next_arg->left;
1857
SEL_ARG *SEL_ARG::last()
1859
SEL_ARG *next_arg=this;
1860
if (!next_arg->right)
1861
return 0; // MAYBE_KEY
1862
while (next_arg->right != &null_element)
1863
next_arg=next_arg->right;
1869
Check if a compare is ok, when one takes ranges in account
1870
Returns -2 or 2 if the ranges where 'joined' like < 2 and >= 2
1873
static int sel_cmp(Field *field, unsigned char *a, unsigned char *b, uint8_t a_flag,
1877
/* First check if there was a compare to a min or max element */
1878
if (a_flag & (NO_MIN_RANGE | NO_MAX_RANGE))
1880
if ((a_flag & (NO_MIN_RANGE | NO_MAX_RANGE)) ==
1881
(b_flag & (NO_MIN_RANGE | NO_MAX_RANGE)))
1883
return (a_flag & NO_MIN_RANGE) ? -1 : 1;
1885
if (b_flag & (NO_MIN_RANGE | NO_MAX_RANGE))
1886
return (b_flag & NO_MIN_RANGE) ? 1 : -1;
1888
if (field->real_maybe_null()) // If null is part of key
1895
goto end; // NULL where equal
1896
a++; b++; // Skip NULL marker
1898
cmp=field->key_cmp(a , b);
1899
if (cmp) return cmp < 0 ? -1 : 1; // The values differed
1901
// Check if the compared equal arguments was defined with open/closed range
1903
if (a_flag & (NEAR_MIN | NEAR_MAX))
1905
if ((a_flag & (NEAR_MIN | NEAR_MAX)) == (b_flag & (NEAR_MIN | NEAR_MAX)))
1907
if (!(b_flag & (NEAR_MIN | NEAR_MAX)))
1908
return (a_flag & NEAR_MIN) ? 2 : -2;
1909
return (a_flag & NEAR_MIN) ? 1 : -1;
1911
if (b_flag & (NEAR_MIN | NEAR_MAX))
1912
return (b_flag & NEAR_MIN) ? -2 : 2;
1913
return 0; // The elements where equal
1917
SEL_ARG *SEL_ARG::clone_tree(RANGE_OPT_PARAM *param)
1919
SEL_ARG tmp_link,*next_arg,*root;
1920
next_arg= &tmp_link;
1921
if (!(root= clone(param, (SEL_ARG *) 0, &next_arg)))
1923
next_arg->next=0; // Fix last link
1924
tmp_link.next->prev=0; // Fix first link
1925
if (root) // If not OOM
1932
979
Find the best index to retrieve first N records in given order
5463
4539
// Add tree at key2 to tree at key1
5464
bool key2_shared=key2->use_count != 0;
5465
key1->maybe_flag|=key2->maybe_flag;
4540
bool key2_shared= key2->use_count != 0;
4541
key1->maybe_flag|= key2->maybe_flag;
5467
4543
for (key2=key2->first(); key2; )
5469
SEL_ARG *tmp=key1->find_range(key2); // Find key1.min <= key2.min
4545
optimizer::SEL_ARG *tmp= key1->find_range(key2); // Find key1.min <= key2.min
5474
tmp=key1->first(); // tmp.min > key2.min
4550
tmp=key1->first(); // tmp.min > key2.min
5477
4553
else if ((cmp=tmp->cmp_max_to_min(key2)) < 0)
5478
4554
{ // Found tmp.max < key2.min
5479
SEL_ARG *next=tmp->next;
4555
optimizer::SEL_ARG *next= tmp->next;
5480
4556
if (cmp == -2 && eq_tree(tmp->next_key_part,key2->next_key_part))
5482
// Join near ranges like tmp.max < 0 and key2.min >= 0
5483
SEL_ARG *key2_next=key2->next;
5486
if (!(key2=new SEL_ARG(*key2)))
5487
return 0; // out of memory
5488
key2->increment_use_count(key1->use_count+1);
5489
key2->next=key2_next; // New copy of key2
5491
key2->copy_min(tmp);
5492
if (!(key1=key1->tree_delete(tmp)))
5493
{ // Only one key in tree
4558
// Join near ranges like tmp.max < 0 and key2.min >= 0
4559
optimizer::SEL_ARG *key2_next=key2->next;
4562
if (! (key2=new optimizer::SEL_ARG(*key2)))
4563
return 0; // out of memory
4564
key2->increment_use_count(key1->use_count+1);
4565
key2->next= key2_next; // New copy of key2
4567
key2->copy_min(tmp);
4568
if (! (key1=key1->tree_delete(tmp)))
4569
{ // Only one key in tree
5500
if (!(tmp=next)) // tmp.min > key2.min
5501
break; // Copy rest of key2
4576
if (! (tmp= next)) // tmp.min > key2.min
4577
break; // Copy rest of key2
5504
4580
{ // tmp.min > key2.min
5506
if ((tmp_cmp=tmp->cmp_min_to_max(key2)) > 0) // if tmp.min > key2.max
4582
if ((tmp_cmp= tmp->cmp_min_to_max(key2)) > 0) // if tmp.min > key2.max
5508
if (tmp_cmp == 2 && eq_tree(tmp->next_key_part,key2->next_key_part))
5509
{ // ranges are connected
5510
tmp->copy_min_to_min(key2);
5511
key1->merge_flags(key2);
5512
if (tmp->min_flag & NO_MIN_RANGE &&
5513
tmp->max_flag & NO_MAX_RANGE)
5515
if (key1->maybe_flag)
5516
return new SEL_ARG(SEL_ARG::MAYBE_KEY);
5519
key2->increment_use_count(-1); // Free not used tree
5525
SEL_ARG *next=key2->next; // Keys are not overlapping
5528
SEL_ARG *cpy= new SEL_ARG(*key2); // Must make copy
5531
key1=key1->insert(cpy);
5532
key2->increment_use_count(key1->use_count+1);
5535
key1=key1->insert(key2); // Will destroy key2_root
4584
if (tmp_cmp == 2 && eq_tree(tmp->next_key_part,key2->next_key_part))
4585
{ // ranges are connected
4586
tmp->copy_min_to_min(key2);
4587
key1->merge_flags(key2);
4588
if (tmp->min_flag & NO_MIN_RANGE &&
4589
tmp->max_flag & NO_MAX_RANGE)
4591
if (key1->maybe_flag)
4592
return new optimizer::SEL_ARG(optimizer::SEL_ARG::MAYBE_KEY);
4595
key2->increment_use_count(-1); // Free not used tree
4601
optimizer::SEL_ARG *next= key2->next; // Keys are not overlapping
4604
optimizer::SEL_ARG *cpy= new optimizer::SEL_ARG(*key2); // Must make copy
4607
key1= key1->insert(cpy);
4608
key2->increment_use_count(key1->use_count+1);
4611
key1= key1->insert(key2); // Will destroy key2_root
5545
4621
if (tmp->is_same(key2))
5547
tmp->merge_flags(key2); // Copy maybe flags
5548
key2->increment_use_count(-1); // Free not used tree
4623
tmp->merge_flags(key2); // Copy maybe flags
4624
key2->increment_use_count(-1); // Free not used tree
5553
while (last->next && last->next->cmp_min_to_max(key2) <= 0 &&
5554
eq_tree(last->next->next_key_part,key2->next_key_part))
5558
key1=key1->tree_delete(save);
4628
optimizer::SEL_ARG *last= tmp;
4629
while (last->next && last->next->cmp_min_to_max(key2) <= 0 &&
4630
eq_tree(last->next->next_key_part,key2->next_key_part))
4632
optimizer::SEL_ARG *save= last;
4634
key1= key1->tree_delete(save);
5560
4636
last->copy_min(tmp);
5561
if (last->copy_min(key2) || last->copy_max(key2))
5564
for (; key2 ; key2=key2->next)
5565
key2->increment_use_count(-1); // Free not used tree
5566
if (key1->maybe_flag)
5567
return new SEL_ARG(SEL_ARG::MAYBE_KEY);
4637
if (last->copy_min(key2) || last->copy_max(key2))
4640
for (; key2; key2= key2->next)
4641
key2->increment_use_count(-1); // Free not used tree
4642
if (key1->maybe_flag)
4643
return new optimizer::SEL_ARG(optimizer::SEL_ARG::MAYBE_KEY);
5575
4651
if (cmp >= 0 && tmp->cmp_min_to_min(key2) < 0)
5576
4652
{ // tmp.min <= x < key2.min
5577
SEL_ARG *new_arg=tmp->clone_first(key2);
4653
optimizer::SEL_ARG *new_arg= tmp->clone_first(key2);
5580
4656
if ((new_arg->next_key_part= key1->next_key_part))
5581
new_arg->increment_use_count(key1->use_count+1);
4657
new_arg->increment_use_count(key1->use_count+1);
5582
4658
tmp->copy_min_to_min(key2);
5583
key1=key1->insert(new_arg);
4659
key1= key1->insert(new_arg);
5586
4662
// tmp.min >= key2.min && tmp.min <= key2.max
5587
SEL_ARG key(*key2); // Get copy we can modify
4663
optimizer::SEL_ARG key(*key2); // Get copy we can modify
5590
4666
if (tmp->cmp_min_to_min(&key) > 0)
5591
4667
{ // key.min <= x < tmp.min
5592
SEL_ARG *new_arg=key.clone_first(tmp);
5595
if ((new_arg->next_key_part=key.next_key_part))
5596
new_arg->increment_use_count(key1->use_count+1);
5597
key1=key1->insert(new_arg);
4668
optimizer::SEL_ARG *new_arg= key.clone_first(tmp);
4671
if ((new_arg->next_key_part=key.next_key_part))
4672
new_arg->increment_use_count(key1->use_count+1);
4673
key1= key1->insert(new_arg);
5599
4675
if ((cmp=tmp->cmp_max_to_max(&key)) <= 0)
5600
4676
{ // tmp.min. <= x <= tmp.max
5601
tmp->maybe_flag|= key.maybe_flag;
5602
key.increment_use_count(key1->use_count+1);
5603
tmp->next_key_part= key_or(param, tmp->next_key_part, key.next_key_part);
5604
if (!cmp) // Key2 is ready
5606
key.copy_max_to_min(tmp);
5607
if (!(tmp=tmp->next))
5609
SEL_ARG *tmp2= new SEL_ARG(key);
5612
key1=key1->insert(tmp2);
5616
if (tmp->cmp_min_to_max(&key) > 0)
5618
SEL_ARG *tmp2= new SEL_ARG(key);
5621
key1=key1->insert(tmp2);
4677
tmp->maybe_flag|= key.maybe_flag;
4678
key.increment_use_count(key1->use_count+1);
4679
tmp->next_key_part= key_or(param, tmp->next_key_part, key.next_key_part);
4680
if (! cmp) // Key2 is ready
4682
key.copy_max_to_min(tmp);
4683
if (! (tmp= tmp->next))
4685
optimizer::SEL_ARG *tmp2= new optimizer::SEL_ARG(key);
4688
key1= key1->insert(tmp2);
4692
if (tmp->cmp_min_to_max(&key) > 0)
4694
optimizer::SEL_ARG *tmp2= new optimizer::SEL_ARG(key);
4697
key1= key1->insert(tmp2);
5627
SEL_ARG *new_arg=tmp->clone_last(&key); // tmp.min <= x <= key.max
5630
tmp->copy_max_to_min(&key);
5631
tmp->increment_use_count(key1->use_count+1);
5632
/* Increment key count as it may be used for next loop */
5633
key.increment_use_count(1);
5634
new_arg->next_key_part= key_or(param, tmp->next_key_part, key.next_key_part);
5635
key1=key1->insert(new_arg);
4703
optimizer::SEL_ARG *new_arg= tmp->clone_last(&key); // tmp.min <= x <= key.max
4706
tmp->copy_max_to_min(&key);
4707
tmp->increment_use_count(key1->use_count+1);
4708
/* Increment key count as it may be used for next loop */
4709
key.increment_use_count(1);
4710
new_arg->next_key_part= key_or(param, tmp->next_key_part, key.next_key_part);
4711
key1= key1->insert(new_arg);
5645
SEL_ARG *next=key2->next;
4721
optimizer::SEL_ARG *next= key2->next;
5646
4722
if (key2_shared)
5648
SEL_ARG *tmp=new SEL_ARG(*key2); // Must make copy
4724
optimizer::SEL_ARG *tmp= new optimizer::SEL_ARG(*key2); // Must make copy
5651
4727
key2->increment_use_count(key1->use_count+1);
5652
key1=key1->insert(tmp);
4728
key1= key1->insert(tmp);
5655
key1=key1->insert(key2); // Will destroy key2_root
4731
key1= key1->insert(key2); // Will destroy key2_root
5658
4734
key1->use_count++;
5663
4739
/* Compare if two trees are equal */
5665
static bool eq_tree(SEL_ARG* a,SEL_ARG *b)
4740
static bool eq_tree(optimizer::SEL_ARG *a, optimizer::SEL_ARG *b)
5669
if (!a || !b || !a->is_same(b))
5671
if (a->left != &null_element && b->left != &null_element)
5673
if (!eq_tree(a->left,b->left))
5676
else if (a->left != &null_element || b->left != &null_element)
5678
if (a->right != &null_element && b->right != &null_element)
5680
if (!eq_tree(a->right,b->right))
5683
else if (a->right != &null_element || b->right != &null_element)
4747
if (! a || ! b || ! a->is_same(b))
4752
if (a->left != &optimizer::null_element && b->left != &optimizer::null_element)
4754
if (! eq_tree(a->left,b->left))
4757
else if (a->left != &optimizer::null_element || b->left != &optimizer::null_element)
4762
if (a->right != &optimizer::null_element && b->right != &optimizer::null_element)
4764
if (! eq_tree(a->right,b->right))
4767
else if (a->right != &optimizer::null_element || b->right != &optimizer::null_element)
5685
4772
if (a->next_key_part != b->next_key_part)
5687
if (!a->next_key_part != !b->next_key_part ||
5688
!eq_tree(a->next_key_part, b->next_key_part))
5696
SEL_ARG::insert(SEL_ARG *key)
5698
SEL_ARG *element, **par= NULL, *last_element= NULL;
5700
for (element= this; element != &null_element ; )
5702
last_element=element;
5703
if (key->cmp_min_to_min(element) > 0)
5705
par= &element->right; element= element->right;
5709
par = &element->left; element= element->left;
5713
key->parent=last_element;
5715
if (par == &last_element->left)
5717
key->next=last_element;
5718
if ((key->prev=last_element->prev))
5719
key->prev->next=key;
5720
last_element->prev=key;
5724
if ((key->next=last_element->next))
5725
key->next->prev=key;
5726
key->prev=last_element;
5727
last_element->next=key;
5729
key->left=key->right= &null_element;
5730
SEL_ARG *root=rb_insert(key); // rebalance tree
5731
root->use_count=this->use_count; // copy root info
5732
root->elements= this->elements+1;
5733
root->maybe_flag=this->maybe_flag;
5739
** Find best key with min <= given key
5740
** Because the call context this should never return 0 to get_range
5744
SEL_ARG::find_range(SEL_ARG *key)
5746
SEL_ARG *element=this,*found=0;
5750
if (element == &null_element)
5752
int cmp=element->cmp_min_to_min(key);
5758
element=element->right;
5761
element=element->left;
5767
Remove a element from the tree
5771
key Key that is to be deleted from tree (this)
5774
This also frees all sub trees that is used by the element
5777
root of new tree (with key deleted)
5781
SEL_ARG::tree_delete(SEL_ARG *key)
5783
enum leaf_color remove_color;
5784
SEL_ARG *root,*nod,**par,*fix_par;
5789
/* Unlink from list */
5791
key->prev->next=key->next;
5793
key->next->prev=key->prev;
5794
key->increment_use_count(-1);
5798
par=key->parent_ptr();
5800
if (key->left == &null_element)
5802
*par=nod=key->right;
5803
fix_par=key->parent;
5804
if (nod != &null_element)
5805
nod->parent=fix_par;
5806
remove_color= key->color;
5808
else if (key->right == &null_element)
5810
*par= nod=key->left;
5811
nod->parent=fix_par=key->parent;
5812
remove_color= key->color;
5816
SEL_ARG *tmp=key->next; // next bigger key (exist!)
5817
nod= *tmp->parent_ptr()= tmp->right; // unlink tmp from tree
5818
fix_par=tmp->parent;
5819
if (nod != &null_element)
5820
nod->parent=fix_par;
5821
remove_color= tmp->color;
5823
tmp->parent=key->parent; // Move node in place of key
5824
(tmp->left=key->left)->parent=tmp;
5825
if ((tmp->right=key->right) != &null_element)
5826
tmp->right->parent=tmp;
5827
tmp->color=key->color;
5829
if (fix_par == key) // key->right == key->next
5830
fix_par=tmp; // new parent of nod
5833
if (root == &null_element)
5834
return 0; // Maybe root later
5835
if (remove_color == BLACK)
5836
root=rb_delete_fixup(root,nod,fix_par);
5838
test_rb_tree(root,root->parent);
5839
#endif /* EXTRA_DEBUG */
5841
root->use_count=this->use_count; // Fix root counters
5842
root->elements=this->elements-1;
5843
root->maybe_flag=this->maybe_flag;
5848
/* Functions to fix up the tree after insert and delete */
5850
static void left_rotate(SEL_ARG **root,SEL_ARG *leaf)
5852
SEL_ARG *y=leaf->right;
5853
leaf->right=y->left;
5854
if (y->left != &null_element)
5855
y->left->parent=leaf;
5856
if (!(y->parent=leaf->parent))
5859
*leaf->parent_ptr()=y;
5864
static void right_rotate(SEL_ARG **root,SEL_ARG *leaf)
5866
SEL_ARG *y=leaf->left;
5867
leaf->left=y->right;
5868
if (y->right != &null_element)
5869
y->right->parent=leaf;
5870
if (!(y->parent=leaf->parent))
5873
*leaf->parent_ptr()=y;
5880
SEL_ARG::rb_insert(SEL_ARG *leaf)
5882
SEL_ARG *y,*par,*par2,*root;
5883
root= this; root->parent= 0;
5886
while (leaf != root && (par= leaf->parent)->color == RED)
5887
{ // This can't be root or 1 level under
5888
if (par == (par2= leaf->parent->parent)->left)
5891
if (y->color == RED)
5896
leaf->color=RED; /* And the loop continues */
5900
if (leaf == par->right)
5902
left_rotate(&root,leaf->parent);
5903
par=leaf; /* leaf is now parent to old leaf */
5907
right_rotate(&root,par2);
5914
if (y->color == RED)
5919
leaf->color=RED; /* And the loop continues */
5923
if (leaf == par->left)
5925
right_rotate(&root,par);
5930
left_rotate(&root,par2);
5937
test_rb_tree(root,root->parent);
5938
#endif /* EXTRA_DEBUG */
5944
SEL_ARG *rb_delete_fixup(SEL_ARG *root,SEL_ARG *key,SEL_ARG *par)
5950
while (x != root && x->color == SEL_ARG::BLACK)
5955
if (w->color == SEL_ARG::RED)
5957
w->color=SEL_ARG::BLACK;
5958
par->color=SEL_ARG::RED;
5959
left_rotate(&root,par);
5962
if (w->left->color == SEL_ARG::BLACK && w->right->color == SEL_ARG::BLACK)
5964
w->color=SEL_ARG::RED;
5969
if (w->right->color == SEL_ARG::BLACK)
5971
w->left->color=SEL_ARG::BLACK;
5972
w->color=SEL_ARG::RED;
5973
right_rotate(&root,w);
5976
w->color=par->color;
5977
par->color=SEL_ARG::BLACK;
5978
w->right->color=SEL_ARG::BLACK;
5979
left_rotate(&root,par);
5987
if (w->color == SEL_ARG::RED)
5989
w->color=SEL_ARG::BLACK;
5990
par->color=SEL_ARG::RED;
5991
right_rotate(&root,par);
5994
if (w->right->color == SEL_ARG::BLACK && w->left->color == SEL_ARG::BLACK)
5996
w->color=SEL_ARG::RED;
6001
if (w->left->color == SEL_ARG::BLACK)
6003
w->right->color=SEL_ARG::BLACK;
6004
w->color=SEL_ARG::RED;
6005
left_rotate(&root,w);
6008
w->color=par->color;
6009
par->color=SEL_ARG::BLACK;
6010
w->left->color=SEL_ARG::BLACK;
6011
right_rotate(&root,par);
6018
x->color=SEL_ARG::BLACK;
6023
/* Test that the properties for a red-black tree hold */
6026
int test_rb_tree(SEL_ARG *element,SEL_ARG *parent)
6028
int count_l,count_r;
6030
if (element == &null_element)
6031
return 0; // Found end of tree
6032
if (element->parent != parent)
6034
errmsg_printf(ERRMSG_LVL_ERROR, "Wrong tree: Parent doesn't point at parent");
6037
if (element->color == SEL_ARG::RED &&
6038
(element->left->color == SEL_ARG::RED ||
6039
element->right->color == SEL_ARG::RED))
6041
errmsg_printf(ERRMSG_LVL_ERROR, "Wrong tree: Found two red in a row");
6044
if (element->left == element->right && element->left != &null_element)
6046
errmsg_printf(ERRMSG_LVL_ERROR, "Wrong tree: Found right == left");
6049
count_l=test_rb_tree(element->left,element);
6050
count_r=test_rb_tree(element->right,element);
6051
if (count_l >= 0 && count_r >= 0)
6053
if (count_l == count_r)
6054
return count_l+(element->color == SEL_ARG::BLACK);
6055
errmsg_printf(ERRMSG_LVL_ERROR, "Wrong tree: Incorrect black-count: %d - %d",
6058
return -1; // Error, no more warnings
6063
Count how many times SEL_ARG graph "root" refers to its part "key"
6066
count_key_part_usage()
6067
root An RB-Root node in a SEL_ARG graph.
6068
key Another RB-Root node in that SEL_ARG graph.
6071
The passed "root" node may refer to "key" node via root->next_key_part,
6074
This function counts how many times the node "key" is referred (via
6075
SEL_ARG::next_key_part) by
6076
- intervals of RB-tree pointed by "root",
6077
- intervals of RB-trees that are pointed by SEL_ARG::next_key_part from
6078
intervals of RB-tree pointed by "root",
6081
Here is an example (horizontal links represent next_key_part pointers,
6082
vertical links - next/prev prev pointers):
6085
|root|-----------------+
6089
+----+ +---+ $ | +---+ Here the return value
6090
| |- ... -| |---$-+--+->|key| will be 4.
6091
+----+ +---+ $ | | +---+
6096
| |---| |---------+ |
6103
Number of links to "key" from nodes reachable from "root".
6106
static ulong count_key_part_usage(SEL_ARG *root, SEL_ARG *key)
6109
for (root=root->first(); root ; root=root->next)
6111
if (root->next_key_part)
6113
if (root->next_key_part == key)
6115
if (root->next_key_part->part < key->part)
6116
count+=count_key_part_usage(root->next_key_part,key);
6124
Check if SEL_ARG::use_count value is correct
6127
SEL_ARG::test_use_count()
6128
root The root node of the SEL_ARG graph (an RB-tree root node that
6129
has the least value of sel_arg->part in the entire graph, and
6130
thus is the "origin" of the graph)
6133
Check if SEL_ARG::use_count value is correct. See the definition of
6134
use_count for what is "correct".
6137
void SEL_ARG::test_use_count(SEL_ARG *root)
6140
if (this == root && use_count != 1)
6142
errmsg_printf(ERRMSG_LVL_INFO, "Use_count: Wrong count %lu for root",use_count);
6145
if (this->type != SEL_ARG::KEY_RANGE)
6147
for (SEL_ARG *pos=first(); pos ; pos=pos->next)
6150
if (pos->next_key_part)
6152
ulong count=count_key_part_usage(root,pos->next_key_part);
6153
if (count > pos->next_key_part->use_count)
6155
errmsg_printf(ERRMSG_LVL_INFO, "Use_count: Wrong count for key at 0x%lx, %lu "
6156
"should be %lu", (long unsigned int)pos,
6157
pos->next_key_part->use_count, count);
6160
pos->next_key_part->test_use_count(root);
6163
if (e_count != elements)
6164
errmsg_printf(ERRMSG_LVL_WARN, "Wrong use count: %u (should be %u) for tree at 0x%lx",
6165
e_count, elements, (long unsigned int) this);
4774
if (! a->next_key_part != ! b->next_key_part ||
4775
! eq_tree(a->next_key_part, b->next_key_part))
6170
4783
/****************************************************************************
6171
4784
MRR Range Sequence Interface implementation that walks a SEL_ARG* tree.
7400
5813
1 No more ranges in the sequence
7403
5815
uint32_t optimizer::quick_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range)
7405
QUICK_RANGE_SEQ_CTX *ctx= (QUICK_RANGE_SEQ_CTX*)rseq;
5817
QuickRangeSequenceContext *ctx= (QuickRangeSequenceContext*) rseq;
7407
5819
if (ctx->cur == ctx->last)
7408
5820
return 1; /* no more ranges */
7410
optimizer::QUICK_RANGE *cur= *(ctx->cur);
5822
optimizer::QuickRange *cur= *(ctx->cur);
7411
5823
key_range *start_key= &range->start_key;
7412
key_range *end_key= &range->end_key;
5824
key_range *end_key= &range->end_key;
7414
start_key->key= cur->min_key;
5826
start_key->key= cur->min_key;
7415
5827
start_key->length= cur->min_length;
7416
5828
start_key->keypart_map= cur->min_keypart_map;
7417
start_key->flag= ((cur->flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
7418
(cur->flag & EQ_RANGE) ?
7419
HA_READ_KEY_EXACT : HA_READ_KEY_OR_NEXT);
7420
end_key->key= cur->max_key;
7421
end_key->length= cur->max_length;
5829
start_key->flag= ((cur->flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
5830
(cur->flag & EQ_RANGE) ?
5831
HA_READ_KEY_EXACT : HA_READ_KEY_OR_NEXT);
5832
end_key->key= cur->max_key;
5833
end_key->length= cur->max_length;
7422
5834
end_key->keypart_map= cur->max_keypart_map;
7424
5836
We use HA_READ_AFTER_KEY here because if we are reading on a key
7425
5837
prefix. We want to find all keys with this prefix.
7427
end_key->flag= (cur->flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
5839
end_key->flag= (cur->flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
7429
5841
range->range_flag= cur->flag;
7436
Get next possible record using quick-struct.
7439
QUICK_RANGE_SELECT::get_next()
7442
Record is read into table->record[0]
7446
HA_ERR_END_OF_FILE No (more) rows in range
7450
int optimizer::QUICK_RANGE_SELECT::get_next()
7453
if (in_ror_merged_scan)
7456
We don't need to signal the bitmap change as the bitmap is always the
7457
same for this head->cursor
7459
head->column_bitmaps_set(&column_bitmap, &column_bitmap);
7462
int result= cursor->multi_range_read_next(&dummy);
7464
if (in_ror_merged_scan)
7466
/* Restore bitmaps set on entry */
7467
head->column_bitmaps_set(save_read_set, save_write_set);
7474
Get the next record with a different prefix.
7477
QUICK_RANGE_SELECT::get_next_prefix()
7478
prefix_length length of cur_prefix
7479
cur_prefix prefix of a key to be searched for
7482
Each subsequent call to the method retrieves the first record that has a
7483
prefix with length prefix_length different from cur_prefix, such that the
7484
record with the new prefix is within the ranges described by
7485
this->ranges. The record found is stored into the buffer pointed by
7487
The method is useful for GROUP-BY queries with range conditions to
7488
discover the prefix of the next group that satisfies the range conditions.
7491
This method is a modified copy of QUICK_RANGE_SELECT::get_next(), so both
7492
methods should be unified into a more general one to reduce code
7497
HA_ERR_END_OF_FILE if returned all keys
7498
other if some error occurred
7501
int optimizer::QUICK_RANGE_SELECT::get_next_prefix(uint32_t prefix_length,
7502
key_part_map keypart_map,
7503
unsigned char *cur_prefix)
7508
key_range start_key, end_key;
7511
/* Read the next record in the same range with prefix after cur_prefix. */
7512
assert(cur_prefix != 0);
7513
result= cursor->index_read_map(record, cur_prefix, keypart_map,
7515
if (result || (cursor->compare_key(cursor->end_range) <= 0))
7519
uint32_t count= ranges.elements - (cur_range - (optimizer::QUICK_RANGE**) ranges.buffer);
7522
/* Ranges have already been used up before. None is left for read. */
7524
return HA_ERR_END_OF_FILE;
7526
last_range= *(cur_range++);
7528
start_key.key= (const unsigned char*) last_range->min_key;
7529
start_key.length= min(last_range->min_length, (uint16_t)prefix_length);
7530
start_key.keypart_map= last_range->min_keypart_map & keypart_map;
7531
start_key.flag= ((last_range->flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
7532
(last_range->flag & EQ_RANGE) ?
7533
HA_READ_KEY_EXACT : HA_READ_KEY_OR_NEXT);
7534
end_key.key= (const unsigned char*) last_range->max_key;
7535
end_key.length= min(last_range->max_length, (uint16_t)prefix_length);
7536
end_key.keypart_map= last_range->max_keypart_map & keypart_map;
7538
We use READ_AFTER_KEY here because if we are reading on a key
7539
prefix we want to find all keys with this prefix
7541
end_key.flag= (last_range->flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
7544
result= cursor->read_range_first(last_range->min_keypart_map ? &start_key : 0,
7545
last_range->max_keypart_map ? &end_key : 0,
7546
test(last_range->flag & EQ_RANGE),
7548
if (last_range->flag == (UNIQUE_RANGE | EQ_RANGE))
7549
last_range= 0; // Stop searching
7551
if (result != HA_ERR_END_OF_FILE)
7553
last_range= 0; // No matching rows; go to next range
7559
Check if current row will be retrieved by this QUICK_RANGE_SELECT
7562
It is assumed that currently a scan is being done on another index
7563
which reads all necessary parts of the index that is scanned by this
7565
The implementation does a binary search on sorted array of disjoint
7566
ranges, without taking size of range into account.
7568
This function is used to filter out clustered PK scan rows in
7569
index_merge quick select.
7572
true if current row will be retrieved by this quick select
7576
bool optimizer::QUICK_RANGE_SELECT::row_in_ranges()
7578
optimizer::QUICK_RANGE *res;
7580
uint32_t max= ranges.elements - 1;
7581
uint32_t mid= (max + min)/2;
7585
if (cmp_next(*(optimizer::QUICK_RANGE**)dynamic_array_ptr(&ranges, mid)))
7587
/* current row value > mid->max */
7592
mid= (min + max) / 2;
7594
res= *(optimizer::QUICK_RANGE**)dynamic_array_ptr(&ranges, mid);
7595
return (!cmp_next(res) && !cmp_prev(res));
7599
This is a hack: we inherit from QUICK_SELECT so that we can use the
7600
get_next() interface, but we have to hold a pointer to the original
7601
QUICK_SELECT because its data are used all over the place. What
7602
should be done is to factor out the data that is needed into a base
7603
class (QUICK_SELECT), and then have two subclasses (_ASC and _DESC)
7604
which handle the ranges and implement the get_next() function. But
7605
for now, this seems to work right at least.
7608
optimizer::QUICK_SELECT_DESC::QUICK_SELECT_DESC(optimizer::QUICK_RANGE_SELECT *q, uint32_t, bool *)
7610
optimizer::QUICK_RANGE_SELECT(*q),
7613
optimizer::QUICK_RANGE *r;
7615
optimizer::QUICK_RANGE **pr= (optimizer::QUICK_RANGE**)ranges.buffer;
7616
optimizer::QUICK_RANGE **end_range= pr + ranges.elements;
7617
for (; pr!=end_range; pr++)
7618
rev_ranges.push_front(*pr);
7620
/* Remove EQ_RANGE flag for keys that are not using the full key */
7621
for (r = rev_it++; r; r = rev_it++)
7623
if ((r->flag & EQ_RANGE) &&
7624
head->key_info[index].key_length != r->max_length)
7625
r->flag&= ~EQ_RANGE;
7628
q->dont_free=1; // Don't free shared mem
7633
int optimizer::QUICK_SELECT_DESC::get_next()
7635
/* The max key is handled as follows:
7636
* - if there is NO_MAX_RANGE, start at the end and move backwards
7637
* - if it is an EQ_RANGE, which means that max key covers the entire
7638
* key, go directly to the key and read through it (sorting backwards is
7639
* same as sorting forwards)
7640
* - if it is NEAR_MAX, go to the key or next, step back once, and
7642
* - otherwise (not NEAR_MAX == include the key), go after the key,
7643
* step back once, and move backwards
7650
{ // Already read through key
7651
result = ((last_range->flag & EQ_RANGE)
7652
? cursor->index_next_same(record, last_range->min_key,
7653
last_range->min_length) :
7654
cursor->index_prev(record));
7657
if (cmp_prev(*rev_it.ref()) == 0)
7660
else if (result != HA_ERR_END_OF_FILE)
7664
if (!(last_range= rev_it++))
7665
return HA_ERR_END_OF_FILE; // All ranges used
7667
if (last_range->flag & NO_MAX_RANGE) // Read last record
7670
if ((local_error=cursor->index_last(record)))
7671
return(local_error); // Empty table
7672
if (cmp_prev(last_range) == 0)
7674
last_range= 0; // No match; go to next range
7678
if (last_range->flag & EQ_RANGE)
7680
result = cursor->index_read_map(record, last_range->max_key,
7681
last_range->max_keypart_map,
7686
assert(last_range->flag & NEAR_MAX ||
7687
range_reads_after_key(last_range));
7688
result=cursor->index_read_map(record, last_range->max_key,
7689
last_range->max_keypart_map,
7690
((last_range->flag & NEAR_MAX) ?
7691
HA_READ_BEFORE_KEY :
7692
HA_READ_PREFIX_LAST_OR_PREV));
7696
if (result != HA_ERR_KEY_NOT_FOUND && result != HA_ERR_END_OF_FILE)
7698
last_range= 0; // Not found, to next range
7701
if (cmp_prev(last_range) == 0)
7703
if (last_range->flag == (UNIQUE_RANGE | EQ_RANGE))
7704
last_range= 0; // Stop searching
7705
return 0; // Found key is in range
7707
last_range= 0; // To next range
7713
Compare if found key is over max-value
7714
Returns 0 if key <= range->max_key
7715
TODO: Figure out why can't this function be as simple as cmp_prev().
7718
int optimizer::QUICK_RANGE_SELECT::cmp_next(optimizer::QUICK_RANGE *range_arg)
7720
if (range_arg->flag & NO_MAX_RANGE)
7721
return 0; /* key can't be to large */
7723
KEY_PART *key_part=key_parts;
7724
uint32_t store_length;
7726
for (unsigned char *key=range_arg->max_key, *end=key+range_arg->max_length;
7728
key+= store_length, key_part++)
7731
store_length= key_part->store_length;
7732
if (key_part->null_bit)
7736
if (!key_part->field->is_null())
7740
else if (key_part->field->is_null())
7742
key++; // Skip null byte
7745
if ((cmp=key_part->field->key_cmp(key, key_part->length)) < 0)
7750
return (range_arg->flag & NEAR_MAX) ? 1 : 0; // Exact match
7755
Returns 0 if found key is inside range (found key >= range->min_key).
7758
int optimizer::QUICK_RANGE_SELECT::cmp_prev(optimizer::QUICK_RANGE *range_arg)
7761
if (range_arg->flag & NO_MIN_RANGE)
7762
return 0; /* key can't be to small */
7764
cmp= key_cmp(key_part_info, range_arg->min_key,
7765
range_arg->min_length);
7766
if (cmp > 0 || (cmp == 0 && (range_arg->flag & NEAR_MIN) == false))
7768
return 1; // outside of range
7773
* true if this range will require using HA_READ_AFTER_KEY
7774
See comment in get_next() about this
7777
bool optimizer::QUICK_SELECT_DESC::range_reads_after_key(optimizer::QUICK_RANGE *range_arg)
7779
return ((range_arg->flag & (NO_MAX_RANGE | NEAR_MAX)) ||
7780
!(range_arg->flag & EQ_RANGE) ||
7781
head->key_info[index].key_length != range_arg->max_length) ? 1 : 0;
7785
void optimizer::QUICK_RANGE_SELECT::add_info_string(String *str)
7787
KEY *key_info= head->key_info + index;
7788
str->append(key_info->name);
7791
void optimizer::QUICK_INDEX_MERGE_SELECT::add_info_string(String *str)
7793
optimizer::QUICK_RANGE_SELECT *quick;
7795
List_iterator_fast<optimizer::QUICK_RANGE_SELECT> it(quick_selects);
7796
str->append(STRING_WITH_LEN("sort_union("));
7797
while ((quick= it++))
7803
quick->add_info_string(str);
7805
if (pk_quick_select)
7808
pk_quick_select->add_info_string(str);
7813
5847
void optimizer::QUICK_ROR_INTERSECT_SELECT::add_info_string(String *str)
7815
5849
bool first= true;
7816
optimizer::QUICK_RANGE_SELECT *quick;
7817
List_iterator_fast<optimizer::QUICK_RANGE_SELECT> it(quick_selects);
5850
optimizer::QuickRangeSelect *quick;
5851
List_iterator_fast<optimizer::QuickRangeSelect> it(quick_selects);
7818
5852
str->append(STRING_WITH_LEN("intersect("));
7819
5853
while ((quick= it++))
7821
5855
KEY *key_info= head->key_info + quick->index;
7823
5857
str->append(',');