mySQL 5.0.11 sources for tomato
[tomato.git] / release / src / router / mysql / sql / opt_range.cc
blob3adf27539a5dbaa89afad27c649fd5abdee7ce05
1 /* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 of the License.
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
17 TODO:
18 Fix that MAYBE_KEY are stored in the tree so that we can detect use
19 of full hash keys for queries like:
21 select s.id, kws.keyword_id from sites as s,kws where s.id=kws.site_id and kws.keyword_id in (204,205);
26 This file contains:
28 RangeAnalysisModule
29 A module that accepts a condition, index (or partitioning) description,
30 and builds lists of intervals (in index/partitioning space), such that
31 all possible records that match the condition are contained within the
32 intervals.
33 The entry point for the range analysis module is get_mm_tree() function.
35 The lists are returned in form of complicated structure of interlinked
36 SEL_TREE/SEL_IMERGE/SEL_ARG objects.
37 See check_quick_keys, find_used_partitions for examples of how to walk
38 this structure.
39 All direct "users" of this module are located within this file, too.
42 PartitionPruningModule
43 A module that accepts a partitioned table, condition, and finds which
44 partitions we will need to use in query execution. Search down for
45 "PartitionPruningModule" for description.
46 The module has single entry point - prune_partitions() function.
49 Range/index_merge/groupby-minmax optimizer module
50 A module that accepts a table, condition, and returns
51 - a QUICK_*_SELECT object that can be used to retrieve rows that match
52 the specified condition, or a "no records will match the condition"
53 statement.
55 The module entry points are
56 test_quick_select()
57 get_quick_select_for_ref()
60 Record retrieval code for range/index_merge/groupby-min-max.
61 Implementations of QUICK_*_SELECT classes.
64 #ifdef USE_PRAGMA_IMPLEMENTATION
65 #pragma implementation // gcc: Class implementation
66 #endif
68 #include "mysql_priv.h"
69 #include <m_ctype.h>
70 #include "sql_select.h"
72 #ifndef EXTRA_DEBUG
73 #define test_rb_tree(A,B) {}
74 #define test_use_count(A) {}
75 #endif
78 Convert double value to #rows. Currently this does floor(), and we
79 might consider using round() instead.
81 #define double2rows(x) ((ha_rows)(x))
83 static int sel_cmp(Field *f,uchar *a,uchar *b,uint8 a_flag,uint8 b_flag);
85 static uchar is_null_string[2]= {1,0};
87 class RANGE_OPT_PARAM;
89 A construction block of the SEL_ARG-graph.
91 The following description only covers graphs of SEL_ARG objects with
92 sel_arg->type==KEY_RANGE:
94 One SEL_ARG object represents an "elementary interval" in form
96 min_value <=? table.keypartX <=? max_value
98 The interval is a non-empty interval of any kind: with[out] minimum/maximum
99 bound, [half]open/closed, single-point interval, etc.
101 1. SEL_ARG GRAPH STRUCTURE
103 SEL_ARG objects are linked together in a graph. The meaning of the graph
104 is better demostrated by an example:
106 tree->keys[i]
108 | $ $
109 | part=1 $ part=2 $ part=3
110 | $ $
111 | +-------+ $ +-------+ $ +--------+
112 | | kp1<1 |--$-->| kp2=5 |--$-->| kp3=10 |
113 | +-------+ $ +-------+ $ +--------+
114 | | $ $ |
115 | | $ $ +--------+
116 | | $ $ | kp3=12 |
117 | | $ $ +--------+
118 | +-------+ $ $
119 \->| kp1=2 |--$--------------$-+
120 +-------+ $ $ | +--------+
121 | $ $ ==>| kp3=11 |
122 +-------+ $ $ | +--------+
123 | kp1=3 |--$--------------$-+ |
124 +-------+ $ $ +--------+
125 | $ $ | kp3=14 |
126 ... $ $ +--------+
128 The entire graph is partitioned into "interval lists".
130 An interval list is a sequence of ordered disjoint intervals over the same
131 key part. SEL_ARG are linked via "next" and "prev" pointers. Additionally,
132 all intervals in the list form an RB-tree, linked via left/right/parent
133 pointers. The RB-tree root SEL_ARG object will be further called "root of the
134 interval list".
136 In the example pic, there are 4 interval lists:
137 "kp<1 OR kp1=2 OR kp1=3", "kp2=5", "kp3=10 OR kp3=12", "kp3=11 OR kp3=13".
138 The vertical lines represent SEL_ARG::next/prev pointers.
140 In an interval list, each member X may have SEL_ARG::next_key_part pointer
141 pointing to the root of another interval list Y. The pointed interval list
142 must cover a key part with greater number (i.e. Y->part > X->part).
144 In the example pic, the next_key_part pointers are represented by
145 horisontal lines.
147 2. SEL_ARG GRAPH SEMANTICS
149 It represents a condition in a special form (we don't have a name for it ATM)
150 The SEL_ARG::next/prev is "OR", and next_key_part is "AND".
152 For example, the picture represents the condition in form:
153 (kp1 < 1 AND kp2=5 AND (kp3=10 OR kp3=12)) OR
154 (kp1=2 AND (kp3=11 OR kp3=14)) OR
155 (kp1=3 AND (kp3=11 OR kp3=14))
158 3. SEL_ARG GRAPH USE
160 Use get_mm_tree() to construct SEL_ARG graph from WHERE condition.
161 Then walk the SEL_ARG graph and get a list of dijsoint ordered key
162 intervals (i.e. intervals in form
164 (constA1, .., const1_K) < (keypart1,.., keypartK) < (constB1, .., constB_K)
166 Those intervals can be used to access the index. The uses are in:
167 - check_quick_select() - Walk the SEL_ARG graph and find an estimate of
168 how many table records are contained within all
169 intervals.
170 - get_quick_select() - Walk the SEL_ARG, materialize the key intervals,
171 and create QUICK_RANGE_SELECT object that will
172 read records within these intervals.
174 4. SPACE COMPLEXITY NOTES
176 SEL_ARG graph is a representation of an ordered disjoint sequence of
177 intervals over the ordered set of index tuple values.
179 For multi-part keys, one can construct a WHERE expression such that its
180 list of intervals will be of combinatorial size. Here is an example:
182 (keypart1 IN (1,2, ..., n1)) AND
183 (keypart2 IN (1,2, ..., n2)) AND
184 (keypart3 IN (1,2, ..., n3))
186 For this WHERE clause the list of intervals will have n1*n2*n3 intervals
187 of form
189 (keypart1, keypart2, keypart3) = (k1, k2, k3), where 1 <= k{i} <= n{i}
191 SEL_ARG graph structure aims to reduce the amount of required space by
192 "sharing" the elementary intervals when possible (the pic at the
193 beginning of this comment has examples of such sharing). The sharing may
194 prevent combinatorial blowup:
196 There are WHERE clauses that have combinatorial-size interval lists but
197 will be represented by a compact SEL_ARG graph.
198 Example:
199 (keypartN IN (1,2, ..., n1)) AND
201 (keypart2 IN (1,2, ..., n2)) AND
202 (keypart1 IN (1,2, ..., n3))
204 but not in all cases:
206 - There are WHERE clauses that do have a compact SEL_ARG-graph
207 representation but get_mm_tree() and its callees will construct a
208 graph of combinatorial size.
209 Example:
210 (keypart1 IN (1,2, ..., n1)) AND
211 (keypart2 IN (1,2, ..., n2)) AND
213 (keypartN IN (1,2, ..., n3))
215 - There are WHERE clauses for which the minimal possible SEL_ARG graph
216 representation will have combinatorial size.
217 Example:
218 By induction: Let's take any interval on some keypart in the middle:
220 kp15=c0
222 Then let's AND it with this interval 'structure' from preceding and
223 following keyparts:
225 (kp14=c1 AND kp16=c3) OR keypart14=c2) (*)
227 We will obtain this SEL_ARG graph:
229 kp14 $ kp15 $ kp16
231 +---------+ $ +---------+ $ +---------+
232 | kp14=c1 |--$-->| kp15=c0 |--$-->| kp16=c3 |
233 +---------+ $ +---------+ $ +---------+
234 | $ $
235 +---------+ $ +---------+ $
236 | kp14=c2 |--$-->| kp15=c0 | $
237 +---------+ $ +---------+ $
240 Note that we had to duplicate "kp15=c0" and there was no way to avoid
241 that.
242 The induction step: AND the obtained expression with another "wrapping"
243 expression like (*).
244 When the process ends because of the limit on max. number of keyparts
245 we'll have:
247 WHERE clause length is O(3*#max_keyparts)
248 SEL_ARG graph size is O(2^(#max_keyparts/2))
250 (it is also possible to construct a case where instead of 2 in 2^n we
251 have a bigger constant, e.g. 4, and get a graph with 4^(31/2)= 2^31
252 nodes)
254 We avoid consuming too much memory by setting a limit on the number of
255 SEL_ARG object we can construct during one range analysis invocation.
258 class SEL_ARG :public Sql_alloc
260 public:
261 uint8 min_flag,max_flag,maybe_flag;
262 uint8 part; // Which key part
263 uint8 maybe_null;
265 Number of children of this element in the RB-tree, plus 1 for this
266 element itself.
268 uint16 elements;
270 Valid only for elements which are RB-tree roots: Number of times this
271 RB-tree is referred to (it is referred by SEL_ARG::next_key_part or by
272 SEL_TREE::keys[i] or by a temporary SEL_ARG* variable)
274 ulong use_count;
276 Field *field;
277 uchar *min_value,*max_value; // Pointer to range
280 eq_tree() requires that left == right == 0 if the type is MAYBE_KEY.
282 SEL_ARG *left,*right; /* R-B tree children */
283 SEL_ARG *next,*prev; /* Links for bi-directional interval list */
284 SEL_ARG *parent; /* R-B tree parent */
285 SEL_ARG *next_key_part;
286 enum leaf_color { BLACK,RED } color;
287 enum Type { IMPOSSIBLE, MAYBE, MAYBE_KEY, KEY_RANGE } type;
289 enum { MAX_SEL_ARGS = 16000 };
291 SEL_ARG() {}
292 SEL_ARG(SEL_ARG &);
293 SEL_ARG(Field *,const uchar *, const uchar *);
294 SEL_ARG(Field *field, uint8 part, uchar *min_value, uchar *max_value,
295 uint8 min_flag, uint8 max_flag, uint8 maybe_flag);
296 SEL_ARG(enum Type type_arg)
297 :min_flag(0),elements(1),use_count(1),left(0),right(0),next_key_part(0),
298 color(BLACK), type(type_arg)
300 inline bool is_same(SEL_ARG *arg)
302 if (type != arg->type || part != arg->part)
303 return 0;
304 if (type != KEY_RANGE)
305 return 1;
306 return cmp_min_to_min(arg) == 0 && cmp_max_to_max(arg) == 0;
308 inline void merge_flags(SEL_ARG *arg) { maybe_flag|=arg->maybe_flag; }
309 inline void maybe_smaller() { maybe_flag=1; }
310 /* Return true iff it's a single-point null interval */
311 inline bool is_null_interval() { return maybe_null && max_value[0] == 1; }
312 inline int cmp_min_to_min(SEL_ARG* arg)
314 return sel_cmp(field,min_value, arg->min_value, min_flag, arg->min_flag);
316 inline int cmp_min_to_max(SEL_ARG* arg)
318 return sel_cmp(field,min_value, arg->max_value, min_flag, arg->max_flag);
320 inline int cmp_max_to_max(SEL_ARG* arg)
322 return sel_cmp(field,max_value, arg->max_value, max_flag, arg->max_flag);
324 inline int cmp_max_to_min(SEL_ARG* arg)
326 return sel_cmp(field,max_value, arg->min_value, max_flag, arg->min_flag);
328 SEL_ARG *clone_and(SEL_ARG* arg)
329 { // Get overlapping range
330 uchar *new_min,*new_max;
331 uint8 flag_min,flag_max;
332 if (cmp_min_to_min(arg) >= 0)
334 new_min=min_value; flag_min=min_flag;
336 else
338 new_min=arg->min_value; flag_min=arg->min_flag; /* purecov: deadcode */
340 if (cmp_max_to_max(arg) <= 0)
342 new_max=max_value; flag_max=max_flag;
344 else
346 new_max=arg->max_value; flag_max=arg->max_flag;
348 return new SEL_ARG(field, part, new_min, new_max, flag_min, flag_max,
349 test(maybe_flag && arg->maybe_flag));
351 SEL_ARG *clone_first(SEL_ARG *arg)
352 { // min <= X < arg->min
353 return new SEL_ARG(field,part, min_value, arg->min_value,
354 min_flag, arg->min_flag & NEAR_MIN ? 0 : NEAR_MAX,
355 maybe_flag | arg->maybe_flag);
357 SEL_ARG *clone_last(SEL_ARG *arg)
358 { // min <= X <= key_max
359 return new SEL_ARG(field, part, min_value, arg->max_value,
360 min_flag, arg->max_flag, maybe_flag | arg->maybe_flag);
362 SEL_ARG *clone(RANGE_OPT_PARAM *param, SEL_ARG *new_parent, SEL_ARG **next);
364 bool copy_min(SEL_ARG* arg)
365 { // Get overlapping range
366 if (cmp_min_to_min(arg) > 0)
368 min_value=arg->min_value; min_flag=arg->min_flag;
369 if ((max_flag & (NO_MAX_RANGE | NO_MIN_RANGE)) ==
370 (NO_MAX_RANGE | NO_MIN_RANGE))
371 return 1; // Full range
373 maybe_flag|=arg->maybe_flag;
374 return 0;
376 bool copy_max(SEL_ARG* arg)
377 { // Get overlapping range
378 if (cmp_max_to_max(arg) <= 0)
380 max_value=arg->max_value; max_flag=arg->max_flag;
381 if ((max_flag & (NO_MAX_RANGE | NO_MIN_RANGE)) ==
382 (NO_MAX_RANGE | NO_MIN_RANGE))
383 return 1; // Full range
385 maybe_flag|=arg->maybe_flag;
386 return 0;
389 void copy_min_to_min(SEL_ARG *arg)
391 min_value=arg->min_value; min_flag=arg->min_flag;
393 void copy_min_to_max(SEL_ARG *arg)
395 max_value=arg->min_value;
396 max_flag=arg->min_flag & NEAR_MIN ? 0 : NEAR_MAX;
398 void copy_max_to_min(SEL_ARG *arg)
400 min_value=arg->max_value;
401 min_flag=arg->max_flag & NEAR_MAX ? 0 : NEAR_MIN;
403 /* returns a number of keypart values (0 or 1) appended to the key buffer */
404 int store_min(uint length, uchar **min_key,uint min_key_flag)
406 if ((min_flag & GEOM_FLAG) ||
407 (!(min_flag & NO_MIN_RANGE) &&
408 !(min_key_flag & (NO_MIN_RANGE | NEAR_MIN))))
410 if (maybe_null && *min_value)
412 **min_key=1;
413 bzero(*min_key+1,length-1);
415 else
416 memcpy(*min_key,min_value,length);
417 (*min_key)+= length;
418 return 1;
420 return 0;
422 /* returns a number of keypart values (0 or 1) appended to the key buffer */
423 int store_max(uint length, uchar **max_key, uint max_key_flag)
425 if (!(max_flag & NO_MAX_RANGE) &&
426 !(max_key_flag & (NO_MAX_RANGE | NEAR_MAX)))
428 if (maybe_null && *max_value)
430 **max_key=1;
431 bzero(*max_key+1,length-1);
433 else
434 memcpy(*max_key,max_value,length);
435 (*max_key)+= length;
436 return 1;
438 return 0;
441 /* returns a number of keypart values appended to the key buffer */
442 int store_min_key(KEY_PART *key, uchar **range_key, uint *range_key_flag)
444 SEL_ARG *key_tree= first();
445 uint res= key_tree->store_min(key[key_tree->part].store_length,
446 range_key, *range_key_flag);
447 *range_key_flag|= key_tree->min_flag;
448 if (key_tree->next_key_part &&
449 key_tree->next_key_part->type == SEL_ARG::KEY_RANGE &&
450 key_tree->next_key_part->part == key_tree->part+1 &&
451 !(*range_key_flag & (NO_MIN_RANGE | NEAR_MIN)))
452 res+= key_tree->next_key_part->store_min_key(key, range_key,
453 range_key_flag);
454 return res;
457 /* returns a number of keypart values appended to the key buffer */
458 int store_max_key(KEY_PART *key, uchar **range_key, uint *range_key_flag)
460 SEL_ARG *key_tree= last();
461 uint res=key_tree->store_max(key[key_tree->part].store_length,
462 range_key, *range_key_flag);
463 (*range_key_flag)|= key_tree->max_flag;
464 if (key_tree->next_key_part &&
465 key_tree->next_key_part->type == SEL_ARG::KEY_RANGE &&
466 key_tree->next_key_part->part == key_tree->part+1 &&
467 !(*range_key_flag & (NO_MAX_RANGE | NEAR_MAX)))
468 res+= key_tree->next_key_part->store_max_key(key, range_key,
469 range_key_flag);
470 return res;
473 SEL_ARG *insert(SEL_ARG *key);
474 SEL_ARG *tree_delete(SEL_ARG *key);
475 SEL_ARG *find_range(SEL_ARG *key);
476 SEL_ARG *rb_insert(SEL_ARG *leaf);
477 friend SEL_ARG *rb_delete_fixup(SEL_ARG *root,SEL_ARG *key, SEL_ARG *par);
478 #ifdef EXTRA_DEBUG
479 friend int test_rb_tree(SEL_ARG *element,SEL_ARG *parent);
480 void test_use_count(SEL_ARG *root);
481 #endif
482 SEL_ARG *first();
483 SEL_ARG *last();
484 void make_root();
485 inline bool simple_key()
487 return !next_key_part && elements == 1;
489 void increment_use_count(long count)
491 if (next_key_part)
493 next_key_part->use_count+=count;
494 count*= (next_key_part->use_count-count);
495 for (SEL_ARG *pos=next_key_part->first(); pos ; pos=pos->next)
496 if (pos->next_key_part)
497 pos->increment_use_count(count);
500 void free_tree()
502 for (SEL_ARG *pos=first(); pos ; pos=pos->next)
503 if (pos->next_key_part)
505 pos->next_key_part->use_count--;
506 pos->next_key_part->free_tree();
510 inline SEL_ARG **parent_ptr()
512 return parent->left == this ? &parent->left : &parent->right;
517 Check if this SEL_ARG object represents a single-point interval
519 SYNOPSIS
520 is_singlepoint()
522 DESCRIPTION
523 Check if this SEL_ARG object (not tree) represents a single-point
524 interval, i.e. if it represents a "keypart = const" or
525 "keypart IS NULL".
527 RETURN
528 TRUE This SEL_ARG object represents a singlepoint interval
529 FALSE Otherwise
532 bool is_singlepoint()
535 Check for NEAR_MIN ("strictly less") and NO_MIN_RANGE (-inf < field)
536 flags, and the same for right edge.
538 if (min_flag || max_flag)
539 return FALSE;
540 uchar *min_val= min_value;
541 uchar *max_val= max_value;
543 if (maybe_null)
545 /* First byte is a NULL value indicator */
546 if (*min_val != *max_val)
547 return FALSE;
549 if (*min_val)
550 return TRUE; /* This "x IS NULL" */
551 min_val++;
552 max_val++;
554 return !field->key_cmp(min_val, max_val);
556 SEL_ARG *clone_tree(RANGE_OPT_PARAM *param);
559 class SEL_IMERGE;
562 class SEL_TREE :public Sql_alloc
564 public:
566 Starting an effort to document this field:
567 (for some i, keys[i]->type == SEL_ARG::IMPOSSIBLE) =>
568 (type == SEL_TREE::IMPOSSIBLE)
570 enum Type { IMPOSSIBLE, ALWAYS, MAYBE, KEY, KEY_SMALLER } type;
571 SEL_TREE(enum Type type_arg) :type(type_arg) {}
572 SEL_TREE() :type(KEY)
574 keys_map.clear_all();
575 bzero((char*) keys,sizeof(keys));
577 SEL_TREE(SEL_TREE *arg, RANGE_OPT_PARAM *param);
579 Note: there may exist SEL_TREE objects with sel_tree->type=KEY and
580 keys[i]=0 for all i. (SergeyP: it is not clear whether there is any
581 merit in range analyzer functions (e.g. get_mm_parts) returning a
582 pointer to such SEL_TREE instead of NULL)
584 SEL_ARG *keys[MAX_KEY];
585 key_map keys_map; /* bitmask of non-NULL elements in keys */
588 Possible ways to read rows using index_merge. The list is non-empty only
589 if type==KEY. Currently can be non empty only if keys_map.is_clear_all().
591 List<SEL_IMERGE> merges;
593 /* The members below are filled/used only after get_mm_tree is done */
594 key_map ror_scans_map; /* bitmask of ROR scan-able elements in keys */
595 uint n_ror_scans; /* number of set bits in ror_scans_map */
597 struct st_ror_scan_info **ror_scans; /* list of ROR key scans */
598 struct st_ror_scan_info **ror_scans_end; /* last ROR scan */
599 /* Note that #records for each key scan is stored in table->quick_rows */
602 class RANGE_OPT_PARAM
604 public:
605 THD *thd; /* Current thread handle */
606 TABLE *table; /* Table being analyzed */
607 COND *cond; /* Used inside get_mm_tree(). */
608 table_map prev_tables;
609 table_map read_tables;
610 table_map current_table; /* Bit of the table being analyzed */
612 /* Array of parts of all keys for which range analysis is performed */
613 KEY_PART *key_parts;
614 KEY_PART *key_parts_end;
615 MEM_ROOT *mem_root; /* Memory that will be freed when range analysis completes */
616 MEM_ROOT *old_root; /* Memory that will last until the query end */
618 Number of indexes used in range analysis (In SEL_TREE::keys only first
619 #keys elements are not empty)
621 uint keys;
624 If true, the index descriptions describe real indexes (and it is ok to
625 call field->optimize_range(real_keynr[...], ...).
626 Otherwise index description describes fake indexes.
628 bool using_real_indexes;
630 bool remove_jump_scans;
633 used_key_no -> table_key_no translation table. Only makes sense if
634 using_real_indexes==TRUE
636 uint real_keynr[MAX_KEY];
637 /* Number of SEL_ARG objects allocated by SEL_ARG::clone_tree operations */
638 uint alloced_sel_args;
641 class PARAM : public RANGE_OPT_PARAM
643 public:
644 KEY_PART *key[MAX_KEY]; /* First key parts of keys used in the query */
645 longlong baseflag;
646 uint max_key_part, range_count;
648 uchar min_key[MAX_KEY_LENGTH+MAX_FIELD_WIDTH],
649 max_key[MAX_KEY_LENGTH+MAX_FIELD_WIDTH];
650 bool quick; // Don't calulate possible keys
652 uint fields_bitmap_size;
653 MY_BITMAP needed_fields; /* bitmask of fields needed by the query */
654 MY_BITMAP tmp_covered_fields;
656 key_map *needed_reg; /* ptr to SQL_SELECT::needed_reg */
658 uint *imerge_cost_buff; /* buffer for index_merge cost estimates */
659 uint imerge_cost_buff_size; /* size of the buffer */
661 /* TRUE if last checked tree->key can be used for ROR-scan */
662 bool is_ror_scan;
663 /* Number of ranges in the last checked tree->key */
664 uint n_ranges;
665 uint8 first_null_comp; /* first null component if any, 0 - otherwise */
668 class TABLE_READ_PLAN;
669 class TRP_RANGE;
670 class TRP_ROR_INTERSECT;
671 class TRP_ROR_UNION;
672 class TRP_ROR_INDEX_MERGE;
673 class TRP_GROUP_MIN_MAX;
675 struct st_ror_scan_info;
677 static SEL_TREE * get_mm_parts(RANGE_OPT_PARAM *param,COND *cond_func,Field *field,
678 Item_func::Functype type,Item *value,
679 Item_result cmp_type);
680 static SEL_ARG *get_mm_leaf(RANGE_OPT_PARAM *param,COND *cond_func,Field *field,
681 KEY_PART *key_part,
682 Item_func::Functype type,Item *value);
683 static SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param,COND *cond);
685 static bool is_key_scan_ror(PARAM *param, uint keynr, uint8 nparts);
686 static ha_rows check_quick_select(PARAM *param,uint index,SEL_ARG *key_tree,
687 bool update_tbl_stats);
688 static ha_rows check_quick_keys(PARAM *param,uint index,SEL_ARG *key_tree,
689 uchar *min_key, uint min_key_flag, int,
690 uchar *max_key, uint max_key_flag, int);
692 QUICK_RANGE_SELECT *get_quick_select(PARAM *param,uint index,
693 SEL_ARG *key_tree,
694 MEM_ROOT *alloc = NULL);
695 static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
696 bool index_read_must_be_used,
697 bool update_tbl_stats,
698 double read_time);
699 static
700 TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree,
701 double read_time,
702 bool *are_all_covering);
703 static
704 TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param,
705 SEL_TREE *tree,
706 double read_time);
707 static
708 TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
709 double read_time);
710 static
711 TRP_GROUP_MIN_MAX *get_best_group_min_max(PARAM *param, SEL_TREE *tree);
712 static double get_index_only_read_time(const PARAM* param, ha_rows records,
713 int keynr);
715 #ifndef DBUG_OFF
716 static void print_sel_tree(PARAM *param, SEL_TREE *tree, key_map *tree_map,
717 const char *msg);
718 static void print_ror_scans_arr(TABLE *table, const char *msg,
719 struct st_ror_scan_info **start,
720 struct st_ror_scan_info **end);
721 static void print_quick(QUICK_SELECT_I *quick, const key_map *needed_reg);
722 #endif
724 static SEL_TREE *tree_and(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2);
725 static SEL_TREE *tree_or(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2);
726 static SEL_ARG *sel_add(SEL_ARG *key1,SEL_ARG *key2);
727 static SEL_ARG *key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2);
728 static SEL_ARG *key_and(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2,
729 uint clone_flag);
730 static bool get_range(SEL_ARG **e1,SEL_ARG **e2,SEL_ARG *root1);
731 bool get_quick_keys(PARAM *param,QUICK_RANGE_SELECT *quick,KEY_PART *key,
732 SEL_ARG *key_tree, uchar *min_key,uint min_key_flag,
733 uchar *max_key,uint max_key_flag);
734 static bool eq_tree(SEL_ARG* a,SEL_ARG *b);
736 static SEL_ARG null_element(SEL_ARG::IMPOSSIBLE);
737 static bool null_part_in_key(KEY_PART *key_part, const uchar *key,
738 uint length);
739 bool sel_trees_can_be_ored(SEL_TREE *tree1, SEL_TREE *tree2, RANGE_OPT_PARAM* param);
743 SEL_IMERGE is a list of possible ways to do index merge, i.e. it is
744 a condition in the following form:
745 (t_1||t_2||...||t_N) && (next)
747 where all t_i are SEL_TREEs, next is another SEL_IMERGE and no pair
748 (t_i,t_j) contains SEL_ARGS for the same index.
750 SEL_TREE contained in SEL_IMERGE always has merges=NULL.
752 This class relies on memory manager to do the cleanup.
755 class SEL_IMERGE : public Sql_alloc
757 enum { PREALLOCED_TREES= 10};
758 public:
759 SEL_TREE *trees_prealloced[PREALLOCED_TREES];
760 SEL_TREE **trees; /* trees used to do index_merge */
761 SEL_TREE **trees_next; /* last of these trees */
762 SEL_TREE **trees_end; /* end of allocated space */
764 SEL_ARG ***best_keys; /* best keys to read in SEL_TREEs */
766 SEL_IMERGE() :
767 trees(&trees_prealloced[0]),
768 trees_next(trees),
769 trees_end(trees + PREALLOCED_TREES)
771 SEL_IMERGE (SEL_IMERGE *arg, RANGE_OPT_PARAM *param);
772 int or_sel_tree(RANGE_OPT_PARAM *param, SEL_TREE *tree);
773 int or_sel_tree_with_checks(RANGE_OPT_PARAM *param, SEL_TREE *new_tree);
774 int or_sel_imerge_with_checks(RANGE_OPT_PARAM *param, SEL_IMERGE* imerge);
779 Add SEL_TREE to this index_merge without any checks,
781 NOTES
782 This function implements the following:
783 (x_1||...||x_N) || t = (x_1||...||x_N||t), where x_i, t are SEL_TREEs
785 RETURN
786 0 - OK
787 -1 - Out of memory.
790 int SEL_IMERGE::or_sel_tree(RANGE_OPT_PARAM *param, SEL_TREE *tree)
792 if (trees_next == trees_end)
794 const int realloc_ratio= 2; /* Double size for next round */
795 uint old_elements= (trees_end - trees);
796 uint old_size= sizeof(SEL_TREE**) * old_elements;
797 uint new_size= old_size * realloc_ratio;
798 SEL_TREE **new_trees;
799 if (!(new_trees= (SEL_TREE**)alloc_root(param->mem_root, new_size)))
800 return -1;
801 memcpy(new_trees, trees, old_size);
802 trees= new_trees;
803 trees_next= trees + old_elements;
804 trees_end= trees + old_elements * realloc_ratio;
806 *(trees_next++)= tree;
807 return 0;
812 Perform OR operation on this SEL_IMERGE and supplied SEL_TREE new_tree,
813 combining new_tree with one of the trees in this SEL_IMERGE if they both
814 have SEL_ARGs for the same key.
816 SYNOPSIS
817 or_sel_tree_with_checks()
818 param PARAM from SQL_SELECT::test_quick_select
819 new_tree SEL_TREE with type KEY or KEY_SMALLER.
821 NOTES
822 This does the following:
823 (t_1||...||t_k)||new_tree =
824 either
825 = (t_1||...||t_k||new_tree)
827 = (t_1||....||(t_j|| new_tree)||...||t_k),
829 where t_i, y are SEL_TREEs.
830 new_tree is combined with the first t_j it has a SEL_ARG on common
831 key with. As a consequence of this, choice of keys to do index_merge
832 read may depend on the order of conditions in WHERE part of the query.
834 RETURN
835 0 OK
836 1 One of the trees was combined with new_tree to SEL_TREE::ALWAYS,
837 and (*this) should be discarded.
838 -1 An error occurred.
841 int SEL_IMERGE::or_sel_tree_with_checks(RANGE_OPT_PARAM *param, SEL_TREE *new_tree)
843 for (SEL_TREE** tree = trees;
844 tree != trees_next;
845 tree++)
847 if (sel_trees_can_be_ored(*tree, new_tree, param))
849 *tree = tree_or(param, *tree, new_tree);
850 if (!*tree)
851 return 1;
852 if (((*tree)->type == SEL_TREE::MAYBE) ||
853 ((*tree)->type == SEL_TREE::ALWAYS))
854 return 1;
855 /* SEL_TREE::IMPOSSIBLE is impossible here */
856 return 0;
860 /* New tree cannot be combined with any of existing trees. */
861 return or_sel_tree(param, new_tree);
866 Perform OR operation on this index_merge and supplied index_merge list.
868 RETURN
869 0 - OK
870 1 - One of conditions in result is always TRUE and this SEL_IMERGE
871 should be discarded.
872 -1 - An error occurred
875 int SEL_IMERGE::or_sel_imerge_with_checks(RANGE_OPT_PARAM *param, SEL_IMERGE* imerge)
877 for (SEL_TREE** tree= imerge->trees;
878 tree != imerge->trees_next;
879 tree++)
881 if (or_sel_tree_with_checks(param, *tree))
882 return 1;
884 return 0;
888 SEL_TREE::SEL_TREE(SEL_TREE *arg, RANGE_OPT_PARAM *param): Sql_alloc()
890 keys_map= arg->keys_map;
891 type= arg->type;
892 for (int idx= 0; idx < MAX_KEY; idx++)
894 if ((keys[idx]= arg->keys[idx]))
895 keys[idx]->increment_use_count(1);
898 List_iterator<SEL_IMERGE> it(arg->merges);
899 for (SEL_IMERGE *el= it++; el; el= it++)
901 SEL_IMERGE *merge= new SEL_IMERGE(el, param);
902 if (!merge || merge->trees == merge->trees_next)
904 merges.empty();
905 return;
907 merges.push_back (merge);
912 SEL_IMERGE::SEL_IMERGE (SEL_IMERGE *arg, RANGE_OPT_PARAM *param) : Sql_alloc()
914 uint elements= (arg->trees_end - arg->trees);
915 if (elements > PREALLOCED_TREES)
917 uint size= elements * sizeof (SEL_TREE **);
918 if (!(trees= (SEL_TREE **)alloc_root(param->mem_root, size)))
919 goto mem_err;
921 else
922 trees= &trees_prealloced[0];
924 trees_next= trees;
925 trees_end= trees + elements;
927 for (SEL_TREE **tree = trees, **arg_tree= arg->trees; tree < trees_end;
928 tree++, arg_tree++)
930 if (!(*tree= new SEL_TREE(*arg_tree, param)))
931 goto mem_err;
934 return;
936 mem_err:
937 trees= &trees_prealloced[0];
938 trees_next= trees;
939 trees_end= trees;
944 Perform AND operation on two index_merge lists and store result in *im1.
947 inline void imerge_list_and_list(List<SEL_IMERGE> *im1, List<SEL_IMERGE> *im2)
949 im1->concat(im2);
954 Perform OR operation on 2 index_merge lists, storing result in first list.
956 NOTES
957 The following conversion is implemented:
958 (a_1 &&...&& a_N)||(b_1 &&...&& b_K) = AND_i,j(a_i || b_j) =>
959 => (a_1||b_1).
961 i.e. all conjuncts except the first one are currently dropped.
962 This is done to avoid producing N*K ways to do index_merge.
964 If (a_1||b_1) produce a condition that is always TRUE, NULL is returned
965 and index_merge is discarded (while it is actually possible to try
966 harder).
968 As a consequence of this, choice of keys to do index_merge read may depend
969 on the order of conditions in WHERE part of the query.
971 RETURN
972 0 OK, result is stored in *im1
973 other Error, both passed lists are unusable
976 int imerge_list_or_list(RANGE_OPT_PARAM *param,
977 List<SEL_IMERGE> *im1,
978 List<SEL_IMERGE> *im2)
980 SEL_IMERGE *imerge= im1->head();
981 im1->empty();
982 im1->push_back(imerge);
984 return imerge->or_sel_imerge_with_checks(param, im2->head());
989 Perform OR operation on index_merge list and key tree.
991 RETURN
992 0 OK, result is stored in *im1.
993 other Error
996 int imerge_list_or_tree(RANGE_OPT_PARAM *param,
997 List<SEL_IMERGE> *im1,
998 SEL_TREE *tree)
1000 SEL_IMERGE *imerge;
1001 List_iterator<SEL_IMERGE> it(*im1);
1002 bool tree_used= FALSE;
1003 while ((imerge= it++))
1005 SEL_TREE *or_tree;
1006 if (tree_used)
1008 or_tree= new SEL_TREE (tree, param);
1009 if (!or_tree ||
1010 (or_tree->keys_map.is_clear_all() && or_tree->merges.is_empty()))
1011 return FALSE;
1013 else
1014 or_tree= tree;
1016 if (imerge->or_sel_tree_with_checks(param, or_tree))
1017 it.remove();
1018 tree_used= TRUE;
1020 return im1->is_empty();
1024 /***************************************************************************
1025 ** Basic functions for SQL_SELECT and QUICK_RANGE_SELECT
1026 ***************************************************************************/
1028 /* make a select from mysql info
1029 Error is set as following:
1030 0 = ok
1031 1 = Got some error (out of memory?)
1034 SQL_SELECT *make_select(TABLE *head, table_map const_tables,
1035 table_map read_tables, COND *conds,
1036 bool allow_null_cond,
1037 int *error)
1039 SQL_SELECT *select;
1040 DBUG_ENTER("make_select");
1042 *error=0;
1044 if (!conds && !allow_null_cond)
1045 DBUG_RETURN(0);
1046 if (!(select= new SQL_SELECT))
1048 *error= 1; // out of memory
1049 DBUG_RETURN(0); /* purecov: inspected */
1051 select->read_tables=read_tables;
1052 select->const_tables=const_tables;
1053 select->head=head;
1054 select->cond=conds;
1056 if (head->sort.io_cache)
1058 select->file= *head->sort.io_cache;
1059 select->records=(ha_rows) (select->file.end_of_file/
1060 head->file->ref_length);
1061 my_free(head->sort.io_cache, MYF(0));
1062 head->sort.io_cache=0;
1064 DBUG_RETURN(select);
1068 SQL_SELECT::SQL_SELECT() :quick(0),cond(0),free_cond(0)
1070 quick_keys.clear_all(); needed_reg.clear_all();
1071 my_b_clear(&file);
1075 void SQL_SELECT::cleanup()
1077 delete quick;
1078 quick= 0;
1079 if (free_cond)
1081 free_cond=0;
1082 delete cond;
1083 cond= 0;
1085 close_cached_file(&file);
1089 SQL_SELECT::~SQL_SELECT()
1091 cleanup();
1094 #undef index // Fix for Unixware 7
1096 QUICK_SELECT_I::QUICK_SELECT_I()
1097 :max_used_key_length(0),
1098 used_key_parts(0)
1101 QUICK_RANGE_SELECT::QUICK_RANGE_SELECT(THD *thd, TABLE *table, uint key_nr,
1102 bool no_alloc, MEM_ROOT *parent_alloc)
1103 :dont_free(0),error(0),free_file(0),in_range(0),cur_range(NULL),last_range(0)
1105 my_bitmap_map *bitmap;
1106 DBUG_ENTER("QUICK_RANGE_SELECT::QUICK_RANGE_SELECT");
1108 in_ror_merged_scan= 0;
1109 sorted= 0;
1110 index= key_nr;
1111 head= table;
1112 key_part_info= head->key_info[index].key_part;
1113 my_init_dynamic_array(&ranges, sizeof(QUICK_RANGE*), 16, 16);
1115 /* 'thd' is not accessible in QUICK_RANGE_SELECT::reset(). */
1116 multi_range_bufsiz= thd->variables.read_rnd_buff_size;
1117 multi_range_count= thd->variables.multi_range_count;
1118 multi_range_length= 0;
1119 multi_range= NULL;
1120 multi_range_buff= NULL;
1122 if (!no_alloc && !parent_alloc)
1124 // Allocates everything through the internal memroot
1125 init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0);
1126 thd->mem_root= &alloc;
1128 else
1129 bzero((char*) &alloc,sizeof(alloc));
1130 file= head->file;
1131 record= head->record[0];
1132 save_read_set= head->read_set;
1133 save_write_set= head->write_set;
1135 /* Allocate a bitmap for used columns */
1136 if (!(bitmap= (my_bitmap_map*) my_malloc(head->s->column_bitmap_size,
1137 MYF(MY_WME))))
1139 column_bitmap.bitmap= 0;
1140 error= 1;
1142 else
1143 bitmap_init(&column_bitmap, bitmap, head->s->fields, FALSE);
1144 DBUG_VOID_RETURN;
1148 int QUICK_RANGE_SELECT::init()
1150 DBUG_ENTER("QUICK_RANGE_SELECT::init");
1152 if (file->inited != handler::NONE)
1153 file->ha_index_or_rnd_end();
1154 DBUG_RETURN(FALSE);
1158 void QUICK_RANGE_SELECT::range_end()
1160 if (file->inited != handler::NONE)
1161 file->ha_index_or_rnd_end();
1165 QUICK_RANGE_SELECT::~QUICK_RANGE_SELECT()
1167 DBUG_ENTER("QUICK_RANGE_SELECT::~QUICK_RANGE_SELECT");
1168 if (!dont_free)
1170 /* file is NULL for CPK scan on covering ROR-intersection */
1171 if (file)
1173 range_end();
1174 head->set_keyread(FALSE);
1175 if (free_file)
1177 DBUG_PRINT("info", ("Freeing separate handler 0x%lx (free: %d)", (long) file,
1178 free_file));
1179 file->ha_external_lock(current_thd, F_UNLCK);
1180 file->close();
1181 delete file;
1184 delete_dynamic(&ranges); /* ranges are allocated in alloc */
1185 free_root(&alloc,MYF(0));
1186 my_free((char*) column_bitmap.bitmap, MYF(MY_ALLOW_ZERO_PTR));
1188 head->column_bitmaps_set(save_read_set, save_write_set);
1189 x_free(multi_range);
1190 x_free(multi_range_buff);
1191 DBUG_VOID_RETURN;
1195 QUICK_INDEX_MERGE_SELECT::QUICK_INDEX_MERGE_SELECT(THD *thd_param,
1196 TABLE *table)
1197 :unique(NULL), pk_quick_select(NULL), thd(thd_param)
1199 DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::QUICK_INDEX_MERGE_SELECT");
1200 index= MAX_KEY;
1201 head= table;
1202 bzero(&read_record, sizeof(read_record));
1203 init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0);
1204 DBUG_VOID_RETURN;
1207 int QUICK_INDEX_MERGE_SELECT::init()
1209 DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::init");
1210 DBUG_RETURN(0);
1213 int QUICK_INDEX_MERGE_SELECT::reset()
1215 DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::reset");
1216 DBUG_RETURN(read_keys_and_merge());
1219 bool
1220 QUICK_INDEX_MERGE_SELECT::push_quick_back(QUICK_RANGE_SELECT *quick_sel_range)
1223 Save quick_select that does scan on clustered primary key as it will be
1224 processed separately.
1226 if (head->file->primary_key_is_clustered() &&
1227 quick_sel_range->index == head->s->primary_key)
1228 pk_quick_select= quick_sel_range;
1229 else
1230 return quick_selects.push_back(quick_sel_range);
1231 return 0;
1234 QUICK_INDEX_MERGE_SELECT::~QUICK_INDEX_MERGE_SELECT()
1236 List_iterator_fast<QUICK_RANGE_SELECT> quick_it(quick_selects);
1237 QUICK_RANGE_SELECT* quick;
1238 DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::~QUICK_INDEX_MERGE_SELECT");
1239 delete unique;
1240 quick_it.rewind();
1241 while ((quick= quick_it++))
1242 quick->file= NULL;
1243 quick_selects.delete_elements();
1244 delete pk_quick_select;
1245 /* It's ok to call the next two even if they are already deinitialized */
1246 end_read_record(&read_record);
1247 free_io_cache(head);
1248 free_root(&alloc,MYF(0));
1249 DBUG_VOID_RETURN;
1253 QUICK_ROR_INTERSECT_SELECT::QUICK_ROR_INTERSECT_SELECT(THD *thd_param,
1254 TABLE *table,
1255 bool retrieve_full_rows,
1256 MEM_ROOT *parent_alloc)
1257 : cpk_quick(NULL), thd(thd_param), need_to_fetch_row(retrieve_full_rows),
1258 scans_inited(FALSE)
1260 index= MAX_KEY;
1261 head= table;
1262 record= head->record[0];
1263 if (!parent_alloc)
1264 init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0);
1265 else
1266 bzero(&alloc, sizeof(MEM_ROOT));
1267 last_rowid= (uchar*) alloc_root(parent_alloc? parent_alloc : &alloc,
1268 head->file->ref_length);
1273 Do post-constructor initialization.
1274 SYNOPSIS
1275 QUICK_ROR_INTERSECT_SELECT::init()
1277 RETURN
1278 0 OK
1279 other Error code
1282 int QUICK_ROR_INTERSECT_SELECT::init()
1284 DBUG_ENTER("QUICK_ROR_INTERSECT_SELECT::init");
1285 /* Check if last_rowid was successfully allocated in ctor */
1286 DBUG_RETURN(!last_rowid);
1291 Initialize this quick select to be a ROR-merged scan.
1293 SYNOPSIS
1294 QUICK_RANGE_SELECT::init_ror_merged_scan()
1295 reuse_handler If TRUE, use head->file, otherwise create a separate
1296 handler object
1298 NOTES
1299 This function creates and prepares for subsequent use a separate handler
1300 object if it can't reuse head->file. The reason for this is that during
1301 ROR-merge several key scans are performed simultaneously, and a single
1302 handler is only capable of preserving context of a single key scan.
1304 In ROR-merge the quick select doing merge does full records retrieval,
1305 merged quick selects read only keys.
1307 RETURN
1308 0 ROR child scan initialized, ok to use.
1309 1 error
1312 int QUICK_RANGE_SELECT::init_ror_merged_scan(bool reuse_handler)
1314 handler *save_file= file, *org_file;
1315 THD *thd;
1316 DBUG_ENTER("QUICK_RANGE_SELECT::init_ror_merged_scan");
1318 in_ror_merged_scan= 1;
1319 if (reuse_handler)
1321 DBUG_PRINT("info", ("Reusing handler 0x%lx", (long) file));
1322 if (init() || reset())
1324 DBUG_RETURN(1);
1326 head->column_bitmaps_set(&column_bitmap, &column_bitmap);
1327 goto end;
1330 /* Create a separate handler object for this quick select */
1331 if (free_file)
1333 /* already have own 'handler' object. */
1334 DBUG_RETURN(0);
1337 thd= head->in_use;
1338 if (!(file= head->file->clone(head->s->normalized_path.str, thd->mem_root)))
1341 Manually set the error flag. Note: there seems to be quite a few
1342 places where a failure could cause the server to "hang" the client by
1343 sending no response to a query. ATM those are not real errors because
1344 the storage engine calls in question happen to never fail with the
1345 existing storage engines.
1347 my_error(ER_OUT_OF_RESOURCES, MYF(0)); /* purecov: inspected */
1348 /* Caller will free the memory */
1349 goto failure; /* purecov: inspected */
1352 head->column_bitmaps_set(&column_bitmap, &column_bitmap);
1354 if (file->ha_external_lock(thd, F_RDLCK))
1355 goto failure;
1357 if (init() || reset())
1359 file->ha_external_lock(thd, F_UNLCK);
1360 file->close();
1361 goto failure;
1363 free_file= TRUE;
1364 last_rowid= file->ref;
1366 end:
1368 We are only going to read key fields and call position() on 'file'
1369 The following sets head->tmp_set to only use this key and then updates
1370 head->read_set and head->write_set to use this bitmap.
1371 The now bitmap is stored in 'column_bitmap' which is used in ::get_next()
1373 org_file= head->file;
1374 head->file= file;
1375 /* We don't have to set 'head->keyread' here as the 'file' is unique */
1376 if (!head->no_keyread)
1377 head->mark_columns_used_by_index(index);
1378 head->prepare_for_position();
1379 head->file= org_file;
1380 bitmap_copy(&column_bitmap, head->read_set);
1381 head->column_bitmaps_set(&column_bitmap, &column_bitmap);
1383 DBUG_RETURN(0);
1385 failure:
1386 head->column_bitmaps_set(save_read_set, save_write_set);
1387 delete file;
1388 file= save_file;
1389 DBUG_RETURN(1);
1394 Initialize this quick select to be a part of a ROR-merged scan.
1395 SYNOPSIS
1396 QUICK_ROR_INTERSECT_SELECT::init_ror_merged_scan()
1397 reuse_handler If TRUE, use head->file, otherwise create separate
1398 handler object.
1399 RETURN
1400 0 OK
1401 other error code
1403 int QUICK_ROR_INTERSECT_SELECT::init_ror_merged_scan(bool reuse_handler)
1405 List_iterator_fast<QUICK_RANGE_SELECT> quick_it(quick_selects);
1406 QUICK_RANGE_SELECT* quick;
1407 DBUG_ENTER("QUICK_ROR_INTERSECT_SELECT::init_ror_merged_scan");
1409 /* Initialize all merged "children" quick selects */
1410 DBUG_ASSERT(!need_to_fetch_row || reuse_handler);
1411 if (!need_to_fetch_row && reuse_handler)
1413 quick= quick_it++;
1415 There is no use of this->file. Use it for the first of merged range
1416 selects.
1418 if (quick->init_ror_merged_scan(TRUE))
1419 DBUG_RETURN(1);
1420 quick->file->extra(HA_EXTRA_KEYREAD_PRESERVE_FIELDS);
1422 while ((quick= quick_it++))
1424 if (quick->init_ror_merged_scan(FALSE))
1425 DBUG_RETURN(1);
1426 quick->file->extra(HA_EXTRA_KEYREAD_PRESERVE_FIELDS);
1427 /* All merged scans share the same record buffer in intersection. */
1428 quick->record= head->record[0];
1431 if (need_to_fetch_row && head->file->ha_rnd_init(1))
1433 DBUG_PRINT("error", ("ROR index_merge rnd_init call failed"));
1434 DBUG_RETURN(1);
1436 DBUG_RETURN(0);
1441 Initialize quick select for row retrieval.
1442 SYNOPSIS
1443 reset()
1444 RETURN
1445 0 OK
1446 other Error code
1449 int QUICK_ROR_INTERSECT_SELECT::reset()
1451 DBUG_ENTER("QUICK_ROR_INTERSECT_SELECT::reset");
1452 if (!scans_inited && init_ror_merged_scan(TRUE))
1453 DBUG_RETURN(1);
1454 scans_inited= TRUE;
1455 List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
1456 QUICK_RANGE_SELECT *quick;
1457 while ((quick= it++))
1458 quick->reset();
1459 DBUG_RETURN(0);
1464 Add a merged quick select to this ROR-intersection quick select.
1466 SYNOPSIS
1467 QUICK_ROR_INTERSECT_SELECT::push_quick_back()
1468 quick Quick select to be added. The quick select must return
1469 rows in rowid order.
1470 NOTES
1471 This call can only be made before init() is called.
1473 RETURN
1474 FALSE OK
1475 TRUE Out of memory.
1478 bool
1479 QUICK_ROR_INTERSECT_SELECT::push_quick_back(QUICK_RANGE_SELECT *quick)
1481 return quick_selects.push_back(quick);
1484 QUICK_ROR_INTERSECT_SELECT::~QUICK_ROR_INTERSECT_SELECT()
1486 DBUG_ENTER("QUICK_ROR_INTERSECT_SELECT::~QUICK_ROR_INTERSECT_SELECT");
1487 quick_selects.delete_elements();
1488 delete cpk_quick;
1489 free_root(&alloc,MYF(0));
1490 if (need_to_fetch_row && head->file->inited != handler::NONE)
1491 head->file->ha_rnd_end();
1492 DBUG_VOID_RETURN;
1496 QUICK_ROR_UNION_SELECT::QUICK_ROR_UNION_SELECT(THD *thd_param,
1497 TABLE *table)
1498 : thd(thd_param), scans_inited(FALSE)
1500 index= MAX_KEY;
1501 head= table;
1502 rowid_length= table->file->ref_length;
1503 record= head->record[0];
1504 init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0);
1505 thd_param->mem_root= &alloc;
1510 Do post-constructor initialization.
1511 SYNOPSIS
1512 QUICK_ROR_UNION_SELECT::init()
1514 RETURN
1515 0 OK
1516 other Error code
1519 int QUICK_ROR_UNION_SELECT::init()
1521 DBUG_ENTER("QUICK_ROR_UNION_SELECT::init");
1522 if (init_queue(&queue, quick_selects.elements, 0,
1523 FALSE , QUICK_ROR_UNION_SELECT::queue_cmp,
1524 (void*) this))
1526 bzero(&queue, sizeof(QUEUE));
1527 DBUG_RETURN(1);
1530 if (!(cur_rowid= (uchar*) alloc_root(&alloc, 2*head->file->ref_length)))
1531 DBUG_RETURN(1);
1532 prev_rowid= cur_rowid + head->file->ref_length;
1533 DBUG_RETURN(0);
1538 Comparison function to be used QUICK_ROR_UNION_SELECT::queue priority
1539 queue.
1541 SYNPOSIS
1542 QUICK_ROR_UNION_SELECT::queue_cmp()
1543 arg Pointer to QUICK_ROR_UNION_SELECT
1544 val1 First merged select
1545 val2 Second merged select
1548 int QUICK_ROR_UNION_SELECT::queue_cmp(void *arg, uchar *val1, uchar *val2)
1550 QUICK_ROR_UNION_SELECT *self= (QUICK_ROR_UNION_SELECT*)arg;
1551 return self->head->file->cmp_ref(((QUICK_SELECT_I*)val1)->last_rowid,
1552 ((QUICK_SELECT_I*)val2)->last_rowid);
1557 Initialize quick select for row retrieval.
1558 SYNOPSIS
1559 reset()
1561 RETURN
1562 0 OK
1563 other Error code
1566 int QUICK_ROR_UNION_SELECT::reset()
1568 QUICK_SELECT_I *quick;
1569 int error;
1570 DBUG_ENTER("QUICK_ROR_UNION_SELECT::reset");
1571 have_prev_rowid= FALSE;
1572 if (!scans_inited)
1574 List_iterator_fast<QUICK_SELECT_I> it(quick_selects);
1575 while ((quick= it++))
1577 if (quick->init_ror_merged_scan(FALSE))
1578 DBUG_RETURN(1);
1580 scans_inited= TRUE;
1582 queue_remove_all(&queue);
1584 Initialize scans for merged quick selects and put all merged quick
1585 selects into the queue.
1587 List_iterator_fast<QUICK_SELECT_I> it(quick_selects);
1588 while ((quick= it++))
1590 if (quick->reset())
1591 DBUG_RETURN(1);
1592 if ((error= quick->get_next()))
1594 if (error == HA_ERR_END_OF_FILE)
1595 continue;
1596 DBUG_RETURN(error);
1598 quick->save_last_pos();
1599 queue_insert(&queue, (uchar*)quick);
1602 if (head->file->ha_rnd_init(1))
1604 DBUG_PRINT("error", ("ROR index_merge rnd_init call failed"));
1605 DBUG_RETURN(1);
1608 DBUG_RETURN(0);
1612 bool
1613 QUICK_ROR_UNION_SELECT::push_quick_back(QUICK_SELECT_I *quick_sel_range)
1615 return quick_selects.push_back(quick_sel_range);
1618 QUICK_ROR_UNION_SELECT::~QUICK_ROR_UNION_SELECT()
1620 DBUG_ENTER("QUICK_ROR_UNION_SELECT::~QUICK_ROR_UNION_SELECT");
1621 delete_queue(&queue);
1622 quick_selects.delete_elements();
1623 if (head->file->inited != handler::NONE)
1624 head->file->ha_rnd_end();
1625 free_root(&alloc,MYF(0));
1626 DBUG_VOID_RETURN;
1630 QUICK_RANGE::QUICK_RANGE()
1631 :min_key(0),max_key(0),min_length(0),max_length(0),
1632 flag(NO_MIN_RANGE | NO_MAX_RANGE),
1633 min_keypart_map(0), max_keypart_map(0)
1636 SEL_ARG::SEL_ARG(SEL_ARG &arg) :Sql_alloc()
1638 type=arg.type;
1639 min_flag=arg.min_flag;
1640 max_flag=arg.max_flag;
1641 maybe_flag=arg.maybe_flag;
1642 maybe_null=arg.maybe_null;
1643 part=arg.part;
1644 field=arg.field;
1645 min_value=arg.min_value;
1646 max_value=arg.max_value;
1647 next_key_part=arg.next_key_part;
1648 use_count=1; elements=1;
1652 inline void SEL_ARG::make_root()
1654 left=right= &null_element;
1655 color=BLACK;
1656 next=prev=0;
1657 use_count=0; elements=1;
1660 SEL_ARG::SEL_ARG(Field *f,const uchar *min_value_arg,
1661 const uchar *max_value_arg)
1662 :min_flag(0), max_flag(0), maybe_flag(0), maybe_null(f->real_maybe_null()),
1663 elements(1), use_count(1), field(f), min_value((uchar*) min_value_arg),
1664 max_value((uchar*) max_value_arg), next(0),prev(0),
1665 next_key_part(0),color(BLACK),type(KEY_RANGE)
1667 left=right= &null_element;
1670 SEL_ARG::SEL_ARG(Field *field_,uint8 part_,
1671 uchar *min_value_, uchar *max_value_,
1672 uint8 min_flag_,uint8 max_flag_,uint8 maybe_flag_)
1673 :min_flag(min_flag_),max_flag(max_flag_),maybe_flag(maybe_flag_),
1674 part(part_),maybe_null(field_->real_maybe_null()), elements(1),use_count(1),
1675 field(field_), min_value(min_value_), max_value(max_value_),
1676 next(0),prev(0),next_key_part(0),color(BLACK),type(KEY_RANGE)
1678 left=right= &null_element;
1681 SEL_ARG *SEL_ARG::clone(RANGE_OPT_PARAM *param, SEL_ARG *new_parent,
1682 SEL_ARG **next_arg)
1684 SEL_ARG *tmp;
1686 /* Bail out if we have already generated too many SEL_ARGs */
1687 if (++param->alloced_sel_args > MAX_SEL_ARGS)
1688 return 0;
1690 if (type != KEY_RANGE)
1692 if (!(tmp= new (param->mem_root) SEL_ARG(type)))
1693 return 0; // out of memory
1694 tmp->prev= *next_arg; // Link into next/prev chain
1695 (*next_arg)->next=tmp;
1696 (*next_arg)= tmp;
1697 tmp->part= this->part;
1699 else
1701 if (!(tmp= new (param->mem_root) SEL_ARG(field,part, min_value,max_value,
1702 min_flag, max_flag, maybe_flag)))
1703 return 0; // OOM
1704 tmp->parent=new_parent;
1705 tmp->next_key_part=next_key_part;
1706 if (left != &null_element)
1707 if (!(tmp->left=left->clone(param, tmp, next_arg)))
1708 return 0; // OOM
1710 tmp->prev= *next_arg; // Link into next/prev chain
1711 (*next_arg)->next=tmp;
1712 (*next_arg)= tmp;
1714 if (right != &null_element)
1715 if (!(tmp->right= right->clone(param, tmp, next_arg)))
1716 return 0; // OOM
1718 increment_use_count(1);
1719 tmp->color= color;
1720 tmp->elements= this->elements;
1721 return tmp;
1724 SEL_ARG *SEL_ARG::first()
1726 SEL_ARG *next_arg=this;
1727 if (!next_arg->left)
1728 return 0; // MAYBE_KEY
1729 while (next_arg->left != &null_element)
1730 next_arg=next_arg->left;
1731 return next_arg;
1734 SEL_ARG *SEL_ARG::last()
1736 SEL_ARG *next_arg=this;
1737 if (!next_arg->right)
1738 return 0; // MAYBE_KEY
1739 while (next_arg->right != &null_element)
1740 next_arg=next_arg->right;
1741 return next_arg;
1746 Check if a compare is ok, when one takes ranges in account
1747 Returns -2 or 2 if the ranges where 'joined' like < 2 and >= 2
1750 static int sel_cmp(Field *field, uchar *a, uchar *b, uint8 a_flag,
1751 uint8 b_flag)
1753 int cmp;
1754 /* First check if there was a compare to a min or max element */
1755 if (a_flag & (NO_MIN_RANGE | NO_MAX_RANGE))
1757 if ((a_flag & (NO_MIN_RANGE | NO_MAX_RANGE)) ==
1758 (b_flag & (NO_MIN_RANGE | NO_MAX_RANGE)))
1759 return 0;
1760 return (a_flag & NO_MIN_RANGE) ? -1 : 1;
1762 if (b_flag & (NO_MIN_RANGE | NO_MAX_RANGE))
1763 return (b_flag & NO_MIN_RANGE) ? 1 : -1;
1765 if (field->real_maybe_null()) // If null is part of key
1767 if (*a != *b)
1769 return *a ? -1 : 1;
1771 if (*a)
1772 goto end; // NULL where equal
1773 a++; b++; // Skip NULL marker
1775 cmp=field->key_cmp(a , b);
1776 if (cmp) return cmp < 0 ? -1 : 1; // The values differed
1778 // Check if the compared equal arguments was defined with open/closed range
1779 end:
1780 if (a_flag & (NEAR_MIN | NEAR_MAX))
1782 if ((a_flag & (NEAR_MIN | NEAR_MAX)) == (b_flag & (NEAR_MIN | NEAR_MAX)))
1783 return 0;
1784 if (!(b_flag & (NEAR_MIN | NEAR_MAX)))
1785 return (a_flag & NEAR_MIN) ? 2 : -2;
1786 return (a_flag & NEAR_MIN) ? 1 : -1;
1788 if (b_flag & (NEAR_MIN | NEAR_MAX))
1789 return (b_flag & NEAR_MIN) ? -2 : 2;
1790 return 0; // The elements where equal
1794 SEL_ARG *SEL_ARG::clone_tree(RANGE_OPT_PARAM *param)
1796 SEL_ARG tmp_link,*next_arg,*root;
1797 next_arg= &tmp_link;
1798 if (!(root= clone(param, (SEL_ARG *) 0, &next_arg)))
1799 return 0;
1800 next_arg->next=0; // Fix last link
1801 tmp_link.next->prev=0; // Fix first link
1802 if (root) // If not OOM
1803 root->use_count= 0;
1804 return root;
1809 Find the best index to retrieve first N records in given order
1811 SYNOPSIS
1812 get_index_for_order()
1813 table Table to be accessed
1814 order Required ordering
1815 limit Number of records that will be retrieved
1817 DESCRIPTION
1818 Find the best index that allows to retrieve first #limit records in the
1819 given order cheaper then one would retrieve them using full table scan.
1821 IMPLEMENTATION
1822 Run through all table indexes and find the shortest index that allows
1823 records to be retrieved in given order. We look for the shortest index
1824 as we will have fewer index pages to read with it.
1826 This function is used only by UPDATE/DELETE, so we take into account how
1827 the UPDATE/DELETE code will work:
1828 * index can only be scanned in forward direction
1829 * HA_EXTRA_KEYREAD will not be used
1830 Perhaps these assumptions could be relaxed.
1832 RETURN
1833 Number of the index that produces the required ordering in the cheapest way
1834 MAX_KEY if no such index was found.
1837 uint get_index_for_order(TABLE *table, ORDER *order, ha_rows limit)
1839 uint idx;
1840 uint match_key= MAX_KEY, match_key_len= MAX_KEY_LENGTH + 1;
1841 ORDER *ord;
1843 for (ord= order; ord; ord= ord->next)
1844 if (!ord->asc)
1845 return MAX_KEY;
1847 for (idx= 0; idx < table->s->keys; idx++)
1849 if (!(table->keys_in_use_for_query.is_set(idx)))
1850 continue;
1851 KEY_PART_INFO *keyinfo= table->key_info[idx].key_part;
1852 uint n_parts= table->key_info[idx].key_parts;
1853 uint partno= 0;
1856 The below check is sufficient considering we now have either BTREE
1857 indexes (records are returned in order for any index prefix) or HASH
1858 indexes (records are not returned in order for any index prefix).
1860 if (!(table->file->index_flags(idx, 0, 1) & HA_READ_ORDER))
1861 continue;
1862 for (ord= order; ord && partno < n_parts; ord= ord->next, partno++)
1864 Item *item= order->item[0];
1865 if (!(item->type() == Item::FIELD_ITEM &&
1866 ((Item_field*)item)->field->eq(keyinfo[partno].field)))
1867 break;
1870 if (!ord && table->key_info[idx].key_length < match_key_len)
1873 Ok, the ordering is compatible and this key is shorter then
1874 previous match (we want shorter keys as we'll have to read fewer
1875 index pages for the same number of records)
1877 match_key= idx;
1878 match_key_len= table->key_info[idx].key_length;
1882 if (match_key != MAX_KEY)
1885 Found an index that allows records to be retrieved in the requested
1886 order. Now we'll check if using the index is cheaper then doing a table
1887 scan.
1889 double full_scan_time= table->file->scan_time();
1890 double index_scan_time= table->file->read_time(match_key, 1, limit);
1891 if (index_scan_time > full_scan_time)
1892 match_key= MAX_KEY;
1894 return match_key;
1899 Table rows retrieval plan. Range optimizer creates QUICK_SELECT_I-derived
1900 objects from table read plans.
1902 class TABLE_READ_PLAN
1904 public:
1906 Plan read cost, with or without cost of full row retrieval, depending
1907 on plan creation parameters.
1909 double read_cost;
1910 ha_rows records; /* estimate of #rows to be examined */
1913 If TRUE, the scan returns rows in rowid order. This is used only for
1914 scans that can be both ROR and non-ROR.
1916 bool is_ror;
1919 Create quick select for this plan.
1920 SYNOPSIS
1921 make_quick()
1922 param Parameter from test_quick_select
1923 retrieve_full_rows If TRUE, created quick select will do full record
1924 retrieval.
1925 parent_alloc Memory pool to use, if any.
1927 NOTES
1928 retrieve_full_rows is ignored by some implementations.
1930 RETURN
1931 created quick select
1932 NULL on any error.
1934 virtual QUICK_SELECT_I *make_quick(PARAM *param,
1935 bool retrieve_full_rows,
1936 MEM_ROOT *parent_alloc=NULL) = 0;
1938 /* Table read plans are allocated on MEM_ROOT and are never deleted */
1939 static void *operator new(size_t size, MEM_ROOT *mem_root)
1940 { return (void*) alloc_root(mem_root, (uint) size); }
1941 static void operator delete(void *ptr,size_t size) { TRASH(ptr, size); }
1942 static void operator delete(void *ptr, MEM_ROOT *mem_root) { /* Never called */ }
1943 virtual ~TABLE_READ_PLAN() {} /* Remove gcc warning */
1947 class TRP_ROR_INTERSECT;
1948 class TRP_ROR_UNION;
1949 class TRP_INDEX_MERGE;
1953 Plan for a QUICK_RANGE_SELECT scan.
1954 TRP_RANGE::make_quick ignores retrieve_full_rows parameter because
1955 QUICK_RANGE_SELECT doesn't distinguish between 'index only' scans and full
1956 record retrieval scans.
1959 class TRP_RANGE : public TABLE_READ_PLAN
1961 public:
1962 SEL_ARG *key; /* set of intervals to be used in "range" method retrieval */
1963 uint key_idx; /* key number in PARAM::key */
1965 TRP_RANGE(SEL_ARG *key_arg, uint idx_arg)
1966 : key(key_arg), key_idx(idx_arg)
1968 virtual ~TRP_RANGE() {} /* Remove gcc warning */
1970 QUICK_SELECT_I *make_quick(PARAM *param, bool retrieve_full_rows,
1971 MEM_ROOT *parent_alloc)
1973 DBUG_ENTER("TRP_RANGE::make_quick");
1974 QUICK_RANGE_SELECT *quick;
1975 if ((quick= get_quick_select(param, key_idx, key, parent_alloc)))
1977 quick->records= records;
1978 quick->read_time= read_cost;
1980 DBUG_RETURN(quick);
1985 /* Plan for QUICK_ROR_INTERSECT_SELECT scan. */
1987 class TRP_ROR_INTERSECT : public TABLE_READ_PLAN
1989 public:
1990 TRP_ROR_INTERSECT() {} /* Remove gcc warning */
1991 virtual ~TRP_ROR_INTERSECT() {} /* Remove gcc warning */
1992 QUICK_SELECT_I *make_quick(PARAM *param, bool retrieve_full_rows,
1993 MEM_ROOT *parent_alloc);
1995 /* Array of pointers to ROR range scans used in this intersection */
1996 struct st_ror_scan_info **first_scan;
1997 struct st_ror_scan_info **last_scan; /* End of the above array */
1998 struct st_ror_scan_info *cpk_scan; /* Clustered PK scan, if there is one */
1999 bool is_covering; /* TRUE if no row retrieval phase is necessary */
2000 double index_scan_costs; /* SUM(cost(index_scan)) */
2005 Plan for QUICK_ROR_UNION_SELECT scan.
2006 QUICK_ROR_UNION_SELECT always retrieves full rows, so retrieve_full_rows
2007 is ignored by make_quick.
2010 class TRP_ROR_UNION : public TABLE_READ_PLAN
2012 public:
2013 TRP_ROR_UNION() {} /* Remove gcc warning */
2014 virtual ~TRP_ROR_UNION() {} /* Remove gcc warning */
2015 QUICK_SELECT_I *make_quick(PARAM *param, bool retrieve_full_rows,
2016 MEM_ROOT *parent_alloc);
2017 TABLE_READ_PLAN **first_ror; /* array of ptrs to plans for merged scans */
2018 TABLE_READ_PLAN **last_ror; /* end of the above array */
2023 Plan for QUICK_INDEX_MERGE_SELECT scan.
2024 QUICK_ROR_INTERSECT_SELECT always retrieves full rows, so retrieve_full_rows
2025 is ignored by make_quick.
2028 class TRP_INDEX_MERGE : public TABLE_READ_PLAN
2030 public:
2031 TRP_INDEX_MERGE() {} /* Remove gcc warning */
2032 virtual ~TRP_INDEX_MERGE() {} /* Remove gcc warning */
2033 QUICK_SELECT_I *make_quick(PARAM *param, bool retrieve_full_rows,
2034 MEM_ROOT *parent_alloc);
2035 TRP_RANGE **range_scans; /* array of ptrs to plans of merged scans */
2036 TRP_RANGE **range_scans_end; /* end of the array */
2041 Plan for a QUICK_GROUP_MIN_MAX_SELECT scan.
2044 class TRP_GROUP_MIN_MAX : public TABLE_READ_PLAN
2046 private:
2047 bool have_min, have_max;
2048 KEY_PART_INFO *min_max_arg_part;
2049 uint group_prefix_len;
2050 uint used_key_parts;
2051 uint group_key_parts;
2052 KEY *index_info;
2053 uint index;
2054 uint key_infix_len;
2055 uchar key_infix[MAX_KEY_LENGTH];
2056 SEL_TREE *range_tree; /* Represents all range predicates in the query. */
2057 SEL_ARG *index_tree; /* The SEL_ARG sub-tree corresponding to index_info. */
2058 uint param_idx; /* Index of used key in param->key. */
2059 /* Number of records selected by the ranges in index_tree. */
2060 public:
2061 ha_rows quick_prefix_records;
2062 public:
2063 TRP_GROUP_MIN_MAX(bool have_min_arg, bool have_max_arg,
2064 KEY_PART_INFO *min_max_arg_part_arg,
2065 uint group_prefix_len_arg, uint used_key_parts_arg,
2066 uint group_key_parts_arg, KEY *index_info_arg,
2067 uint index_arg, uint key_infix_len_arg,
2068 uchar *key_infix_arg,
2069 SEL_TREE *tree_arg, SEL_ARG *index_tree_arg,
2070 uint param_idx_arg, ha_rows quick_prefix_records_arg)
2071 : have_min(have_min_arg), have_max(have_max_arg),
2072 min_max_arg_part(min_max_arg_part_arg),
2073 group_prefix_len(group_prefix_len_arg), used_key_parts(used_key_parts_arg),
2074 group_key_parts(group_key_parts_arg), index_info(index_info_arg),
2075 index(index_arg), key_infix_len(key_infix_len_arg), range_tree(tree_arg),
2076 index_tree(index_tree_arg), param_idx(param_idx_arg),
2077 quick_prefix_records(quick_prefix_records_arg)
2079 if (key_infix_len)
2080 memcpy(this->key_infix, key_infix_arg, key_infix_len);
2082 virtual ~TRP_GROUP_MIN_MAX() {} /* Remove gcc warning */
2084 QUICK_SELECT_I *make_quick(PARAM *param, bool retrieve_full_rows,
2085 MEM_ROOT *parent_alloc);
2090 Fill param->needed_fields with bitmap of fields used in the query.
2091 SYNOPSIS
2092 fill_used_fields_bitmap()
2093 param Parameter from test_quick_select function.
2095 NOTES
2096 Clustered PK members are not put into the bitmap as they are implicitly
2097 present in all keys (and it is impossible to avoid reading them).
2098 RETURN
2099 0 Ok
2100 1 Out of memory.
2103 static int fill_used_fields_bitmap(PARAM *param)
2105 TABLE *table= param->table;
2106 my_bitmap_map *tmp;
2107 uint pk;
2108 param->tmp_covered_fields.bitmap= 0;
2109 param->fields_bitmap_size= table->s->column_bitmap_size;
2110 if (!(tmp= (my_bitmap_map*) alloc_root(param->mem_root,
2111 param->fields_bitmap_size)) ||
2112 bitmap_init(&param->needed_fields, tmp, table->s->fields, FALSE))
2113 return 1;
2115 bitmap_copy(&param->needed_fields, table->read_set);
2116 bitmap_union(&param->needed_fields, table->write_set);
2118 pk= param->table->s->primary_key;
2119 if (pk != MAX_KEY && param->table->file->primary_key_is_clustered())
2121 /* The table uses clustered PK and it is not internally generated */
2122 KEY_PART_INFO *key_part= param->table->key_info[pk].key_part;
2123 KEY_PART_INFO *key_part_end= key_part +
2124 param->table->key_info[pk].key_parts;
2125 for (;key_part != key_part_end; ++key_part)
2126 bitmap_clear_bit(&param->needed_fields, key_part->fieldnr-1);
2128 return 0;
2133 Test if a key can be used in different ranges
2135 SYNOPSIS
2136 SQL_SELECT::test_quick_select()
2137 thd Current thread
2138 keys_to_use Keys to use for range retrieval
2139 prev_tables Tables assumed to be already read when the scan is
2140 performed (but not read at the moment of this call)
2141 limit Query limit
2142 force_quick_range Prefer to use range (instead of full table scan) even
2143 if it is more expensive.
2145 NOTES
2146 Updates the following in the select parameter:
2147 needed_reg - Bits for keys with may be used if all prev regs are read
2148 quick - Parameter to use when reading records.
2150 In the table struct the following information is updated:
2151 quick_keys - Which keys can be used
2152 quick_rows - How many rows the key matches
2153 quick_condition_rows - E(# rows that will satisfy the table condition)
2155 IMPLEMENTATION
2156 quick_condition_rows value is obtained as follows:
2158 It is a minimum of E(#output rows) for all considered table access
2159 methods (range and index_merge accesses over various indexes).
2161 The obtained value is not a true E(#rows that satisfy table condition)
2162 but rather a pessimistic estimate. To obtain a true E(#...) one would
2163 need to combine estimates of various access methods, taking into account
2164 correlations between sets of rows they will return.
2166 For example, if values of tbl.key1 and tbl.key2 are independent (a right
2167 assumption if we have no information about their correlation) then the
2168 correct estimate will be:
2170 E(#rows("tbl.key1 < c1 AND tbl.key2 < c2")) =
2171 = E(#rows(tbl.key1 < c1)) / total_rows(tbl) * E(#rows(tbl.key2 < c2)
2173 which is smaller than
2175 MIN(E(#rows(tbl.key1 < c1), E(#rows(tbl.key2 < c2)))
2177 which is currently produced.
2179 TODO
2180 * Change the value returned in quick_condition_rows from a pessimistic
2181 estimate to true E(#rows that satisfy table condition).
2182 (we can re-use some of E(#rows) calcuation code from index_merge/intersection
2183 for this)
2185 * Check if this function really needs to modify keys_to_use, and change the
2186 code to pass it by reference if it doesn't.
2188 * In addition to force_quick_range other means can be (an usually are) used
2189 to make this function prefer range over full table scan. Figure out if
2190 force_quick_range is really needed.
2192 RETURN
2193 -1 if impossible select (i.e. certainly no rows will be selected)
2194 0 if can't use quick_select
2195 1 if found usable ranges and quick select has been successfully created.
2198 int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
2199 table_map prev_tables,
2200 ha_rows limit, bool force_quick_range)
2202 uint idx;
2203 double scan_time;
2204 DBUG_ENTER("SQL_SELECT::test_quick_select");
2205 DBUG_PRINT("enter",("keys_to_use: %lu prev_tables: %lu const_tables: %lu",
2206 (ulong) keys_to_use.to_ulonglong(), (ulong) prev_tables,
2207 (ulong) const_tables));
2208 DBUG_PRINT("info", ("records: %lu", (ulong) head->file->stats.records));
2209 delete quick;
2210 quick=0;
2211 needed_reg.clear_all();
2212 quick_keys.clear_all();
2213 if (keys_to_use.is_clear_all())
2214 DBUG_RETURN(0);
2215 records= head->file->stats.records;
2216 if (!records)
2217 records++; /* purecov: inspected */
2218 scan_time= (double) records / TIME_FOR_COMPARE + 1;
2219 read_time= (double) head->file->scan_time() + scan_time + 1.1;
2220 if (head->force_index)
2221 scan_time= read_time= DBL_MAX;
2222 if (limit < records)
2223 read_time= (double) records + scan_time + 1; // Force to use index
2224 else if (read_time <= 2.0 && !force_quick_range)
2225 DBUG_RETURN(0); /* No need for quick select */
2227 DBUG_PRINT("info",("Time to scan table: %g", read_time));
2229 keys_to_use.intersect(head->keys_in_use_for_query);
2230 if (!keys_to_use.is_clear_all())
2232 #ifndef EMBEDDED_LIBRARY // Avoid compiler warning
2233 uchar buff[STACK_BUFF_ALLOC];
2234 #endif
2235 MEM_ROOT alloc;
2236 SEL_TREE *tree= NULL;
2237 KEY_PART *key_parts;
2238 KEY *key_info;
2239 PARAM param;
2241 if (check_stack_overrun(thd, 2*STACK_MIN_SIZE + sizeof(PARAM), buff))
2242 DBUG_RETURN(0); // Fatal error flag is set
2244 /* set up parameter that is passed to all functions */
2245 param.thd= thd;
2246 param.baseflag= head->file->ha_table_flags();
2247 param.prev_tables=prev_tables | const_tables;
2248 param.read_tables=read_tables;
2249 param.current_table= head->map;
2250 param.table=head;
2251 param.keys=0;
2252 param.mem_root= &alloc;
2253 param.old_root= thd->mem_root;
2254 param.needed_reg= &needed_reg;
2255 param.imerge_cost_buff_size= 0;
2256 param.using_real_indexes= TRUE;
2257 param.remove_jump_scans= TRUE;
2259 thd->no_errors=1; // Don't warn about NULL
2260 init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0);
2261 if (!(param.key_parts= (KEY_PART*) alloc_root(&alloc,
2262 sizeof(KEY_PART)*
2263 head->s->key_parts)) ||
2264 fill_used_fields_bitmap(&param))
2266 thd->no_errors=0;
2267 free_root(&alloc,MYF(0)); // Return memory & allocator
2268 DBUG_RETURN(0); // Can't use range
2270 key_parts= param.key_parts;
2271 thd->mem_root= &alloc;
2274 Make an array with description of all key parts of all table keys.
2275 This is used in get_mm_parts function.
2277 key_info= head->key_info;
2278 for (idx=0 ; idx < head->s->keys ; idx++, key_info++)
2280 KEY_PART_INFO *key_part_info;
2281 if (!keys_to_use.is_set(idx))
2282 continue;
2283 if (key_info->flags & HA_FULLTEXT)
2284 continue; // ToDo: ft-keys in non-ft ranges, if possible SerG
2286 param.key[param.keys]=key_parts;
2287 key_part_info= key_info->key_part;
2288 for (uint part=0 ; part < key_info->key_parts ;
2289 part++, key_parts++, key_part_info++)
2291 key_parts->key= param.keys;
2292 key_parts->part= part;
2293 key_parts->length= key_part_info->length;
2294 key_parts->store_length= key_part_info->store_length;
2295 key_parts->field= key_part_info->field;
2296 key_parts->null_bit= key_part_info->null_bit;
2297 key_parts->image_type =
2298 (key_info->flags & HA_SPATIAL) ? Field::itMBR : Field::itRAW;
2299 /* Only HA_PART_KEY_SEG is used */
2300 key_parts->flag= (uint8) key_part_info->key_part_flag;
2302 param.real_keynr[param.keys++]=idx;
2304 param.key_parts_end=key_parts;
2305 param.alloced_sel_args= 0;
2307 /* Calculate cost of full index read for the shortest covering index */
2308 if (!head->covering_keys.is_clear_all())
2310 int key_for_use= find_shortest_key(head, &head->covering_keys);
2311 double key_read_time= (get_index_only_read_time(&param, records,
2312 key_for_use) +
2313 (double) records / TIME_FOR_COMPARE);
2314 DBUG_PRINT("info", ("'all'+'using index' scan will be using key %d, "
2315 "read time %g", key_for_use, key_read_time));
2316 if (key_read_time < read_time)
2317 read_time= key_read_time;
2320 TABLE_READ_PLAN *best_trp= NULL;
2321 TRP_GROUP_MIN_MAX *group_trp;
2322 double best_read_time= read_time;
2324 if (cond)
2326 if ((tree= get_mm_tree(&param,cond)))
2328 if (tree->type == SEL_TREE::IMPOSSIBLE)
2330 records=0L; /* Return -1 from this function. */
2331 read_time= (double) HA_POS_ERROR;
2332 goto free_mem;
2335 If the tree can't be used for range scans, proceed anyway, as we
2336 can construct a group-min-max quick select
2338 if (tree->type != SEL_TREE::KEY && tree->type != SEL_TREE::KEY_SMALLER)
2339 tree= NULL;
2344 Try to construct a QUICK_GROUP_MIN_MAX_SELECT.
2345 Notice that it can be constructed no matter if there is a range tree.
2347 group_trp= get_best_group_min_max(&param, tree);
2348 if (group_trp)
2350 param.table->quick_condition_rows= min(group_trp->records,
2351 head->file->stats.records);
2352 if (group_trp->read_cost < best_read_time)
2354 best_trp= group_trp;
2355 best_read_time= best_trp->read_cost;
2359 if (tree)
2362 It is possible to use a range-based quick select (but it might be
2363 slower than 'all' table scan).
2365 if (tree->merges.is_empty())
2367 TRP_RANGE *range_trp;
2368 TRP_ROR_INTERSECT *rori_trp;
2369 bool can_build_covering= FALSE;
2371 /* Get best 'range' plan and prepare data for making other plans */
2372 if ((range_trp= get_key_scans_params(&param, tree, FALSE, TRUE,
2373 best_read_time)))
2375 best_trp= range_trp;
2376 best_read_time= best_trp->read_cost;
2380 Simultaneous key scans and row deletes on several handler
2381 objects are not allowed so don't use ROR-intersection for
2382 table deletes.
2384 if ((thd->lex->sql_command != SQLCOM_DELETE) &&
2385 optimizer_flag(thd, OPTIMIZER_SWITCH_INDEX_MERGE))
2388 Get best non-covering ROR-intersection plan and prepare data for
2389 building covering ROR-intersection.
2391 if ((rori_trp= get_best_ror_intersect(&param, tree, best_read_time,
2392 &can_build_covering)))
2394 best_trp= rori_trp;
2395 best_read_time= best_trp->read_cost;
2397 Try constructing covering ROR-intersect only if it looks possible
2398 and worth doing.
2400 if (!rori_trp->is_covering && can_build_covering &&
2401 (rori_trp= get_best_covering_ror_intersect(&param, tree,
2402 best_read_time)))
2403 best_trp= rori_trp;
2407 else
2409 if (optimizer_flag(thd, OPTIMIZER_SWITCH_INDEX_MERGE))
2411 /* Try creating index_merge/ROR-union scan. */
2412 SEL_IMERGE *imerge;
2413 TABLE_READ_PLAN *best_conj_trp= NULL, *new_conj_trp;
2414 LINT_INIT(new_conj_trp); /* no empty index_merge lists possible */
2415 DBUG_PRINT("info",("No range reads possible,"
2416 " trying to construct index_merge"));
2417 List_iterator_fast<SEL_IMERGE> it(tree->merges);
2418 while ((imerge= it++))
2420 new_conj_trp= get_best_disjunct_quick(&param, imerge, best_read_time);
2421 if (new_conj_trp)
2422 set_if_smaller(param.table->quick_condition_rows,
2423 new_conj_trp->records);
2424 if (!best_conj_trp || (new_conj_trp && new_conj_trp->read_cost <
2425 best_conj_trp->read_cost))
2426 best_conj_trp= new_conj_trp;
2428 if (best_conj_trp)
2429 best_trp= best_conj_trp;
2434 thd->mem_root= param.old_root;
2436 /* If we got a read plan, create a quick select from it. */
2437 if (best_trp)
2439 records= best_trp->records;
2440 if (!(quick= best_trp->make_quick(&param, TRUE)) || quick->init())
2442 delete quick;
2443 quick= NULL;
2447 free_mem:
2448 free_root(&alloc,MYF(0)); // Return memory & allocator
2449 thd->mem_root= param.old_root;
2450 thd->no_errors=0;
2453 DBUG_EXECUTE("info", print_quick(quick, &needed_reg););
2456 Assume that if the user is using 'limit' we will only need to scan
2457 limit rows if we are using a key
2459 DBUG_RETURN(records ? test(quick) : -1);
2462 /****************************************************************************
2463 * Partition pruning module
2464 ****************************************************************************/
2465 #ifdef WITH_PARTITION_STORAGE_ENGINE
2468 PartitionPruningModule
2470 This part of the code does partition pruning. Partition pruning solves the
2471 following problem: given a query over partitioned tables, find partitions
2472 that we will not need to access (i.e. partitions that we can assume to be
2473 empty) when executing the query.
2474 The set of partitions to prune doesn't depend on which query execution
2475 plan will be used to execute the query.
2477 HOW IT WORKS
2479 Partition pruning module makes use of RangeAnalysisModule. The following
2480 examples show how the problem of partition pruning can be reduced to the
2481 range analysis problem:
2483 EXAMPLE 1
2484 Consider a query:
2486 SELECT * FROM t1 WHERE (t1.a < 5 OR t1.a = 10) AND t1.a > 3 AND t1.b='z'
2488 where table t1 is partitioned using PARTITION BY RANGE(t1.a). An apparent
2489 way to find the used (i.e. not pruned away) partitions is as follows:
2491 1. analyze the WHERE clause and extract the list of intervals over t1.a
2492 for the above query we will get this list: {(3 < t1.a < 5), (t1.a=10)}
2494 2. for each interval I
2496 find partitions that have non-empty intersection with I;
2497 mark them as used;
2500 EXAMPLE 2
2501 Suppose the table is partitioned by HASH(part_func(t1.a, t1.b)). Then
2502 we need to:
2504 1. Analyze the WHERE clause and get a list of intervals over (t1.a, t1.b).
2505 The list of intervals we'll obtain will look like this:
2506 ((t1.a, t1.b) = (1,'foo')),
2507 ((t1.a, t1.b) = (2,'bar')),
2508 ((t1,a, t1.b) > (10,'zz'))
2510 2. for each interval I
2512 if (the interval has form "(t1.a, t1.b) = (const1, const2)" )
2514 calculate HASH(part_func(t1.a, t1.b));
2515 find which partition has records with this hash value and mark
2516 it as used;
2518 else
2520 mark all partitions as used;
2521 break;
2525 For both examples the step #1 is exactly what RangeAnalysisModule could
2526 be used to do, if it was provided with appropriate index description
2527 (array of KEY_PART structures).
2528 In example #1, we need to provide it with description of index(t1.a),
2529 in example #2, we need to provide it with description of index(t1.a, t1.b).
2531 These index descriptions are further called "partitioning index
2532 descriptions". Note that it doesn't matter if such indexes really exist,
2533 as range analysis module only uses the description.
2535 Putting it all together, partitioning module works as follows:
2537 prune_partitions() {
2538 call create_partition_index_description();
2540 call get_mm_tree(); // invoke the RangeAnalysisModule
2542 // analyze the obtained interval list and get used partitions
2543 call find_used_partitions();
2548 struct st_part_prune_param;
2549 struct st_part_opt_info;
2551 typedef void (*mark_full_part_func)(partition_info*, uint32);
2554 Partition pruning operation context
2556 typedef struct st_part_prune_param
2558 RANGE_OPT_PARAM range_param; /* Range analyzer parameters */
2560 /***************************************************************
2561 Following fields are filled in based solely on partitioning
2562 definition and not modified after that:
2563 **************************************************************/
2564 partition_info *part_info; /* Copy of table->part_info */
2565 /* Function to get partition id from partitioning fields only */
2566 get_part_id_func get_top_partition_id_func;
2567 /* Function to mark a partition as used (w/all subpartitions if they exist)*/
2568 mark_full_part_func mark_full_partition_used;
2570 /* Partitioning 'index' description, array of key parts */
2571 KEY_PART *key;
2574 Number of fields in partitioning 'index' definition created for
2575 partitioning (0 if partitioning 'index' doesn't include partitioning
2576 fields)
2578 uint part_fields;
2579 uint subpart_fields; /* Same as above for subpartitioning */
2582 Number of the last partitioning field keypart in the index, or -1 if
2583 partitioning index definition doesn't include partitioning fields.
2585 int last_part_partno;
2586 int last_subpart_partno; /* Same as above for supartitioning */
2589 is_part_keypart[i] == test(keypart #i in partitioning index is a member
2590 used in partitioning)
2591 Used to maintain current values of cur_part_fields and cur_subpart_fields
2593 my_bool *is_part_keypart;
2594 /* Same as above for subpartitioning */
2595 my_bool *is_subpart_keypart;
2597 /***************************************************************
2598 Following fields form find_used_partitions() recursion context:
2599 **************************************************************/
2600 SEL_ARG **arg_stack; /* "Stack" of SEL_ARGs */
2601 SEL_ARG **arg_stack_end; /* Top of the stack */
2602 /* Number of partitioning fields for which we have a SEL_ARG* in arg_stack */
2603 uint cur_part_fields;
2604 /* Same as cur_part_fields, but for subpartitioning */
2605 uint cur_subpart_fields;
2607 /* Iterator to be used to obtain the "current" set of used partitions */
2608 PARTITION_ITERATOR part_iter;
2610 /* Initialized bitmap of no_subparts size */
2611 MY_BITMAP subparts_bitmap;
2612 } PART_PRUNE_PARAM;
2614 static bool create_partition_index_description(PART_PRUNE_PARAM *prune_par);
2615 static int find_used_partitions(PART_PRUNE_PARAM *ppar, SEL_ARG *key_tree);
2616 static int find_used_partitions_imerge(PART_PRUNE_PARAM *ppar,
2617 SEL_IMERGE *imerge);
2618 static int find_used_partitions_imerge_list(PART_PRUNE_PARAM *ppar,
2619 List<SEL_IMERGE> &merges);
2620 static void mark_all_partitions_as_used(partition_info *part_info);
2622 #ifndef DBUG_OFF
2623 static void print_partitioning_index(KEY_PART *parts, KEY_PART *parts_end);
2624 static void dbug_print_field(Field *field);
2625 static void dbug_print_segment_range(SEL_ARG *arg, KEY_PART *part);
2626 static void dbug_print_singlepoint_range(SEL_ARG **start, uint num);
2627 #endif
2631 Perform partition pruning for a given table and condition.
2633 SYNOPSIS
2634 prune_partitions()
2635 thd Thread handle
2636 table Table to perform partition pruning for
2637 pprune_cond Condition to use for partition pruning
2639 DESCRIPTION
2640 This function assumes that all partitions are marked as unused when it
2641 is invoked. The function analyzes the condition, finds partitions that
2642 need to be used to retrieve the records that match the condition, and
2643 marks them as used by setting appropriate bit in part_info->used_partitions
2644 In the worst case all partitions are marked as used.
2646 NOTE
2647 This function returns promptly if called for non-partitioned table.
2649 RETURN
2650 TRUE We've inferred that no partitions need to be used (i.e. no table
2651 records will satisfy pprune_cond)
2652 FALSE Otherwise
2655 bool prune_partitions(THD *thd, TABLE *table, Item *pprune_cond)
2657 bool retval= FALSE;
2658 partition_info *part_info = table->part_info;
2659 DBUG_ENTER("prune_partitions");
2661 if (!part_info)
2662 DBUG_RETURN(FALSE); /* not a partitioned table */
2664 if (!pprune_cond)
2666 mark_all_partitions_as_used(part_info);
2667 DBUG_RETURN(FALSE);
2670 PART_PRUNE_PARAM prune_param;
2671 MEM_ROOT alloc;
2672 RANGE_OPT_PARAM *range_par= &prune_param.range_param;
2673 my_bitmap_map *old_sets[2];
2675 prune_param.part_info= part_info;
2676 init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0);
2677 range_par->mem_root= &alloc;
2678 range_par->old_root= thd->mem_root;
2680 if (create_partition_index_description(&prune_param))
2682 mark_all_partitions_as_used(part_info);
2683 free_root(&alloc,MYF(0)); // Return memory & allocator
2684 DBUG_RETURN(FALSE);
2687 dbug_tmp_use_all_columns(table, old_sets,
2688 table->read_set, table->write_set);
2689 range_par->thd= thd;
2690 range_par->table= table;
2691 /* range_par->cond doesn't need initialization */
2692 range_par->prev_tables= range_par->read_tables= 0;
2693 range_par->current_table= table->map;
2695 range_par->keys= 1; // one index
2696 range_par->using_real_indexes= FALSE;
2697 range_par->remove_jump_scans= FALSE;
2698 range_par->real_keynr[0]= 0;
2699 range_par->alloced_sel_args= 0;
2701 thd->no_errors=1; // Don't warn about NULL
2702 thd->mem_root=&alloc;
2704 bitmap_clear_all(&part_info->used_partitions);
2706 prune_param.key= prune_param.range_param.key_parts;
2707 SEL_TREE *tree;
2708 int res;
2710 tree= get_mm_tree(range_par, pprune_cond);
2711 if (!tree)
2712 goto all_used;
2714 if (tree->type == SEL_TREE::IMPOSSIBLE)
2716 retval= TRUE;
2717 goto end;
2720 if (tree->type != SEL_TREE::KEY && tree->type != SEL_TREE::KEY_SMALLER)
2721 goto all_used;
2723 if (tree->merges.is_empty())
2725 /* Range analysis has produced a single list of intervals. */
2726 prune_param.arg_stack_end= prune_param.arg_stack;
2727 prune_param.cur_part_fields= 0;
2728 prune_param.cur_subpart_fields= 0;
2729 init_all_partitions_iterator(part_info, &prune_param.part_iter);
2730 if (!tree->keys[0] || (-1 == (res= find_used_partitions(&prune_param,
2731 tree->keys[0]))))
2732 goto all_used;
2734 else
2736 if (tree->merges.elements == 1)
2739 Range analysis has produced a "merge" of several intervals lists, a
2740 SEL_TREE that represents an expression in form
2741 sel_imerge = (tree1 OR tree2 OR ... OR treeN)
2742 that cannot be reduced to one tree. This can only happen when
2743 partitioning index has several keyparts and the condition is OR of
2744 conditions that refer to different key parts. For example, we'll get
2745 here for "partitioning_field=const1 OR subpartitioning_field=const2"
2747 if (-1 == (res= find_used_partitions_imerge(&prune_param,
2748 tree->merges.head())))
2749 goto all_used;
2751 else
2754 Range analysis has produced a list of several imerges, i.e. a
2755 structure that represents a condition in form
2756 imerge_list= (sel_imerge1 AND sel_imerge2 AND ... AND sel_imergeN)
2757 This is produced for complicated WHERE clauses that range analyzer
2758 can't really analyze properly.
2760 if (-1 == (res= find_used_partitions_imerge_list(&prune_param,
2761 tree->merges)))
2762 goto all_used;
2767 res == 0 => no used partitions => retval=TRUE
2768 res == 1 => some used partitions => retval=FALSE
2769 res == -1 - we jump over this line to all_used:
2771 retval= test(!res);
2772 goto end;
2774 all_used:
2775 retval= FALSE; // some partitions are used
2776 mark_all_partitions_as_used(prune_param.part_info);
2777 end:
2778 dbug_tmp_restore_column_maps(table->read_set, table->write_set, old_sets);
2779 thd->no_errors=0;
2780 thd->mem_root= range_par->old_root;
2781 free_root(&alloc,MYF(0)); // Return memory & allocator
2782 DBUG_RETURN(retval);
2787 Store field key image to table record
2789 SYNOPSIS
2790 store_key_image_to_rec()
2791 field Field which key image should be stored
2792 ptr Field value in key format
2793 len Length of the value, in bytes
2795 DESCRIPTION
2796 Copy the field value from its key image to the table record. The source
2797 is the value in key image format, occupying len bytes in buffer pointed
2798 by ptr. The destination is table record, in "field value in table record"
2799 format.
2802 void store_key_image_to_rec(Field *field, uchar *ptr, uint len)
2804 /* Do the same as print_key() does */
2805 my_bitmap_map *old_map;
2807 if (field->real_maybe_null())
2809 if (*ptr)
2811 field->set_null();
2812 return;
2814 field->set_notnull();
2815 ptr++;
2817 old_map= dbug_tmp_use_all_columns(field->table,
2818 field->table->write_set);
2819 field->set_key_image(ptr, len);
2820 dbug_tmp_restore_column_map(field->table->write_set, old_map);
2825 For SEL_ARG* array, store sel_arg->min values into table record buffer
2827 SYNOPSIS
2828 store_selargs_to_rec()
2829 ppar Partition pruning context
2830 start Array of SEL_ARG* for which the minimum values should be stored
2831 num Number of elements in the array
2833 DESCRIPTION
2834 For each SEL_ARG* interval in the specified array, store the left edge
2835 field value (sel_arg->min, key image format) into the table record.
2838 static void store_selargs_to_rec(PART_PRUNE_PARAM *ppar, SEL_ARG **start,
2839 int num)
2841 KEY_PART *parts= ppar->range_param.key_parts;
2842 for (SEL_ARG **end= start + num; start != end; start++)
2844 SEL_ARG *sel_arg= (*start);
2845 store_key_image_to_rec(sel_arg->field, sel_arg->min_value,
2846 parts[sel_arg->part].length);
2851 /* Mark a partition as used in the case when there are no subpartitions */
2852 static void mark_full_partition_used_no_parts(partition_info* part_info,
2853 uint32 part_id)
2855 DBUG_ENTER("mark_full_partition_used_no_parts");
2856 DBUG_PRINT("enter", ("Mark partition %u as used", part_id));
2857 bitmap_set_bit(&part_info->used_partitions, part_id);
2858 DBUG_VOID_RETURN;
2862 /* Mark a partition as used in the case when there are subpartitions */
2863 static void mark_full_partition_used_with_parts(partition_info *part_info,
2864 uint32 part_id)
2866 uint32 start= part_id * part_info->no_subparts;
2867 uint32 end= start + part_info->no_subparts;
2868 DBUG_ENTER("mark_full_partition_used_with_parts");
2870 for (; start != end; start++)
2872 DBUG_PRINT("info", ("1:Mark subpartition %u as used", start));
2873 bitmap_set_bit(&part_info->used_partitions, start);
2875 DBUG_VOID_RETURN;
2879 Find the set of used partitions for List<SEL_IMERGE>
2880 SYNOPSIS
2881 find_used_partitions_imerge_list
2882 ppar Partition pruning context.
2883 key_tree Intervals tree to perform pruning for.
2885 DESCRIPTION
2886 List<SEL_IMERGE> represents "imerge1 AND imerge2 AND ...".
2887 The set of used partitions is an intersection of used partitions sets
2888 for imerge_{i}.
2889 We accumulate this intersection in a separate bitmap.
2891 RETURN
2892 See find_used_partitions()
2895 static int find_used_partitions_imerge_list(PART_PRUNE_PARAM *ppar,
2896 List<SEL_IMERGE> &merges)
2898 MY_BITMAP all_merges;
2899 uint bitmap_bytes;
2900 my_bitmap_map *bitmap_buf;
2901 uint n_bits= ppar->part_info->used_partitions.n_bits;
2902 bitmap_bytes= bitmap_buffer_size(n_bits);
2903 if (!(bitmap_buf= (my_bitmap_map*) alloc_root(ppar->range_param.mem_root,
2904 bitmap_bytes)))
2907 Fallback, process just the first SEL_IMERGE. This can leave us with more
2908 partitions marked as used then actually needed.
2910 return find_used_partitions_imerge(ppar, merges.head());
2912 bitmap_init(&all_merges, bitmap_buf, n_bits, FALSE);
2913 bitmap_set_prefix(&all_merges, n_bits);
2915 List_iterator<SEL_IMERGE> it(merges);
2916 SEL_IMERGE *imerge;
2917 while ((imerge=it++))
2919 int res= find_used_partitions_imerge(ppar, imerge);
2920 if (!res)
2922 /* no used partitions on one ANDed imerge => no used partitions at all */
2923 return 0;
2926 if (res != -1)
2927 bitmap_intersect(&all_merges, &ppar->part_info->used_partitions);
2929 if (bitmap_is_clear_all(&all_merges))
2930 return 0;
2932 bitmap_clear_all(&ppar->part_info->used_partitions);
2934 memcpy(ppar->part_info->used_partitions.bitmap, all_merges.bitmap,
2935 bitmap_bytes);
2936 return 1;
2941 Find the set of used partitions for SEL_IMERGE structure
2942 SYNOPSIS
2943 find_used_partitions_imerge()
2944 ppar Partition pruning context.
2945 key_tree Intervals tree to perform pruning for.
2947 DESCRIPTION
2948 SEL_IMERGE represents "tree1 OR tree2 OR ...". The implementation is
2949 trivial - just use mark used partitions for each tree and bail out early
2950 if for some tree_{i} all partitions are used.
2952 RETURN
2953 See find_used_partitions().
2956 static
2957 int find_used_partitions_imerge(PART_PRUNE_PARAM *ppar, SEL_IMERGE *imerge)
2959 int res= 0;
2960 for (SEL_TREE **ptree= imerge->trees; ptree < imerge->trees_next; ptree++)
2962 ppar->arg_stack_end= ppar->arg_stack;
2963 ppar->cur_part_fields= 0;
2964 ppar->cur_subpart_fields= 0;
2965 init_all_partitions_iterator(ppar->part_info, &ppar->part_iter);
2966 SEL_ARG *key_tree= (*ptree)->keys[0];
2967 if (!key_tree || (-1 == (res |= find_used_partitions(ppar, key_tree))))
2968 return -1;
2970 return res;
2975 Collect partitioning ranges for the SEL_ARG tree and mark partitions as used
2977 SYNOPSIS
2978 find_used_partitions()
2979 ppar Partition pruning context.
2980 key_tree SEL_ARG range tree to perform pruning for
2982 DESCRIPTION
2983 This function
2984 * recursively walks the SEL_ARG* tree collecting partitioning "intervals"
2985 * finds the partitions one needs to use to get rows in these intervals
2986 * marks these partitions as used.
2987 The next session desribes the process in greater detail.
2989 IMPLEMENTATION
2990 TYPES OF RESTRICTIONS THAT WE CAN OBTAIN PARTITIONS FOR
2991 We can find out which [sub]partitions to use if we obtain restrictions on
2992 [sub]partitioning fields in the following form:
2993 1. "partition_field1=const1 AND ... AND partition_fieldN=constN"
2994 1.1 Same as (1) but for subpartition fields
2996 If partitioning supports interval analysis (i.e. partitioning is a
2997 function of a single table field, and partition_info::
2998 get_part_iter_for_interval != NULL), then we can also use condition in
2999 this form:
3000 2. "const1 <=? partition_field <=? const2"
3001 2.1 Same as (2) but for subpartition_field
3003 INFERRING THE RESTRICTIONS FROM SEL_ARG TREE
3005 The below is an example of what SEL_ARG tree may represent:
3007 (start)
3009 | Partitioning keyparts $ subpartitioning keyparts
3011 | ... ... $
3012 | | | $
3013 | +---------+ +---------+ $ +-----------+ +-----------+
3014 \-| par1=c1 |--| par2=c2 |-----| subpar1=c3|--| subpar2=c5|
3015 +---------+ +---------+ $ +-----------+ +-----------+
3016 | $ | |
3017 | $ | +-----------+
3018 | $ | | subpar2=c6|
3019 | $ | +-----------+
3020 | $ |
3021 | $ +-----------+ +-----------+
3022 | $ | subpar1=c4|--| subpar2=c8|
3023 | $ +-----------+ +-----------+
3024 | $
3026 +---------+ $ +------------+ +------------+
3027 | par1=c2 |------------------| subpar1=c10|--| subpar2=c12|
3028 +---------+ $ +------------+ +------------+
3030 ... $
3032 The up-down connections are connections via SEL_ARG::left and
3033 SEL_ARG::right. A horizontal connection to the right is the
3034 SEL_ARG::next_key_part connection.
3036 find_used_partitions() traverses the entire tree via recursion on
3037 * SEL_ARG::next_key_part (from left to right on the picture)
3038 * SEL_ARG::left|right (up/down on the pic). Left-right recursion is
3039 performed for each depth level.
3041 Recursion descent on SEL_ARG::next_key_part is used to accumulate (in
3042 ppar->arg_stack) constraints on partitioning and subpartitioning fields.
3043 For the example in the above picture, one of stack states is:
3044 in find_used_partitions(key_tree = "subpar2=c5") (***)
3045 in find_used_partitions(key_tree = "subpar1=c3")
3046 in find_used_partitions(key_tree = "par2=c2") (**)
3047 in find_used_partitions(key_tree = "par1=c1")
3048 in prune_partitions(...)
3049 We apply partitioning limits as soon as possible, e.g. when we reach the
3050 depth (**), we find which partition(s) correspond to "par1=c1 AND par2=c2",
3051 and save them in ppar->part_iter.
3052 When we reach the depth (***), we find which subpartition(s) correspond to
3053 "subpar1=c3 AND subpar2=c5", and then mark appropriate subpartitions in
3054 appropriate subpartitions as used.
3056 It is possible that constraints on some partitioning fields are missing.
3057 For the above example, consider this stack state:
3058 in find_used_partitions(key_tree = "subpar2=c12") (***)
3059 in find_used_partitions(key_tree = "subpar1=c10")
3060 in find_used_partitions(key_tree = "par1=c2")
3061 in prune_partitions(...)
3062 Here we don't have constraints for all partitioning fields. Since we've
3063 never set the ppar->part_iter to contain used set of partitions, we use
3064 its default "all partitions" value. We get subpartition id for
3065 "subpar1=c3 AND subpar2=c5", and mark that subpartition as used in every
3066 partition.
3068 The inverse is also possible: we may get constraints on partitioning
3069 fields, but not constraints on subpartitioning fields. In that case,
3070 calls to find_used_partitions() with depth below (**) will return -1,
3071 and we will mark entire partition as used.
3073 TODO
3074 Replace recursion on SEL_ARG::left and SEL_ARG::right with a loop
3076 RETURN
3077 1 OK, one or more [sub]partitions are marked as used.
3078 0 The passed condition doesn't match any partitions
3079 -1 Couldn't infer any partition pruning "intervals" from the passed
3080 SEL_ARG* tree (which means that all partitions should be marked as
3081 used) Marking partitions as used is the responsibility of the caller.
3084 static
3085 int find_used_partitions(PART_PRUNE_PARAM *ppar, SEL_ARG *key_tree)
3087 int res, left_res=0, right_res=0;
3088 int partno= (int)key_tree->part;
3089 bool pushed= FALSE;
3090 bool set_full_part_if_bad_ret= FALSE;
3092 if (key_tree->left != &null_element)
3094 if (-1 == (left_res= find_used_partitions(ppar,key_tree->left)))
3095 return -1;
3098 if (key_tree->type == SEL_ARG::KEY_RANGE)
3100 if (partno == 0 && (NULL != ppar->part_info->get_part_iter_for_interval))
3103 Partitioning is done by RANGE|INTERVAL(monotonic_expr(fieldX)), and
3104 we got "const1 CMP fieldX CMP const2" interval <-- psergey-todo: change
3106 DBUG_EXECUTE("info", dbug_print_segment_range(key_tree,
3107 ppar->range_param.
3108 key_parts););
3109 res= ppar->part_info->
3110 get_part_iter_for_interval(ppar->part_info,
3111 FALSE,
3112 key_tree->min_value,
3113 key_tree->max_value,
3114 key_tree->min_flag | key_tree->max_flag,
3115 &ppar->part_iter);
3116 if (!res)
3117 goto go_right; /* res==0 --> no satisfying partitions */
3118 if (res == -1)
3120 //get a full range iterator
3121 init_all_partitions_iterator(ppar->part_info, &ppar->part_iter);
3124 Save our intent to mark full partition as used if we will not be able
3125 to obtain further limits on subpartitions
3127 set_full_part_if_bad_ret= TRUE;
3128 goto process_next_key_part;
3131 if (partno == ppar->last_subpart_partno &&
3132 (NULL != ppar->part_info->get_subpart_iter_for_interval))
3134 PARTITION_ITERATOR subpart_iter;
3135 DBUG_EXECUTE("info", dbug_print_segment_range(key_tree,
3136 ppar->range_param.
3137 key_parts););
3138 res= ppar->part_info->
3139 get_subpart_iter_for_interval(ppar->part_info,
3140 TRUE,
3141 key_tree->min_value,
3142 key_tree->max_value,
3143 key_tree->min_flag | key_tree->max_flag,
3144 &subpart_iter);
3145 DBUG_ASSERT(res); /* We can't get "no satisfying subpartitions" */
3146 if (res == -1)
3147 return -1; /* all subpartitions satisfy */
3149 uint32 subpart_id;
3150 bitmap_clear_all(&ppar->subparts_bitmap);
3151 while ((subpart_id= subpart_iter.get_next(&subpart_iter)) !=
3152 NOT_A_PARTITION_ID)
3153 bitmap_set_bit(&ppar->subparts_bitmap, subpart_id);
3155 /* Mark each partition as used in each subpartition. */
3156 uint32 part_id;
3157 while ((part_id= ppar->part_iter.get_next(&ppar->part_iter)) !=
3158 NOT_A_PARTITION_ID)
3160 for (uint i= 0; i < ppar->part_info->no_subparts; i++)
3161 if (bitmap_is_set(&ppar->subparts_bitmap, i))
3162 bitmap_set_bit(&ppar->part_info->used_partitions,
3163 part_id * ppar->part_info->no_subparts + i);
3165 goto go_right;
3168 if (key_tree->is_singlepoint())
3170 pushed= TRUE;
3171 ppar->cur_part_fields+= ppar->is_part_keypart[partno];
3172 ppar->cur_subpart_fields+= ppar->is_subpart_keypart[partno];
3173 *(ppar->arg_stack_end++) = key_tree;
3175 if (partno == ppar->last_part_partno &&
3176 ppar->cur_part_fields == ppar->part_fields)
3179 Ok, we've got "fieldN<=>constN"-type SEL_ARGs for all partitioning
3180 fields. Save all constN constants into table record buffer.
3182 store_selargs_to_rec(ppar, ppar->arg_stack, ppar->part_fields);
3183 DBUG_EXECUTE("info", dbug_print_singlepoint_range(ppar->arg_stack,
3184 ppar->part_fields););
3185 uint32 part_id;
3186 longlong func_value;
3187 /* Find in which partition the {const1, ...,constN} tuple goes */
3188 if (ppar->get_top_partition_id_func(ppar->part_info, &part_id,
3189 &func_value))
3191 res= 0; /* No satisfying partitions */
3192 goto pop_and_go_right;
3194 /* Rembember the limit we got - single partition #part_id */
3195 init_single_partition_iterator(part_id, &ppar->part_iter);
3198 If there are no subpartitions/we fail to get any limit for them,
3199 then we'll mark full partition as used.
3201 set_full_part_if_bad_ret= TRUE;
3202 goto process_next_key_part;
3205 if (partno == ppar->last_subpart_partno &&
3206 ppar->cur_subpart_fields == ppar->subpart_fields)
3209 Ok, we've got "fieldN<=>constN"-type SEL_ARGs for all subpartitioning
3210 fields. Save all constN constants into table record buffer.
3212 store_selargs_to_rec(ppar, ppar->arg_stack_end - ppar->subpart_fields,
3213 ppar->subpart_fields);
3214 DBUG_EXECUTE("info", dbug_print_singlepoint_range(ppar->arg_stack_end-
3215 ppar->subpart_fields,
3216 ppar->subpart_fields););
3217 /* Find the subpartition (it's HASH/KEY so we always have one) */
3218 partition_info *part_info= ppar->part_info;
3219 uint32 part_id, subpart_id;
3221 if (part_info->get_subpartition_id(part_info, &subpart_id))
3222 return 0;
3224 /* Mark this partition as used in each subpartition. */
3225 while ((part_id= ppar->part_iter.get_next(&ppar->part_iter)) !=
3226 NOT_A_PARTITION_ID)
3228 bitmap_set_bit(&part_info->used_partitions,
3229 part_id * part_info->no_subparts + subpart_id);
3231 res= 1; /* Some partitions were marked as used */
3232 goto pop_and_go_right;
3235 else
3238 Can't handle condition on current key part. If we're that deep that
3239 we're processing subpartititoning's key parts, this means we'll not be
3240 able to infer any suitable condition, so bail out.
3242 if (partno >= ppar->last_part_partno)
3243 return -1;
3247 process_next_key_part:
3248 if (key_tree->next_key_part)
3249 res= find_used_partitions(ppar, key_tree->next_key_part);
3250 else
3251 res= -1;
3253 if (set_full_part_if_bad_ret)
3255 if (res == -1)
3257 /* Got "full range" for subpartitioning fields */
3258 uint32 part_id;
3259 bool found= FALSE;
3260 while ((part_id= ppar->part_iter.get_next(&ppar->part_iter)) !=
3261 NOT_A_PARTITION_ID)
3263 ppar->mark_full_partition_used(ppar->part_info, part_id);
3264 found= TRUE;
3266 res= test(found);
3269 Restore the "used partitions iterator" to the default setting that
3270 specifies iteration over all partitions.
3272 init_all_partitions_iterator(ppar->part_info, &ppar->part_iter);
3275 if (pushed)
3277 pop_and_go_right:
3278 /* Pop this key part info off the "stack" */
3279 ppar->arg_stack_end--;
3280 ppar->cur_part_fields-= ppar->is_part_keypart[partno];
3281 ppar->cur_subpart_fields-= ppar->is_subpart_keypart[partno];
3284 if (res == -1)
3285 return -1;
3286 go_right:
3287 if (key_tree->right != &null_element)
3289 if (-1 == (right_res= find_used_partitions(ppar,key_tree->right)))
3290 return -1;
3292 return (left_res || right_res || res);
3296 static void mark_all_partitions_as_used(partition_info *part_info)
3298 bitmap_set_all(&part_info->used_partitions);
3303 Check if field types allow to construct partitioning index description
3305 SYNOPSIS
3306 fields_ok_for_partition_index()
3307 pfield NULL-terminated array of pointers to fields.
3309 DESCRIPTION
3310 For an array of fields, check if we can use all of the fields to create
3311 partitioning index description.
3313 We can't process GEOMETRY fields - for these fields singlepoint intervals
3314 cant be generated, and non-singlepoint are "special" kinds of intervals
3315 to which our processing logic can't be applied.
3317 It is not known if we could process ENUM fields, so they are disabled to be
3318 on the safe side.
3320 RETURN
3321 TRUE Yes, fields can be used in partitioning index
3322 FALSE Otherwise
3325 static bool fields_ok_for_partition_index(Field **pfield)
3327 if (!pfield)
3328 return FALSE;
3329 for (; (*pfield); pfield++)
3331 enum_field_types ftype= (*pfield)->real_type();
3332 if (ftype == MYSQL_TYPE_ENUM || ftype == MYSQL_TYPE_GEOMETRY)
3333 return FALSE;
3335 return TRUE;
3340 Create partition index description and fill related info in the context
3341 struct
3343 SYNOPSIS
3344 create_partition_index_description()
3345 prune_par INOUT Partition pruning context
3347 DESCRIPTION
3348 Create partition index description. Partition index description is:
3350 part_index(used_fields_list(part_expr), used_fields_list(subpart_expr))
3352 If partitioning/sub-partitioning uses BLOB or Geometry fields, then
3353 corresponding fields_list(...) is not included into index description
3354 and we don't perform partition pruning for partitions/subpartitions.
3356 RETURN
3357 TRUE Out of memory or can't do partition pruning at all
3358 FALSE OK
3361 static bool create_partition_index_description(PART_PRUNE_PARAM *ppar)
3363 RANGE_OPT_PARAM *range_par= &(ppar->range_param);
3364 partition_info *part_info= ppar->part_info;
3365 uint used_part_fields, used_subpart_fields;
3367 used_part_fields= fields_ok_for_partition_index(part_info->part_field_array) ?
3368 part_info->no_part_fields : 0;
3369 used_subpart_fields=
3370 fields_ok_for_partition_index(part_info->subpart_field_array)?
3371 part_info->no_subpart_fields : 0;
3373 uint total_parts= used_part_fields + used_subpart_fields;
3375 ppar->part_fields= used_part_fields;
3376 ppar->last_part_partno= (int)used_part_fields - 1;
3378 ppar->subpart_fields= used_subpart_fields;
3379 ppar->last_subpart_partno=
3380 used_subpart_fields?(int)(used_part_fields + used_subpart_fields - 1): -1;
3382 if (part_info->is_sub_partitioned())
3384 ppar->mark_full_partition_used= mark_full_partition_used_with_parts;
3385 ppar->get_top_partition_id_func= part_info->get_part_partition_id;
3387 else
3389 ppar->mark_full_partition_used= mark_full_partition_used_no_parts;
3390 ppar->get_top_partition_id_func= part_info->get_partition_id;
3393 KEY_PART *key_part;
3394 MEM_ROOT *alloc= range_par->mem_root;
3395 if (!total_parts ||
3396 !(key_part= (KEY_PART*)alloc_root(alloc, sizeof(KEY_PART)*
3397 total_parts)) ||
3398 !(ppar->arg_stack= (SEL_ARG**)alloc_root(alloc, sizeof(SEL_ARG*)*
3399 total_parts)) ||
3400 !(ppar->is_part_keypart= (my_bool*)alloc_root(alloc, sizeof(my_bool)*
3401 total_parts)) ||
3402 !(ppar->is_subpart_keypart= (my_bool*)alloc_root(alloc, sizeof(my_bool)*
3403 total_parts)))
3404 return TRUE;
3406 if (ppar->subpart_fields)
3408 my_bitmap_map *buf;
3409 uint32 bufsize= bitmap_buffer_size(ppar->part_info->no_subparts);
3410 if (!(buf= (my_bitmap_map*) alloc_root(alloc, bufsize)))
3411 return TRUE;
3412 bitmap_init(&ppar->subparts_bitmap, buf, ppar->part_info->no_subparts,
3413 FALSE);
3415 range_par->key_parts= key_part;
3416 Field **field= (ppar->part_fields)? part_info->part_field_array :
3417 part_info->subpart_field_array;
3418 bool in_subpart_fields= FALSE;
3419 for (uint part= 0; part < total_parts; part++, key_part++)
3421 key_part->key= 0;
3422 key_part->part= part;
3423 key_part->store_length= key_part->length= (uint16) (*field)->key_length();
3424 if ((*field)->real_maybe_null())
3425 key_part->store_length+= HA_KEY_NULL_LENGTH;
3426 if ((*field)->type() == MYSQL_TYPE_BLOB ||
3427 (*field)->real_type() == MYSQL_TYPE_VARCHAR)
3428 key_part->store_length+= HA_KEY_BLOB_LENGTH;
3430 DBUG_PRINT("info", ("part %u length %u store_length %u", part,
3431 key_part->length, key_part->store_length));
3433 key_part->field= (*field);
3434 key_part->image_type = Field::itRAW;
3436 We set keypart flag to 0 here as the only HA_PART_KEY_SEG is checked
3437 in the RangeAnalysisModule.
3439 key_part->flag= 0;
3440 /* We don't set key_parts->null_bit as it will not be used */
3442 ppar->is_part_keypart[part]= !in_subpart_fields;
3443 ppar->is_subpart_keypart[part]= in_subpart_fields;
3446 Check if this was last field in this array, in this case we
3447 switch to subpartitioning fields. (This will only happens if
3448 there are subpartitioning fields to cater for).
3450 if (!*(++field))
3452 field= part_info->subpart_field_array;
3453 in_subpart_fields= TRUE;
3456 range_par->key_parts_end= key_part;
3458 DBUG_EXECUTE("info", print_partitioning_index(range_par->key_parts,
3459 range_par->key_parts_end););
3460 return FALSE;
3464 #ifndef DBUG_OFF
3466 static void print_partitioning_index(KEY_PART *parts, KEY_PART *parts_end)
3468 DBUG_ENTER("print_partitioning_index");
3469 DBUG_LOCK_FILE;
3470 fprintf(DBUG_FILE, "partitioning INDEX(");
3471 for (KEY_PART *p=parts; p != parts_end; p++)
3473 fprintf(DBUG_FILE, "%s%s", p==parts?"":" ,", p->field->field_name);
3475 fputs(");\n", DBUG_FILE);
3476 DBUG_UNLOCK_FILE;
3477 DBUG_VOID_RETURN;
3480 /* Print field value into debug trace, in NULL-aware way. */
3481 static void dbug_print_field(Field *field)
3483 if (field->is_real_null())
3484 fprintf(DBUG_FILE, "NULL");
3485 else
3487 char buf[256];
3488 String str(buf, sizeof(buf), &my_charset_bin);
3489 str.length(0);
3490 String *pstr;
3491 pstr= field->val_str(&str);
3492 fprintf(DBUG_FILE, "'%s'", pstr->c_ptr_safe());
3497 /* Print a "c1 < keypartX < c2" - type interval into debug trace. */
3498 static void dbug_print_segment_range(SEL_ARG *arg, KEY_PART *part)
3500 DBUG_ENTER("dbug_print_segment_range");
3501 DBUG_LOCK_FILE;
3502 if (!(arg->min_flag & NO_MIN_RANGE))
3504 store_key_image_to_rec(part->field, arg->min_value, part->length);
3505 dbug_print_field(part->field);
3506 if (arg->min_flag & NEAR_MIN)
3507 fputs(" < ", DBUG_FILE);
3508 else
3509 fputs(" <= ", DBUG_FILE);
3512 fprintf(DBUG_FILE, "%s", part->field->field_name);
3514 if (!(arg->max_flag & NO_MAX_RANGE))
3516 if (arg->max_flag & NEAR_MAX)
3517 fputs(" < ", DBUG_FILE);
3518 else
3519 fputs(" <= ", DBUG_FILE);
3520 store_key_image_to_rec(part->field, arg->max_value, part->length);
3521 dbug_print_field(part->field);
3523 fputs("\n", DBUG_FILE);
3524 DBUG_UNLOCK_FILE;
3525 DBUG_VOID_RETURN;
3530 Print a singlepoint multi-keypart range interval to debug trace
3532 SYNOPSIS
3533 dbug_print_singlepoint_range()
3534 start Array of SEL_ARG* ptrs representing conditions on key parts
3535 num Number of elements in the array.
3537 DESCRIPTION
3538 This function prints a "keypartN=constN AND ... AND keypartK=constK"-type
3539 interval to debug trace.
3542 static void dbug_print_singlepoint_range(SEL_ARG **start, uint num)
3544 DBUG_ENTER("dbug_print_singlepoint_range");
3545 DBUG_LOCK_FILE;
3546 SEL_ARG **end= start + num;
3548 for (SEL_ARG **arg= start; arg != end; arg++)
3550 Field *field= (*arg)->field;
3551 fprintf(DBUG_FILE, "%s%s=", (arg==start)?"":", ", field->field_name);
3552 dbug_print_field(field);
3554 fputs("\n", DBUG_FILE);
3555 DBUG_UNLOCK_FILE;
3556 DBUG_VOID_RETURN;
3558 #endif
3560 /****************************************************************************
3561 * Partition pruning code ends
3562 ****************************************************************************/
3563 #endif
3567 Get cost of 'sweep' full records retrieval.
3568 SYNOPSIS
3569 get_sweep_read_cost()
3570 param Parameter from test_quick_select
3571 records # of records to be retrieved
3572 RETURN
3573 cost of sweep
3576 double get_sweep_read_cost(const PARAM *param, ha_rows records)
3578 double result;
3579 DBUG_ENTER("get_sweep_read_cost");
3580 if (param->table->file->primary_key_is_clustered())
3582 result= param->table->file->read_time(param->table->s->primary_key,
3583 (uint)records, records);
3585 else
3587 double n_blocks=
3588 ceil(ulonglong2double(param->table->file->stats.data_file_length) /
3589 IO_SIZE);
3590 double busy_blocks=
3591 n_blocks * (1.0 - pow(1.0 - 1.0/n_blocks, rows2double(records)));
3592 if (busy_blocks < 1.0)
3593 busy_blocks= 1.0;
3594 DBUG_PRINT("info",("sweep: nblocks: %g, busy_blocks: %g", n_blocks,
3595 busy_blocks));
3597 Disabled: Bail out if # of blocks to read is bigger than # of blocks in
3598 table data file.
3599 if (max_cost != DBL_MAX && (busy_blocks+index_reads_cost) >= n_blocks)
3600 return 1;
3602 JOIN *join= param->thd->lex->select_lex.join;
3603 if (!join || join->tables == 1)
3605 /* No join, assume reading is done in one 'sweep' */
3606 result= busy_blocks*(DISK_SEEK_BASE_COST +
3607 DISK_SEEK_PROP_COST*n_blocks/busy_blocks);
3609 else
3612 Possibly this is a join with source table being non-last table, so
3613 assume that disk seeks are random here.
3615 result= busy_blocks;
3618 DBUG_PRINT("return",("cost: %g", result));
3619 DBUG_RETURN(result);
3624 Get best plan for a SEL_IMERGE disjunctive expression.
3625 SYNOPSIS
3626 get_best_disjunct_quick()
3627 param Parameter from check_quick_select function
3628 imerge Expression to use
3629 read_time Don't create scans with cost > read_time
3631 NOTES
3632 index_merge cost is calculated as follows:
3633 index_merge_cost =
3634 cost(index_reads) + (see #1)
3635 cost(rowid_to_row_scan) + (see #2)
3636 cost(unique_use) (see #3)
3638 1. cost(index_reads) =SUM_i(cost(index_read_i))
3639 For non-CPK scans,
3640 cost(index_read_i) = {cost of ordinary 'index only' scan}
3641 For CPK scan,
3642 cost(index_read_i) = {cost of non-'index only' scan}
3644 2. cost(rowid_to_row_scan)
3645 If table PK is clustered then
3646 cost(rowid_to_row_scan) =
3647 {cost of ordinary clustered PK scan with n_ranges=n_rows}
3649 Otherwise, we use the following model to calculate costs:
3650 We need to retrieve n_rows rows from file that occupies n_blocks blocks.
3651 We assume that offsets of rows we need are independent variates with
3652 uniform distribution in [0..max_file_offset] range.
3654 We'll denote block as "busy" if it contains row(s) we need to retrieve
3655 and "empty" if doesn't contain rows we need.
3657 Probability that a block is empty is (1 - 1/n_blocks)^n_rows (this
3658 applies to any block in file). Let x_i be a variate taking value 1 if
3659 block #i is empty and 0 otherwise.
3661 Then E(x_i) = (1 - 1/n_blocks)^n_rows;
3663 E(n_empty_blocks) = E(sum(x_i)) = sum(E(x_i)) =
3664 = n_blocks * ((1 - 1/n_blocks)^n_rows) =
3665 ~= n_blocks * exp(-n_rows/n_blocks).
3667 E(n_busy_blocks) = n_blocks*(1 - (1 - 1/n_blocks)^n_rows) =
3668 ~= n_blocks * (1 - exp(-n_rows/n_blocks)).
3670 Average size of "hole" between neighbor non-empty blocks is
3671 E(hole_size) = n_blocks/E(n_busy_blocks).
3673 The total cost of reading all needed blocks in one "sweep" is:
3675 E(n_busy_blocks)*
3676 (DISK_SEEK_BASE_COST + DISK_SEEK_PROP_COST*n_blocks/E(n_busy_blocks)).
3678 3. Cost of Unique use is calculated in Unique::get_use_cost function.
3680 ROR-union cost is calculated in the same way index_merge, but instead of
3681 Unique a priority queue is used.
3683 RETURN
3684 Created read plan
3685 NULL - Out of memory or no read scan could be built.
3688 static
3689 TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
3690 double read_time)
3692 SEL_TREE **ptree;
3693 TRP_INDEX_MERGE *imerge_trp= NULL;
3694 uint n_child_scans= imerge->trees_next - imerge->trees;
3695 TRP_RANGE **range_scans;
3696 TRP_RANGE **cur_child;
3697 TRP_RANGE **cpk_scan= NULL;
3698 bool imerge_too_expensive= FALSE;
3699 double imerge_cost= 0.0;
3700 ha_rows cpk_scan_records= 0;
3701 ha_rows non_cpk_scan_records= 0;
3702 bool pk_is_clustered= param->table->file->primary_key_is_clustered();
3703 bool all_scans_ror_able= TRUE;
3704 bool all_scans_rors= TRUE;
3705 uint unique_calc_buff_size;
3706 TABLE_READ_PLAN **roru_read_plans;
3707 TABLE_READ_PLAN **cur_roru_plan;
3708 double roru_index_costs;
3709 ha_rows roru_total_records;
3710 double roru_intersect_part= 1.0;
3711 DBUG_ENTER("get_best_disjunct_quick");
3712 DBUG_PRINT("info", ("Full table scan cost: %g", read_time));
3714 if (!(range_scans= (TRP_RANGE**)alloc_root(param->mem_root,
3715 sizeof(TRP_RANGE*)*
3716 n_child_scans)))
3717 DBUG_RETURN(NULL);
3719 Collect best 'range' scan for each of disjuncts, and, while doing so,
3720 analyze possibility of ROR scans. Also calculate some values needed by
3721 other parts of the code.
3723 for (ptree= imerge->trees, cur_child= range_scans;
3724 ptree != imerge->trees_next;
3725 ptree++, cur_child++)
3727 DBUG_EXECUTE("info", print_sel_tree(param, *ptree, &(*ptree)->keys_map,
3728 "tree in SEL_IMERGE"););
3729 if (!(*cur_child= get_key_scans_params(param, *ptree, TRUE, FALSE, read_time)))
3732 One of index scans in this index_merge is more expensive than entire
3733 table read for another available option. The entire index_merge (and
3734 any possible ROR-union) will be more expensive then, too. We continue
3735 here only to update SQL_SELECT members.
3737 imerge_too_expensive= TRUE;
3739 if (imerge_too_expensive)
3740 continue;
3742 imerge_cost += (*cur_child)->read_cost;
3743 all_scans_ror_able &= ((*ptree)->n_ror_scans > 0);
3744 all_scans_rors &= (*cur_child)->is_ror;
3745 if (pk_is_clustered &&
3746 param->real_keynr[(*cur_child)->key_idx] ==
3747 param->table->s->primary_key)
3749 cpk_scan= cur_child;
3750 cpk_scan_records= (*cur_child)->records;
3752 else
3753 non_cpk_scan_records += (*cur_child)->records;
3756 DBUG_PRINT("info", ("index_merge scans cost %g", imerge_cost));
3757 if (imerge_too_expensive || (imerge_cost > read_time) ||
3758 ((non_cpk_scan_records+cpk_scan_records >= param->table->file->stats.records) &&
3759 read_time != DBL_MAX))
3762 Bail out if it is obvious that both index_merge and ROR-union will be
3763 more expensive
3765 DBUG_PRINT("info", ("Sum of index_merge scans is more expensive than "
3766 "full table scan, bailing out"));
3767 DBUG_RETURN(NULL);
3771 If all scans happen to be ROR, proceed to generate a ROR-union plan (it's
3772 guaranteed to be cheaper than non-ROR union), unless ROR-unions are
3773 disabled in @@optimizer_switch
3775 if (all_scans_rors &&
3776 optimizer_flag(param->thd, OPTIMIZER_SWITCH_INDEX_MERGE_UNION))
3778 roru_read_plans= (TABLE_READ_PLAN**)range_scans;
3779 goto skip_to_ror_scan;
3782 if (cpk_scan)
3785 Add one ROWID comparison for each row retrieved on non-CPK scan. (it
3786 is done in QUICK_RANGE_SELECT::row_in_ranges)
3788 imerge_cost += non_cpk_scan_records / TIME_FOR_COMPARE_ROWID;
3791 /* Calculate cost(rowid_to_row_scan) */
3792 imerge_cost += get_sweep_read_cost(param, non_cpk_scan_records);
3793 DBUG_PRINT("info",("index_merge cost with rowid-to-row scan: %g",
3794 imerge_cost));
3795 if (imerge_cost > read_time ||
3796 !optimizer_flag(param->thd, OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION))
3798 goto build_ror_index_merge;
3801 /* Add Unique operations cost */
3802 unique_calc_buff_size=
3803 Unique::get_cost_calc_buff_size((ulong)non_cpk_scan_records,
3804 param->table->file->ref_length,
3805 param->thd->variables.sortbuff_size);
3806 if (param->imerge_cost_buff_size < unique_calc_buff_size)
3808 if (!(param->imerge_cost_buff= (uint*)alloc_root(param->mem_root,
3809 unique_calc_buff_size)))
3810 DBUG_RETURN(NULL);
3811 param->imerge_cost_buff_size= unique_calc_buff_size;
3814 imerge_cost +=
3815 Unique::get_use_cost(param->imerge_cost_buff, (uint)non_cpk_scan_records,
3816 param->table->file->ref_length,
3817 param->thd->variables.sortbuff_size);
3818 DBUG_PRINT("info",("index_merge total cost: %g (wanted: less then %g)",
3819 imerge_cost, read_time));
3820 if (imerge_cost < read_time)
3822 if ((imerge_trp= new (param->mem_root)TRP_INDEX_MERGE))
3824 imerge_trp->read_cost= imerge_cost;
3825 imerge_trp->records= non_cpk_scan_records + cpk_scan_records;
3826 imerge_trp->records= min(imerge_trp->records,
3827 param->table->file->stats.records);
3828 imerge_trp->range_scans= range_scans;
3829 imerge_trp->range_scans_end= range_scans + n_child_scans;
3830 read_time= imerge_cost;
3834 build_ror_index_merge:
3835 if (!all_scans_ror_able ||
3836 param->thd->lex->sql_command == SQLCOM_DELETE ||
3837 !optimizer_flag(param->thd, OPTIMIZER_SWITCH_INDEX_MERGE_UNION))
3838 DBUG_RETURN(imerge_trp);
3840 /* Ok, it is possible to build a ROR-union, try it. */
3841 bool dummy;
3842 if (!(roru_read_plans=
3843 (TABLE_READ_PLAN**)alloc_root(param->mem_root,
3844 sizeof(TABLE_READ_PLAN*)*
3845 n_child_scans)))
3846 DBUG_RETURN(imerge_trp);
3847 skip_to_ror_scan:
3848 roru_index_costs= 0.0;
3849 roru_total_records= 0;
3850 cur_roru_plan= roru_read_plans;
3852 /* Find 'best' ROR scan for each of trees in disjunction */
3853 for (ptree= imerge->trees, cur_child= range_scans;
3854 ptree != imerge->trees_next;
3855 ptree++, cur_child++, cur_roru_plan++)
3858 Assume the best ROR scan is the one that has cheapest full-row-retrieval
3859 scan cost.
3860 Also accumulate index_only scan costs as we'll need them to calculate
3861 overall index_intersection cost.
3863 double cost;
3864 if ((*cur_child)->is_ror)
3866 /* Ok, we have index_only cost, now get full rows scan cost */
3867 cost= param->table->file->
3868 read_time(param->real_keynr[(*cur_child)->key_idx], 1,
3869 (*cur_child)->records) +
3870 rows2double((*cur_child)->records) / TIME_FOR_COMPARE;
3872 else
3873 cost= read_time;
3875 TABLE_READ_PLAN *prev_plan= *cur_child;
3876 if (!(*cur_roru_plan= get_best_ror_intersect(param, *ptree, cost,
3877 &dummy)))
3879 if (prev_plan->is_ror)
3880 *cur_roru_plan= prev_plan;
3881 else
3882 DBUG_RETURN(imerge_trp);
3883 roru_index_costs += (*cur_roru_plan)->read_cost;
3885 else
3886 roru_index_costs +=
3887 ((TRP_ROR_INTERSECT*)(*cur_roru_plan))->index_scan_costs;
3888 roru_total_records += (*cur_roru_plan)->records;
3889 roru_intersect_part *= (*cur_roru_plan)->records /
3890 param->table->file->stats.records;
3894 rows to retrieve=
3895 SUM(rows_in_scan_i) - table_rows * PROD(rows_in_scan_i / table_rows).
3896 This is valid because index_merge construction guarantees that conditions
3897 in disjunction do not share key parts.
3899 roru_total_records -= (ha_rows)(roru_intersect_part*
3900 param->table->file->stats.records);
3901 /* ok, got a ROR read plan for each of the disjuncts
3902 Calculate cost:
3903 cost(index_union_scan(scan_1, ... scan_n)) =
3904 SUM_i(cost_of_index_only_scan(scan_i)) +
3905 queue_use_cost(rowid_len, n) +
3906 cost_of_row_retrieval
3907 See get_merge_buffers_cost function for queue_use_cost formula derivation.
3910 double roru_total_cost;
3911 roru_total_cost= roru_index_costs +
3912 rows2double(roru_total_records)*log((double)n_child_scans) /
3913 (TIME_FOR_COMPARE_ROWID * M_LN2) +
3914 get_sweep_read_cost(param, roru_total_records);
3916 DBUG_PRINT("info", ("ROR-union: cost %g, %d members", roru_total_cost,
3917 n_child_scans));
3918 TRP_ROR_UNION* roru;
3919 if (roru_total_cost < read_time)
3921 if ((roru= new (param->mem_root) TRP_ROR_UNION))
3923 roru->first_ror= roru_read_plans;
3924 roru->last_ror= roru_read_plans + n_child_scans;
3925 roru->read_cost= roru_total_cost;
3926 roru->records= roru_total_records;
3927 DBUG_RETURN(roru);
3930 DBUG_RETURN(imerge_trp);
3935 Calculate cost of 'index only' scan for given index and number of records.
3937 SYNOPSIS
3938 get_index_only_read_time()
3939 param parameters structure
3940 records #of records to read
3941 keynr key to read
3943 NOTES
3944 It is assumed that we will read trough the whole key range and that all
3945 key blocks are half full (normally things are much better). It is also
3946 assumed that each time we read the next key from the index, the handler
3947 performs a random seek, thus the cost is proportional to the number of
3948 blocks read.
3950 TODO:
3951 Move this to handler->read_time() by adding a flag 'index-only-read' to
3952 this call. The reason for doing this is that the current function doesn't
3953 handle the case when the row is stored in the b-tree (like in innodb
3954 clustered index)
3957 static double get_index_only_read_time(const PARAM* param, ha_rows records,
3958 int keynr)
3960 double read_time;
3961 uint keys_per_block= (param->table->file->stats.block_size/2/
3962 (param->table->key_info[keynr].key_length+
3963 param->table->file->ref_length) + 1);
3964 read_time=((double) (records+keys_per_block-1)/
3965 (double) keys_per_block);
3966 return read_time;
3970 typedef struct st_ror_scan_info
3972 uint idx; /* # of used key in param->keys */
3973 uint keynr; /* # of used key in table */
3974 ha_rows records; /* estimate of # records this scan will return */
3976 /* Set of intervals over key fields that will be used for row retrieval. */
3977 SEL_ARG *sel_arg;
3979 /* Fields used in the query and covered by this ROR scan. */
3980 MY_BITMAP covered_fields;
3981 uint used_fields_covered; /* # of set bits in covered_fields */
3982 int key_rec_length; /* length of key record (including rowid) */
3985 Cost of reading all index records with values in sel_arg intervals set
3986 (assuming there is no need to access full table records)
3988 double index_read_cost;
3989 uint first_uncovered_field; /* first unused bit in covered_fields */
3990 uint key_components; /* # of parts in the key */
3991 } ROR_SCAN_INFO;
3995 Create ROR_SCAN_INFO* structure with a single ROR scan on index idx using
3996 sel_arg set of intervals.
3998 SYNOPSIS
3999 make_ror_scan()
4000 param Parameter from test_quick_select function
4001 idx Index of key in param->keys
4002 sel_arg Set of intervals for a given key
4004 RETURN
4005 NULL - out of memory
4006 ROR scan structure containing a scan for {idx, sel_arg}
4009 static
4010 ROR_SCAN_INFO *make_ror_scan(const PARAM *param, int idx, SEL_ARG *sel_arg)
4012 ROR_SCAN_INFO *ror_scan;
4013 my_bitmap_map *bitmap_buf;
4014 uint keynr;
4015 DBUG_ENTER("make_ror_scan");
4017 if (!(ror_scan= (ROR_SCAN_INFO*)alloc_root(param->mem_root,
4018 sizeof(ROR_SCAN_INFO))))
4019 DBUG_RETURN(NULL);
4021 ror_scan->idx= idx;
4022 ror_scan->keynr= keynr= param->real_keynr[idx];
4023 ror_scan->key_rec_length= (param->table->key_info[keynr].key_length +
4024 param->table->file->ref_length);
4025 ror_scan->sel_arg= sel_arg;
4026 ror_scan->records= param->table->quick_rows[keynr];
4028 if (!(bitmap_buf= (my_bitmap_map*) alloc_root(param->mem_root,
4029 param->fields_bitmap_size)))
4030 DBUG_RETURN(NULL);
4032 if (bitmap_init(&ror_scan->covered_fields, bitmap_buf,
4033 param->table->s->fields, FALSE))
4034 DBUG_RETURN(NULL);
4035 bitmap_clear_all(&ror_scan->covered_fields);
4037 KEY_PART_INFO *key_part= param->table->key_info[keynr].key_part;
4038 KEY_PART_INFO *key_part_end= key_part +
4039 param->table->key_info[keynr].key_parts;
4040 for (;key_part != key_part_end; ++key_part)
4042 if (bitmap_is_set(&param->needed_fields, key_part->fieldnr-1))
4043 bitmap_set_bit(&ror_scan->covered_fields, key_part->fieldnr-1);
4045 ror_scan->index_read_cost=
4046 get_index_only_read_time(param, param->table->quick_rows[ror_scan->keynr],
4047 ror_scan->keynr);
4048 DBUG_RETURN(ror_scan);
4053 Compare two ROR_SCAN_INFO** by E(#records_matched) * key_record_length.
4054 SYNOPSIS
4055 cmp_ror_scan_info()
4056 a ptr to first compared value
4057 b ptr to second compared value
4059 RETURN
4060 -1 a < b
4061 0 a = b
4062 1 a > b
4065 static int cmp_ror_scan_info(ROR_SCAN_INFO** a, ROR_SCAN_INFO** b)
4067 double val1= rows2double((*a)->records) * (*a)->key_rec_length;
4068 double val2= rows2double((*b)->records) * (*b)->key_rec_length;
4069 return (val1 < val2)? -1: (val1 == val2)? 0 : 1;
4073 Compare two ROR_SCAN_INFO** by
4074 (#covered fields in F desc,
4075 #components asc,
4076 number of first not covered component asc)
4078 SYNOPSIS
4079 cmp_ror_scan_info_covering()
4080 a ptr to first compared value
4081 b ptr to second compared value
4083 RETURN
4084 -1 a < b
4085 0 a = b
4086 1 a > b
4089 static int cmp_ror_scan_info_covering(ROR_SCAN_INFO** a, ROR_SCAN_INFO** b)
4091 if ((*a)->used_fields_covered > (*b)->used_fields_covered)
4092 return -1;
4093 if ((*a)->used_fields_covered < (*b)->used_fields_covered)
4094 return 1;
4095 if ((*a)->key_components < (*b)->key_components)
4096 return -1;
4097 if ((*a)->key_components > (*b)->key_components)
4098 return 1;
4099 if ((*a)->first_uncovered_field < (*b)->first_uncovered_field)
4100 return -1;
4101 if ((*a)->first_uncovered_field > (*b)->first_uncovered_field)
4102 return 1;
4103 return 0;
4107 /* Auxiliary structure for incremental ROR-intersection creation */
4108 typedef struct
4110 const PARAM *param;
4111 MY_BITMAP covered_fields; /* union of fields covered by all scans */
4113 Fraction of table records that satisfies conditions of all scans.
4114 This is the number of full records that will be retrieved if a
4115 non-index_only index intersection will be employed.
4117 double out_rows;
4118 /* TRUE if covered_fields is a superset of needed_fields */
4119 bool is_covering;
4121 ha_rows index_records; /* sum(#records to look in indexes) */
4122 double index_scan_costs; /* SUM(cost of 'index-only' scans) */
4123 double total_cost;
4124 } ROR_INTERSECT_INFO;
4128 Allocate a ROR_INTERSECT_INFO and initialize it to contain zero scans.
4130 SYNOPSIS
4131 ror_intersect_init()
4132 param Parameter from test_quick_select
4134 RETURN
4135 allocated structure
4136 NULL on error
4139 static
4140 ROR_INTERSECT_INFO* ror_intersect_init(const PARAM *param)
4142 ROR_INTERSECT_INFO *info;
4143 my_bitmap_map* buf;
4144 if (!(info= (ROR_INTERSECT_INFO*)alloc_root(param->mem_root,
4145 sizeof(ROR_INTERSECT_INFO))))
4146 return NULL;
4147 info->param= param;
4148 if (!(buf= (my_bitmap_map*) alloc_root(param->mem_root,
4149 param->fields_bitmap_size)))
4150 return NULL;
4151 if (bitmap_init(&info->covered_fields, buf, param->table->s->fields,
4152 FALSE))
4153 return NULL;
4154 info->is_covering= FALSE;
4155 info->index_scan_costs= 0.0;
4156 info->index_records= 0;
4157 info->out_rows= (double) param->table->file->stats.records;
4158 bitmap_clear_all(&info->covered_fields);
4159 return info;
4162 void ror_intersect_cpy(ROR_INTERSECT_INFO *dst, const ROR_INTERSECT_INFO *src)
4164 dst->param= src->param;
4165 memcpy(dst->covered_fields.bitmap, src->covered_fields.bitmap,
4166 no_bytes_in_map(&src->covered_fields));
4167 dst->out_rows= src->out_rows;
4168 dst->is_covering= src->is_covering;
4169 dst->index_records= src->index_records;
4170 dst->index_scan_costs= src->index_scan_costs;
4171 dst->total_cost= src->total_cost;
4176 Get selectivity of a ROR scan wrt ROR-intersection.
4178 SYNOPSIS
4179 ror_scan_selectivity()
4180 info ROR-interection
4181 scan ROR scan
4183 NOTES
4184 Suppose we have a condition on several keys
4185 cond=k_11=c_11 AND k_12=c_12 AND ... // parts of first key
4186 k_21=c_21 AND k_22=c_22 AND ... // parts of second key
4188 k_n1=c_n1 AND k_n3=c_n3 AND ... (1) //parts of the key used by *scan
4190 where k_ij may be the same as any k_pq (i.e. keys may have common parts).
4192 A full row is retrieved if entire condition holds.
4194 The recursive procedure for finding P(cond) is as follows:
4196 First step:
4197 Pick 1st part of 1st key and break conjunction (1) into two parts:
4198 cond= (k_11=c_11 AND R)
4200 Here R may still contain condition(s) equivalent to k_11=c_11.
4201 Nevertheless, the following holds:
4203 P(k_11=c_11 AND R) = P(k_11=c_11) * P(R | k_11=c_11).
4205 Mark k_11 as fixed field (and satisfied condition) F, save P(F),
4206 save R to be cond and proceed to recursion step.
4208 Recursion step:
4209 We have a set of fixed fields/satisfied conditions) F, probability P(F),
4210 and remaining conjunction R
4211 Pick next key part on current key and its condition "k_ij=c_ij".
4212 We will add "k_ij=c_ij" into F and update P(F).
4213 Lets denote k_ij as t, R = t AND R1, where R1 may still contain t. Then
4215 P((t AND R1)|F) = P(t|F) * P(R1|t|F) = P(t|F) * P(R1|(t AND F)) (2)
4217 (where '|' mean conditional probability, not "or")
4219 Consider the first multiplier in (2). One of the following holds:
4220 a) F contains condition on field used in t (i.e. t AND F = F).
4221 Then P(t|F) = 1
4223 b) F doesn't contain condition on field used in t. Then F and t are
4224 considered independent.
4226 P(t|F) = P(t|(fields_before_t_in_key AND other_fields)) =
4227 = P(t|fields_before_t_in_key).
4229 P(t|fields_before_t_in_key) = #records(fields_before_t_in_key) /
4230 #records(fields_before_t_in_key, t)
4232 The second multiplier is calculated by applying this step recursively.
4234 IMPLEMENTATION
4235 This function calculates the result of application of the "recursion step"
4236 described above for all fixed key members of a single key, accumulating set
4237 of covered fields, selectivity, etc.
4239 The calculation is conducted as follows:
4240 Lets denote #records(keypart1, ... keypartK) as n_k. We need to calculate
4242 n_{k1} n_{k2}
4243 --------- * --------- * .... (3)
4244 n_{k1-1} n_{k2-1}
4246 where k1,k2,... are key parts which fields were not yet marked as fixed
4247 ( this is result of application of option b) of the recursion step for
4248 parts of a single key).
4249 Since it is reasonable to expect that most of the fields are not marked
4250 as fixed, we calculate (3) as
4252 n_{i1} n_{i2}
4253 (3) = n_{max_key_part} / ( --------- * --------- * .... )
4254 n_{i1-1} n_{i2-1}
4256 where i1,i2, .. are key parts that were already marked as fixed.
4258 In order to minimize number of expensive records_in_range calls we group
4259 and reduce adjacent fractions.
4261 RETURN
4262 Selectivity of given ROR scan.
4265 static double ror_scan_selectivity(const ROR_INTERSECT_INFO *info,
4266 const ROR_SCAN_INFO *scan)
4268 double selectivity_mult= 1.0;
4269 KEY_PART_INFO *key_part= info->param->table->key_info[scan->keynr].key_part;
4270 uchar key_val[MAX_KEY_LENGTH+MAX_FIELD_WIDTH]; /* key values tuple */
4271 uchar *key_ptr= key_val;
4272 SEL_ARG *sel_arg, *tuple_arg= NULL;
4273 key_part_map keypart_map= 0;
4274 bool cur_covered;
4275 bool prev_covered= test(bitmap_is_set(&info->covered_fields,
4276 key_part->fieldnr-1));
4277 key_range min_range;
4278 key_range max_range;
4279 min_range.key= key_val;
4280 min_range.flag= HA_READ_KEY_EXACT;
4281 max_range.key= key_val;
4282 max_range.flag= HA_READ_AFTER_KEY;
4283 ha_rows prev_records= info->param->table->file->stats.records;
4284 DBUG_ENTER("ror_scan_selectivity");
4286 for (sel_arg= scan->sel_arg; sel_arg;
4287 sel_arg= sel_arg->next_key_part)
4289 DBUG_PRINT("info",("sel_arg step"));
4290 cur_covered= test(bitmap_is_set(&info->covered_fields,
4291 key_part[sel_arg->part].fieldnr-1));
4292 if (cur_covered != prev_covered)
4294 /* create (part1val, ..., part{n-1}val) tuple. */
4295 ha_rows records;
4296 if (!tuple_arg)
4298 tuple_arg= scan->sel_arg;
4299 /* Here we use the length of the first key part */
4300 tuple_arg->store_min(key_part->store_length, &key_ptr, 0);
4301 keypart_map= 1;
4303 while (tuple_arg->next_key_part != sel_arg)
4305 tuple_arg= tuple_arg->next_key_part;
4306 tuple_arg->store_min(key_part[tuple_arg->part].store_length,
4307 &key_ptr, 0);
4308 keypart_map= (keypart_map << 1) | 1;
4310 min_range.length= max_range.length= (size_t) (key_ptr - key_val);
4311 min_range.keypart_map= max_range.keypart_map= keypart_map;
4312 records= (info->param->table->file->
4313 records_in_range(scan->keynr, &min_range, &max_range));
4314 if (cur_covered)
4316 /* uncovered -> covered */
4317 double tmp= rows2double(records)/rows2double(prev_records);
4318 DBUG_PRINT("info", ("Selectivity multiplier: %g", tmp));
4319 selectivity_mult *= tmp;
4320 prev_records= HA_POS_ERROR;
4322 else
4324 /* covered -> uncovered */
4325 prev_records= records;
4328 prev_covered= cur_covered;
4330 if (!prev_covered)
4332 double tmp= rows2double(info->param->table->quick_rows[scan->keynr]) /
4333 rows2double(prev_records);
4334 DBUG_PRINT("info", ("Selectivity multiplier: %g", tmp));
4335 selectivity_mult *= tmp;
4337 DBUG_PRINT("info", ("Returning multiplier: %g", selectivity_mult));
4338 DBUG_RETURN(selectivity_mult);
4343 Check if adding a ROR scan to a ROR-intersection reduces its cost of
4344 ROR-intersection and if yes, update parameters of ROR-intersection,
4345 including its cost.
4347 SYNOPSIS
4348 ror_intersect_add()
4349 param Parameter from test_quick_select
4350 info ROR-intersection structure to add the scan to.
4351 ror_scan ROR scan info to add.
4352 is_cpk_scan If TRUE, add the scan as CPK scan (this can be inferred
4353 from other parameters and is passed separately only to
4354 avoid duplicating the inference code)
4356 NOTES
4357 Adding a ROR scan to ROR-intersect "makes sense" iff the cost of ROR-
4358 intersection decreases. The cost of ROR-intersection is calculated as
4359 follows:
4361 cost= SUM_i(key_scan_cost_i) + cost_of_full_rows_retrieval
4363 When we add a scan the first increases and the second decreases.
4365 cost_of_full_rows_retrieval=
4366 (union of indexes used covers all needed fields) ?
4367 cost_of_sweep_read(E(rows_to_retrieve), rows_in_table) :
4370 E(rows_to_retrieve) = #rows_in_table * ror_scan_selectivity(null, scan1) *
4371 ror_scan_selectivity({scan1}, scan2) * ... *
4372 ror_scan_selectivity({scan1,...}, scanN).
4373 RETURN
4374 TRUE ROR scan added to ROR-intersection, cost updated.
4375 FALSE It doesn't make sense to add this ROR scan to this ROR-intersection.
4378 static bool ror_intersect_add(ROR_INTERSECT_INFO *info,
4379 ROR_SCAN_INFO* ror_scan, bool is_cpk_scan)
4381 double selectivity_mult= 1.0;
4383 DBUG_ENTER("ror_intersect_add");
4384 DBUG_PRINT("info", ("Current out_rows= %g", info->out_rows));
4385 DBUG_PRINT("info", ("Adding scan on %s",
4386 info->param->table->key_info[ror_scan->keynr].name));
4387 DBUG_PRINT("info", ("is_cpk_scan: %d",is_cpk_scan));
4389 selectivity_mult = ror_scan_selectivity(info, ror_scan);
4390 if (selectivity_mult == 1.0)
4392 /* Don't add this scan if it doesn't improve selectivity. */
4393 DBUG_PRINT("info", ("The scan doesn't improve selectivity."));
4394 DBUG_RETURN(FALSE);
4397 info->out_rows *= selectivity_mult;
4399 if (is_cpk_scan)
4402 CPK scan is used to filter out rows. We apply filtering for
4403 each record of every scan. Assuming 1/TIME_FOR_COMPARE_ROWID
4404 per check this gives us:
4406 info->index_scan_costs += rows2double(info->index_records) /
4407 TIME_FOR_COMPARE_ROWID;
4409 else
4411 info->index_records += info->param->table->quick_rows[ror_scan->keynr];
4412 info->index_scan_costs += ror_scan->index_read_cost;
4413 bitmap_union(&info->covered_fields, &ror_scan->covered_fields);
4414 if (!info->is_covering && bitmap_is_subset(&info->param->needed_fields,
4415 &info->covered_fields))
4417 DBUG_PRINT("info", ("ROR-intersect is covering now"));
4418 info->is_covering= TRUE;
4422 info->total_cost= info->index_scan_costs;
4423 DBUG_PRINT("info", ("info->total_cost: %g", info->total_cost));
4424 if (!info->is_covering)
4426 info->total_cost +=
4427 get_sweep_read_cost(info->param, double2rows(info->out_rows));
4428 DBUG_PRINT("info", ("info->total_cost= %g", info->total_cost));
4430 DBUG_PRINT("info", ("New out_rows: %g", info->out_rows));
4431 DBUG_PRINT("info", ("New cost: %g, %scovering", info->total_cost,
4432 info->is_covering?"" : "non-"));
4433 DBUG_RETURN(TRUE);
4438 Get best ROR-intersection plan using non-covering ROR-intersection search
4439 algorithm. The returned plan may be covering.
4441 SYNOPSIS
4442 get_best_ror_intersect()
4443 param Parameter from test_quick_select function.
4444 tree Transformed restriction condition to be used to look
4445 for ROR scans.
4446 read_time Do not return read plans with cost > read_time.
4447 are_all_covering [out] set to TRUE if union of all scans covers all
4448 fields needed by the query (and it is possible to build
4449 a covering ROR-intersection)
4451 NOTES
4452 get_key_scans_params must be called before this function can be called.
4454 When this function is called by ROR-union construction algorithm it
4455 assumes it is building an uncovered ROR-intersection (and thus # of full
4456 records to be retrieved is wrong here). This is a hack.
4458 IMPLEMENTATION
4459 The approximate best non-covering plan search algorithm is as follows:
4461 find_min_ror_intersection_scan()
4463 R= select all ROR scans;
4464 order R by (E(#records_matched) * key_record_length).
4466 S= first(R); -- set of scans that will be used for ROR-intersection
4467 R= R-first(S);
4468 min_cost= cost(S);
4469 min_scan= make_scan(S);
4470 while (R is not empty)
4472 firstR= R - first(R);
4473 if (!selectivity(S + firstR < selectivity(S)))
4474 continue;
4476 S= S + first(R);
4477 if (cost(S) < min_cost)
4479 min_cost= cost(S);
4480 min_scan= make_scan(S);
4483 return min_scan;
4486 See ror_intersect_add function for ROR intersection costs.
4488 Special handling for Clustered PK scans
4489 Clustered PK contains all table fields, so using it as a regular scan in
4490 index intersection doesn't make sense: a range scan on CPK will be less
4491 expensive in this case.
4492 Clustered PK scan has special handling in ROR-intersection: it is not used
4493 to retrieve rows, instead its condition is used to filter row references
4494 we get from scans on other keys.
4496 RETURN
4497 ROR-intersection table read plan
4498 NULL if out of memory or no suitable plan found.
4501 static
4502 TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree,
4503 double read_time,
4504 bool *are_all_covering)
4506 uint idx;
4507 double min_cost= DBL_MAX;
4508 DBUG_ENTER("get_best_ror_intersect");
4510 if ((tree->n_ror_scans < 2) || !param->table->file->stats.records ||
4511 !optimizer_flag(param->thd, OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT))
4512 DBUG_RETURN(NULL);
4515 Step1: Collect ROR-able SEL_ARGs and create ROR_SCAN_INFO for each of
4516 them. Also find and save clustered PK scan if there is one.
4518 ROR_SCAN_INFO **cur_ror_scan;
4519 ROR_SCAN_INFO *cpk_scan= NULL;
4520 uint cpk_no;
4521 bool cpk_scan_used= FALSE;
4523 if (!(tree->ror_scans= (ROR_SCAN_INFO**)alloc_root(param->mem_root,
4524 sizeof(ROR_SCAN_INFO*)*
4525 param->keys)))
4526 return NULL;
4527 cpk_no= ((param->table->file->primary_key_is_clustered()) ?
4528 param->table->s->primary_key : MAX_KEY);
4530 for (idx= 0, cur_ror_scan= tree->ror_scans; idx < param->keys; idx++)
4532 ROR_SCAN_INFO *scan;
4533 if (!tree->ror_scans_map.is_set(idx))
4534 continue;
4535 if (!(scan= make_ror_scan(param, idx, tree->keys[idx])))
4536 return NULL;
4537 if (param->real_keynr[idx] == cpk_no)
4539 cpk_scan= scan;
4540 tree->n_ror_scans--;
4542 else
4543 *(cur_ror_scan++)= scan;
4546 tree->ror_scans_end= cur_ror_scan;
4547 DBUG_EXECUTE("info",print_ror_scans_arr(param->table, "original",
4548 tree->ror_scans,
4549 tree->ror_scans_end););
4551 Ok, [ror_scans, ror_scans_end) is array of ptrs to initialized
4552 ROR_SCAN_INFO's.
4553 Step 2: Get best ROR-intersection using an approximate algorithm.
4555 my_qsort(tree->ror_scans, tree->n_ror_scans, sizeof(ROR_SCAN_INFO*),
4556 (qsort_cmp)cmp_ror_scan_info);
4557 DBUG_EXECUTE("info",print_ror_scans_arr(param->table, "ordered",
4558 tree->ror_scans,
4559 tree->ror_scans_end););
4561 ROR_SCAN_INFO **intersect_scans; /* ROR scans used in index intersection */
4562 ROR_SCAN_INFO **intersect_scans_end;
4563 if (!(intersect_scans= (ROR_SCAN_INFO**)alloc_root(param->mem_root,
4564 sizeof(ROR_SCAN_INFO*)*
4565 tree->n_ror_scans)))
4566 return NULL;
4567 intersect_scans_end= intersect_scans;
4569 /* Create and incrementally update ROR intersection. */
4570 ROR_INTERSECT_INFO *intersect, *intersect_best;
4571 if (!(intersect= ror_intersect_init(param)) ||
4572 !(intersect_best= ror_intersect_init(param)))
4573 return NULL;
4575 /* [intersect_scans,intersect_scans_best) will hold the best intersection */
4576 ROR_SCAN_INFO **intersect_scans_best;
4577 cur_ror_scan= tree->ror_scans;
4578 intersect_scans_best= intersect_scans;
4579 while (cur_ror_scan != tree->ror_scans_end && !intersect->is_covering)
4581 /* S= S + first(R); R= R - first(R); */
4582 if (!ror_intersect_add(intersect, *cur_ror_scan, FALSE))
4584 cur_ror_scan++;
4585 continue;
4588 *(intersect_scans_end++)= *(cur_ror_scan++);
4590 if (intersect->total_cost < min_cost)
4592 /* Local minimum found, save it */
4593 ror_intersect_cpy(intersect_best, intersect);
4594 intersect_scans_best= intersect_scans_end;
4595 min_cost = intersect->total_cost;
4599 if (intersect_scans_best == intersect_scans)
4601 DBUG_PRINT("info", ("None of scans increase selectivity"));
4602 DBUG_RETURN(NULL);
4605 DBUG_EXECUTE("info",print_ror_scans_arr(param->table,
4606 "best ROR-intersection",
4607 intersect_scans,
4608 intersect_scans_best););
4610 *are_all_covering= intersect->is_covering;
4611 uint best_num= intersect_scans_best - intersect_scans;
4612 ror_intersect_cpy(intersect, intersect_best);
4615 Ok, found the best ROR-intersection of non-CPK key scans.
4616 Check if we should add a CPK scan. If the obtained ROR-intersection is
4617 covering, it doesn't make sense to add CPK scan.
4619 if (cpk_scan && !intersect->is_covering)
4621 if (ror_intersect_add(intersect, cpk_scan, TRUE) &&
4622 (intersect->total_cost < min_cost))
4624 cpk_scan_used= TRUE;
4625 intersect_best= intersect; //just set pointer here
4629 /* Ok, return ROR-intersect plan if we have found one */
4630 TRP_ROR_INTERSECT *trp= NULL;
4631 if (min_cost < read_time && (cpk_scan_used || best_num > 1))
4633 if (!(trp= new (param->mem_root) TRP_ROR_INTERSECT))
4634 DBUG_RETURN(trp);
4635 if (!(trp->first_scan=
4636 (ROR_SCAN_INFO**)alloc_root(param->mem_root,
4637 sizeof(ROR_SCAN_INFO*)*best_num)))
4638 DBUG_RETURN(NULL);
4639 memcpy(trp->first_scan, intersect_scans, best_num*sizeof(ROR_SCAN_INFO*));
4640 trp->last_scan= trp->first_scan + best_num;
4641 trp->is_covering= intersect_best->is_covering;
4642 trp->read_cost= intersect_best->total_cost;
4643 /* Prevent divisons by zero */
4644 ha_rows best_rows = double2rows(intersect_best->out_rows);
4645 if (!best_rows)
4646 best_rows= 1;
4647 set_if_smaller(param->table->quick_condition_rows, best_rows);
4648 trp->records= best_rows;
4649 trp->index_scan_costs= intersect_best->index_scan_costs;
4650 trp->cpk_scan= cpk_scan_used? cpk_scan: NULL;
4651 DBUG_PRINT("info", ("Returning non-covering ROR-intersect plan:"
4652 "cost %g, records %lu",
4653 trp->read_cost, (ulong) trp->records));
4655 DBUG_RETURN(trp);
4660 Get best covering ROR-intersection.
4661 SYNOPSIS
4662 get_best_covering_ror_intersect()
4663 param Parameter from test_quick_select function.
4664 tree SEL_TREE with sets of intervals for different keys.
4665 read_time Don't return table read plans with cost > read_time.
4667 RETURN
4668 Best covering ROR-intersection plan
4669 NULL if no plan found.
4671 NOTES
4672 get_best_ror_intersect must be called for a tree before calling this
4673 function for it.
4674 This function invalidates tree->ror_scans member values.
4676 The following approximate algorithm is used:
4677 I=set of all covering indexes
4678 F=set of all fields to cover
4679 S={}
4683 Order I by (#covered fields in F desc,
4684 #components asc,
4685 number of first not covered component asc);
4686 F=F-covered by first(I);
4687 S=S+first(I);
4688 I=I-first(I);
4689 } while F is not empty.
4692 static
4693 TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param,
4694 SEL_TREE *tree,
4695 double read_time)
4697 ROR_SCAN_INFO **ror_scan_mark;
4698 ROR_SCAN_INFO **ror_scans_end= tree->ror_scans_end;
4699 DBUG_ENTER("get_best_covering_ror_intersect");
4701 if (!optimizer_flag(param->thd, OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT))
4702 DBUG_RETURN(NULL);
4704 for (ROR_SCAN_INFO **scan= tree->ror_scans; scan != ror_scans_end; ++scan)
4705 (*scan)->key_components=
4706 param->table->key_info[(*scan)->keynr].key_parts;
4709 Run covering-ROR-search algorithm.
4710 Assume set I is [ror_scan .. ror_scans_end)
4713 /*I=set of all covering indexes */
4714 ror_scan_mark= tree->ror_scans;
4716 MY_BITMAP *covered_fields= &param->tmp_covered_fields;
4717 if (!covered_fields->bitmap)
4718 covered_fields->bitmap= (my_bitmap_map*)alloc_root(param->mem_root,
4719 param->fields_bitmap_size);
4720 if (!covered_fields->bitmap ||
4721 bitmap_init(covered_fields, covered_fields->bitmap,
4722 param->table->s->fields, FALSE))
4723 DBUG_RETURN(0);
4724 bitmap_clear_all(covered_fields);
4726 double total_cost= 0.0f;
4727 ha_rows records=0;
4728 bool all_covered;
4730 DBUG_PRINT("info", ("Building covering ROR-intersection"));
4731 DBUG_EXECUTE("info", print_ror_scans_arr(param->table,
4732 "building covering ROR-I",
4733 ror_scan_mark, ror_scans_end););
4737 Update changed sorting info:
4738 #covered fields,
4739 number of first not covered component
4740 Calculate and save these values for each of remaining scans.
4742 for (ROR_SCAN_INFO **scan= ror_scan_mark; scan != ror_scans_end; ++scan)
4744 bitmap_subtract(&(*scan)->covered_fields, covered_fields);
4745 (*scan)->used_fields_covered=
4746 bitmap_bits_set(&(*scan)->covered_fields);
4747 (*scan)->first_uncovered_field=
4748 bitmap_get_first(&(*scan)->covered_fields);
4751 my_qsort(ror_scan_mark, ror_scans_end-ror_scan_mark, sizeof(ROR_SCAN_INFO*),
4752 (qsort_cmp)cmp_ror_scan_info_covering);
4754 DBUG_EXECUTE("info", print_ror_scans_arr(param->table,
4755 "remaining scans",
4756 ror_scan_mark, ror_scans_end););
4758 /* I=I-first(I) */
4759 total_cost += (*ror_scan_mark)->index_read_cost;
4760 records += (*ror_scan_mark)->records;
4761 DBUG_PRINT("info", ("Adding scan on %s",
4762 param->table->key_info[(*ror_scan_mark)->keynr].name));
4763 if (total_cost > read_time)
4764 DBUG_RETURN(NULL);
4765 /* F=F-covered by first(I) */
4766 bitmap_union(covered_fields, &(*ror_scan_mark)->covered_fields);
4767 all_covered= bitmap_is_subset(&param->needed_fields, covered_fields);
4768 } while ((++ror_scan_mark < ror_scans_end) && !all_covered);
4770 if (!all_covered || (ror_scan_mark - tree->ror_scans) == 1)
4771 DBUG_RETURN(NULL);
4774 Ok, [tree->ror_scans .. ror_scan) holds covering index_intersection with
4775 cost total_cost.
4777 DBUG_PRINT("info", ("Covering ROR-intersect scans cost: %g", total_cost));
4778 DBUG_EXECUTE("info", print_ror_scans_arr(param->table,
4779 "creating covering ROR-intersect",
4780 tree->ror_scans, ror_scan_mark););
4782 /* Add priority queue use cost. */
4783 total_cost += rows2double(records)*
4784 log((double)(ror_scan_mark - tree->ror_scans)) /
4785 (TIME_FOR_COMPARE_ROWID * M_LN2);
4786 DBUG_PRINT("info", ("Covering ROR-intersect full cost: %g", total_cost));
4788 if (total_cost > read_time)
4789 DBUG_RETURN(NULL);
4791 TRP_ROR_INTERSECT *trp;
4792 if (!(trp= new (param->mem_root) TRP_ROR_INTERSECT))
4793 DBUG_RETURN(trp);
4794 uint best_num= (ror_scan_mark - tree->ror_scans);
4795 if (!(trp->first_scan= (ROR_SCAN_INFO**)alloc_root(param->mem_root,
4796 sizeof(ROR_SCAN_INFO*)*
4797 best_num)))
4798 DBUG_RETURN(NULL);
4799 memcpy(trp->first_scan, tree->ror_scans, best_num*sizeof(ROR_SCAN_INFO*));
4800 trp->last_scan= trp->first_scan + best_num;
4801 trp->is_covering= TRUE;
4802 trp->read_cost= total_cost;
4803 trp->records= records;
4804 trp->cpk_scan= NULL;
4805 set_if_smaller(param->table->quick_condition_rows, records);
4807 DBUG_PRINT("info",
4808 ("Returning covering ROR-intersect plan: cost %g, records %lu",
4809 trp->read_cost, (ulong) trp->records));
4810 DBUG_RETURN(trp);
4815 Get best "range" table read plan for given SEL_TREE.
4816 Also update PARAM members and store ROR scans info in the SEL_TREE.
4817 SYNOPSIS
4818 get_key_scans_params
4819 param parameters from test_quick_select
4820 tree make range select for this SEL_TREE
4821 index_read_must_be_used if TRUE, assume 'index only' option will be set
4822 (except for clustered PK indexes)
4823 read_time don't create read plans with cost > read_time.
4824 RETURN
4825 Best range read plan
4826 NULL if no plan found or error occurred
4829 static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
4830 bool index_read_must_be_used,
4831 bool update_tbl_stats,
4832 double read_time)
4834 int idx;
4835 SEL_ARG **key,**end, **key_to_read= NULL;
4836 ha_rows UNINIT_VAR(best_records); /* protected by key_to_read */
4837 TRP_RANGE* read_plan= NULL;
4838 bool pk_is_clustered= param->table->file->primary_key_is_clustered();
4839 DBUG_ENTER("get_key_scans_params");
4841 Note that there may be trees that have type SEL_TREE::KEY but contain no
4842 key reads at all, e.g. tree for expression "key1 is not null" where key1
4843 is defined as "not null".
4845 DBUG_EXECUTE("info", print_sel_tree(param, tree, &tree->keys_map,
4846 "tree scans"););
4847 tree->ror_scans_map.clear_all();
4848 tree->n_ror_scans= 0;
4849 for (idx= 0,key=tree->keys, end=key+param->keys;
4850 key != end ;
4851 key++,idx++)
4853 ha_rows found_records;
4854 double found_read_time;
4855 if (*key)
4857 uint keynr= param->real_keynr[idx];
4858 if ((*key)->type == SEL_ARG::MAYBE_KEY ||
4859 (*key)->maybe_flag)
4860 param->needed_reg->set_bit(keynr);
4862 bool read_index_only= index_read_must_be_used ? TRUE :
4863 (bool) param->table->covering_keys.is_set(keynr);
4865 found_records= check_quick_select(param, idx, *key, update_tbl_stats);
4866 if (param->is_ror_scan)
4868 tree->n_ror_scans++;
4869 tree->ror_scans_map.set_bit(idx);
4871 double cpu_cost= (double) found_records / TIME_FOR_COMPARE;
4872 if (found_records != HA_POS_ERROR && found_records > 2 &&
4873 read_index_only &&
4874 (param->table->file->index_flags(keynr, param->max_key_part,1) &
4875 HA_KEYREAD_ONLY) &&
4876 !(pk_is_clustered && keynr == param->table->s->primary_key))
4879 We can resolve this by only reading through this key.
4880 0.01 is added to avoid races between range and 'index' scan.
4882 found_read_time= get_index_only_read_time(param,found_records,keynr) +
4883 cpu_cost + 0.01;
4885 else
4888 cost(read_through_index) = cost(disk_io) + cost(row_in_range_checks)
4889 The row_in_range check is in QUICK_RANGE_SELECT::cmp_next function.
4891 found_read_time= param->table->file->read_time(keynr,
4892 param->range_count,
4893 found_records) +
4894 cpu_cost + 0.01;
4896 DBUG_PRINT("info",("key %s: found_read_time: %g (cur. read_time: %g)",
4897 param->table->key_info[keynr].name, found_read_time,
4898 read_time));
4900 if (read_time > found_read_time && found_records != HA_POS_ERROR)
4902 read_time= found_read_time;
4903 best_records= found_records;
4904 key_to_read= key;
4910 DBUG_EXECUTE("info", print_sel_tree(param, tree, &tree->ror_scans_map,
4911 "ROR scans"););
4912 if (key_to_read)
4914 idx= key_to_read - tree->keys;
4915 if ((read_plan= new (param->mem_root) TRP_RANGE(*key_to_read, idx)))
4917 read_plan->records= best_records;
4918 read_plan->is_ror= tree->ror_scans_map.is_set(idx);
4919 read_plan->read_cost= read_time;
4920 DBUG_PRINT("info",
4921 ("Returning range plan for key %s, cost %g, records %lu",
4922 param->table->key_info[param->real_keynr[idx]].name,
4923 read_plan->read_cost, (ulong) read_plan->records));
4926 else
4927 DBUG_PRINT("info", ("No 'range' table read plan found"));
4929 DBUG_RETURN(read_plan);
4933 QUICK_SELECT_I *TRP_INDEX_MERGE::make_quick(PARAM *param,
4934 bool retrieve_full_rows,
4935 MEM_ROOT *parent_alloc)
4937 QUICK_INDEX_MERGE_SELECT *quick_imerge;
4938 QUICK_RANGE_SELECT *quick;
4939 /* index_merge always retrieves full rows, ignore retrieve_full_rows */
4940 if (!(quick_imerge= new QUICK_INDEX_MERGE_SELECT(param->thd, param->table)))
4941 return NULL;
4943 quick_imerge->records= records;
4944 quick_imerge->read_time= read_cost;
4945 for (TRP_RANGE **range_scan= range_scans; range_scan != range_scans_end;
4946 range_scan++)
4948 if (!(quick= (QUICK_RANGE_SELECT*)
4949 ((*range_scan)->make_quick(param, FALSE, &quick_imerge->alloc)))||
4950 quick_imerge->push_quick_back(quick))
4952 delete quick;
4953 delete quick_imerge;
4954 return NULL;
4957 return quick_imerge;
4960 QUICK_SELECT_I *TRP_ROR_INTERSECT::make_quick(PARAM *param,
4961 bool retrieve_full_rows,
4962 MEM_ROOT *parent_alloc)
4964 QUICK_ROR_INTERSECT_SELECT *quick_intrsect;
4965 QUICK_RANGE_SELECT *quick;
4966 DBUG_ENTER("TRP_ROR_INTERSECT::make_quick");
4967 MEM_ROOT *alloc;
4969 if ((quick_intrsect=
4970 new QUICK_ROR_INTERSECT_SELECT(param->thd, param->table,
4971 (retrieve_full_rows? (!is_covering) :
4972 FALSE),
4973 parent_alloc)))
4975 DBUG_EXECUTE("info", print_ror_scans_arr(param->table,
4976 "creating ROR-intersect",
4977 first_scan, last_scan););
4978 alloc= parent_alloc? parent_alloc: &quick_intrsect->alloc;
4979 for (; first_scan != last_scan;++first_scan)
4981 if (!(quick= get_quick_select(param, (*first_scan)->idx,
4982 (*first_scan)->sel_arg, alloc)) ||
4983 quick_intrsect->push_quick_back(quick))
4985 delete quick_intrsect;
4986 DBUG_RETURN(NULL);
4989 if (cpk_scan)
4991 if (!(quick= get_quick_select(param, cpk_scan->idx,
4992 cpk_scan->sel_arg, alloc)))
4994 delete quick_intrsect;
4995 DBUG_RETURN(NULL);
4997 quick->file= NULL;
4998 quick_intrsect->cpk_quick= quick;
5000 quick_intrsect->records= records;
5001 quick_intrsect->read_time= read_cost;
5003 DBUG_RETURN(quick_intrsect);
5007 QUICK_SELECT_I *TRP_ROR_UNION::make_quick(PARAM *param,
5008 bool retrieve_full_rows,
5009 MEM_ROOT *parent_alloc)
5011 QUICK_ROR_UNION_SELECT *quick_roru;
5012 TABLE_READ_PLAN **scan;
5013 QUICK_SELECT_I *quick;
5014 DBUG_ENTER("TRP_ROR_UNION::make_quick");
5016 It is impossible to construct a ROR-union that will not retrieve full
5017 rows, ignore retrieve_full_rows parameter.
5019 if ((quick_roru= new QUICK_ROR_UNION_SELECT(param->thd, param->table)))
5021 for (scan= first_ror; scan != last_ror; scan++)
5023 if (!(quick= (*scan)->make_quick(param, FALSE, &quick_roru->alloc)) ||
5024 quick_roru->push_quick_back(quick))
5025 DBUG_RETURN(NULL);
5027 quick_roru->records= records;
5028 quick_roru->read_time= read_cost;
5030 DBUG_RETURN(quick_roru);
5035 Build a SEL_TREE for <> or NOT BETWEEN predicate
5037 SYNOPSIS
5038 get_ne_mm_tree()
5039 param PARAM from SQL_SELECT::test_quick_select
5040 cond_func item for the predicate
5041 field field in the predicate
5042 lt_value constant that field should be smaller
5043 gt_value constant that field should be greaterr
5044 cmp_type compare type for the field
5046 RETURN
5047 # Pointer to tree built tree
5048 0 on error
5051 static SEL_TREE *get_ne_mm_tree(RANGE_OPT_PARAM *param, Item_func *cond_func,
5052 Field *field,
5053 Item *lt_value, Item *gt_value,
5054 Item_result cmp_type)
5056 SEL_TREE *tree;
5057 tree= get_mm_parts(param, cond_func, field, Item_func::LT_FUNC,
5058 lt_value, cmp_type);
5059 if (tree)
5061 tree= tree_or(param, tree, get_mm_parts(param, cond_func, field,
5062 Item_func::GT_FUNC,
5063 gt_value, cmp_type));
5065 return tree;
5070 Build a SEL_TREE for a simple predicate
5072 SYNOPSIS
5073 get_func_mm_tree()
5074 param PARAM from SQL_SELECT::test_quick_select
5075 cond_func item for the predicate
5076 field field in the predicate
5077 value constant in the predicate
5078 cmp_type compare type for the field
5079 inv TRUE <> NOT cond_func is considered
5080 (makes sense only when cond_func is BETWEEN or IN)
5082 RETURN
5083 Pointer to the tree built tree
5086 static SEL_TREE *get_func_mm_tree(RANGE_OPT_PARAM *param, Item_func *cond_func,
5087 Field *field, Item *value,
5088 Item_result cmp_type, bool inv)
5090 SEL_TREE *tree= 0;
5091 DBUG_ENTER("get_func_mm_tree");
5093 switch (cond_func->functype()) {
5095 case Item_func::NE_FUNC:
5096 tree= get_ne_mm_tree(param, cond_func, field, value, value, cmp_type);
5097 break;
5099 case Item_func::BETWEEN:
5101 if (!value)
5103 if (inv)
5105 tree= get_ne_mm_tree(param, cond_func, field, cond_func->arguments()[1],
5106 cond_func->arguments()[2], cmp_type);
5108 else
5110 tree= get_mm_parts(param, cond_func, field, Item_func::GE_FUNC,
5111 cond_func->arguments()[1],cmp_type);
5112 if (tree)
5114 tree= tree_and(param, tree, get_mm_parts(param, cond_func, field,
5115 Item_func::LE_FUNC,
5116 cond_func->arguments()[2],
5117 cmp_type));
5121 else
5122 tree= get_mm_parts(param, cond_func, field,
5123 (inv ?
5124 (value == (Item*)1 ? Item_func::GT_FUNC :
5125 Item_func::LT_FUNC):
5126 (value == (Item*)1 ? Item_func::LE_FUNC :
5127 Item_func::GE_FUNC)),
5128 cond_func->arguments()[0], cmp_type);
5129 break;
5131 case Item_func::IN_FUNC:
5133 Item_func_in *func=(Item_func_in*) cond_func;
5136 Array for IN() is constructed when all values have the same result
5137 type. Tree won't be built for values with different result types,
5138 so we check it here to avoid unnecessary work.
5140 if (!func->arg_types_compatible)
5141 break;
5143 if (inv)
5145 if (func->array && func->array->result_type() != ROW_RESULT)
5148 We get here for conditions in form "t.key NOT IN (c1, c2, ...)",
5149 where c{i} are constants. Our goal is to produce a SEL_TREE that
5150 represents intervals:
5152 ($MIN<t.key<c1) OR (c1<t.key<c2) OR (c2<t.key<c3) OR ... (*)
5154 where $MIN is either "-inf" or NULL.
5156 The most straightforward way to produce it is to convert NOT IN
5157 into "(t.key != c1) AND (t.key != c2) AND ... " and let the range
5158 analyzer to build SEL_TREE from that. The problem is that the
5159 range analyzer will use O(N^2) memory (which is probably a bug),
5160 and people do use big NOT IN lists (e.g. see BUG#15872, BUG#21282),
5161 will run out of memory.
5163 Another problem with big lists like (*) is that a big list is
5164 unlikely to produce a good "range" access, while considering that
5165 range access will require expensive CPU calculations (and for
5166 MyISAM even index accesses). In short, big NOT IN lists are rarely
5167 worth analyzing.
5169 Considering the above, we'll handle NOT IN as follows:
5170 * if the number of entries in the NOT IN list is less than
5171 NOT_IN_IGNORE_THRESHOLD, construct the SEL_TREE (*) manually.
5172 * Otherwise, don't produce a SEL_TREE.
5174 #define NOT_IN_IGNORE_THRESHOLD 1000
5175 MEM_ROOT *tmp_root= param->mem_root;
5176 param->thd->mem_root= param->old_root;
5178 Create one Item_type constant object. We'll need it as
5179 get_mm_parts only accepts constant values wrapped in Item_Type
5180 objects.
5181 We create the Item on param->mem_root which points to
5182 per-statement mem_root (while thd->mem_root is currently pointing
5183 to mem_root local to range optimizer).
5185 Item *value_item= func->array->create_item();
5186 param->thd->mem_root= tmp_root;
5188 if (func->array->count > NOT_IN_IGNORE_THRESHOLD || !value_item)
5189 break;
5191 /* Get a SEL_TREE for "(-inf|NULL) < X < c_0" interval. */
5192 uint i=0;
5195 func->array->value_to_item(i, value_item);
5196 tree= get_mm_parts(param, cond_func, field, Item_func::LT_FUNC,
5197 value_item, cmp_type);
5198 if (!tree)
5199 break;
5200 i++;
5201 } while (i < func->array->count && tree->type == SEL_TREE::IMPOSSIBLE);
5203 if (!tree || tree->type == SEL_TREE::IMPOSSIBLE)
5205 /* We get here in cases like "t.unsigned NOT IN (-1,-2,-3) */
5206 tree= NULL;
5207 break;
5209 SEL_TREE *tree2;
5210 for (; i < func->array->count; i++)
5212 if (func->array->compare_elems(i, i-1))
5214 /* Get a SEL_TREE for "-inf < X < c_i" interval */
5215 func->array->value_to_item(i, value_item);
5216 tree2= get_mm_parts(param, cond_func, field, Item_func::LT_FUNC,
5217 value_item, cmp_type);
5218 if (!tree2)
5220 tree= NULL;
5221 break;
5224 /* Change all intervals to be "c_{i-1} < X < c_i" */
5225 for (uint idx= 0; idx < param->keys; idx++)
5227 SEL_ARG *new_interval, *last_val;
5228 if (((new_interval= tree2->keys[idx])) &&
5229 (tree->keys[idx]) &&
5230 ((last_val= tree->keys[idx]->last())))
5232 new_interval->min_value= last_val->max_value;
5233 new_interval->min_flag= NEAR_MIN;
5237 The following doesn't try to allocate memory so no need to
5238 check for NULL.
5240 tree= tree_or(param, tree, tree2);
5244 if (tree && tree->type != SEL_TREE::IMPOSSIBLE)
5247 Get the SEL_TREE for the last "c_last < X < +inf" interval
5248 (value_item cotains c_last already)
5250 tree2= get_mm_parts(param, cond_func, field, Item_func::GT_FUNC,
5251 value_item, cmp_type);
5252 tree= tree_or(param, tree, tree2);
5255 else
5257 tree= get_ne_mm_tree(param, cond_func, field,
5258 func->arguments()[1], func->arguments()[1],
5259 cmp_type);
5260 if (tree)
5262 Item **arg, **end;
5263 for (arg= func->arguments()+2, end= arg+func->argument_count()-2;
5264 arg < end ; arg++)
5266 tree= tree_and(param, tree, get_ne_mm_tree(param, cond_func, field,
5267 *arg, *arg, cmp_type));
5272 else
5274 tree= get_mm_parts(param, cond_func, field, Item_func::EQ_FUNC,
5275 func->arguments()[1], cmp_type);
5276 if (tree)
5278 Item **arg, **end;
5279 for (arg= func->arguments()+2, end= arg+func->argument_count()-2;
5280 arg < end ; arg++)
5282 tree= tree_or(param, tree, get_mm_parts(param, cond_func, field,
5283 Item_func::EQ_FUNC,
5284 *arg, cmp_type));
5288 break;
5290 default:
5293 Here the function for the following predicates are processed:
5294 <, <=, =, >=, >, LIKE, IS NULL, IS NOT NULL.
5295 If the predicate is of the form (value op field) it is handled
5296 as the equivalent predicate (field rev_op value), e.g.
5297 2 <= a is handled as a >= 2.
5299 Item_func::Functype func_type=
5300 (value != cond_func->arguments()[0]) ? cond_func->functype() :
5301 ((Item_bool_func2*) cond_func)->rev_functype();
5302 tree= get_mm_parts(param, cond_func, field, func_type, value, cmp_type);
5306 DBUG_RETURN(tree);
5311 Build conjunction of all SEL_TREEs for a simple predicate applying equalities
5313 SYNOPSIS
5314 get_full_func_mm_tree()
5315 param PARAM from SQL_SELECT::test_quick_select
5316 cond_func item for the predicate
5317 field_item field in the predicate
5318 value constant in the predicate
5319 (for BETWEEN it contains the number of the field argument,
5320 for IN it's always 0)
5321 inv TRUE <> NOT cond_func is considered
5322 (makes sense only when cond_func is BETWEEN or IN)
5324 DESCRIPTION
5325 For a simple SARGable predicate of the form (f op c), where f is a field and
5326 c is a constant, the function builds a conjunction of all SEL_TREES that can
5327 be obtained by the substitution of f for all different fields equal to f.
5329 NOTES
5330 If the WHERE condition contains a predicate (fi op c),
5331 then not only SELL_TREE for this predicate is built, but
5332 the trees for the results of substitution of fi for
5333 each fj belonging to the same multiple equality as fi
5334 are built as well.
5335 E.g. for WHERE t1.a=t2.a AND t2.a > 10
5336 a SEL_TREE for t2.a > 10 will be built for quick select from t2
5337 and
5338 a SEL_TREE for t1.a > 10 will be built for quick select from t1.
5340 A BETWEEN predicate of the form (fi [NOT] BETWEEN c1 AND c2) is treated
5341 in a similar way: we build a conjuction of trees for the results
5342 of all substitutions of fi for equal fj.
5343 Yet a predicate of the form (c BETWEEN f1i AND f2i) is processed
5344 differently. It is considered as a conjuction of two SARGable
5345 predicates (f1i <= c) and (f2i <=c) and the function get_full_func_mm_tree
5346 is called for each of them separately producing trees for
5347 AND j (f1j <=c ) and AND j (f2j <= c)
5348 After this these two trees are united in one conjunctive tree.
5349 It's easy to see that the same tree is obtained for
5350 AND j,k (f1j <=c AND f2k<=c)
5351 which is equivalent to
5352 AND j,k (c BETWEEN f1j AND f2k).
5353 The validity of the processing of the predicate (c NOT BETWEEN f1i AND f2i)
5354 which equivalent to (f1i > c OR f2i < c) is not so obvious. Here the
5355 function get_full_func_mm_tree is called for (f1i > c) and (f2i < c)
5356 producing trees for AND j (f1j > c) and AND j (f2j < c). Then this two
5357 trees are united in one OR-tree. The expression
5358 (AND j (f1j > c) OR AND j (f2j < c)
5359 is equivalent to the expression
5360 AND j,k (f1j > c OR f2k < c)
5361 which is just a translation of
5362 AND j,k (c NOT BETWEEN f1j AND f2k)
5364 In the cases when one of the items f1, f2 is a constant c1 we do not create
5365 a tree for it at all. It works for BETWEEN predicates but does not
5366 work for NOT BETWEEN predicates as we have to evaluate the expression
5367 with it. If it is TRUE then the other tree can be completely ignored.
5368 We do not do it now and no trees are built in these cases for
5369 NOT BETWEEN predicates.
5371 As to IN predicates only ones of the form (f IN (c1,...,cn)),
5372 where f1 is a field and c1,...,cn are constant, are considered as
5373 SARGable. We never try to narrow the index scan using predicates of
5374 the form (c IN (c1,...,f,...,cn)).
5376 RETURN
5377 Pointer to the tree representing the built conjunction of SEL_TREEs
5380 static SEL_TREE *get_full_func_mm_tree(RANGE_OPT_PARAM *param,
5381 Item_func *cond_func,
5382 Item_field *field_item, Item *value,
5383 bool inv)
5385 SEL_TREE *tree= 0;
5386 SEL_TREE *ftree= 0;
5387 table_map ref_tables= 0;
5388 table_map param_comp= ~(param->prev_tables | param->read_tables |
5389 param->current_table);
5390 DBUG_ENTER("get_full_func_mm_tree");
5392 for (uint i= 0; i < cond_func->arg_count; i++)
5394 Item *arg= cond_func->arguments()[i]->real_item();
5395 if (arg != field_item)
5396 ref_tables|= arg->used_tables();
5398 Field *field= field_item->field;
5399 Item_result cmp_type= field->cmp_type();
5400 if (!((ref_tables | field->table->map) & param_comp))
5401 ftree= get_func_mm_tree(param, cond_func, field, value, cmp_type, inv);
5402 Item_equal *item_equal= field_item->item_equal;
5403 if (item_equal)
5405 Item_equal_iterator it(*item_equal);
5406 Item_field *item;
5407 while ((item= it++))
5409 Field *f= item->field;
5410 if (field->eq(f))
5411 continue;
5412 if (!((ref_tables | f->table->map) & param_comp))
5414 tree= get_func_mm_tree(param, cond_func, f, value, cmp_type, inv);
5415 ftree= !ftree ? tree : tree_and(param, ftree, tree);
5419 DBUG_RETURN(ftree);
5422 /* make a select tree of all keys in condition */
5424 static SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param,COND *cond)
5426 SEL_TREE *tree=0;
5427 SEL_TREE *ftree= 0;
5428 Item_field *field_item= 0;
5429 bool inv= FALSE;
5430 Item *value= 0;
5431 DBUG_ENTER("get_mm_tree");
5433 if (cond->type() == Item::COND_ITEM)
5435 List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
5437 if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
5439 tree=0;
5440 Item *item;
5441 while ((item=li++))
5443 SEL_TREE *new_tree=get_mm_tree(param,item);
5444 if (param->thd->is_fatal_error ||
5445 param->alloced_sel_args > SEL_ARG::MAX_SEL_ARGS)
5446 DBUG_RETURN(0); // out of memory
5447 tree=tree_and(param,tree,new_tree);
5448 if (tree && tree->type == SEL_TREE::IMPOSSIBLE)
5449 break;
5452 else
5453 { // COND OR
5454 tree=get_mm_tree(param,li++);
5455 if (tree)
5457 Item *item;
5458 while ((item=li++))
5460 SEL_TREE *new_tree=get_mm_tree(param,item);
5461 if (!new_tree)
5462 DBUG_RETURN(0); // out of memory
5463 tree=tree_or(param,tree,new_tree);
5464 if (!tree || tree->type == SEL_TREE::ALWAYS)
5465 break;
5469 DBUG_RETURN(tree);
5471 /* Here when simple cond */
5472 if (cond->const_item())
5475 During the cond->val_int() evaluation we can come across a subselect
5476 item which may allocate memory on the thd->mem_root and assumes
5477 all the memory allocated has the same life span as the subselect
5478 item itself. So we have to restore the thread's mem_root here.
5480 MEM_ROOT *tmp_root= param->mem_root;
5481 param->thd->mem_root= param->old_root;
5482 tree= cond->val_int() ? new(tmp_root) SEL_TREE(SEL_TREE::ALWAYS) :
5483 new(tmp_root) SEL_TREE(SEL_TREE::IMPOSSIBLE);
5484 param->thd->mem_root= tmp_root;
5485 DBUG_RETURN(tree);
5488 table_map ref_tables= 0;
5489 table_map param_comp= ~(param->prev_tables | param->read_tables |
5490 param->current_table);
5491 if (cond->type() != Item::FUNC_ITEM)
5492 { // Should be a field
5493 ref_tables= cond->used_tables();
5494 if ((ref_tables & param->current_table) ||
5495 (ref_tables & ~(param->prev_tables | param->read_tables)))
5496 DBUG_RETURN(0);
5497 DBUG_RETURN(new SEL_TREE(SEL_TREE::MAYBE));
5500 Item_func *cond_func= (Item_func*) cond;
5501 if (cond_func->functype() == Item_func::BETWEEN ||
5502 cond_func->functype() == Item_func::IN_FUNC)
5503 inv= ((Item_func_opt_neg *) cond_func)->negated;
5504 else if (cond_func->select_optimize() == Item_func::OPTIMIZE_NONE)
5505 DBUG_RETURN(0);
5507 param->cond= cond;
5509 switch (cond_func->functype()) {
5510 case Item_func::BETWEEN:
5511 if (cond_func->arguments()[0]->real_item()->type() == Item::FIELD_ITEM)
5513 field_item= (Item_field*) (cond_func->arguments()[0]->real_item());
5514 ftree= get_full_func_mm_tree(param, cond_func, field_item, NULL, inv);
5518 Concerning the code below see the NOTES section in
5519 the comments for the function get_full_func_mm_tree()
5521 for (uint i= 1 ; i < cond_func->arg_count ; i++)
5523 if (cond_func->arguments()[i]->real_item()->type() == Item::FIELD_ITEM)
5525 field_item= (Item_field*) (cond_func->arguments()[i]->real_item());
5526 SEL_TREE *tmp= get_full_func_mm_tree(param, cond_func,
5527 field_item, (Item*)(intptr)i, inv);
5528 if (inv)
5530 tree= !tree ? tmp : tree_or(param, tree, tmp);
5531 if (tree == NULL)
5532 break;
5534 else
5535 tree= tree_and(param, tree, tmp);
5537 else if (inv)
5539 tree= 0;
5540 break;
5544 ftree = tree_and(param, ftree, tree);
5545 break;
5546 case Item_func::IN_FUNC:
5548 Item_func_in *func=(Item_func_in*) cond_func;
5549 if (func->key_item()->real_item()->type() != Item::FIELD_ITEM)
5550 DBUG_RETURN(0);
5551 field_item= (Item_field*) (func->key_item()->real_item());
5552 ftree= get_full_func_mm_tree(param, cond_func, field_item, NULL, inv);
5553 break;
5555 case Item_func::MULT_EQUAL_FUNC:
5557 Item_equal *item_equal= (Item_equal *) cond;
5558 if (!(value= item_equal->get_const()))
5559 DBUG_RETURN(0);
5560 Item_equal_iterator it(*item_equal);
5561 ref_tables= value->used_tables();
5562 while ((field_item= it++))
5564 Field *field= field_item->field;
5565 Item_result cmp_type= field->cmp_type();
5566 if (!((ref_tables | field->table->map) & param_comp))
5568 tree= get_mm_parts(param, cond, field, Item_func::EQ_FUNC,
5569 value,cmp_type);
5570 ftree= !ftree ? tree : tree_and(param, ftree, tree);
5574 DBUG_RETURN(ftree);
5576 default:
5577 if (cond_func->arguments()[0]->real_item()->type() == Item::FIELD_ITEM)
5579 field_item= (Item_field*) (cond_func->arguments()[0]->real_item());
5580 value= cond_func->arg_count > 1 ? cond_func->arguments()[1] : 0;
5582 else if (cond_func->have_rev_func() &&
5583 cond_func->arguments()[1]->real_item()->type() ==
5584 Item::FIELD_ITEM)
5586 field_item= (Item_field*) (cond_func->arguments()[1]->real_item());
5587 value= cond_func->arguments()[0];
5589 else
5590 DBUG_RETURN(0);
5591 ftree= get_full_func_mm_tree(param, cond_func, field_item, value, inv);
5594 DBUG_RETURN(ftree);
5598 static SEL_TREE *
5599 get_mm_parts(RANGE_OPT_PARAM *param, COND *cond_func, Field *field,
5600 Item_func::Functype type,
5601 Item *value, Item_result cmp_type)
5603 DBUG_ENTER("get_mm_parts");
5604 if (field->table != param->table)
5605 DBUG_RETURN(0);
5607 KEY_PART *key_part = param->key_parts;
5608 KEY_PART *end = param->key_parts_end;
5609 SEL_TREE *tree=0;
5610 if (value &&
5611 value->used_tables() & ~(param->prev_tables | param->read_tables))
5612 DBUG_RETURN(0);
5613 for (; key_part != end ; key_part++)
5615 if (field->eq(key_part->field))
5617 SEL_ARG *sel_arg=0;
5618 if (!tree && !(tree=new SEL_TREE()))
5619 DBUG_RETURN(0); // OOM
5620 if (!value || !(value->used_tables() & ~param->read_tables))
5622 sel_arg=get_mm_leaf(param,cond_func,
5623 key_part->field,key_part,type,value);
5624 if (!sel_arg)
5625 continue;
5626 if (sel_arg->type == SEL_ARG::IMPOSSIBLE)
5628 tree->type=SEL_TREE::IMPOSSIBLE;
5629 DBUG_RETURN(tree);
5632 else
5634 // This key may be used later
5635 if (!(sel_arg= new SEL_ARG(SEL_ARG::MAYBE_KEY)))
5636 DBUG_RETURN(0); // OOM
5638 sel_arg->part=(uchar) key_part->part;
5639 tree->keys[key_part->key]=sel_add(tree->keys[key_part->key],sel_arg);
5640 tree->keys_map.set_bit(key_part->key);
5644 if (tree && tree->merges.is_empty() && tree->keys_map.is_clear_all())
5645 tree= NULL;
5646 DBUG_RETURN(tree);
5650 static SEL_ARG *
5651 get_mm_leaf(RANGE_OPT_PARAM *param, COND *conf_func, Field *field,
5652 KEY_PART *key_part, Item_func::Functype type,Item *value)
5654 uint maybe_null=(uint) field->real_maybe_null();
5655 bool optimize_range;
5656 SEL_ARG *tree= 0;
5657 MEM_ROOT *alloc= param->mem_root;
5658 uchar *str;
5659 ulong orig_sql_mode;
5660 int err;
5661 DBUG_ENTER("get_mm_leaf");
5664 We need to restore the runtime mem_root of the thread in this
5665 function because it evaluates the value of its argument, while
5666 the argument can be any, e.g. a subselect. The subselect
5667 items, in turn, assume that all the memory allocated during
5668 the evaluation has the same life span as the item itself.
5669 TODO: opt_range.cc should not reset thd->mem_root at all.
5671 param->thd->mem_root= param->old_root;
5672 if (!value) // IS NULL or IS NOT NULL
5674 if (field->table->maybe_null) // Can't use a key on this
5675 goto end;
5676 if (!maybe_null) // Not null field
5678 if (type == Item_func::ISNULL_FUNC)
5679 tree= &null_element;
5680 goto end;
5682 if (!(tree= new (alloc) SEL_ARG(field,is_null_string,is_null_string)))
5683 goto end; // out of memory
5684 if (type == Item_func::ISNOTNULL_FUNC)
5686 tree->min_flag=NEAR_MIN; /* IS NOT NULL -> X > NULL */
5687 tree->max_flag=NO_MAX_RANGE;
5689 goto end;
5693 1. Usually we can't use an index if the column collation
5694 differ from the operation collation.
5696 2. However, we can reuse a case insensitive index for
5697 the binary searches:
5699 WHERE latin1_swedish_ci_column = 'a' COLLATE lati1_bin;
5701 WHERE latin1_swedish_ci_colimn = BINARY 'a '
5704 if (field->result_type() == STRING_RESULT &&
5705 value->result_type() == STRING_RESULT &&
5706 key_part->image_type == Field::itRAW &&
5707 ((Field_str*)field)->charset() != conf_func->compare_collation() &&
5708 !(conf_func->compare_collation()->state & MY_CS_BINSORT))
5709 goto end;
5711 if (key_part->image_type == Field::itMBR)
5713 switch (type) {
5714 case Item_func::SP_EQUALS_FUNC:
5715 case Item_func::SP_DISJOINT_FUNC:
5716 case Item_func::SP_INTERSECTS_FUNC:
5717 case Item_func::SP_TOUCHES_FUNC:
5718 case Item_func::SP_CROSSES_FUNC:
5719 case Item_func::SP_WITHIN_FUNC:
5720 case Item_func::SP_CONTAINS_FUNC:
5721 case Item_func::SP_OVERLAPS_FUNC:
5722 break;
5723 default:
5725 We cannot involve spatial indexes for queries that
5726 don't use MBREQUALS(), MBRDISJOINT(), etc. functions.
5728 goto end;
5732 if (param->using_real_indexes)
5733 optimize_range= field->optimize_range(param->real_keynr[key_part->key],
5734 key_part->part);
5735 else
5736 optimize_range= TRUE;
5738 if (type == Item_func::LIKE_FUNC)
5740 bool like_error;
5741 char buff1[MAX_FIELD_WIDTH];
5742 uchar *min_str,*max_str;
5743 String tmp(buff1,sizeof(buff1),value->collation.collation),*res;
5744 size_t length, offset, min_length, max_length;
5745 uint field_length= field->pack_length()+maybe_null;
5747 if (!optimize_range)
5748 goto end;
5749 if (!(res= value->val_str(&tmp)))
5751 tree= &null_element;
5752 goto end;
5756 TODO:
5757 Check if this was a function. This should have be optimized away
5758 in the sql_select.cc
5760 if (res != &tmp)
5762 tmp.copy(*res); // Get own copy
5763 res= &tmp;
5765 if (field->cmp_type() != STRING_RESULT)
5766 goto end; // Can only optimize strings
5768 offset=maybe_null;
5769 length=key_part->store_length;
5771 if (length != key_part->length + maybe_null)
5773 /* key packed with length prefix */
5774 offset+= HA_KEY_BLOB_LENGTH;
5775 field_length= length - HA_KEY_BLOB_LENGTH;
5777 else
5779 if (unlikely(length < field_length))
5782 This can only happen in a table created with UNIREG where one key
5783 overlaps many fields
5785 length= field_length;
5787 else
5788 field_length= length;
5790 length+=offset;
5791 if (!(min_str= (uchar*) alloc_root(alloc, length*2)))
5792 goto end;
5794 max_str=min_str+length;
5795 if (maybe_null)
5796 max_str[0]= min_str[0]=0;
5798 field_length-= maybe_null;
5799 like_error= my_like_range(field->charset(),
5800 res->ptr(), res->length(),
5801 ((Item_func_like*)(param->cond))->escape,
5802 wild_one, wild_many,
5803 field_length,
5804 (char*) min_str+offset, (char*) max_str+offset,
5805 &min_length, &max_length);
5806 if (like_error) // Can't optimize with LIKE
5807 goto end;
5809 if (offset != maybe_null) // BLOB or VARCHAR
5811 int2store(min_str+maybe_null,min_length);
5812 int2store(max_str+maybe_null,max_length);
5814 tree= new (alloc) SEL_ARG(field, min_str, max_str);
5815 goto end;
5818 if (!optimize_range &&
5819 type != Item_func::EQ_FUNC &&
5820 type != Item_func::EQUAL_FUNC)
5821 goto end; // Can't optimize this
5824 We can't always use indexes when comparing a string index to a number
5825 cmp_type() is checked to allow compare of dates to numbers
5827 if (field->result_type() == STRING_RESULT &&
5828 value->result_type() != STRING_RESULT &&
5829 field->cmp_type() != value->result_type())
5830 goto end;
5831 /* For comparison purposes allow invalid dates like 2000-01-32 */
5832 orig_sql_mode= field->table->in_use->variables.sql_mode;
5833 if (value->real_item()->type() == Item::STRING_ITEM &&
5834 (field->type() == MYSQL_TYPE_DATE ||
5835 field->type() == MYSQL_TYPE_DATETIME))
5836 field->table->in_use->variables.sql_mode|= MODE_INVALID_DATES;
5837 err= value->save_in_field_no_warnings(field, 1);
5838 if (err > 0)
5840 if (field->cmp_type() != value->result_type())
5842 if ((type == Item_func::EQ_FUNC || type == Item_func::EQUAL_FUNC) &&
5843 value->result_type() == item_cmp_type(field->result_type(),
5844 value->result_type()))
5846 tree= new (alloc) SEL_ARG(field, 0, 0);
5847 tree->type= SEL_ARG::IMPOSSIBLE;
5848 field->table->in_use->variables.sql_mode= orig_sql_mode;
5849 goto end;
5851 else
5854 TODO: We should return trees of the type SEL_ARG::IMPOSSIBLE
5855 for the cases like int_field > 999999999999999999999999 as well.
5857 tree= 0;
5858 if (err == 3 && field->type() == FIELD_TYPE_DATE &&
5859 (type == Item_func::GT_FUNC || type == Item_func::GE_FUNC ||
5860 type == Item_func::LT_FUNC || type == Item_func::LE_FUNC) )
5863 We were saving DATETIME into a DATE column, the conversion went ok
5864 but a non-zero time part was cut off.
5866 In MySQL's SQL dialect, DATE and DATETIME are compared as datetime
5867 values. Index over a DATE column uses DATE comparison. Changing
5868 from one comparison to the other is possible:
5870 datetime(date_col)< '2007-12-10 12:34:55' -> date_col<='2007-12-10'
5871 datetime(date_col)<='2007-12-10 12:34:55' -> date_col<='2007-12-10'
5873 datetime(date_col)> '2007-12-10 12:34:55' -> date_col>='2007-12-10'
5874 datetime(date_col)>='2007-12-10 12:34:55' -> date_col>='2007-12-10'
5876 but we'll need to convert '>' to '>=' and '<' to '<='. This will
5877 be done together with other types at the end of this function
5878 (grep for stored_field_cmp_to_item)
5881 else
5883 field->table->in_use->variables.sql_mode= orig_sql_mode;
5884 goto end;
5890 guaranteed at this point: err > 0; field and const of same type
5891 If an integer got bounded (e.g. to within 0..255 / -128..127)
5892 for < or >, set flags as for <= or >= (no NEAR_MAX / NEAR_MIN)
5894 else if (err == 1 && field->result_type() == INT_RESULT)
5896 if (type == Item_func::LT_FUNC && (value->val_int() > 0))
5897 type = Item_func::LE_FUNC;
5898 else if (type == Item_func::GT_FUNC &&
5899 (field->type() != FIELD_TYPE_BIT) &&
5900 !((Field_num*)field)->unsigned_flag &&
5901 !((Item_int*)value)->unsigned_flag &&
5902 (value->val_int() < 0))
5903 type = Item_func::GE_FUNC;
5906 else if (err < 0)
5908 field->table->in_use->variables.sql_mode= orig_sql_mode;
5909 /* This happens when we try to insert a NULL field in a not null column */
5910 tree= &null_element; // cmp with NULL is never TRUE
5911 goto end;
5913 field->table->in_use->variables.sql_mode= orig_sql_mode;
5916 Any sargable predicate except "<=>" involving NULL as a constant is always
5917 FALSE
5919 if (type != Item_func::EQUAL_FUNC && field->is_real_null())
5921 tree= &null_element;
5922 goto end;
5925 str= (uchar*) alloc_root(alloc, key_part->store_length+1);
5926 if (!str)
5927 goto end;
5928 if (maybe_null)
5929 *str= (uchar) field->is_real_null(); // Set to 1 if null
5930 field->get_key_image(str+maybe_null, key_part->length,
5931 key_part->image_type);
5932 if (!(tree= new (alloc) SEL_ARG(field, str, str)))
5933 goto end; // out of memory
5936 Check if we are comparing an UNSIGNED integer with a negative constant.
5937 In this case we know that:
5938 (a) (unsigned_int [< | <=] negative_constant) == FALSE
5939 (b) (unsigned_int [> | >=] negative_constant) == TRUE
5940 In case (a) the condition is false for all values, and in case (b) it
5941 is true for all values, so we can avoid unnecessary retrieval and condition
5942 testing, and we also get correct comparison of unsinged integers with
5943 negative integers (which otherwise fails because at query execution time
5944 negative integers are cast to unsigned if compared with unsigned).
5946 if (field->result_type() == INT_RESULT &&
5947 value->result_type() == INT_RESULT &&
5948 ((field->type() == FIELD_TYPE_BIT ||
5949 ((Field_num *) field)->unsigned_flag) &&
5950 !((Item_int*) value)->unsigned_flag))
5952 longlong item_val= value->val_int();
5953 if (item_val < 0)
5955 if (type == Item_func::LT_FUNC || type == Item_func::LE_FUNC)
5957 tree->type= SEL_ARG::IMPOSSIBLE;
5958 goto end;
5960 if (type == Item_func::GT_FUNC || type == Item_func::GE_FUNC)
5962 tree= 0;
5963 goto end;
5968 switch (type) {
5969 case Item_func::LT_FUNC:
5970 if (stored_field_cmp_to_item(param->thd, field, value) == 0)
5971 tree->max_flag=NEAR_MAX;
5972 /* fall through */
5973 case Item_func::LE_FUNC:
5974 if (!maybe_null)
5975 tree->min_flag=NO_MIN_RANGE; /* From start */
5976 else
5977 { // > NULL
5978 tree->min_value=is_null_string;
5979 tree->min_flag=NEAR_MIN;
5981 break;
5982 case Item_func::GT_FUNC:
5983 /* Don't use open ranges for partial key_segments */
5984 if ((!(key_part->flag & HA_PART_KEY_SEG)) &&
5985 (stored_field_cmp_to_item(param->thd, field, value) <= 0))
5986 tree->min_flag=NEAR_MIN;
5987 tree->max_flag= NO_MAX_RANGE;
5988 break;
5989 case Item_func::GE_FUNC:
5990 /* Don't use open ranges for partial key_segments */
5991 if ((!(key_part->flag & HA_PART_KEY_SEG)) &&
5992 (stored_field_cmp_to_item(param->thd, field, value) < 0))
5993 tree->min_flag= NEAR_MIN;
5994 tree->max_flag=NO_MAX_RANGE;
5995 break;
5996 case Item_func::SP_EQUALS_FUNC:
5997 tree->min_flag=GEOM_FLAG | HA_READ_MBR_EQUAL;// NEAR_MIN;//512;
5998 tree->max_flag=NO_MAX_RANGE;
5999 break;
6000 case Item_func::SP_DISJOINT_FUNC:
6001 tree->min_flag=GEOM_FLAG | HA_READ_MBR_DISJOINT;// NEAR_MIN;//512;
6002 tree->max_flag=NO_MAX_RANGE;
6003 break;
6004 case Item_func::SP_INTERSECTS_FUNC:
6005 tree->min_flag=GEOM_FLAG | HA_READ_MBR_INTERSECT;// NEAR_MIN;//512;
6006 tree->max_flag=NO_MAX_RANGE;
6007 break;
6008 case Item_func::SP_TOUCHES_FUNC:
6009 tree->min_flag=GEOM_FLAG | HA_READ_MBR_INTERSECT;// NEAR_MIN;//512;
6010 tree->max_flag=NO_MAX_RANGE;
6011 break;
6013 case Item_func::SP_CROSSES_FUNC:
6014 tree->min_flag=GEOM_FLAG | HA_READ_MBR_INTERSECT;// NEAR_MIN;//512;
6015 tree->max_flag=NO_MAX_RANGE;
6016 break;
6017 case Item_func::SP_WITHIN_FUNC:
6018 tree->min_flag=GEOM_FLAG | HA_READ_MBR_WITHIN;// NEAR_MIN;//512;
6019 tree->max_flag=NO_MAX_RANGE;
6020 break;
6022 case Item_func::SP_CONTAINS_FUNC:
6023 tree->min_flag=GEOM_FLAG | HA_READ_MBR_CONTAIN;// NEAR_MIN;//512;
6024 tree->max_flag=NO_MAX_RANGE;
6025 break;
6026 case Item_func::SP_OVERLAPS_FUNC:
6027 tree->min_flag=GEOM_FLAG | HA_READ_MBR_INTERSECT;// NEAR_MIN;//512;
6028 tree->max_flag=NO_MAX_RANGE;
6029 break;
6031 default:
6032 break;
6035 end:
6036 param->thd->mem_root= alloc;
6037 DBUG_RETURN(tree);
6041 /******************************************************************************
6042 ** Tree manipulation functions
6043 ** If tree is 0 it means that the condition can't be tested. It refers
6044 ** to a non existent table or to a field in current table with isn't a key.
6045 ** The different tree flags:
6046 ** IMPOSSIBLE: Condition is never TRUE
6047 ** ALWAYS: Condition is always TRUE
6048 ** MAYBE: Condition may exists when tables are read
6049 ** MAYBE_KEY: Condition refers to a key that may be used in join loop
6050 ** KEY_RANGE: Condition uses a key
6051 ******************************************************************************/
6054 Add a new key test to a key when scanning through all keys
6055 This will never be called for same key parts.
6058 static SEL_ARG *
6059 sel_add(SEL_ARG *key1,SEL_ARG *key2)
6061 SEL_ARG *root,**key_link;
6063 if (!key1)
6064 return key2;
6065 if (!key2)
6066 return key1;
6068 key_link= &root;
6069 while (key1 && key2)
6071 if (key1->part < key2->part)
6073 *key_link= key1;
6074 key_link= &key1->next_key_part;
6075 key1=key1->next_key_part;
6077 else
6079 *key_link= key2;
6080 key_link= &key2->next_key_part;
6081 key2=key2->next_key_part;
6084 *key_link=key1 ? key1 : key2;
6085 return root;
6088 #define CLONE_KEY1_MAYBE 1
6089 #define CLONE_KEY2_MAYBE 2
6090 #define swap_clone_flag(A) ((A & 1) << 1) | ((A & 2) >> 1)
6093 static SEL_TREE *
6094 tree_and(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2)
6096 DBUG_ENTER("tree_and");
6097 if (!tree1)
6098 DBUG_RETURN(tree2);
6099 if (!tree2)
6100 DBUG_RETURN(tree1);
6101 if (tree1->type == SEL_TREE::IMPOSSIBLE || tree2->type == SEL_TREE::ALWAYS)
6102 DBUG_RETURN(tree1);
6103 if (tree2->type == SEL_TREE::IMPOSSIBLE || tree1->type == SEL_TREE::ALWAYS)
6104 DBUG_RETURN(tree2);
6105 if (tree1->type == SEL_TREE::MAYBE)
6107 if (tree2->type == SEL_TREE::KEY)
6108 tree2->type=SEL_TREE::KEY_SMALLER;
6109 DBUG_RETURN(tree2);
6111 if (tree2->type == SEL_TREE::MAYBE)
6113 tree1->type=SEL_TREE::KEY_SMALLER;
6114 DBUG_RETURN(tree1);
6116 key_map result_keys;
6117 result_keys.clear_all();
6119 /* Join the trees key per key */
6120 SEL_ARG **key1,**key2,**end;
6121 for (key1= tree1->keys,key2= tree2->keys,end=key1+param->keys ;
6122 key1 != end ; key1++,key2++)
6124 uint flag=0;
6125 if (*key1 || *key2)
6127 if (*key1 && !(*key1)->simple_key())
6128 flag|=CLONE_KEY1_MAYBE;
6129 if (*key2 && !(*key2)->simple_key())
6130 flag|=CLONE_KEY2_MAYBE;
6131 *key1=key_and(param, *key1, *key2, flag);
6132 if (*key1 && (*key1)->type == SEL_ARG::IMPOSSIBLE)
6134 tree1->type= SEL_TREE::IMPOSSIBLE;
6135 DBUG_RETURN(tree1);
6137 result_keys.set_bit(key1 - tree1->keys);
6138 #ifdef EXTRA_DEBUG
6139 if (*key1 && param->alloced_sel_args < SEL_ARG::MAX_SEL_ARGS)
6140 (*key1)->test_use_count(*key1);
6141 #endif
6144 tree1->keys_map= result_keys;
6145 /* dispose index_merge if there is a "range" option */
6146 if (!result_keys.is_clear_all())
6148 tree1->merges.empty();
6149 DBUG_RETURN(tree1);
6152 /* ok, both trees are index_merge trees */
6153 imerge_list_and_list(&tree1->merges, &tree2->merges);
6154 DBUG_RETURN(tree1);
6159 Check if two SEL_TREES can be combined into one (i.e. a single key range
6160 read can be constructed for "cond_of_tree1 OR cond_of_tree2" ) without
6161 using index_merge.
6164 bool sel_trees_can_be_ored(SEL_TREE *tree1, SEL_TREE *tree2,
6165 RANGE_OPT_PARAM* param)
6167 key_map common_keys= tree1->keys_map;
6168 DBUG_ENTER("sel_trees_can_be_ored");
6169 common_keys.intersect(tree2->keys_map);
6171 if (common_keys.is_clear_all())
6172 DBUG_RETURN(FALSE);
6174 /* trees have a common key, check if they refer to same key part */
6175 SEL_ARG **key1,**key2;
6176 for (uint key_no=0; key_no < param->keys; key_no++)
6178 if (common_keys.is_set(key_no))
6180 key1= tree1->keys + key_no;
6181 key2= tree2->keys + key_no;
6182 if ((*key1)->part == (*key2)->part)
6184 DBUG_RETURN(TRUE);
6188 DBUG_RETURN(FALSE);
6193 Remove the trees that are not suitable for record retrieval.
6194 SYNOPSIS
6195 param Range analysis parameter
6196 tree Tree to be processed, tree->type is KEY or KEY_SMALLER
6198 DESCRIPTION
6199 This function walks through tree->keys[] and removes the SEL_ARG* trees
6200 that are not "maybe" trees (*) and cannot be used to construct quick range
6201 selects.
6202 (*) - have type MAYBE or MAYBE_KEY. Perhaps we should remove trees of
6203 these types here as well.
6205 A SEL_ARG* tree cannot be used to construct quick select if it has
6206 tree->part != 0. (e.g. it could represent "keypart2 < const").
6208 WHY THIS FUNCTION IS NEEDED
6210 Normally we allow construction of SEL_TREE objects that have SEL_ARG
6211 trees that do not allow quick range select construction. For example for
6212 " keypart1=1 AND keypart2=2 " the execution will proceed as follows:
6213 tree1= SEL_TREE { SEL_ARG{keypart1=1} }
6214 tree2= SEL_TREE { SEL_ARG{keypart2=2} } -- can't make quick range select
6215 from this
6216 call tree_and(tree1, tree2) -- this joins SEL_ARGs into a usable SEL_ARG
6217 tree.
6219 There is an exception though: when we construct index_merge SEL_TREE,
6220 any SEL_ARG* tree that cannot be used to construct quick range select can
6221 be removed, because current range analysis code doesn't provide any way
6222 that tree could be later combined with another tree.
6223 Consider an example: we should not construct
6224 st1 = SEL_TREE {
6225 merges = SEL_IMERGE {
6226 SEL_TREE(t.key1part1 = 1),
6227 SEL_TREE(t.key2part2 = 2) -- (*)
6230 because
6231 - (*) cannot be used to construct quick range select,
6232 - There is no execution path that would cause (*) to be converted to
6233 a tree that could be used.
6235 The latter is easy to verify: first, notice that the only way to convert
6236 (*) into a usable tree is to call tree_and(something, (*)).
6238 Second look at what tree_and/tree_or function would do when passed a
6239 SEL_TREE that has the structure like st1 tree has, and conlcude that
6240 tree_and(something, (*)) will not be called.
6242 RETURN
6243 0 Ok, some suitable trees left
6244 1 No tree->keys[] left.
6247 static bool remove_nonrange_trees(RANGE_OPT_PARAM *param, SEL_TREE *tree)
6249 bool res= FALSE;
6250 for (uint i=0; i < param->keys; i++)
6252 if (tree->keys[i])
6254 if (tree->keys[i]->part)
6256 tree->keys[i]= NULL;
6257 tree->keys_map.clear_bit(i);
6259 else
6260 res= TRUE;
6263 return !res;
6267 static SEL_TREE *
6268 tree_or(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2)
6270 DBUG_ENTER("tree_or");
6271 if (!tree1 || !tree2)
6272 DBUG_RETURN(0);
6273 if (tree1->type == SEL_TREE::IMPOSSIBLE || tree2->type == SEL_TREE::ALWAYS)
6274 DBUG_RETURN(tree2);
6275 if (tree2->type == SEL_TREE::IMPOSSIBLE || tree1->type == SEL_TREE::ALWAYS)
6276 DBUG_RETURN(tree1);
6277 if (tree1->type == SEL_TREE::MAYBE)
6278 DBUG_RETURN(tree1); // Can't use this
6279 if (tree2->type == SEL_TREE::MAYBE)
6280 DBUG_RETURN(tree2);
6282 SEL_TREE *result= 0;
6283 key_map result_keys;
6284 result_keys.clear_all();
6285 if (sel_trees_can_be_ored(tree1, tree2, param))
6287 /* Join the trees key per key */
6288 SEL_ARG **key1,**key2,**end;
6289 for (key1= tree1->keys,key2= tree2->keys,end= key1+param->keys ;
6290 key1 != end ; key1++,key2++)
6292 *key1=key_or(param, *key1, *key2);
6293 if (*key1)
6295 result=tree1; // Added to tree1
6296 result_keys.set_bit(key1 - tree1->keys);
6297 #ifdef EXTRA_DEBUG
6298 if (param->alloced_sel_args < SEL_ARG::MAX_SEL_ARGS)
6299 (*key1)->test_use_count(*key1);
6300 #endif
6303 if (result)
6304 result->keys_map= result_keys;
6306 else
6308 /* ok, two trees have KEY type but cannot be used without index merge */
6309 if (tree1->merges.is_empty() && tree2->merges.is_empty())
6311 if (param->remove_jump_scans)
6313 bool no_trees= remove_nonrange_trees(param, tree1);
6314 no_trees= no_trees || remove_nonrange_trees(param, tree2);
6315 if (no_trees)
6316 DBUG_RETURN(new SEL_TREE(SEL_TREE::ALWAYS));
6318 SEL_IMERGE *merge;
6319 /* both trees are "range" trees, produce new index merge structure */
6320 if (!(result= new SEL_TREE()) || !(merge= new SEL_IMERGE()) ||
6321 (result->merges.push_back(merge)) ||
6322 (merge->or_sel_tree(param, tree1)) ||
6323 (merge->or_sel_tree(param, tree2)))
6324 result= NULL;
6325 else
6326 result->type= tree1->type;
6328 else if (!tree1->merges.is_empty() && !tree2->merges.is_empty())
6330 if (imerge_list_or_list(param, &tree1->merges, &tree2->merges))
6331 result= new SEL_TREE(SEL_TREE::ALWAYS);
6332 else
6333 result= tree1;
6335 else
6337 /* one tree is index merge tree and another is range tree */
6338 if (tree1->merges.is_empty())
6339 swap_variables(SEL_TREE*, tree1, tree2);
6341 if (param->remove_jump_scans && remove_nonrange_trees(param, tree2))
6342 DBUG_RETURN(new SEL_TREE(SEL_TREE::ALWAYS));
6343 /* add tree2 to tree1->merges, checking if it collapses to ALWAYS */
6344 if (imerge_list_or_tree(param, &tree1->merges, tree2))
6345 result= new SEL_TREE(SEL_TREE::ALWAYS);
6346 else
6347 result= tree1;
6350 DBUG_RETURN(result);
6354 /* And key trees where key1->part < key2 -> part */
6356 static SEL_ARG *
6357 and_all_keys(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2,
6358 uint clone_flag)
6360 SEL_ARG *next;
6361 ulong use_count=key1->use_count;
6363 if (key1->elements != 1)
6365 key2->use_count+=key1->elements-1; //psergey: why we don't count that key1 has n-k-p?
6366 key2->increment_use_count((int) key1->elements-1);
6368 if (key1->type == SEL_ARG::MAYBE_KEY)
6370 key1->right= key1->left= &null_element;
6371 key1->next= key1->prev= 0;
6373 for (next=key1->first(); next ; next=next->next)
6375 if (next->next_key_part)
6377 SEL_ARG *tmp= key_and(param, next->next_key_part, key2, clone_flag);
6378 if (tmp && tmp->type == SEL_ARG::IMPOSSIBLE)
6380 key1=key1->tree_delete(next);
6381 continue;
6383 next->next_key_part=tmp;
6384 if (use_count)
6385 next->increment_use_count(use_count);
6386 if (param->alloced_sel_args > SEL_ARG::MAX_SEL_ARGS)
6387 break;
6389 else
6390 next->next_key_part=key2;
6392 if (!key1)
6393 return &null_element; // Impossible ranges
6394 key1->use_count++;
6395 return key1;
6400 Produce a SEL_ARG graph that represents "key1 AND key2"
6402 SYNOPSIS
6403 key_and()
6404 param Range analysis context (needed to track if we have allocated
6405 too many SEL_ARGs)
6406 key1 First argument, root of its RB-tree
6407 key2 Second argument, root of its RB-tree
6409 RETURN
6410 RB-tree root of the resulting SEL_ARG graph.
6411 NULL if the result of AND operation is an empty interval {0}.
6414 static SEL_ARG *
6415 key_and(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2, uint clone_flag)
6417 if (!key1)
6418 return key2;
6419 if (!key2)
6420 return key1;
6421 if (key1->part != key2->part)
6423 if (key1->part > key2->part)
6425 swap_variables(SEL_ARG *, key1, key2);
6426 clone_flag=swap_clone_flag(clone_flag);
6428 // key1->part < key2->part
6429 key1->use_count--;
6430 if (key1->use_count > 0)
6431 if (!(key1= key1->clone_tree(param)))
6432 return 0; // OOM
6433 return and_all_keys(param, key1, key2, clone_flag);
6436 if (((clone_flag & CLONE_KEY2_MAYBE) &&
6437 !(clone_flag & CLONE_KEY1_MAYBE) &&
6438 key2->type != SEL_ARG::MAYBE_KEY) ||
6439 key1->type == SEL_ARG::MAYBE_KEY)
6440 { // Put simple key in key2
6441 swap_variables(SEL_ARG *, key1, key2);
6442 clone_flag=swap_clone_flag(clone_flag);
6445 /* If one of the key is MAYBE_KEY then the found region may be smaller */
6446 if (key2->type == SEL_ARG::MAYBE_KEY)
6448 if (key1->use_count > 1)
6450 key1->use_count--;
6451 if (!(key1=key1->clone_tree(param)))
6452 return 0; // OOM
6453 key1->use_count++;
6455 if (key1->type == SEL_ARG::MAYBE_KEY)
6456 { // Both are maybe key
6457 key1->next_key_part=key_and(param, key1->next_key_part,
6458 key2->next_key_part, clone_flag);
6459 if (key1->next_key_part &&
6460 key1->next_key_part->type == SEL_ARG::IMPOSSIBLE)
6461 return key1;
6463 else
6465 key1->maybe_smaller();
6466 if (key2->next_key_part)
6468 key1->use_count--; // Incremented in and_all_keys
6469 return and_all_keys(param, key1, key2, clone_flag);
6471 key2->use_count--; // Key2 doesn't have a tree
6473 return key1;
6476 if ((key1->min_flag | key2->min_flag) & GEOM_FLAG)
6478 /* TODO: why not leave one of the trees? */
6479 key1->free_tree();
6480 key2->free_tree();
6481 return 0; // Can't optimize this
6484 key1->use_count--;
6485 key2->use_count--;
6486 SEL_ARG *e1=key1->first(), *e2=key2->first(), *new_tree=0;
6488 while (e1 && e2)
6490 int cmp=e1->cmp_min_to_min(e2);
6491 if (cmp < 0)
6493 if (get_range(&e1,&e2,key1))
6494 continue;
6496 else if (get_range(&e2,&e1,key2))
6497 continue;
6498 SEL_ARG *next=key_and(param, e1->next_key_part, e2->next_key_part,
6499 clone_flag);
6500 e1->increment_use_count(1);
6501 e2->increment_use_count(1);
6502 if (!next || next->type != SEL_ARG::IMPOSSIBLE)
6504 SEL_ARG *new_arg= e1->clone_and(e2);
6505 if (!new_arg)
6506 return &null_element; // End of memory
6507 new_arg->next_key_part=next;
6508 if (!new_tree)
6510 new_tree=new_arg;
6512 else
6513 new_tree=new_tree->insert(new_arg);
6515 if (e1->cmp_max_to_max(e2) < 0)
6516 e1=e1->next; // e1 can't overlapp next e2
6517 else
6518 e2=e2->next;
6520 key1->free_tree();
6521 key2->free_tree();
6522 if (!new_tree)
6523 return &null_element; // Impossible range
6524 return new_tree;
6528 static bool
6529 get_range(SEL_ARG **e1,SEL_ARG **e2,SEL_ARG *root1)
6531 (*e1)=root1->find_range(*e2); // first e1->min < e2->min
6532 if ((*e1)->cmp_max_to_min(*e2) < 0)
6534 if (!((*e1)=(*e1)->next))
6535 return 1;
6536 if ((*e1)->cmp_min_to_max(*e2) > 0)
6538 (*e2)=(*e2)->next;
6539 return 1;
6542 return 0;
6547 Combine two range expression under a common OR. On a logical level, the
6548 transformation is key_or( expr1, expr2 ) => expr1 OR expr2.
6550 Both expressions are assumed to be in the SEL_ARG format. In a logic sense,
6551 theformat is reminiscent of DNF, since an expression such as the following
6553 ( 1 < kp1 < 10 AND p1 ) OR ( 10 <= kp2 < 20 AND p2 )
6555 where there is a key consisting of keyparts ( kp1, kp2, ..., kpn ) and p1
6556 and p2 are valid SEL_ARG expressions over keyparts kp2 ... kpn, is a valid
6557 SEL_ARG condition. The disjuncts appear ordered by the minimum endpoint of
6558 the first range and ranges must not overlap. It follows that they are also
6559 ordered by maximum endpoints. Thus
6561 ( 1 < kp1 <= 2 AND ( kp2 = 2 OR kp2 = 3 ) ) OR kp1 = 3
6563 Is a a valid SER_ARG expression for a key of at least 2 keyparts.
6565 For simplicity, we will assume that expr2 is a single range predicate,
6566 i.e. on the form ( a < x < b AND ... ). It is easy to generalize to a
6567 disjunction of several predicates by subsequently call key_or for each
6568 disjunct.
6570 The algorithm iterates over each disjunct of expr1, and for each disjunct
6571 where the first keypart's range overlaps with the first keypart's range in
6572 expr2:
6574 If the predicates are equal for the rest of the keyparts, or if there are
6575 no more, the range in expr2 has its endpoints copied in, and the SEL_ARG
6576 node in expr2 is deallocated. If more ranges became connected in expr1, the
6577 surplus is also dealocated. If they differ, two ranges are created.
6579 - The range leading up to the overlap. Empty if endpoints are equal.
6581 - The overlapping sub-range. May be the entire range if they are equal.
6583 Finally, there may be one more range if expr2's first keypart's range has a
6584 greater maximum endpoint than the last range in expr1.
6586 For the overlapping sub-range, we recursively call key_or. Thus in order to
6587 compute key_or of
6589 (1) ( 1 < kp1 < 10 AND 1 < kp2 < 10 )
6591 (2) ( 2 < kp1 < 20 AND 4 < kp2 < 20 )
6593 We create the ranges 1 < kp <= 2, 2 < kp1 < 10, 10 <= kp1 < 20. For the
6594 first one, we simply hook on the condition for the second keypart from (1)
6595 : 1 < kp2 < 10. For the second range 2 < kp1 < 10, key_or( 1 < kp2 < 10, 4
6596 < kp2 < 20 ) is called, yielding 1 < kp2 < 20. For the last range, we reuse
6597 the range 4 < kp2 < 20 from (2) for the second keypart. The result is thus
6599 ( 1 < kp1 <= 2 AND 1 < kp2 < 10 ) OR
6600 ( 2 < kp1 < 10 AND 1 < kp2 < 20 ) OR
6601 ( 10 <= kp1 < 20 AND 4 < kp2 < 20 )
6603 static SEL_ARG *
6604 key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1,SEL_ARG *key2)
6606 if (!key1)
6608 if (key2)
6610 key2->use_count--;
6611 key2->free_tree();
6613 return 0;
6615 if (!key2)
6617 key1->use_count--;
6618 key1->free_tree();
6619 return 0;
6621 key1->use_count--;
6622 key2->use_count--;
6624 if (key1->part != key2->part ||
6625 (key1->min_flag | key2->min_flag) & GEOM_FLAG)
6627 key1->free_tree();
6628 key2->free_tree();
6629 return 0; // Can't optimize this
6632 // If one of the key is MAYBE_KEY then the found region may be bigger
6633 if (key1->type == SEL_ARG::MAYBE_KEY)
6635 key2->free_tree();
6636 key1->use_count++;
6637 return key1;
6639 if (key2->type == SEL_ARG::MAYBE_KEY)
6641 key1->free_tree();
6642 key2->use_count++;
6643 return key2;
6646 if (key1->use_count > 0)
6648 if (key2->use_count == 0 || key1->elements > key2->elements)
6650 swap_variables(SEL_ARG *,key1,key2);
6652 if (key1->use_count > 0 || !(key1=key1->clone_tree(param)))
6653 return 0; // OOM
6656 // Add tree at key2 to tree at key1
6657 bool key2_shared=key2->use_count != 0;
6658 key1->maybe_flag|=key2->maybe_flag;
6660 for (key2=key2->first(); key2; )
6662 SEL_ARG *tmp=key1->find_range(key2); // Find key1.min <= key2.min
6663 int cmp;
6665 if (!tmp)
6667 tmp=key1->first(); // tmp.min > key2.min
6668 cmp= -1;
6670 else if ((cmp=tmp->cmp_max_to_min(key2)) < 0)
6671 { // Found tmp.max < key2.min
6672 SEL_ARG *next=tmp->next;
6673 /* key1 on the left of key2 non-overlapping */
6674 if (cmp == -2 && eq_tree(tmp->next_key_part,key2->next_key_part))
6676 // Join near ranges like tmp.max < 0 and key2.min >= 0
6677 SEL_ARG *key2_next=key2->next;
6678 if (key2_shared)
6680 if (!(key2=new SEL_ARG(*key2)))
6681 return 0; // out of memory
6682 key2->increment_use_count(key1->use_count+1);
6683 key2->next=key2_next; // New copy of key2
6685 key2->copy_min(tmp);
6686 if (!(key1=key1->tree_delete(tmp)))
6687 { // Only one key in tree
6688 key1=key2;
6689 key1->make_root();
6690 key2=key2_next;
6691 break;
6694 if (!(tmp=next)) // tmp.min > key2.min
6695 break; // Copy rest of key2
6697 if (cmp < 0)
6698 { // tmp.min > key2.min
6699 int tmp_cmp;
6700 if ((tmp_cmp=tmp->cmp_min_to_max(key2)) > 0) // if tmp.min > key2.max
6702 /* tmp is on the right of key2 non-overlapping */
6703 if (tmp_cmp == 2 && eq_tree(tmp->next_key_part,key2->next_key_part))
6704 { // ranges are connected
6705 tmp->copy_min_to_min(key2);
6706 key1->merge_flags(key2);
6707 if (tmp->min_flag & NO_MIN_RANGE &&
6708 tmp->max_flag & NO_MAX_RANGE)
6710 if (key1->maybe_flag)
6711 return new SEL_ARG(SEL_ARG::MAYBE_KEY);
6712 return 0;
6714 key2->increment_use_count(-1); // Free not used tree
6715 key2=key2->next;
6716 continue;
6718 else
6720 SEL_ARG *next=key2->next; // Keys are not overlapping
6721 if (key2_shared)
6723 SEL_ARG *cpy= new SEL_ARG(*key2); // Must make copy
6724 if (!cpy)
6725 return 0; // OOM
6726 key1=key1->insert(cpy);
6727 key2->increment_use_count(key1->use_count+1);
6729 else
6730 key1=key1->insert(key2); // Will destroy key2_root
6731 key2=next;
6732 continue;
6738 tmp.min >= key2.min && tmp.min <= key.max (overlapping ranges)
6739 key2.min <= tmp.min <= key2.max
6741 if (eq_tree(tmp->next_key_part,key2->next_key_part))
6743 if (tmp->is_same(key2))
6746 Found exact match of key2 inside key1.
6747 Use the relevant range in key1.
6749 tmp->merge_flags(key2); // Copy maybe flags
6750 key2->increment_use_count(-1); // Free not used tree
6752 else
6754 SEL_ARG *last=tmp;
6755 SEL_ARG *first=tmp;
6757 Find the last range in tmp that overlaps key2 and has the same
6758 condition on the rest of the keyparts.
6760 while (last->next && last->next->cmp_min_to_max(key2) <= 0 &&
6761 eq_tree(last->next->next_key_part,key2->next_key_part))
6764 We've found the last overlapping key1 range in last.
6765 This means that the ranges between (and including) the
6766 first overlapping range (tmp) and the last overlapping range
6767 (last) are fully nested into the current range of key2
6768 and can safely be discarded. We just need the minimum endpoint
6769 of the first overlapping range (tmp) so we can compare it with
6770 the minimum endpoint of the enclosing key2 range.
6772 SEL_ARG *save=last;
6773 last=last->next;
6774 key1=key1->tree_delete(save);
6777 The tmp range (the first overlapping range) could have been discarded
6778 by the previous loop. We should re-direct tmp to the new united range
6779 that's taking its place.
6781 tmp= last;
6782 last->copy_min(first);
6783 bool full_range= last->copy_min(key2);
6784 if (!full_range)
6786 if (last->next && key2->cmp_max_to_min(last->next) >= 0)
6788 last->max_value= last->next->min_value;
6789 if (last->next->min_flag & NEAR_MIN)
6790 last->max_flag&= ~NEAR_MAX;
6791 else
6792 last->max_flag|= NEAR_MAX;
6794 else
6795 full_range= last->copy_max(key2);
6797 if (full_range)
6798 { // Full range
6799 key1->free_tree();
6800 for (; key2 ; key2=key2->next)
6801 key2->increment_use_count(-1); // Free not used tree
6802 if (key1->maybe_flag)
6803 return new SEL_ARG(SEL_ARG::MAYBE_KEY);
6804 return 0;
6809 if (cmp >= 0 && tmp->cmp_min_to_min(key2) < 0)
6810 { // tmp.min <= x < key2.min
6811 SEL_ARG *new_arg=tmp->clone_first(key2);
6812 if (!new_arg)
6813 return 0; // OOM
6814 if ((new_arg->next_key_part= key1->next_key_part))
6815 new_arg->increment_use_count(key1->use_count+1);
6816 tmp->copy_min_to_min(key2);
6817 key1=key1->insert(new_arg);
6820 // tmp.min >= key2.min && tmp.min <= key2.max
6821 SEL_ARG key(*key2); // Get copy we can modify
6822 for (;;)
6824 if (tmp->cmp_min_to_min(&key) > 0)
6825 { // key.min <= x < tmp.min
6826 SEL_ARG *new_arg=key.clone_first(tmp);
6827 if (!new_arg)
6828 return 0; // OOM
6829 if ((new_arg->next_key_part=key.next_key_part))
6830 new_arg->increment_use_count(key1->use_count+1);
6831 key1=key1->insert(new_arg);
6833 if ((cmp=tmp->cmp_max_to_max(&key)) <= 0)
6834 { // tmp.min. <= x <= tmp.max
6835 tmp->maybe_flag|= key.maybe_flag;
6836 key.increment_use_count(key1->use_count+1);
6837 tmp->next_key_part= key_or(param, tmp->next_key_part, key.next_key_part);
6838 if (!cmp) // Key2 is ready
6839 break;
6840 key.copy_max_to_min(tmp);
6841 if (!(tmp=tmp->next))
6843 SEL_ARG *tmp2= new SEL_ARG(key);
6844 if (!tmp2)
6845 return 0; // OOM
6846 key1=key1->insert(tmp2);
6847 key2=key2->next;
6848 goto end;
6850 if (tmp->cmp_min_to_max(&key) > 0)
6852 SEL_ARG *tmp2= new SEL_ARG(key);
6853 if (!tmp2)
6854 return 0; // OOM
6855 key1=key1->insert(tmp2);
6856 break;
6859 else
6861 SEL_ARG *new_arg=tmp->clone_last(&key); // tmp.min <= x <= key.max
6862 if (!new_arg)
6863 return 0; // OOM
6864 tmp->copy_max_to_min(&key);
6865 tmp->increment_use_count(key1->use_count+1);
6866 /* Increment key count as it may be used for next loop */
6867 key.increment_use_count(1);
6868 new_arg->next_key_part= key_or(param, tmp->next_key_part, key.next_key_part);
6869 key1=key1->insert(new_arg);
6870 break;
6873 key2=key2->next;
6876 end:
6877 while (key2)
6879 SEL_ARG *next=key2->next;
6880 if (key2_shared)
6882 SEL_ARG *tmp=new SEL_ARG(*key2); // Must make copy
6883 if (!tmp)
6884 return 0;
6885 key2->increment_use_count(key1->use_count+1);
6886 key1=key1->insert(tmp);
6888 else
6889 key1=key1->insert(key2); // Will destroy key2_root
6890 key2=next;
6892 key1->use_count++;
6893 return key1;
6897 /* Compare if two trees are equal */
6899 static bool eq_tree(SEL_ARG* a,SEL_ARG *b)
6901 if (a == b)
6902 return 1;
6903 if (!a || !b || !a->is_same(b))
6904 return 0;
6905 if (a->left != &null_element && b->left != &null_element)
6907 if (!eq_tree(a->left,b->left))
6908 return 0;
6910 else if (a->left != &null_element || b->left != &null_element)
6911 return 0;
6912 if (a->right != &null_element && b->right != &null_element)
6914 if (!eq_tree(a->right,b->right))
6915 return 0;
6917 else if (a->right != &null_element || b->right != &null_element)
6918 return 0;
6919 if (a->next_key_part != b->next_key_part)
6920 { // Sub range
6921 if (!a->next_key_part != !b->next_key_part ||
6922 !eq_tree(a->next_key_part, b->next_key_part))
6923 return 0;
6925 return 1;
6929 SEL_ARG *
6930 SEL_ARG::insert(SEL_ARG *key)
6932 SEL_ARG *element,**UNINIT_VAR(par),*UNINIT_VAR(last_element);
6934 for (element= this; element != &null_element ; )
6936 last_element=element;
6937 if (key->cmp_min_to_min(element) > 0)
6939 par= &element->right; element= element->right;
6941 else
6943 par = &element->left; element= element->left;
6946 *par=key;
6947 key->parent=last_element;
6948 /* Link in list */
6949 if (par == &last_element->left)
6951 key->next=last_element;
6952 if ((key->prev=last_element->prev))
6953 key->prev->next=key;
6954 last_element->prev=key;
6956 else
6958 if ((key->next=last_element->next))
6959 key->next->prev=key;
6960 key->prev=last_element;
6961 last_element->next=key;
6963 key->left=key->right= &null_element;
6964 SEL_ARG *root=rb_insert(key); // rebalance tree
6965 root->use_count=this->use_count; // copy root info
6966 root->elements= this->elements+1;
6967 root->maybe_flag=this->maybe_flag;
6968 return root;
6973 ** Find best key with min <= given key
6974 ** Because the call context this should never return 0 to get_range
6977 SEL_ARG *
6978 SEL_ARG::find_range(SEL_ARG *key)
6980 SEL_ARG *element=this,*found=0;
6982 for (;;)
6984 if (element == &null_element)
6985 return found;
6986 int cmp=element->cmp_min_to_min(key);
6987 if (cmp == 0)
6988 return element;
6989 if (cmp < 0)
6991 found=element;
6992 element=element->right;
6994 else
6995 element=element->left;
7001 Remove a element from the tree
7003 SYNOPSIS
7004 tree_delete()
7005 key Key that is to be deleted from tree (this)
7007 NOTE
7008 This also frees all sub trees that is used by the element
7010 RETURN
7011 root of new tree (with key deleted)
7014 SEL_ARG *
7015 SEL_ARG::tree_delete(SEL_ARG *key)
7017 enum leaf_color remove_color;
7018 SEL_ARG *root,*nod,**par,*fix_par;
7019 DBUG_ENTER("tree_delete");
7021 root=this;
7022 this->parent= 0;
7024 /* Unlink from list */
7025 if (key->prev)
7026 key->prev->next=key->next;
7027 if (key->next)
7028 key->next->prev=key->prev;
7029 key->increment_use_count(-1);
7030 if (!key->parent)
7031 par= &root;
7032 else
7033 par=key->parent_ptr();
7035 if (key->left == &null_element)
7037 *par=nod=key->right;
7038 fix_par=key->parent;
7039 if (nod != &null_element)
7040 nod->parent=fix_par;
7041 remove_color= key->color;
7043 else if (key->right == &null_element)
7045 *par= nod=key->left;
7046 nod->parent=fix_par=key->parent;
7047 remove_color= key->color;
7049 else
7051 SEL_ARG *tmp=key->next; // next bigger key (exist!)
7052 nod= *tmp->parent_ptr()= tmp->right; // unlink tmp from tree
7053 fix_par=tmp->parent;
7054 if (nod != &null_element)
7055 nod->parent=fix_par;
7056 remove_color= tmp->color;
7058 tmp->parent=key->parent; // Move node in place of key
7059 (tmp->left=key->left)->parent=tmp;
7060 if ((tmp->right=key->right) != &null_element)
7061 tmp->right->parent=tmp;
7062 tmp->color=key->color;
7063 *par=tmp;
7064 if (fix_par == key) // key->right == key->next
7065 fix_par=tmp; // new parent of nod
7068 if (root == &null_element)
7069 DBUG_RETURN(0); // Maybe root later
7070 if (remove_color == BLACK)
7071 root=rb_delete_fixup(root,nod,fix_par);
7072 test_rb_tree(root,root->parent);
7074 root->use_count=this->use_count; // Fix root counters
7075 root->elements=this->elements-1;
7076 root->maybe_flag=this->maybe_flag;
7077 DBUG_RETURN(root);
7081 /* Functions to fix up the tree after insert and delete */
7083 static void left_rotate(SEL_ARG **root,SEL_ARG *leaf)
7085 SEL_ARG *y=leaf->right;
7086 leaf->right=y->left;
7087 if (y->left != &null_element)
7088 y->left->parent=leaf;
7089 if (!(y->parent=leaf->parent))
7090 *root=y;
7091 else
7092 *leaf->parent_ptr()=y;
7093 y->left=leaf;
7094 leaf->parent=y;
7097 static void right_rotate(SEL_ARG **root,SEL_ARG *leaf)
7099 SEL_ARG *y=leaf->left;
7100 leaf->left=y->right;
7101 if (y->right != &null_element)
7102 y->right->parent=leaf;
7103 if (!(y->parent=leaf->parent))
7104 *root=y;
7105 else
7106 *leaf->parent_ptr()=y;
7107 y->right=leaf;
7108 leaf->parent=y;
7112 SEL_ARG *
7113 SEL_ARG::rb_insert(SEL_ARG *leaf)
7115 SEL_ARG *y,*par,*par2,*root;
7116 root= this; root->parent= 0;
7118 leaf->color=RED;
7119 while (leaf != root && (par= leaf->parent)->color == RED)
7120 { // This can't be root or 1 level under
7121 if (par == (par2= leaf->parent->parent)->left)
7123 y= par2->right;
7124 if (y->color == RED)
7126 par->color=BLACK;
7127 y->color=BLACK;
7128 leaf=par2;
7129 leaf->color=RED; /* And the loop continues */
7131 else
7133 if (leaf == par->right)
7135 left_rotate(&root,leaf->parent);
7136 par=leaf; /* leaf is now parent to old leaf */
7138 par->color=BLACK;
7139 par2->color=RED;
7140 right_rotate(&root,par2);
7141 break;
7144 else
7146 y= par2->left;
7147 if (y->color == RED)
7149 par->color=BLACK;
7150 y->color=BLACK;
7151 leaf=par2;
7152 leaf->color=RED; /* And the loop continues */
7154 else
7156 if (leaf == par->left)
7158 right_rotate(&root,par);
7159 par=leaf;
7161 par->color=BLACK;
7162 par2->color=RED;
7163 left_rotate(&root,par2);
7164 break;
7168 root->color=BLACK;
7169 test_rb_tree(root,root->parent);
7170 return root;
7174 SEL_ARG *rb_delete_fixup(SEL_ARG *root,SEL_ARG *key,SEL_ARG *par)
7176 SEL_ARG *x,*w;
7177 root->parent=0;
7179 x= key;
7180 while (x != root && x->color == SEL_ARG::BLACK)
7182 if (x == par->left)
7184 w=par->right;
7185 if (w->color == SEL_ARG::RED)
7187 w->color=SEL_ARG::BLACK;
7188 par->color=SEL_ARG::RED;
7189 left_rotate(&root,par);
7190 w=par->right;
7192 if (w->left->color == SEL_ARG::BLACK && w->right->color == SEL_ARG::BLACK)
7194 w->color=SEL_ARG::RED;
7195 x=par;
7197 else
7199 if (w->right->color == SEL_ARG::BLACK)
7201 w->left->color=SEL_ARG::BLACK;
7202 w->color=SEL_ARG::RED;
7203 right_rotate(&root,w);
7204 w=par->right;
7206 w->color=par->color;
7207 par->color=SEL_ARG::BLACK;
7208 w->right->color=SEL_ARG::BLACK;
7209 left_rotate(&root,par);
7210 x=root;
7211 break;
7214 else
7216 w=par->left;
7217 if (w->color == SEL_ARG::RED)
7219 w->color=SEL_ARG::BLACK;
7220 par->color=SEL_ARG::RED;
7221 right_rotate(&root,par);
7222 w=par->left;
7224 if (w->right->color == SEL_ARG::BLACK && w->left->color == SEL_ARG::BLACK)
7226 w->color=SEL_ARG::RED;
7227 x=par;
7229 else
7231 if (w->left->color == SEL_ARG::BLACK)
7233 w->right->color=SEL_ARG::BLACK;
7234 w->color=SEL_ARG::RED;
7235 left_rotate(&root,w);
7236 w=par->left;
7238 w->color=par->color;
7239 par->color=SEL_ARG::BLACK;
7240 w->left->color=SEL_ARG::BLACK;
7241 right_rotate(&root,par);
7242 x=root;
7243 break;
7246 par=x->parent;
7248 x->color=SEL_ARG::BLACK;
7249 return root;
7253 /* Test that the properties for a red-black tree hold */
7255 #ifdef EXTRA_DEBUG
7256 int test_rb_tree(SEL_ARG *element,SEL_ARG *parent)
7258 int count_l,count_r;
7260 if (element == &null_element)
7261 return 0; // Found end of tree
7262 if (element->parent != parent)
7264 sql_print_error("Wrong tree: Parent doesn't point at parent");
7265 return -1;
7267 if (element->color == SEL_ARG::RED &&
7268 (element->left->color == SEL_ARG::RED ||
7269 element->right->color == SEL_ARG::RED))
7271 sql_print_error("Wrong tree: Found two red in a row");
7272 return -1;
7274 if (element->left == element->right && element->left != &null_element)
7275 { // Dummy test
7276 sql_print_error("Wrong tree: Found right == left");
7277 return -1;
7279 count_l=test_rb_tree(element->left,element);
7280 count_r=test_rb_tree(element->right,element);
7281 if (count_l >= 0 && count_r >= 0)
7283 if (count_l == count_r)
7284 return count_l+(element->color == SEL_ARG::BLACK);
7285 sql_print_error("Wrong tree: Incorrect black-count: %d - %d",
7286 count_l,count_r);
7288 return -1; // Error, no more warnings
7293 Count how many times SEL_ARG graph "root" refers to its part "key" via
7294 transitive closure.
7296 @param root An RB-Root node in a SEL_ARG graph.
7297 @param key Another RB-Root node in that SEL_ARG graph.
7299 The passed "root" node may refer to "key" node via root->next_key_part,
7300 root->next->n
7302 This function counts how many times the node "key" is referred (via
7303 SEL_ARG::next_key_part) by
7304 - intervals of RB-tree pointed by "root",
7305 - intervals of RB-trees that are pointed by SEL_ARG::next_key_part from
7306 intervals of RB-tree pointed by "root",
7307 - and so on.
7309 Here is an example (horizontal links represent next_key_part pointers,
7310 vertical links - next/prev prev pointers):
7312 +----+ $
7313 |root|-----------------+
7314 +----+ $ |
7315 | $ |
7316 | $ |
7317 +----+ +---+ $ | +---+ Here the return value
7318 | |- ... -| |---$-+--+->|key| will be 4.
7319 +----+ +---+ $ | | +---+
7320 | $ | |
7321 ... $ | |
7322 | $ | |
7323 +----+ +---+ $ | |
7324 | |---| |---------+ |
7325 +----+ +---+ $ |
7326 | | $ |
7327 ... +---+ $ |
7328 | |------------+
7329 +---+ $
7330 @return
7331 Number of links to "key" from nodes reachable from "root".
7334 static ulong count_key_part_usage(SEL_ARG *root, SEL_ARG *key)
7336 ulong count= 0;
7337 for (root=root->first(); root ; root=root->next)
7339 if (root->next_key_part)
7341 if (root->next_key_part == key)
7342 count++;
7343 if (root->next_key_part->part < key->part)
7344 count+=count_key_part_usage(root->next_key_part,key);
7347 return count;
7352 Check if SEL_ARG::use_count value is correct
7354 SYNOPSIS
7355 SEL_ARG::test_use_count()
7356 root The root node of the SEL_ARG graph (an RB-tree root node that
7357 has the least value of sel_arg->part in the entire graph, and
7358 thus is the "origin" of the graph)
7360 DESCRIPTION
7361 Check if SEL_ARG::use_count value is correct. See the definition of
7362 use_count for what is "correct".
7365 void SEL_ARG::test_use_count(SEL_ARG *root)
7367 uint e_count=0;
7368 if (this == root && use_count != 1)
7370 sql_print_information("Use_count: Wrong count %lu for root",use_count);
7371 return;
7373 if (this->type != SEL_ARG::KEY_RANGE)
7374 return;
7375 for (SEL_ARG *pos=first(); pos ; pos=pos->next)
7377 e_count++;
7378 if (pos->next_key_part)
7380 ulong count=count_key_part_usage(root,pos->next_key_part);
7381 if (count > pos->next_key_part->use_count)
7383 sql_print_information("Use_count: Wrong count for key at 0x%lx, %lu "
7384 "should be %lu", (long unsigned int)pos,
7385 pos->next_key_part->use_count, count);
7386 return;
7388 pos->next_key_part->test_use_count(root);
7391 if (e_count != elements)
7392 sql_print_warning("Wrong use count: %u (should be %u) for tree at 0x%lx",
7393 e_count, elements, (long unsigned int) this);
7396 #endif
7400 Calculate estimate of number records that will be retrieved by a range
7401 scan on given index using given SEL_ARG intervals tree.
7402 SYNOPSIS
7403 check_quick_select
7404 param Parameter from test_quick_select
7405 idx Number of index to use in tree->keys
7406 tree Transformed selection condition, tree->keys[idx]
7407 holds the range tree to be used for scanning.
7408 update_tbl_stats If true, update table->quick_keys with information
7409 about range scan we've evaluated.
7411 NOTES
7412 param->is_ror_scan is set to reflect if the key scan is a ROR (see
7413 is_key_scan_ror function for more info)
7414 param->table->quick_*, param->range_count (and maybe others) are
7415 updated with data of given key scan, see check_quick_keys for details.
7417 RETURN
7418 Estimate # of records to be retrieved.
7419 HA_POS_ERROR if estimate calculation failed due to table handler problems.
7423 static ha_rows
7424 check_quick_select(PARAM *param,uint idx,SEL_ARG *tree, bool update_tbl_stats)
7426 ha_rows records;
7427 bool cpk_scan;
7428 uint key;
7429 DBUG_ENTER("check_quick_select");
7431 param->is_ror_scan= FALSE;
7432 param->first_null_comp= 0;
7434 if (!tree)
7435 DBUG_RETURN(HA_POS_ERROR); // Can't use it
7436 param->max_key_part=0;
7437 param->range_count=0;
7438 key= param->real_keynr[idx];
7440 if (tree->type == SEL_ARG::IMPOSSIBLE)
7441 DBUG_RETURN(0L); // Impossible select. return
7442 if (tree->type != SEL_ARG::KEY_RANGE || tree->part != 0)
7443 DBUG_RETURN(HA_POS_ERROR); // Don't use tree
7445 enum ha_key_alg key_alg= param->table->key_info[key].algorithm;
7446 if ((key_alg != HA_KEY_ALG_BTREE) && (key_alg!= HA_KEY_ALG_UNDEF))
7448 /* Records are not ordered by rowid for other types of indexes. */
7449 cpk_scan= FALSE;
7451 else
7454 Clustered PK scan is a special case, check_quick_keys doesn't recognize
7455 CPK scans as ROR scans (while actually any CPK scan is a ROR scan).
7457 cpk_scan= ((param->table->s->primary_key == param->real_keynr[idx]) &&
7458 param->table->file->primary_key_is_clustered());
7459 param->is_ror_scan= !cpk_scan;
7461 param->n_ranges= 0;
7463 records= check_quick_keys(param, idx, tree,
7464 param->min_key, 0, -1,
7465 param->max_key, 0, -1);
7466 if (records != HA_POS_ERROR)
7468 if (update_tbl_stats)
7470 param->table->quick_keys.set_bit(key);
7471 param->table->quick_key_parts[key]=param->max_key_part+1;
7472 param->table->quick_n_ranges[key]= param->n_ranges;
7473 param->table->quick_condition_rows=
7474 min(param->table->quick_condition_rows, records);
7477 Need to save quick_rows in any case as it is used when calculating
7478 cost of ROR intersection:
7480 param->table->quick_rows[key]=records;
7481 if (cpk_scan)
7482 param->is_ror_scan= TRUE;
7484 if (param->table->file->index_flags(key, 0, TRUE) & HA_KEY_SCAN_NOT_ROR)
7485 param->is_ror_scan= FALSE;
7486 DBUG_PRINT("exit", ("Records: %lu", (ulong) records));
7487 DBUG_RETURN(records);
7492 Recursively calculate estimate of # rows that will be retrieved by
7493 key scan on key idx.
7494 SYNOPSIS
7495 check_quick_keys()
7496 param Parameter from test_quick select function.
7497 idx Number of key to use in PARAM::keys in list of used keys
7498 (param->real_keynr[idx] holds the key number in table)
7499 key_tree SEL_ARG tree being examined.
7500 min_key Buffer with partial min key value tuple
7501 min_key_flag
7502 max_key Buffer with partial max key value tuple
7503 max_key_flag
7505 NOTES
7506 The function does the recursive descent on the tree via SEL_ARG::left,
7507 SEL_ARG::right, and SEL_ARG::next_key_part edges. The #rows estimates
7508 are calculated using records_in_range calls at the leaf nodes and then
7509 summed.
7511 param->min_key and param->max_key are used to hold prefixes of key value
7512 tuples.
7514 The side effects are:
7516 param->max_key_part is updated to hold the maximum number of key parts used
7517 in scan minus 1.
7519 param->range_count is incremented if the function finds a range that
7520 wasn't counted by the caller.
7522 param->is_ror_scan is cleared if the function detects that the key scan is
7523 not a Rowid-Ordered Retrieval scan ( see comments for is_key_scan_ror
7524 function for description of which key scans are ROR scans)
7526 RETURN
7527 #records E(#records) for given subtree
7528 HA_POS_ERROR if subtree cannot be used for record retrieval
7532 static ha_rows
7533 check_quick_keys(PARAM *param, uint idx, SEL_ARG *key_tree,
7534 uchar *min_key, uint min_key_flag, int min_keypart,
7535 uchar *max_key, uint max_key_flag, int max_keypart)
7537 ha_rows records=0, tmp;
7538 uint tmp_min_flag, tmp_max_flag, keynr, min_key_length, max_key_length;
7539 uint tmp_min_keypart= min_keypart, tmp_max_keypart= max_keypart;
7540 uchar *tmp_min_key, *tmp_max_key;
7541 uint8 save_first_null_comp= param->first_null_comp;
7543 param->max_key_part=max(param->max_key_part,key_tree->part);
7544 if (key_tree->left != &null_element)
7547 There are at least two intervals for current key part, i.e. condition
7548 was converted to something like
7549 (keyXpartY less/equals c1) OR (keyXpartY more/equals c2).
7550 This is not a ROR scan if the key is not Clustered Primary Key.
7552 param->is_ror_scan= FALSE;
7553 records=check_quick_keys(param, idx, key_tree->left,
7554 min_key, min_key_flag, min_keypart,
7555 max_key, max_key_flag, max_keypart);
7556 if (records == HA_POS_ERROR) // Impossible
7557 return records;
7560 tmp_min_key= min_key;
7561 tmp_max_key= max_key;
7562 tmp_min_keypart+= key_tree->store_min(param->key[idx][key_tree->part].store_length,
7563 &tmp_min_key, min_key_flag);
7564 tmp_max_keypart+= key_tree->store_max(param->key[idx][key_tree->part].store_length,
7565 &tmp_max_key, max_key_flag);
7566 min_key_length= (uint) (tmp_min_key - param->min_key);
7567 max_key_length= (uint) (tmp_max_key - param->max_key);
7569 if (param->is_ror_scan)
7572 If the index doesn't cover entire key, mark the scan as non-ROR scan.
7573 Actually we're cutting off some ROR scans here.
7575 uint16 fieldnr= param->table->key_info[param->real_keynr[idx]].
7576 key_part[key_tree->part].fieldnr - 1;
7577 if (param->table->field[fieldnr]->key_length() !=
7578 param->key[idx][key_tree->part].length)
7579 param->is_ror_scan= FALSE;
7582 if (!param->first_null_comp && key_tree->is_null_interval())
7583 param->first_null_comp= key_tree->part+1;
7585 if (key_tree->next_key_part &&
7586 key_tree->next_key_part->type == SEL_ARG::KEY_RANGE &&
7587 key_tree->next_key_part->part == key_tree->part+1)
7588 { // const key as prefix
7589 if (min_key_length == max_key_length &&
7590 !memcmp(min_key, max_key, (uint) (tmp_max_key - max_key)) &&
7591 !key_tree->min_flag && !key_tree->max_flag)
7593 tmp=check_quick_keys(param,idx,key_tree->next_key_part, tmp_min_key,
7594 min_key_flag | key_tree->min_flag, tmp_min_keypart,
7595 tmp_max_key, max_key_flag | key_tree->max_flag,
7596 tmp_max_keypart);
7597 goto end; // Ugly, but efficient
7599 else
7601 /* The interval for current key part is not c1 <= keyXpartY <= c1 */
7602 param->is_ror_scan= FALSE;
7605 tmp_min_flag=key_tree->min_flag;
7606 tmp_max_flag=key_tree->max_flag;
7607 if (!tmp_min_flag)
7608 tmp_min_keypart+=
7609 key_tree->next_key_part->store_min_key(param->key[idx], &tmp_min_key,
7610 &tmp_min_flag);
7611 if (!tmp_max_flag)
7612 tmp_max_keypart+=
7613 key_tree->next_key_part->store_max_key(param->key[idx], &tmp_max_key,
7614 &tmp_max_flag);
7615 min_key_length= (uint) (tmp_min_key - param->min_key);
7616 max_key_length= (uint) (tmp_max_key - param->max_key);
7618 else
7620 tmp_min_flag= min_key_flag | key_tree->min_flag;
7621 tmp_max_flag= max_key_flag | key_tree->max_flag;
7624 if (unlikely(param->thd->killed != 0))
7625 return HA_POS_ERROR;
7627 keynr=param->real_keynr[idx];
7628 param->range_count++;
7629 if (!tmp_min_flag && ! tmp_max_flag &&
7630 (uint) key_tree->part+1 == param->table->key_info[keynr].key_parts &&
7631 (param->table->key_info[keynr].flags & (HA_NOSAME | HA_END_SPACE_KEY)) ==
7632 HA_NOSAME && min_key_length == max_key_length &&
7633 !memcmp(param->min_key, param->max_key, min_key_length) &&
7634 !param->first_null_comp)
7636 tmp=1; // Max one record
7637 param->n_ranges++;
7639 else
7641 if (param->is_ror_scan)
7644 If we get here, the condition on the key was converted to form
7645 "(keyXpart1 = c1) AND ... AND (keyXpart{key_tree->part - 1} = cN) AND
7646 somecond(keyXpart{key_tree->part})"
7647 Check if
7648 somecond is "keyXpart{key_tree->part} = const" and
7649 uncovered "tail" of KeyX parts is either empty or is identical to
7650 first members of clustered primary key.
7652 if (!(min_key_length == max_key_length &&
7653 !memcmp(min_key, max_key, (uint) (tmp_max_key - max_key)) &&
7654 !key_tree->min_flag && !key_tree->max_flag &&
7655 is_key_scan_ror(param, keynr, key_tree->part + 1)))
7656 param->is_ror_scan= FALSE;
7658 param->n_ranges++;
7660 if (tmp_min_flag & GEOM_FLAG)
7662 key_range min_range;
7663 min_range.key= param->min_key;
7664 min_range.length= min_key_length;
7665 min_range.keypart_map= make_keypart_map(tmp_min_keypart);
7666 /* In this case tmp_min_flag contains the handler-read-function */
7667 min_range.flag= (ha_rkey_function) (tmp_min_flag ^ GEOM_FLAG);
7669 tmp= param->table->file->records_in_range(keynr,
7670 &min_range, (key_range*) 0);
7672 else
7674 key_range min_range, max_range;
7676 min_range.key= param->min_key;
7677 min_range.length= min_key_length;
7678 min_range.flag= (tmp_min_flag & NEAR_MIN ? HA_READ_AFTER_KEY :
7679 HA_READ_KEY_EXACT);
7680 min_range.keypart_map= make_keypart_map(tmp_min_keypart);
7681 max_range.key= param->max_key;
7682 max_range.length= max_key_length;
7683 max_range.flag= (tmp_max_flag & NEAR_MAX ?
7684 HA_READ_BEFORE_KEY : HA_READ_AFTER_KEY);
7685 max_range.keypart_map= make_keypart_map(tmp_max_keypart);
7686 tmp=param->table->file->records_in_range(keynr,
7687 (min_key_length ? &min_range :
7688 (key_range*) 0),
7689 (max_key_length ? &max_range :
7690 (key_range*) 0));
7693 end:
7694 if (tmp == HA_POS_ERROR) // Impossible range
7695 return tmp;
7696 records+=tmp;
7697 if (key_tree->right != &null_element)
7700 There are at least two intervals for current key part, i.e. condition
7701 was converted to something like
7702 (keyXpartY less/equals c1) OR (keyXpartY more/equals c2).
7703 This is not a ROR scan if the key is not Clustered Primary Key.
7705 param->is_ror_scan= FALSE;
7706 tmp=check_quick_keys(param, idx, key_tree->right,
7707 min_key, min_key_flag, min_keypart,
7708 max_key, max_key_flag, max_keypart);
7709 if (tmp == HA_POS_ERROR)
7710 return tmp;
7711 records+=tmp;
7713 param->first_null_comp= save_first_null_comp;
7714 return records;
7719 Check if key scan on given index with equality conditions on first n key
7720 parts is a ROR scan.
7722 SYNOPSIS
7723 is_key_scan_ror()
7724 param Parameter from test_quick_select
7725 keynr Number of key in the table. The key must not be a clustered
7726 primary key.
7727 nparts Number of first key parts for which equality conditions
7728 are present.
7730 NOTES
7731 ROR (Rowid Ordered Retrieval) key scan is a key scan that produces
7732 ordered sequence of rowids (ha_xxx::cmp_ref is the comparison function)
7734 This function is needed to handle a practically-important special case:
7735 an index scan is a ROR scan if it is done using a condition in form
7737 "key1_1=c_1 AND ... AND key1_n=c_n"
7739 where the index is defined on (key1_1, ..., key1_N [,a_1, ..., a_n])
7741 and the table has a clustered Primary Key defined as
7743 PRIMARY KEY(a_1, ..., a_n, b1, ..., b_k)
7745 i.e. the first key parts of it are identical to uncovered parts ot the
7746 key being scanned. This function assumes that the index flags do not
7747 include HA_KEY_SCAN_NOT_ROR flag (that is checked elsewhere).
7749 RETURN
7750 TRUE The scan is ROR-scan
7751 FALSE Otherwise
7754 static bool is_key_scan_ror(PARAM *param, uint keynr, uint8 nparts)
7756 KEY *table_key= param->table->key_info + keynr;
7757 KEY_PART_INFO *key_part= table_key->key_part + nparts;
7758 KEY_PART_INFO *key_part_end= (table_key->key_part +
7759 table_key->key_parts);
7760 uint pk_number;
7762 if (key_part == key_part_end)
7763 return TRUE;
7764 pk_number= param->table->s->primary_key;
7765 if (!param->table->file->primary_key_is_clustered() || pk_number == MAX_KEY)
7766 return FALSE;
7768 KEY_PART_INFO *pk_part= param->table->key_info[pk_number].key_part;
7769 KEY_PART_INFO *pk_part_end= pk_part +
7770 param->table->key_info[pk_number].key_parts;
7771 for (;(key_part!=key_part_end) && (pk_part != pk_part_end);
7772 ++key_part, ++pk_part)
7774 if ((key_part->field != pk_part->field) ||
7775 (key_part->length != pk_part->length))
7776 return FALSE;
7778 return (key_part == key_part_end);
7783 Create a QUICK_RANGE_SELECT from given key and SEL_ARG tree for that key.
7785 SYNOPSIS
7786 get_quick_select()
7787 param
7788 idx Index of used key in param->key.
7789 key_tree SEL_ARG tree for the used key
7790 parent_alloc If not NULL, use it to allocate memory for
7791 quick select data. Otherwise use quick->alloc.
7792 NOTES
7793 The caller must call QUICK_SELECT::init for returned quick select
7795 CAUTION! This function may change thd->mem_root to a MEM_ROOT which will be
7796 deallocated when the returned quick select is deleted.
7798 RETURN
7799 NULL on error
7800 otherwise created quick select
7803 QUICK_RANGE_SELECT *
7804 get_quick_select(PARAM *param,uint idx,SEL_ARG *key_tree,
7805 MEM_ROOT *parent_alloc)
7807 QUICK_RANGE_SELECT *quick;
7808 DBUG_ENTER("get_quick_select");
7810 if (param->table->key_info[param->real_keynr[idx]].flags & HA_SPATIAL)
7811 quick=new QUICK_RANGE_SELECT_GEOM(param->thd, param->table,
7812 param->real_keynr[idx],
7813 test(parent_alloc),
7814 parent_alloc);
7815 else
7816 quick=new QUICK_RANGE_SELECT(param->thd, param->table,
7817 param->real_keynr[idx],
7818 test(parent_alloc));
7820 if (quick)
7822 if (quick->error ||
7823 get_quick_keys(param,quick,param->key[idx],key_tree,param->min_key,0,
7824 param->max_key,0))
7826 delete quick;
7827 quick=0;
7829 else
7831 quick->key_parts=(KEY_PART*)
7832 memdup_root(parent_alloc? parent_alloc : &quick->alloc,
7833 (char*) param->key[idx],
7834 sizeof(KEY_PART)*
7835 param->table->key_info[param->real_keynr[idx]].key_parts);
7838 DBUG_RETURN(quick);
7843 ** Fix this to get all possible sub_ranges
7845 bool
7846 get_quick_keys(PARAM *param,QUICK_RANGE_SELECT *quick,KEY_PART *key,
7847 SEL_ARG *key_tree, uchar *min_key,uint min_key_flag,
7848 uchar *max_key, uint max_key_flag)
7850 QUICK_RANGE *range;
7851 uint flag;
7852 int min_part= key_tree->part-1, // # of keypart values in min_key buffer
7853 max_part= key_tree->part-1; // # of keypart values in max_key buffer
7855 if (key_tree->left != &null_element)
7857 if (get_quick_keys(param,quick,key,key_tree->left,
7858 min_key,min_key_flag, max_key, max_key_flag))
7859 return 1;
7861 uchar *tmp_min_key=min_key,*tmp_max_key=max_key;
7862 min_part+= key_tree->store_min(key[key_tree->part].store_length,
7863 &tmp_min_key,min_key_flag);
7864 max_part+= key_tree->store_max(key[key_tree->part].store_length,
7865 &tmp_max_key,max_key_flag);
7867 if (key_tree->next_key_part &&
7868 key_tree->next_key_part->type == SEL_ARG::KEY_RANGE &&
7869 key_tree->next_key_part->part == key_tree->part+1)
7870 { // const key as prefix
7871 if ((tmp_min_key - min_key) == (tmp_max_key - max_key) &&
7872 memcmp(min_key, max_key, (uint)(tmp_max_key - max_key))==0 &&
7873 key_tree->min_flag==0 && key_tree->max_flag==0)
7875 if (get_quick_keys(param,quick,key,key_tree->next_key_part,
7876 tmp_min_key, min_key_flag | key_tree->min_flag,
7877 tmp_max_key, max_key_flag | key_tree->max_flag))
7878 return 1;
7879 goto end; // Ugly, but efficient
7882 uint tmp_min_flag=key_tree->min_flag,tmp_max_flag=key_tree->max_flag;
7883 if (!tmp_min_flag)
7884 min_part+= key_tree->next_key_part->store_min_key(key, &tmp_min_key,
7885 &tmp_min_flag);
7886 if (!tmp_max_flag)
7887 max_part+= key_tree->next_key_part->store_max_key(key, &tmp_max_key,
7888 &tmp_max_flag);
7889 flag=tmp_min_flag | tmp_max_flag;
7892 else
7894 flag = (key_tree->min_flag & GEOM_FLAG) ?
7895 key_tree->min_flag : key_tree->min_flag | key_tree->max_flag;
7899 Ensure that some part of min_key and max_key are used. If not,
7900 regard this as no lower/upper range
7902 if ((flag & GEOM_FLAG) == 0)
7904 if (tmp_min_key != param->min_key)
7905 flag&= ~NO_MIN_RANGE;
7906 else
7907 flag|= NO_MIN_RANGE;
7908 if (tmp_max_key != param->max_key)
7909 flag&= ~NO_MAX_RANGE;
7910 else
7911 flag|= NO_MAX_RANGE;
7913 if (flag == 0)
7915 uint length= (uint) (tmp_min_key - param->min_key);
7916 if (length == (uint) (tmp_max_key - param->max_key) &&
7917 !memcmp(param->min_key,param->max_key,length))
7919 KEY *table_key=quick->head->key_info+quick->index;
7920 flag=EQ_RANGE;
7921 if ((table_key->flags & (HA_NOSAME | HA_END_SPACE_KEY)) == HA_NOSAME &&
7922 key->part == table_key->key_parts-1)
7924 if (!(table_key->flags & HA_NULL_PART_KEY) ||
7925 !null_part_in_key(key,
7926 param->min_key,
7927 (uint) (tmp_min_key - param->min_key)))
7928 flag|= UNIQUE_RANGE;
7929 else
7930 flag|= NULL_RANGE;
7935 /* Get range for retrieving rows in QUICK_SELECT::get_next */
7936 if (!(range= new QUICK_RANGE(param->min_key,
7937 (uint) (tmp_min_key - param->min_key),
7938 min_part >=0 ? make_keypart_map(min_part) : 0,
7939 param->max_key,
7940 (uint) (tmp_max_key - param->max_key),
7941 max_part >=0 ? make_keypart_map(max_part) : 0,
7942 flag)))
7943 return 1; // out of memory
7945 set_if_bigger(quick->max_used_key_length, range->min_length);
7946 set_if_bigger(quick->max_used_key_length, range->max_length);
7947 set_if_bigger(quick->used_key_parts, (uint) key_tree->part+1);
7948 if (insert_dynamic(&quick->ranges, (uchar*) &range))
7949 return 1;
7951 end:
7952 if (key_tree->right != &null_element)
7953 return get_quick_keys(param,quick,key,key_tree->right,
7954 min_key,min_key_flag,
7955 max_key,max_key_flag);
7956 return 0;
7960 Return 1 if there is only one range and this uses the whole primary key
7963 bool QUICK_RANGE_SELECT::unique_key_range()
7965 if (ranges.elements == 1)
7967 QUICK_RANGE *tmp= *((QUICK_RANGE**)ranges.buffer);
7968 if ((tmp->flag & (EQ_RANGE | NULL_RANGE)) == EQ_RANGE)
7970 KEY *key=head->key_info+index;
7971 return ((key->flags & (HA_NOSAME | HA_END_SPACE_KEY)) == HA_NOSAME &&
7972 key->key_length == tmp->min_length);
7975 return 0;
7979 /* Returns TRUE if any part of the key is NULL */
7981 static bool null_part_in_key(KEY_PART *key_part, const uchar *key, uint length)
7983 for (const uchar *end=key+length ;
7984 key < end;
7985 key+= key_part++->store_length)
7987 if (key_part->null_bit && *key)
7988 return 1;
7990 return 0;
7994 bool QUICK_SELECT_I::is_keys_used(const MY_BITMAP *fields)
7996 return is_key_used(head, index, fields);
7999 bool QUICK_INDEX_MERGE_SELECT::is_keys_used(const MY_BITMAP *fields)
8001 QUICK_RANGE_SELECT *quick;
8002 List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
8003 while ((quick= it++))
8005 if (is_key_used(head, quick->index, fields))
8006 return 1;
8008 return 0;
8011 bool QUICK_ROR_INTERSECT_SELECT::is_keys_used(const MY_BITMAP *fields)
8013 QUICK_RANGE_SELECT *quick;
8014 List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
8015 while ((quick= it++))
8017 if (is_key_used(head, quick->index, fields))
8018 return 1;
8020 return 0;
8023 bool QUICK_ROR_UNION_SELECT::is_keys_used(const MY_BITMAP *fields)
8025 QUICK_SELECT_I *quick;
8026 List_iterator_fast<QUICK_SELECT_I> it(quick_selects);
8027 while ((quick= it++))
8029 if (quick->is_keys_used(fields))
8030 return 1;
8032 return 0;
8037 Create quick select from ref/ref_or_null scan.
8039 SYNOPSIS
8040 get_quick_select_for_ref()
8041 thd Thread handle
8042 table Table to access
8043 ref ref[_or_null] scan parameters
8044 records Estimate of number of records (needed only to construct
8045 quick select)
8046 NOTES
8047 This allocates things in a new memory root, as this may be called many
8048 times during a query.
8050 RETURN
8051 Quick select that retrieves the same rows as passed ref scan
8052 NULL on error.
8055 QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table,
8056 TABLE_REF *ref, ha_rows records)
8058 MEM_ROOT *old_root, *alloc;
8059 QUICK_RANGE_SELECT *quick;
8060 KEY *key_info = &table->key_info[ref->key];
8061 KEY_PART *key_part;
8062 QUICK_RANGE *range;
8063 uint part;
8065 old_root= thd->mem_root;
8066 /* The following call may change thd->mem_root */
8067 quick= new QUICK_RANGE_SELECT(thd, table, ref->key, 0);
8068 /* save mem_root set by QUICK_RANGE_SELECT constructor */
8069 alloc= thd->mem_root;
8071 return back default mem_root (thd->mem_root) changed by
8072 QUICK_RANGE_SELECT constructor
8074 thd->mem_root= old_root;
8076 if (!quick)
8077 return 0; /* no ranges found */
8078 if (quick->init())
8079 goto err;
8080 quick->records= records;
8082 if ((cp_buffer_from_ref(thd, table, ref) && thd->is_fatal_error) ||
8083 !(range= new(alloc) QUICK_RANGE()))
8084 goto err; // out of memory
8086 range->min_key= range->max_key= ref->key_buff;
8087 range->min_length= range->max_length= ref->key_length;
8088 range->min_keypart_map= range->max_keypart_map=
8089 make_prev_keypart_map(ref->key_parts);
8090 range->flag= ((ref->key_length == key_info->key_length &&
8091 (key_info->flags & HA_END_SPACE_KEY) == 0) ? EQ_RANGE : 0);
8093 if (!(quick->key_parts=key_part=(KEY_PART *)
8094 alloc_root(&quick->alloc,sizeof(KEY_PART)*ref->key_parts)))
8095 goto err;
8097 for (part=0 ; part < ref->key_parts ;part++,key_part++)
8099 key_part->part=part;
8100 key_part->field= key_info->key_part[part].field;
8101 key_part->length= key_info->key_part[part].length;
8102 key_part->store_length= key_info->key_part[part].store_length;
8103 key_part->null_bit= key_info->key_part[part].null_bit;
8104 key_part->flag= (uint8) key_info->key_part[part].key_part_flag;
8106 if (insert_dynamic(&quick->ranges,(uchar*)&range))
8107 goto err;
8110 Add a NULL range if REF_OR_NULL optimization is used.
8111 For example:
8112 if we have "WHERE A=2 OR A IS NULL" we created the (A=2) range above
8113 and have ref->null_ref_key set. Will create a new NULL range here.
8115 if (ref->null_ref_key)
8117 QUICK_RANGE *null_range;
8119 *ref->null_ref_key= 1; // Set null byte then create a range
8120 if (!(null_range= new (alloc)
8121 QUICK_RANGE(ref->key_buff, ref->key_length,
8122 make_prev_keypart_map(ref->key_parts),
8123 ref->key_buff, ref->key_length,
8124 make_prev_keypart_map(ref->key_parts), EQ_RANGE)))
8125 goto err;
8126 *ref->null_ref_key= 0; // Clear null byte
8127 if (insert_dynamic(&quick->ranges,(uchar*)&null_range))
8128 goto err;
8131 return quick;
8133 err:
8134 delete quick;
8135 return 0;
8140 Perform key scans for all used indexes (except CPK), get rowids and merge
8141 them into an ordered non-recurrent sequence of rowids.
8143 The merge/duplicate removal is performed using Unique class. We put all
8144 rowids into Unique, get the sorted sequence and destroy the Unique.
8146 If table has a clustered primary key that covers all rows (TRUE for bdb
8147 and innodb currently) and one of the index_merge scans is a scan on PK,
8148 then rows that will be retrieved by PK scan are not put into Unique and
8149 primary key scan is not performed here, it is performed later separately.
8151 RETURN
8152 0 OK
8153 other error
8156 int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge()
8158 List_iterator_fast<QUICK_RANGE_SELECT> cur_quick_it(quick_selects);
8159 QUICK_RANGE_SELECT* cur_quick;
8160 int result;
8161 handler *file= head->file;
8162 DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::read_keys_and_merge");
8164 /* We're going to just read rowids. */
8165 head->set_keyread(TRUE);
8166 head->prepare_for_position();
8168 cur_quick_it.rewind();
8169 cur_quick= cur_quick_it++;
8170 DBUG_ASSERT(cur_quick != 0);
8173 We reuse the same instance of handler so we need to call both init and
8174 reset here.
8176 if (cur_quick->init() || cur_quick->reset())
8177 DBUG_RETURN(1);
8179 if (unique == NULL)
8181 DBUG_EXECUTE_IF("index_merge_may_not_create_a_Unique", abort(); );
8182 DBUG_EXECUTE_IF("only_one_Unique_may_be_created",
8183 DBUG_SET("+d,index_merge_may_not_create_a_Unique"); );
8185 unique= new Unique(refpos_order_cmp, (void *)file,
8186 file->ref_length,
8187 thd->variables.sortbuff_size);
8189 else
8190 unique->reset();
8192 DBUG_ASSERT(file->ref_length == unique->get_size());
8193 DBUG_ASSERT(thd->variables.sortbuff_size == unique->get_max_in_memory_size());
8195 if (!unique)
8196 DBUG_RETURN(1);
8197 for (;;)
8199 while ((result= cur_quick->get_next()) == HA_ERR_END_OF_FILE)
8201 cur_quick->range_end();
8202 cur_quick= cur_quick_it++;
8203 if (!cur_quick)
8204 break;
8206 if (cur_quick->file->inited != handler::NONE)
8207 cur_quick->file->ha_index_end();
8208 if (cur_quick->init() || cur_quick->reset())
8209 DBUG_RETURN(1);
8212 if (result)
8214 if (result != HA_ERR_END_OF_FILE)
8216 cur_quick->range_end();
8217 DBUG_RETURN(result);
8219 break;
8222 if (thd->killed)
8223 DBUG_RETURN(1);
8225 /* skip row if it will be retrieved by clustered PK scan */
8226 if (pk_quick_select && pk_quick_select->row_in_ranges())
8227 continue;
8229 cur_quick->file->position(cur_quick->record);
8230 result= unique->unique_add((char*)cur_quick->file->ref);
8231 if (result)
8232 DBUG_RETURN(1);
8236 Ok all rowids are in the Unique now. The next call will initialize
8237 head->sort structure so it can be used to iterate through the rowids
8238 sequence.
8240 result= unique->get(head);
8241 doing_pk_scan= FALSE;
8242 /* index_merge currently doesn't support "using index" at all */
8243 head->set_keyread(FALSE);
8244 init_read_record(&read_record, thd, head, (SQL_SELECT*) 0, 1 , 1, TRUE);
8245 DBUG_RETURN(result);
8250 Get next row for index_merge.
8251 NOTES
8252 The rows are read from
8253 1. rowids stored in Unique.
8254 2. QUICK_RANGE_SELECT with clustered primary key (if any).
8255 The sets of rows retrieved in 1) and 2) are guaranteed to be disjoint.
8258 int QUICK_INDEX_MERGE_SELECT::get_next()
8260 int result;
8261 DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::get_next");
8263 if (doing_pk_scan)
8264 DBUG_RETURN(pk_quick_select->get_next());
8266 if ((result= read_record.read_record(&read_record)) == -1)
8268 result= HA_ERR_END_OF_FILE;
8269 end_read_record(&read_record);
8270 free_io_cache(head);
8271 /* All rows from Unique have been retrieved, do a clustered PK scan */
8272 if (pk_quick_select)
8274 doing_pk_scan= TRUE;
8275 if ((result= pk_quick_select->init()) ||
8276 (result= pk_quick_select->reset()))
8277 DBUG_RETURN(result);
8278 DBUG_RETURN(pk_quick_select->get_next());
8282 DBUG_RETURN(result);
8287 Retrieve next record.
8288 SYNOPSIS
8289 QUICK_ROR_INTERSECT_SELECT::get_next()
8291 NOTES
8292 Invariant on enter/exit: all intersected selects have retrieved all index
8293 records with rowid <= some_rowid_val and no intersected select has
8294 retrieved any index records with rowid > some_rowid_val.
8295 We start fresh and loop until we have retrieved the same rowid in each of
8296 the key scans or we got an error.
8298 If a Clustered PK scan is present, it is used only to check if row
8299 satisfies its condition (and never used for row retrieval).
8301 RETURN
8302 0 - Ok
8303 other - Error code if any error occurred.
8306 int QUICK_ROR_INTERSECT_SELECT::get_next()
8308 List_iterator_fast<QUICK_RANGE_SELECT> quick_it(quick_selects);
8309 QUICK_RANGE_SELECT* quick;
8310 int error, cmp;
8311 uint last_rowid_count=0;
8312 DBUG_ENTER("QUICK_ROR_INTERSECT_SELECT::get_next");
8316 /* Get a rowid for first quick and save it as a 'candidate' */
8317 quick= quick_it++;
8318 error= quick->get_next();
8319 if (cpk_quick)
8321 while (!error && !cpk_quick->row_in_ranges())
8322 error= quick->get_next();
8324 if (error)
8325 DBUG_RETURN(error);
8327 quick->file->position(quick->record);
8328 memcpy(last_rowid, quick->file->ref, head->file->ref_length);
8329 last_rowid_count= 1;
8331 while (last_rowid_count < quick_selects.elements)
8333 if (!(quick= quick_it++))
8335 quick_it.rewind();
8336 quick= quick_it++;
8341 if ((error= quick->get_next()))
8342 DBUG_RETURN(error);
8343 quick->file->position(quick->record);
8344 cmp= head->file->cmp_ref(quick->file->ref, last_rowid);
8345 } while (cmp < 0);
8347 /* Ok, current select 'caught up' and returned ref >= cur_ref */
8348 if (cmp > 0)
8350 /* Found a row with ref > cur_ref. Make it a new 'candidate' */
8351 if (cpk_quick)
8353 while (!cpk_quick->row_in_ranges())
8355 if ((error= quick->get_next()))
8356 DBUG_RETURN(error);
8358 quick->file->position(quick->record);
8360 memcpy(last_rowid, quick->file->ref, head->file->ref_length);
8361 last_rowid_count= 1;
8363 else
8365 /* current 'candidate' row confirmed by this select */
8366 last_rowid_count++;
8370 /* We get here if we got the same row ref in all scans. */
8371 if (need_to_fetch_row)
8372 error= head->file->rnd_pos(head->record[0], last_rowid);
8373 } while (error == HA_ERR_RECORD_DELETED);
8374 DBUG_RETURN(error);
8379 Retrieve next record.
8380 SYNOPSIS
8381 QUICK_ROR_UNION_SELECT::get_next()
8383 NOTES
8384 Enter/exit invariant:
8385 For each quick select in the queue a {key,rowid} tuple has been
8386 retrieved but the corresponding row hasn't been passed to output.
8388 RETURN
8389 0 - Ok
8390 other - Error code if any error occurred.
8393 int QUICK_ROR_UNION_SELECT::get_next()
8395 int error, dup_row;
8396 QUICK_SELECT_I *quick;
8397 uchar *tmp;
8398 DBUG_ENTER("QUICK_ROR_UNION_SELECT::get_next");
8404 if (!queue.elements)
8405 DBUG_RETURN(HA_ERR_END_OF_FILE);
8406 /* Ok, we have a queue with >= 1 scans */
8408 quick= (QUICK_SELECT_I*)queue_top(&queue);
8409 memcpy(cur_rowid, quick->last_rowid, rowid_length);
8411 /* put into queue rowid from the same stream as top element */
8412 if ((error= quick->get_next()))
8414 if (error != HA_ERR_END_OF_FILE)
8415 DBUG_RETURN(error);
8416 queue_remove(&queue, 0);
8418 else
8420 quick->save_last_pos();
8421 queue_replaced(&queue);
8424 if (!have_prev_rowid)
8426 /* No rows have been returned yet */
8427 dup_row= FALSE;
8428 have_prev_rowid= TRUE;
8430 else
8431 dup_row= !head->file->cmp_ref(cur_rowid, prev_rowid);
8432 } while (dup_row);
8434 tmp= cur_rowid;
8435 cur_rowid= prev_rowid;
8436 prev_rowid= tmp;
8438 error= head->file->rnd_pos(quick->record, prev_rowid);
8439 } while (error == HA_ERR_RECORD_DELETED);
8440 DBUG_RETURN(error);
8444 int QUICK_RANGE_SELECT::reset()
8446 uint mrange_bufsiz;
8447 uchar *mrange_buff;
8448 DBUG_ENTER("QUICK_RANGE_SELECT::reset");
8449 next=0;
8450 last_range= NULL;
8451 in_range= FALSE;
8452 cur_range= (QUICK_RANGE**) ranges.buffer;
8454 if (file->inited == handler::NONE)
8456 if (in_ror_merged_scan)
8457 head->column_bitmaps_set_no_signal(&column_bitmap, &column_bitmap);
8458 if ((error= file->ha_index_init(index,1)))
8459 DBUG_RETURN(error);
8462 /* Do not allocate the buffers twice. */
8463 if (multi_range_length)
8465 DBUG_ASSERT(multi_range_length == min(multi_range_count, ranges.elements));
8466 DBUG_RETURN(0);
8469 /* Allocate the ranges array. */
8470 DBUG_ASSERT(ranges.elements);
8471 multi_range_length= min(multi_range_count, ranges.elements);
8472 DBUG_ASSERT(multi_range_length > 0);
8473 while (multi_range_length && ! (multi_range= (KEY_MULTI_RANGE*)
8474 my_malloc(multi_range_length *
8475 sizeof(KEY_MULTI_RANGE),
8476 MYF(MY_WME))))
8478 /* Try to shrink the buffers until it is 0. */
8479 multi_range_length/= 2;
8481 if (! multi_range)
8483 multi_range_length= 0;
8484 DBUG_RETURN(HA_ERR_OUT_OF_MEM);
8487 /* Allocate the handler buffer if necessary. */
8488 if (file->ha_table_flags() & HA_NEED_READ_RANGE_BUFFER)
8490 mrange_bufsiz= min(multi_range_bufsiz,
8491 ((uint)QUICK_SELECT_I::records + 1)* head->s->reclength);
8493 while (mrange_bufsiz &&
8494 ! my_multi_malloc(MYF(MY_WME),
8495 &multi_range_buff,
8496 (uint) sizeof(*multi_range_buff),
8497 &mrange_buff, (uint) mrange_bufsiz,
8498 NullS))
8500 /* Try to shrink the buffers until both are 0. */
8501 mrange_bufsiz/= 2;
8503 if (! multi_range_buff)
8505 my_free((char*) multi_range, MYF(0));
8506 multi_range= NULL;
8507 multi_range_length= 0;
8508 DBUG_RETURN(HA_ERR_OUT_OF_MEM);
8511 /* Initialize the handler buffer. */
8512 multi_range_buff->buffer= mrange_buff;
8513 multi_range_buff->buffer_end= mrange_buff + mrange_bufsiz;
8514 multi_range_buff->end_of_used_area= mrange_buff;
8515 #ifdef HAVE_purify
8517 We need this until ndb will use the buffer efficiently
8518 (Now ndb stores complete row in here, instead of only the used fields
8519 which gives us valgrind warnings in compare_record[])
8521 bzero((char*) mrange_buff, mrange_bufsiz);
8522 #endif
8524 DBUG_RETURN(0);
8529 Get next possible record using quick-struct.
8531 SYNOPSIS
8532 QUICK_RANGE_SELECT::get_next()
8534 NOTES
8535 Record is read into table->record[0]
8537 RETURN
8538 0 Found row
8539 HA_ERR_END_OF_FILE No (more) rows in range
8540 # Error code
8543 int QUICK_RANGE_SELECT::get_next()
8545 int result;
8546 KEY_MULTI_RANGE *mrange;
8547 DBUG_ENTER("QUICK_RANGE_SELECT::get_next");
8548 DBUG_ASSERT(multi_range_length && multi_range &&
8549 (cur_range >= (QUICK_RANGE**) ranges.buffer) &&
8550 (cur_range <= (QUICK_RANGE**) ranges.buffer + ranges.elements));
8552 if (in_ror_merged_scan)
8555 We don't need to signal the bitmap change as the bitmap is always the
8556 same for this head->file
8558 head->column_bitmaps_set_no_signal(&column_bitmap, &column_bitmap);
8561 for (;;)
8563 if (in_range)
8565 /* We did already start to read this key. */
8566 result= file->read_multi_range_next(&mrange);
8567 if (result != HA_ERR_END_OF_FILE)
8568 goto end;
8571 uint count= min(multi_range_length, ranges.elements -
8572 (cur_range - (QUICK_RANGE**) ranges.buffer));
8573 if (count == 0)
8575 /* Ranges have already been used up before. None is left for read. */
8576 in_range= FALSE;
8577 if (in_ror_merged_scan)
8578 head->column_bitmaps_set_no_signal(save_read_set, save_write_set);
8579 DBUG_RETURN(HA_ERR_END_OF_FILE);
8581 KEY_MULTI_RANGE *mrange_slot, *mrange_end;
8582 for (mrange_slot= multi_range, mrange_end= mrange_slot+count;
8583 mrange_slot < mrange_end;
8584 mrange_slot++)
8586 last_range= *(cur_range++);
8587 last_range->make_min_endpoint(&mrange_slot->start_key);
8588 last_range->make_max_endpoint(&mrange_slot->end_key);
8589 mrange_slot->range_flag= last_range->flag;
8592 result= file->read_multi_range_first(&mrange, multi_range, count,
8593 sorted, multi_range_buff);
8594 if (result != HA_ERR_END_OF_FILE)
8595 goto end;
8596 in_range= FALSE; /* No matching rows; go to next set of ranges. */
8599 end:
8600 in_range= ! result;
8601 if (in_ror_merged_scan)
8603 /* Restore bitmaps set on entry */
8604 head->column_bitmaps_set_no_signal(save_read_set, save_write_set);
8606 DBUG_RETURN(result);
8610 Get the next record with a different prefix.
8612 @param prefix_length length of cur_prefix
8613 @param group_key_parts The number of key parts in the group prefix
8614 @param cur_prefix prefix of a key to be searched for
8616 Each subsequent call to the method retrieves the first record that has a
8617 prefix with length prefix_length and which is different from cur_prefix,
8618 such that the record with the new prefix is within the ranges described by
8619 this->ranges. The record found is stored into the buffer pointed by
8620 this->record. The method is useful for GROUP-BY queries with range
8621 conditions to discover the prefix of the next group that satisfies the range
8622 conditions.
8624 @todo
8626 This method is a modified copy of QUICK_RANGE_SELECT::get_next(), so both
8627 methods should be unified into a more general one to reduce code
8628 duplication.
8630 @retval 0 on success
8631 @retval HA_ERR_END_OF_FILE if returned all keys
8632 @retval other if some error occurred
8635 int QUICK_RANGE_SELECT::get_next_prefix(uint prefix_length,
8636 uint group_key_parts,
8637 uchar *cur_prefix)
8639 DBUG_ENTER("QUICK_RANGE_SELECT::get_next_prefix");
8640 const key_part_map keypart_map= make_prev_keypart_map(group_key_parts);
8642 for (;;)
8644 int result;
8645 if (last_range)
8647 /* Read the next record in the same range with prefix after cur_prefix. */
8648 DBUG_ASSERT(cur_prefix != NULL);
8649 result= file->index_read_map(record, cur_prefix, keypart_map,
8650 HA_READ_AFTER_KEY);
8651 if (result || last_range->max_keypart_map == 0)
8652 DBUG_RETURN(result);
8654 key_range previous_endpoint;
8655 last_range->make_max_endpoint(&previous_endpoint, prefix_length, keypart_map);
8656 if (file->compare_key(&previous_endpoint) <= 0)
8657 DBUG_RETURN(0);
8660 uint count= ranges.elements - (cur_range - (QUICK_RANGE**) ranges.buffer);
8661 if (count == 0)
8663 /* Ranges have already been used up before. None is left for read. */
8664 last_range= 0;
8665 DBUG_RETURN(HA_ERR_END_OF_FILE);
8667 last_range= *(cur_range++);
8669 key_range start_key, end_key;
8670 last_range->make_min_endpoint(&start_key, prefix_length, keypart_map);
8671 last_range->make_max_endpoint(&end_key, prefix_length, keypart_map);
8673 result= file->read_range_first(last_range->min_keypart_map ? &start_key : 0,
8674 last_range->max_keypart_map ? &end_key : 0,
8675 test(last_range->flag & EQ_RANGE),
8676 TRUE);
8677 if (last_range->flag == (UNIQUE_RANGE | EQ_RANGE))
8678 last_range= 0; // Stop searching
8680 if (result != HA_ERR_END_OF_FILE)
8681 DBUG_RETURN(result);
8682 last_range= 0; // No matching rows; go to next range
8687 /* Get next for geometrical indexes */
8689 int QUICK_RANGE_SELECT_GEOM::get_next()
8691 DBUG_ENTER("QUICK_RANGE_SELECT_GEOM::get_next");
8693 for (;;)
8695 int result;
8696 if (last_range)
8698 // Already read through key
8699 result= file->index_next_same(record, last_range->min_key,
8700 last_range->min_length);
8701 if (result != HA_ERR_END_OF_FILE)
8702 DBUG_RETURN(result);
8705 uint count= ranges.elements - (cur_range - (QUICK_RANGE**) ranges.buffer);
8706 if (count == 0)
8708 /* Ranges have already been used up before. None is left for read. */
8709 last_range= 0;
8710 DBUG_RETURN(HA_ERR_END_OF_FILE);
8712 last_range= *(cur_range++);
8714 result= file->index_read_map(record, last_range->min_key,
8715 last_range->min_keypart_map,
8716 (ha_rkey_function)(last_range->flag ^
8717 GEOM_FLAG));
8718 if (result != HA_ERR_KEY_NOT_FOUND && result != HA_ERR_END_OF_FILE)
8719 DBUG_RETURN(result);
8720 last_range= 0; // Not found, to next range
8726 Check if current row will be retrieved by this QUICK_RANGE_SELECT
8728 NOTES
8729 It is assumed that currently a scan is being done on another index
8730 which reads all necessary parts of the index that is scanned by this
8731 quick select.
8732 The implementation does a binary search on sorted array of disjoint
8733 ranges, without taking size of range into account.
8735 This function is used to filter out clustered PK scan rows in
8736 index_merge quick select.
8738 RETURN
8739 TRUE if current row will be retrieved by this quick select
8740 FALSE if not
8743 bool QUICK_RANGE_SELECT::row_in_ranges()
8745 QUICK_RANGE *res;
8746 uint min= 0;
8747 uint max= ranges.elements - 1;
8748 uint mid= (max + min)/2;
8750 while (min != max)
8752 if (cmp_next(*(QUICK_RANGE**)dynamic_array_ptr(&ranges, mid)))
8754 /* current row value > mid->max */
8755 min= mid + 1;
8757 else
8758 max= mid;
8759 mid= (min + max) / 2;
8761 res= *(QUICK_RANGE**)dynamic_array_ptr(&ranges, mid);
8762 return (!cmp_next(res) && !cmp_prev(res));
8766 This is a hack: we inherit from QUICK_RANGE_SELECT so that we can use the
8767 get_next() interface, but we have to hold a pointer to the original
8768 QUICK_RANGE_SELECT because its data are used all over the place. What
8769 should be done is to factor out the data that is needed into a base
8770 class (QUICK_SELECT), and then have two subclasses (_ASC and _DESC)
8771 which handle the ranges and implement the get_next() function. But
8772 for now, this seems to work right at least.
8775 QUICK_SELECT_DESC::QUICK_SELECT_DESC(QUICK_RANGE_SELECT *q,
8776 uint used_key_parts_arg)
8777 :QUICK_RANGE_SELECT(*q), rev_it(rev_ranges),
8778 used_key_parts (used_key_parts_arg)
8780 QUICK_RANGE *r;
8782 Use default MRR implementation for reverse scans. No table engine
8783 currently can do an MRR scan with output in reverse index order.
8785 multi_range_length= 0;
8786 multi_range= NULL;
8787 multi_range_buff= NULL;
8789 QUICK_RANGE **pr= (QUICK_RANGE**)ranges.buffer;
8790 QUICK_RANGE **end_range= pr + ranges.elements;
8791 for (; pr!=end_range; pr++)
8792 rev_ranges.push_front(*pr);
8794 /* Remove EQ_RANGE flag for keys that are not using the full key */
8795 for (r = rev_it++; r; r = rev_it++)
8797 if ((r->flag & EQ_RANGE) &&
8798 head->key_info[index].key_length != r->max_length)
8799 r->flag&= ~EQ_RANGE;
8801 rev_it.rewind();
8802 q->dont_free=1; // Don't free shared mem
8803 delete q;
8807 int QUICK_SELECT_DESC::get_next()
8809 DBUG_ENTER("QUICK_SELECT_DESC::get_next");
8811 /* The max key is handled as follows:
8812 * - if there is NO_MAX_RANGE, start at the end and move backwards
8813 * - if it is an EQ_RANGE, which means that max key covers the entire
8814 * key, go directly to the key and read through it (sorting backwards is
8815 * same as sorting forwards)
8816 * - if it is NEAR_MAX, go to the key or next, step back once, and
8817 * move backwards
8818 * - otherwise (not NEAR_MAX == include the key), go after the key,
8819 * step back once, and move backwards
8822 for (;;)
8824 int result;
8825 if (last_range)
8826 { // Already read through key
8827 result = ((last_range->flag & EQ_RANGE &&
8828 used_key_parts <= head->key_info[index].key_parts) ?
8829 file->index_next_same(record, last_range->min_key,
8830 last_range->min_length) :
8831 file->index_prev(record));
8832 if (!result)
8834 if (cmp_prev(*rev_it.ref()) == 0)
8835 DBUG_RETURN(0);
8837 else if (result != HA_ERR_END_OF_FILE)
8838 DBUG_RETURN(result);
8841 if (!(last_range= rev_it++))
8842 DBUG_RETURN(HA_ERR_END_OF_FILE); // All ranges used
8844 if (last_range->flag & NO_MAX_RANGE) // Read last record
8846 int local_error;
8847 if ((local_error=file->index_last(record)))
8848 DBUG_RETURN(local_error); // Empty table
8849 if (cmp_prev(last_range) == 0)
8850 DBUG_RETURN(0);
8851 last_range= 0; // No match; go to next range
8852 continue;
8855 if (last_range->flag & EQ_RANGE &&
8856 used_key_parts <= head->key_info[index].key_parts)
8859 result = file->index_read_map(record, last_range->max_key,
8860 last_range->max_keypart_map,
8861 HA_READ_KEY_EXACT);
8863 else
8865 DBUG_ASSERT(last_range->flag & NEAR_MAX ||
8866 (last_range->flag & EQ_RANGE &&
8867 used_key_parts > head->key_info[index].key_parts) ||
8868 range_reads_after_key(last_range));
8869 result=file->index_read_map(record, last_range->max_key,
8870 last_range->max_keypart_map,
8871 ((last_range->flag & NEAR_MAX) ?
8872 HA_READ_BEFORE_KEY :
8873 HA_READ_PREFIX_LAST_OR_PREV));
8875 if (result)
8877 if (result != HA_ERR_KEY_NOT_FOUND && result != HA_ERR_END_OF_FILE)
8878 DBUG_RETURN(result);
8879 last_range= 0; // Not found, to next range
8880 continue;
8882 if (cmp_prev(last_range) == 0)
8884 if (last_range->flag == (UNIQUE_RANGE | EQ_RANGE))
8885 last_range= 0; // Stop searching
8886 DBUG_RETURN(0); // Found key is in range
8888 last_range= 0; // To next range
8894 Compare if found key is over max-value
8895 Returns 0 if key <= range->max_key
8898 int QUICK_RANGE_SELECT::cmp_next(QUICK_RANGE *range_arg)
8900 if (range_arg->flag & NO_MAX_RANGE)
8901 return 0; /* key can't be to large */
8903 KEY_PART *key_part=key_parts;
8904 uint store_length;
8906 for (uchar *key=range_arg->max_key, *end=key+range_arg->max_length;
8907 key < end;
8908 key+= store_length, key_part++)
8910 int cmp;
8911 store_length= key_part->store_length;
8912 if (key_part->null_bit)
8914 if (*key)
8916 if (!key_part->field->is_null())
8917 return 1;
8918 continue;
8920 else if (key_part->field->is_null())
8921 return 0;
8922 key++; // Skip null byte
8923 store_length--;
8925 if ((cmp=key_part->field->key_cmp(key, key_part->length)) < 0)
8926 return 0;
8927 if (cmp > 0)
8928 return 1;
8930 return (range_arg->flag & NEAR_MAX) ? 1 : 0; // Exact match
8935 Returns 0 if found key is inside range (found key >= range->min_key).
8938 int QUICK_RANGE_SELECT::cmp_prev(QUICK_RANGE *range_arg)
8940 int cmp;
8941 if (range_arg->flag & NO_MIN_RANGE)
8942 return 0; /* key can't be to small */
8944 cmp= key_cmp(key_part_info, range_arg->min_key,
8945 range_arg->min_length);
8946 if (cmp > 0 || (cmp == 0 && !(range_arg->flag & NEAR_MIN)))
8947 return 0;
8948 return 1; // outside of range
8953 * TRUE if this range will require using HA_READ_AFTER_KEY
8954 See comment in get_next() about this
8957 bool QUICK_SELECT_DESC::range_reads_after_key(QUICK_RANGE *range_arg)
8959 return ((range_arg->flag & (NO_MAX_RANGE | NEAR_MAX)) ||
8960 !(range_arg->flag & EQ_RANGE) ||
8961 head->key_info[index].key_length != range_arg->max_length) ? 1 : 0;
8965 void QUICK_RANGE_SELECT::add_info_string(String *str)
8967 KEY *key_info= head->key_info + index;
8968 str->append(key_info->name);
8971 void QUICK_INDEX_MERGE_SELECT::add_info_string(String *str)
8973 QUICK_RANGE_SELECT *quick;
8974 bool first= TRUE;
8975 List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
8976 str->append(STRING_WITH_LEN("sort_union("));
8977 while ((quick= it++))
8979 if (!first)
8980 str->append(',');
8981 else
8982 first= FALSE;
8983 quick->add_info_string(str);
8985 if (pk_quick_select)
8987 str->append(',');
8988 pk_quick_select->add_info_string(str);
8990 str->append(')');
8993 void QUICK_ROR_INTERSECT_SELECT::add_info_string(String *str)
8995 bool first= TRUE;
8996 QUICK_RANGE_SELECT *quick;
8997 List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
8998 str->append(STRING_WITH_LEN("intersect("));
8999 while ((quick= it++))
9001 KEY *key_info= head->key_info + quick->index;
9002 if (!first)
9003 str->append(',');
9004 else
9005 first= FALSE;
9006 str->append(key_info->name);
9008 if (cpk_quick)
9010 KEY *key_info= head->key_info + cpk_quick->index;
9011 str->append(',');
9012 str->append(key_info->name);
9014 str->append(')');
9017 void QUICK_ROR_UNION_SELECT::add_info_string(String *str)
9019 bool first= TRUE;
9020 QUICK_SELECT_I *quick;
9021 List_iterator_fast<QUICK_SELECT_I> it(quick_selects);
9022 str->append(STRING_WITH_LEN("union("));
9023 while ((quick= it++))
9025 if (!first)
9026 str->append(',');
9027 else
9028 first= FALSE;
9029 quick->add_info_string(str);
9031 str->append(')');
9035 void QUICK_RANGE_SELECT::add_keys_and_lengths(String *key_names,
9036 String *used_lengths)
9038 char buf[64];
9039 uint length;
9040 KEY *key_info= head->key_info + index;
9041 key_names->append(key_info->name);
9042 length= longlong2str(max_used_key_length, buf, 10) - buf;
9043 used_lengths->append(buf, length);
9046 void QUICK_INDEX_MERGE_SELECT::add_keys_and_lengths(String *key_names,
9047 String *used_lengths)
9049 char buf[64];
9050 uint length;
9051 bool first= TRUE;
9052 QUICK_RANGE_SELECT *quick;
9054 List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
9055 while ((quick= it++))
9057 if (first)
9058 first= FALSE;
9059 else
9061 key_names->append(',');
9062 used_lengths->append(',');
9065 KEY *key_info= head->key_info + quick->index;
9066 key_names->append(key_info->name);
9067 length= longlong2str(quick->max_used_key_length, buf, 10) - buf;
9068 used_lengths->append(buf, length);
9070 if (pk_quick_select)
9072 KEY *key_info= head->key_info + pk_quick_select->index;
9073 key_names->append(',');
9074 key_names->append(key_info->name);
9075 length= longlong2str(pk_quick_select->max_used_key_length, buf, 10) - buf;
9076 used_lengths->append(',');
9077 used_lengths->append(buf, length);
9081 void QUICK_ROR_INTERSECT_SELECT::add_keys_and_lengths(String *key_names,
9082 String *used_lengths)
9084 char buf[64];
9085 uint length;
9086 bool first= TRUE;
9087 QUICK_RANGE_SELECT *quick;
9088 List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
9089 while ((quick= it++))
9091 KEY *key_info= head->key_info + quick->index;
9092 if (first)
9093 first= FALSE;
9094 else
9096 key_names->append(',');
9097 used_lengths->append(',');
9099 key_names->append(key_info->name);
9100 length= longlong2str(quick->max_used_key_length, buf, 10) - buf;
9101 used_lengths->append(buf, length);
9104 if (cpk_quick)
9106 KEY *key_info= head->key_info + cpk_quick->index;
9107 key_names->append(',');
9108 key_names->append(key_info->name);
9109 length= longlong2str(cpk_quick->max_used_key_length, buf, 10) - buf;
9110 used_lengths->append(',');
9111 used_lengths->append(buf, length);
9115 void QUICK_ROR_UNION_SELECT::add_keys_and_lengths(String *key_names,
9116 String *used_lengths)
9118 bool first= TRUE;
9119 QUICK_SELECT_I *quick;
9120 List_iterator_fast<QUICK_SELECT_I> it(quick_selects);
9121 while ((quick= it++))
9123 if (first)
9124 first= FALSE;
9125 else
9127 used_lengths->append(',');
9128 key_names->append(',');
9130 quick->add_keys_and_lengths(key_names, used_lengths);
9135 /*******************************************************************************
9136 * Implementation of QUICK_GROUP_MIN_MAX_SELECT
9137 *******************************************************************************/
9139 static inline uint get_field_keypart(KEY *index, Field *field);
9140 static inline SEL_ARG * get_index_range_tree(uint index, SEL_TREE* range_tree,
9141 PARAM *param, uint *param_idx);
9142 static bool get_constant_key_infix(KEY *index_info, SEL_ARG *index_range_tree,
9143 KEY_PART_INFO *first_non_group_part,
9144 KEY_PART_INFO *min_max_arg_part,
9145 KEY_PART_INFO *last_part, THD *thd,
9146 uchar *key_infix, uint *key_infix_len,
9147 KEY_PART_INFO **first_non_infix_part);
9148 static bool
9149 check_group_min_max_predicates(COND *cond, Item_field *min_max_arg_item,
9150 Field::imagetype image_type);
9152 static void
9153 cost_group_min_max(TABLE* table, KEY *index_info, uint used_key_parts,
9154 uint group_key_parts, SEL_TREE *range_tree,
9155 SEL_ARG *index_tree, ha_rows quick_prefix_records,
9156 bool have_min, bool have_max,
9157 double *read_cost, ha_rows *records);
9161 Test if this access method is applicable to a GROUP query with MIN/MAX
9162 functions, and if so, construct a new TRP object.
9164 SYNOPSIS
9165 get_best_group_min_max()
9166 param Parameter from test_quick_select
9167 sel_tree Range tree generated by get_mm_tree
9169 DESCRIPTION
9170 Test whether a query can be computed via a QUICK_GROUP_MIN_MAX_SELECT.
9171 Queries computable via a QUICK_GROUP_MIN_MAX_SELECT must satisfy the
9172 following conditions:
9173 A) Table T has at least one compound index I of the form:
9174 I = <A_1, ...,A_k, [B_1,..., B_m], C, [D_1,...,D_n]>
9175 B) Query conditions:
9176 B0. Q is over a single table T.
9177 B1. The attributes referenced by Q are a subset of the attributes of I.
9178 B2. All attributes QA in Q can be divided into 3 overlapping groups:
9179 - SA = {S_1, ..., S_l, [C]} - from the SELECT clause, where C is
9180 referenced by any number of MIN and/or MAX functions if present.
9181 - WA = {W_1, ..., W_p} - from the WHERE clause
9182 - GA = <G_1, ..., G_k> - from the GROUP BY clause (if any)
9183 = SA - if Q is a DISTINCT query (based on the
9184 equivalence of DISTINCT and GROUP queries.
9185 - NGA = QA - (GA union C) = {NG_1, ..., NG_m} - the ones not in
9186 GROUP BY and not referenced by MIN/MAX functions.
9187 with the following properties specified below.
9188 B3. If Q has a GROUP BY WITH ROLLUP clause the access method is not
9189 applicable.
9191 SA1. There is at most one attribute in SA referenced by any number of
9192 MIN and/or MAX functions which, which if present, is denoted as C.
9193 SA2. The position of the C attribute in the index is after the last A_k.
9194 SA3. The attribute C can be referenced in the WHERE clause only in
9195 predicates of the forms:
9196 - (C {< | <= | > | >= | =} const)
9197 - (const {< | <= | > | >= | =} C)
9198 - (C between const_i and const_j)
9199 - C IS NULL
9200 - C IS NOT NULL
9201 - C != const
9202 SA4. If Q has a GROUP BY clause, there are no other aggregate functions
9203 except MIN and MAX. For queries with DISTINCT, aggregate functions
9204 are allowed.
9205 SA5. The select list in DISTINCT queries should not contain expressions.
9206 GA1. If Q has a GROUP BY clause, then GA is a prefix of I. That is, if
9207 G_i = A_j => i = j.
9208 GA2. If Q has a DISTINCT clause, then there is a permutation of SA that
9209 forms a prefix of I. This permutation is used as the GROUP clause
9210 when the DISTINCT query is converted to a GROUP query.
9211 GA3. The attributes in GA may participate in arbitrary predicates, divided
9212 into two groups:
9213 - RNG(G_1,...,G_q ; where q <= k) is a range condition over the
9214 attributes of a prefix of GA
9215 - PA(G_i1,...G_iq) is an arbitrary predicate over an arbitrary subset
9216 of GA. Since P is applied to only GROUP attributes it filters some
9217 groups, and thus can be applied after the grouping.
9218 GA4. There are no expressions among G_i, just direct column references.
9219 NGA1.If in the index I there is a gap between the last GROUP attribute G_k,
9220 and the MIN/MAX attribute C, then NGA must consist of exactly the
9221 index attributes that constitute the gap. As a result there is a
9222 permutation of NGA, BA=<B_1,...,B_m>, that coincides with the gap
9223 in the index.
9224 NGA2.If BA <> {}, then the WHERE clause must contain a conjunction EQ of
9225 equality conditions for all NG_i of the form (NG_i = const) or
9226 (const = NG_i), such that each NG_i is referenced in exactly one
9227 conjunct. Informally, the predicates provide constants to fill the
9228 gap in the index.
9229 NGA3.If BA <> {}, there can only be one range. TODO: This is a code
9230 limitation and is not strictly needed. See BUG#15947433
9231 WA1. There are no other attributes in the WHERE clause except the ones
9232 referenced in predicates RNG, PA, PC, EQ defined above. Therefore
9233 WA is subset of (GA union NGA union C) for GA,NGA,C that pass the
9234 above tests. By transitivity then it also follows that each WA_i
9235 participates in the index I (if this was already tested for GA, NGA
9236 and C).
9238 C) Overall query form:
9239 SELECT EXPR([A_1,...,A_k], [B_1,...,B_m], [MIN(C)], [MAX(C)])
9240 FROM T
9241 WHERE [RNG(A_1,...,A_p ; where p <= k)]
9242 [AND EQ(B_1,...,B_m)]
9243 [AND PC(C)]
9244 [AND PA(A_i1,...,A_iq)]
9245 GROUP BY A_1,...,A_k
9246 [HAVING PH(A_1, ..., B_1,..., C)]
9247 where EXPR(...) is an arbitrary expression over some or all SELECT fields,
9249 SELECT DISTINCT A_i1,...,A_ik
9250 FROM T
9251 WHERE [RNG(A_1,...,A_p ; where p <= k)]
9252 [AND PA(A_i1,...,A_iq)];
9254 NOTES
9255 If the current query satisfies the conditions above, and if
9256 (mem_root! = NULL), then the function constructs and returns a new TRP
9257 object, that is later used to construct a new QUICK_GROUP_MIN_MAX_SELECT.
9258 If (mem_root == NULL), then the function only tests whether the current
9259 query satisfies the conditions above, and, if so, sets
9260 is_applicable = TRUE.
9262 Queries with DISTINCT for which index access can be used are transformed
9263 into equivalent group-by queries of the form:
9265 SELECT A_1,...,A_k FROM T
9266 WHERE [RNG(A_1,...,A_p ; where p <= k)]
9267 [AND PA(A_i1,...,A_iq)]
9268 GROUP BY A_1,...,A_k;
9270 The group-by list is a permutation of the select attributes, according
9271 to their order in the index.
9273 TODO
9274 - What happens if the query groups by the MIN/MAX field, and there is no
9275 other field as in: "select min(a) from t1 group by a" ?
9276 - We assume that the general correctness of the GROUP-BY query was checked
9277 before this point. Is this correct, or do we have to check it completely?
9278 - Lift the limitation in condition (B3), that is, make this access method
9279 applicable to ROLLUP queries.
9281 RETURN
9282 If mem_root != NULL
9283 - valid TRP_GROUP_MIN_MAX object if this QUICK class can be used for
9284 the query
9285 - NULL o/w.
9286 If mem_root == NULL
9287 - NULL
9290 static TRP_GROUP_MIN_MAX *
9291 get_best_group_min_max(PARAM *param, SEL_TREE *tree)
9293 THD *thd= param->thd;
9294 JOIN *join= thd->lex->current_select->join;
9295 TABLE *table= param->table;
9296 bool have_min= FALSE; /* TRUE if there is a MIN function. */
9297 bool have_max= FALSE; /* TRUE if there is a MAX function. */
9298 Item_field *min_max_arg_item= NULL; // The argument of all MIN/MAX functions
9299 KEY_PART_INFO *min_max_arg_part= NULL; /* The corresponding keypart. */
9300 uint group_prefix_len= 0; /* Length (in bytes) of the key prefix. */
9301 KEY *index_info= NULL; /* The index chosen for data access. */
9302 uint index= 0; /* The id of the chosen index. */
9303 uint group_key_parts= 0; // Number of index key parts in the group prefix.
9304 uint used_key_parts= 0; /* Number of index key parts used for access. */
9305 uchar key_infix[MAX_KEY_LENGTH]; /* Constants from equality predicates.*/
9306 uint key_infix_len= 0; /* Length of key_infix. */
9307 TRP_GROUP_MIN_MAX *read_plan= NULL; /* The eventually constructed TRP. */
9308 uint key_part_nr;
9309 ORDER *tmp_group;
9310 Item *item;
9311 Item_field *item_field;
9312 DBUG_ENTER("get_best_group_min_max");
9314 /* Perform few 'cheap' tests whether this access method is applicable. */
9315 if (!join)
9316 DBUG_RETURN(NULL); /* This is not a select statement. */
9317 if ((join->tables != 1) || /* The query must reference one table. */
9318 ((!join->group_list) && /* Neither GROUP BY nor a DISTINCT query. */
9319 (!join->select_distinct)) ||
9320 (join->select_lex->olap == ROLLUP_TYPE)) /* Check (B3) for ROLLUP */
9321 DBUG_RETURN(NULL);
9322 if (table->s->keys == 0) /* There are no indexes to use. */
9323 DBUG_RETURN(NULL);
9325 /* Analyze the query in more detail. */
9326 List_iterator<Item> select_items_it(join->fields_list);
9328 /* Check (SA1,SA4) and store the only MIN/MAX argument - the C attribute.*/
9329 if (join->make_sum_func_list(join->all_fields, join->fields_list, 1))
9330 DBUG_RETURN(NULL);
9331 if (join->sum_funcs[0])
9333 Item_sum *min_max_item;
9334 Item_sum **func_ptr= join->sum_funcs;
9335 while ((min_max_item= *(func_ptr++)))
9337 if (min_max_item->sum_func() == Item_sum::MIN_FUNC)
9338 have_min= TRUE;
9339 else if (min_max_item->sum_func() == Item_sum::MAX_FUNC)
9340 have_max= TRUE;
9341 else
9342 DBUG_RETURN(NULL);
9344 /* The argument of MIN/MAX. */
9345 Item *expr= min_max_item->get_arg(0)->real_item();
9346 if (expr->type() == Item::FIELD_ITEM) /* Is it an attribute? */
9348 if (! min_max_arg_item)
9349 min_max_arg_item= (Item_field*) expr;
9350 else if (! min_max_arg_item->eq(expr, 1))
9351 DBUG_RETURN(NULL);
9353 else
9354 DBUG_RETURN(NULL);
9358 /* Check (SA5). */
9359 if (join->select_distinct)
9361 while ((item= select_items_it++))
9363 if (item->type() != Item::FIELD_ITEM)
9364 DBUG_RETURN(NULL);
9368 /* Check (GA4) - that there are no expressions among the group attributes. */
9369 for (tmp_group= join->group_list; tmp_group; tmp_group= tmp_group->next)
9371 if ((*tmp_group->item)->type() != Item::FIELD_ITEM)
9372 DBUG_RETURN(NULL);
9376 Check that table has at least one compound index such that the conditions
9377 (GA1,GA2) are all TRUE. If there is more than one such index, select the
9378 first one. Here we set the variables: group_prefix_len and index_info.
9380 KEY *cur_index_info= table->key_info;
9381 KEY *cur_index_info_end= cur_index_info + table->s->keys;
9382 /* Cost-related variables for the best index so far. */
9383 double best_read_cost= DBL_MAX;
9384 ha_rows best_records= 0;
9385 SEL_ARG *best_index_tree= NULL;
9386 ha_rows best_quick_prefix_records= 0;
9387 uint best_param_idx= 0;
9389 const uint pk= param->table->s->primary_key;
9390 SEL_ARG *cur_index_tree= NULL;
9391 ha_rows cur_quick_prefix_records= 0;
9392 uint cur_param_idx=MAX_KEY;
9394 for (uint cur_index= 0 ; cur_index_info != cur_index_info_end ;
9395 cur_index_info++, cur_index++)
9397 KEY_PART_INFO *cur_part;
9398 KEY_PART_INFO *end_part; /* Last part for loops. */
9399 /* Last index part. */
9400 KEY_PART_INFO *last_part;
9401 KEY_PART_INFO *first_non_group_part;
9402 KEY_PART_INFO *first_non_infix_part;
9403 uint key_infix_parts;
9404 uint cur_group_key_parts= 0;
9405 uint cur_group_prefix_len= 0;
9406 double cur_read_cost;
9407 ha_rows cur_records;
9408 key_map used_key_parts_map;
9409 uint cur_key_infix_len= 0;
9410 uchar cur_key_infix[MAX_KEY_LENGTH];
9411 uint cur_used_key_parts;
9413 /* Check (B1) - if current index is covering. */
9414 if (!table->covering_keys.is_set(cur_index))
9415 goto next_index;
9418 If the current storage manager is such that it appends the primary key to
9419 each index, then the above condition is insufficient to check if the
9420 index is covering. In such cases it may happen that some fields are
9421 covered by the PK index, but not by the current index. Since we can't
9422 use the concatenation of both indexes for index lookup, such an index
9423 does not qualify as covering in our case. If this is the case, below
9424 we check that all query fields are indeed covered by 'cur_index'.
9426 if (pk < MAX_KEY && cur_index != pk &&
9427 (table->file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX))
9429 /* For each table field */
9430 for (uint i= 0; i < table->s->fields; i++)
9432 Field *cur_field= table->field[i];
9434 If the field is used in the current query ensure that it's
9435 part of 'cur_index'
9437 if (bitmap_is_set(table->read_set, cur_field->field_index) &&
9438 !cur_field->part_of_key_not_clustered.is_set(cur_index))
9439 goto next_index; // Field was not part of key
9444 Check (GA1) for GROUP BY queries.
9446 if (join->group_list)
9448 cur_part= cur_index_info->key_part;
9449 end_part= cur_part + cur_index_info->key_parts;
9450 /* Iterate in parallel over the GROUP list and the index parts. */
9451 for (tmp_group= join->group_list; tmp_group && (cur_part != end_part);
9452 tmp_group= tmp_group->next, cur_part++)
9455 TODO:
9456 tmp_group::item is an array of Item, is it OK to consider only the
9457 first Item? If so, then why? What is the array for?
9459 /* Above we already checked that all group items are fields. */
9460 DBUG_ASSERT((*tmp_group->item)->type() == Item::FIELD_ITEM);
9461 Item_field *group_field= (Item_field *) (*tmp_group->item);
9462 if (group_field->field->eq(cur_part->field))
9464 cur_group_prefix_len+= cur_part->store_length;
9465 ++cur_group_key_parts;
9467 else
9468 goto next_index;
9472 Check (GA2) if this is a DISTINCT query.
9473 If GA2, then Store a new ORDER object in group_fields_array at the
9474 position of the key part of item_field->field. Thus we get the ORDER
9475 objects for each field ordered as the corresponding key parts.
9476 Later group_fields_array of ORDER objects is used to convert the query
9477 to a GROUP query.
9479 else if (join->select_distinct)
9481 select_items_it.rewind();
9482 used_key_parts_map.clear_all();
9483 uint max_key_part= 0;
9484 while ((item= select_items_it++))
9486 item_field= (Item_field*) item; /* (SA5) already checked above. */
9487 /* Find the order of the key part in the index. */
9488 key_part_nr= get_field_keypart(cur_index_info, item_field->field);
9490 Check if this attribute was already present in the select list.
9491 If it was present, then its corresponding key part was alredy used.
9493 if (used_key_parts_map.is_set(key_part_nr))
9494 continue;
9495 if (key_part_nr < 1 || key_part_nr > join->fields_list.elements)
9496 goto next_index;
9497 cur_part= cur_index_info->key_part + key_part_nr - 1;
9498 cur_group_prefix_len+= cur_part->store_length;
9499 used_key_parts_map.set_bit(key_part_nr);
9500 ++cur_group_key_parts;
9501 max_key_part= max(max_key_part,key_part_nr);
9504 Check that used key parts forms a prefix of the index.
9505 To check this we compare bits in all_parts and cur_parts.
9506 all_parts have all bits set from 0 to (max_key_part-1).
9507 cur_parts have bits set for only used keyparts.
9509 ulonglong all_parts, cur_parts;
9510 all_parts= (1<<max_key_part) - 1;
9511 cur_parts= used_key_parts_map.to_ulonglong() >> 1;
9512 if (all_parts != cur_parts)
9513 goto next_index;
9515 else
9517 DBUG_ASSERT(FALSE);
9520 /* Check (SA2). */
9521 if (min_max_arg_item)
9523 key_part_nr= get_field_keypart(cur_index_info, min_max_arg_item->field);
9524 if (key_part_nr <= cur_group_key_parts)
9525 goto next_index;
9526 min_max_arg_part= cur_index_info->key_part + key_part_nr - 1;
9530 Check (NGA1, NGA2) and extract a sequence of constants to be used as part
9531 of all search keys.
9535 If there is MIN/MAX, each keypart between the last group part and the
9536 MIN/MAX part must participate in one equality with constants, and all
9537 keyparts after the MIN/MAX part must not be referenced in the query.
9539 If there is no MIN/MAX, the keyparts after the last group part can be
9540 referenced only in equalities with constants, and the referenced keyparts
9541 must form a sequence without any gaps that starts immediately after the
9542 last group keypart.
9544 last_part= cur_index_info->key_part + cur_index_info->key_parts;
9545 first_non_group_part= (cur_group_key_parts < cur_index_info->key_parts) ?
9546 cur_index_info->key_part + cur_group_key_parts :
9547 NULL;
9548 first_non_infix_part= min_max_arg_part ?
9549 (min_max_arg_part < last_part) ?
9550 min_max_arg_part :
9551 NULL :
9552 NULL;
9553 if (first_non_group_part &&
9554 (!min_max_arg_part || (min_max_arg_part - first_non_group_part > 0)))
9556 if (tree)
9558 uint dummy;
9559 SEL_ARG *index_range_tree= get_index_range_tree(cur_index, tree, param,
9560 &dummy);
9561 if (!get_constant_key_infix(cur_index_info, index_range_tree,
9562 first_non_group_part, min_max_arg_part,
9563 last_part, thd, cur_key_infix,
9564 &cur_key_infix_len,
9565 &first_non_infix_part))
9566 goto next_index;
9568 else if (min_max_arg_part &&
9569 (min_max_arg_part - first_non_group_part > 0))
9572 There is a gap but no range tree, thus no predicates at all for the
9573 non-group keyparts.
9575 goto next_index;
9577 else if (first_non_group_part && join->conds)
9580 If there is no MIN/MAX function in the query, but some index
9581 key part is referenced in the WHERE clause, then this index
9582 cannot be used because the WHERE condition over the keypart's
9583 field cannot be 'pushed' to the index (because there is no
9584 range 'tree'), and the WHERE clause must be evaluated before
9585 GROUP BY/DISTINCT.
9588 Store the first and last keyparts that need to be analyzed
9589 into one array that can be passed as parameter.
9591 KEY_PART_INFO *key_part_range[2];
9592 key_part_range[0]= first_non_group_part;
9593 key_part_range[1]= last_part;
9595 /* Check if cur_part is referenced in the WHERE clause. */
9596 if (join->conds->walk(&Item::find_item_in_field_list_processor, 0,
9597 (uchar*) key_part_range))
9598 goto next_index;
9603 Test (WA1) partially - that no other keypart after the last infix part is
9604 referenced in the query.
9606 if (first_non_infix_part)
9608 cur_part= first_non_infix_part +
9609 (min_max_arg_part && (min_max_arg_part < last_part));
9610 for (; cur_part != last_part; cur_part++)
9612 if (bitmap_is_set(table->read_set, cur_part->field->field_index))
9613 goto next_index;
9617 /* If we got to this point, cur_index_info passes the test. */
9618 key_infix_parts= cur_key_infix_len ? (uint)
9619 (first_non_infix_part - first_non_group_part) : 0;
9620 cur_used_key_parts= cur_group_key_parts + key_infix_parts;
9622 /* Compute the cost of using this index. */
9623 if (tree)
9625 /* Find the SEL_ARG sub-tree that corresponds to the chosen index. */
9626 cur_index_tree= get_index_range_tree(cur_index, tree, param,
9627 &cur_param_idx);
9628 /* Check if this range tree can be used for prefix retrieval. */
9629 cur_quick_prefix_records= check_quick_select(param, cur_param_idx,
9630 cur_index_tree, TRUE);
9632 cost_group_min_max(table, cur_index_info, cur_used_key_parts,
9633 cur_group_key_parts, tree, cur_index_tree,
9634 cur_quick_prefix_records, have_min, have_max,
9635 &cur_read_cost, &cur_records);
9637 If cur_read_cost is lower than best_read_cost use cur_index.
9638 Do not compare doubles directly because they may have different
9639 representations (64 vs. 80 bits).
9641 if (cur_read_cost < best_read_cost - (DBL_EPSILON * cur_read_cost))
9643 index_info= cur_index_info;
9644 index= cur_index;
9645 best_read_cost= cur_read_cost;
9646 best_records= cur_records;
9647 best_index_tree= cur_index_tree;
9648 best_quick_prefix_records= cur_quick_prefix_records;
9649 best_param_idx= cur_param_idx;
9650 group_key_parts= cur_group_key_parts;
9651 group_prefix_len= cur_group_prefix_len;
9652 key_infix_len= cur_key_infix_len;
9653 if (key_infix_len)
9654 memcpy (key_infix, cur_key_infix, sizeof (key_infix));
9655 used_key_parts= cur_used_key_parts;
9658 next_index:;
9660 if (!index_info) /* No usable index found. */
9661 DBUG_RETURN(NULL);
9663 /* Check (SA3) for the where clause. */
9664 if (join->conds && min_max_arg_item &&
9665 !check_group_min_max_predicates(join->conds, min_max_arg_item,
9666 (index_info->flags & HA_SPATIAL) ?
9667 Field::itMBR : Field::itRAW))
9668 DBUG_RETURN(NULL);
9670 /* The query passes all tests, so construct a new TRP object. */
9671 read_plan= new (param->mem_root)
9672 TRP_GROUP_MIN_MAX(have_min, have_max, min_max_arg_part,
9673 group_prefix_len, used_key_parts,
9674 group_key_parts, index_info, index,
9675 key_infix_len,
9676 (key_infix_len > 0) ? key_infix : NULL,
9677 tree, best_index_tree, best_param_idx,
9678 best_quick_prefix_records);
9679 if (read_plan)
9681 if (tree && read_plan->quick_prefix_records == 0)
9682 DBUG_RETURN(NULL);
9684 read_plan->read_cost= best_read_cost;
9685 read_plan->records= best_records;
9687 DBUG_PRINT("info",
9688 ("Returning group min/max plan: cost: %g, records: %lu",
9689 read_plan->read_cost, (ulong) read_plan->records));
9692 DBUG_RETURN(read_plan);
9697 Check that the MIN/MAX attribute participates only in range predicates
9698 with constants.
9700 SYNOPSIS
9701 check_group_min_max_predicates()
9702 cond tree (or subtree) describing all or part of the WHERE
9703 clause being analyzed
9704 min_max_arg_item the field referenced by the MIN/MAX function(s)
9705 min_max_arg_part the keypart of the MIN/MAX argument if any
9707 DESCRIPTION
9708 The function walks recursively over the cond tree representing a WHERE
9709 clause, and checks condition (SA3) - if a field is referenced by a MIN/MAX
9710 aggregate function, it is referenced only by one of the following
9711 predicates: {=, !=, <, <=, >, >=, between, is null, is not null}.
9713 RETURN
9714 TRUE if cond passes the test
9715 FALSE o/w
9718 static bool
9719 check_group_min_max_predicates(COND *cond, Item_field *min_max_arg_item,
9720 Field::imagetype image_type)
9722 DBUG_ENTER("check_group_min_max_predicates");
9723 DBUG_ASSERT(cond && min_max_arg_item);
9725 cond= cond->real_item();
9726 Item::Type cond_type= cond->type();
9727 if (cond_type == Item::COND_ITEM) /* 'AND' or 'OR' */
9729 DBUG_PRINT("info", ("Analyzing: %s", ((Item_func*) cond)->func_name()));
9730 List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
9731 Item *and_or_arg;
9732 while ((and_or_arg= li++))
9734 if (!check_group_min_max_predicates(and_or_arg, min_max_arg_item,
9735 image_type))
9736 DBUG_RETURN(FALSE);
9738 DBUG_RETURN(TRUE);
9742 TODO:
9743 This is a very crude fix to handle sub-selects in the WHERE clause
9744 (Item_subselect objects). With the test below we rule out from the
9745 optimization all queries with subselects in the WHERE clause. What has to
9746 be done, is that here we should analyze whether the subselect references
9747 the MIN/MAX argument field, and disallow the optimization only if this is
9750 if (cond_type == Item::SUBSELECT_ITEM)
9751 DBUG_RETURN(FALSE);
9754 Condition of the form 'field' is equivalent to 'field <> 0' and thus
9755 satisfies the SA3 condition.
9757 if (cond_type == Item::FIELD_ITEM)
9759 DBUG_PRINT("info", ("Analyzing: %s", cond->full_name()));
9760 DBUG_RETURN(TRUE);
9763 /* We presume that at this point there are no other Items than functions. */
9764 DBUG_ASSERT(cond_type == Item::FUNC_ITEM);
9766 /* Test if cond references only group-by or non-group fields. */
9767 Item_func *pred= (Item_func*) cond;
9768 Item **arguments= pred->arguments();
9769 Item *cur_arg;
9770 DBUG_PRINT("info", ("Analyzing: %s", pred->func_name()));
9771 for (uint arg_idx= 0; arg_idx < pred->argument_count (); arg_idx++)
9773 cur_arg= arguments[arg_idx]->real_item();
9774 DBUG_PRINT("info", ("cur_arg: %s", cur_arg->full_name()));
9775 if (cur_arg->type() == Item::FIELD_ITEM)
9777 if (min_max_arg_item->eq(cur_arg, 1))
9780 If pred references the MIN/MAX argument, check whether pred is a range
9781 condition that compares the MIN/MAX argument with a constant.
9783 Item_func::Functype pred_type= pred->functype();
9784 if (pred_type != Item_func::EQUAL_FUNC &&
9785 pred_type != Item_func::LT_FUNC &&
9786 pred_type != Item_func::LE_FUNC &&
9787 pred_type != Item_func::GT_FUNC &&
9788 pred_type != Item_func::GE_FUNC &&
9789 pred_type != Item_func::BETWEEN &&
9790 pred_type != Item_func::ISNULL_FUNC &&
9791 pred_type != Item_func::ISNOTNULL_FUNC &&
9792 pred_type != Item_func::EQ_FUNC &&
9793 pred_type != Item_func::NE_FUNC)
9794 DBUG_RETURN(FALSE);
9796 /* Check that pred compares min_max_arg_item with a constant. */
9797 Item *args[3];
9798 bzero(args, 3 * sizeof(Item*));
9799 bool inv;
9800 /* Test if this is a comparison of a field and a constant. */
9801 if (!simple_pred(pred, args, &inv))
9802 DBUG_RETURN(FALSE);
9804 /* Check for compatible string comparisons - similar to get_mm_leaf. */
9805 if (args[0] && args[1] && !args[2] && // this is a binary function
9806 min_max_arg_item->result_type() == STRING_RESULT &&
9808 Don't use an index when comparing strings of different collations.
9810 ((args[1]->result_type() == STRING_RESULT &&
9811 image_type == Field::itRAW &&
9812 ((Field_str*) min_max_arg_item->field)->charset() !=
9813 pred->compare_collation())
9816 We can't always use indexes when comparing a string index to a
9817 number.
9819 (args[1]->result_type() != STRING_RESULT &&
9820 min_max_arg_item->field->cmp_type() != args[1]->result_type())))
9821 DBUG_RETURN(FALSE);
9824 else if (cur_arg->type() == Item::FUNC_ITEM)
9826 if (!check_group_min_max_predicates(cur_arg, min_max_arg_item,
9827 image_type))
9828 DBUG_RETURN(FALSE);
9830 else if (cur_arg->const_item())
9833 For predicates of the form "const OP expr" we also have to check 'expr'
9834 to make a decision.
9836 continue;
9838 else
9839 DBUG_RETURN(FALSE);
9842 DBUG_RETURN(TRUE);
9847 Get SEL_ARG tree, if any, for the keypart covering non grouping
9848 attribute (NGA) field 'nga_field'.
9850 This function enforces the NGA3 test: If 'keypart_tree' contains a
9851 condition for 'nga_field', there can only be one range. In the
9852 opposite case, this function returns with error and 'cur_range'
9853 should not be used.
9855 Note that the NGA1 and NGA2 requirements, like whether or not the
9856 range predicate for 'nga_field' is equality, is not tested by this
9857 function.
9859 @param[in] nga_field The NGA field we want the SEL_ARG tree for
9860 @param[in] keypart_tree Root node of the SEL_ARG* tree for the index
9861 @param[out] cur_range The SEL_ARG tree, if any, for the keypart
9862 covering field 'keypart_field'
9863 @retval true 'keypart_tree' contained a predicate for 'nga_field' but
9864 multiple ranges exists. 'cur_range' should not be used.
9865 @retval false otherwise
9868 static bool
9869 get_sel_arg_for_keypart(Field *nga_field,
9870 SEL_ARG *keypart_tree,
9871 SEL_ARG **cur_range)
9873 if(keypart_tree == NULL)
9874 return false;
9875 if(keypart_tree->field->eq(nga_field))
9878 Enforce NGA3: If a condition for nga_field has been found, only
9879 a single range is allowed.
9881 if (keypart_tree->prev || keypart_tree->next)
9882 return true; // There are multiple ranges
9884 *cur_range= keypart_tree;
9885 return false;
9888 SEL_ARG *found_tree= NULL;
9889 SEL_ARG *first_kp= keypart_tree->first();
9891 for (SEL_ARG *cur_kp= first_kp; cur_kp && !found_tree;
9892 cur_kp= cur_kp->next)
9894 if (cur_kp->next_key_part)
9896 if (get_sel_arg_for_keypart(nga_field,
9897 cur_kp->next_key_part,
9898 &found_tree))
9899 return true;
9903 Enforce NGA3: If a condition for nga_field has been found,only
9904 a single range is allowed.
9906 if (found_tree && first_kp->next)
9907 return true; // There are multiple ranges
9909 *cur_range= found_tree;
9910 return false;
9915 Extract a sequence of constants from a conjunction of equality predicates.
9917 SYNOPSIS
9918 get_constant_key_infix()
9919 index_info [in] Descriptor of the chosen index.
9920 index_range_tree [in] Range tree for the chosen index
9921 first_non_group_part [in] First index part after group attribute parts
9922 min_max_arg_part [in] The keypart of the MIN/MAX argument if any
9923 last_part [in] Last keypart of the index
9924 thd [in] Current thread
9925 key_infix [out] Infix of constants to be used for index lookup
9926 key_infix_len [out] Lenghth of the infix
9927 first_non_infix_part [out] The first keypart after the infix (if any)
9929 DESCRIPTION
9930 Test conditions (NGA1, NGA2, NGA3) from get_best_group_min_max(). Namely,
9931 for each keypart field NG_i not in GROUP-BY, check that there is exactly one
9932 constant equality predicate among conds with the form (NG_i = const_ci) or
9933 (const_ci = NG_i).. In addition, there can only be one range when there is
9934 such a gap.
9935 Thus all the NGF_i attributes must fill the 'gap' between the last group-by
9936 attribute and the MIN/MAX attribute in the index (if present). If these
9937 conditions hold, copy each constant from its corresponding predicate into
9938 key_infix, in the order its NG_i attribute appears in the index, and update
9939 key_infix_len with the total length of the key parts in key_infix.
9941 RETURN
9942 TRUE if the index passes the test
9943 FALSE o/w
9946 static bool
9947 get_constant_key_infix(KEY *index_info, SEL_ARG *index_range_tree,
9948 KEY_PART_INFO *first_non_group_part,
9949 KEY_PART_INFO *min_max_arg_part,
9950 KEY_PART_INFO *last_part, THD *thd,
9951 uchar *key_infix, uint *key_infix_len,
9952 KEY_PART_INFO **first_non_infix_part)
9954 SEL_ARG *cur_range;
9955 KEY_PART_INFO *cur_part;
9956 /* End part for the first loop below. */
9957 KEY_PART_INFO *end_part= min_max_arg_part ? min_max_arg_part : last_part;
9959 *key_infix_len= 0;
9960 uchar *key_ptr= key_infix;
9961 for (cur_part= first_non_group_part; cur_part != end_part; cur_part++)
9963 cur_range= NULL;
9965 Find the range tree for the current keypart. We assume that
9966 index_range_tree points to the first keypart in the index.
9968 if(get_sel_arg_for_keypart(cur_part->field, index_range_tree, &cur_range))
9969 return false;
9971 if (!cur_range)
9973 if (min_max_arg_part)
9974 return FALSE; /* The current keypart has no range predicates at all. */
9975 else
9977 *first_non_infix_part= cur_part;
9978 return TRUE;
9982 if ((cur_range->min_flag & NO_MIN_RANGE) ||
9983 (cur_range->max_flag & NO_MAX_RANGE) ||
9984 (cur_range->min_flag & NEAR_MIN) || (cur_range->max_flag & NEAR_MAX))
9985 return FALSE;
9987 uint field_length= cur_part->store_length;
9988 if (cur_range->maybe_null &&
9989 cur_range->min_value[0] && cur_range->max_value[0])
9992 cur_range specifies 'IS NULL'. In this case the argument points
9993 to a "null value" (is_null_string) that may not always be long
9994 enough for a direct memcpy to a field.
9996 DBUG_ASSERT (field_length > 0);
9997 *key_ptr= 1;
9998 bzero(key_ptr+1,field_length-1);
9999 key_ptr+= field_length;
10000 *key_infix_len+= field_length;
10002 else if (memcmp(cur_range->min_value, cur_range->max_value, field_length) == 0)
10003 { /* cur_range specifies an equality condition. */
10004 memcpy(key_ptr, cur_range->min_value, field_length);
10005 key_ptr+= field_length;
10006 *key_infix_len+= field_length;
10008 else
10009 return FALSE;
10012 if (!min_max_arg_part && (cur_part == last_part))
10013 *first_non_infix_part= last_part;
10015 return TRUE;
10020 Find the key part referenced by a field.
10022 SYNOPSIS
10023 get_field_keypart()
10024 index descriptor of an index
10025 field field that possibly references some key part in index
10027 NOTES
10028 The return value can be used to get a KEY_PART_INFO pointer by
10029 part= index->key_part + get_field_keypart(...) - 1;
10031 RETURN
10032 Positive number which is the consecutive number of the key part, or
10033 0 if field does not reference any index field.
10036 static inline uint
10037 get_field_keypart(KEY *index, Field *field)
10039 KEY_PART_INFO *part, *end;
10041 for (part= index->key_part, end= part + index->key_parts; part < end; part++)
10043 if (field->eq(part->field))
10044 return part - index->key_part + 1;
10046 return 0;
10051 Find the SEL_ARG sub-tree that corresponds to the chosen index.
10053 SYNOPSIS
10054 get_index_range_tree()
10055 index [in] The ID of the index being looked for
10056 range_tree[in] Tree of ranges being searched
10057 param [in] PARAM from SQL_SELECT::test_quick_select
10058 param_idx [out] Index in the array PARAM::key that corresponds to 'index'
10060 DESCRIPTION
10062 A SEL_TREE contains range trees for all usable indexes. This procedure
10063 finds the SEL_ARG sub-tree for 'index'. The members of a SEL_TREE are
10064 ordered in the same way as the members of PARAM::key, thus we first find
10065 the corresponding index in the array PARAM::key. This index is returned
10066 through the variable param_idx, to be used later as argument of
10067 check_quick_select().
10069 RETURN
10070 Pointer to the SEL_ARG subtree that corresponds to index.
10073 SEL_ARG * get_index_range_tree(uint index, SEL_TREE* range_tree, PARAM *param,
10074 uint *param_idx)
10076 uint idx= 0; /* Index nr in param->key_parts */
10077 while (idx < param->keys)
10079 if (index == param->real_keynr[idx])
10080 break;
10081 idx++;
10083 *param_idx= idx;
10084 return(range_tree->keys[idx]);
10089 Compute the cost of a quick_group_min_max_select for a particular index.
10091 SYNOPSIS
10092 cost_group_min_max()
10093 table [in] The table being accessed
10094 index_info [in] The index used to access the table
10095 used_key_parts [in] Number of key parts used to access the index
10096 group_key_parts [in] Number of index key parts in the group prefix
10097 range_tree [in] Tree of ranges for all indexes
10098 index_tree [in] The range tree for the current index
10099 quick_prefix_records [in] Number of records retrieved by the internally
10100 used quick range select if any
10101 have_min [in] True if there is a MIN function
10102 have_max [in] True if there is a MAX function
10103 read_cost [out] The cost to retrieve rows via this quick select
10104 records [out] The number of rows retrieved
10106 DESCRIPTION
10107 This method computes the access cost of a TRP_GROUP_MIN_MAX instance and
10108 the number of rows returned. It updates this->read_cost and this->records.
10110 NOTES
10111 The cost computation distinguishes several cases:
10112 1) No equality predicates over non-group attributes (thus no key_infix).
10113 If groups are bigger than blocks on the average, then we assume that it
10114 is very unlikely that block ends are aligned with group ends, thus even
10115 if we look for both MIN and MAX keys, all pairs of neighbor MIN/MAX
10116 keys, except for the first MIN and the last MAX keys, will be in the
10117 same block. If groups are smaller than blocks, then we are going to
10118 read all blocks.
10119 2) There are equality predicates over non-group attributes.
10120 In this case the group prefix is extended by additional constants, and
10121 as a result the min/max values are inside sub-groups of the original
10122 groups. The number of blocks that will be read depends on whether the
10123 ends of these sub-groups will be contained in the same or in different
10124 blocks. We compute the probability for the two ends of a subgroup to be
10125 in two different blocks as the ratio of:
10126 - the number of positions of the left-end of a subgroup inside a group,
10127 such that the right end of the subgroup is past the end of the buffer
10128 containing the left-end, and
10129 - the total number of possible positions for the left-end of the
10130 subgroup, which is the number of keys in the containing group.
10131 We assume it is very unlikely that two ends of subsequent subgroups are
10132 in the same block.
10133 3) The are range predicates over the group attributes.
10134 Then some groups may be filtered by the range predicates. We use the
10135 selectivity of the range predicates to decide how many groups will be
10136 filtered.
10138 TODO
10139 - Take into account the optional range predicates over the MIN/MAX
10140 argument.
10141 - Check if we have a PK index and we use all cols - then each key is a
10142 group, and it will be better to use an index scan.
10144 RETURN
10145 None
10148 void cost_group_min_max(TABLE* table, KEY *index_info, uint used_key_parts,
10149 uint group_key_parts, SEL_TREE *range_tree,
10150 SEL_ARG *index_tree, ha_rows quick_prefix_records,
10151 bool have_min, bool have_max,
10152 double *read_cost, ha_rows *records)
10154 ha_rows table_records;
10155 uint num_groups;
10156 uint num_blocks;
10157 uint keys_per_block;
10158 uint keys_per_group;
10159 uint keys_per_subgroup; /* Average number of keys in sub-groups */
10160 /* formed by a key infix. */
10161 double p_overlap; /* Probability that a sub-group overlaps two blocks. */
10162 double quick_prefix_selectivity;
10163 double io_cost;
10164 double cpu_cost= 0; /* TODO: CPU cost of index_read calls? */
10165 DBUG_ENTER("cost_group_min_max");
10167 table_records= table->file->stats.records;
10168 keys_per_block= (table->file->stats.block_size / 2 /
10169 (index_info->key_length + table->file->ref_length)
10170 + 1);
10171 num_blocks= (uint)(table_records / keys_per_block) + 1;
10173 /* Compute the number of keys in a group. */
10174 keys_per_group= index_info->rec_per_key[group_key_parts - 1];
10175 if (keys_per_group == 0) /* If there is no statistics try to guess */
10176 /* each group contains 10% of all records */
10177 keys_per_group= (uint)(table_records / 10) + 1;
10178 num_groups= (uint)(table_records / keys_per_group) + 1;
10180 /* Apply the selectivity of the quick select for group prefixes. */
10181 if (range_tree && (quick_prefix_records != HA_POS_ERROR))
10183 quick_prefix_selectivity= (double) quick_prefix_records /
10184 (double) table_records;
10185 num_groups= (uint) rint(num_groups * quick_prefix_selectivity);
10186 set_if_bigger(num_groups, 1);
10189 if (used_key_parts > group_key_parts)
10190 { /*
10191 Compute the probability that two ends of a subgroup are inside
10192 different blocks.
10194 keys_per_subgroup= index_info->rec_per_key[used_key_parts - 1];
10195 if (keys_per_subgroup >= keys_per_block) /* If a subgroup is bigger than */
10196 p_overlap= 1.0; /* a block, it will overlap at least two blocks. */
10197 else
10199 double blocks_per_group= (double) num_blocks / (double) num_groups;
10200 p_overlap= (blocks_per_group * (keys_per_subgroup - 1)) / keys_per_group;
10201 p_overlap= min(p_overlap, 1.0);
10203 io_cost= (double) min(num_groups * (1 + p_overlap), num_blocks);
10205 else
10206 io_cost= (keys_per_group > keys_per_block) ?
10207 (have_min && have_max) ? (double) (num_groups + 1) :
10208 (double) num_groups :
10209 (double) num_blocks;
10212 TODO: If there is no WHERE clause and no other expressions, there should be
10213 no CPU cost. We leave it here to make this cost comparable to that of index
10214 scan as computed in SQL_SELECT::test_quick_select().
10216 cpu_cost= (double) num_groups / TIME_FOR_COMPARE;
10218 *read_cost= io_cost + cpu_cost;
10219 *records= num_groups;
10221 DBUG_PRINT("info",
10222 ("table rows: %lu keys/block: %u keys/group: %u result rows: %lu blocks: %u",
10223 (ulong)table_records, keys_per_block, keys_per_group,
10224 (ulong) *records, num_blocks));
10225 DBUG_VOID_RETURN;
10230 Construct a new quick select object for queries with group by with min/max.
10232 SYNOPSIS
10233 TRP_GROUP_MIN_MAX::make_quick()
10234 param Parameter from test_quick_select
10235 retrieve_full_rows ignored
10236 parent_alloc Memory pool to use, if any.
10238 NOTES
10239 Make_quick ignores the retrieve_full_rows parameter because
10240 QUICK_GROUP_MIN_MAX_SELECT always performs 'index only' scans.
10241 The other parameter are ignored as well because all necessary
10242 data to create the QUICK object is computed at this TRP creation
10243 time.
10245 RETURN
10246 New QUICK_GROUP_MIN_MAX_SELECT object if successfully created,
10247 NULL otherwise.
10250 QUICK_SELECT_I *
10251 TRP_GROUP_MIN_MAX::make_quick(PARAM *param, bool retrieve_full_rows,
10252 MEM_ROOT *parent_alloc)
10254 QUICK_GROUP_MIN_MAX_SELECT *quick;
10255 DBUG_ENTER("TRP_GROUP_MIN_MAX::make_quick");
10257 quick= new QUICK_GROUP_MIN_MAX_SELECT(param->table,
10258 param->thd->lex->current_select->join,
10259 have_min, have_max, min_max_arg_part,
10260 group_prefix_len, group_key_parts,
10261 used_key_parts, index_info, index,
10262 read_cost, records, key_infix_len,
10263 key_infix, parent_alloc);
10264 if (!quick)
10265 DBUG_RETURN(NULL);
10267 if (quick->init())
10269 delete quick;
10270 DBUG_RETURN(NULL);
10273 if (range_tree)
10275 DBUG_ASSERT(quick_prefix_records > 0);
10276 if (quick_prefix_records == HA_POS_ERROR)
10277 quick->quick_prefix_select= NULL; /* Can't construct a quick select. */
10278 else
10279 /* Make a QUICK_RANGE_SELECT to be used for group prefix retrieval. */
10280 quick->quick_prefix_select= get_quick_select(param, param_idx,
10281 index_tree,
10282 &quick->alloc);
10285 Extract the SEL_ARG subtree that contains only ranges for the MIN/MAX
10286 attribute, and create an array of QUICK_RANGES to be used by the
10287 new quick select.
10289 if (min_max_arg_part)
10291 SEL_ARG *min_max_range= index_tree;
10292 while (min_max_range) /* Find the tree for the MIN/MAX key part. */
10294 if (min_max_range->field->eq(min_max_arg_part->field))
10295 break;
10296 min_max_range= min_max_range->next_key_part;
10298 /* Scroll to the leftmost interval for the MIN/MAX argument. */
10299 while (min_max_range && min_max_range->prev)
10300 min_max_range= min_max_range->prev;
10301 /* Create an array of QUICK_RANGEs for the MIN/MAX argument. */
10302 while (min_max_range)
10304 if (quick->add_range(min_max_range))
10306 delete quick;
10307 quick= NULL;
10308 DBUG_RETURN(NULL);
10310 min_max_range= min_max_range->next;
10314 else
10315 quick->quick_prefix_select= NULL;
10317 quick->update_key_stat();
10318 quick->adjust_prefix_ranges();
10320 DBUG_RETURN(quick);
10325 Construct new quick select for group queries with min/max.
10327 SYNOPSIS
10328 QUICK_GROUP_MIN_MAX_SELECT::QUICK_GROUP_MIN_MAX_SELECT()
10329 table The table being accessed
10330 join Descriptor of the current query
10331 have_min TRUE if the query selects a MIN function
10332 have_max TRUE if the query selects a MAX function
10333 min_max_arg_part The only argument field of all MIN/MAX functions
10334 group_prefix_len Length of all key parts in the group prefix
10335 prefix_key_parts All key parts in the group prefix
10336 index_info The index chosen for data access
10337 use_index The id of index_info
10338 read_cost Cost of this access method
10339 records Number of records returned
10340 key_infix_len Length of the key infix appended to the group prefix
10341 key_infix Infix of constants from equality predicates
10342 parent_alloc Memory pool for this and quick_prefix_select data
10344 RETURN
10345 None
10348 QUICK_GROUP_MIN_MAX_SELECT::
10349 QUICK_GROUP_MIN_MAX_SELECT(TABLE *table, JOIN *join_arg, bool have_min_arg,
10350 bool have_max_arg,
10351 KEY_PART_INFO *min_max_arg_part_arg,
10352 uint group_prefix_len_arg, uint group_key_parts_arg,
10353 uint used_key_parts_arg, KEY *index_info_arg,
10354 uint use_index, double read_cost_arg,
10355 ha_rows records_arg, uint key_infix_len_arg,
10356 uchar *key_infix_arg, MEM_ROOT *parent_alloc)
10357 :file(table->file), join(join_arg), index_info(index_info_arg),
10358 group_prefix_len(group_prefix_len_arg),
10359 group_key_parts(group_key_parts_arg), have_min(have_min_arg),
10360 have_max(have_max_arg), seen_first_key(FALSE),
10361 min_max_arg_part(min_max_arg_part_arg), key_infix(key_infix_arg),
10362 key_infix_len(key_infix_len_arg), min_functions_it(NULL),
10363 max_functions_it(NULL)
10365 head= table;
10366 index= use_index;
10367 record= head->record[0];
10368 tmp_record= head->record[1];
10369 read_time= read_cost_arg;
10370 records= records_arg;
10371 used_key_parts= used_key_parts_arg;
10372 real_key_parts= used_key_parts_arg;
10373 real_prefix_len= group_prefix_len + key_infix_len;
10374 group_prefix= NULL;
10375 min_max_arg_len= min_max_arg_part ? min_max_arg_part->store_length : 0;
10378 We can't have parent_alloc set as the init function can't handle this case
10379 yet.
10381 DBUG_ASSERT(!parent_alloc);
10382 if (!parent_alloc)
10384 init_sql_alloc(&alloc, join->thd->variables.range_alloc_block_size, 0);
10385 join->thd->mem_root= &alloc;
10387 else
10388 bzero(&alloc, sizeof(MEM_ROOT)); // ensure that it's not used
10393 Do post-constructor initialization.
10395 SYNOPSIS
10396 QUICK_GROUP_MIN_MAX_SELECT::init()
10398 DESCRIPTION
10399 The method performs initialization that cannot be done in the constructor
10400 such as memory allocations that may fail. It allocates memory for the
10401 group prefix and inifix buffers, and for the lists of MIN/MAX item to be
10402 updated during execution.
10404 RETURN
10405 0 OK
10406 other Error code
10409 int QUICK_GROUP_MIN_MAX_SELECT::init()
10411 if (group_prefix) /* Already initialized. */
10412 return 0;
10414 if (!(last_prefix= (uchar*) alloc_root(&alloc, group_prefix_len)))
10415 return 1;
10417 We may use group_prefix to store keys with all select fields, so allocate
10418 enough space for it.
10420 if (!(group_prefix= (uchar*) alloc_root(&alloc,
10421 real_prefix_len + min_max_arg_len)))
10422 return 1;
10424 if (key_infix_len > 0)
10427 The memory location pointed to by key_infix will be deleted soon, so
10428 allocate a new buffer and copy the key_infix into it.
10430 uchar *tmp_key_infix= (uchar*) alloc_root(&alloc, key_infix_len);
10431 if (!tmp_key_infix)
10432 return 1;
10433 memcpy(tmp_key_infix, this->key_infix, key_infix_len);
10434 this->key_infix= tmp_key_infix;
10437 if (min_max_arg_part)
10439 if (my_init_dynamic_array(&min_max_ranges, sizeof(QUICK_RANGE*), 16, 16))
10440 return 1;
10442 if (have_min)
10444 if (!(min_functions= new List<Item_sum>))
10445 return 1;
10447 else
10448 min_functions= NULL;
10449 if (have_max)
10451 if (!(max_functions= new List<Item_sum>))
10452 return 1;
10454 else
10455 max_functions= NULL;
10457 Item_sum *min_max_item;
10458 Item_sum **func_ptr= join->sum_funcs;
10459 while ((min_max_item= *(func_ptr++)))
10461 if (have_min && (min_max_item->sum_func() == Item_sum::MIN_FUNC))
10462 min_functions->push_back(min_max_item);
10463 else if (have_max && (min_max_item->sum_func() == Item_sum::MAX_FUNC))
10464 max_functions->push_back(min_max_item);
10467 if (have_min)
10469 if (!(min_functions_it= new List_iterator<Item_sum>(*min_functions)))
10470 return 1;
10473 if (have_max)
10475 if (!(max_functions_it= new List_iterator<Item_sum>(*max_functions)))
10476 return 1;
10479 else
10480 min_max_ranges.elements= 0;
10482 return 0;
10486 QUICK_GROUP_MIN_MAX_SELECT::~QUICK_GROUP_MIN_MAX_SELECT()
10488 DBUG_ENTER("QUICK_GROUP_MIN_MAX_SELECT::~QUICK_GROUP_MIN_MAX_SELECT");
10489 if (file->inited != handler::NONE)
10490 file->ha_index_end();
10491 if (min_max_arg_part)
10492 delete_dynamic(&min_max_ranges);
10493 free_root(&alloc,MYF(0));
10494 delete min_functions_it;
10495 delete max_functions_it;
10496 delete quick_prefix_select;
10497 DBUG_VOID_RETURN;
10502 Eventually create and add a new quick range object.
10504 SYNOPSIS
10505 QUICK_GROUP_MIN_MAX_SELECT::add_range()
10506 sel_range Range object from which a
10508 NOTES
10509 Construct a new QUICK_RANGE object from a SEL_ARG object, and
10510 add it to the array min_max_ranges. If sel_arg is an infinite
10511 range, e.g. (x < 5 or x > 4), then skip it and do not construct
10512 a quick range.
10514 RETURN
10515 FALSE on success
10516 TRUE otherwise
10519 bool QUICK_GROUP_MIN_MAX_SELECT::add_range(SEL_ARG *sel_range)
10521 QUICK_RANGE *range;
10522 uint range_flag= sel_range->min_flag | sel_range->max_flag;
10524 /* Skip (-inf,+inf) ranges, e.g. (x < 5 or x > 4). */
10525 if ((range_flag & NO_MIN_RANGE) && (range_flag & NO_MAX_RANGE))
10526 return FALSE;
10528 if (!(sel_range->min_flag & NO_MIN_RANGE) &&
10529 !(sel_range->max_flag & NO_MAX_RANGE))
10531 if (sel_range->maybe_null &&
10532 sel_range->min_value[0] && sel_range->max_value[0])
10533 range_flag|= NULL_RANGE; /* IS NULL condition */
10534 else if (memcmp(sel_range->min_value, sel_range->max_value,
10535 min_max_arg_len) == 0)
10536 range_flag|= EQ_RANGE; /* equality condition */
10538 range= new QUICK_RANGE(sel_range->min_value, min_max_arg_len,
10539 make_keypart_map(sel_range->part),
10540 sel_range->max_value, min_max_arg_len,
10541 make_keypart_map(sel_range->part),
10542 range_flag);
10543 if (!range)
10544 return TRUE;
10545 if (insert_dynamic(&min_max_ranges, (uchar*)&range))
10546 return TRUE;
10547 return FALSE;
10552 Opens the ranges if there are more conditions in quick_prefix_select than
10553 the ones used for jumping through the prefixes.
10555 SYNOPSIS
10556 QUICK_GROUP_MIN_MAX_SELECT::adjust_prefix_ranges()
10558 NOTES
10559 quick_prefix_select is made over the conditions on the whole key.
10560 It defines a number of ranges of length x.
10561 However when jumping through the prefixes we use only the the first
10562 few most significant keyparts in the range key. However if there
10563 are more keyparts to follow the ones we are using we must make the
10564 condition on the key inclusive (because x < "ab" means
10565 x[0] < 'a' OR (x[0] == 'a' AND x[1] < 'b').
10566 To achive the above we must turn off the NEAR_MIN/NEAR_MAX
10568 void QUICK_GROUP_MIN_MAX_SELECT::adjust_prefix_ranges ()
10570 if (quick_prefix_select &&
10571 group_prefix_len < quick_prefix_select->max_used_key_length)
10573 DYNAMIC_ARRAY *arr;
10574 uint inx;
10576 for (inx= 0, arr= &quick_prefix_select->ranges; inx < arr->elements; inx++)
10578 QUICK_RANGE *range;
10580 get_dynamic(arr, (uchar*)&range, inx);
10581 range->flag &= ~(NEAR_MIN | NEAR_MAX);
10588 Determine the total number and length of the keys that will be used for
10589 index lookup.
10591 SYNOPSIS
10592 QUICK_GROUP_MIN_MAX_SELECT::update_key_stat()
10594 DESCRIPTION
10595 The total length of the keys used for index lookup depends on whether
10596 there are any predicates referencing the min/max argument, and/or if
10597 the min/max argument field can be NULL.
10598 This function does an optimistic analysis whether the search key might
10599 be extended by a constant for the min/max keypart. It is 'optimistic'
10600 because during actual execution it may happen that a particular range
10601 is skipped, and then a shorter key will be used. However this is data
10602 dependent and can't be easily estimated here.
10604 RETURN
10605 None
10608 void QUICK_GROUP_MIN_MAX_SELECT::update_key_stat()
10610 max_used_key_length= real_prefix_len;
10611 if (min_max_ranges.elements > 0)
10613 QUICK_RANGE *cur_range;
10614 if (have_min)
10615 { /* Check if the right-most range has a lower boundary. */
10616 get_dynamic(&min_max_ranges, (uchar*)&cur_range,
10617 min_max_ranges.elements - 1);
10618 if (!(cur_range->flag & NO_MIN_RANGE))
10620 max_used_key_length+= min_max_arg_len;
10621 used_key_parts++;
10622 return;
10625 if (have_max)
10626 { /* Check if the left-most range has an upper boundary. */
10627 get_dynamic(&min_max_ranges, (uchar*)&cur_range, 0);
10628 if (!(cur_range->flag & NO_MAX_RANGE))
10630 max_used_key_length+= min_max_arg_len;
10631 used_key_parts++;
10632 return;
10636 else if (have_min && min_max_arg_part &&
10637 min_max_arg_part->field->real_maybe_null())
10640 If a MIN/MAX argument value is NULL, we can quickly determine
10641 that we're in the beginning of the next group, because NULLs
10642 are always < any other value. This allows us to quickly
10643 determine the end of the current group and jump to the next
10644 group (see next_min()) and thus effectively increases the
10645 usable key length.
10647 max_used_key_length+= min_max_arg_len;
10648 used_key_parts++;
10654 Initialize a quick group min/max select for key retrieval.
10656 SYNOPSIS
10657 QUICK_GROUP_MIN_MAX_SELECT::reset()
10659 DESCRIPTION
10660 Initialize the index chosen for access and find and store the prefix
10661 of the last group. The method is expensive since it performs disk access.
10663 RETURN
10664 0 OK
10665 other Error code
10668 int QUICK_GROUP_MIN_MAX_SELECT::reset(void)
10670 int result;
10671 DBUG_ENTER("QUICK_GROUP_MIN_MAX_SELECT::reset");
10673 head->set_keyread(TRUE); /* We need only the key attributes */
10674 if ((result= file->ha_index_init(index,1)))
10675 DBUG_RETURN(result);
10676 if (quick_prefix_select && quick_prefix_select->reset())
10677 DBUG_RETURN(1);
10678 result= file->index_last(record);
10679 if (result == HA_ERR_END_OF_FILE)
10680 DBUG_RETURN(0);
10681 /* Save the prefix of the last group. */
10682 key_copy(last_prefix, record, index_info, group_prefix_len);
10684 DBUG_RETURN(0);
10690 Get the next key containing the MIN and/or MAX key for the next group.
10692 SYNOPSIS
10693 QUICK_GROUP_MIN_MAX_SELECT::get_next()
10695 DESCRIPTION
10696 The method finds the next subsequent group of records that satisfies the
10697 query conditions and finds the keys that contain the MIN/MAX values for
10698 the key part referenced by the MIN/MAX function(s). Once a group and its
10699 MIN/MAX values are found, store these values in the Item_sum objects for
10700 the MIN/MAX functions. The rest of the values in the result row are stored
10701 in the Item_field::result_field of each select field. If the query does
10702 not contain MIN and/or MAX functions, then the function only finds the
10703 group prefix, which is a query answer itself.
10705 NOTES
10706 If both MIN and MAX are computed, then we use the fact that if there is
10707 no MIN key, there can't be a MAX key as well, so we can skip looking
10708 for a MAX key in this case.
10710 RETURN
10711 0 on success
10712 HA_ERR_END_OF_FILE if returned all keys
10713 other if some error occurred
10716 int QUICK_GROUP_MIN_MAX_SELECT::get_next()
10718 int min_res= 0;
10719 int max_res= 0;
10720 #ifdef HPUX11
10722 volatile is required by a bug in the HP compiler due to which the
10723 last test of result fails.
10725 volatile int result;
10726 #else
10727 int result;
10728 #endif
10729 int is_last_prefix= 0;
10731 DBUG_ENTER("QUICK_GROUP_MIN_MAX_SELECT::get_next");
10734 Loop until a group is found that satisfies all query conditions or the last
10735 group is reached.
10739 result= next_prefix();
10741 Check if this is the last group prefix. Notice that at this point
10742 this->record contains the current prefix in record format.
10744 if (!result)
10746 is_last_prefix= key_cmp(index_info->key_part, last_prefix,
10747 group_prefix_len);
10748 DBUG_ASSERT(is_last_prefix <= 0);
10750 else
10752 if (result == HA_ERR_KEY_NOT_FOUND)
10753 continue;
10754 break;
10757 if (have_min)
10759 min_res= next_min();
10760 if (min_res == 0)
10761 update_min_result();
10763 /* If there is no MIN in the group, there is no MAX either. */
10764 if ((have_max && !have_min) ||
10765 (have_max && have_min && (min_res == 0)))
10767 max_res= next_max();
10768 if (max_res == 0)
10769 update_max_result();
10770 /* If a MIN was found, a MAX must have been found as well. */
10771 DBUG_ASSERT((have_max && !have_min) ||
10772 (have_max && have_min && (max_res == 0)));
10775 If this is just a GROUP BY or DISTINCT without MIN or MAX and there
10776 are equality predicates for the key parts after the group, find the
10777 first sub-group with the extended prefix.
10779 if (!have_min && !have_max && key_infix_len > 0)
10780 result= file->index_read_map(record, group_prefix,
10781 make_prev_keypart_map(real_key_parts),
10782 HA_READ_KEY_EXACT);
10784 result= have_min ? min_res : have_max ? max_res : result;
10785 } while ((result == HA_ERR_KEY_NOT_FOUND || result == HA_ERR_END_OF_FILE) &&
10786 is_last_prefix != 0);
10788 if (result == 0)
10791 Partially mimic the behavior of end_select_send. Copy the
10792 field data from Item_field::field into Item_field::result_field
10793 of each non-aggregated field (the group fields, and optionally
10794 other fields in non-ANSI SQL mode).
10796 copy_fields(&join->tmp_table_param);
10798 else if (result == HA_ERR_KEY_NOT_FOUND)
10799 result= HA_ERR_END_OF_FILE;
10801 DBUG_RETURN(result);
10806 Retrieve the minimal key in the next group.
10808 SYNOPSIS
10809 QUICK_GROUP_MIN_MAX_SELECT::next_min()
10811 DESCRIPTION
10812 Find the minimal key within this group such that the key satisfies the query
10813 conditions and NULL semantics. The found key is loaded into this->record.
10815 IMPLEMENTATION
10816 Depending on the values of min_max_ranges.elements, key_infix_len, and
10817 whether there is a NULL in the MIN field, this function may directly
10818 return without any data access. In this case we use the key loaded into
10819 this->record by the call to this->next_prefix() just before this call.
10821 RETURN
10822 0 on success
10823 HA_ERR_KEY_NOT_FOUND if no MIN key was found that fulfills all conditions.
10824 HA_ERR_END_OF_FILE - "" -
10825 other if some error occurred
10828 int QUICK_GROUP_MIN_MAX_SELECT::next_min()
10830 int result= 0;
10831 DBUG_ENTER("QUICK_GROUP_MIN_MAX_SELECT::next_min");
10833 /* Find the MIN key using the eventually extended group prefix. */
10834 if (min_max_ranges.elements > 0)
10836 if ((result= next_min_in_range()))
10837 DBUG_RETURN(result);
10839 else
10841 /* Apply the constant equality conditions to the non-group select fields */
10842 if (key_infix_len > 0)
10844 if ((result= file->index_read_map(record, group_prefix,
10845 make_prev_keypart_map(real_key_parts),
10846 HA_READ_KEY_EXACT)))
10847 DBUG_RETURN(result);
10851 If the min/max argument field is NULL, skip subsequent rows in the same
10852 group with NULL in it. Notice that:
10853 - if the first row in a group doesn't have a NULL in the field, no row
10854 in the same group has (because NULL < any other value),
10855 - min_max_arg_part->field->ptr points to some place in 'record'.
10857 if (min_max_arg_part && min_max_arg_part->field->is_null())
10859 uchar key_buf[MAX_KEY_LENGTH];
10861 /* Find the first subsequent record without NULL in the MIN/MAX field. */
10862 key_copy(key_buf, record, index_info, 0);
10863 result= file->index_read_map(record, key_buf,
10864 make_keypart_map(real_key_parts),
10865 HA_READ_AFTER_KEY);
10867 Check if the new record belongs to the current group by comparing its
10868 prefix with the group's prefix. If it is from the next group, then the
10869 whole group has NULLs in the MIN/MAX field, so use the first record in
10870 the group as a result.
10871 TODO:
10872 It is possible to reuse this new record as the result candidate for the
10873 next call to next_min(), and to save one lookup in the next call. For
10874 this add a new member 'this->next_group_prefix'.
10876 if (!result)
10878 if (key_cmp(index_info->key_part, group_prefix, real_prefix_len))
10879 key_restore(record, key_buf, index_info, 0);
10881 else if (result == HA_ERR_KEY_NOT_FOUND || result == HA_ERR_END_OF_FILE)
10882 result= 0; /* There is a result in any case. */
10887 If the MIN attribute is non-nullable, this->record already contains the
10888 MIN key in the group, so just return.
10890 DBUG_RETURN(result);
10895 Retrieve the maximal key in the next group.
10897 SYNOPSIS
10898 QUICK_GROUP_MIN_MAX_SELECT::next_max()
10900 DESCRIPTION
10901 Lookup the maximal key of the group, and store it into this->record.
10903 RETURN
10904 0 on success
10905 HA_ERR_KEY_NOT_FOUND if no MAX key was found that fulfills all conditions.
10906 HA_ERR_END_OF_FILE - "" -
10907 other if some error occurred
10910 int QUICK_GROUP_MIN_MAX_SELECT::next_max()
10912 int result;
10914 DBUG_ENTER("QUICK_GROUP_MIN_MAX_SELECT::next_max");
10916 /* Get the last key in the (possibly extended) group. */
10917 if (min_max_ranges.elements > 0)
10918 result= next_max_in_range();
10919 else
10920 result= file->index_read_map(record, group_prefix,
10921 make_prev_keypart_map(real_key_parts),
10922 HA_READ_PREFIX_LAST);
10923 DBUG_RETURN(result);
10928 Determine the prefix of the next group.
10930 SYNOPSIS
10931 QUICK_GROUP_MIN_MAX_SELECT::next_prefix()
10933 DESCRIPTION
10934 Determine the prefix of the next group that satisfies the query conditions.
10935 If there is a range condition referencing the group attributes, use a
10936 QUICK_RANGE_SELECT object to retrieve the *first* key that satisfies the
10937 condition. If there is a key infix of constants, append this infix
10938 immediately after the group attributes. The possibly extended prefix is
10939 stored in this->group_prefix. The first key of the found group is stored in
10940 this->record, on which relies this->next_min().
10942 RETURN
10943 0 on success
10944 HA_ERR_KEY_NOT_FOUND if there is no key with the formed prefix
10945 HA_ERR_END_OF_FILE if there are no more keys
10946 other if some error occurred
10948 int QUICK_GROUP_MIN_MAX_SELECT::next_prefix()
10950 int result;
10951 DBUG_ENTER("QUICK_GROUP_MIN_MAX_SELECT::next_prefix");
10953 if (quick_prefix_select)
10955 uchar *cur_prefix= seen_first_key ? group_prefix : NULL;
10956 if ((result= quick_prefix_select->get_next_prefix(group_prefix_len,
10957 group_key_parts,
10958 cur_prefix)))
10959 DBUG_RETURN(result);
10960 seen_first_key= TRUE;
10962 else
10964 if (!seen_first_key)
10966 result= file->index_first(record);
10967 if (result)
10968 DBUG_RETURN(result);
10969 seen_first_key= TRUE;
10971 else
10973 /* Load the first key in this group into record. */
10974 result= file->index_read_map(record, group_prefix,
10975 make_prev_keypart_map(group_key_parts),
10976 HA_READ_AFTER_KEY);
10977 if (result)
10978 DBUG_RETURN(result);
10982 /* Save the prefix of this group for subsequent calls. */
10983 key_copy(group_prefix, record, index_info, group_prefix_len);
10984 /* Append key_infix to group_prefix. */
10985 if (key_infix_len > 0)
10986 memcpy(group_prefix + group_prefix_len,
10987 key_infix, key_infix_len);
10989 DBUG_RETURN(0);
10994 Find the minimal key in a group that satisfies some range conditions for the
10995 min/max argument field.
10997 SYNOPSIS
10998 QUICK_GROUP_MIN_MAX_SELECT::next_min_in_range()
11000 DESCRIPTION
11001 Given the sequence of ranges min_max_ranges, find the minimal key that is
11002 in the left-most possible range. If there is no such key, then the current
11003 group does not have a MIN key that satisfies the WHERE clause. If a key is
11004 found, its value is stored in this->record.
11006 RETURN
11007 0 on success
11008 HA_ERR_KEY_NOT_FOUND if there is no key with the given prefix in any of
11009 the ranges
11010 HA_ERR_END_OF_FILE - "" -
11011 other if some error
11014 int QUICK_GROUP_MIN_MAX_SELECT::next_min_in_range()
11016 ha_rkey_function find_flag;
11017 key_part_map keypart_map;
11018 QUICK_RANGE *cur_range;
11019 bool found_null= FALSE;
11020 int result= HA_ERR_KEY_NOT_FOUND;
11022 DBUG_ASSERT(min_max_ranges.elements > 0);
11024 for (uint range_idx= 0; range_idx < min_max_ranges.elements; range_idx++)
11025 { /* Search from the left-most range to the right. */
11026 get_dynamic(&min_max_ranges, (uchar*)&cur_range, range_idx);
11029 If the current value for the min/max argument is bigger than the right
11030 boundary of cur_range, there is no need to check this range.
11032 if (range_idx != 0 && !(cur_range->flag & NO_MAX_RANGE) &&
11033 (key_cmp(min_max_arg_part, (const uchar*) cur_range->max_key,
11034 min_max_arg_len) == 1))
11035 continue;
11037 if (cur_range->flag & NO_MIN_RANGE)
11039 keypart_map= make_prev_keypart_map(real_key_parts);
11040 find_flag= HA_READ_KEY_EXACT;
11042 else
11044 /* Extend the search key with the lower boundary for this range. */
11045 memcpy(group_prefix + real_prefix_len, cur_range->min_key,
11046 cur_range->min_length);
11047 keypart_map= make_keypart_map(real_key_parts);
11048 find_flag= (cur_range->flag & (EQ_RANGE | NULL_RANGE)) ?
11049 HA_READ_KEY_EXACT : (cur_range->flag & NEAR_MIN) ?
11050 HA_READ_AFTER_KEY : HA_READ_KEY_OR_NEXT;
11053 result= file->index_read_map(record, group_prefix, keypart_map, find_flag);
11054 if (result)
11056 if ((result == HA_ERR_KEY_NOT_FOUND || result == HA_ERR_END_OF_FILE) &&
11057 (cur_range->flag & (EQ_RANGE | NULL_RANGE)))
11058 continue; /* Check the next range. */
11061 In all other cases (HA_ERR_*, HA_READ_KEY_EXACT with NO_MIN_RANGE,
11062 HA_READ_AFTER_KEY, HA_READ_KEY_OR_NEXT) if the lookup failed for this
11063 range, it can't succeed for any other subsequent range.
11065 break;
11068 /* A key was found. */
11069 if (cur_range->flag & EQ_RANGE)
11070 break; /* No need to perform the checks below for equal keys. */
11072 if (cur_range->flag & NULL_RANGE)
11075 Remember this key, and continue looking for a non-NULL key that
11076 satisfies some other condition.
11078 memcpy(tmp_record, record, head->s->rec_buff_length);
11079 found_null= TRUE;
11080 continue;
11083 /* Check if record belongs to the current group. */
11084 if (key_cmp(index_info->key_part, group_prefix, real_prefix_len))
11086 result= HA_ERR_KEY_NOT_FOUND;
11087 continue;
11090 /* If there is an upper limit, check if the found key is in the range. */
11091 if ( !(cur_range->flag & NO_MAX_RANGE) )
11093 /* Compose the MAX key for the range. */
11094 uchar *max_key= (uchar*) my_alloca(real_prefix_len + min_max_arg_len);
11095 memcpy(max_key, group_prefix, real_prefix_len);
11096 memcpy(max_key + real_prefix_len, cur_range->max_key,
11097 cur_range->max_length);
11098 /* Compare the found key with max_key. */
11099 int cmp_res= key_cmp(index_info->key_part, max_key,
11100 real_prefix_len + min_max_arg_len);
11102 The key is outside of the range if:
11103 the interval is open and the key is equal to the maximum boundry
11105 the key is greater than the maximum
11107 if (((cur_range->flag & NEAR_MAX) && cmp_res == 0) ||
11108 cmp_res > 0)
11110 result= HA_ERR_KEY_NOT_FOUND;
11111 continue;
11114 /* If we got to this point, the current key qualifies as MIN. */
11115 DBUG_ASSERT(result == 0);
11116 break;
11119 If there was a key with NULL in the MIN/MAX field, and there was no other
11120 key without NULL from the same group that satisfies some other condition,
11121 then use the key with the NULL.
11123 if (found_null && result)
11125 memcpy(record, tmp_record, head->s->rec_buff_length);
11126 result= 0;
11128 return result;
11133 Find the maximal key in a group that satisfies some range conditions for the
11134 min/max argument field.
11136 SYNOPSIS
11137 QUICK_GROUP_MIN_MAX_SELECT::next_max_in_range()
11139 DESCRIPTION
11140 Given the sequence of ranges min_max_ranges, find the maximal key that is
11141 in the right-most possible range. If there is no such key, then the current
11142 group does not have a MAX key that satisfies the WHERE clause. If a key is
11143 found, its value is stored in this->record.
11145 RETURN
11146 0 on success
11147 HA_ERR_KEY_NOT_FOUND if there is no key with the given prefix in any of
11148 the ranges
11149 HA_ERR_END_OF_FILE - "" -
11150 other if some error
11153 int QUICK_GROUP_MIN_MAX_SELECT::next_max_in_range()
11155 ha_rkey_function find_flag;
11156 key_part_map keypart_map;
11157 QUICK_RANGE *cur_range;
11158 int result;
11160 DBUG_ASSERT(min_max_ranges.elements > 0);
11162 for (uint range_idx= min_max_ranges.elements; range_idx > 0; range_idx--)
11163 { /* Search from the right-most range to the left. */
11164 get_dynamic(&min_max_ranges, (uchar*)&cur_range, range_idx - 1);
11167 If the current value for the min/max argument is smaller than the left
11168 boundary of cur_range, there is no need to check this range.
11170 if (range_idx != min_max_ranges.elements &&
11171 !(cur_range->flag & NO_MIN_RANGE) &&
11172 (key_cmp(min_max_arg_part, (const uchar*) cur_range->min_key,
11173 min_max_arg_len) == -1))
11174 continue;
11176 if (cur_range->flag & NO_MAX_RANGE)
11178 keypart_map= make_prev_keypart_map(real_key_parts);
11179 find_flag= HA_READ_PREFIX_LAST;
11181 else
11183 /* Extend the search key with the upper boundary for this range. */
11184 memcpy(group_prefix + real_prefix_len, cur_range->max_key,
11185 cur_range->max_length);
11186 keypart_map= make_keypart_map(real_key_parts);
11187 find_flag= (cur_range->flag & EQ_RANGE) ?
11188 HA_READ_KEY_EXACT : (cur_range->flag & NEAR_MAX) ?
11189 HA_READ_BEFORE_KEY : HA_READ_PREFIX_LAST_OR_PREV;
11192 result= file->index_read_map(record, group_prefix, keypart_map, find_flag);
11194 if (result)
11196 if ((result == HA_ERR_KEY_NOT_FOUND || result == HA_ERR_END_OF_FILE) &&
11197 (cur_range->flag & EQ_RANGE))
11198 continue; /* Check the next range. */
11201 In no key was found with this upper bound, there certainly are no keys
11202 in the ranges to the left.
11204 return result;
11206 /* A key was found. */
11207 if (cur_range->flag & EQ_RANGE)
11208 return 0; /* No need to perform the checks below for equal keys. */
11210 /* Check if record belongs to the current group. */
11211 if (key_cmp(index_info->key_part, group_prefix, real_prefix_len))
11212 continue; // Row not found
11214 /* If there is a lower limit, check if the found key is in the range. */
11215 if ( !(cur_range->flag & NO_MIN_RANGE) )
11217 /* Compose the MIN key for the range. */
11218 uchar *min_key= (uchar*) my_alloca(real_prefix_len + min_max_arg_len);
11219 memcpy(min_key, group_prefix, real_prefix_len);
11220 memcpy(min_key + real_prefix_len, cur_range->min_key,
11221 cur_range->min_length);
11222 /* Compare the found key with min_key. */
11223 int cmp_res= key_cmp(index_info->key_part, min_key,
11224 real_prefix_len + min_max_arg_len);
11226 The key is outside of the range if:
11227 the interval is open and the key is equal to the minimum boundry
11229 the key is less than the minimum
11231 if (((cur_range->flag & NEAR_MIN) && cmp_res == 0) ||
11232 cmp_res < 0)
11233 continue;
11235 /* If we got to this point, the current key qualifies as MAX. */
11236 return result;
11238 return HA_ERR_KEY_NOT_FOUND;
11243 Update all MIN function results with the newly found value.
11245 SYNOPSIS
11246 QUICK_GROUP_MIN_MAX_SELECT::update_min_result()
11248 DESCRIPTION
11249 The method iterates through all MIN functions and updates the result value
11250 of each function by calling Item_sum::reset(), which in turn picks the new
11251 result value from this->head->record[0], previously updated by
11252 next_min(). The updated value is stored in a member variable of each of the
11253 Item_sum objects, depending on the value type.
11255 IMPLEMENTATION
11256 The update must be done separately for MIN and MAX, immediately after
11257 next_min() was called and before next_max() is called, because both MIN and
11258 MAX take their result value from the same buffer this->head->record[0]
11259 (i.e. this->record).
11261 RETURN
11262 None
11265 void QUICK_GROUP_MIN_MAX_SELECT::update_min_result()
11267 Item_sum *min_func;
11269 min_functions_it->rewind();
11270 while ((min_func= (*min_functions_it)++))
11271 min_func->reset();
11276 Update all MAX function results with the newly found value.
11278 SYNOPSIS
11279 QUICK_GROUP_MIN_MAX_SELECT::update_max_result()
11281 DESCRIPTION
11282 The method iterates through all MAX functions and updates the result value
11283 of each function by calling Item_sum::reset(), which in turn picks the new
11284 result value from this->head->record[0], previously updated by
11285 next_max(). The updated value is stored in a member variable of each of the
11286 Item_sum objects, depending on the value type.
11288 IMPLEMENTATION
11289 The update must be done separately for MIN and MAX, immediately after
11290 next_max() was called, because both MIN and MAX take their result value
11291 from the same buffer this->head->record[0] (i.e. this->record).
11293 RETURN
11294 None
11297 void QUICK_GROUP_MIN_MAX_SELECT::update_max_result()
11299 Item_sum *max_func;
11301 max_functions_it->rewind();
11302 while ((max_func= (*max_functions_it)++))
11303 max_func->reset();
11308 Append comma-separated list of keys this quick select uses to key_names;
11309 append comma-separated list of corresponding used lengths to used_lengths.
11311 SYNOPSIS
11312 QUICK_GROUP_MIN_MAX_SELECT::add_keys_and_lengths()
11313 key_names [out] Names of used indexes
11314 used_lengths [out] Corresponding lengths of the index names
11316 DESCRIPTION
11317 This method is used by select_describe to extract the names of the
11318 indexes used by a quick select.
11322 void QUICK_GROUP_MIN_MAX_SELECT::add_keys_and_lengths(String *key_names,
11323 String *used_lengths)
11325 char buf[64];
11326 uint length;
11327 key_names->append(index_info->name);
11328 length= longlong2str(max_used_key_length, buf, 10) - buf;
11329 used_lengths->append(buf, length);
11333 #ifndef DBUG_OFF
11335 static void print_sel_tree(PARAM *param, SEL_TREE *tree, key_map *tree_map,
11336 const char *msg)
11338 SEL_ARG **key,**end;
11339 int idx;
11340 char buff[1024];
11341 DBUG_ENTER("print_sel_tree");
11343 String tmp(buff,sizeof(buff),&my_charset_bin);
11344 tmp.length(0);
11345 for (idx= 0,key=tree->keys, end=key+param->keys ;
11346 key != end ;
11347 key++,idx++)
11349 if (tree_map->is_set(idx))
11351 uint keynr= param->real_keynr[idx];
11352 if (tmp.length())
11353 tmp.append(',');
11354 tmp.append(param->table->key_info[keynr].name);
11357 if (!tmp.length())
11358 tmp.append(STRING_WITH_LEN("(empty)"));
11360 DBUG_PRINT("info", ("SEL_TREE: 0x%lx (%s) scans: %s", (long) tree, msg, tmp.ptr()));
11362 DBUG_VOID_RETURN;
11366 static void print_ror_scans_arr(TABLE *table, const char *msg,
11367 struct st_ror_scan_info **start,
11368 struct st_ror_scan_info **end)
11370 DBUG_ENTER("print_ror_scans_arr");
11372 char buff[1024];
11373 String tmp(buff,sizeof(buff),&my_charset_bin);
11374 tmp.length(0);
11375 for (;start != end; start++)
11377 if (tmp.length())
11378 tmp.append(',');
11379 tmp.append(table->key_info[(*start)->keynr].name);
11381 if (!tmp.length())
11382 tmp.append(STRING_WITH_LEN("(empty)"));
11383 DBUG_PRINT("info", ("ROR key scans (%s): %s", msg, tmp.ptr()));
11384 DBUG_VOID_RETURN;
11387 /*****************************************************************************
11388 ** Print a quick range for debugging
11389 ** TODO:
11390 ** This should be changed to use a String to store each row instead
11391 ** of locking the DEBUG stream !
11392 *****************************************************************************/
11394 static void
11395 print_key(KEY_PART *key_part, const uchar *key, uint used_length)
11397 char buff[1024];
11398 const uchar *key_end= key+used_length;
11399 String tmp(buff,sizeof(buff),&my_charset_bin);
11400 uint store_length;
11401 TABLE *table= key_part->field->table;
11402 my_bitmap_map *old_sets[2];
11404 dbug_tmp_use_all_columns(table, old_sets, table->read_set, table->write_set);
11406 for (; key < key_end; key+=store_length, key_part++)
11408 Field *field= key_part->field;
11409 store_length= key_part->store_length;
11411 if (field->real_maybe_null())
11413 if (*key)
11415 fwrite("NULL",sizeof(char),4,DBUG_FILE);
11416 continue;
11418 key++; // Skip null byte
11419 store_length--;
11421 field->set_key_image(key, key_part->length);
11422 if (field->type() == MYSQL_TYPE_BIT)
11423 (void) field->val_int_as_str(&tmp, 1);
11424 else
11425 field->val_str(&tmp);
11426 fwrite(tmp.ptr(),sizeof(char),tmp.length(),DBUG_FILE);
11427 if (key+store_length < key_end)
11428 fputc('/',DBUG_FILE);
11430 dbug_tmp_restore_column_maps(table->read_set, table->write_set, old_sets);
11434 static void print_quick(QUICK_SELECT_I *quick, const key_map *needed_reg)
11436 char buf[MAX_KEY/8+1];
11437 TABLE *table;
11438 my_bitmap_map *old_sets[2];
11439 DBUG_ENTER("print_quick");
11440 if (!quick)
11441 DBUG_VOID_RETURN;
11442 DBUG_LOCK_FILE;
11444 table= quick->head;
11445 dbug_tmp_use_all_columns(table, old_sets, table->read_set, table->write_set);
11446 quick->dbug_dump(0, TRUE);
11447 dbug_tmp_restore_column_maps(table->read_set, table->write_set, old_sets);
11449 fprintf(DBUG_FILE,"other_keys: 0x%s:\n", needed_reg->print(buf));
11451 DBUG_UNLOCK_FILE;
11452 DBUG_VOID_RETURN;
11456 void QUICK_RANGE_SELECT::dbug_dump(int indent, bool verbose)
11458 /* purecov: begin inspected */
11459 fprintf(DBUG_FILE, "%*squick range select, key %s, length: %d\n",
11460 indent, "", head->key_info[index].name, max_used_key_length);
11462 if (verbose)
11464 QUICK_RANGE *range;
11465 QUICK_RANGE **pr= (QUICK_RANGE**)ranges.buffer;
11466 QUICK_RANGE **end_range= pr + ranges.elements;
11467 for (; pr != end_range; ++pr)
11469 fprintf(DBUG_FILE, "%*s", indent + 2, "");
11470 range= *pr;
11471 if (!(range->flag & NO_MIN_RANGE))
11473 print_key(key_parts, range->min_key, range->min_length);
11474 if (range->flag & NEAR_MIN)
11475 fputs(" < ",DBUG_FILE);
11476 else
11477 fputs(" <= ",DBUG_FILE);
11479 fputs("X",DBUG_FILE);
11481 if (!(range->flag & NO_MAX_RANGE))
11483 if (range->flag & NEAR_MAX)
11484 fputs(" < ",DBUG_FILE);
11485 else
11486 fputs(" <= ",DBUG_FILE);
11487 print_key(key_parts, range->max_key, range->max_length);
11489 fputs("\n",DBUG_FILE);
11492 /* purecov: end */
11495 void QUICK_INDEX_MERGE_SELECT::dbug_dump(int indent, bool verbose)
11497 List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
11498 QUICK_RANGE_SELECT *quick;
11499 fprintf(DBUG_FILE, "%*squick index_merge select\n", indent, "");
11500 fprintf(DBUG_FILE, "%*smerged scans {\n", indent, "");
11501 while ((quick= it++))
11502 quick->dbug_dump(indent+2, verbose);
11503 if (pk_quick_select)
11505 fprintf(DBUG_FILE, "%*sclustered PK quick:\n", indent, "");
11506 pk_quick_select->dbug_dump(indent+2, verbose);
11508 fprintf(DBUG_FILE, "%*s}\n", indent, "");
11511 void QUICK_ROR_INTERSECT_SELECT::dbug_dump(int indent, bool verbose)
11513 List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
11514 QUICK_RANGE_SELECT *quick;
11515 fprintf(DBUG_FILE, "%*squick ROR-intersect select, %scovering\n",
11516 indent, "", need_to_fetch_row? "":"non-");
11517 fprintf(DBUG_FILE, "%*smerged scans {\n", indent, "");
11518 while ((quick= it++))
11519 quick->dbug_dump(indent+2, verbose);
11520 if (cpk_quick)
11522 fprintf(DBUG_FILE, "%*sclustered PK quick:\n", indent, "");
11523 cpk_quick->dbug_dump(indent+2, verbose);
11525 fprintf(DBUG_FILE, "%*s}\n", indent, "");
11528 void QUICK_ROR_UNION_SELECT::dbug_dump(int indent, bool verbose)
11530 List_iterator_fast<QUICK_SELECT_I> it(quick_selects);
11531 QUICK_SELECT_I *quick;
11532 fprintf(DBUG_FILE, "%*squick ROR-union select\n", indent, "");
11533 fprintf(DBUG_FILE, "%*smerged scans {\n", indent, "");
11534 while ((quick= it++))
11535 quick->dbug_dump(indent+2, verbose);
11536 fprintf(DBUG_FILE, "%*s}\n", indent, "");
11541 Print quick select information to DBUG_FILE.
11543 SYNOPSIS
11544 QUICK_GROUP_MIN_MAX_SELECT::dbug_dump()
11545 indent Indentation offset
11546 verbose If TRUE show more detailed output.
11548 DESCRIPTION
11549 Print the contents of this quick select to DBUG_FILE. The method also
11550 calls dbug_dump() for the used quick select if any.
11552 IMPLEMENTATION
11553 Caller is responsible for locking DBUG_FILE before this call and unlocking
11554 it afterwards.
11556 RETURN
11557 None
11560 void QUICK_GROUP_MIN_MAX_SELECT::dbug_dump(int indent, bool verbose)
11562 fprintf(DBUG_FILE,
11563 "%*squick_group_min_max_select: index %s (%d), length: %d\n",
11564 indent, "", index_info->name, index, max_used_key_length);
11565 if (key_infix_len > 0)
11567 fprintf(DBUG_FILE, "%*susing key_infix with length %d:\n",
11568 indent, "", key_infix_len);
11570 if (quick_prefix_select)
11572 fprintf(DBUG_FILE, "%*susing quick_range_select:\n", indent, "");
11573 quick_prefix_select->dbug_dump(indent + 2, verbose);
11575 if (min_max_ranges.elements > 0)
11577 fprintf(DBUG_FILE, "%*susing %d quick_ranges for MIN/MAX:\n",
11578 indent, "", min_max_ranges.elements);
11583 #endif /* NOT_USED */
11585 /*****************************************************************************
11586 ** Instantiate templates
11587 *****************************************************************************/
11589 #ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
11590 template class List<QUICK_RANGE>;
11591 template class List_iterator<QUICK_RANGE>;
11592 #endif