~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 2000-2006 MySQL AB
2
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.
6
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.
11
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
16
/*
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:
20
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);
22
23
*/
24
25
/*
26
  This file contains:
27
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
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
1 by brian
clean slate
32
    intervals.
33
    The entry point for the range analysis module is get_mm_tree() function.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
34
1 by brian
clean slate
35
    The lists are returned in form of complicated structure of interlinked
36
    SEL_TREE/SEL_IMERGE/SEL_ARG objects.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
37
    See quick_range_seq_next, find_used_partitions for examples of how to walk
1 by brian
clean slate
38
    this structure.
39
    All direct "users" of this module are located within this file, too.
40
41
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.
47
48
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
49
  Range/index_merge/groupby-minmax optimizer module
50
    A module that accepts a table, condition, and returns
1 by brian
clean slate
51
     - a QUICK_*_SELECT object that can be used to retrieve rows that match
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
52
       the specified condition, or a "no records will match the condition"
1 by brian
clean slate
53
       statement.
54
55
    The module entry points are
56
      test_quick_select()
57
      get_quick_select_for_ref()
58
59
60
  Record retrieval code for range/index_merge/groupby-min-max.
61
    Implementations of QUICK_*_SELECT classes.
62
63
  KeyTupleFormat
64
  ~~~~~~~~~~~~~~
65
  The code in this file (and elsewhere) makes operations on key value tuples.
66
  Those tuples are stored in the following format:
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
67
1 by brian
clean slate
68
  The tuple is a sequence of key part values. The length of key part value
69
  depends only on its type (and not depends on the what value is stored)
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
70
1 by brian
clean slate
71
    KeyTuple: keypart1-data, keypart2-data, ...
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
72
1 by brian
clean slate
73
  The value of each keypart is stored in the following format:
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
74
1 by brian
clean slate
75
    keypart_data: [isnull_byte] keypart-value-bytes
76
77
  If a keypart may have a NULL value (key_part->field->real_maybe_null() can
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
78
  be used to check this), then the first byte is a NULL indicator with the
1 by brian
clean slate
79
  following valid values:
80
    1  - keypart has NULL value.
81
    0  - keypart has non-NULL value.
82
83
  <questionable-statement> If isnull_byte==1 (NULL value), then the following
84
  keypart->length bytes must be 0.
85
  </questionable-statement>
86
87
  keypart-value-bytes holds the value. Its format depends on the field type.
88
  The length of keypart-value-bytes may or may not depend on the value being
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
89
  stored. The default is that length is static and equal to
1 by brian
clean slate
90
  KEY_PART_INFO::length.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
91
92
  Key parts with (key_part_flag & HA_BLOB_PART) have length depending of the
1 by brian
clean slate
93
  value:
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
94
1 by brian
clean slate
95
     keypart-value-bytes: value_length value_bytes
96
97
  The value_length part itself occupies HA_KEY_BLOB_LENGTH=2 bytes.
98
99
  See key_copy() and key_restore() for code to move data between index tuple
100
  and table record
101
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
102
  CAUTION: the above description is only sergefp's understanding of the
1 by brian
clean slate
103
           subject and may omit some details.
104
*/
105
243.1.17 by Jay Pipes
FINAL PHASE removal of mysql_priv.h (Bye, bye my friend.)
106
#include <drizzled/server_includes.h>
107
#include <drizzled/sql_select.h>
550 by Monty Taylor
Moved error.h into just the files that need it.
108
#include <drizzled/error.h>
575.1.3 by Monty Taylor
Moved some stuff out of handler.h.
109
#include <drizzled/cost_vect.h>
584.4.7 by Monty Taylor
Removed a big bank of includes from item.h.
110
#include <drizzled/item/cmpfunc.h>
584.5.1 by Monty Taylor
Removed field includes from field.h.
111
#include <drizzled/field/num.h>
670.2.4 by Monty Taylor
Removed more stuff from the headers.
112
#include <drizzled/check_stack_overrun.h>
575.1.3 by Monty Taylor
Moved some stuff out of handler.h.
113
907.1.7 by Jay Pipes
Merged in remove-timezone work
114
#include "drizzled/temporal.h" /* Needed in get_mm_leaf() for timestamp -> datetime comparisons */
115
656.1.1 by Monty Taylor
OOOh doggie. Got rid of my_alloca.
116
#include <string>
572.1.4 by Monty Taylor
Removed a bunch of unusued tests and defines from autoconf.
117
656.1.1 by Monty Taylor
OOOh doggie. Got rid of my_alloca.
118
using namespace std;
1 by brian
clean slate
119
120
/*
121
  Convert double value to #rows. Currently this does floor(), and we
122
  might consider using round() instead.
123
*/
919.2.11 by Monty Taylor
Removed C99 isnan() usage, which allows us to remove the util/math.{cc,h} workarounds. Yay for standards!
124
static inline ha_rows double2rows(double x)
125
{
126
    return static_cast<ha_rows>(x);
127
}
1 by brian
clean slate
128
481 by Brian Aker
Remove all of uchar.
129
static int sel_cmp(Field *f,unsigned char *a,unsigned char *b,uint8_t a_flag,uint8_t b_flag);
1 by brian
clean slate
130
481 by Brian Aker
Remove all of uchar.
131
static unsigned char is_null_string[2]= {1,0};
1 by brian
clean slate
132
133
class RANGE_OPT_PARAM;
134
/*
135
  A construction block of the SEL_ARG-graph.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
136
137
  The following description only covers graphs of SEL_ARG objects with
1 by brian
clean slate
138
  sel_arg->type==KEY_RANGE:
139
140
  One SEL_ARG object represents an "elementary interval" in form
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
141
1 by brian
clean slate
142
      min_value <=?  table.keypartX  <=? max_value
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
143
1 by brian
clean slate
144
  The interval is a non-empty interval of any kind: with[out] minimum/maximum
145
  bound, [half]open/closed, single-point interval, etc.
146
147
  1. SEL_ARG GRAPH STRUCTURE
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
148
1 by brian
clean slate
149
  SEL_ARG objects are linked together in a graph. The meaning of the graph
150
  is better demostrated by an example:
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
151
1 by brian
clean slate
152
     tree->keys[i]
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
153
      |
1 by brian
clean slate
154
      |             $              $
155
      |    part=1   $     part=2   $    part=3
156
      |             $              $
157
      |  +-------+  $   +-------+  $   +--------+
158
      |  | kp1<1 |--$-->| kp2=5 |--$-->| kp3=10 |
159
      |  +-------+  $   +-------+  $   +--------+
160
      |      |      $              $       |
161
      |      |      $              $   +--------+
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
162
      |      |      $              $   | kp3=12 |
163
      |      |      $              $   +--------+
164
      |  +-------+  $              $
165
      \->| kp1=2 |--$--------------$-+
1 by brian
clean slate
166
         +-------+  $              $ |   +--------+
167
             |      $              $  ==>| kp3=11 |
168
         +-------+  $              $ |   +--------+
169
         | kp1=3 |--$--------------$-+       |
170
         +-------+  $              $     +--------+
171
             |      $              $     | kp3=14 |
172
            ...     $              $     +--------+
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
173
1 by brian
clean slate
174
  The entire graph is partitioned into "interval lists".
175
176
  An interval list is a sequence of ordered disjoint intervals over the same
177
  key part. SEL_ARG are linked via "next" and "prev" pointers. Additionally,
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
178
  all intervals in the list form an RB-tree, linked via left/right/parent
1 by brian
clean slate
179
  pointers. The RB-tree root SEL_ARG object will be further called "root of the
180
  interval list".
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
181
182
    In the example pic, there are 4 interval lists:
1 by brian
clean slate
183
    "kp<1 OR kp1=2 OR kp1=3", "kp2=5", "kp3=10 OR kp3=12", "kp3=11 OR kp3=13".
184
    The vertical lines represent SEL_ARG::next/prev pointers.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
185
1 by brian
clean slate
186
  In an interval list, each member X may have SEL_ARG::next_key_part pointer
187
  pointing to the root of another interval list Y. The pointed interval list
188
  must cover a key part with greater number (i.e. Y->part > X->part).
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
189
1 by brian
clean slate
190
    In the example pic, the next_key_part pointers are represented by
191
    horisontal lines.
192
193
  2. SEL_ARG GRAPH SEMANTICS
194
195
  It represents a condition in a special form (we don't have a name for it ATM)
196
  The SEL_ARG::next/prev is "OR", and next_key_part is "AND".
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
197
1 by brian
clean slate
198
  For example, the picture represents the condition in form:
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
199
   (kp1 < 1 AND kp2=5 AND (kp3=10 OR kp3=12)) OR
200
   (kp1=2 AND (kp3=11 OR kp3=14)) OR
1 by brian
clean slate
201
   (kp1=3 AND (kp3=11 OR kp3=14))
202
203
204
  3. SEL_ARG GRAPH USE
205
206
  Use get_mm_tree() to construct SEL_ARG graph from WHERE condition.
207
  Then walk the SEL_ARG graph and get a list of dijsoint ordered key
208
  intervals (i.e. intervals in form
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
209
1 by brian
clean slate
210
   (constA1, .., const1_K) < (keypart1,.., keypartK) < (constB1, .., constB_K)
211
212
  Those intervals can be used to access the index. The uses are in:
213
   - check_quick_select() - Walk the SEL_ARG graph and find an estimate of
214
                            how many table records are contained within all
215
                            intervals.
216
   - get_quick_select()   - Walk the SEL_ARG, materialize the key intervals,
217
                            and create QUICK_RANGE_SELECT object that will
218
                            read records within these intervals.
219
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
220
  4. SPACE COMPLEXITY NOTES
1 by brian
clean slate
221
222
    SEL_ARG graph is a representation of an ordered disjoint sequence of
223
    intervals over the ordered set of index tuple values.
224
225
    For multi-part keys, one can construct a WHERE expression such that its
226
    list of intervals will be of combinatorial size. Here is an example:
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
227
228
      (keypart1 IN (1,2, ..., n1)) AND
229
      (keypart2 IN (1,2, ..., n2)) AND
1 by brian
clean slate
230
      (keypart3 IN (1,2, ..., n3))
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
231
1 by brian
clean slate
232
    For this WHERE clause the list of intervals will have n1*n2*n3 intervals
233
    of form
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
234
1 by brian
clean slate
235
      (keypart1, keypart2, keypart3) = (k1, k2, k3), where 1 <= k{i} <= n{i}
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
236
1 by brian
clean slate
237
    SEL_ARG graph structure aims to reduce the amount of required space by
238
    "sharing" the elementary intervals when possible (the pic at the
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
239
    beginning of this comment has examples of such sharing). The sharing may
1 by brian
clean slate
240
    prevent combinatorial blowup:
241
242
      There are WHERE clauses that have combinatorial-size interval lists but
243
      will be represented by a compact SEL_ARG graph.
244
      Example:
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
245
        (keypartN IN (1,2, ..., n1)) AND
1 by brian
clean slate
246
        ...
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
247
        (keypart2 IN (1,2, ..., n2)) AND
1 by brian
clean slate
248
        (keypart1 IN (1,2, ..., n3))
249
250
    but not in all cases:
251
252
    - There are WHERE clauses that do have a compact SEL_ARG-graph
253
      representation but get_mm_tree() and its callees will construct a
254
      graph of combinatorial size.
255
      Example:
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
256
        (keypart1 IN (1,2, ..., n1)) AND
257
        (keypart2 IN (1,2, ..., n2)) AND
1 by brian
clean slate
258
        ...
259
        (keypartN IN (1,2, ..., n3))
260
261
    - There are WHERE clauses for which the minimal possible SEL_ARG graph
262
      representation will have combinatorial size.
263
      Example:
264
        By induction: Let's take any interval on some keypart in the middle:
265
266
           kp15=c0
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
267
1 by brian
clean slate
268
        Then let's AND it with this interval 'structure' from preceding and
269
        following keyparts:
270
271
          (kp14=c1 AND kp16=c3) OR keypart14=c2) (*)
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
272
1 by brian
clean slate
273
        We will obtain this SEL_ARG graph:
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
274
1 by brian
clean slate
275
             kp14     $      kp15      $      kp16
276
                      $                $
277
         +---------+  $   +---------+  $   +---------+
278
         | kp14=c1 |--$-->| kp15=c0 |--$-->| kp16=c3 |
279
         +---------+  $   +---------+  $   +---------+
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
280
              |       $                $
281
         +---------+  $   +---------+  $
282
         | kp14=c2 |--$-->| kp15=c0 |  $
283
         +---------+  $   +---------+  $
1 by brian
clean slate
284
                      $                $
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
285
1 by brian
clean slate
286
       Note that we had to duplicate "kp15=c0" and there was no way to avoid
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
287
       that.
1 by brian
clean slate
288
       The induction step: AND the obtained expression with another "wrapping"
289
       expression like (*).
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
290
       When the process ends because of the limit on max. number of keyparts
1 by brian
clean slate
291
       we'll have:
292
293
         WHERE clause length  is O(3*#max_keyparts)
294
         SEL_ARG graph size   is O(2^(#max_keyparts/2))
295
296
       (it is also possible to construct a case where instead of 2 in 2^n we
297
        have a bigger constant, e.g. 4, and get a graph with 4^(31/2)= 2^31
298
        nodes)
299
300
    We avoid consuming too much memory by setting a limit on the number of
301
    SEL_ARG object we can construct during one range analysis invocation.
302
*/
303
304
class SEL_ARG :public Sql_alloc
305
{
306
public:
206 by Brian Aker
Removed final uint dead types.
307
  uint8_t min_flag,max_flag,maybe_flag;
308
  uint8_t part;					// Which key part
309
  uint8_t maybe_null;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
310
  /*
1 by brian
clean slate
311
    Number of children of this element in the RB-tree, plus 1 for this
312
    element itself.
313
  */
206 by Brian Aker
Removed final uint dead types.
314
  uint16_t elements;
1 by brian
clean slate
315
  /*
316
    Valid only for elements which are RB-tree roots: Number of times this
317
    RB-tree is referred to (it is referred by SEL_ARG::next_key_part or by
318
    SEL_TREE::keys[i] or by a temporary SEL_ARG* variable)
319
  */
320
  ulong use_count;
321
322
  Field *field;
481 by Brian Aker
Remove all of uchar.
323
  unsigned char *min_value,*max_value;			// Pointer to range
1 by brian
clean slate
324
325
  /*
326
    eq_tree() requires that left == right == 0 if the type is MAYBE_KEY.
327
   */
328
  SEL_ARG *left,*right;   /* R-B tree children */
329
  SEL_ARG *next,*prev;    /* Links for bi-directional interval list */
330
  SEL_ARG *parent;        /* R-B tree parent */
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
331
  SEL_ARG *next_key_part;
1 by brian
clean slate
332
  enum leaf_color { BLACK,RED } color;
333
  enum Type { IMPOSSIBLE, MAYBE, MAYBE_KEY, KEY_RANGE } type;
334
335
  enum { MAX_SEL_ARGS = 16000 };
336
337
  SEL_ARG() {}
338
  SEL_ARG(SEL_ARG &);
481 by Brian Aker
Remove all of uchar.
339
  SEL_ARG(Field *,const unsigned char *, const unsigned char *);
340
  SEL_ARG(Field *field, uint8_t part, unsigned char *min_value, unsigned char *max_value,
206 by Brian Aker
Removed final uint dead types.
341
	  uint8_t min_flag, uint8_t max_flag, uint8_t maybe_flag);
1 by brian
clean slate
342
  SEL_ARG(enum Type type_arg)
343
    :min_flag(0),elements(1),use_count(1),left(0),right(0),next_key_part(0),
344
    color(BLACK), type(type_arg)
345
  {}
346
  inline bool is_same(SEL_ARG *arg)
347
  {
348
    if (type != arg->type || part != arg->part)
349
      return 0;
350
    if (type != KEY_RANGE)
351
      return 1;
352
    return cmp_min_to_min(arg) == 0 && cmp_max_to_max(arg) == 0;
353
  }
354
  inline void merge_flags(SEL_ARG *arg) { maybe_flag|=arg->maybe_flag; }
355
  inline void maybe_smaller() { maybe_flag=1; }
356
  /* Return true iff it's a single-point null interval */
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
357
  inline bool is_null_interval() { return maybe_null && max_value[0] == 1; }
1 by brian
clean slate
358
  inline int cmp_min_to_min(SEL_ARG* arg)
359
  {
360
    return sel_cmp(field,min_value, arg->min_value, min_flag, arg->min_flag);
361
  }
362
  inline int cmp_min_to_max(SEL_ARG* arg)
363
  {
364
    return sel_cmp(field,min_value, arg->max_value, min_flag, arg->max_flag);
365
  }
366
  inline int cmp_max_to_max(SEL_ARG* arg)
367
  {
368
    return sel_cmp(field,max_value, arg->max_value, max_flag, arg->max_flag);
369
  }
370
  inline int cmp_max_to_min(SEL_ARG* arg)
371
  {
372
    return sel_cmp(field,max_value, arg->min_value, max_flag, arg->min_flag);
373
  }
374
  SEL_ARG *clone_and(SEL_ARG* arg)
375
  {						// Get overlapping range
481 by Brian Aker
Remove all of uchar.
376
    unsigned char *new_min,*new_max;
206 by Brian Aker
Removed final uint dead types.
377
    uint8_t flag_min,flag_max;
1 by brian
clean slate
378
    if (cmp_min_to_min(arg) >= 0)
379
    {
380
      new_min=min_value; flag_min=min_flag;
381
    }
382
    else
383
    {
384
      new_min=arg->min_value; flag_min=arg->min_flag; /* purecov: deadcode */
385
    }
386
    if (cmp_max_to_max(arg) <= 0)
387
    {
388
      new_max=max_value; flag_max=max_flag;
389
    }
390
    else
391
    {
392
      new_max=arg->max_value; flag_max=arg->max_flag;
393
    }
394
    return new SEL_ARG(field, part, new_min, new_max, flag_min, flag_max,
395
		       test(maybe_flag && arg->maybe_flag));
396
  }
397
  SEL_ARG *clone_first(SEL_ARG *arg)
398
  {						// min <= X < arg->min
399
    return new SEL_ARG(field,part, min_value, arg->min_value,
400
		       min_flag, arg->min_flag & NEAR_MIN ? 0 : NEAR_MAX,
401
		       maybe_flag | arg->maybe_flag);
402
  }
403
  SEL_ARG *clone_last(SEL_ARG *arg)
404
  {						// min <= X <= key_max
405
    return new SEL_ARG(field, part, min_value, arg->max_value,
406
		       min_flag, arg->max_flag, maybe_flag | arg->maybe_flag);
407
  }
408
  SEL_ARG *clone(RANGE_OPT_PARAM *param, SEL_ARG *new_parent, SEL_ARG **next);
409
410
  bool copy_min(SEL_ARG* arg)
411
  {						// Get overlapping range
412
    if (cmp_min_to_min(arg) > 0)
413
    {
414
      min_value=arg->min_value; min_flag=arg->min_flag;
415
      if ((max_flag & (NO_MAX_RANGE | NO_MIN_RANGE)) ==
416
	  (NO_MAX_RANGE | NO_MIN_RANGE))
417
	return 1;				// Full range
418
    }
419
    maybe_flag|=arg->maybe_flag;
420
    return 0;
421
  }
422
  bool copy_max(SEL_ARG* arg)
423
  {						// Get overlapping range
424
    if (cmp_max_to_max(arg) <= 0)
425
    {
426
      max_value=arg->max_value; max_flag=arg->max_flag;
427
      if ((max_flag & (NO_MAX_RANGE | NO_MIN_RANGE)) ==
428
	  (NO_MAX_RANGE | NO_MIN_RANGE))
429
	return 1;				// Full range
430
    }
431
    maybe_flag|=arg->maybe_flag;
432
    return 0;
433
  }
434
435
  void copy_min_to_min(SEL_ARG *arg)
436
  {
437
    min_value=arg->min_value; min_flag=arg->min_flag;
438
  }
439
  void copy_min_to_max(SEL_ARG *arg)
440
  {
441
    max_value=arg->min_value;
442
    max_flag=arg->min_flag & NEAR_MIN ? 0 : NEAR_MAX;
443
  }
444
  void copy_max_to_min(SEL_ARG *arg)
445
  {
446
    min_value=arg->max_value;
447
    min_flag=arg->max_flag & NEAR_MAX ? 0 : NEAR_MIN;
448
  }
449
  /* returns a number of keypart values (0 or 1) appended to the key buffer */
482 by Brian Aker
Remove uint.
450
  int store_min(uint32_t length, unsigned char **min_key,uint32_t min_key_flag)
1 by brian
clean slate
451
  {
452
    /* "(kp1 > c1) AND (kp2 OP c2) AND ..." -> (kp1 > c1) */
453
    if ((!(min_flag & NO_MIN_RANGE) &&
454
	!(min_key_flag & (NO_MIN_RANGE | NEAR_MIN))))
455
    {
456
      if (maybe_null && *min_value)
457
      {
458
	**min_key=1;
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
459
	memset(*min_key+1, 0, length-1);
1 by brian
clean slate
460
      }
461
      else
462
	memcpy(*min_key,min_value,length);
463
      (*min_key)+= length;
464
      return 1;
465
    }
466
    return 0;
467
  }
468
  /* returns a number of keypart values (0 or 1) appended to the key buffer */
482 by Brian Aker
Remove uint.
469
  int store_max(uint32_t length, unsigned char **max_key, uint32_t max_key_flag)
1 by brian
clean slate
470
  {
471
    if (!(max_flag & NO_MAX_RANGE) &&
472
	!(max_key_flag & (NO_MAX_RANGE | NEAR_MAX)))
473
    {
474
      if (maybe_null && *max_value)
475
      {
476
	**max_key=1;
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
477
	memset(*max_key+1, 0, length-1);
1 by brian
clean slate
478
      }
479
      else
480
	memcpy(*max_key,max_value,length);
481
      (*max_key)+= length;
482
      return 1;
483
    }
484
    return 0;
485
  }
486
487
  /* returns a number of keypart values appended to the key buffer */
482 by Brian Aker
Remove uint.
488
  int store_min_key(KEY_PART *key, unsigned char **range_key, uint32_t *range_key_flag)
1 by brian
clean slate
489
  {
490
    SEL_ARG *key_tree= first();
482 by Brian Aker
Remove uint.
491
    uint32_t res= key_tree->store_min(key[key_tree->part].store_length,
1 by brian
clean slate
492
                                  range_key, *range_key_flag);
493
    *range_key_flag|= key_tree->min_flag;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
494
1 by brian
clean slate
495
    if (key_tree->next_key_part &&
496
	key_tree->next_key_part->part == key_tree->part+1 &&
497
	!(*range_key_flag & (NO_MIN_RANGE | NEAR_MIN)) &&
498
	key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
499
      res+= key_tree->next_key_part->store_min_key(key, range_key,
500
                                                   range_key_flag);
501
    return res;
502
  }
503
504
  /* returns a number of keypart values appended to the key buffer */
482 by Brian Aker
Remove uint.
505
  int store_max_key(KEY_PART *key, unsigned char **range_key, uint32_t *range_key_flag)
1 by brian
clean slate
506
  {
507
    SEL_ARG *key_tree= last();
482 by Brian Aker
Remove uint.
508
    uint32_t res=key_tree->store_max(key[key_tree->part].store_length,
1 by brian
clean slate
509
                                 range_key, *range_key_flag);
510
    (*range_key_flag)|= key_tree->max_flag;
511
    if (key_tree->next_key_part &&
512
	key_tree->next_key_part->part == key_tree->part+1 &&
513
	!(*range_key_flag & (NO_MAX_RANGE | NEAR_MAX)) &&
514
	key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
515
      res+= key_tree->next_key_part->store_max_key(key, range_key,
516
                                                   range_key_flag);
517
    return res;
518
  }
519
520
  SEL_ARG *insert(SEL_ARG *key);
521
  SEL_ARG *tree_delete(SEL_ARG *key);
522
  SEL_ARG *find_range(SEL_ARG *key);
523
  SEL_ARG *rb_insert(SEL_ARG *leaf);
524
  friend SEL_ARG *rb_delete_fixup(SEL_ARG *root,SEL_ARG *key, SEL_ARG *par);
525
#ifdef EXTRA_DEBUG
526
  friend int test_rb_tree(SEL_ARG *element,SEL_ARG *parent);
527
  void test_use_count(SEL_ARG *root);
528
#endif
529
  SEL_ARG *first();
530
  SEL_ARG *last();
531
  void make_root();
532
  inline bool simple_key()
533
  {
534
    return !next_key_part && elements == 1;
535
  }
536
  void increment_use_count(long count)
537
  {
538
    if (next_key_part)
539
    {
540
      next_key_part->use_count+=count;
541
      count*= (next_key_part->use_count-count);
542
      for (SEL_ARG *pos=next_key_part->first(); pos ; pos=pos->next)
543
	if (pos->next_key_part)
544
	  pos->increment_use_count(count);
545
    }
546
  }
547
  void free_tree()
548
  {
549
    for (SEL_ARG *pos=first(); pos ; pos=pos->next)
550
      if (pos->next_key_part)
551
      {
552
	pos->next_key_part->use_count--;
553
	pos->next_key_part->free_tree();
554
      }
555
  }
556
557
  inline SEL_ARG **parent_ptr()
558
  {
559
    return parent->left == this ? &parent->left : &parent->right;
560
  }
561
562
563
  /*
564
    Check if this SEL_ARG object represents a single-point interval
565
566
    SYNOPSIS
567
      is_singlepoint()
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
568
1 by brian
clean slate
569
    DESCRIPTION
570
      Check if this SEL_ARG object (not tree) represents a single-point
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
571
      interval, i.e. if it represents a "keypart = const" or
1 by brian
clean slate
572
      "keypart IS NULL".
573
574
    RETURN
55 by brian
Update for using real bool types.
575
      true   This SEL_ARG object represents a singlepoint interval
576
      false  Otherwise
1 by brian
clean slate
577
  */
578
579
  bool is_singlepoint()
580
  {
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
581
    /*
582
      Check for NEAR_MIN ("strictly less") and NO_MIN_RANGE (-inf < field)
1 by brian
clean slate
583
      flags, and the same for right edge.
584
    */
585
    if (min_flag || max_flag)
55 by brian
Update for using real bool types.
586
      return false;
481 by Brian Aker
Remove all of uchar.
587
    unsigned char *min_val= min_value;
588
    unsigned char *max_val= max_value;
1 by brian
clean slate
589
590
    if (maybe_null)
591
    {
592
      /* First byte is a NULL value indicator */
593
      if (*min_val != *max_val)
55 by brian
Update for using real bool types.
594
        return false;
1 by brian
clean slate
595
596
      if (*min_val)
55 by brian
Update for using real bool types.
597
        return true; /* This "x IS NULL" */
1 by brian
clean slate
598
      min_val++;
599
      max_val++;
600
    }
601
    return !field->key_cmp(min_val, max_val);
602
  }
603
  SEL_ARG *clone_tree(RANGE_OPT_PARAM *param);
604
};
605
606
class SEL_IMERGE;
607
608
609
class SEL_TREE :public Sql_alloc
610
{
611
public:
612
  /*
613
    Starting an effort to document this field:
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
614
    (for some i, keys[i]->type == SEL_ARG::IMPOSSIBLE) =>
1 by brian
clean slate
615
       (type == SEL_TREE::IMPOSSIBLE)
616
  */
617
  enum Type { IMPOSSIBLE, ALWAYS, MAYBE, KEY, KEY_SMALLER } type;
618
  SEL_TREE(enum Type type_arg) :type(type_arg) {}
619
  SEL_TREE() :type(KEY)
620
  {
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
621
    keys_map.reset();
212.6.6 by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove().
622
    memset(keys, 0, sizeof(keys));
1 by brian
clean slate
623
  }
624
  /*
625
    Note: there may exist SEL_TREE objects with sel_tree->type=KEY and
626
    keys[i]=0 for all i. (SergeyP: it is not clear whether there is any
627
    merit in range analyzer functions (e.g. get_mm_parts) returning a
628
    pointer to such SEL_TREE instead of NULL)
629
  */
630
  SEL_ARG *keys[MAX_KEY];
631
  key_map keys_map;        /* bitmask of non-NULL elements in keys */
632
633
  /*
634
    Possible ways to read rows using index_merge. The list is non-empty only
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
635
    if type==KEY. Currently can be non empty only if keys_map.none().
1 by brian
clean slate
636
  */
637
  List<SEL_IMERGE> merges;
638
639
  /* The members below are filled/used only after get_mm_tree is done */
640
  key_map ror_scans_map;   /* bitmask of ROR scan-able elements in keys */
482 by Brian Aker
Remove uint.
641
  uint32_t    n_ror_scans;     /* number of set bits in ror_scans_map */
1 by brian
clean slate
642
643
  struct st_ror_scan_info **ror_scans;     /* list of ROR key scans */
644
  struct st_ror_scan_info **ror_scans_end; /* last ROR scan */
645
  /* Note that #records for each key scan is stored in table->quick_rows */
646
};
647
648
class RANGE_OPT_PARAM
649
{
650
public:
520.1.22 by Brian Aker
Second pass of thd cleanup
651
  Session	*session;   /* Current thread handle */
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
652
  Table *table; /* Table being analyzed */
1 by brian
clean slate
653
  COND *cond;   /* Used inside get_mm_tree(). */
654
  table_map prev_tables;
655
  table_map read_tables;
656
  table_map current_table; /* Bit of the table being analyzed */
657
658
  /* Array of parts of all keys for which range analysis is performed */
659
  KEY_PART *key_parts;
660
  KEY_PART *key_parts_end;
661
  MEM_ROOT *mem_root; /* Memory that will be freed when range analysis completes */
662
  MEM_ROOT *old_root; /* Memory that will last until the query end */
663
  /*
664
    Number of indexes used in range analysis (In SEL_TREE::keys only first
665
    #keys elements are not empty)
666
  */
482 by Brian Aker
Remove uint.
667
  uint32_t keys;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
668
669
  /*
1 by brian
clean slate
670
    If true, the index descriptions describe real indexes (and it is ok to
671
    call field->optimize_range(real_keynr[...], ...).
672
    Otherwise index description describes fake indexes.
673
  */
674
  bool using_real_indexes;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
675
1 by brian
clean slate
676
  bool remove_jump_scans;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
677
1 by brian
clean slate
678
  /*
679
    used_key_no -> table_key_no translation table. Only makes sense if
55 by brian
Update for using real bool types.
680
    using_real_indexes==true
1 by brian
clean slate
681
  */
482 by Brian Aker
Remove uint.
682
  uint32_t real_keynr[MAX_KEY];
1 by brian
clean slate
683
  /* Number of SEL_ARG objects allocated by SEL_ARG::clone_tree operations */
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
684
  uint32_t alloced_sel_args;
1 by brian
clean slate
685
  bool force_default_mrr;
686
};
687
688
class PARAM : public RANGE_OPT_PARAM
689
{
690
public:
691
  KEY_PART *key[MAX_KEY]; /* First key parts of keys used in the query */
152 by Brian Aker
longlong replacement
692
  int64_t baseflag;
482 by Brian Aker
Remove uint.
693
  uint32_t max_key_part;
1 by brian
clean slate
694
  /* Number of ranges in the last checked tree->key */
482 by Brian Aker
Remove uint.
695
  uint32_t range_count;
481 by Brian Aker
Remove all of uchar.
696
  unsigned char min_key[MAX_KEY_LENGTH+MAX_FIELD_WIDTH],
1 by brian
clean slate
697
    max_key[MAX_KEY_LENGTH+MAX_FIELD_WIDTH];
698
  bool quick;				// Don't calulate possible keys
699
482 by Brian Aker
Remove uint.
700
  uint32_t fields_bitmap_size;
1005.2.3 by Monty Taylor
Further reversion of P.
701
  MY_BITMAP needed_fields;    /* bitmask of fields needed by the query */
702
  MY_BITMAP tmp_covered_fields;
1 by brian
clean slate
703
704
  key_map *needed_reg;        /* ptr to SQL_SELECT::needed_reg */
705
482 by Brian Aker
Remove uint.
706
  uint32_t *imerge_cost_buff;     /* buffer for index_merge cost estimates */
707
  uint32_t imerge_cost_buff_size; /* size of the buffer */
1 by brian
clean slate
708
55 by brian
Update for using real bool types.
709
  /* true if last checked tree->key can be used for ROR-scan */
1 by brian
clean slate
710
  bool is_ror_scan;
711
  /* Number of ranges in the last checked tree->key */
482 by Brian Aker
Remove uint.
712
  uint32_t n_ranges;
1 by brian
clean slate
713
};
714
715
class TABLE_READ_PLAN;
716
  class TRP_RANGE;
717
  class TRP_ROR_INTERSECT;
718
  class TRP_ROR_UNION;
719
  class TRP_ROR_INDEX_MERGE;
720
  class TRP_GROUP_MIN_MAX;
721
722
struct st_ror_scan_info;
723
724
static SEL_TREE * get_mm_parts(RANGE_OPT_PARAM *param,COND *cond_func,Field *field,
725
			       Item_func::Functype type,Item *value,
726
			       Item_result cmp_type);
727
static SEL_ARG *get_mm_leaf(RANGE_OPT_PARAM *param,COND *cond_func,Field *field,
728
			    KEY_PART *key_part,
729
			    Item_func::Functype type,Item *value);
730
static SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param,COND *cond);
731
482 by Brian Aker
Remove uint.
732
static bool is_key_scan_ror(PARAM *param, uint32_t keynr, uint8_t nparts);
733
static ha_rows check_quick_select(PARAM *param, uint32_t idx, bool index_only,
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
734
                                  SEL_ARG *tree, bool update_tbl_stats,
482 by Brian Aker
Remove uint.
735
                                  uint32_t *mrr_flags, uint32_t *bufsize,
1 by brian
clean slate
736
                                  COST_VECT *cost);
737
                                  //bool update_tbl_stats);
482 by Brian Aker
Remove uint.
738
/*static ha_rows check_quick_keys(PARAM *param,uint32_t index,SEL_ARG *key_tree,
739
                                unsigned char *min_key, uint32_t min_key_flag, int,
740
                                unsigned char *max_key, uint32_t max_key_flag, int);
1 by brian
clean slate
741
*/
742
482 by Brian Aker
Remove uint.
743
QUICK_RANGE_SELECT *get_quick_select(PARAM *param,uint32_t index,
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
744
                                     SEL_ARG *key_tree, uint32_t mrr_flags,
482 by Brian Aker
Remove uint.
745
                                     uint32_t mrr_buf_size, MEM_ROOT *alloc);
1 by brian
clean slate
746
static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
747
                                       bool index_read_must_be_used,
748
                                       bool update_tbl_stats,
749
                                       double read_time);
750
static
751
TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree,
752
                                          double read_time,
753
                                          bool *are_all_covering);
754
static
755
TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param,
756
                                                   SEL_TREE *tree,
757
                                                   double read_time);
758
static
759
TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
760
                                         double read_time);
761
static
762
TRP_GROUP_MIN_MAX *get_best_group_min_max(PARAM *param, SEL_TREE *tree);
763
764
static void print_sel_tree(PARAM *param, SEL_TREE *tree, key_map *tree_map,
765
                           const char *msg);
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
766
static void print_ror_scans_arr(Table *table, const char *msg,
1 by brian
clean slate
767
                                struct st_ror_scan_info **start,
768
                                struct st_ror_scan_info **end);
769
770
static SEL_TREE *tree_and(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2);
771
static SEL_TREE *tree_or(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2);
772
static SEL_ARG *sel_add(SEL_ARG *key1,SEL_ARG *key2);
773
static SEL_ARG *key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2);
774
static SEL_ARG *key_and(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2,
482 by Brian Aker
Remove uint.
775
                        uint32_t clone_flag);
1 by brian
clean slate
776
static bool get_range(SEL_ARG **e1,SEL_ARG **e2,SEL_ARG *root1);
777
bool get_quick_keys(PARAM *param,QUICK_RANGE_SELECT *quick,KEY_PART *key,
482 by Brian Aker
Remove uint.
778
                    SEL_ARG *key_tree, unsigned char *min_key,uint32_t min_key_flag,
779
                    unsigned char *max_key,uint32_t max_key_flag);
1 by brian
clean slate
780
static bool eq_tree(SEL_ARG* a,SEL_ARG *b);
781
782
static SEL_ARG null_element(SEL_ARG::IMPOSSIBLE);
481 by Brian Aker
Remove all of uchar.
783
static bool null_part_in_key(KEY_PART *key_part, const unsigned char *key,
482 by Brian Aker
Remove uint.
784
                             uint32_t length);
1 by brian
clean slate
785
bool sel_trees_can_be_ored(SEL_TREE *tree1, SEL_TREE *tree2, RANGE_OPT_PARAM* param);
786
787
788
/*
789
  SEL_IMERGE is a list of possible ways to do index merge, i.e. it is
790
  a condition in the following form:
791
   (t_1||t_2||...||t_N) && (next)
792
793
  where all t_i are SEL_TREEs, next is another SEL_IMERGE and no pair
794
  (t_i,t_j) contains SEL_ARGS for the same index.
795
796
  SEL_TREE contained in SEL_IMERGE always has merges=NULL.
797
798
  This class relies on memory manager to do the cleanup.
799
*/
800
801
class SEL_IMERGE : public Sql_alloc
802
{
803
  enum { PREALLOCED_TREES= 10};
804
public:
805
  SEL_TREE *trees_prealloced[PREALLOCED_TREES];
806
  SEL_TREE **trees;             /* trees used to do index_merge   */
807
  SEL_TREE **trees_next;        /* last of these trees            */
808
  SEL_TREE **trees_end;         /* end of allocated space         */
809
810
  SEL_ARG  ***best_keys;        /* best keys to read in SEL_TREEs */
811
812
  SEL_IMERGE() :
813
    trees(&trees_prealloced[0]),
814
    trees_next(trees),
815
    trees_end(trees + PREALLOCED_TREES)
816
  {}
817
  int or_sel_tree(RANGE_OPT_PARAM *param, SEL_TREE *tree);
818
  int or_sel_tree_with_checks(RANGE_OPT_PARAM *param, SEL_TREE *new_tree);
819
  int or_sel_imerge_with_checks(RANGE_OPT_PARAM *param, SEL_IMERGE* imerge);
820
};
821
822
823
/*
824
  Add SEL_TREE to this index_merge without any checks,
825
826
  NOTES
827
    This function implements the following:
828
      (x_1||...||x_N) || t = (x_1||...||x_N||t), where x_i, t are SEL_TREEs
829
830
  RETURN
831
     0 - OK
832
    -1 - Out of memory.
833
*/
834
835
int SEL_IMERGE::or_sel_tree(RANGE_OPT_PARAM *param, SEL_TREE *tree)
836
{
837
  if (trees_next == trees_end)
838
  {
839
    const int realloc_ratio= 2;		/* Double size for next round */
482 by Brian Aker
Remove uint.
840
    uint32_t old_elements= (trees_end - trees);
841
    uint32_t old_size= sizeof(SEL_TREE**) * old_elements;
842
    uint32_t new_size= old_size * realloc_ratio;
1 by brian
clean slate
843
    SEL_TREE **new_trees;
844
    if (!(new_trees= (SEL_TREE**)alloc_root(param->mem_root, new_size)))
845
      return -1;
846
    memcpy(new_trees, trees, old_size);
847
    trees=      new_trees;
848
    trees_next= trees + old_elements;
849
    trees_end=  trees + old_elements * realloc_ratio;
850
  }
851
  *(trees_next++)= tree;
852
  return 0;
853
}
854
855
856
/*
857
  Perform OR operation on this SEL_IMERGE and supplied SEL_TREE new_tree,
858
  combining new_tree with one of the trees in this SEL_IMERGE if they both
859
  have SEL_ARGs for the same key.
860
861
  SYNOPSIS
862
    or_sel_tree_with_checks()
863
      param    PARAM from SQL_SELECT::test_quick_select
864
      new_tree SEL_TREE with type KEY or KEY_SMALLER.
865
866
  NOTES
867
    This does the following:
868
    (t_1||...||t_k)||new_tree =
869
     either
870
       = (t_1||...||t_k||new_tree)
871
     or
872
       = (t_1||....||(t_j|| new_tree)||...||t_k),
873
874
     where t_i, y are SEL_TREEs.
875
    new_tree is combined with the first t_j it has a SEL_ARG on common
876
    key with. As a consequence of this, choice of keys to do index_merge
877
    read may depend on the order of conditions in WHERE part of the query.
878
879
  RETURN
880
    0  OK
881
    1  One of the trees was combined with new_tree to SEL_TREE::ALWAYS,
882
       and (*this) should be discarded.
883
   -1  An error occurred.
884
*/
885
886
int SEL_IMERGE::or_sel_tree_with_checks(RANGE_OPT_PARAM *param, SEL_TREE *new_tree)
887
{
888
  for (SEL_TREE** tree = trees;
889
       tree != trees_next;
890
       tree++)
891
  {
892
    if (sel_trees_can_be_ored(*tree, new_tree, param))
893
    {
894
      *tree = tree_or(param, *tree, new_tree);
895
      if (!*tree)
896
        return 1;
897
      if (((*tree)->type == SEL_TREE::MAYBE) ||
898
          ((*tree)->type == SEL_TREE::ALWAYS))
899
        return 1;
900
      /* SEL_TREE::IMPOSSIBLE is impossible here */
901
      return 0;
902
    }
903
  }
904
905
  /* New tree cannot be combined with any of existing trees. */
906
  return or_sel_tree(param, new_tree);
907
}
908
909
910
/*
911
  Perform OR operation on this index_merge and supplied index_merge list.
912
913
  RETURN
914
    0 - OK
55 by brian
Update for using real bool types.
915
    1 - One of conditions in result is always true and this SEL_IMERGE
1 by brian
clean slate
916
        should be discarded.
917
   -1 - An error occurred
918
*/
919
920
int SEL_IMERGE::or_sel_imerge_with_checks(RANGE_OPT_PARAM *param, SEL_IMERGE* imerge)
921
{
922
  for (SEL_TREE** tree= imerge->trees;
923
       tree != imerge->trees_next;
924
       tree++)
925
  {
926
    if (or_sel_tree_with_checks(param, *tree))
927
      return 1;
928
  }
929
  return 0;
930
}
931
932
933
/*
934
  Perform AND operation on two index_merge lists and store result in *im1.
935
*/
936
937
inline void imerge_list_and_list(List<SEL_IMERGE> *im1, List<SEL_IMERGE> *im2)
938
{
939
  im1->concat(im2);
940
}
941
942
943
/*
944
  Perform OR operation on 2 index_merge lists, storing result in first list.
945
946
  NOTES
947
    The following conversion is implemented:
948
     (a_1 &&...&& a_N)||(b_1 &&...&& b_K) = AND_i,j(a_i || b_j) =>
949
      => (a_1||b_1).
950
951
    i.e. all conjuncts except the first one are currently dropped.
952
    This is done to avoid producing N*K ways to do index_merge.
953
55 by brian
Update for using real bool types.
954
    If (a_1||b_1) produce a condition that is always true, NULL is returned
1 by brian
clean slate
955
    and index_merge is discarded (while it is actually possible to try
956
    harder).
957
958
    As a consequence of this, choice of keys to do index_merge read may depend
959
    on the order of conditions in WHERE part of the query.
960
961
  RETURN
962
    0     OK, result is stored in *im1
963
    other Error, both passed lists are unusable
964
*/
965
966
int imerge_list_or_list(RANGE_OPT_PARAM *param,
967
                        List<SEL_IMERGE> *im1,
968
                        List<SEL_IMERGE> *im2)
969
{
970
  SEL_IMERGE *imerge= im1->head();
971
  im1->empty();
972
  im1->push_back(imerge);
973
974
  return imerge->or_sel_imerge_with_checks(param, im2->head());
975
}
976
977
978
/*
979
  Perform OR operation on index_merge list and key tree.
980
981
  RETURN
982
    0     OK, result is stored in *im1.
983
    other Error
984
*/
985
986
int imerge_list_or_tree(RANGE_OPT_PARAM *param,
987
                        List<SEL_IMERGE> *im1,
988
                        SEL_TREE *tree)
989
{
990
  SEL_IMERGE *imerge;
991
  List_iterator<SEL_IMERGE> it(*im1);
992
  while ((imerge= it++))
993
  {
994
    if (imerge->or_sel_tree_with_checks(param, tree))
995
      it.remove();
996
  }
997
  return im1->is_empty();
998
}
999
1000
1001
/***************************************************************************
1002
** Basic functions for SQL_SELECT and QUICK_RANGE_SELECT
1003
***************************************************************************/
1004
1005
	/* make a select from mysql info
1006
	   Error is set as following:
1007
	   0 = ok
1008
	   1 = Got some error (out of memory?)
1009
	   */
1010
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
1011
SQL_SELECT *make_select(Table *head, table_map const_tables,
1 by brian
clean slate
1012
			table_map read_tables, COND *conds,
1013
                        bool allow_null_cond,
1014
                        int *error)
1015
{
1016
  SQL_SELECT *select;
1017
1018
  *error=0;
1019
1020
  if (!conds && !allow_null_cond)
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
1021
    return 0;
1 by brian
clean slate
1022
  if (!(select= new SQL_SELECT))
1023
  {
1024
    *error= 1;			// out of memory
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
1025
    return 0;		/* purecov: inspected */
1 by brian
clean slate
1026
  }
1027
  select->read_tables=read_tables;
1028
  select->const_tables=const_tables;
1029
  select->head=head;
1030
  select->cond=conds;
1031
1032
  if (head->sort.io_cache)
1033
  {
1034
    select->file= *head->sort.io_cache;
1035
    select->records=(ha_rows) (select->file.end_of_file/
1036
			       head->file->ref_length);
760.1.3 by Kristian Nielsen
Fix IO_CACHE memory handling, if we allocate with new, we must not
1037
    delete head->sort.io_cache;
1 by brian
clean slate
1038
    head->sort.io_cache=0;
1039
  }
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
1040
  return(select);
1 by brian
clean slate
1041
}
1042
1043
1044
SQL_SELECT::SQL_SELECT() :quick(0),cond(0),free_cond(0)
1045
{
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
1046
  quick_keys.reset(); 
1047
  needed_reg.reset();
1 by brian
clean slate
1048
  my_b_clear(&file);
1049
}
1050
1051
1052
void SQL_SELECT::cleanup()
1053
{
1054
  delete quick;
1055
  quick= 0;
1056
  if (free_cond)
1057
  {
1058
    free_cond=0;
1059
    delete cond;
1060
    cond= 0;
1061
  }
1062
  close_cached_file(&file);
1063
}
1064
1065
1066
SQL_SELECT::~SQL_SELECT()
1067
{
1068
  cleanup();
1069
}
1070
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
1071
1072
bool SQL_SELECT::check_quick(Session *session, bool force_quick_range,
1073
                             ha_rows limit)
1074
{
1075
  key_map tmp;
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
1076
  tmp.set();
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
1077
  return test_quick_select(session, tmp, 0, limit,
1078
                           force_quick_range, false) < 0;
1079
}
1080
1081
1082
bool SQL_SELECT::skip_record()
1083
{
1084
  return cond ? cond->val_int() == 0 : 0;
1085
}
1086
1087
1 by brian
clean slate
1088
QUICK_SELECT_I::QUICK_SELECT_I()
1089
  :max_used_key_length(0),
1090
   used_key_parts(0)
1091
{}
1092
520.1.22 by Brian Aker
Second pass of thd cleanup
1093
QUICK_RANGE_SELECT::QUICK_RANGE_SELECT(Session *session, Table *table, uint32_t key_nr,
1005.2.3 by Monty Taylor
Further reversion of P.
1094
                                       bool no_alloc, MEM_ROOT *parent_alloc,
1095
                                       bool *create_error)
1 by brian
clean slate
1096
  :free_file(0),cur_range(NULL),last_range(0),dont_free(0)
1097
{
1005.2.3 by Monty Taylor
Further reversion of P.
1098
  my_bitmap_map *bitmap;
1099
1 by brian
clean slate
1100
  in_ror_merged_scan= 0;
1101
  sorted= 0;
1102
  index= key_nr;
1103
  head=  table;
1104
  key_part_info= head->key_info[index].key_part;
1105
  my_init_dynamic_array(&ranges, sizeof(QUICK_RANGE*), 16, 16);
1106
520.1.22 by Brian Aker
Second pass of thd cleanup
1107
  /* 'session' is not accessible in QUICK_RANGE_SELECT::reset(). */
1108
  mrr_buf_size= session->variables.read_rnd_buff_size;
1 by brian
clean slate
1109
  mrr_buf_desc= NULL;
1110
1111
  if (!no_alloc && !parent_alloc)
1112
  {
1113
    // Allocates everything through the internal memroot
520.1.22 by Brian Aker
Second pass of thd cleanup
1114
    init_sql_alloc(&alloc, session->variables.range_alloc_block_size, 0);
1115
    session->mem_root= &alloc;
1 by brian
clean slate
1116
  }
1117
  else
212.6.6 by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove().
1118
    memset(&alloc, 0, sizeof(alloc));
1 by brian
clean slate
1119
  file= head->file;
1120
  record= head->record[0];
1121
  save_read_set= head->read_set;
1122
  save_write_set= head->write_set;
1123
1005.2.3 by Monty Taylor
Further reversion of P.
1124
  /* Allocate a bitmap for used columns (Q: why not on MEM_ROOT?) */
1125
  if (!(bitmap= (my_bitmap_map*) malloc(head->s->column_bitmap_size)))
1126
  {
1127
    column_bitmap.bitmap= 0;
1128
    *create_error= 1;
1129
  }
1130
  else
1014.2.12 by Monty Taylor
Removed the thread-safe crap in MY_BITMAP. Also remove the temp-pool option for
1131
    bitmap_init(&column_bitmap, bitmap, head->s->fields);
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
1132
  return;
1 by brian
clean slate
1133
}
1134
1135
1136
int QUICK_RANGE_SELECT::init()
1137
{
1138
  if (file->inited != handler::NONE)
1139
    file->ha_index_or_rnd_end();
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
1140
  return(file->ha_index_init(index, 1));
1 by brian
clean slate
1141
}
1142
1143
1144
void QUICK_RANGE_SELECT::range_end()
1145
{
1146
  if (file->inited != handler::NONE)
1147
    file->ha_index_or_rnd_end();
1148
}
1149
1150
1151
QUICK_RANGE_SELECT::~QUICK_RANGE_SELECT()
1152
{
1153
  if (!dont_free)
1154
  {
1155
    /* file is NULL for CPK scan on covering ROR-intersection */
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1156
    if (file)
1 by brian
clean slate
1157
    {
1158
      range_end();
1159
      if (head->key_read)
1160
      {
1161
        head->key_read= 0;
1162
        file->extra(HA_EXTRA_NO_KEYREAD);
1163
      }
1164
      if (free_file)
1165
      {
520.1.22 by Brian Aker
Second pass of thd cleanup
1166
        file->ha_external_lock(current_session, F_UNLCK);
1 by brian
clean slate
1167
        file->close();
1168
        delete file;
1169
      }
1170
    }
1171
    delete_dynamic(&ranges); /* ranges are allocated in alloc */
1172
    free_root(&alloc,MYF(0));
1005.2.3 by Monty Taylor
Further reversion of P.
1173
    free((char*) column_bitmap.bitmap);
1 by brian
clean slate
1174
  }
1175
  head->column_bitmaps_set(save_read_set, save_write_set);
460 by Monty Taylor
Removed x_free calls.
1176
  if (mrr_buf_desc)
1177
    free(mrr_buf_desc);
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
1178
  return;
1 by brian
clean slate
1179
}
1180
1181
520.1.22 by Brian Aker
Second pass of thd cleanup
1182
QUICK_INDEX_MERGE_SELECT::QUICK_INDEX_MERGE_SELECT(Session *session_param,
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
1183
                                                   Table *table)
520.1.22 by Brian Aker
Second pass of thd cleanup
1184
  :pk_quick_select(NULL), session(session_param)
1 by brian
clean slate
1185
{
1186
  index= MAX_KEY;
1187
  head= table;
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
1188
  memset(&read_record, 0, sizeof(read_record));
520.1.22 by Brian Aker
Second pass of thd cleanup
1189
  init_sql_alloc(&alloc, session->variables.range_alloc_block_size, 0);
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
1190
  return;
1 by brian
clean slate
1191
}
1192
1193
int QUICK_INDEX_MERGE_SELECT::init()
1194
{
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
1195
  return 0;
1 by brian
clean slate
1196
}
1197
1198
int QUICK_INDEX_MERGE_SELECT::reset()
1199
{
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
1200
  return(read_keys_and_merge());
1 by brian
clean slate
1201
}
1202
1203
bool
1204
QUICK_INDEX_MERGE_SELECT::push_quick_back(QUICK_RANGE_SELECT *quick_sel_range)
1205
{
1206
  /*
1207
    Save quick_select that does scan on clustered primary key as it will be
1208
    processed separately.
1209
  */
1210
  if (head->file->primary_key_is_clustered() &&
1211
      quick_sel_range->index == head->s->primary_key)
1212
    pk_quick_select= quick_sel_range;
1213
  else
1214
    return quick_selects.push_back(quick_sel_range);
1215
  return 0;
1216
}
1217
1218
QUICK_INDEX_MERGE_SELECT::~QUICK_INDEX_MERGE_SELECT()
1219
{
1220
  List_iterator_fast<QUICK_RANGE_SELECT> quick_it(quick_selects);
1221
  QUICK_RANGE_SELECT* quick;
1222
  quick_it.rewind();
1223
  while ((quick= quick_it++))
1224
    quick->file= NULL;
1225
  quick_selects.delete_elements();
1226
  delete pk_quick_select;
1227
  free_root(&alloc,MYF(0));
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
1228
  return;
1 by brian
clean slate
1229
}
1230
1231
520.1.22 by Brian Aker
Second pass of thd cleanup
1232
QUICK_ROR_INTERSECT_SELECT::QUICK_ROR_INTERSECT_SELECT(Session *session_param,
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
1233
                                                       Table *table,
1 by brian
clean slate
1234
                                                       bool retrieve_full_rows,
1235
                                                       MEM_ROOT *parent_alloc)
520.1.22 by Brian Aker
Second pass of thd cleanup
1236
  : cpk_quick(NULL), session(session_param), need_to_fetch_row(retrieve_full_rows),
55 by brian
Update for using real bool types.
1237
    scans_inited(false)
1 by brian
clean slate
1238
{
1239
  index= MAX_KEY;
1240
  head= table;
1241
  record= head->record[0];
1242
  if (!parent_alloc)
520.1.22 by Brian Aker
Second pass of thd cleanup
1243
    init_sql_alloc(&alloc, session->variables.range_alloc_block_size, 0);
1 by brian
clean slate
1244
  else
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
1245
    memset(&alloc, 0, sizeof(MEM_ROOT));
481 by Brian Aker
Remove all of uchar.
1246
  last_rowid= (unsigned char*) alloc_root(parent_alloc? parent_alloc : &alloc,
1 by brian
clean slate
1247
                                  head->file->ref_length);
1248
}
1249
1250
1251
/*
1252
  Do post-constructor initialization.
1253
  SYNOPSIS
1254
    QUICK_ROR_INTERSECT_SELECT::init()
1255
1256
  RETURN
1257
    0      OK
1258
    other  Error code
1259
*/
1260
1261
int QUICK_ROR_INTERSECT_SELECT::init()
1262
{
1263
 /* Check if last_rowid was successfully allocated in ctor */
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
1264
  return(!last_rowid);
1 by brian
clean slate
1265
}
1266
1267
1268
/*
1269
  Initialize this quick select to be a ROR-merged scan.
1270
1271
  SYNOPSIS
1272
    QUICK_RANGE_SELECT::init_ror_merged_scan()
55 by brian
Update for using real bool types.
1273
      reuse_handler If true, use head->file, otherwise create a separate
1 by brian
clean slate
1274
                    handler object
1275
1276
  NOTES
1277
    This function creates and prepares for subsequent use a separate handler
1278
    object if it can't reuse head->file. The reason for this is that during
1279
    ROR-merge several key scans are performed simultaneously, and a single
1280
    handler is only capable of preserving context of a single key scan.
1281
1282
    In ROR-merge the quick select doing merge does full records retrieval,
1283
    merged quick selects read only keys.
1284
1285
  RETURN
1286
    0  ROR child scan initialized, ok to use.
1287
    1  error
1288
*/
1289
1290
int QUICK_RANGE_SELECT::init_ror_merged_scan(bool reuse_handler)
1291
{
1292
  handler *save_file= file, *org_file;
520.1.22 by Brian Aker
Second pass of thd cleanup
1293
  Session *session;
1 by brian
clean slate
1294
1295
  in_ror_merged_scan= 1;
1296
  if (reuse_handler)
1297
  {
1298
    if (init() || reset())
1299
    {
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
1300
      return 0;
1 by brian
clean slate
1301
    }
1302
    head->column_bitmaps_set(&column_bitmap, &column_bitmap);
1303
    goto end;
1304
  }
1305
1306
  /* Create a separate handler object for this quick select */
1307
  if (free_file)
1308
  {
1309
    /* already have own 'handler' object. */
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
1310
    return 0;
1 by brian
clean slate
1311
  }
1312
520.1.22 by Brian Aker
Second pass of thd cleanup
1313
  session= head->in_use;
1314
  if (!(file= head->file->clone(session->mem_root)))
1 by brian
clean slate
1315
  {
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1316
    /*
1 by brian
clean slate
1317
      Manually set the error flag. Note: there seems to be quite a few
1318
      places where a failure could cause the server to "hang" the client by
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1319
      sending no response to a query. ATM those are not real errors because
1320
      the storage engine calls in question happen to never fail with the
1321
      existing storage engines.
1 by brian
clean slate
1322
    */
1323
    my_error(ER_OUT_OF_RESOURCES, MYF(0)); /* purecov: inspected */
1324
    /* Caller will free the memory */
1325
    goto failure;  /* purecov: inspected */
1326
  }
1327
1328
  head->column_bitmaps_set(&column_bitmap, &column_bitmap);
1329
520.1.22 by Brian Aker
Second pass of thd cleanup
1330
  if (file->ha_external_lock(session, F_RDLCK))
1 by brian
clean slate
1331
    goto failure;
1332
1333
  if (init() || reset())
1334
  {
520.1.22 by Brian Aker
Second pass of thd cleanup
1335
    file->ha_external_lock(session, F_UNLCK);
1 by brian
clean slate
1336
    file->close();
1337
    goto failure;
1338
  }
55 by brian
Update for using real bool types.
1339
  free_file= true;
1 by brian
clean slate
1340
  last_rowid= file->ref;
1341
1342
end:
1343
  /*
1344
    We are only going to read key fields and call position() on 'file'
1345
    The following sets head->tmp_set to only use this key and then updates
1346
    head->read_set and head->write_set to use this bitmap.
1347
    The now bitmap is stored in 'column_bitmap' which is used in ::get_next()
1348
  */
1349
  org_file= head->file;
1350
  head->file= file;
1351
  /* We don't have to set 'head->keyread' here as the 'file' is unique */
1352
  if (!head->no_keyread)
1353
  {
1354
    head->key_read= 1;
1355
    head->mark_columns_used_by_index(index);
1356
  }
1357
  head->prepare_for_position();
1358
  head->file= org_file;
1005.2.3 by Monty Taylor
Further reversion of P.
1359
  bitmap_copy(&column_bitmap, head->read_set);
1 by brian
clean slate
1360
  head->column_bitmaps_set(&column_bitmap, &column_bitmap);
1361
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
1362
  return 0;
1 by brian
clean slate
1363
1364
failure:
1365
  head->column_bitmaps_set(save_read_set, save_write_set);
1366
  delete file;
1367
  file= save_file;
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
1368
  return 0;
1 by brian
clean slate
1369
}
1370
1371
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
1372
void QUICK_RANGE_SELECT::save_last_pos()
1373
{
1374
  file->position(record);
1375
}
1376
1377
1 by brian
clean slate
1378
/*
1379
  Initialize this quick select to be a part of a ROR-merged scan.
1380
  SYNOPSIS
1381
    QUICK_ROR_INTERSECT_SELECT::init_ror_merged_scan()
55 by brian
Update for using real bool types.
1382
      reuse_handler If true, use head->file, otherwise create separate
1 by brian
clean slate
1383
                    handler object.
1384
  RETURN
1385
    0     OK
1386
    other error code
1387
*/
1388
int QUICK_ROR_INTERSECT_SELECT::init_ror_merged_scan(bool reuse_handler)
1389
{
1390
  List_iterator_fast<QUICK_RANGE_SELECT> quick_it(quick_selects);
1391
  QUICK_RANGE_SELECT* quick;
1392
1393
  /* Initialize all merged "children" quick selects */
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
1394
  assert(!need_to_fetch_row || reuse_handler);
1 by brian
clean slate
1395
  if (!need_to_fetch_row && reuse_handler)
1396
  {
1397
    quick= quick_it++;
1398
    /*
1399
      There is no use of this->file. Use it for the first of merged range
1400
      selects.
1401
    */
55 by brian
Update for using real bool types.
1402
    if (quick->init_ror_merged_scan(true))
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
1403
      return 0;
1 by brian
clean slate
1404
    quick->file->extra(HA_EXTRA_KEYREAD_PRESERVE_FIELDS);
1405
  }
1406
  while ((quick= quick_it++))
1407
  {
55 by brian
Update for using real bool types.
1408
    if (quick->init_ror_merged_scan(false))
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
1409
      return 0;
1 by brian
clean slate
1410
    quick->file->extra(HA_EXTRA_KEYREAD_PRESERVE_FIELDS);
1411
    /* All merged scans share the same record buffer in intersection. */
1412
    quick->record= head->record[0];
1413
  }
1414
1415
  if (need_to_fetch_row && head->file->ha_rnd_init(1))
1416
  {
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
1417
    return 0;
1 by brian
clean slate
1418
  }
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
1419
  return 0;
1 by brian
clean slate
1420
}
1421
1422
1423
/*
1424
  Initialize quick select for row retrieval.
1425
  SYNOPSIS
1426
    reset()
1427
  RETURN
1428
    0      OK
1429
    other  Error code
1430
*/
1431
1432
int QUICK_ROR_INTERSECT_SELECT::reset()
1433
{
55 by brian
Update for using real bool types.
1434
  if (!scans_inited && init_ror_merged_scan(true))
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
1435
    return 0;
55 by brian
Update for using real bool types.
1436
  scans_inited= true;
1 by brian
clean slate
1437
  List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
1438
  QUICK_RANGE_SELECT *quick;
1439
  while ((quick= it++))
1440
    quick->reset();
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
1441
  return 0;
1 by brian
clean slate
1442
}
1443
1444
1445
/*
1446
  Add a merged quick select to this ROR-intersection quick select.
1447
1448
  SYNOPSIS
1449
    QUICK_ROR_INTERSECT_SELECT::push_quick_back()
1450
      quick Quick select to be added. The quick select must return
1451
            rows in rowid order.
1452
  NOTES
1453
    This call can only be made before init() is called.
1454
1455
  RETURN
55 by brian
Update for using real bool types.
1456
    false OK
1457
    true  Out of memory.
1 by brian
clean slate
1458
*/
1459
1460
bool
1461
QUICK_ROR_INTERSECT_SELECT::push_quick_back(QUICK_RANGE_SELECT *quick)
1462
{
1463
  return quick_selects.push_back(quick);
1464
}
1465
1466
QUICK_ROR_INTERSECT_SELECT::~QUICK_ROR_INTERSECT_SELECT()
1467
{
1468
  quick_selects.delete_elements();
1469
  delete cpk_quick;
1470
  free_root(&alloc,MYF(0));
1471
  if (need_to_fetch_row && head->file->inited != handler::NONE)
1472
    head->file->ha_rnd_end();
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
1473
  return;
1 by brian
clean slate
1474
}
1475
1476
520.1.22 by Brian Aker
Second pass of thd cleanup
1477
QUICK_ROR_UNION_SELECT::QUICK_ROR_UNION_SELECT(Session *session_param,
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
1478
                                               Table *table)
520.1.22 by Brian Aker
Second pass of thd cleanup
1479
  : session(session_param), scans_inited(false)
1 by brian
clean slate
1480
{
1481
  index= MAX_KEY;
1482
  head= table;
1483
  rowid_length= table->file->ref_length;
1484
  record= head->record[0];
520.1.22 by Brian Aker
Second pass of thd cleanup
1485
  init_sql_alloc(&alloc, session->variables.range_alloc_block_size, 0);
1486
  session_param->mem_root= &alloc;
1 by brian
clean slate
1487
}
1488
957.1.6 by Padraig O'Sullivan
Fixed function object to ensure it correctly returns a boolean type since
1489
/*
1490
 * Function object that is used as the comparison function
1491
 * for the priority queue in the QUICK_ROR_UNION_SELECT
1492
 * class.
1493
 */
1494
class compare_functor
1495
{
1496
  QUICK_ROR_UNION_SELECT *self;
1497
  public:
1498
  compare_functor(QUICK_ROR_UNION_SELECT *in_arg)
1499
    : self(in_arg) { }
1500
  inline bool operator()(const QUICK_SELECT_I *i, const QUICK_SELECT_I *j) const
1501
  {
1502
    int val= self->head->file->cmp_ref(i->last_rowid,
1503
                                       j->last_rowid);
1504
    return (val >= 0);
1505
  }
1506
};
1 by brian
clean slate
1507
1508
/*
1509
  Do post-constructor initialization.
1510
  SYNOPSIS
1511
    QUICK_ROR_UNION_SELECT::init()
1512
1513
  RETURN
1514
    0      OK
1515
    other  Error code
1516
*/
1517
1518
int QUICK_ROR_UNION_SELECT::init()
1519
{
957.1.6 by Padraig O'Sullivan
Fixed function object to ensure it correctly returns a boolean type since
1520
  queue= 
1521
    new priority_queue<QUICK_SELECT_I *, vector<QUICK_SELECT_I *>, compare_functor >(compare_functor(this));
481 by Brian Aker
Remove all of uchar.
1522
  if (!(cur_rowid= (unsigned char*) alloc_root(&alloc, 2*head->file->ref_length)))
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
1523
    return 0;
1 by brian
clean slate
1524
  prev_rowid= cur_rowid + head->file->ref_length;
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
1525
  return 0;
1 by brian
clean slate
1526
}
1527
1528
1529
/*
1530
  Comparison function to be used QUICK_ROR_UNION_SELECT::queue priority
1531
  queue.
1532
1533
  SYNPOSIS
1534
    QUICK_ROR_UNION_SELECT::queue_cmp()
1535
      arg   Pointer to QUICK_ROR_UNION_SELECT
1536
      val1  First merged select
1537
      val2  Second merged select
1538
*/
1539
892.1.2 by Monty Taylor
Fixed solaris warnings.
1540
int quick_ror_union_select_queue_cmp(void *arg, unsigned char *val1, unsigned char *val2)
1 by brian
clean slate
1541
{
1542
  QUICK_ROR_UNION_SELECT *self= (QUICK_ROR_UNION_SELECT*)arg;
1543
  return self->head->file->cmp_ref(((QUICK_SELECT_I*)val1)->last_rowid,
1544
                                   ((QUICK_SELECT_I*)val2)->last_rowid);
1545
}
1546
1547
1548
/*
1549
  Initialize quick select for row retrieval.
1550
  SYNOPSIS
1551
    reset()
1552
1553
  RETURN
1554
    0      OK
1555
    other  Error code
1556
*/
1557
1558
int QUICK_ROR_UNION_SELECT::reset()
1559
{
1560
  QUICK_SELECT_I *quick;
1561
  int error;
55 by brian
Update for using real bool types.
1562
  have_prev_rowid= false;
1 by brian
clean slate
1563
  if (!scans_inited)
1564
  {
1565
    List_iterator_fast<QUICK_SELECT_I> it(quick_selects);
1566
    while ((quick= it++))
1567
    {
55 by brian
Update for using real bool types.
1568
      if (quick->init_ror_merged_scan(false))
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
1569
        return 0;
1 by brian
clean slate
1570
    }
55 by brian
Update for using real bool types.
1571
    scans_inited= true;
1 by brian
clean slate
1572
  }
957.1.6 by Padraig O'Sullivan
Fixed function object to ensure it correctly returns a boolean type since
1573
  while (!queue->empty())
1574
    queue->pop();
1 by brian
clean slate
1575
  /*
1576
    Initialize scans for merged quick selects and put all merged quick
1577
    selects into the queue.
1578
  */
1579
  List_iterator_fast<QUICK_SELECT_I> it(quick_selects);
1580
  while ((quick= it++))
1581
  {
1582
    if (quick->reset())
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
1583
      return 0;
1 by brian
clean slate
1584
    if ((error= quick->get_next()))
1585
    {
1586
      if (error == HA_ERR_END_OF_FILE)
1587
        continue;
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
1588
      return(error);
1 by brian
clean slate
1589
    }
1590
    quick->save_last_pos();
957.1.6 by Padraig O'Sullivan
Fixed function object to ensure it correctly returns a boolean type since
1591
    queue->push(quick);
1 by brian
clean slate
1592
  }
1593
1594
  if (head->file->ha_rnd_init(1))
1595
  {
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
1596
    return 0;
1 by brian
clean slate
1597
  }
1598
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
1599
  return 0;
1 by brian
clean slate
1600
}
1601
1602
1603
bool
1604
QUICK_ROR_UNION_SELECT::push_quick_back(QUICK_SELECT_I *quick_sel_range)
1605
{
1606
  return quick_selects.push_back(quick_sel_range);
1607
}
1608
1609
QUICK_ROR_UNION_SELECT::~QUICK_ROR_UNION_SELECT()
1610
{
957.1.6 by Padraig O'Sullivan
Fixed function object to ensure it correctly returns a boolean type since
1611
  while (!queue->empty())
1612
    queue->pop();
1613
  delete queue;
1 by brian
clean slate
1614
  quick_selects.delete_elements();
1615
  if (head->file->inited != handler::NONE)
1616
    head->file->ha_rnd_end();
1617
  free_root(&alloc,MYF(0));
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
1618
  return;
1 by brian
clean slate
1619
}
1620
1621
1622
QUICK_RANGE::QUICK_RANGE()
1623
  :min_key(0),max_key(0),min_length(0),max_length(0),
1624
   flag(NO_MIN_RANGE | NO_MAX_RANGE),
1625
  min_keypart_map(0), max_keypart_map(0)
1626
{}
1627
1628
SEL_ARG::SEL_ARG(SEL_ARG &arg) :Sql_alloc()
1629
{
1630
  type=arg.type;
1631
  min_flag=arg.min_flag;
1632
  max_flag=arg.max_flag;
1633
  maybe_flag=arg.maybe_flag;
1634
  maybe_null=arg.maybe_null;
1635
  part=arg.part;
1636
  field=arg.field;
1637
  min_value=arg.min_value;
1638
  max_value=arg.max_value;
1639
  next_key_part=arg.next_key_part;
1640
  use_count=1; elements=1;
1641
}
1642
1643
1644
inline void SEL_ARG::make_root()
1645
{
1646
  left=right= &null_element;
1647
  color=BLACK;
1648
  next=prev=0;
1649
  use_count=0; elements=1;
1650
}
1651
481 by Brian Aker
Remove all of uchar.
1652
SEL_ARG::SEL_ARG(Field *f,const unsigned char *min_value_arg,
1653
                 const unsigned char *max_value_arg)
1 by brian
clean slate
1654
  :min_flag(0), max_flag(0), maybe_flag(0), maybe_null(f->real_maybe_null()),
481 by Brian Aker
Remove all of uchar.
1655
   elements(1), use_count(1), field(f), min_value((unsigned char*) min_value_arg),
1656
   max_value((unsigned char*) max_value_arg), next(0),prev(0),
1 by brian
clean slate
1657
   next_key_part(0),color(BLACK),type(KEY_RANGE)
1658
{
1659
  left=right= &null_element;
1660
}
1661
206 by Brian Aker
Removed final uint dead types.
1662
SEL_ARG::SEL_ARG(Field *field_,uint8_t part_,
481 by Brian Aker
Remove all of uchar.
1663
                 unsigned char *min_value_, unsigned char *max_value_,
206 by Brian Aker
Removed final uint dead types.
1664
		 uint8_t min_flag_,uint8_t max_flag_,uint8_t maybe_flag_)
1 by brian
clean slate
1665
  :min_flag(min_flag_),max_flag(max_flag_),maybe_flag(maybe_flag_),
1666
   part(part_),maybe_null(field_->real_maybe_null()), elements(1),use_count(1),
1667
   field(field_), min_value(min_value_), max_value(max_value_),
1668
   next(0),prev(0),next_key_part(0),color(BLACK),type(KEY_RANGE)
1669
{
1670
  left=right= &null_element;
1671
}
1672
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1673
SEL_ARG *SEL_ARG::clone(RANGE_OPT_PARAM *param, SEL_ARG *new_parent,
1 by brian
clean slate
1674
                        SEL_ARG **next_arg)
1675
{
1676
  SEL_ARG *tmp;
1677
1678
  /* Bail out if we have already generated too many SEL_ARGs */
1679
  if (++param->alloced_sel_args > MAX_SEL_ARGS)
1680
    return 0;
1681
1682
  if (type != KEY_RANGE)
1683
  {
1684
    if (!(tmp= new (param->mem_root) SEL_ARG(type)))
1685
      return 0;					// out of memory
1686
    tmp->prev= *next_arg;			// Link into next/prev chain
1687
    (*next_arg)->next=tmp;
1688
    (*next_arg)= tmp;
1689
  }
1690
  else
1691
  {
1692
    if (!(tmp= new (param->mem_root) SEL_ARG(field,part, min_value,max_value,
1693
                                             min_flag, max_flag, maybe_flag)))
1694
      return 0;					// OOM
1695
    tmp->parent=new_parent;
1696
    tmp->next_key_part=next_key_part;
1697
    if (left != &null_element)
1698
      if (!(tmp->left=left->clone(param, tmp, next_arg)))
1699
	return 0;				// OOM
1700
1701
    tmp->prev= *next_arg;			// Link into next/prev chain
1702
    (*next_arg)->next=tmp;
1703
    (*next_arg)= tmp;
1704
1705
    if (right != &null_element)
1706
      if (!(tmp->right= right->clone(param, tmp, next_arg)))
1707
	return 0;				// OOM
1708
  }
1709
  increment_use_count(1);
1710
  tmp->color= color;
1711
  tmp->elements= this->elements;
1712
  return tmp;
1713
}
1714
1715
SEL_ARG *SEL_ARG::first()
1716
{
1717
  SEL_ARG *next_arg=this;
1718
  if (!next_arg->left)
1719
    return 0;					// MAYBE_KEY
1720
  while (next_arg->left != &null_element)
1721
    next_arg=next_arg->left;
1722
  return next_arg;
1723
}
1724
1725
SEL_ARG *SEL_ARG::last()
1726
{
1727
  SEL_ARG *next_arg=this;
1728
  if (!next_arg->right)
1729
    return 0;					// MAYBE_KEY
1730
  while (next_arg->right != &null_element)
1731
    next_arg=next_arg->right;
1732
  return next_arg;
1733
}
1734
1735
1736
/*
1737
  Check if a compare is ok, when one takes ranges in account
1738
  Returns -2 or 2 if the ranges where 'joined' like  < 2 and >= 2
1739
*/
1740
481 by Brian Aker
Remove all of uchar.
1741
static int sel_cmp(Field *field, unsigned char *a, unsigned char *b, uint8_t a_flag,
206 by Brian Aker
Removed final uint dead types.
1742
                   uint8_t b_flag)
1 by brian
clean slate
1743
{
1744
  int cmp;
1745
  /* First check if there was a compare to a min or max element */
1746
  if (a_flag & (NO_MIN_RANGE | NO_MAX_RANGE))
1747
  {
1748
    if ((a_flag & (NO_MIN_RANGE | NO_MAX_RANGE)) ==
1749
	(b_flag & (NO_MIN_RANGE | NO_MAX_RANGE)))
1750
      return 0;
1751
    return (a_flag & NO_MIN_RANGE) ? -1 : 1;
1752
  }
1753
  if (b_flag & (NO_MIN_RANGE | NO_MAX_RANGE))
1754
    return (b_flag & NO_MIN_RANGE) ? 1 : -1;
1755
1756
  if (field->real_maybe_null())			// If null is part of key
1757
  {
1758
    if (*a != *b)
1759
    {
1760
      return *a ? -1 : 1;
1761
    }
1762
    if (*a)
1763
      goto end;					// NULL where equal
1764
    a++; b++;					// Skip NULL marker
1765
  }
1766
  cmp=field->key_cmp(a , b);
1767
  if (cmp) return cmp < 0 ? -1 : 1;		// The values differed
1768
1769
  // Check if the compared equal arguments was defined with open/closed range
1770
 end:
1771
  if (a_flag & (NEAR_MIN | NEAR_MAX))
1772
  {
1773
    if ((a_flag & (NEAR_MIN | NEAR_MAX)) == (b_flag & (NEAR_MIN | NEAR_MAX)))
1774
      return 0;
1775
    if (!(b_flag & (NEAR_MIN | NEAR_MAX)))
1776
      return (a_flag & NEAR_MIN) ? 2 : -2;
1777
    return (a_flag & NEAR_MIN) ? 1 : -1;
1778
  }
1779
  if (b_flag & (NEAR_MIN | NEAR_MAX))
1780
    return (b_flag & NEAR_MIN) ? -2 : 2;
1781
  return 0;					// The elements where equal
1782
}
1783
1784
1785
SEL_ARG *SEL_ARG::clone_tree(RANGE_OPT_PARAM *param)
1786
{
1787
  SEL_ARG tmp_link,*next_arg,*root;
1788
  next_arg= &tmp_link;
1789
  if (!(root= clone(param, (SEL_ARG *) 0, &next_arg)))
1790
    return 0;
1791
  next_arg->next=0;				// Fix last link
1792
  tmp_link.next->prev=0;			// Fix first link
1793
  if (root)					// If not OOM
1794
    root->use_count= 0;
1795
  return root;
1796
}
1797
1798
1799
/*
1800
  Find the best index to retrieve first N records in given order
1801
1802
  SYNOPSIS
1803
    get_index_for_order()
1804
      table  Table to be accessed
1805
      order  Required ordering
1806
      limit  Number of records that will be retrieved
1807
1808
  DESCRIPTION
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1809
    Find the best index that allows to retrieve first #limit records in the
1 by brian
clean slate
1810
    given order cheaper then one would retrieve them using full table scan.
1811
1812
  IMPLEMENTATION
1813
    Run through all table indexes and find the shortest index that allows
1814
    records to be retrieved in given order. We look for the shortest index
1815
    as we will have fewer index pages to read with it.
1816
1817
    This function is used only by UPDATE/DELETE, so we take into account how
1818
    the UPDATE/DELETE code will work:
1819
     * index can only be scanned in forward direction
1820
     * HA_EXTRA_KEYREAD will not be used
1821
    Perhaps these assumptions could be relaxed.
1822
1823
  RETURN
1824
    Number of the index that produces the required ordering in the cheapest way
1825
    MAX_KEY if no such index was found.
1826
*/
1827
482 by Brian Aker
Remove uint.
1828
uint32_t get_index_for_order(Table *table, order_st *order, ha_rows limit)
1 by brian
clean slate
1829
{
482 by Brian Aker
Remove uint.
1830
  uint32_t idx;
1831
  uint32_t match_key= MAX_KEY, match_key_len= MAX_KEY_LENGTH + 1;
327.2.3 by Brian Aker
Refactoring of class Table
1832
  order_st *ord;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1833
1 by brian
clean slate
1834
  for (ord= order; ord; ord= ord->next)
1835
    if (!ord->asc)
1836
      return MAX_KEY;
1837
1838
  for (idx= 0; idx < table->s->keys; idx++)
1839
  {
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
1840
    if (!(table->keys_in_use_for_query.test(idx)))
1 by brian
clean slate
1841
      continue;
1842
    KEY_PART_INFO *keyinfo= table->key_info[idx].key_part;
482 by Brian Aker
Remove uint.
1843
    uint32_t n_parts=  table->key_info[idx].key_parts;
1844
    uint32_t partno= 0;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1845
1846
    /*
1847
      The below check is sufficient considering we now have either BTREE
1848
      indexes (records are returned in order for any index prefix) or HASH
1 by brian
clean slate
1849
      indexes (records are not returned in order for any index prefix).
1850
    */
1851
    if (!(table->file->index_flags(idx, 0, 1) & HA_READ_ORDER))
1852
      continue;
1853
    for (ord= order; ord && partno < n_parts; ord= ord->next, partno++)
1854
    {
1855
      Item *item= order->item[0];
1856
      if (!(item->type() == Item::FIELD_ITEM &&
1857
           ((Item_field*)item)->field->eq(keyinfo[partno].field)))
1858
        break;
1859
    }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1860
1 by brian
clean slate
1861
    if (!ord && table->key_info[idx].key_length < match_key_len)
1862
    {
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1863
      /*
1 by brian
clean slate
1864
        Ok, the ordering is compatible and this key is shorter then
1865
        previous match (we want shorter keys as we'll have to read fewer
1866
        index pages for the same number of records)
1867
      */
1868
      match_key= idx;
1869
      match_key_len= table->key_info[idx].key_length;
1870
    }
1871
  }
1872
1873
  if (match_key != MAX_KEY)
1874
  {
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1875
    /*
1876
      Found an index that allows records to be retrieved in the requested
1 by brian
clean slate
1877
      order. Now we'll check if using the index is cheaper then doing a table
1878
      scan.
1879
    */
1880
    double full_scan_time= table->file->scan_time();
1881
    double index_scan_time= table->file->read_time(match_key, 1, limit);
1882
    if (index_scan_time > full_scan_time)
1883
      match_key= MAX_KEY;
1884
  }
1885
  return match_key;
1886
}
1887
1888
1889
/*
1890
  Table rows retrieval plan. Range optimizer creates QUICK_SELECT_I-derived
1891
  objects from table read plans.
1892
*/
1893
class TABLE_READ_PLAN
1894
{
1895
public:
1896
  /*
1897
    Plan read cost, with or without cost of full row retrieval, depending
1898
    on plan creation parameters.
1899
  */
1900
  double read_cost;
1901
  ha_rows records; /* estimate of #rows to be examined */
1902
1903
  /*
55 by brian
Update for using real bool types.
1904
    If true, the scan returns rows in rowid order. This is used only for
1 by brian
clean slate
1905
    scans that can be both ROR and non-ROR.
1906
  */
1907
  bool is_ror;
1908
1909
  /*
1910
    Create quick select for this plan.
1911
    SYNOPSIS
1912
     make_quick()
1913
       param               Parameter from test_quick_select
55 by brian
Update for using real bool types.
1914
       retrieve_full_rows  If true, created quick select will do full record
1 by brian
clean slate
1915
                           retrieval.
1916
       parent_alloc        Memory pool to use, if any.
1917
1918
    NOTES
1919
      retrieve_full_rows is ignored by some implementations.
1920
1921
    RETURN
1922
      created quick select
1923
      NULL on any error.
1924
  */
1925
  virtual QUICK_SELECT_I *make_quick(PARAM *param,
1926
                                     bool retrieve_full_rows,
1927
                                     MEM_ROOT *parent_alloc=NULL) = 0;
1928
1929
  /* Table read plans are allocated on MEM_ROOT and are never deleted */
1930
  static void *operator new(size_t size, MEM_ROOT *mem_root)
895 by Brian Aker
Completion (?) of uint conversion.
1931
  { return (void*) alloc_root(mem_root, (uint32_t) size); }
655 by Brian Aker
Yet more unused.... damn annoying... (also tossed some prototypes that were
1932
  static void operator delete(void *, size_t)
77.1.46 by Monty Taylor
Finished the warnings work!
1933
    { TRASH(ptr, size); }
655 by Brian Aker
Yet more unused.... damn annoying... (also tossed some prototypes that were
1934
  static void operator delete(void *, MEM_ROOT *)
77.1.46 by Monty Taylor
Finished the warnings work!
1935
    { /* Never called */ }
1 by brian
clean slate
1936
  virtual ~TABLE_READ_PLAN() {}               /* Remove gcc warning */
1937
1938
};
1939
1940
class TRP_ROR_INTERSECT;
1941
class TRP_ROR_UNION;
1942
class TRP_INDEX_MERGE;
1943
1944
1945
/*
1946
  Plan for a QUICK_RANGE_SELECT scan.
1947
  TRP_RANGE::make_quick ignores retrieve_full_rows parameter because
1948
  QUICK_RANGE_SELECT doesn't distinguish between 'index only' scans and full
1949
  record retrieval scans.
1950
*/
1951
1952
class TRP_RANGE : public TABLE_READ_PLAN
1953
{
1954
public:
1955
  SEL_ARG *key; /* set of intervals to be used in "range" method retrieval */
482 by Brian Aker
Remove uint.
1956
  uint32_t     key_idx; /* key number in PARAM::key */
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1957
  uint32_t     mrr_flags;
482 by Brian Aker
Remove uint.
1958
  uint32_t     mrr_buf_size;
1 by brian
clean slate
1959
482 by Brian Aker
Remove uint.
1960
  TRP_RANGE(SEL_ARG *key_arg, uint32_t idx_arg, uint32_t mrr_flags_arg)
1 by brian
clean slate
1961
   : key(key_arg), key_idx(idx_arg), mrr_flags(mrr_flags_arg)
1962
  {}
1963
  virtual ~TRP_RANGE() {}                     /* Remove gcc warning */
1964
655 by Brian Aker
Yet more unused.... damn annoying... (also tossed some prototypes that were
1965
  QUICK_SELECT_I *make_quick(PARAM *param, bool, MEM_ROOT *parent_alloc)
1 by brian
clean slate
1966
  {
1967
    QUICK_RANGE_SELECT *quick;
1968
    if ((quick= get_quick_select(param, key_idx, key, mrr_flags, mrr_buf_size,
1969
                                 parent_alloc)))
1970
    {
1971
      quick->records= records;
1972
      quick->read_time= read_cost;
1973
    }
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
1974
    return quick;
1 by brian
clean slate
1975
  }
1976
};
1977
1978
1979
/* Plan for QUICK_ROR_INTERSECT_SELECT scan. */
1980
1981
class TRP_ROR_INTERSECT : public TABLE_READ_PLAN
1982
{
1983
public:
1984
  TRP_ROR_INTERSECT() {}                      /* Remove gcc warning */
1985
  virtual ~TRP_ROR_INTERSECT() {}             /* Remove gcc warning */
1986
  QUICK_SELECT_I *make_quick(PARAM *param, bool retrieve_full_rows,
1987
                             MEM_ROOT *parent_alloc);
1988
1989
  /* Array of pointers to ROR range scans used in this intersection */
1990
  struct st_ror_scan_info **first_scan;
1991
  struct st_ror_scan_info **last_scan; /* End of the above array */
1992
  struct st_ror_scan_info *cpk_scan;  /* Clustered PK scan, if there is one */
55 by brian
Update for using real bool types.
1993
  bool is_covering; /* true if no row retrieval phase is necessary */
1 by brian
clean slate
1994
  double index_scan_costs; /* SUM(cost(index_scan)) */
1995
};
1996
1997
1998
/*
1999
  Plan for QUICK_ROR_UNION_SELECT scan.
2000
  QUICK_ROR_UNION_SELECT always retrieves full rows, so retrieve_full_rows
2001
  is ignored by make_quick.
2002
*/
2003
2004
class TRP_ROR_UNION : public TABLE_READ_PLAN
2005
{
2006
public:
2007
  TRP_ROR_UNION() {}                          /* Remove gcc warning */
2008
  virtual ~TRP_ROR_UNION() {}                 /* Remove gcc warning */
2009
  QUICK_SELECT_I *make_quick(PARAM *param, bool retrieve_full_rows,
2010
                             MEM_ROOT *parent_alloc);
2011
  TABLE_READ_PLAN **first_ror; /* array of ptrs to plans for merged scans */
2012
  TABLE_READ_PLAN **last_ror;  /* end of the above array */
2013
};
2014
2015
2016
/*
2017
  Plan for QUICK_INDEX_MERGE_SELECT scan.
2018
  QUICK_ROR_INTERSECT_SELECT always retrieves full rows, so retrieve_full_rows
2019
  is ignored by make_quick.
2020
*/
2021
2022
class TRP_INDEX_MERGE : public TABLE_READ_PLAN
2023
{
2024
public:
2025
  TRP_INDEX_MERGE() {}                        /* Remove gcc warning */
2026
  virtual ~TRP_INDEX_MERGE() {}               /* Remove gcc warning */
2027
  QUICK_SELECT_I *make_quick(PARAM *param, bool retrieve_full_rows,
2028
                             MEM_ROOT *parent_alloc);
2029
  TRP_RANGE **range_scans; /* array of ptrs to plans of merged scans */
2030
  TRP_RANGE **range_scans_end; /* end of the array */
2031
};
2032
2033
2034
/*
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2035
  Plan for a QUICK_GROUP_MIN_MAX_SELECT scan.
1 by brian
clean slate
2036
*/
2037
2038
class TRP_GROUP_MIN_MAX : public TABLE_READ_PLAN
2039
{
2040
private:
2041
  bool have_min, have_max;
2042
  KEY_PART_INFO *min_max_arg_part;
482 by Brian Aker
Remove uint.
2043
  uint32_t group_prefix_len;
2044
  uint32_t used_key_parts;
2045
  uint32_t group_key_parts;
1 by brian
clean slate
2046
  KEY *index_info;
482 by Brian Aker
Remove uint.
2047
  uint32_t index;
2048
  uint32_t key_infix_len;
481 by Brian Aker
Remove all of uchar.
2049
  unsigned char key_infix[MAX_KEY_LENGTH];
1 by brian
clean slate
2050
  SEL_TREE *range_tree; /* Represents all range predicates in the query. */
2051
  SEL_ARG  *index_tree; /* The SEL_ARG sub-tree corresponding to index_info. */
482 by Brian Aker
Remove uint.
2052
  uint32_t param_idx; /* Index of used key in param->key. */
1 by brian
clean slate
2053
  /* Number of records selected by the ranges in index_tree. */
2054
public:
2055
  ha_rows quick_prefix_records;
2056
public:
2057
  TRP_GROUP_MIN_MAX(bool have_min_arg, bool have_max_arg,
2058
                    KEY_PART_INFO *min_max_arg_part_arg,
482 by Brian Aker
Remove uint.
2059
                    uint32_t group_prefix_len_arg, uint32_t used_key_parts_arg,
2060
                    uint32_t group_key_parts_arg, KEY *index_info_arg,
2061
                    uint32_t index_arg, uint32_t key_infix_len_arg,
481 by Brian Aker
Remove all of uchar.
2062
                    unsigned char *key_infix_arg,
1 by brian
clean slate
2063
                    SEL_TREE *tree_arg, SEL_ARG *index_tree_arg,
482 by Brian Aker
Remove uint.
2064
                    uint32_t param_idx_arg, ha_rows quick_prefix_records_arg)
1 by brian
clean slate
2065
  : have_min(have_min_arg), have_max(have_max_arg),
2066
    min_max_arg_part(min_max_arg_part_arg),
2067
    group_prefix_len(group_prefix_len_arg), used_key_parts(used_key_parts_arg),
2068
    group_key_parts(group_key_parts_arg), index_info(index_info_arg),
2069
    index(index_arg), key_infix_len(key_infix_len_arg), range_tree(tree_arg),
2070
    index_tree(index_tree_arg), param_idx(param_idx_arg),
2071
    quick_prefix_records(quick_prefix_records_arg)
2072
    {
2073
      if (key_infix_len)
2074
        memcpy(this->key_infix, key_infix_arg, key_infix_len);
2075
    }
2076
  virtual ~TRP_GROUP_MIN_MAX() {}             /* Remove gcc warning */
2077
2078
  QUICK_SELECT_I *make_quick(PARAM *param, bool retrieve_full_rows,
2079
                             MEM_ROOT *parent_alloc);
2080
};
2081
2082
2083
/*
2084
  Fill param->needed_fields with bitmap of fields used in the query.
2085
  SYNOPSIS
2086
    fill_used_fields_bitmap()
2087
      param Parameter from test_quick_select function.
2088
2089
  NOTES
2090
    Clustered PK members are not put into the bitmap as they are implicitly
2091
    present in all keys (and it is impossible to avoid reading them).
2092
  RETURN
2093
    0  Ok
2094
    1  Out of memory.
2095
*/
2096
2097
static int fill_used_fields_bitmap(PARAM *param)
2098
{
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
2099
  Table *table= param->table;
1005.2.3 by Monty Taylor
Further reversion of P.
2100
  my_bitmap_map *tmp;
482 by Brian Aker
Remove uint.
2101
  uint32_t pk;
1005.2.3 by Monty Taylor
Further reversion of P.
2102
  param->tmp_covered_fields.bitmap= 0;
1 by brian
clean slate
2103
  param->fields_bitmap_size= table->s->column_bitmap_size;
1005.2.3 by Monty Taylor
Further reversion of P.
2104
  if (!(tmp= (my_bitmap_map*) alloc_root(param->mem_root,
2105
                                  param->fields_bitmap_size)) ||
1014.2.12 by Monty Taylor
Removed the thread-safe crap in MY_BITMAP. Also remove the temp-pool option for
2106
      bitmap_init(&param->needed_fields, tmp, table->s->fields))
1005.2.3 by Monty Taylor
Further reversion of P.
2107
    return 1;
982.1.4 by Padraig O'Sullivan
More changes to some files to reflect the changes I've made by removing
2108
1005.2.3 by Monty Taylor
Further reversion of P.
2109
  bitmap_copy(&param->needed_fields, table->read_set);
2110
  bitmap_union(&param->needed_fields, table->write_set);
1 by brian
clean slate
2111
2112
  pk= param->table->s->primary_key;
2113
  if (pk != MAX_KEY && param->table->file->primary_key_is_clustered())
2114
  {
2115
    /* The table uses clustered PK and it is not internally generated */
2116
    KEY_PART_INFO *key_part= param->table->key_info[pk].key_part;
2117
    KEY_PART_INFO *key_part_end= key_part +
2118
                                 param->table->key_info[pk].key_parts;
2119
    for (;key_part != key_part_end; ++key_part)
1005.2.3 by Monty Taylor
Further reversion of P.
2120
      bitmap_clear_bit(&param->needed_fields, key_part->fieldnr-1);
1 by brian
clean slate
2121
  }
2122
  return 0;
2123
}
2124
2125
2126
/*
2127
  Test if a key can be used in different ranges
2128
2129
  SYNOPSIS
2130
    SQL_SELECT::test_quick_select()
520.1.22 by Brian Aker
Second pass of thd cleanup
2131
      session               Current thread
1 by brian
clean slate
2132
      keys_to_use       Keys to use for range retrieval
2133
      prev_tables       Tables assumed to be already read when the scan is
2134
                        performed (but not read at the moment of this call)
2135
      limit             Query limit
2136
      force_quick_range Prefer to use range (instead of full table scan) even
2137
                        if it is more expensive.
2138
2139
  NOTES
2140
    Updates the following in the select parameter:
2141
      needed_reg - Bits for keys with may be used if all prev regs are read
2142
      quick      - Parameter to use when reading records.
2143
2144
    In the table struct the following information is updated:
2145
      quick_keys           - Which keys can be used
2146
      quick_rows           - How many rows the key matches
2147
      quick_condition_rows - E(# rows that will satisfy the table condition)
2148
2149
  IMPLEMENTATION
2150
    quick_condition_rows value is obtained as follows:
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2151
1 by brian
clean slate
2152
      It is a minimum of E(#output rows) for all considered table access
2153
      methods (range and index_merge accesses over various indexes).
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2154
1 by brian
clean slate
2155
    The obtained value is not a true E(#rows that satisfy table condition)
2156
    but rather a pessimistic estimate. To obtain a true E(#...) one would
2157
    need to combine estimates of various access methods, taking into account
2158
    correlations between sets of rows they will return.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2159
1 by brian
clean slate
2160
    For example, if values of tbl.key1 and tbl.key2 are independent (a right
2161
    assumption if we have no information about their correlation) then the
2162
    correct estimate will be:
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2163
2164
      E(#rows("tbl.key1 < c1 AND tbl.key2 < c2")) =
1 by brian
clean slate
2165
      = E(#rows(tbl.key1 < c1)) / total_rows(tbl) * E(#rows(tbl.key2 < c2)
2166
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2167
    which is smaller than
2168
1 by brian
clean slate
2169
       MIN(E(#rows(tbl.key1 < c1), E(#rows(tbl.key2 < c2)))
2170
2171
    which is currently produced.
2172
2173
  TODO
2174
   * Change the value returned in quick_condition_rows from a pessimistic
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2175
     estimate to true E(#rows that satisfy table condition).
2176
     (we can re-use some of E(#rows) calcuation code from index_merge/intersection
1 by brian
clean slate
2177
      for this)
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2178
1 by brian
clean slate
2179
   * Check if this function really needs to modify keys_to_use, and change the
2180
     code to pass it by reference if it doesn't.
2181
2182
   * In addition to force_quick_range other means can be (an usually are) used
2183
     to make this function prefer range over full table scan. Figure out if
2184
     force_quick_range is really needed.
2185
2186
  RETURN
2187
   -1 if impossible select (i.e. certainly no rows will be selected)
2188
    0 if can't use quick_select
2189
    1 if found usable ranges and quick select has been successfully created.
2190
*/
2191
520.1.22 by Brian Aker
Second pass of thd cleanup
2192
int SQL_SELECT::test_quick_select(Session *session, key_map keys_to_use,
1 by brian
clean slate
2193
				  table_map prev_tables,
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2194
				  ha_rows limit, bool force_quick_range,
1 by brian
clean slate
2195
                                  bool ordered_output)
2196
{
482 by Brian Aker
Remove uint.
2197
  uint32_t idx;
1 by brian
clean slate
2198
  double scan_time;
2199
  delete quick;
2200
  quick=0;
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
2201
  needed_reg.reset();
2202
  quick_keys.reset();
2203
  if (keys_to_use.none())
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
2204
    return 0;
1 by brian
clean slate
2205
  records= head->file->stats.records;
2206
  if (!records)
2207
    records++;					/* purecov: inspected */
2208
  scan_time= (double) records / TIME_FOR_COMPARE + 1;
2209
  read_time= (double) head->file->scan_time() + scan_time + 1.1;
2210
  if (head->force_index)
2211
    scan_time= read_time= DBL_MAX;
2212
  if (limit < records)
2213
    read_time= (double) records + scan_time + 1; // Force to use index
2214
  else if (read_time <= 2.0 && !force_quick_range)
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
2215
    return 0;				/* No need for quick select */
1 by brian
clean slate
2216
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
2217
  keys_to_use&= head->keys_in_use_for_query;
2218
  if (keys_to_use.any())
1 by brian
clean slate
2219
  {
2220
    MEM_ROOT alloc;
2221
    SEL_TREE *tree= NULL;
2222
    KEY_PART *key_parts;
2223
    KEY *key_info;
2224
    PARAM param;
2225
520.1.22 by Brian Aker
Second pass of thd cleanup
2226
    if (check_stack_overrun(session, 2*STACK_MIN_SIZE, NULL))
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
2227
      return 0;                           // Fatal error flag is set
1 by brian
clean slate
2228
2229
    /* set up parameter that is passed to all functions */
520.1.22 by Brian Aker
Second pass of thd cleanup
2230
    param.session= session;
1 by brian
clean slate
2231
    param.baseflag= head->file->ha_table_flags();
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
2232
    param.prev_tables= prev_tables | const_tables;
2233
    param.read_tables= read_tables;
1 by brian
clean slate
2234
    param.current_table= head->map;
2235
    param.table=head;
2236
    param.keys=0;
2237
    param.mem_root= &alloc;
520.1.22 by Brian Aker
Second pass of thd cleanup
2238
    param.old_root= session->mem_root;
1 by brian
clean slate
2239
    param.needed_reg= &needed_reg;
2240
    param.imerge_cost_buff_size= 0;
55 by brian
Update for using real bool types.
2241
    param.using_real_indexes= true;
2242
    param.remove_jump_scans= true;
1 by brian
clean slate
2243
    param.force_default_mrr= ordered_output;
2244
520.1.22 by Brian Aker
Second pass of thd cleanup
2245
    session->no_errors=1;				// Don't warn about NULL
2246
    init_sql_alloc(&alloc, session->variables.range_alloc_block_size, 0);
1 by brian
clean slate
2247
    if (!(param.key_parts= (KEY_PART*) alloc_root(&alloc,
2248
                                                  sizeof(KEY_PART)*
2249
                                                  head->s->key_parts)) ||
2250
        fill_used_fields_bitmap(&param))
2251
    {
520.1.22 by Brian Aker
Second pass of thd cleanup
2252
      session->no_errors=0;
1 by brian
clean slate
2253
      free_root(&alloc,MYF(0));			// Return memory & allocator
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
2254
      return 0;				// Can't use range
1 by brian
clean slate
2255
    }
2256
    key_parts= param.key_parts;
520.1.22 by Brian Aker
Second pass of thd cleanup
2257
    session->mem_root= &alloc;
1 by brian
clean slate
2258
2259
    /*
2260
      Make an array with description of all key parts of all table keys.
2261
      This is used in get_mm_parts function.
2262
    */
2263
    key_info= head->key_info;
2264
    for (idx=0 ; idx < head->s->keys ; idx++, key_info++)
2265
    {
2266
      KEY_PART_INFO *key_part_info;
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
2267
      if (! keys_to_use.test(idx))
1 by brian
clean slate
2268
	continue;
2269
2270
      param.key[param.keys]=key_parts;
2271
      key_part_info= key_info->key_part;
482 by Brian Aker
Remove uint.
2272
      for (uint32_t part=0 ; part < key_info->key_parts ;
1 by brian
clean slate
2273
	   part++, key_parts++, key_part_info++)
2274
      {
2275
	key_parts->key=		 param.keys;
2276
	key_parts->part=	 part;
2277
	key_parts->length=       key_part_info->length;
2278
	key_parts->store_length= key_part_info->store_length;
2279
	key_parts->field=	 key_part_info->field;
2280
	key_parts->null_bit=	 key_part_info->null_bit;
2281
        key_parts->image_type =  Field::itRAW;
2282
        /* Only HA_PART_KEY_SEG is used */
206 by Brian Aker
Removed final uint dead types.
2283
        key_parts->flag=         (uint8_t) key_part_info->key_part_flag;
1 by brian
clean slate
2284
      }
2285
      param.real_keynr[param.keys++]=idx;
2286
    }
2287
    param.key_parts_end=key_parts;
2288
    param.alloced_sel_args= 0;
2289
2290
    /* Calculate cost of full index read for the shortest covering index */
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
2291
    if (!head->covering_keys.none())
1 by brian
clean slate
2292
    {
355 by Brian Aker
More Table cleanup
2293
      int key_for_use= head->find_shortest_key(&head->covering_keys);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2294
      double key_read_time=
2295
        param.table->file->index_only_read_time(key_for_use,
1 by brian
clean slate
2296
                                                rows2double(records)) +
2297
        (double) records / TIME_FOR_COMPARE;
2298
      if (key_read_time < read_time)
2299
        read_time= key_read_time;
2300
    }
2301
2302
    TABLE_READ_PLAN *best_trp= NULL;
2303
    TRP_GROUP_MIN_MAX *group_trp;
2304
    double best_read_time= read_time;
2305
2306
    if (cond)
2307
    {
2308
      if ((tree= get_mm_tree(&param,cond)))
2309
      {
2310
        if (tree->type == SEL_TREE::IMPOSSIBLE)
2311
        {
2312
          records=0L;                      /* Return -1 from this function. */
2313
          read_time= (double) HA_POS_ERROR;
2314
          goto free_mem;
2315
        }
2316
        /*
2317
          If the tree can't be used for range scans, proceed anyway, as we
2318
          can construct a group-min-max quick select
2319
        */
2320
        if (tree->type != SEL_TREE::KEY && tree->type != SEL_TREE::KEY_SMALLER)
2321
          tree= NULL;
2322
      }
2323
    }
2324
2325
    /*
2326
      Try to construct a QUICK_GROUP_MIN_MAX_SELECT.
2327
      Notice that it can be constructed no matter if there is a range tree.
2328
    */
2329
    group_trp= get_best_group_min_max(&param, tree);
2330
    if (group_trp)
2331
    {
398.1.4 by Monty Taylor
Renamed max/min.
2332
      param.table->quick_condition_rows= cmin(group_trp->records,
1 by brian
clean slate
2333
                                             head->file->stats.records);
2334
      if (group_trp->read_cost < best_read_time)
2335
      {
2336
        best_trp= group_trp;
2337
        best_read_time= best_trp->read_cost;
2338
      }
2339
    }
2340
2341
    if (tree)
2342
    {
2343
      /*
2344
        It is possible to use a range-based quick select (but it might be
2345
        slower than 'all' table scan).
2346
      */
2347
      if (tree->merges.is_empty())
2348
      {
2349
        TRP_RANGE         *range_trp;
2350
        TRP_ROR_INTERSECT *rori_trp;
55 by brian
Update for using real bool types.
2351
        bool can_build_covering= false;
1 by brian
clean slate
2352
2353
        /* Get best 'range' plan and prepare data for making other plans */
55 by brian
Update for using real bool types.
2354
        if ((range_trp= get_key_scans_params(&param, tree, false, true,
1 by brian
clean slate
2355
                                             best_read_time)))
2356
        {
2357
          best_trp= range_trp;
2358
          best_read_time= best_trp->read_cost;
2359
        }
2360
2361
        /*
2362
          Simultaneous key scans and row deletes on several handler
2363
          objects are not allowed so don't use ROR-intersection for
2364
          table deletes.
2365
        */
520.1.22 by Brian Aker
Second pass of thd cleanup
2366
        if ((session->lex->sql_command != SQLCOM_DELETE))
1 by brian
clean slate
2367
        {
2368
          /*
2369
            Get best non-covering ROR-intersection plan and prepare data for
2370
            building covering ROR-intersection.
2371
          */
2372
          if ((rori_trp= get_best_ror_intersect(&param, tree, best_read_time,
2373
                                                &can_build_covering)))
2374
          {
2375
            best_trp= rori_trp;
2376
            best_read_time= best_trp->read_cost;
2377
            /*
2378
              Try constructing covering ROR-intersect only if it looks possible
2379
              and worth doing.
2380
            */
2381
            if (!rori_trp->is_covering && can_build_covering &&
2382
                (rori_trp= get_best_covering_ror_intersect(&param, tree,
2383
                                                           best_read_time)))
2384
              best_trp= rori_trp;
2385
          }
2386
        }
2387
      }
2388
      else
2389
      {
2390
        /* Try creating index_merge/ROR-union scan. */
2391
        SEL_IMERGE *imerge;
2392
        TABLE_READ_PLAN *best_conj_trp= NULL, *new_conj_trp;
2393
        List_iterator_fast<SEL_IMERGE> it(tree->merges);
2394
        while ((imerge= it++))
2395
        {
2396
          new_conj_trp= get_best_disjunct_quick(&param, imerge, best_read_time);
2397
          if (new_conj_trp)
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2398
            set_if_smaller(param.table->quick_condition_rows,
1 by brian
clean slate
2399
                           new_conj_trp->records);
2400
          if (!best_conj_trp || (new_conj_trp && new_conj_trp->read_cost <
2401
                                 best_conj_trp->read_cost))
2402
            best_conj_trp= new_conj_trp;
2403
        }
2404
        if (best_conj_trp)
2405
          best_trp= best_conj_trp;
2406
      }
2407
    }
2408
520.1.22 by Brian Aker
Second pass of thd cleanup
2409
    session->mem_root= param.old_root;
1 by brian
clean slate
2410
2411
    /* If we got a read plan, create a quick select from it. */
2412
    if (best_trp)
2413
    {
2414
      records= best_trp->records;
55 by brian
Update for using real bool types.
2415
      if (!(quick= best_trp->make_quick(&param, true)) || quick->init())
1 by brian
clean slate
2416
      {
2417
        delete quick;
2418
        quick= NULL;
2419
      }
2420
    }
2421
2422
  free_mem:
2423
    free_root(&alloc,MYF(0));			// Return memory & allocator
520.1.22 by Brian Aker
Second pass of thd cleanup
2424
    session->mem_root= param.old_root;
2425
    session->no_errors=0;
1 by brian
clean slate
2426
  }
2427
2428
  /*
2429
    Assume that if the user is using 'limit' we will only need to scan
2430
    limit rows if we are using a key
2431
  */
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
2432
  return(records ? test(quick) : -1);
1 by brian
clean slate
2433
}
2434
2435
/*
2436
  Get best plan for a SEL_IMERGE disjunctive expression.
2437
  SYNOPSIS
2438
    get_best_disjunct_quick()
2439
      param     Parameter from check_quick_select function
2440
      imerge    Expression to use
2441
      read_time Don't create scans with cost > read_time
2442
2443
  NOTES
2444
    index_merge cost is calculated as follows:
2445
    index_merge_cost =
2446
      cost(index_reads) +         (see #1)
2447
      cost(rowid_to_row_scan) +   (see #2)
2448
      cost(unique_use)            (see #3)
2449
2450
    1. cost(index_reads) =SUM_i(cost(index_read_i))
2451
       For non-CPK scans,
2452
         cost(index_read_i) = {cost of ordinary 'index only' scan}
2453
       For CPK scan,
2454
         cost(index_read_i) = {cost of non-'index only' scan}
2455
2456
    2. cost(rowid_to_row_scan)
2457
      If table PK is clustered then
2458
        cost(rowid_to_row_scan) =
2459
          {cost of ordinary clustered PK scan with n_ranges=n_rows}
2460
2461
      Otherwise, we use the following model to calculate costs:
2462
      We need to retrieve n_rows rows from file that occupies n_blocks blocks.
2463
      We assume that offsets of rows we need are independent variates with
2464
      uniform distribution in [0..max_file_offset] range.
2465
2466
      We'll denote block as "busy" if it contains row(s) we need to retrieve
2467
      and "empty" if doesn't contain rows we need.
2468
2469
      Probability that a block is empty is (1 - 1/n_blocks)^n_rows (this
2470
      applies to any block in file). Let x_i be a variate taking value 1 if
2471
      block #i is empty and 0 otherwise.
2472
2473
      Then E(x_i) = (1 - 1/n_blocks)^n_rows;
2474
2475
      E(n_empty_blocks) = E(sum(x_i)) = sum(E(x_i)) =
2476
        = n_blocks * ((1 - 1/n_blocks)^n_rows) =
2477
       ~= n_blocks * exp(-n_rows/n_blocks).
2478
2479
      E(n_busy_blocks) = n_blocks*(1 - (1 - 1/n_blocks)^n_rows) =
2480
       ~= n_blocks * (1 - exp(-n_rows/n_blocks)).
2481
2482
      Average size of "hole" between neighbor non-empty blocks is
2483
           E(hole_size) = n_blocks/E(n_busy_blocks).
2484
2485
      The total cost of reading all needed blocks in one "sweep" is:
2486
2487
      E(n_busy_blocks)*
2488
       (DISK_SEEK_BASE_COST + DISK_SEEK_PROP_COST*n_blocks/E(n_busy_blocks)).
2489
2490
    3. Cost of Unique use is calculated in Unique::get_use_cost function.
2491
2492
  ROR-union cost is calculated in the same way index_merge, but instead of
2493
  Unique a priority queue is used.
2494
2495
  RETURN
2496
    Created read plan
2497
    NULL - Out of memory or no read scan could be built.
2498
*/
2499
2500
static
2501
TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
2502
                                         double read_time)
2503
{
2504
  SEL_TREE **ptree;
2505
  TRP_INDEX_MERGE *imerge_trp= NULL;
482 by Brian Aker
Remove uint.
2506
  uint32_t n_child_scans= imerge->trees_next - imerge->trees;
1 by brian
clean slate
2507
  TRP_RANGE **range_scans;
2508
  TRP_RANGE **cur_child;
2509
  TRP_RANGE **cpk_scan= NULL;
55 by brian
Update for using real bool types.
2510
  bool imerge_too_expensive= false;
1 by brian
clean slate
2511
  double imerge_cost= 0.0;
2512
  ha_rows cpk_scan_records= 0;
2513
  ha_rows non_cpk_scan_records= 0;
2514
  bool pk_is_clustered= param->table->file->primary_key_is_clustered();
55 by brian
Update for using real bool types.
2515
  bool all_scans_ror_able= true;
2516
  bool all_scans_rors= true;
482 by Brian Aker
Remove uint.
2517
  uint32_t unique_calc_buff_size;
1 by brian
clean slate
2518
  TABLE_READ_PLAN **roru_read_plans;
2519
  TABLE_READ_PLAN **cur_roru_plan;
2520
  double roru_index_costs;
2521
  ha_rows roru_total_records;
2522
  double roru_intersect_part= 1.0;
2523
2524
  if (!(range_scans= (TRP_RANGE**)alloc_root(param->mem_root,
2525
                                             sizeof(TRP_RANGE*)*
2526
                                             n_child_scans)))
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
2527
    return NULL;
1 by brian
clean slate
2528
  /*
2529
    Collect best 'range' scan for each of disjuncts, and, while doing so,
2530
    analyze possibility of ROR scans. Also calculate some values needed by
2531
    other parts of the code.
2532
  */
2533
  for (ptree= imerge->trees, cur_child= range_scans;
2534
       ptree != imerge->trees_next;
2535
       ptree++, cur_child++)
2536
  {
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
2537
    print_sel_tree(param, *ptree, &(*ptree)->keys_map, "tree in SEL_IMERGE");
55 by brian
Update for using real bool types.
2538
    if (!(*cur_child= get_key_scans_params(param, *ptree, true, false, read_time)))
1 by brian
clean slate
2539
    {
2540
      /*
2541
        One of index scans in this index_merge is more expensive than entire
2542
        table read for another available option. The entire index_merge (and
2543
        any possible ROR-union) will be more expensive then, too. We continue
2544
        here only to update SQL_SELECT members.
2545
      */
55 by brian
Update for using real bool types.
2546
      imerge_too_expensive= true;
1 by brian
clean slate
2547
    }
2548
    if (imerge_too_expensive)
2549
      continue;
2550
2551
    imerge_cost += (*cur_child)->read_cost;
2552
    all_scans_ror_able &= ((*ptree)->n_ror_scans > 0);
2553
    all_scans_rors &= (*cur_child)->is_ror;
2554
    if (pk_is_clustered &&
2555
        param->real_keynr[(*cur_child)->key_idx] ==
2556
        param->table->s->primary_key)
2557
    {
2558
      cpk_scan= cur_child;
2559
      cpk_scan_records= (*cur_child)->records;
2560
    }
2561
    else
2562
      non_cpk_scan_records += (*cur_child)->records;
2563
  }
2564
2565
  if (imerge_too_expensive || (imerge_cost > read_time) ||
2566
      ((non_cpk_scan_records+cpk_scan_records >= param->table->file->stats.records) && read_time != DBL_MAX))
2567
  {
2568
    /*
2569
      Bail out if it is obvious that both index_merge and ROR-union will be
2570
      more expensive
2571
    */
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
2572
    return NULL;
1 by brian
clean slate
2573
  }
2574
  if (all_scans_rors)
2575
  {
2576
    roru_read_plans= (TABLE_READ_PLAN**)range_scans;
2577
    goto skip_to_ror_scan;
2578
  }
2579
  if (cpk_scan)
2580
  {
2581
    /*
2582
      Add one ROWID comparison for each row retrieved on non-CPK scan.  (it
2583
      is done in QUICK_RANGE_SELECT::row_in_ranges)
2584
     */
2585
    imerge_cost += non_cpk_scan_records / TIME_FOR_COMPARE_ROWID;
2586
  }
2587
2588
  /* Calculate cost(rowid_to_row_scan) */
2589
  {
2590
    COST_VECT sweep_cost;
520.1.22 by Brian Aker
Second pass of thd cleanup
2591
    JOIN *join= param->session->lex->select_lex.join;
1 by brian
clean slate
2592
    bool is_interrupted= test(join && join->tables == 1);
2593
    get_sweep_read_cost(param->table, non_cpk_scan_records, is_interrupted,
2594
                        &sweep_cost);
2595
    imerge_cost += sweep_cost.total_cost();
2596
  }
2597
  if (imerge_cost > read_time)
2598
    goto build_ror_index_merge;
2599
2600
  /* Add Unique operations cost */
2601
  unique_calc_buff_size=
2602
    Unique::get_cost_calc_buff_size((ulong)non_cpk_scan_records,
2603
                                    param->table->file->ref_length,
520.1.22 by Brian Aker
Second pass of thd cleanup
2604
                                    param->session->variables.sortbuff_size);
1 by brian
clean slate
2605
  if (param->imerge_cost_buff_size < unique_calc_buff_size)
2606
  {
2607
    if (!(param->imerge_cost_buff= (uint*)alloc_root(param->mem_root,
2608
                                                     unique_calc_buff_size)))
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
2609
      return NULL;
1 by brian
clean slate
2610
    param->imerge_cost_buff_size= unique_calc_buff_size;
2611
  }
2612
2613
  imerge_cost +=
895 by Brian Aker
Completion (?) of uint conversion.
2614
    Unique::get_use_cost(param->imerge_cost_buff, (uint32_t)non_cpk_scan_records,
1 by brian
clean slate
2615
                         param->table->file->ref_length,
520.1.22 by Brian Aker
Second pass of thd cleanup
2616
                         param->session->variables.sortbuff_size);
1 by brian
clean slate
2617
  if (imerge_cost < read_time)
2618
  {
2619
    if ((imerge_trp= new (param->mem_root)TRP_INDEX_MERGE))
2620
    {
2621
      imerge_trp->read_cost= imerge_cost;
2622
      imerge_trp->records= non_cpk_scan_records + cpk_scan_records;
398.1.4 by Monty Taylor
Renamed max/min.
2623
      imerge_trp->records= cmin(imerge_trp->records,
1 by brian
clean slate
2624
                               param->table->file->stats.records);
2625
      imerge_trp->range_scans= range_scans;
2626
      imerge_trp->range_scans_end= range_scans + n_child_scans;
2627
      read_time= imerge_cost;
2628
    }
2629
  }
2630
2631
build_ror_index_merge:
520.1.22 by Brian Aker
Second pass of thd cleanup
2632
  if (!all_scans_ror_able || param->session->lex->sql_command == SQLCOM_DELETE)
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
2633
    return(imerge_trp);
1 by brian
clean slate
2634
2635
  /* Ok, it is possible to build a ROR-union, try it. */
2636
  bool dummy;
2637
  if (!(roru_read_plans=
2638
          (TABLE_READ_PLAN**)alloc_root(param->mem_root,
2639
                                        sizeof(TABLE_READ_PLAN*)*
2640
                                        n_child_scans)))
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
2641
    return(imerge_trp);
1 by brian
clean slate
2642
skip_to_ror_scan:
2643
  roru_index_costs= 0.0;
2644
  roru_total_records= 0;
2645
  cur_roru_plan= roru_read_plans;
2646
2647
  /* Find 'best' ROR scan for each of trees in disjunction */
2648
  for (ptree= imerge->trees, cur_child= range_scans;
2649
       ptree != imerge->trees_next;
2650
       ptree++, cur_child++, cur_roru_plan++)
2651
  {
2652
    /*
2653
      Assume the best ROR scan is the one that has cheapest full-row-retrieval
2654
      scan cost.
2655
      Also accumulate index_only scan costs as we'll need them to calculate
2656
      overall index_intersection cost.
2657
    */
2658
    double cost;
2659
    if ((*cur_child)->is_ror)
2660
    {
2661
      /* Ok, we have index_only cost, now get full rows scan cost */
2662
      cost= param->table->file->
2663
              read_time(param->real_keynr[(*cur_child)->key_idx], 1,
2664
                        (*cur_child)->records) +
2665
              rows2double((*cur_child)->records) / TIME_FOR_COMPARE;
2666
    }
2667
    else
2668
      cost= read_time;
2669
2670
    TABLE_READ_PLAN *prev_plan= *cur_child;
2671
    if (!(*cur_roru_plan= get_best_ror_intersect(param, *ptree, cost,
2672
                                                 &dummy)))
2673
    {
2674
      if (prev_plan->is_ror)
2675
        *cur_roru_plan= prev_plan;
2676
      else
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
2677
        return(imerge_trp);
1 by brian
clean slate
2678
      roru_index_costs += (*cur_roru_plan)->read_cost;
2679
    }
2680
    else
2681
      roru_index_costs +=
2682
        ((TRP_ROR_INTERSECT*)(*cur_roru_plan))->index_scan_costs;
2683
    roru_total_records += (*cur_roru_plan)->records;
2684
    roru_intersect_part *= (*cur_roru_plan)->records /
2685
                           param->table->file->stats.records;
2686
  }
2687
2688
  /*
2689
    rows to retrieve=
2690
      SUM(rows_in_scan_i) - table_rows * PROD(rows_in_scan_i / table_rows).
2691
    This is valid because index_merge construction guarantees that conditions
2692
    in disjunction do not share key parts.
2693
  */
2694
  roru_total_records -= (ha_rows)(roru_intersect_part*
2695
                                  param->table->file->stats.records);
2696
  /* ok, got a ROR read plan for each of the disjuncts
2697
    Calculate cost:
2698
    cost(index_union_scan(scan_1, ... scan_n)) =
2699
      SUM_i(cost_of_index_only_scan(scan_i)) +
2700
      queue_use_cost(rowid_len, n) +
2701
      cost_of_row_retrieval
2702
    See get_merge_buffers_cost function for queue_use_cost formula derivation.
2703
  */
2704
  double roru_total_cost;
2705
  {
2706
    COST_VECT sweep_cost;
520.1.22 by Brian Aker
Second pass of thd cleanup
2707
    JOIN *join= param->session->lex->select_lex.join;
1 by brian
clean slate
2708
    bool is_interrupted= test(join && join->tables == 1);
2709
    get_sweep_read_cost(param->table, roru_total_records, is_interrupted,
2710
                        &sweep_cost);
2711
    roru_total_cost= roru_index_costs +
2712
                     rows2double(roru_total_records)*log((double)n_child_scans) /
2713
                     (TIME_FOR_COMPARE_ROWID * M_LN2) +
2714
                     sweep_cost.total_cost();
2715
  }
2716
2717
  TRP_ROR_UNION* roru;
2718
  if (roru_total_cost < read_time)
2719
  {
2720
    if ((roru= new (param->mem_root) TRP_ROR_UNION))
2721
    {
2722
      roru->first_ror= roru_read_plans;
2723
      roru->last_ror= roru_read_plans + n_child_scans;
2724
      roru->read_cost= roru_total_cost;
2725
      roru->records= roru_total_records;
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
2726
      return(roru);
1 by brian
clean slate
2727
    }
2728
  }
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
2729
  return(imerge_trp);
1 by brian
clean slate
2730
}
2731
2732
2733
typedef struct st_ror_scan_info
2734
{
482 by Brian Aker
Remove uint.
2735
  uint32_t      idx;      /* # of used key in param->keys */
2736
  uint32_t      keynr;    /* # of used key in table */
1 by brian
clean slate
2737
  ha_rows   records;  /* estimate of # records this scan will return */
2738
2739
  /* Set of intervals over key fields that will be used for row retrieval. */
2740
  SEL_ARG   *sel_arg;
2741
2742
  /* Fields used in the query and covered by this ROR scan. */
1005.2.3 by Monty Taylor
Further reversion of P.
2743
  MY_BITMAP covered_fields;
482 by Brian Aker
Remove uint.
2744
  uint32_t      used_fields_covered; /* # of set bits in covered_fields */
1 by brian
clean slate
2745
  int       key_rec_length; /* length of key record (including rowid) */
2746
2747
  /*
2748
    Cost of reading all index records with values in sel_arg intervals set
2749
    (assuming there is no need to access full table records)
2750
  */
2751
  double    index_read_cost;
482 by Brian Aker
Remove uint.
2752
  uint32_t      first_uncovered_field; /* first unused bit in covered_fields */
2753
  uint32_t      key_components; /* # of parts in the key */
1 by brian
clean slate
2754
} ROR_SCAN_INFO;
2755
2756
2757
/*
2758
  Create ROR_SCAN_INFO* structure with a single ROR scan on index idx using
2759
  sel_arg set of intervals.
2760
2761
  SYNOPSIS
2762
    make_ror_scan()
2763
      param    Parameter from test_quick_select function
2764
      idx      Index of key in param->keys
2765
      sel_arg  Set of intervals for a given key
2766
2767
  RETURN
2768
    NULL - out of memory
2769
    ROR scan structure containing a scan for {idx, sel_arg}
2770
*/
2771
2772
static
2773
ROR_SCAN_INFO *make_ror_scan(const PARAM *param, int idx, SEL_ARG *sel_arg)
2774
{
2775
  ROR_SCAN_INFO *ror_scan;
1005.2.1 by Monty Taylor
Reverted a crap-ton of padraig's work.
2776
  my_bitmap_map *bitmap_buf;
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
2777
482 by Brian Aker
Remove uint.
2778
  uint32_t keynr;
1 by brian
clean slate
2779
2780
  if (!(ror_scan= (ROR_SCAN_INFO*)alloc_root(param->mem_root,
2781
                                             sizeof(ROR_SCAN_INFO))))
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
2782
    return NULL;
1 by brian
clean slate
2783
2784
  ror_scan->idx= idx;
2785
  ror_scan->keynr= keynr= param->real_keynr[idx];
2786
  ror_scan->key_rec_length= (param->table->key_info[keynr].key_length +
2787
                             param->table->file->ref_length);
2788
  ror_scan->sel_arg= sel_arg;
2789
  ror_scan->records= param->table->quick_rows[keynr];
1005.2.1 by Monty Taylor
Reverted a crap-ton of padraig's work.
2790
2791
  if (!(bitmap_buf= (my_bitmap_map*) alloc_root(param->mem_root,
2792
                                                param->fields_bitmap_size)))
2793
    return NULL;
2794
1005.2.3 by Monty Taylor
Further reversion of P.
2795
  if (bitmap_init(&ror_scan->covered_fields, bitmap_buf,
1014.2.12 by Monty Taylor
Removed the thread-safe crap in MY_BITMAP. Also remove the temp-pool option for
2796
                  param->table->s->fields))
1005.2.3 by Monty Taylor
Further reversion of P.
2797
    return NULL;
2798
  bitmap_clear_all(&ror_scan->covered_fields);
1 by brian
clean slate
2799
2800
  KEY_PART_INFO *key_part= param->table->key_info[keynr].key_part;
2801
  KEY_PART_INFO *key_part_end= key_part +
2802
                               param->table->key_info[keynr].key_parts;
2803
  for (;key_part != key_part_end; ++key_part)
2804
  {
1005.2.3 by Monty Taylor
Further reversion of P.
2805
    if (bitmap_is_set(&param->needed_fields, key_part->fieldnr-1))
2806
      bitmap_set_bit(&ror_scan->covered_fields, key_part->fieldnr-1);
1 by brian
clean slate
2807
  }
2808
  double rows= rows2double(param->table->quick_rows[ror_scan->keynr]);
2809
  ror_scan->index_read_cost=
2810
    param->table->file->index_only_read_time(ror_scan->keynr, rows);
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
2811
  return(ror_scan);
1 by brian
clean slate
2812
}
2813
2814
2815
/*
2816
  Compare two ROR_SCAN_INFO** by  E(#records_matched) * key_record_length.
2817
  SYNOPSIS
2818
    cmp_ror_scan_info()
2819
      a ptr to first compared value
2820
      b ptr to second compared value
2821
2822
  RETURN
2823
   -1 a < b
2824
    0 a = b
2825
    1 a > b
2826
*/
2827
2828
static int cmp_ror_scan_info(ROR_SCAN_INFO** a, ROR_SCAN_INFO** b)
2829
{
2830
  double val1= rows2double((*a)->records) * (*a)->key_rec_length;
2831
  double val2= rows2double((*b)->records) * (*b)->key_rec_length;
2832
  return (val1 < val2)? -1: (val1 == val2)? 0 : 1;
2833
}
2834
2835
/*
2836
  Compare two ROR_SCAN_INFO** by
2837
   (#covered fields in F desc,
2838
    #components asc,
2839
    number of first not covered component asc)
2840
2841
  SYNOPSIS
2842
    cmp_ror_scan_info_covering()
2843
      a ptr to first compared value
2844
      b ptr to second compared value
2845
2846
  RETURN
2847
   -1 a < b
2848
    0 a = b
2849
    1 a > b
2850
*/
2851
2852
static int cmp_ror_scan_info_covering(ROR_SCAN_INFO** a, ROR_SCAN_INFO** b)
2853
{
2854
  if ((*a)->used_fields_covered > (*b)->used_fields_covered)
2855
    return -1;
2856
  if ((*a)->used_fields_covered < (*b)->used_fields_covered)
2857
    return 1;
2858
  if ((*a)->key_components < (*b)->key_components)
2859
    return -1;
2860
  if ((*a)->key_components > (*b)->key_components)
2861
    return 1;
2862
  if ((*a)->first_uncovered_field < (*b)->first_uncovered_field)
2863
    return -1;
2864
  if ((*a)->first_uncovered_field > (*b)->first_uncovered_field)
2865
    return 1;
2866
  return 0;
2867
}
2868
2869
2870
/* Auxiliary structure for incremental ROR-intersection creation */
2871
typedef struct
2872
{
2873
  const PARAM *param;
1005.2.3 by Monty Taylor
Further reversion of P.
2874
  MY_BITMAP covered_fields; /* union of fields covered by all scans */
1 by brian
clean slate
2875
  /*
2876
    Fraction of table records that satisfies conditions of all scans.
2877
    This is the number of full records that will be retrieved if a
2878
    non-index_only index intersection will be employed.
2879
  */
2880
  double out_rows;
55 by brian
Update for using real bool types.
2881
  /* true if covered_fields is a superset of needed_fields */
1 by brian
clean slate
2882
  bool is_covering;
2883
2884
  ha_rows index_records; /* sum(#records to look in indexes) */
2885
  double index_scan_costs; /* SUM(cost of 'index-only' scans) */
2886
  double total_cost;
2887
} ROR_INTERSECT_INFO;
2888
2889
2890
/*
2891
  Allocate a ROR_INTERSECT_INFO and initialize it to contain zero scans.
2892
2893
  SYNOPSIS
2894
    ror_intersect_init()
2895
      param         Parameter from test_quick_select
2896
2897
  RETURN
2898
    allocated structure
2899
    NULL on error
2900
*/
2901
2902
static
2903
ROR_INTERSECT_INFO* ror_intersect_init(const PARAM *param)
2904
{
2905
  ROR_INTERSECT_INFO *info;
1005.2.3 by Monty Taylor
Further reversion of P.
2906
  my_bitmap_map* buf;
1 by brian
clean slate
2907
  if (!(info= (ROR_INTERSECT_INFO*)alloc_root(param->mem_root,
2908
                                              sizeof(ROR_INTERSECT_INFO))))
2909
    return NULL;
2910
  info->param= param;
1005.2.3 by Monty Taylor
Further reversion of P.
2911
  if (!(buf= (my_bitmap_map*) alloc_root(param->mem_root,
2912
                                         param->fields_bitmap_size)))
2913
    return NULL;
1014.2.12 by Monty Taylor
Removed the thread-safe crap in MY_BITMAP. Also remove the temp-pool option for
2914
  if (bitmap_init(&info->covered_fields, buf, param->table->s->fields))
1005.2.3 by Monty Taylor
Further reversion of P.
2915
    return NULL;
55 by brian
Update for using real bool types.
2916
  info->is_covering= false;
1 by brian
clean slate
2917
  info->index_scan_costs= 0.0;
2918
  info->index_records= 0;
2919
  info->out_rows= (double) param->table->file->stats.records;
1005.2.3 by Monty Taylor
Further reversion of P.
2920
  bitmap_clear_all(&info->covered_fields);
1 by brian
clean slate
2921
  return info;
2922
}
2923
2924
void ror_intersect_cpy(ROR_INTERSECT_INFO *dst, const ROR_INTERSECT_INFO *src)
2925
{
2926
  dst->param= src->param;
1005.2.3 by Monty Taylor
Further reversion of P.
2927
  memcpy(dst->covered_fields.bitmap, src->covered_fields.bitmap,
2928
         no_bytes_in_map(&src->covered_fields));
1 by brian
clean slate
2929
  dst->out_rows= src->out_rows;
2930
  dst->is_covering= src->is_covering;
2931
  dst->index_records= src->index_records;
2932
  dst->index_scan_costs= src->index_scan_costs;
2933
  dst->total_cost= src->total_cost;
2934
}
2935
2936
2937
/*
2938
  Get selectivity of a ROR scan wrt ROR-intersection.
2939
2940
  SYNOPSIS
2941
    ror_scan_selectivity()
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2942
      info  ROR-interection
1 by brian
clean slate
2943
      scan  ROR scan
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2944
1 by brian
clean slate
2945
  NOTES
2946
    Suppose we have a condition on several keys
2947
    cond=k_11=c_11 AND k_12=c_12 AND ...  // parts of first key
2948
         k_21=c_21 AND k_22=c_22 AND ...  // parts of second key
2949
          ...
2950
         k_n1=c_n1 AND k_n3=c_n3 AND ...  (1) //parts of the key used by *scan
2951
2952
    where k_ij may be the same as any k_pq (i.e. keys may have common parts).
2953
2954
    A full row is retrieved if entire condition holds.
2955
2956
    The recursive procedure for finding P(cond) is as follows:
2957
2958
    First step:
2959
    Pick 1st part of 1st key and break conjunction (1) into two parts:
2960
      cond= (k_11=c_11 AND R)
2961
2962
    Here R may still contain condition(s) equivalent to k_11=c_11.
2963
    Nevertheless, the following holds:
2964
2965
      P(k_11=c_11 AND R) = P(k_11=c_11) * P(R | k_11=c_11).
2966
2967
    Mark k_11 as fixed field (and satisfied condition) F, save P(F),
2968
    save R to be cond and proceed to recursion step.
2969
2970
    Recursion step:
2971
    We have a set of fixed fields/satisfied conditions) F, probability P(F),
2972
    and remaining conjunction R
2973
    Pick next key part on current key and its condition "k_ij=c_ij".
2974
    We will add "k_ij=c_ij" into F and update P(F).
2975
    Lets denote k_ij as t,  R = t AND R1, where R1 may still contain t. Then
2976
2977
     P((t AND R1)|F) = P(t|F) * P(R1|t|F) = P(t|F) * P(R1|(t AND F)) (2)
2978
2979
    (where '|' mean conditional probability, not "or")
2980
2981
    Consider the first multiplier in (2). One of the following holds:
2982
    a) F contains condition on field used in t (i.e. t AND F = F).
2983
      Then P(t|F) = 1
2984
2985
    b) F doesn't contain condition on field used in t. Then F and t are
2986
     considered independent.
2987
2988
     P(t|F) = P(t|(fields_before_t_in_key AND other_fields)) =
2989
          = P(t|fields_before_t_in_key).
2990
2991
     P(t|fields_before_t_in_key) = #records(fields_before_t_in_key) /
2992
                                   #records(fields_before_t_in_key, t)
2993
2994
    The second multiplier is calculated by applying this step recursively.
2995
2996
  IMPLEMENTATION
2997
    This function calculates the result of application of the "recursion step"
2998
    described above for all fixed key members of a single key, accumulating set
2999
    of covered fields, selectivity, etc.
3000
3001
    The calculation is conducted as follows:
3002
    Lets denote #records(keypart1, ... keypartK) as n_k. We need to calculate
3003
3004
     n_{k1}      n_{k2}
3005
    --------- * ---------  * .... (3)
3006
     n_{k1-1}    n_{k2-1}
3007
3008
    where k1,k2,... are key parts which fields were not yet marked as fixed
3009
    ( this is result of application of option b) of the recursion step for
3010
      parts of a single key).
3011
    Since it is reasonable to expect that most of the fields are not marked
3012
    as fixed, we calculate (3) as
3013
3014
                                  n_{i1}      n_{i2}
3015
    (3) = n_{max_key_part}  / (   --------- * ---------  * ....  )
3016
                                  n_{i1-1}    n_{i2-1}
3017
3018
    where i1,i2, .. are key parts that were already marked as fixed.
3019
3020
    In order to minimize number of expensive records_in_range calls we group
3021
    and reduce adjacent fractions.
3022
3023
  RETURN
3024
    Selectivity of given ROR scan.
3025
*/
3026
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3027
static double ror_scan_selectivity(const ROR_INTERSECT_INFO *info,
1 by brian
clean slate
3028
                                   const ROR_SCAN_INFO *scan)
3029
{
3030
  double selectivity_mult= 1.0;
3031
  KEY_PART_INFO *key_part= info->param->table->key_info[scan->keynr].key_part;
481 by Brian Aker
Remove all of uchar.
3032
  unsigned char key_val[MAX_KEY_LENGTH+MAX_FIELD_WIDTH]; /* key values tuple */
3033
  unsigned char *key_ptr= key_val;
1 by brian
clean slate
3034
  SEL_ARG *sel_arg, *tuple_arg= NULL;
3035
  key_part_map keypart_map= 0;
3036
  bool cur_covered;
1005.2.3 by Monty Taylor
Further reversion of P.
3037
  bool prev_covered= test(bitmap_is_set(&info->covered_fields,
3038
                                        key_part->fieldnr-1));
1 by brian
clean slate
3039
  key_range min_range;
3040
  key_range max_range;
3041
  min_range.key= key_val;
3042
  min_range.flag= HA_READ_KEY_EXACT;
3043
  max_range.key= key_val;
3044
  max_range.flag= HA_READ_AFTER_KEY;
3045
  ha_rows prev_records= info->param->table->file->stats.records;
3046
3047
  for (sel_arg= scan->sel_arg; sel_arg;
3048
       sel_arg= sel_arg->next_key_part)
3049
  {
1005.2.3 by Monty Taylor
Further reversion of P.
3050
    cur_covered= test(bitmap_is_set(&info->covered_fields,
3051
                                    key_part[sel_arg->part].fieldnr-1));
1 by brian
clean slate
3052
    if (cur_covered != prev_covered)
3053
    {
3054
      /* create (part1val, ..., part{n-1}val) tuple. */
3055
      ha_rows records;
3056
      if (!tuple_arg)
3057
      {
3058
        tuple_arg= scan->sel_arg;
3059
        /* Here we use the length of the first key part */
3060
        tuple_arg->store_min(key_part->store_length, &key_ptr, 0);
3061
        keypart_map= 1;
3062
      }
3063
      while (tuple_arg->next_key_part != sel_arg)
3064
      {
3065
        tuple_arg= tuple_arg->next_key_part;
3066
        tuple_arg->store_min(key_part[tuple_arg->part].store_length,
3067
                             &key_ptr, 0);
3068
        keypart_map= (keypart_map << 1) | 1;
3069
      }
3070
      min_range.length= max_range.length= (size_t) (key_ptr - key_val);
3071
      min_range.keypart_map= max_range.keypart_map= keypart_map;
3072
      records= (info->param->table->file->
3073
                records_in_range(scan->keynr, &min_range, &max_range));
3074
      if (cur_covered)
3075
      {
3076
        /* uncovered -> covered */
3077
        double tmp= rows2double(records)/rows2double(prev_records);
3078
        selectivity_mult *= tmp;
3079
        prev_records= HA_POS_ERROR;
3080
      }
3081
      else
3082
      {
3083
        /* covered -> uncovered */
3084
        prev_records= records;
3085
      }
3086
    }
3087
    prev_covered= cur_covered;
3088
  }
3089
  if (!prev_covered)
3090
  {
3091
    double tmp= rows2double(info->param->table->quick_rows[scan->keynr]) /
3092
                rows2double(prev_records);
3093
    selectivity_mult *= tmp;
3094
  }
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
3095
  return(selectivity_mult);
1 by brian
clean slate
3096
}
3097
3098
3099
/*
3100
  Check if adding a ROR scan to a ROR-intersection reduces its cost of
3101
  ROR-intersection and if yes, update parameters of ROR-intersection,
3102
  including its cost.
3103
3104
  SYNOPSIS
3105
    ror_intersect_add()
3106
      param        Parameter from test_quick_select
3107
      info         ROR-intersection structure to add the scan to.
3108
      ror_scan     ROR scan info to add.
55 by brian
Update for using real bool types.
3109
      is_cpk_scan  If true, add the scan as CPK scan (this can be inferred
1 by brian
clean slate
3110
                   from other parameters and is passed separately only to
3111
                   avoid duplicating the inference code)
3112
3113
  NOTES
3114
    Adding a ROR scan to ROR-intersect "makes sense" iff the cost of ROR-
3115
    intersection decreases. The cost of ROR-intersection is calculated as
3116
    follows:
3117
3118
    cost= SUM_i(key_scan_cost_i) + cost_of_full_rows_retrieval
3119
3120
    When we add a scan the first increases and the second decreases.
3121
3122
    cost_of_full_rows_retrieval=
3123
      (union of indexes used covers all needed fields) ?
3124
        cost_of_sweep_read(E(rows_to_retrieve), rows_in_table) :
3125
        0
3126
3127
    E(rows_to_retrieve) = #rows_in_table * ror_scan_selectivity(null, scan1) *
3128
                           ror_scan_selectivity({scan1}, scan2) * ... *
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3129
                           ror_scan_selectivity({scan1,...}, scanN).
1 by brian
clean slate
3130
  RETURN
55 by brian
Update for using real bool types.
3131
    true   ROR scan added to ROR-intersection, cost updated.
3132
    false  It doesn't make sense to add this ROR scan to this ROR-intersection.
1 by brian
clean slate
3133
*/
3134
3135
static bool ror_intersect_add(ROR_INTERSECT_INFO *info,
3136
                              ROR_SCAN_INFO* ror_scan, bool is_cpk_scan)
3137
{
3138
  double selectivity_mult= 1.0;
3139
3140
  selectivity_mult = ror_scan_selectivity(info, ror_scan);
3141
  if (selectivity_mult == 1.0)
3142
  {
3143
    /* Don't add this scan if it doesn't improve selectivity. */
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
3144
    return false;
1 by brian
clean slate
3145
  }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3146
1 by brian
clean slate
3147
  info->out_rows *= selectivity_mult;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3148
1 by brian
clean slate
3149
  if (is_cpk_scan)
3150
  {
3151
    /*
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3152
      CPK scan is used to filter out rows. We apply filtering for
1 by brian
clean slate
3153
      each record of every scan. Assuming 1/TIME_FOR_COMPARE_ROWID
3154
      per check this gives us:
3155
    */
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3156
    info->index_scan_costs += rows2double(info->index_records) /
1 by brian
clean slate
3157
                              TIME_FOR_COMPARE_ROWID;
3158
  }
3159
  else
3160
  {
3161
    info->index_records += info->param->table->quick_rows[ror_scan->keynr];
3162
    info->index_scan_costs += ror_scan->index_read_cost;
1005.2.3 by Monty Taylor
Further reversion of P.
3163
    bitmap_union(&info->covered_fields, &ror_scan->covered_fields);
3164
    if (!info->is_covering && bitmap_is_subset(&info->param->needed_fields,
3165
                                               &info->covered_fields))
1 by brian
clean slate
3166
    {
55 by brian
Update for using real bool types.
3167
      info->is_covering= true;
1 by brian
clean slate
3168
    }
3169
  }
3170
3171
  info->total_cost= info->index_scan_costs;
3172
  if (!info->is_covering)
3173
  {
3174
    COST_VECT sweep_cost;
520.1.22 by Brian Aker
Second pass of thd cleanup
3175
    JOIN *join= info->param->session->lex->select_lex.join;
1 by brian
clean slate
3176
    bool is_interrupted= test(join && join->tables == 1);
3177
    get_sweep_read_cost(info->param->table, double2rows(info->out_rows),
3178
                        is_interrupted, &sweep_cost);
3179
    info->total_cost += sweep_cost.total_cost();
3180
  }
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
3181
  return true;
1 by brian
clean slate
3182
}
3183
3184
3185
/*
3186
  Get best ROR-intersection plan using non-covering ROR-intersection search
3187
  algorithm. The returned plan may be covering.
3188
3189
  SYNOPSIS
3190
    get_best_ror_intersect()
3191
      param            Parameter from test_quick_select function.
3192
      tree             Transformed restriction condition to be used to look
3193
                       for ROR scans.
3194
      read_time        Do not return read plans with cost > read_time.
55 by brian
Update for using real bool types.
3195
      are_all_covering [out] set to true if union of all scans covers all
1 by brian
clean slate
3196
                       fields needed by the query (and it is possible to build
3197
                       a covering ROR-intersection)
3198
3199
  NOTES
3200
    get_key_scans_params must be called before this function can be called.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3201
1 by brian
clean slate
3202
    When this function is called by ROR-union construction algorithm it
3203
    assumes it is building an uncovered ROR-intersection (and thus # of full
3204
    records to be retrieved is wrong here). This is a hack.
3205
3206
  IMPLEMENTATION
3207
    The approximate best non-covering plan search algorithm is as follows:
3208
3209
    find_min_ror_intersection_scan()
3210
    {
3211
      R= select all ROR scans;
3212
      order R by (E(#records_matched) * key_record_length).
3213
3214
      S= first(R); -- set of scans that will be used for ROR-intersection
3215
      R= R-first(S);
3216
      min_cost= cost(S);
3217
      min_scan= make_scan(S);
3218
      while (R is not empty)
3219
      {
3220
        firstR= R - first(R);
3221
        if (!selectivity(S + firstR < selectivity(S)))
3222
          continue;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3223
1 by brian
clean slate
3224
        S= S + first(R);
3225
        if (cost(S) < min_cost)
3226
        {
3227
          min_cost= cost(S);
3228
          min_scan= make_scan(S);
3229
        }
3230
      }
3231
      return min_scan;
3232
    }
3233
3234
    See ror_intersect_add function for ROR intersection costs.
3235
3236
    Special handling for Clustered PK scans
3237
    Clustered PK contains all table fields, so using it as a regular scan in
3238
    index intersection doesn't make sense: a range scan on CPK will be less
3239
    expensive in this case.
3240
    Clustered PK scan has special handling in ROR-intersection: it is not used
3241
    to retrieve rows, instead its condition is used to filter row references
3242
    we get from scans on other keys.
3243
3244
  RETURN
3245
    ROR-intersection table read plan
3246
    NULL if out of memory or no suitable plan found.
3247
*/
3248
3249
static
3250
TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree,
3251
                                          double read_time,
3252
                                          bool *are_all_covering)
3253
{
482 by Brian Aker
Remove uint.
3254
  uint32_t idx;
1 by brian
clean slate
3255
  double min_cost= DBL_MAX;
3256
3257
  if ((tree->n_ror_scans < 2) || !param->table->file->stats.records)
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
3258
    return NULL;
1 by brian
clean slate
3259
3260
  /*
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3261
    Step1: Collect ROR-able SEL_ARGs and create ROR_SCAN_INFO for each of
1 by brian
clean slate
3262
    them. Also find and save clustered PK scan if there is one.
3263
  */
3264
  ROR_SCAN_INFO **cur_ror_scan;
3265
  ROR_SCAN_INFO *cpk_scan= NULL;
482 by Brian Aker
Remove uint.
3266
  uint32_t cpk_no;
55 by brian
Update for using real bool types.
3267
  bool cpk_scan_used= false;
1 by brian
clean slate
3268
3269
  if (!(tree->ror_scans= (ROR_SCAN_INFO**)alloc_root(param->mem_root,
3270
                                                     sizeof(ROR_SCAN_INFO*)*
3271
                                                     param->keys)))
3272
    return NULL;
3273
  cpk_no= ((param->table->file->primary_key_is_clustered()) ?
3274
           param->table->s->primary_key : MAX_KEY);
3275
3276
  for (idx= 0, cur_ror_scan= tree->ror_scans; idx < param->keys; idx++)
3277
  {
3278
    ROR_SCAN_INFO *scan;
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
3279
    if (! tree->ror_scans_map.test(idx))
1 by brian
clean slate
3280
      continue;
3281
    if (!(scan= make_ror_scan(param, idx, tree->keys[idx])))
3282
      return NULL;
3283
    if (param->real_keynr[idx] == cpk_no)
3284
    {
3285
      cpk_scan= scan;
3286
      tree->n_ror_scans--;
3287
    }
3288
    else
3289
      *(cur_ror_scan++)= scan;
3290
  }
3291
3292
  tree->ror_scans_end= cur_ror_scan;
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
3293
  print_ror_scans_arr(param->table, "original",
1 by brian
clean slate
3294
                                          tree->ror_scans,
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
3295
                                          tree->ror_scans_end);
1 by brian
clean slate
3296
  /*
3297
    Ok, [ror_scans, ror_scans_end) is array of ptrs to initialized
3298
    ROR_SCAN_INFO's.
3299
    Step 2: Get best ROR-intersection using an approximate algorithm.
3300
  */
3301
  my_qsort(tree->ror_scans, tree->n_ror_scans, sizeof(ROR_SCAN_INFO*),
3302
           (qsort_cmp)cmp_ror_scan_info);
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
3303
  print_ror_scans_arr(param->table, "ordered",
1 by brian
clean slate
3304
                                          tree->ror_scans,
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
3305
                                          tree->ror_scans_end);
1 by brian
clean slate
3306
3307
  ROR_SCAN_INFO **intersect_scans; /* ROR scans used in index intersection */
3308
  ROR_SCAN_INFO **intersect_scans_end;
3309
  if (!(intersect_scans= (ROR_SCAN_INFO**)alloc_root(param->mem_root,
3310
                                                     sizeof(ROR_SCAN_INFO*)*
3311
                                                     tree->n_ror_scans)))
3312
    return NULL;
3313
  intersect_scans_end= intersect_scans;
3314
3315
  /* Create and incrementally update ROR intersection. */
3316
  ROR_INTERSECT_INFO *intersect, *intersect_best;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3317
  if (!(intersect= ror_intersect_init(param)) ||
1 by brian
clean slate
3318
      !(intersect_best= ror_intersect_init(param)))
3319
    return NULL;
3320
3321
  /* [intersect_scans,intersect_scans_best) will hold the best intersection */
3322
  ROR_SCAN_INFO **intersect_scans_best;
3323
  cur_ror_scan= tree->ror_scans;
3324
  intersect_scans_best= intersect_scans;
3325
  while (cur_ror_scan != tree->ror_scans_end && !intersect->is_covering)
3326
  {
3327
    /* S= S + first(R);  R= R - first(R); */
55 by brian
Update for using real bool types.
3328
    if (!ror_intersect_add(intersect, *cur_ror_scan, false))
1 by brian
clean slate
3329
    {
3330
      cur_ror_scan++;
3331
      continue;
3332
    }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3333
1 by brian
clean slate
3334
    *(intersect_scans_end++)= *(cur_ror_scan++);
3335
3336
    if (intersect->total_cost < min_cost)
3337
    {
3338
      /* Local minimum found, save it */
3339
      ror_intersect_cpy(intersect_best, intersect);
3340
      intersect_scans_best= intersect_scans_end;
3341
      min_cost = intersect->total_cost;
3342
    }
3343
  }
3344
3345
  if (intersect_scans_best == intersect_scans)
3346
  {
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
3347
    return NULL;
1 by brian
clean slate
3348
  }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3349
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
3350
  print_ror_scans_arr(param->table,
1 by brian
clean slate
3351
                                          "best ROR-intersection",
3352
                                          intersect_scans,
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
3353
                                          intersect_scans_best);
1 by brian
clean slate
3354
3355
  *are_all_covering= intersect->is_covering;
482 by Brian Aker
Remove uint.
3356
  uint32_t best_num= intersect_scans_best - intersect_scans;
1 by brian
clean slate
3357
  ror_intersect_cpy(intersect, intersect_best);
3358
3359
  /*
3360
    Ok, found the best ROR-intersection of non-CPK key scans.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3361
    Check if we should add a CPK scan. If the obtained ROR-intersection is
1 by brian
clean slate
3362
    covering, it doesn't make sense to add CPK scan.
3363
  */
3364
  if (cpk_scan && !intersect->is_covering)
3365
  {
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3366
    if (ror_intersect_add(intersect, cpk_scan, true) &&
1 by brian
clean slate
3367
        (intersect->total_cost < min_cost))
3368
    {
55 by brian
Update for using real bool types.
3369
      cpk_scan_used= true;
1 by brian
clean slate
3370
      intersect_best= intersect; //just set pointer here
3371
    }
3372
  }
3373
3374
  /* Ok, return ROR-intersect plan if we have found one */
3375
  TRP_ROR_INTERSECT *trp= NULL;
3376
  if (min_cost < read_time && (cpk_scan_used || best_num > 1))
3377
  {
3378
    if (!(trp= new (param->mem_root) TRP_ROR_INTERSECT))
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
3379
      return(trp);
1 by brian
clean slate
3380
    if (!(trp->first_scan=
3381
           (ROR_SCAN_INFO**)alloc_root(param->mem_root,
3382
                                       sizeof(ROR_SCAN_INFO*)*best_num)))
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
3383
      return NULL;
1 by brian
clean slate
3384
    memcpy(trp->first_scan, intersect_scans, best_num*sizeof(ROR_SCAN_INFO*));
3385
    trp->last_scan=  trp->first_scan + best_num;
3386
    trp->is_covering= intersect_best->is_covering;
3387
    trp->read_cost= intersect_best->total_cost;
3388
    /* Prevent divisons by zero */
3389
    ha_rows best_rows = double2rows(intersect_best->out_rows);
3390
    if (!best_rows)
3391
      best_rows= 1;
3392
    set_if_smaller(param->table->quick_condition_rows, best_rows);
3393
    trp->records= best_rows;
3394
    trp->index_scan_costs= intersect_best->index_scan_costs;
3395
    trp->cpk_scan= cpk_scan_used? cpk_scan: NULL;
3396
  }
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
3397
  return(trp);
1 by brian
clean slate
3398
}
3399
1005.2.3 by Monty Taylor
Further reversion of P.
3400
982.1.7 by Padraig O'Sullivan
Added a new helper function for testing and setting a bit in a bitset. Also,
3401
/*
1 by brian
clean slate
3402
  Get best covering ROR-intersection.
3403
  SYNOPSIS
3404
    get_best_covering_ror_intersect()
3405
      param     Parameter from test_quick_select function.
3406
      tree      SEL_TREE with sets of intervals for different keys.
3407
      read_time Don't return table read plans with cost > read_time.
3408
3409
  RETURN
3410
    Best covering ROR-intersection plan
3411
    NULL if no plan found.
3412
3413
  NOTES
3414
    get_best_ror_intersect must be called for a tree before calling this
3415
    function for it.
3416
    This function invalidates tree->ror_scans member values.
3417
3418
  The following approximate algorithm is used:
3419
    I=set of all covering indexes
3420
    F=set of all fields to cover
3421
    S={}
3422
3423
    do
3424
    {
3425
      Order I by (#covered fields in F desc,
3426
                  #components asc,
3427
                  number of first not covered component asc);
3428
      F=F-covered by first(I);
3429
      S=S+first(I);
3430
      I=I-first(I);
3431
    } while F is not empty.
3432
*/
3433
3434
static
3435
TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param,
3436
                                                   SEL_TREE *tree,
3437
                                                   double read_time)
3438
{
3439
  ROR_SCAN_INFO **ror_scan_mark;
3440
  ROR_SCAN_INFO **ror_scans_end= tree->ror_scans_end;
3441
3442
  for (ROR_SCAN_INFO **scan= tree->ror_scans; scan != ror_scans_end; ++scan)
3443
    (*scan)->key_components=
3444
      param->table->key_info[(*scan)->keynr].key_parts;
3445
3446
  /*
3447
    Run covering-ROR-search algorithm.
3448
    Assume set I is [ror_scan .. ror_scans_end)
3449
  */
3450
3451
  /*I=set of all covering indexes */
3452
  ror_scan_mark= tree->ror_scans;
3453
1005.2.3 by Monty Taylor
Further reversion of P.
3454
  MY_BITMAP *covered_fields= &param->tmp_covered_fields;
3455
  if (!covered_fields->bitmap)
3456
    covered_fields->bitmap= (my_bitmap_map*)alloc_root(param->mem_root,
3457
                                               param->fields_bitmap_size);
3458
  if (!covered_fields->bitmap ||
3459
      bitmap_init(covered_fields, covered_fields->bitmap,
1014.2.12 by Monty Taylor
Removed the thread-safe crap in MY_BITMAP. Also remove the temp-pool option for
3460
                  param->table->s->fields))
1005.2.3 by Monty Taylor
Further reversion of P.
3461
    return 0;
3462
  bitmap_clear_all(covered_fields);
1 by brian
clean slate
3463
3464
  double total_cost= 0.0f;
3465
  ha_rows records=0;
3466
  bool all_covered;
3467
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
3468
  print_ror_scans_arr(param->table,
1 by brian
clean slate
3469
                                           "building covering ROR-I",
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
3470
                                           ror_scan_mark, ror_scans_end);
1 by brian
clean slate
3471
  do
3472
  {
3473
    /*
3474
      Update changed sorting info:
3475
        #covered fields,
3476
	number of first not covered component
3477
      Calculate and save these values for each of remaining scans.
3478
    */
3479
    for (ROR_SCAN_INFO **scan= ror_scan_mark; scan != ror_scans_end; ++scan)
3480
    {
1005.2.3 by Monty Taylor
Further reversion of P.
3481
      bitmap_subtract(&(*scan)->covered_fields, covered_fields);
3482
      (*scan)->used_fields_covered=
3483
        bitmap_bits_set(&(*scan)->covered_fields);
3484
      (*scan)->first_uncovered_field=
3485
        bitmap_get_first(&(*scan)->covered_fields);
1 by brian
clean slate
3486
    }
3487
3488
    my_qsort(ror_scan_mark, ror_scans_end-ror_scan_mark, sizeof(ROR_SCAN_INFO*),
3489
             (qsort_cmp)cmp_ror_scan_info_covering);
3490
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
3491
    print_ror_scans_arr(param->table,
1 by brian
clean slate
3492
                                             "remaining scans",
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
3493
                                             ror_scan_mark, ror_scans_end);
1 by brian
clean slate
3494
3495
    /* I=I-first(I) */
3496
    total_cost += (*ror_scan_mark)->index_read_cost;
3497
    records += (*ror_scan_mark)->records;
3498
    if (total_cost > read_time)
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
3499
      return NULL;
1 by brian
clean slate
3500
    /* F=F-covered by first(I) */
1005.2.3 by Monty Taylor
Further reversion of P.
3501
    bitmap_union(covered_fields, &(*ror_scan_mark)->covered_fields);
3502
    all_covered= bitmap_is_subset(&param->needed_fields, covered_fields);
1 by brian
clean slate
3503
  } while ((++ror_scan_mark < ror_scans_end) && !all_covered);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3504
1 by brian
clean slate
3505
  if (!all_covered || (ror_scan_mark - tree->ror_scans) == 1)
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
3506
    return NULL;
1 by brian
clean slate
3507
3508
  /*
3509
    Ok, [tree->ror_scans .. ror_scan) holds covering index_intersection with
3510
    cost total_cost.
3511
  */
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
3512
  print_ror_scans_arr(param->table,
1 by brian
clean slate
3513
                                           "creating covering ROR-intersect",
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
3514
                                           tree->ror_scans, ror_scan_mark);
1 by brian
clean slate
3515
3516
  /* Add priority queue use cost. */
3517
  total_cost += rows2double(records)*
3518
                log((double)(ror_scan_mark - tree->ror_scans)) /
3519
                (TIME_FOR_COMPARE_ROWID * M_LN2);
3520
3521
  if (total_cost > read_time)
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
3522
    return NULL;
1 by brian
clean slate
3523
3524
  TRP_ROR_INTERSECT *trp;
3525
  if (!(trp= new (param->mem_root) TRP_ROR_INTERSECT))
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
3526
    return(trp);
482 by Brian Aker
Remove uint.
3527
  uint32_t best_num= (ror_scan_mark - tree->ror_scans);
1 by brian
clean slate
3528
  if (!(trp->first_scan= (ROR_SCAN_INFO**)alloc_root(param->mem_root,
3529
                                                     sizeof(ROR_SCAN_INFO*)*
3530
                                                     best_num)))
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
3531
    return NULL;
1 by brian
clean slate
3532
  memcpy(trp->first_scan, tree->ror_scans, best_num*sizeof(ROR_SCAN_INFO*));
3533
  trp->last_scan=  trp->first_scan + best_num;
55 by brian
Update for using real bool types.
3534
  trp->is_covering= true;
1 by brian
clean slate
3535
  trp->read_cost= total_cost;
3536
  trp->records= records;
3537
  trp->cpk_scan= NULL;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3538
  set_if_smaller(param->table->quick_condition_rows, records);
1 by brian
clean slate
3539
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
3540
  return(trp);
1 by brian
clean slate
3541
}
3542
3543
3544
/*
3545
  Get best "range" table read plan for given SEL_TREE, also update some info
3546
3547
  SYNOPSIS
3548
    get_key_scans_params()
3549
      param                    Parameters from test_quick_select
3550
      tree                     Make range select for this SEL_TREE
55 by brian
Update for using real bool types.
3551
      index_read_must_be_used  true <=> assume 'index only' option will be set
1 by brian
clean slate
3552
                               (except for clustered PK indexes)
55 by brian
Update for using real bool types.
3553
      update_tbl_stats         true <=> update table->quick_* with information
1 by brian
clean slate
3554
                               about range scans we've evaluated.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3555
      read_time                Maximum cost. i.e. don't create read plans with
1 by brian
clean slate
3556
                               cost > read_time.
3557
3558
  DESCRIPTION
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3559
    Find the best "range" table read plan for given SEL_TREE.
3560
    The side effects are
1 by brian
clean slate
3561
     - tree->ror_scans is updated to indicate which scans are ROR scans.
55 by brian
Update for using real bool types.
3562
     - if update_tbl_stats=true then table->quick_* is updated with info
1 by brian
clean slate
3563
       about every possible range scan.
3564
3565
  RETURN
3566
    Best range read plan
3567
    NULL if no plan found or error occurred
3568
*/
3569
3570
static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3571
                                       bool index_read_must_be_used,
1 by brian
clean slate
3572
                                       bool update_tbl_stats,
3573
                                       double read_time)
3574
{
482 by Brian Aker
Remove uint.
3575
  uint32_t idx;
1 by brian
clean slate
3576
  SEL_ARG **key,**end, **key_to_read= NULL;
3577
  ha_rows best_records= 0;
482 by Brian Aker
Remove uint.
3578
  uint32_t    best_mrr_flags= 0, best_buf_size= 0;
1 by brian
clean slate
3579
  TRP_RANGE* read_plan= NULL;
3580
  /*
3581
    Note that there may be trees that have type SEL_TREE::KEY but contain no
3582
    key reads at all, e.g. tree for expression "key1 is not null" where key1
3583
    is defined as "not null".
3584
  */
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
3585
  print_sel_tree(param, tree, &tree->keys_map, "tree scans");
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
3586
  tree->ror_scans_map.reset();
1 by brian
clean slate
3587
  tree->n_ror_scans= 0;
3588
  for (idx= 0,key=tree->keys, end=key+param->keys; key != end; key++,idx++)
3589
  {
3590
    if (*key)
3591
    {
3592
      ha_rows found_records;
3593
      COST_VECT cost;
3594
      double found_read_time;
482 by Brian Aker
Remove uint.
3595
      uint32_t mrr_flags, buf_size;
3596
      uint32_t keynr= param->real_keynr[idx];
1 by brian
clean slate
3597
      if ((*key)->type == SEL_ARG::MAYBE_KEY ||
3598
          (*key)->maybe_flag)
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
3599
        param->needed_reg->set(keynr);
1 by brian
clean slate
3600
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3601
      bool read_index_only= index_read_must_be_used ||
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
3602
                            param->table->covering_keys.test(keynr);
1 by brian
clean slate
3603
3604
      found_records= check_quick_select(param, idx, read_index_only, *key,
3605
                                        update_tbl_stats, &mrr_flags,
3606
                                        &buf_size, &cost);
3607
      found_read_time= cost.total_cost();
3608
      if ((found_records != HA_POS_ERROR) && param->is_ror_scan)
3609
      {
3610
        tree->n_ror_scans++;
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
3611
        tree->ror_scans_map.set(idx);
1 by brian
clean slate
3612
      }
3613
      if (read_time > found_read_time && found_records != HA_POS_ERROR)
3614
      {
3615
        read_time=    found_read_time;
3616
        best_records= found_records;
3617
        key_to_read=  key;
3618
        best_mrr_flags= mrr_flags;
3619
        best_buf_size=  buf_size;
3620
      }
3621
    }
3622
  }
3623
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
3624
  print_sel_tree(param, tree, &tree->ror_scans_map, "ROR scans");
1 by brian
clean slate
3625
  if (key_to_read)
3626
  {
3627
    idx= key_to_read - tree->keys;
3628
    if ((read_plan= new (param->mem_root) TRP_RANGE(*key_to_read, idx,
3629
                                                    best_mrr_flags)))
3630
    {
3631
      read_plan->records= best_records;
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
3632
      read_plan->is_ror= tree->ror_scans_map.test(idx);
1 by brian
clean slate
3633
      read_plan->read_cost= read_time;
3634
      read_plan->mrr_buf_size= best_buf_size;
3635
    }
3636
  }
3637
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
3638
  return(read_plan);
1 by brian
clean slate
3639
}
3640
3641
655 by Brian Aker
Yet more unused.... damn annoying... (also tossed some prototypes that were
3642
QUICK_SELECT_I *TRP_INDEX_MERGE::make_quick(PARAM *param, bool, MEM_ROOT *)
1 by brian
clean slate
3643
{
3644
  QUICK_INDEX_MERGE_SELECT *quick_imerge;
3645
  QUICK_RANGE_SELECT *quick;
3646
  /* index_merge always retrieves full rows, ignore retrieve_full_rows */
520.1.22 by Brian Aker
Second pass of thd cleanup
3647
  if (!(quick_imerge= new QUICK_INDEX_MERGE_SELECT(param->session, param->table)))
1 by brian
clean slate
3648
    return NULL;
3649
3650
  quick_imerge->records= records;
3651
  quick_imerge->read_time= read_cost;
3652
  for (TRP_RANGE **range_scan= range_scans; range_scan != range_scans_end;
3653
       range_scan++)
3654
  {
3655
    if (!(quick= (QUICK_RANGE_SELECT*)
55 by brian
Update for using real bool types.
3656
          ((*range_scan)->make_quick(param, false, &quick_imerge->alloc)))||
1 by brian
clean slate
3657
        quick_imerge->push_quick_back(quick))
3658
    {
3659
      delete quick;
3660
      delete quick_imerge;
3661
      return NULL;
3662
    }
3663
  }
3664
  return quick_imerge;
3665
}
3666
3667
QUICK_SELECT_I *TRP_ROR_INTERSECT::make_quick(PARAM *param,
3668
                                              bool retrieve_full_rows,
3669
                                              MEM_ROOT *parent_alloc)
3670
{
3671
  QUICK_ROR_INTERSECT_SELECT *quick_intrsect;
3672
  QUICK_RANGE_SELECT *quick;
3673
  MEM_ROOT *alloc;
3674
3675
  if ((quick_intrsect=
520.1.22 by Brian Aker
Second pass of thd cleanup
3676
         new QUICK_ROR_INTERSECT_SELECT(param->session, param->table,
1 by brian
clean slate
3677
                                        (retrieve_full_rows? (!is_covering) :
55 by brian
Update for using real bool types.
3678
                                         false),
1 by brian
clean slate
3679
                                        parent_alloc)))
3680
  {
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
3681
    print_ror_scans_arr(param->table,
1 by brian
clean slate
3682
                                             "creating ROR-intersect",
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
3683
                                             first_scan, last_scan);
1 by brian
clean slate
3684
    alloc= parent_alloc? parent_alloc: &quick_intrsect->alloc;
3685
    for (; first_scan != last_scan;++first_scan)
3686
    {
3687
      if (!(quick= get_quick_select(param, (*first_scan)->idx,
3688
                                    (*first_scan)->sel_arg,
3689
                                    HA_MRR_USE_DEFAULT_IMPL | HA_MRR_SORTED,
3690
                                    0, alloc)) ||
3691
          quick_intrsect->push_quick_back(quick))
3692
      {
3693
        delete quick_intrsect;
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
3694
        return NULL;
1 by brian
clean slate
3695
      }
3696
    }
3697
    if (cpk_scan)
3698
    {
3699
      if (!(quick= get_quick_select(param, cpk_scan->idx,
3700
                                    cpk_scan->sel_arg,
3701
                                    HA_MRR_USE_DEFAULT_IMPL | HA_MRR_SORTED,
3702
                                    0, alloc)))
3703
      {
3704
        delete quick_intrsect;
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
3705
        return NULL;
1 by brian
clean slate
3706
      }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3707
      quick->file= NULL;
1 by brian
clean slate
3708
      quick_intrsect->cpk_quick= quick;
3709
    }
3710
    quick_intrsect->records= records;
3711
    quick_intrsect->read_time= read_cost;
3712
  }
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
3713
  return(quick_intrsect);
1 by brian
clean slate
3714
}
3715
3716
655 by Brian Aker
Yet more unused.... damn annoying... (also tossed some prototypes that were
3717
QUICK_SELECT_I *TRP_ROR_UNION::make_quick(PARAM *param, bool, MEM_ROOT *)
1 by brian
clean slate
3718
{
3719
  QUICK_ROR_UNION_SELECT *quick_roru;
3720
  TABLE_READ_PLAN **scan;
3721
  QUICK_SELECT_I *quick;
3722
  /*
3723
    It is impossible to construct a ROR-union that will not retrieve full
3724
    rows, ignore retrieve_full_rows parameter.
3725
  */
520.1.22 by Brian Aker
Second pass of thd cleanup
3726
  if ((quick_roru= new QUICK_ROR_UNION_SELECT(param->session, param->table)))
1 by brian
clean slate
3727
  {
3728
    for (scan= first_ror; scan != last_ror; scan++)
3729
    {
55 by brian
Update for using real bool types.
3730
      if (!(quick= (*scan)->make_quick(param, false, &quick_roru->alloc)) ||
1 by brian
clean slate
3731
          quick_roru->push_quick_back(quick))
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
3732
        return NULL;
1 by brian
clean slate
3733
    }
3734
    quick_roru->records= records;
3735
    quick_roru->read_time= read_cost;
3736
  }
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
3737
  return(quick_roru);
1 by brian
clean slate
3738
}
3739
3740
3741
/*
3742
  Build a SEL_TREE for <> or NOT BETWEEN predicate
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3743
1 by brian
clean slate
3744
  SYNOPSIS
3745
    get_ne_mm_tree()
3746
      param       PARAM from SQL_SELECT::test_quick_select
3747
      cond_func   item for the predicate
3748
      field       field in the predicate
3749
      lt_value    constant that field should be smaller
3750
      gt_value    constant that field should be greaterr
3751
      cmp_type    compare type for the field
3752
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3753
  RETURN
1 by brian
clean slate
3754
    #  Pointer to tree built tree
3755
    0  on error
3756
*/
3757
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3758
static SEL_TREE *get_ne_mm_tree(RANGE_OPT_PARAM *param, Item_func *cond_func,
1 by brian
clean slate
3759
                                Field *field,
3760
                                Item *lt_value, Item *gt_value,
3761
                                Item_result cmp_type)
3762
{
3763
  SEL_TREE *tree;
3764
  tree= get_mm_parts(param, cond_func, field, Item_func::LT_FUNC,
3765
                     lt_value, cmp_type);
3766
  if (tree)
3767
  {
3768
    tree= tree_or(param, tree, get_mm_parts(param, cond_func, field,
3769
					    Item_func::GT_FUNC,
3770
					    gt_value, cmp_type));
3771
  }
3772
  return tree;
3773
}
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3774
1 by brian
clean slate
3775
3776
/*
3777
  Build a SEL_TREE for a simple predicate
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3778
1 by brian
clean slate
3779
  SYNOPSIS
3780
    get_func_mm_tree()
3781
      param       PARAM from SQL_SELECT::test_quick_select
3782
      cond_func   item for the predicate
3783
      field       field in the predicate
3784
      value       constant in the predicate
3785
      cmp_type    compare type for the field
55 by brian
Update for using real bool types.
3786
      inv         true <> NOT cond_func is considered
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3787
                  (makes sense only when cond_func is BETWEEN or IN)
1 by brian
clean slate
3788
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3789
  RETURN
1 by brian
clean slate
3790
    Pointer to the tree built tree
3791
*/
3792
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3793
static SEL_TREE *get_func_mm_tree(RANGE_OPT_PARAM *param, Item_func *cond_func,
1 by brian
clean slate
3794
                                  Field *field, Item *value,
3795
                                  Item_result cmp_type, bool inv)
3796
{
3797
  SEL_TREE *tree= 0;
3798
3799
  switch (cond_func->functype()) {
3800
3801
  case Item_func::NE_FUNC:
3802
    tree= get_ne_mm_tree(param, cond_func, field, value, value, cmp_type);
3803
    break;
3804
3805
  case Item_func::BETWEEN:
3806
  {
3807
    if (!value)
3808
    {
3809
      if (inv)
3810
      {
3811
        tree= get_ne_mm_tree(param, cond_func, field, cond_func->arguments()[1],
3812
                             cond_func->arguments()[2], cmp_type);
3813
      }
3814
      else
3815
      {
3816
        tree= get_mm_parts(param, cond_func, field, Item_func::GE_FUNC,
3817
		           cond_func->arguments()[1],cmp_type);
3818
        if (tree)
3819
        {
3820
          tree= tree_and(param, tree, get_mm_parts(param, cond_func, field,
3821
					           Item_func::LE_FUNC,
3822
					           cond_func->arguments()[2],
3823
                                                   cmp_type));
3824
        }
3825
      }
3826
    }
3827
    else
3828
      tree= get_mm_parts(param, cond_func, field,
3829
                         (inv ?
3830
                          (value == (Item*)1 ? Item_func::GT_FUNC :
3831
                                               Item_func::LT_FUNC):
3832
                          (value == (Item*)1 ? Item_func::LE_FUNC :
3833
                                               Item_func::GE_FUNC)),
3834
                         cond_func->arguments()[0], cmp_type);
3835
    break;
3836
  }
3837
  case Item_func::IN_FUNC:
3838
  {
3839
    Item_func_in *func=(Item_func_in*) cond_func;
3840
3841
    /*
3842
      Array for IN() is constructed when all values have the same result
3843
      type. Tree won't be built for values with different result types,
3844
      so we check it here to avoid unnecessary work.
3845
    */
3846
    if (!func->arg_types_compatible)
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3847
      break;
1 by brian
clean slate
3848
3849
    if (inv)
3850
    {
3851
      if (func->array && func->array->result_type() != ROW_RESULT)
3852
      {
3853
        /*
3854
          We get here for conditions in form "t.key NOT IN (c1, c2, ...)",
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3855
          where c{i} are constants. Our goal is to produce a SEL_TREE that
1 by brian
clean slate
3856
          represents intervals:
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3857
1 by brian
clean slate
3858
          ($MIN<t.key<c1) OR (c1<t.key<c2) OR (c2<t.key<c3) OR ...    (*)
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3859
1 by brian
clean slate
3860
          where $MIN is either "-inf" or NULL.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3861
1 by brian
clean slate
3862
          The most straightforward way to produce it is to convert NOT IN
3863
          into "(t.key != c1) AND (t.key != c2) AND ... " and let the range
3864
          analyzer to build SEL_TREE from that. The problem is that the
3865
          range analyzer will use O(N^2) memory (which is probably a bug),
3866
          and people do use big NOT IN lists (e.g. see BUG#15872, BUG#21282),
3867
          will run out of memory.
3868
3869
          Another problem with big lists like (*) is that a big list is
3870
          unlikely to produce a good "range" access, while considering that
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3871
          range access will require expensive CPU calculations (and for
1 by brian
clean slate
3872
          MyISAM even index accesses). In short, big NOT IN lists are rarely
3873
          worth analyzing.
3874
3875
          Considering the above, we'll handle NOT IN as follows:
3876
          * if the number of entries in the NOT IN list is less than
3877
            NOT_IN_IGNORE_THRESHOLD, construct the SEL_TREE (*) manually.
3878
          * Otherwise, don't produce a SEL_TREE.
3879
        */
3880
#define NOT_IN_IGNORE_THRESHOLD 1000
3881
        MEM_ROOT *tmp_root= param->mem_root;
520.1.22 by Brian Aker
Second pass of thd cleanup
3882
        param->session->mem_root= param->old_root;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3883
        /*
1 by brian
clean slate
3884
          Create one Item_type constant object. We'll need it as
3885
          get_mm_parts only accepts constant values wrapped in Item_Type
3886
          objects.
3887
          We create the Item on param->mem_root which points to
520.1.22 by Brian Aker
Second pass of thd cleanup
3888
          per-statement mem_root (while session->mem_root is currently pointing
1 by brian
clean slate
3889
          to mem_root local to range optimizer).
3890
        */
3891
        Item *value_item= func->array->create_item();
520.1.22 by Brian Aker
Second pass of thd cleanup
3892
        param->session->mem_root= tmp_root;
1 by brian
clean slate
3893
3894
        if (func->array->count > NOT_IN_IGNORE_THRESHOLD || !value_item)
3895
          break;
3896
3897
        /* Get a SEL_TREE for "(-inf|NULL) < X < c_0" interval.  */
482 by Brian Aker
Remove uint.
3898
        uint32_t i=0;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3899
        do
1 by brian
clean slate
3900
        {
3901
          func->array->value_to_item(i, value_item);
3902
          tree= get_mm_parts(param, cond_func, field, Item_func::LT_FUNC,
3903
                             value_item, cmp_type);
3904
          if (!tree)
3905
            break;
3906
          i++;
3907
        } while (i < func->array->count && tree->type == SEL_TREE::IMPOSSIBLE);
3908
3909
        if (!tree || tree->type == SEL_TREE::IMPOSSIBLE)
3910
        {
3911
          /* We get here in cases like "t.unsigned NOT IN (-1,-2,-3) */
3912
          tree= NULL;
3913
          break;
3914
        }
3915
        SEL_TREE *tree2;
3916
        for (; i < func->array->count; i++)
3917
        {
3918
          if (func->array->compare_elems(i, i-1))
3919
          {
3920
            /* Get a SEL_TREE for "-inf < X < c_i" interval */
3921
            func->array->value_to_item(i, value_item);
3922
            tree2= get_mm_parts(param, cond_func, field, Item_func::LT_FUNC,
3923
                                value_item, cmp_type);
3924
            if (!tree2)
3925
            {
3926
              tree= NULL;
3927
              break;
3928
            }
3929
3930
            /* Change all intervals to be "c_{i-1} < X < c_i" */
482 by Brian Aker
Remove uint.
3931
            for (uint32_t idx= 0; idx < param->keys; idx++)
1 by brian
clean slate
3932
            {
3933
              SEL_ARG *new_interval, *last_val;
3934
              if (((new_interval= tree2->keys[idx])) &&
3935
                  (tree->keys[idx]) &&
3936
                  ((last_val= tree->keys[idx]->last())))
3937
              {
3938
                new_interval->min_value= last_val->max_value;
3939
                new_interval->min_flag= NEAR_MIN;
3940
              }
3941
            }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3942
            /*
1 by brian
clean slate
3943
              The following doesn't try to allocate memory so no need to
3944
              check for NULL.
3945
            */
3946
            tree= tree_or(param, tree, tree2);
3947
          }
3948
        }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3949
1 by brian
clean slate
3950
        if (tree && tree->type != SEL_TREE::IMPOSSIBLE)
3951
        {
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3952
          /*
3953
            Get the SEL_TREE for the last "c_last < X < +inf" interval
1 by brian
clean slate
3954
            (value_item cotains c_last already)
3955
          */
3956
          tree2= get_mm_parts(param, cond_func, field, Item_func::GT_FUNC,
3957
                              value_item, cmp_type);
3958
          tree= tree_or(param, tree, tree2);
3959
        }
3960
      }
3961
      else
3962
      {
3963
        tree= get_ne_mm_tree(param, cond_func, field,
3964
                             func->arguments()[1], func->arguments()[1],
3965
                             cmp_type);
3966
        if (tree)
3967
        {
3968
          Item **arg, **end;
3969
          for (arg= func->arguments()+2, end= arg+func->argument_count()-2;
3970
               arg < end ; arg++)
3971
          {
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3972
            tree=  tree_and(param, tree, get_ne_mm_tree(param, cond_func, field,
1 by brian
clean slate
3973
                                                        *arg, *arg, cmp_type));
3974
          }
3975
        }
3976
      }
3977
    }
3978
    else
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3979
    {
1 by brian
clean slate
3980
      tree= get_mm_parts(param, cond_func, field, Item_func::EQ_FUNC,
3981
                         func->arguments()[1], cmp_type);
3982
      if (tree)
3983
      {
3984
        Item **arg, **end;
3985
        for (arg= func->arguments()+2, end= arg+func->argument_count()-2;
3986
             arg < end ; arg++)
3987
        {
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3988
          tree= tree_or(param, tree, get_mm_parts(param, cond_func, field,
1 by brian
clean slate
3989
                                                  Item_func::EQ_FUNC,
3990
                                                  *arg, cmp_type));
3991
        }
3992
      }
3993
    }
3994
    break;
3995
  }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3996
  default:
1 by brian
clean slate
3997
  {
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3998
    /*
1 by brian
clean slate
3999
       Here the function for the following predicates are processed:
4000
       <, <=, =, >=, >, LIKE, IS NULL, IS NOT NULL.
4001
       If the predicate is of the form (value op field) it is handled
4002
       as the equivalent predicate (field rev_op value), e.g.
4003
       2 <= a is handled as a >= 2.
4004
    */
4005
    Item_func::Functype func_type=
4006
      (value != cond_func->arguments()[0]) ? cond_func->functype() :
4007
        ((Item_bool_func2*) cond_func)->rev_functype();
4008
    tree= get_mm_parts(param, cond_func, field, func_type, value, cmp_type);
4009
  }
4010
  }
4011
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
4012
  return(tree);
1 by brian
clean slate
4013
}
4014
4015
4016
/*
4017
  Build conjunction of all SEL_TREEs for a simple predicate applying equalities
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
4018
1 by brian
clean slate
4019
  SYNOPSIS
4020
    get_full_func_mm_tree()
4021
      param       PARAM from SQL_SELECT::test_quick_select
4022
      cond_func   item for the predicate
4023
      field_item  field in the predicate
4024
      value       constant in the predicate
4025
                  (for BETWEEN it contains the number of the field argument,
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
4026
                   for IN it's always 0)
55 by brian
Update for using real bool types.
4027
      inv         true <> NOT cond_func is considered
1 by brian
clean slate
4028
                  (makes sense only when cond_func is BETWEEN or IN)
4029
4030
  DESCRIPTION
4031
    For a simple SARGable predicate of the form (f op c), where f is a field and
4032
    c is a constant, the function builds a conjunction of all SEL_TREES that can
4033
    be obtained by the substitution of f for all different fields equal to f.
4034
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
4035
  NOTES
1 by brian
clean slate
4036
    If the WHERE condition contains a predicate (fi op c),
4037
    then not only SELL_TREE for this predicate is built, but
4038
    the trees for the results of substitution of fi for
4039
    each fj belonging to the same multiple equality as fi
4040
    are built as well.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
4041
    E.g. for WHERE t1.a=t2.a AND t2.a > 10
1 by brian
clean slate
4042
    a SEL_TREE for t2.a > 10 will be built for quick select from t2
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
4043
    and
1 by brian
clean slate
4044
    a SEL_TREE for t1.a > 10 will be built for quick select from t1.
4045
4046
    A BETWEEN predicate of the form (fi [NOT] BETWEEN c1 AND c2) is treated
4047
    in a similar way: we build a conjuction of trees for the results
4048
    of all substitutions of fi for equal fj.
4049
    Yet a predicate of the form (c BETWEEN f1i AND f2i) is processed
4050
    differently. It is considered as a conjuction of two SARGable
4051
    predicates (f1i <= c) and (f2i <=c) and the function get_full_func_mm_tree
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
4052
    is called for each of them separately producing trees for
4053
       AND j (f1j <=c ) and AND j (f2j <= c)
1 by brian
clean slate
4054
    After this these two trees are united in one conjunctive tree.
4055
    It's easy to see that the same tree is obtained for
4056
       AND j,k (f1j <=c AND f2k<=c)
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
4057
    which is equivalent to
1 by brian
clean slate
4058
       AND j,k (c BETWEEN f1j AND f2k).
4059
    The validity of the processing of the predicate (c NOT BETWEEN f1i AND f2i)
4060
    which equivalent to (f1i > c OR f2i < c) is not so obvious. Here the
4061
    function get_full_func_mm_tree is called for (f1i > c) and (f2i < c)
4062
    producing trees for AND j (f1j > c) and AND j (f2j < c). Then this two
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
4063
    trees are united in one OR-tree. The expression
1 by brian
clean slate
4064
      (AND j (f1j > c) OR AND j (f2j < c)
4065
    is equivalent to the expression
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
4066
      AND j,k (f1j > c OR f2k < c)
4067
    which is just a translation of
1 by brian
clean slate
4068
      AND j,k (c NOT BETWEEN f1j AND f2k)
4069
4070
    In the cases when one of the items f1, f2 is a constant c1 we do not create
4071
    a tree for it at all. It works for BETWEEN predicates but does not
4072
    work for NOT BETWEEN predicates as we have to evaluate the expression
55 by brian
Update for using real bool types.
4073
    with it. If it is true then the other tree can be completely ignored.
1 by brian
clean slate
4074
    We do not do it now and no trees are built in these cases for
4075
    NOT BETWEEN predicates.
4076
4077
    As to IN predicates only ones of the form (f IN (c1,...,cn)),
4078
    where f1 is a field and c1,...,cn are constant, are considered as
4079
    SARGable. We never try to narrow the index scan using predicates of
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
4080
    the form (c IN (c1,...,f,...,cn)).
4081
4082
  RETURN
1 by brian
clean slate
4083
    Pointer to the tree representing the built conjunction of SEL_TREEs
4084
*/
4085
4086
static SEL_TREE *get_full_func_mm_tree(RANGE_OPT_PARAM *param,
4087
                                       Item_func *cond_func,
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
4088
                                       Item_field *field_item, Item *value,
1 by brian
clean slate
4089
                                       bool inv)
4090
{
4091
  SEL_TREE *tree= 0;
4092
  SEL_TREE *ftree= 0;
4093
  table_map ref_tables= 0;
4094
  table_map param_comp= ~(param->prev_tables | param->read_tables |
4095
		          param->current_table);
4096
482 by Brian Aker
Remove uint.
4097
  for (uint32_t i= 0; i < cond_func->arg_count; i++)
1 by brian
clean slate
4098
  {
4099
    Item *arg= cond_func->arguments()[i]->real_item();
4100
    if (arg != field_item)
4101
      ref_tables|= arg->used_tables();
4102
  }
4103
  Field *field= field_item->field;
4104
  Item_result cmp_type= field->cmp_type();
4105
  if (!((ref_tables | field->table->map) & param_comp))
4106
    ftree= get_func_mm_tree(param, cond_func, field, value, cmp_type, inv);
4107
  Item_equal *item_equal= field_item->item_equal;
4108
  if (item_equal)
4109
  {
4110
    Item_equal_iterator it(*item_equal);
4111
    Item_field *item;
4112
    while ((item= it++))
4113
    {
4114
      Field *f= item->field;
4115
      if (field->eq(f))
4116
        continue;
4117
      if (!((ref_tables | f->table->map) & param_comp))
4118
      {
4119
        tree= get_func_mm_tree(param, cond_func, f, value, cmp_type, inv);
4120
        ftree= !ftree ? tree : tree_and(param, ftree, tree);
4121
      }
4122
    }
4123
  }
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
4124
  return(ftree);
1 by brian
clean slate
4125
}
4126
4127
	/* make a select tree of all keys in condition */
4128
4129
static SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param,COND *cond)
4130
{
4131
  SEL_TREE *tree=0;
4132
  SEL_TREE *ftree= 0;
4133
  Item_field *field_item= 0;
55 by brian
Update for using real bool types.
4134
  bool inv= false;
1 by brian
clean slate
4135
  Item *value= 0;
4136
4137
  if (cond->type() == Item::COND_ITEM)
4138
  {
4139
    List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
4140
4141
    if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
4142
    {
4143
      tree=0;
4144
      Item *item;
4145
      while ((item=li++))
4146
      {
4147
	SEL_TREE *new_tree=get_mm_tree(param,item);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
4148
	if (param->session->is_fatal_error ||
1 by brian
clean slate
4149
            param->alloced_sel_args > SEL_ARG::MAX_SEL_ARGS)
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
4150
	  return 0;	// out of memory
1 by brian
clean slate
4151
	tree=tree_and(param,tree,new_tree);
4152
	if (tree && tree->type == SEL_TREE::IMPOSSIBLE)
4153
	  break;
4154
      }
4155
    }
4156
    else
4157
    {						// COND OR
4158
      tree=get_mm_tree(param,li++);
4159
      if (tree)
4160
      {
4161
	Item *item;
4162
	while ((item=li++))
4163
	{
4164
	  SEL_TREE *new_tree=get_mm_tree(param,item);
4165
	  if (!new_tree)
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
4166
	    return 0;	// out of memory
1 by brian
clean slate
4167
	  tree=tree_or(param,tree,new_tree);
4168
	  if (!tree || tree->type == SEL_TREE::ALWAYS)
4169
	    break;
4170
	}
4171
      }
4172
    }
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
4173
    return(tree);
1 by brian
clean slate
4174
  }
4175
  /* Here when simple cond */
4176
  if (cond->const_item())
4177
  {
4178
    /*
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
4179
      During the cond->val_int() evaluation we can come across a subselect
4180
      item which may allocate memory on the session->mem_root and assumes
4181
      all the memory allocated has the same life span as the subselect
1 by brian
clean slate
4182
      item itself. So we have to restore the thread's mem_root here.
4183
    */
4184
    MEM_ROOT *tmp_root= param->mem_root;
520.1.22 by Brian Aker
Second pass of thd cleanup
4185
    param->session->mem_root= param->old_root;
1 by brian
clean slate
4186
    tree= cond->val_int() ? new(tmp_root) SEL_TREE(SEL_TREE::ALWAYS) :
4187
                            new(tmp_root) SEL_TREE(SEL_TREE::IMPOSSIBLE);
520.1.22 by Brian Aker
Second pass of thd cleanup
4188
    param->session->mem_root= tmp_root;
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
4189
    return(tree);
1 by brian
clean slate
4190
  }
4191
4192
  table_map ref_tables= 0;
4193
  table_map param_comp= ~(param->prev_tables | param->read_tables |
4194
		          param->current_table);
4195
  if (cond->type() != Item::FUNC_ITEM)
4196
  {						// Should be a field
4197
    ref_tables= cond->used_tables();
4198
    if ((ref_tables & param->current_table) ||
4199
	(ref_tables & ~(param->prev_tables | param->read_tables)))
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
4200
      return 0;
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
4201
    return(new SEL_TREE(SEL_TREE::MAYBE));
1 by brian
clean slate
4202
  }
4203
4204
  Item_func *cond_func= (Item_func*) cond;
4205
  if (cond_func->functype() == Item_func::BETWEEN ||
4206
      cond_func->functype() == Item_func::IN_FUNC)
4207
    inv= ((Item_func_opt_neg *) cond_func)->negated;
4208
  else if (cond_func->select_optimize() == Item_func::OPTIMIZE_NONE)
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
4209
    return 0;
1 by brian
clean slate
4210
4211
  param->cond= cond;
4212
4213
  switch (cond_func->functype()) {
4214
  case Item_func::BETWEEN:
4215
    if (cond_func->arguments()[0]->real_item()->type() == Item::FIELD_ITEM)
4216
    {
4217
      field_item= (Item_field*) (cond_func->arguments()[0]->real_item());
4218
      ftree= get_full_func_mm_tree(param, cond_func, field_item, NULL, inv);
4219
    }
4220
4221
    /*
4222
      Concerning the code below see the NOTES section in
4223
      the comments for the function get_full_func_mm_tree()
4224
    */
482 by Brian Aker
Remove uint.
4225
    for (uint32_t i= 1 ; i < cond_func->arg_count ; i++)
1 by brian
clean slate
4226
    {
4227
      if (cond_func->arguments()[i]->real_item()->type() == Item::FIELD_ITEM)
4228
      {
4229
        field_item= (Item_field*) (cond_func->arguments()[i]->real_item());
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
4230
        SEL_TREE *tmp= get_full_func_mm_tree(param, cond_func,
157 by Brian Aker
Second pass cleanup on removal of my_uint types
4231
                                    field_item, (Item*)(intptr_t)i, inv);
1 by brian
clean slate
4232
        if (inv)
4233
          tree= !tree ? tmp : tree_or(param, tree, tmp);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
4234
        else
1 by brian
clean slate
4235
          tree= tree_and(param, tree, tmp);
4236
      }
4237
      else if (inv)
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
4238
      {
1 by brian
clean slate
4239
        tree= 0;
4240
        break;
4241
      }
4242
    }
4243
4244
    ftree = tree_and(param, ftree, tree);
4245
    break;
4246
  case Item_func::IN_FUNC:
4247
  {
4248
    Item_func_in *func=(Item_func_in*) cond_func;
4249
    if (func->key_item()->real_item()->type() != Item::FIELD_ITEM)
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
4250
      return 0;
1 by brian
clean slate
4251
    field_item= (Item_field*) (func->key_item()->real_item());
4252
    ftree= get_full_func_mm_tree(param, cond_func, field_item, NULL, inv);
4253
    break;
4254
  }
4255
  case Item_func::MULT_EQUAL_FUNC:
4256
  {
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
4257
    Item_equal *item_equal= (Item_equal *) cond;
1 by brian
clean slate
4258
    if (!(value= item_equal->get_const()))
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
4259
      return 0;
1 by brian
clean slate
4260
    Item_equal_iterator it(*item_equal);
4261
    ref_tables= value->used_tables();
4262
    while ((field_item= it++))
4263
    {
4264
      Field *field= field_item->field;
4265
      Item_result cmp_type= field->cmp_type();
4266
      if (!((ref_tables | field->table->map) & param_comp))
4267
      {
4268
        tree= get_mm_parts(param, cond, field, Item_func::EQ_FUNC,
4269
		           value,cmp_type);
4270
        ftree= !ftree ? tree : tree_and(param, ftree, tree);
4271
      }
4272
    }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
4273
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
4274
    return(ftree);
1 by brian
clean slate
4275
  }
4276
  default:
4277
    if (cond_func->arguments()[0]->real_item()->type() == Item::FIELD_ITEM)
4278
    {
4279
      field_item= (Item_field*) (cond_func->arguments()[0]->real_item());
4280
      value= cond_func->arg_count > 1 ? cond_func->arguments()[1] : 0;
4281
    }
4282
    else if (cond_func->have_rev_func() &&
4283
             cond_func->arguments()[1]->real_item()->type() ==
4284
                                                            Item::FIELD_ITEM)
4285
    {
4286
      field_item= (Item_field*) (cond_func->arguments()[1]->real_item());
4287
      value= cond_func->arguments()[0];
4288
    }
4289
    else
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
4290
      return 0;
1 by brian
clean slate
4291
    ftree= get_full_func_mm_tree(param, cond_func, field_item, value, inv);
4292
  }
4293
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
4294
  return(ftree);
1 by brian
clean slate
4295
}
4296
4297
4298
static SEL_TREE *
4299
get_mm_parts(RANGE_OPT_PARAM *param, COND *cond_func, Field *field,
4300
	     Item_func::Functype type,
655 by Brian Aker
Yet more unused.... damn annoying... (also tossed some prototypes that were
4301
	     Item *value, Item_result)
1 by brian
clean slate
4302
{
4303
  if (field->table != param->table)
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
4304
    return 0;
1 by brian
clean slate
4305
4306
  KEY_PART *key_part = param->key_parts;
4307
  KEY_PART *end = param->key_parts_end;
4308
  SEL_TREE *tree=0;
4309
  if (value &&
4310
      value->used_tables() & ~(param->prev_tables | param->read_tables))
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
4311
    return 0;
1 by brian
clean slate
4312
  for (; key_part != end ; key_part++)
4313
  {
4314
    if (field->eq(key_part->field))
4315
    {
4316
      SEL_ARG *sel_arg=0;
4317
      if (!tree && !(tree=new SEL_TREE()))
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
4318
	return 0;				// OOM
1 by brian
clean slate
4319
      if (!value || !(value->used_tables() & ~param->read_tables))
4320
      {
4321
	sel_arg=get_mm_leaf(param,cond_func,
4322
			    key_part->field,key_part,type,value);
4323
	if (!sel_arg)
4324
	  continue;
4325
	if (sel_arg->type == SEL_ARG::IMPOSSIBLE)
4326
	{
4327
	  tree->type=SEL_TREE::IMPOSSIBLE;
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
4328
	  return(tree);
1 by brian
clean slate
4329
	}
4330
      }
4331
      else
4332
      {
4333
	// This key may be used later
4334
	if (!(sel_arg= new SEL_ARG(SEL_ARG::MAYBE_KEY)))
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
4335
	  return 0;			// OOM
1 by brian
clean slate
4336
      }
481 by Brian Aker
Remove all of uchar.
4337
      sel_arg->part=(unsigned char) key_part->part;
1 by brian
clean slate
4338
      tree->keys[key_part->key]=sel_add(tree->keys[key_part->key],sel_arg);
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
4339
      tree->keys_map.set(key_part->key);
1 by brian
clean slate
4340
    }
4341
  }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
4342
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
4343
  return(tree);
1 by brian
clean slate
4344
}
4345
4346
4347
static SEL_ARG *
4348
get_mm_leaf(RANGE_OPT_PARAM *param, COND *conf_func, Field *field,
4349
            KEY_PART *key_part, Item_func::Functype type,Item *value)
4350
{
895 by Brian Aker
Completion (?) of uint conversion.
4351
  uint32_t maybe_null=(uint32_t) field->real_maybe_null();
1 by brian
clean slate
4352
  bool optimize_range;
4353
  SEL_ARG *tree= 0;
4354
  MEM_ROOT *alloc= param->mem_root;
481 by Brian Aker
Remove all of uchar.
4355
  unsigned char *str;
910.2.7 by Monty Taylor
Merged from Jay.
4356
  int err= 0;
1 by brian
clean slate
4357
4358
  /*
4359
    We need to restore the runtime mem_root of the thread in this
4360
    function because it evaluates the value of its argument, while
4361
    the argument can be any, e.g. a subselect. The subselect
4362
    items, in turn, assume that all the memory allocated during
4363
    the evaluation has the same life span as the item itself.
520.1.22 by Brian Aker
Second pass of thd cleanup
4364
    TODO: opt_range.cc should not reset session->mem_root at all.
1 by brian
clean slate
4365
  */
520.1.22 by Brian Aker
Second pass of thd cleanup
4366
  param->session->mem_root= param->old_root;
1 by brian
clean slate
4367
  if (!value)					// IS NULL or IS NOT NULL
4368
  {
4369
    if (field->table->maybe_null)		// Can't use a key on this
4370
      goto end;
4371
    if (!maybe_null)				// Not null field
4372
    {
4373
      if (type == Item_func::ISNULL_FUNC)
4374
        tree= &null_element;
4375
      goto end;
4376
    }
4377
    if (!(tree= new (alloc) SEL_ARG(field,is_null_string,is_null_string)))
4378
      goto end;                                 // out of memory
4379
    if (type == Item_func::ISNOTNULL_FUNC)
4380
    {
4381
      tree->min_flag=NEAR_MIN;		    /* IS NOT NULL ->  X > NULL */
4382
      tree->max_flag=NO_MAX_RANGE;
4383
    }
4384
    goto end;
4385
  }
4386
4387
  /*
4388
    1. Usually we can't use an index if the column collation
4389
       differ from the operation collation.
4390
4391
    2. However, we can reuse a case insensitive index for
4392
       the binary searches:
4393
4394
       WHERE latin1_swedish_ci_column = 'a' COLLATE lati1_bin;
4395
4396
       WHERE latin1_swedish_ci_colimn = BINARY 'a '
4397
4398
  */
4399
  if (field->result_type() == STRING_RESULT &&
4400
      value->result_type() == STRING_RESULT &&
4401
      key_part->image_type == Field::itRAW &&
4402
      ((Field_str*)field)->charset() != conf_func->compare_collation() &&
4403
      !(conf_func->compare_collation()->state & MY_CS_BINSORT))
4404
    goto end;
4405
4406
  if (param->using_real_indexes)
4407
    optimize_range= field->optimize_range(param->real_keynr[key_part->key],
4408
                                          key_part->part);
4409
  else
55 by brian
Update for using real bool types.
4410
    optimize_range= true;
1 by brian
clean slate
4411
4412
  if (type == Item_func::LIKE_FUNC)
4413
  {
4414
    bool like_error;
4415
    char buff1[MAX_FIELD_WIDTH];
481 by Brian Aker
Remove all of uchar.
4416
    unsigned char *min_str,*max_str;
1 by brian
clean slate
4417
    String tmp(buff1,sizeof(buff1),value->collation.collation),*res;
4418
    size_t length, offset, min_length, max_length;
482 by Brian Aker
Remove uint.
4419
    uint32_t field_length= field->pack_length()+maybe_null;
1 by brian
clean slate
4420
4421
    if (!optimize_range)
4422
      goto end;
4423
    if (!(res= value->val_str(&tmp)))
4424
    {
4425
      tree= &null_element;
4426
      goto end;
4427
    }
4428
4429
    /*
4430
      TODO:
4431
      Check if this was a function. This should have be optimized away
4432
      in the sql_select.cc
4433
    */
4434
    if (res != &tmp)
4435
    {
4436
      tmp.copy(*res);				// Get own copy
4437
      res= &tmp;
4438
    }
4439
    if (field->cmp_type() != STRING_RESULT)
4440
      goto end;                                 // Can only optimize strings
4441
4442
    offset=maybe_null;
4443
    length=key_part->store_length;
4444
4445
    if (length != key_part->length  + maybe_null)
4446
    {
4447
      /* key packed with length prefix */
4448
      offset+= HA_KEY_BLOB_LENGTH;
4449
      field_length= length - HA_KEY_BLOB_LENGTH;
4450
    }
4451
    else
4452
    {
4453
      if (unlikely(length < field_length))
4454
      {
4455
	/*
4456
	  This can only happen in a table created with UNIREG where one key
4457
	  overlaps many fields
4458
	*/
4459
	length= field_length;
4460
      }
4461
      else
4462
	field_length= length;
4463
    }
4464
    length+=offset;
481 by Brian Aker
Remove all of uchar.
4465
    if (!(min_str= (unsigned char*) alloc_root(alloc, length*2)))
1 by brian
clean slate
4466
      goto end;
4467
4468
    max_str=min_str+length;
4469
    if (maybe_null)
4470
      max_str[0]= min_str[0]=0;
4471
4472
    field_length-= maybe_null;
4473
    like_error= my_like_range(field->charset(),
4474
			      res->ptr(), res->length(),
4475
			      ((Item_func_like*)(param->cond))->escape,
4476
			      wild_one, wild_many,
4477
			      field_length,
4478
			      (char*) min_str+offset, (char*) max_str+offset,
4479
			      &min_length, &max_length);
4480
    if (like_error)				// Can't optimize with LIKE
4481
      goto end;
4482
4483
    if (offset != maybe_null)			// BLOB or VARCHAR
4484
    {
4485
      int2store(min_str+maybe_null,min_length);
4486
      int2store(max_str+maybe_null,max_length);
4487
    }
4488
    tree= new (alloc) SEL_ARG(field, min_str, max_str);
4489
    goto end;
4490
  }
4491
4492
  if (!optimize_range &&
4493
      type != Item_func::EQ_FUNC &&
4494
      type != Item_func::EQUAL_FUNC)
4495
    goto end;                                   // Can't optimize this
4496
4497
  /*
4498
    We can't always use indexes when comparing a string index to a number
4499
    cmp_type() is checked to allow compare of dates to numbers
4500
  */
4501
  if (field->result_type() == STRING_RESULT &&
4502
      value->result_type() != STRING_RESULT &&
4503
      field->cmp_type() != value->result_type())
4504
    goto end;
907.1.7 by Jay Pipes
Merged in remove-timezone work
4505
4506
  /*
4507
   * Some notes from Jay...
4508
   *
4509
   * OK, so previously, and in MySQL, what the optimizer does here is
4510
   * override the sql_mode variable to ignore out-of-range or bad date-
4511
   * time values.  It does this because the optimizer is populating the
4512
   * field variable with the incoming value from the comparison field, 
4513
   * and the value may exceed the bounds of a proper column type.
4514
   *
4515
   * For instance, assume the following:
4516
   *
4517
   * CREATE TABLE t1 (ts TIMESTAMP); 
4518
   * INSERT INTO t1 ('2009-03-04 00:00:00');
4519
   * CREATE TABLE t2 (dt1 DATETIME, dt2 DATETIME); 
4520
   * INSERT INT t2 ('2003-12-31 00:00:00','2999-12-31 00:00:00');
4521
   *
4522
   * If we issue this query:
4523
   *
4524
   * SELECT * FROM t1, t2 WHERE t1.ts BETWEEN t2.dt1 AND t2.dt2;
4525
   *
4526
   * We will come into bounds issues.  Field_timestamp::store() will be
4527
   * called with a datetime value of "2999-12-31 00:00:00" and will throw
4528
   * an error for out-of-bounds.  MySQL solves this via a hack with sql_mode
4529
   * but Drizzle always throws errors on bad data storage in a Field class.
4530
   *
4531
   * Therefore, to get around the problem of the Field class being used for
4532
   * "storage" here without actually storing anything...we must check to see 
4533
   * if the value being stored in a Field_timestamp here is out of range.  If
4534
   * it is, then we must convert to the highest Timestamp value (or lowest,
4535
   * depending on whether the datetime is before or after the epoch.
4536
   */
4537
  if (field->type() == DRIZZLE_TYPE_TIMESTAMP)
4538
  {
4539
    /* 
4540
     * The left-side of the range comparison is a timestamp field.  Therefore, 
4541
     * we must check to see if the value in the right-hand side is outside the
4542
     * range of the UNIX epoch, and cut to the epoch bounds if it is.
4543
     */
4544
    /* Datetime and date columns are Item::FIELD_ITEM ... and have a result type of STRING_RESULT */
4545
    if (value->real_item()->type() == Item::FIELD_ITEM
4546
        && value->result_type() == STRING_RESULT)
4547
    {
4548
      char buff[MAX_DATETIME_FULL_WIDTH];
4549
      String tmp(buff, sizeof(buff), &my_charset_bin);
4550
      String *res= value->val_str(&tmp);
4551
4552
      if (!res)
4553
        goto end;
4554
      else
4555
      {
4556
        /* 
4557
         * Create a datetime from the string and compare to fixed timestamp
4558
         * instances representing the epoch boundaries.
4559
         */
4560
        drizzled::DateTime value_datetime;
4561
4562
        if (! value_datetime.from_string(res->c_ptr(), (size_t) res->length()))
4563
          goto end;
4564
4565
        drizzled::Timestamp max_timestamp;
4566
        drizzled::Timestamp min_timestamp;
4567
4568
        (void) max_timestamp.from_time_t((time_t) INT32_MAX);
4569
        (void) min_timestamp.from_time_t((time_t) 0);
4570
4571
        /* We rely on Temporal class operator overloads to do our comparisons. */
4572
        if (value_datetime < min_timestamp)
4573
        {
4574
          /* 
4575
           * Datetime in right-hand side column is before UNIX epoch, so adjust to
4576
           * lower bound.
4577
           */
4578
          char new_value_buff[MAX_DATETIME_FULL_WIDTH];
4579
          size_t new_value_length;
4580
          String new_value_string(new_value_buff, sizeof(new_value_buff), &my_charset_bin);
4581
4582
          min_timestamp.to_string(new_value_string.c_ptr(), &new_value_length);
4583
          new_value_string.length(new_value_length);
4584
          err= value->save_str_value_in_field(field, &new_value_string);
4585
        }
4586
        else if (value_datetime > max_timestamp)
4587
        {
4588
          /*
4589
           * Datetime in right hand side column is after UNIX epoch, so adjust
4590
           * to the higher bound of the epoch.
4591
           */
4592
          char new_value_buff[MAX_DATETIME_FULL_WIDTH];
4593
          size_t new_value_length;
4594
          String new_value_string(new_value_buff, sizeof(new_value_buff), &my_charset_bin);
4595
4596
          max_timestamp.to_string(new_value_string.c_ptr(), &new_value_length);
4597
          new_value_string.length(new_value_length);
4598
          err= value->save_str_value_in_field(field, &new_value_string);
4599
        }
4600
        else
4601
          err= value->save_in_field(field, 1);
4602
      }
4603
    }
4604
    else /* Not a datetime -> timestamp comparison */
4605
      err= value->save_in_field(field, 1);
4606
  }
4607
  else /* Not a timestamp comparison */
4608
    err= value->save_in_field(field, 1);
4609
1 by brian
clean slate
4610
  if (err > 0)
4611
  {
4612
    if (field->cmp_type() != value->result_type())
4613
    {
4614
      if ((type == Item_func::EQ_FUNC || type == Item_func::EQUAL_FUNC) &&
4615
          value->result_type() == item_cmp_type(field->result_type(),
4616
                                                value->result_type()))
4617
      {
4618
        tree= new (alloc) SEL_ARG(field, 0, 0);
4619
        tree->type= SEL_ARG::IMPOSSIBLE;
4620
        goto end;
4621
      }
4622
      else
4623
      {
4624
        /*
4625
          TODO: We should return trees of the type SEL_ARG::IMPOSSIBLE
4626
          for the cases like int_field > 999999999999999999999999 as well.
4627
        */
4628
        tree= 0;
575.5.1 by David Axmark
Changed NEWDATE to DATE. One failing test but I think its somewhere else in the code
4629
        if (err == 3 && field->type() == DRIZZLE_TYPE_DATE &&
1 by brian
clean slate
4630
            (type == Item_func::GT_FUNC || type == Item_func::GE_FUNC ||
4631
             type == Item_func::LT_FUNC || type == Item_func::LE_FUNC) )
4632
        {
4633
          /*
4634
            We were saving DATETIME into a DATE column, the conversion went ok
4635
            but a non-zero time part was cut off.
4636
4637
            In MySQL's SQL dialect, DATE and DATETIME are compared as datetime
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
4638
            values. Index over a DATE column uses DATE comparison. Changing
1 by brian
clean slate
4639
            from one comparison to the other is possible:
4640
4641
            datetime(date_col)< '2007-12-10 12:34:55' -> date_col<='2007-12-10'
4642
            datetime(date_col)<='2007-12-10 12:34:55' -> date_col<='2007-12-10'
4643
4644
            datetime(date_col)> '2007-12-10 12:34:55' -> date_col>='2007-12-10'
4645
            datetime(date_col)>='2007-12-10 12:34:55' -> date_col>='2007-12-10'
4646
4647
            but we'll need to convert '>' to '>=' and '<' to '<='. This will
4648
            be done together with other types at the end of this function
4649
            (grep for field_is_equal_to_item)
4650
          */
4651
        }
4652
        else
4653
          goto end;
4654
      }
4655
    }
4656
4657
    /*
4658
      guaranteed at this point:  err > 0; field and const of same type
4659
      If an integer got bounded (e.g. to within 0..255 / -128..127)
4660
      for < or >, set flags as for <= or >= (no NEAR_MAX / NEAR_MIN)
4661
    */
4662
    else if (err == 1 && field->result_type() == INT_RESULT)
4663
    {
4664
      if (type == Item_func::LT_FUNC && (value->val_int() > 0))
4665
        type = Item_func::LE_FUNC;
4666
      else if (type == Item_func::GT_FUNC &&
4667
               !((Field_num*)field)->unsigned_flag &&
4668
               !((Item_int*)value)->unsigned_flag &&
4669
               (value->val_int() < 0))
4670
        type = Item_func::GE_FUNC;
4671
    }
4672
  }
4673
  else if (err < 0)
4674
  {
4675
    /* This happens when we try to insert a NULL field in a not null column */
55 by brian
Update for using real bool types.
4676
    tree= &null_element;                        // cmp with NULL is never true
1 by brian
clean slate
4677
    goto end;
4678
  }
481 by Brian Aker
Remove all of uchar.
4679
  str= (unsigned char*) alloc_root(alloc, key_part->store_length+1);
1 by brian
clean slate
4680
  if (!str)
4681
    goto end;
4682
  if (maybe_null)
481 by Brian Aker
Remove all of uchar.
4683
    *str= (unsigned char) field->is_real_null();        // Set to 1 if null
1 by brian
clean slate
4684
  field->get_key_image(str+maybe_null, key_part->length,
4685
                       key_part->image_type);
4686
  if (!(tree= new (alloc) SEL_ARG(field, str, str)))
4687
    goto end;                                   // out of memory
4688
4689
  /*
4690
    Check if we are comparing an UNSIGNED integer with a negative constant.
4691
    In this case we know that:
55 by brian
Update for using real bool types.
4692
    (a) (unsigned_int [< | <=] negative_constant) == false
4693
    (b) (unsigned_int [> | >=] negative_constant) == true
1 by brian
clean slate
4694
    In case (a) the condition is false for all values, and in case (b) it
4695
    is true for all values, so we can avoid unnecessary retrieval and condition
4696
    testing, and we also get correct comparison of unsinged integers with
4697
    negative integers (which otherwise fails because at query execution time
4698
    negative integers are cast to unsigned if compared with unsigned).
4699
   */
4700
  if (field->result_type() == INT_RESULT &&
4701
      value->result_type() == INT_RESULT &&
4702
      ((Field_num*)field)->unsigned_flag && !((Item_int*)value)->unsigned_flag)
4703
  {
152 by Brian Aker
longlong replacement
4704
    int64_t item_val= value->val_int();
1 by brian
clean slate
4705
    if (item_val < 0)
4706
    {
4707
      if (type == Item_func::LT_FUNC || type == Item_func::LE_FUNC)
4708
      {
4709
        tree->type= SEL_ARG::IMPOSSIBLE;
4710
        goto end;
4711
      }
4712
      if (type == Item_func::GT_FUNC || type == Item_func::GE_FUNC)
4713
      {
4714
        tree= 0;
4715
        goto end;
4716
      }
4717
    }
4718
  }
4719
4720
  switch (type) {
4721
  case Item_func::LT_FUNC:
4722
    if (field_is_equal_to_item(field,value))
4723
      tree->max_flag=NEAR_MAX;
4724
    /* fall through */
4725
  case Item_func::LE_FUNC:
4726
    if (!maybe_null)
4727
      tree->min_flag=NO_MIN_RANGE;		/* From start */
4728
    else
4729
    {						// > NULL
4730
      tree->min_value=is_null_string;
4731
      tree->min_flag=NEAR_MIN;
4732
    }
4733
    break;
4734
  case Item_func::GT_FUNC:
4735
    /* Don't use open ranges for partial key_segments */
4736
    if (field_is_equal_to_item(field,value) &&
4737
        !(key_part->flag & HA_PART_KEY_SEG))
4738
      tree->min_flag=NEAR_MIN;
4739
    /* fall through */
4740
  case Item_func::GE_FUNC:
4741
    tree->max_flag=NO_MAX_RANGE;
4742
    break;
4743
  default:
4744
    break;
4745
  }
4746
4747
end:
520.1.22 by Brian Aker
Second pass of thd cleanup
4748
  param->session->mem_root= alloc;
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
4749
  return(tree);
1 by brian
clean slate
4750
}
4751
4752
4753
/******************************************************************************
4754
** Tree manipulation functions
4755
** If tree is 0 it means that the condition can't be tested. It refers
4756
** to a non existent table or to a field in current table with isn't a key.
4757
** The different tree flags:
55 by brian
Update for using real bool types.
4758
** IMPOSSIBLE:	 Condition is never true
4759
** ALWAYS:	 Condition is always true
1 by brian
clean slate
4760
** MAYBE:	 Condition may exists when tables are read
4761
** MAYBE_KEY:	 Condition refers to a key that may be used in join loop
4762
** KEY_RANGE:	 Condition uses a key
4763
******************************************************************************/
4764
4765
/*
4766
  Add a new key test to a key when scanning through all keys
4767
  This will never be called for same key parts.
4768
*/
4769
4770
static SEL_ARG *
4771
sel_add(SEL_ARG *key1,SEL_ARG *key2)
4772
{
4773
  SEL_ARG *root,**key_link;
4774
4775
  if (!key1)
4776
    return key2;
4777
  if (!key2)
4778
    return key1;
4779
4780
  key_link= &root;
4781
  while (key1 && key2)
4782
  {
4783
    if (key1->part < key2->part)
4784
    {
4785
      *key_link= key1;
4786
      key_link= &key1->next_key_part;
4787
      key1=key1->next_key_part;
4788
    }
4789
    else
4790
    {
4791
      *key_link= key2;
4792
      key_link= &key2->next_key_part;
4793
      key2=key2->next_key_part;
4794
    }
4795
  }
4796
  *key_link=key1 ? key1 : key2;
4797
  return root;
4798
}
4799
4800
#define CLONE_KEY1_MAYBE 1
4801
#define CLONE_KEY2_MAYBE 2
4802
#define swap_clone_flag(A) ((A & 1) << 1) | ((A & 2) >> 1)
4803
4804
4805
static SEL_TREE *
4806
tree_and(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2)
4807
{
4808
  if (!tree1)
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
4809
    return(tree2);
1 by brian
clean slate
4810
  if (!tree2)
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
4811
    return(tree1);
1 by brian
clean slate
4812
  if (tree1->type == SEL_TREE::IMPOSSIBLE || tree2->type == SEL_TREE::ALWAYS)
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
4813
    return(tree1);
1 by brian
clean slate
4814
  if (tree2->type == SEL_TREE::IMPOSSIBLE || tree1->type == SEL_TREE::ALWAYS)
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
4815
    return(tree2);
1 by brian
clean slate
4816
  if (tree1->type == SEL_TREE::MAYBE)
4817
  {
4818
    if (tree2->type == SEL_TREE::KEY)
4819
      tree2->type=SEL_TREE::KEY_SMALLER;
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
4820
    return(tree2);
1 by brian
clean slate
4821
  }
4822
  if (tree2->type == SEL_TREE::MAYBE)
4823
  {
4824
    tree1->type=SEL_TREE::KEY_SMALLER;
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
4825
    return(tree1);
1 by brian
clean slate
4826
  }
4827
  key_map  result_keys;
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
4828
  result_keys.reset();
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
4829
1 by brian
clean slate
4830
  /* Join the trees key per key */
4831
  SEL_ARG **key1,**key2,**end;
4832
  for (key1= tree1->keys,key2= tree2->keys,end=key1+param->keys ;
4833
       key1 != end ; key1++,key2++)
4834
  {
482 by Brian Aker
Remove uint.
4835
    uint32_t flag=0;
1 by brian
clean slate
4836
    if (*key1 || *key2)
4837
    {
4838
      if (*key1 && !(*key1)->simple_key())
4839
	flag|=CLONE_KEY1_MAYBE;
4840
      if (*key2 && !(*key2)->simple_key())
4841
	flag|=CLONE_KEY2_MAYBE;
4842
      *key1=key_and(param, *key1, *key2, flag);
4843
      if (*key1 && (*key1)->type == SEL_ARG::IMPOSSIBLE)
4844
      {
4845
	tree1->type= SEL_TREE::IMPOSSIBLE;
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
4846
        return(tree1);
1 by brian
clean slate
4847
      }
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
4848
      result_keys.set(key1 - tree1->keys);
1 by brian
clean slate
4849
#ifdef EXTRA_DEBUG
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
4850
        if (*key1 && param->alloced_sel_args < SEL_ARG::MAX_SEL_ARGS)
1 by brian
clean slate
4851
          (*key1)->test_use_count(*key1);
4852
#endif
4853
    }
4854
  }
4855
  tree1->keys_map= result_keys;
4856
  /* dispose index_merge if there is a "range" option */
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
4857
  if (result_keys.any())
1 by brian
clean slate
4858
  {
4859
    tree1->merges.empty();
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
4860
    return(tree1);
1 by brian
clean slate
4861
  }
4862
4863
  /* ok, both trees are index_merge trees */
4864
  imerge_list_and_list(&tree1->merges, &tree2->merges);
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
4865
  return(tree1);
1 by brian
clean slate
4866
}
4867
4868
4869
/*
4870
  Check if two SEL_TREES can be combined into one (i.e. a single key range
4871
  read can be constructed for "cond_of_tree1 OR cond_of_tree2" ) without
4872
  using index_merge.
4873
*/
4874
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
4875
bool sel_trees_can_be_ored(SEL_TREE *tree1, SEL_TREE *tree2,
1 by brian
clean slate
4876
                           RANGE_OPT_PARAM* param)
4877
{
4878
  key_map common_keys= tree1->keys_map;
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
4879
  common_keys&= tree2->keys_map;
1 by brian
clean slate
4880
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
4881
  if (common_keys.none())
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
4882
    return false;
1 by brian
clean slate
4883
4884
  /* trees have a common key, check if they refer to same key part */
4885
  SEL_ARG **key1,**key2;
482 by Brian Aker
Remove uint.
4886
  for (uint32_t key_no=0; key_no < param->keys; key_no++)
1 by brian
clean slate
4887
  {
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
4888
    if (common_keys.test(key_no))
1 by brian
clean slate
4889
    {
4890
      key1= tree1->keys + key_no;
4891
      key2= tree2->keys + key_no;
4892
      if ((*key1)->part == (*key2)->part)
4893
      {
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
4894
        return true;
1 by brian
clean slate
4895
      }
4896
    }
4897
  }
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
4898
  return false;
1 by brian
clean slate
4899
}
4900
4901
4902
/*
4903
  Remove the trees that are not suitable for record retrieval.
4904
  SYNOPSIS
4905
    param  Range analysis parameter
4906
    tree   Tree to be processed, tree->type is KEY or KEY_SMALLER
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
4907
1 by brian
clean slate
4908
  DESCRIPTION
4909
    This function walks through tree->keys[] and removes the SEL_ARG* trees
4910
    that are not "maybe" trees (*) and cannot be used to construct quick range
4911
    selects.
4912
    (*) - have type MAYBE or MAYBE_KEY. Perhaps we should remove trees of
4913
          these types here as well.
4914
4915
    A SEL_ARG* tree cannot be used to construct quick select if it has
4916
    tree->part != 0. (e.g. it could represent "keypart2 < const").
4917
4918
    WHY THIS FUNCTION IS NEEDED
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
4919
1 by brian
clean slate
4920
    Normally we allow construction of SEL_TREE objects that have SEL_ARG
4921
    trees that do not allow quick range select construction. For example for
4922
    " keypart1=1 AND keypart2=2 " the execution will proceed as follows:
4923
    tree1= SEL_TREE { SEL_ARG{keypart1=1} }
4924
    tree2= SEL_TREE { SEL_ARG{keypart2=2} } -- can't make quick range select
4925
                                               from this
4926
    call tree_and(tree1, tree2) -- this joins SEL_ARGs into a usable SEL_ARG
4927
                                   tree.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
4928
1 by brian
clean slate
4929
    There is an exception though: when we construct index_merge SEL_TREE,
4930
    any SEL_ARG* tree that cannot be used to construct quick range select can
4931
    be removed, because current range analysis code doesn't provide any way
4932
    that tree could be later combined with another tree.
4933
    Consider an example: we should not construct
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
4934
    st1 = SEL_TREE {
4935
      merges = SEL_IMERGE {
4936
                            SEL_TREE(t.key1part1 = 1),
1 by brian
clean slate
4937
                            SEL_TREE(t.key2part2 = 2)   -- (*)
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
4938
                          }
1 by brian
clean slate
4939
                   };
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
4940
    because
4941
     - (*) cannot be used to construct quick range select,
4942
     - There is no execution path that would cause (*) to be converted to
1 by brian
clean slate
4943
       a tree that could be used.
4944
4945
    The latter is easy to verify: first, notice that the only way to convert
4946
    (*) into a usable tree is to call tree_and(something, (*)).
4947
4948
    Second look at what tree_and/tree_or function would do when passed a
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
4949
    SEL_TREE that has the structure like st1 tree has, and conlcude that
1 by brian
clean slate
4950
    tree_and(something, (*)) will not be called.
4951
4952
  RETURN
4953
    0  Ok, some suitable trees left
4954
    1  No tree->keys[] left.
4955
*/
4956
4957
static bool remove_nonrange_trees(RANGE_OPT_PARAM *param, SEL_TREE *tree)
4958
{
55 by brian
Update for using real bool types.
4959
  bool res= false;
482 by Brian Aker
Remove uint.
4960
  for (uint32_t i=0; i < param->keys; i++)
1 by brian
clean slate
4961
  {
4962
    if (tree->keys[i])
4963
    {
4964
      if (tree->keys[i]->part)
4965
      {
4966
        tree->keys[i]= NULL;
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
4967
        tree->keys_map.reset(i);
1 by brian
clean slate
4968
      }
4969
      else
55 by brian
Update for using real bool types.
4970
        res= true;
1 by brian
clean slate
4971
    }
4972
  }
4973
  return !res;
4974
}
4975
4976
4977
static SEL_TREE *
4978
tree_or(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2)
4979
{
4980
  if (!tree1 || !tree2)
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
4981
    return 0;
1 by brian
clean slate
4982
  if (tree1->type == SEL_TREE::IMPOSSIBLE || tree2->type == SEL_TREE::ALWAYS)
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
4983
    return(tree2);
1 by brian
clean slate
4984
  if (tree2->type == SEL_TREE::IMPOSSIBLE || tree1->type == SEL_TREE::ALWAYS)
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
4985
    return(tree1);
1 by brian
clean slate
4986
  if (tree1->type == SEL_TREE::MAYBE)
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
4987
    return(tree1);				// Can't use this
1 by brian
clean slate
4988
  if (tree2->type == SEL_TREE::MAYBE)
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
4989
    return(tree2);
1 by brian
clean slate
4990
4991
  SEL_TREE *result= 0;
4992
  key_map  result_keys;
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
4993
  result_keys.reset();
1 by brian
clean slate
4994
  if (sel_trees_can_be_ored(tree1, tree2, param))
4995
  {
4996
    /* Join the trees key per key */
4997
    SEL_ARG **key1,**key2,**end;
4998
    for (key1= tree1->keys,key2= tree2->keys,end= key1+param->keys ;
4999
         key1 != end ; key1++,key2++)
5000
    {
5001
      *key1=key_or(param, *key1, *key2);
5002
      if (*key1)
5003
      {
5004
        result=tree1;				// Added to tree1
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
5005
        result_keys.set(key1 - tree1->keys);
1 by brian
clean slate
5006
#ifdef EXTRA_DEBUG
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
5007
        if (param->alloced_sel_args < SEL_ARG::MAX_SEL_ARGS)
1 by brian
clean slate
5008
          (*key1)->test_use_count(*key1);
5009
#endif
5010
      }
5011
    }
5012
    if (result)
5013
      result->keys_map= result_keys;
5014
  }
5015
  else
5016
  {
5017
    /* ok, two trees have KEY type but cannot be used without index merge */
5018
    if (tree1->merges.is_empty() && tree2->merges.is_empty())
5019
    {
5020
      if (param->remove_jump_scans)
5021
      {
5022
        bool no_trees= remove_nonrange_trees(param, tree1);
5023
        no_trees= no_trees || remove_nonrange_trees(param, tree2);
5024
        if (no_trees)
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
5025
          return(new SEL_TREE(SEL_TREE::ALWAYS));
1 by brian
clean slate
5026
      }
5027
      SEL_IMERGE *merge;
5028
      /* both trees are "range" trees, produce new index merge structure */
5029
      if (!(result= new SEL_TREE()) || !(merge= new SEL_IMERGE()) ||
5030
          (result->merges.push_back(merge)) ||
5031
          (merge->or_sel_tree(param, tree1)) ||
5032
          (merge->or_sel_tree(param, tree2)))
5033
        result= NULL;
5034
      else
5035
        result->type= tree1->type;
5036
    }
5037
    else if (!tree1->merges.is_empty() && !tree2->merges.is_empty())
5038
    {
5039
      if (imerge_list_or_list(param, &tree1->merges, &tree2->merges))
5040
        result= new SEL_TREE(SEL_TREE::ALWAYS);
5041
      else
5042
        result= tree1;
5043
    }
5044
    else
5045
    {
5046
      /* one tree is index merge tree and another is range tree */
5047
      if (tree1->merges.is_empty())
322.2.2 by Mats Kindahl
Hiding THD::proc_info field and providing a setter and getter.
5048
        std::swap(tree1, tree2);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
5049
1 by brian
clean slate
5050
      if (param->remove_jump_scans && remove_nonrange_trees(param, tree2))
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
5051
         return(new SEL_TREE(SEL_TREE::ALWAYS));
1 by brian
clean slate
5052
      /* add tree2 to tree1->merges, checking if it collapses to ALWAYS */
5053
      if (imerge_list_or_tree(param, &tree1->merges, tree2))
5054
        result= new SEL_TREE(SEL_TREE::ALWAYS);
5055
      else
5056
        result= tree1;
5057
    }
5058
  }
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
5059
  return result;
1 by brian
clean slate
5060
}
5061
5062
5063
/* And key trees where key1->part < key2 -> part */
5064
5065
static SEL_ARG *
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
5066
and_all_keys(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2,
482 by Brian Aker
Remove uint.
5067
             uint32_t clone_flag)
1 by brian
clean slate
5068
{
5069
  SEL_ARG *next;
5070
  ulong use_count=key1->use_count;
5071
5072
  if (key1->elements != 1)
5073
  {
5074
    key2->use_count+=key1->elements-1; //psergey: why we don't count that key1 has n-k-p?
5075
    key2->increment_use_count((int) key1->elements-1);
5076
  }
5077
  if (key1->type == SEL_ARG::MAYBE_KEY)
5078
  {
5079
    key1->right= key1->left= &null_element;
5080
    key1->next= key1->prev= 0;
5081
  }
5082
  for (next=key1->first(); next ; next=next->next)
5083
  {
5084
    if (next->next_key_part)
5085
    {
5086
      SEL_ARG *tmp= key_and(param, next->next_key_part, key2, clone_flag);
5087
      if (tmp && tmp->type == SEL_ARG::IMPOSSIBLE)
5088
      {
5089
	key1=key1->tree_delete(next);
5090
	continue;
5091
      }
5092
      next->next_key_part=tmp;
5093
      if (use_count)
5094
	next->increment_use_count(use_count);
5095
      if (param->alloced_sel_args > SEL_ARG::MAX_SEL_ARGS)
5096
        break;
5097
    }
5098
    else
5099
      next->next_key_part=key2;
5100
  }
5101
  if (!key1)
5102
    return &null_element;			// Impossible ranges
5103
  key1->use_count++;
5104
  return key1;
5105
}
5106
5107
5108
/*
5109
  Produce a SEL_ARG graph that represents "key1 AND key2"
5110
5111
  SYNOPSIS
5112
    key_and()
5113
      param   Range analysis context (needed to track if we have allocated
5114
              too many SEL_ARGs)
5115
      key1    First argument, root of its RB-tree
5116
      key2    Second argument, root of its RB-tree
5117
5118
  RETURN
5119
    RB-tree root of the resulting SEL_ARG graph.
5120
    NULL if the result of AND operation is an empty interval {0}.
5121
*/
5122
5123
static SEL_ARG *
482 by Brian Aker
Remove uint.
5124
key_and(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2, uint32_t clone_flag)
1 by brian
clean slate
5125
{
5126
  if (!key1)
5127
    return key2;
5128
  if (!key2)
5129
    return key1;
5130
  if (key1->part != key2->part)
5131
  {
5132
    if (key1->part > key2->part)
5133
    {
322.2.2 by Mats Kindahl
Hiding THD::proc_info field and providing a setter and getter.
5134
      std::swap(key1, key2);
1 by brian
clean slate
5135
      clone_flag=swap_clone_flag(clone_flag);
5136
    }
5137
    // key1->part < key2->part
5138
    key1->use_count--;
5139
    if (key1->use_count > 0)
5140
      if (!(key1= key1->clone_tree(param)))
5141
	return 0;				// OOM
5142
    return and_all_keys(param, key1, key2, clone_flag);
5143
  }
5144
5145
  if (((clone_flag & CLONE_KEY2_MAYBE) &&
5146
       !(clone_flag & CLONE_KEY1_MAYBE) &&
5147
       key2->type != SEL_ARG::MAYBE_KEY) ||
5148
      key1->type == SEL_ARG::MAYBE_KEY)
5149
  {						// Put simple key in key2
322.2.2 by Mats Kindahl
Hiding THD::proc_info field and providing a setter and getter.
5150
    std::swap(key1, key2);
1 by brian
clean slate
5151
    clone_flag=swap_clone_flag(clone_flag);
5152
  }
5153
5154
  /* If one of the key is MAYBE_KEY then the found region may be smaller */
5155
  if (key2->type == SEL_ARG::MAYBE_KEY)
5156
  {
5157
    if (key1->use_count > 1)
5158
    {
5159
      key1->use_count--;
5160
      if (!(key1=key1->clone_tree(param)))
5161
	return 0;				// OOM
5162
      key1->use_count++;
5163
    }
5164
    if (key1->type == SEL_ARG::MAYBE_KEY)
5165
    {						// Both are maybe key
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
5166
      key1->next_key_part=key_and(param, key1->next_key_part,
1 by brian
clean slate
5167
                                  key2->next_key_part, clone_flag);
5168
      if (key1->next_key_part &&
5169
	  key1->next_key_part->type == SEL_ARG::IMPOSSIBLE)
5170
	return key1;
5171
    }
5172
    else
5173
    {
5174
      key1->maybe_smaller();
5175
      if (key2->next_key_part)
5176
      {
5177
	key1->use_count--;			// Incremented in and_all_keys
5178
	return and_all_keys(param, key1, key2, clone_flag);
5179
      }
5180
      key2->use_count--;			// Key2 doesn't have a tree
5181
    }
5182
    return key1;
5183
  }
5184
5185
  key1->use_count--;
5186
  key2->use_count--;
5187
  SEL_ARG *e1=key1->first(), *e2=key2->first(), *new_tree=0;
5188
5189
  while (e1 && e2)
5190
  {
5191
    int cmp=e1->cmp_min_to_min(e2);
5192
    if (cmp < 0)
5193
    {
5194
      if (get_range(&e1,&e2,key1))
5195
	continue;
5196
    }
5197
    else if (get_range(&e2,&e1,key2))
5198
      continue;
5199
    SEL_ARG *next=key_and(param, e1->next_key_part, e2->next_key_part,
5200
                          clone_flag);
5201
    e1->increment_use_count(1);
5202
    e2->increment_use_count(1);
5203
    if (!next || next->type != SEL_ARG::IMPOSSIBLE)
5204
    {
5205
      SEL_ARG *new_arg= e1->clone_and(e2);
5206
      if (!new_arg)
5207
	return &null_element;			// End of memory
5208
      new_arg->next_key_part=next;
5209
      if (!new_tree)
5210
      {
5211
	new_tree=new_arg;
5212
      }
5213
      else
5214
	new_tree=new_tree->insert(new_arg);
5215
    }
5216
    if (e1->cmp_max_to_max(e2) < 0)
5217
      e1=e1->next;				// e1 can't overlapp next e2
5218
    else
5219
      e2=e2->next;
5220
  }
5221
  key1->free_tree();
5222
  key2->free_tree();
5223
  if (!new_tree)
5224
    return &null_element;			// Impossible range
5225
  return new_tree;
5226
}
5227
5228
5229
static bool
5230
get_range(SEL_ARG **e1,SEL_ARG **e2,SEL_ARG *root1)
5231
{
5232
  (*e1)=root1->find_range(*e2);			// first e1->min < e2->min
5233
  if ((*e1)->cmp_max_to_min(*e2) < 0)
5234
  {
5235
    if (!((*e1)=(*e1)->next))
5236
      return 1;
5237
    if ((*e1)->cmp_min_to_max(*e2) > 0)
5238
    {
5239
      (*e2)=(*e2)->next;
5240
      return 1;
5241
    }
5242
  }
5243
  return 0;
5244
}
5245
5246
5247
static SEL_ARG *
5248
key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1,SEL_ARG *key2)
5249
{
5250
  if (!key1)
5251
  {
5252
    if (key2)
5253
    {
5254
      key2->use_count--;
5255
      key2->free_tree();
5256
    }
5257
    return 0;
5258
  }
5259
  if (!key2)
5260
  {
5261
    key1->use_count--;
5262
    key1->free_tree();
5263
    return 0;
5264
  }
5265
  key1->use_count--;
5266
  key2->use_count--;
5267
5268
  if (key1->part != key2->part)
5269
  {
5270
    key1->free_tree();
5271
    key2->free_tree();
5272
    return 0;					// Can't optimize this
5273
  }
5274
5275
  // If one of the key is MAYBE_KEY then the found region may be bigger
5276
  if (key1->type == SEL_ARG::MAYBE_KEY)
5277
  {
5278
    key2->free_tree();
5279
    key1->use_count++;
5280
    return key1;
5281
  }
5282
  if (key2->type == SEL_ARG::MAYBE_KEY)
5283
  {
5284
    key1->free_tree();
5285
    key2->use_count++;
5286
    return key2;
5287
  }
5288
5289
  if (key1->use_count > 0)
5290
  {
5291
    if (key2->use_count == 0 || key1->elements > key2->elements)
5292
    {
322.2.2 by Mats Kindahl
Hiding THD::proc_info field and providing a setter and getter.
5293
      std::swap(key1,key2);
1 by brian
clean slate
5294
    }
5295
    if (key1->use_count > 0 || !(key1=key1->clone_tree(param)))
5296
      return 0;					// OOM
5297
  }
5298
5299
  // Add tree at key2 to tree at key1
5300
  bool key2_shared=key2->use_count != 0;
5301
  key1->maybe_flag|=key2->maybe_flag;
5302
5303
  for (key2=key2->first(); key2; )
5304
  {
5305
    SEL_ARG *tmp=key1->find_range(key2);	// Find key1.min <= key2.min
5306
    int cmp;
5307
5308
    if (!tmp)
5309
    {
5310
      tmp=key1->first();			// tmp.min > key2.min
5311
      cmp= -1;
5312
    }
5313
    else if ((cmp=tmp->cmp_max_to_min(key2)) < 0)
5314
    {						// Found tmp.max < key2.min
5315
      SEL_ARG *next=tmp->next;
5316
      if (cmp == -2 && eq_tree(tmp->next_key_part,key2->next_key_part))
5317
      {
5318
	// Join near ranges like tmp.max < 0 and key2.min >= 0
5319
	SEL_ARG *key2_next=key2->next;
5320
	if (key2_shared)
5321
	{
5322
	  if (!(key2=new SEL_ARG(*key2)))
5323
	    return 0;		// out of memory
5324
	  key2->increment_use_count(key1->use_count+1);
5325
	  key2->next=key2_next;			// New copy of key2
5326
	}
5327
	key2->copy_min(tmp);
5328
	if (!(key1=key1->tree_delete(tmp)))
5329
	{					// Only one key in tree
5330
	  key1=key2;
5331
	  key1->make_root();
5332
	  key2=key2_next;
5333
	  break;
5334
	}
5335
      }
5336
      if (!(tmp=next))				// tmp.min > key2.min
5337
	break;					// Copy rest of key2
5338
    }
5339
    if (cmp < 0)
5340
    {						// tmp.min > key2.min
5341
      int tmp_cmp;
5342
      if ((tmp_cmp=tmp->cmp_min_to_max(key2)) > 0) // if tmp.min > key2.max
5343
      {
5344
	if (tmp_cmp == 2 && eq_tree(tmp->next_key_part,key2->next_key_part))
5345
	{					// ranges are connected
5346
	  tmp->copy_min_to_min(key2);
5347
	  key1->merge_flags(key2);
5348
	  if (tmp->min_flag & NO_MIN_RANGE &&
5349
	      tmp->max_flag & NO_MAX_RANGE)
5350
	  {
5351
	    if (key1->maybe_flag)
5352
	      return new SEL_ARG(SEL_ARG::MAYBE_KEY);
5353
	    return 0;
5354
	  }
5355
	  key2->increment_use_count(-1);	// Free not used tree
5356
	  key2=key2->next;
5357
	  continue;
5358
	}
5359
	else
5360
	{
5361
	  SEL_ARG *next=key2->next;		// Keys are not overlapping
5362
	  if (key2_shared)
5363
	  {
5364
	    SEL_ARG *cpy= new SEL_ARG(*key2);	// Must make copy
5365
	    if (!cpy)
5366
	      return 0;				// OOM
5367
	    key1=key1->insert(cpy);
5368
	    key2->increment_use_count(key1->use_count+1);
5369
	  }
5370
	  else
5371
	    key1=key1->insert(key2);		// Will destroy key2_root
5372
	  key2=next;
5373
	  continue;
5374
	}
5375
      }
5376
    }
5377
398.1.4 by Monty Taylor
Renamed max/min.
5378
    // tmp.max >= key2.min && tmp.min <= key.cmax(overlapping ranges)
1 by brian
clean slate
5379
    if (eq_tree(tmp->next_key_part,key2->next_key_part))
5380
    {
5381
      if (tmp->is_same(key2))
5382
      {
5383
	tmp->merge_flags(key2);			// Copy maybe flags
5384
	key2->increment_use_count(-1);		// Free not used tree
5385
      }
5386
      else
5387
      {
5388
	SEL_ARG *last=tmp;
5389
	while (last->next && last->next->cmp_min_to_max(key2) <= 0 &&
5390
	       eq_tree(last->next->next_key_part,key2->next_key_part))
5391
	{
5392
	  SEL_ARG *save=last;
5393
	  last=last->next;
5394
	  key1=key1->tree_delete(save);
5395
	}
5396
        last->copy_min(tmp);
5397
	if (last->copy_min(key2) || last->copy_max(key2))
5398
	{					// Full range
5399
	  key1->free_tree();
5400
	  for (; key2 ; key2=key2->next)
5401
	    key2->increment_use_count(-1);	// Free not used tree
5402
	  if (key1->maybe_flag)
5403
	    return new SEL_ARG(SEL_ARG::MAYBE_KEY);
5404
	  return 0;
5405
	}
5406
      }
5407
      key2=key2->next;
5408
      continue;
5409
    }
5410
5411
    if (cmp >= 0 && tmp->cmp_min_to_min(key2) < 0)
5412
    {						// tmp.min <= x < key2.min
5413
      SEL_ARG *new_arg=tmp->clone_first(key2);
5414
      if (!new_arg)
5415
	return 0;				// OOM
5416
      if ((new_arg->next_key_part= key1->next_key_part))
5417
	new_arg->increment_use_count(key1->use_count+1);
5418
      tmp->copy_min_to_min(key2);
5419
      key1=key1->insert(new_arg);
5420
    }
5421
5422
    // tmp.min >= key2.min && tmp.min <= key2.max
5423
    SEL_ARG key(*key2);				// Get copy we can modify
5424
    for (;;)
5425
    {
5426
      if (tmp->cmp_min_to_min(&key) > 0)
5427
      {						// key.min <= x < tmp.min
5428
	SEL_ARG *new_arg=key.clone_first(tmp);
5429
	if (!new_arg)
5430
	  return 0;				// OOM
5431
	if ((new_arg->next_key_part=key.next_key_part))
5432
	  new_arg->increment_use_count(key1->use_count+1);
5433
	key1=key1->insert(new_arg);
5434
      }
5435
      if ((cmp=tmp->cmp_max_to_max(&key)) <= 0)
5436
      {						// tmp.min. <= x <= tmp.max
5437
	tmp->maybe_flag|= key.maybe_flag;
5438
	key.increment_use_count(key1->use_count+1);
5439
	tmp->next_key_part= key_or(param, tmp->next_key_part, key.next_key_part);
5440
	if (!cmp)				// Key2 is ready
5441
	  break;
5442
	key.copy_max_to_min(tmp);
5443
	if (!(tmp=tmp->next))
5444
	{
5445
	  SEL_ARG *tmp2= new SEL_ARG(key);
5446
	  if (!tmp2)
5447
	    return 0;				// OOM
5448
	  key1=key1->insert(tmp2);
5449
	  key2=key2->next;
5450
	  goto end;
5451
	}
5452
	if (tmp->cmp_min_to_max(&key) > 0)
5453
	{
5454
	  SEL_ARG *tmp2= new SEL_ARG(key);
5455
	  if (!tmp2)
5456
	    return 0;				// OOM
5457
	  key1=key1->insert(tmp2);
5458
	  break;
5459
	}
5460
      }
5461
      else
5462
      {
5463
	SEL_ARG *new_arg=tmp->clone_last(&key); // tmp.min <= x <= key.max
5464
	if (!new_arg)
5465
	  return 0;				// OOM
5466
	tmp->copy_max_to_min(&key);
5467
	tmp->increment_use_count(key1->use_count+1);
5468
	/* Increment key count as it may be used for next loop */
5469
	key.increment_use_count(1);
5470
	new_arg->next_key_part= key_or(param, tmp->next_key_part, key.next_key_part);
5471
	key1=key1->insert(new_arg);
5472
	break;
5473
      }
5474
    }
5475
    key2=key2->next;
5476
  }
5477
5478
end:
5479
  while (key2)
5480
  {
5481
    SEL_ARG *next=key2->next;
5482
    if (key2_shared)
5483
    {
5484
      SEL_ARG *tmp=new SEL_ARG(*key2);		// Must make copy
5485
      if (!tmp)
5486
	return 0;
5487
      key2->increment_use_count(key1->use_count+1);
5488
      key1=key1->insert(tmp);
5489
    }
5490
    else
5491
      key1=key1->insert(key2);			// Will destroy key2_root
5492
    key2=next;
5493
  }
5494
  key1->use_count++;
5495
  return key1;
5496
}
5497
5498
5499
/* Compare if two trees are equal */
5500
5501
static bool eq_tree(SEL_ARG* a,SEL_ARG *b)
5502
{
5503
  if (a == b)
5504
    return 1;
5505
  if (!a || !b || !a->is_same(b))
5506
    return 0;
5507
  if (a->left != &null_element && b->left != &null_element)
5508
  {
5509
    if (!eq_tree(a->left,b->left))
5510
      return 0;
5511
  }
5512
  else if (a->left != &null_element || b->left != &null_element)
5513
    return 0;
5514
  if (a->right != &null_element && b->right != &null_element)
5515
  {
5516
    if (!eq_tree(a->right,b->right))
5517
      return 0;
5518
  }
5519
  else if (a->right != &null_element || b->right != &null_element)
5520
    return 0;
5521
  if (a->next_key_part != b->next_key_part)
5522
  {						// Sub range
5523
    if (!a->next_key_part != !b->next_key_part ||
5524
	!eq_tree(a->next_key_part, b->next_key_part))
5525
      return 0;
5526
  }
5527
  return 1;
5528
}
5529
5530
5531
SEL_ARG *
5532
SEL_ARG::insert(SEL_ARG *key)
5533
{
5534
  SEL_ARG *element, **par= NULL, *last_element= NULL;
5535
5536
  for (element= this; element != &null_element ; )
5537
  {
5538
    last_element=element;
5539
    if (key->cmp_min_to_min(element) > 0)
5540
    {
5541
      par= &element->right; element= element->right;
5542
    }
5543
    else
5544
    {
5545
      par = &element->left; element= element->left;
5546
    }
5547
  }
5548
  *par=key;
5549
  key->parent=last_element;
5550
	/* Link in list */
5551
  if (par == &last_element->left)
5552
  {
5553
    key->next=last_element;
5554
    if ((key->prev=last_element->prev))
5555
      key->prev->next=key;
5556
    last_element->prev=key;
5557
  }
5558
  else
5559
  {
5560
    if ((key->next=last_element->next))
5561
      key->next->prev=key;
5562
    key->prev=last_element;
5563
    last_element->next=key;
5564
  }
5565
  key->left=key->right= &null_element;
5566
  SEL_ARG *root=rb_insert(key);			// rebalance tree
5567
  root->use_count=this->use_count;		// copy root info
5568
  root->elements= this->elements+1;
5569
  root->maybe_flag=this->maybe_flag;
5570
  return root;
5571
}
5572
5573
5574
/*
5575
** Find best key with min <= given key
5576
** Because the call context this should never return 0 to get_range
5577
*/
5578
5579
SEL_ARG *
5580
SEL_ARG::find_range(SEL_ARG *key)
5581
{
5582
  SEL_ARG *element=this,*found=0;
5583
5584
  for (;;)
5585
  {
5586
    if (element == &null_element)
5587
      return found;
5588
    int cmp=element->cmp_min_to_min(key);
5589
    if (cmp == 0)
5590
      return element;
5591
    if (cmp < 0)
5592
    {
5593
      found=element;
5594
      element=element->right;
5595
    }
5596
    else
5597
      element=element->left;
5598
  }
5599
}
5600
5601
5602
/*
5603
  Remove a element from the tree
5604
5605
  SYNOPSIS
5606
    tree_delete()
5607
    key		Key that is to be deleted from tree (this)
5608
5609
  NOTE
5610
    This also frees all sub trees that is used by the element
5611
5612
  RETURN
5613
    root of new tree (with key deleted)
5614
*/
5615
5616
SEL_ARG *
5617
SEL_ARG::tree_delete(SEL_ARG *key)
5618
{
5619
  enum leaf_color remove_color;
5620
  SEL_ARG *root,*nod,**par,*fix_par;
5621
5622
  root=this;
5623
  this->parent= 0;
5624
5625
  /* Unlink from list */
5626
  if (key->prev)
5627
    key->prev->next=key->next;
5628
  if (key->next)
5629
    key->next->prev=key->prev;
5630
  key->increment_use_count(-1);
5631
  if (!key->parent)
5632
    par= &root;
5633
  else
5634
    par=key->parent_ptr();
5635
5636
  if (key->left == &null_element)
5637
  {
5638
    *par=nod=key->right;
5639
    fix_par=key->parent;
5640
    if (nod != &null_element)
5641
      nod->parent=fix_par;
5642
    remove_color= key->color;
5643
  }
5644
  else if (key->right == &null_element)
5645
  {
5646
    *par= nod=key->left;
5647
    nod->parent=fix_par=key->parent;
5648
    remove_color= key->color;
5649
  }
5650
  else
5651
  {
5652
    SEL_ARG *tmp=key->next;			// next bigger key (exist!)
5653
    nod= *tmp->parent_ptr()= tmp->right;	// unlink tmp from tree
5654
    fix_par=tmp->parent;
5655
    if (nod != &null_element)
5656
      nod->parent=fix_par;
5657
    remove_color= tmp->color;
5658
5659
    tmp->parent=key->parent;			// Move node in place of key
5660
    (tmp->left=key->left)->parent=tmp;
5661
    if ((tmp->right=key->right) != &null_element)
5662
      tmp->right->parent=tmp;
5663
    tmp->color=key->color;
5664
    *par=tmp;
5665
    if (fix_par == key)				// key->right == key->next
5666
      fix_par=tmp;				// new parent of nod
5667
  }
5668
5669
  if (root == &null_element)
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
5670
    return 0;				// Maybe root later
1 by brian
clean slate
5671
  if (remove_color == BLACK)
5672
    root=rb_delete_fixup(root,nod,fix_par);
511.2.6 by Monty Taylor
drizzled/ and storage/archive/ are clean.
5673
#ifdef EXTRA_DEBUG
1 by brian
clean slate
5674
  test_rb_tree(root,root->parent);
511.2.6 by Monty Taylor
drizzled/ and storage/archive/ are clean.
5675
#endif /* EXTRA_DEBUG */
1 by brian
clean slate
5676
5677
  root->use_count=this->use_count;		// Fix root counters
5678
  root->elements=this->elements-1;
5679
  root->maybe_flag=this->maybe_flag;
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
5680
  return(root);
1 by brian
clean slate
5681
}
5682
5683
5684
	/* Functions to fix up the tree after insert and delete */
5685
5686
static void left_rotate(SEL_ARG **root,SEL_ARG *leaf)
5687
{
5688
  SEL_ARG *y=leaf->right;
5689
  leaf->right=y->left;
5690
  if (y->left != &null_element)
5691
    y->left->parent=leaf;
5692
  if (!(y->parent=leaf->parent))
5693
    *root=y;
5694
  else
5695
    *leaf->parent_ptr()=y;
5696
  y->left=leaf;
5697
  leaf->parent=y;
5698
}
5699
5700
static void right_rotate(SEL_ARG **root,SEL_ARG *leaf)
5701
{
5702
  SEL_ARG *y=leaf->left;
5703
  leaf->left=y->right;
5704
  if (y->right != &null_element)
5705
    y->right->parent=leaf;
5706
  if (!(y->parent=leaf->parent))
5707
    *root=y;
5708
  else
5709
    *leaf->parent_ptr()=y;
5710
  y->right=leaf;
5711
  leaf->parent=y;
5712
}
5713
5714
5715
SEL_ARG *
5716
SEL_ARG::rb_insert(SEL_ARG *leaf)
5717
{
5718
  SEL_ARG *y,*par,*par2,*root;
5719
  root= this; root->parent= 0;
5720
5721
  leaf->color=RED;
5722
  while (leaf != root && (par= leaf->parent)->color == RED)
5723
  {					// This can't be root or 1 level under
5724
    if (par == (par2= leaf->parent->parent)->left)
5725
    {
5726
      y= par2->right;
5727
      if (y->color == RED)
5728
      {
5729
	par->color=BLACK;
5730
	y->color=BLACK;
5731
	leaf=par2;
5732
	leaf->color=RED;		/* And the loop continues */
5733
      }
5734
      else
5735
      {
5736
	if (leaf == par->right)
5737
	{
5738
	  left_rotate(&root,leaf->parent);
5739
	  par=leaf;			/* leaf is now parent to old leaf */
5740
	}
5741
	par->color=BLACK;
5742
	par2->color=RED;
5743
	right_rotate(&root,par2);
5744
	break;
5745
      }
5746
    }
5747
    else
5748
    {
5749
      y= par2->left;
5750
      if (y->color == RED)
5751
      {
5752
	par->color=BLACK;
5753
	y->color=BLACK;
5754
	leaf=par2;
5755
	leaf->color=RED;		/* And the loop continues */
5756
      }
5757
      else
5758
      {
5759
	if (leaf == par->left)
5760
	{
5761
	  right_rotate(&root,par);
5762
	  par=leaf;
5763
	}
5764
	par->color=BLACK;
5765
	par2->color=RED;
5766
	left_rotate(&root,par2);
5767
	break;
5768
      }
5769
    }
5770
  }
5771
  root->color=BLACK;
511.2.6 by Monty Taylor
drizzled/ and storage/archive/ are clean.
5772
#ifdef EXTRA_DEBUG
1 by brian
clean slate
5773
  test_rb_tree(root,root->parent);
511.2.6 by Monty Taylor
drizzled/ and storage/archive/ are clean.
5774
#endif /* EXTRA_DEBUG */
5775
1 by brian
clean slate
5776
  return root;
5777
}
5778
5779
5780
SEL_ARG *rb_delete_fixup(SEL_ARG *root,SEL_ARG *key,SEL_ARG *par)
5781
{
5782
  SEL_ARG *x,*w;
5783
  root->parent=0;
5784
5785
  x= key;
5786
  while (x != root && x->color == SEL_ARG::BLACK)
5787
  {
5788
    if (x == par->left)
5789
    {
5790
      w=par->right;
5791
      if (w->color == SEL_ARG::RED)
5792
      {
5793
	w->color=SEL_ARG::BLACK;
5794
	par->color=SEL_ARG::RED;
5795
	left_rotate(&root,par);
5796
	w=par->right;
5797
      }
5798
      if (w->left->color == SEL_ARG::BLACK && w->right->color == SEL_ARG::BLACK)
5799
      {
5800
	w->color=SEL_ARG::RED;
5801
	x=par;
5802
      }
5803
      else
5804
      {
5805
	if (w->right->color == SEL_ARG::BLACK)
5806
	{
5807
	  w->left->color=SEL_ARG::BLACK;
5808
	  w->color=SEL_ARG::RED;
5809
	  right_rotate(&root,w);
5810
	  w=par->right;
5811
	}
5812
	w->color=par->color;
5813
	par->color=SEL_ARG::BLACK;
5814
	w->right->color=SEL_ARG::BLACK;
5815
	left_rotate(&root,par);
5816
	x=root;
5817
	break;
5818
      }
5819
    }
5820
    else
5821
    {
5822
      w=par->left;
5823
      if (w->color == SEL_ARG::RED)
5824
      {
5825
	w->color=SEL_ARG::BLACK;
5826
	par->color=SEL_ARG::RED;
5827
	right_rotate(&root,par);
5828
	w=par->left;
5829
      }
5830
      if (w->right->color == SEL_ARG::BLACK && w->left->color == SEL_ARG::BLACK)
5831
      {
5832
	w->color=SEL_ARG::RED;
5833
	x=par;
5834
      }
5835
      else
5836
      {
5837
	if (w->left->color == SEL_ARG::BLACK)
5838
	{
5839
	  w->right->color=SEL_ARG::BLACK;
5840
	  w->color=SEL_ARG::RED;
5841
	  left_rotate(&root,w);
5842
	  w=par->left;
5843
	}
5844
	w->color=par->color;
5845
	par->color=SEL_ARG::BLACK;
5846
	w->left->color=SEL_ARG::BLACK;
5847
	right_rotate(&root,par);
5848
	x=root;
5849
	break;
5850
      }
5851
    }
5852
    par=x->parent;
5853
  }
5854
  x->color=SEL_ARG::BLACK;
5855
  return root;
5856
}
5857
5858
5859
	/* Test that the properties for a red-black tree hold */
5860
5861
#ifdef EXTRA_DEBUG
5862
int test_rb_tree(SEL_ARG *element,SEL_ARG *parent)
5863
{
5864
  int count_l,count_r;
5865
5866
  if (element == &null_element)
5867
    return 0;					// Found end of tree
5868
  if (element->parent != parent)
5869
  {
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
5870
    errmsg_printf(ERRMSG_LVL_ERROR, "Wrong tree: Parent doesn't point at parent");
1 by brian
clean slate
5871
    return -1;
5872
  }
5873
  if (element->color == SEL_ARG::RED &&
5874
      (element->left->color == SEL_ARG::RED ||
5875
       element->right->color == SEL_ARG::RED))
5876
  {
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
5877
    errmsg_printf(ERRMSG_LVL_ERROR, "Wrong tree: Found two red in a row");
1 by brian
clean slate
5878
    return -1;
5879
  }
5880
  if (element->left == element->right && element->left != &null_element)
5881
  {						// Dummy test
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
5882
    errmsg_printf(ERRMSG_LVL_ERROR, "Wrong tree: Found right == left");
1 by brian
clean slate
5883
    return -1;
5884
  }
5885
  count_l=test_rb_tree(element->left,element);
5886
  count_r=test_rb_tree(element->right,element);
5887
  if (count_l >= 0 && count_r >= 0)
5888
  {
5889
    if (count_l == count_r)
5890
      return count_l+(element->color == SEL_ARG::BLACK);
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
5891
    errmsg_printf(ERRMSG_LVL_ERROR, "Wrong tree: Incorrect black-count: %d - %d",
1 by brian
clean slate
5892
	    count_l,count_r);
5893
  }
5894
  return -1;					// Error, no more warnings
5895
}
5896
5897
5898
/*
5899
  Count how many times SEL_ARG graph "root" refers to its part "key"
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
5900
1 by brian
clean slate
5901
  SYNOPSIS
5902
    count_key_part_usage()
5903
      root  An RB-Root node in a SEL_ARG graph.
5904
      key   Another RB-Root node in that SEL_ARG graph.
5905
5906
  DESCRIPTION
5907
    The passed "root" node may refer to "key" node via root->next_key_part,
5908
    root->next->n
5909
5910
    This function counts how many times the node "key" is referred (via
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
5911
    SEL_ARG::next_key_part) by
5912
     - intervals of RB-tree pointed by "root",
5913
     - intervals of RB-trees that are pointed by SEL_ARG::next_key_part from
1 by brian
clean slate
5914
       intervals of RB-tree pointed by "root",
5915
     - and so on.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
5916
5917
    Here is an example (horizontal links represent next_key_part pointers,
5918
    vertical links - next/prev prev pointers):
5919
1 by brian
clean slate
5920
         +----+               $
5921
         |root|-----------------+
5922
         +----+               $ |
5923
           |                  $ |
5924
           |                  $ |
5925
         +----+       +---+   $ |     +---+    Here the return value
5926
         |    |- ... -|   |---$-+--+->|key|    will be 4.
5927
         +----+       +---+   $ |  |  +---+
5928
           |                  $ |  |
5929
          ...                 $ |  |
5930
           |                  $ |  |
5931
         +----+   +---+       $ |  |
5932
         |    |---|   |---------+  |
5933
         +----+   +---+       $    |
5934
           |        |         $    |
5935
          ...     +---+       $    |
5936
                  |   |------------+
5937
                  +---+       $
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
5938
  RETURN
1 by brian
clean slate
5939
    Number of links to "key" from nodes reachable from "root".
5940
*/
5941
5942
static ulong count_key_part_usage(SEL_ARG *root, SEL_ARG *key)
5943
{
5944
  ulong count= 0;
5945
  for (root=root->first(); root ; root=root->next)
5946
  {
5947
    if (root->next_key_part)
5948
    {
5949
      if (root->next_key_part == key)
5950
	count++;
5951
      if (root->next_key_part->part < key->part)
5952
	count+=count_key_part_usage(root->next_key_part,key);
5953
    }
5954
  }
5955
  return count;
5956
}
5957
5958
5959
/*
5960
  Check if SEL_ARG::use_count value is correct
5961
5962
  SYNOPSIS
5963
    SEL_ARG::test_use_count()
5964
      root  The root node of the SEL_ARG graph (an RB-tree root node that
5965
            has the least value of sel_arg->part in the entire graph, and
5966
            thus is the "origin" of the graph)
5967
5968
  DESCRIPTION
5969
    Check if SEL_ARG::use_count value is correct. See the definition of
5970
    use_count for what is "correct".
5971
*/
5972
5973
void SEL_ARG::test_use_count(SEL_ARG *root)
5974
{
482 by Brian Aker
Remove uint.
5975
  uint32_t e_count=0;
1 by brian
clean slate
5976
  if (this == root && use_count != 1)
5977
  {
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
5978
    errmsg_printf(ERRMSG_LVL_INFO, "Use_count: Wrong count %lu for root",use_count);
1 by brian
clean slate
5979
    return;
5980
  }
5981
  if (this->type != SEL_ARG::KEY_RANGE)
5982
    return;
5983
  for (SEL_ARG *pos=first(); pos ; pos=pos->next)
5984
  {
5985
    e_count++;
5986
    if (pos->next_key_part)
5987
    {
5988
      ulong count=count_key_part_usage(root,pos->next_key_part);
5989
      if (count > pos->next_key_part->use_count)
5990
      {
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
5991
        errmsg_printf(ERRMSG_LVL_INFO, "Use_count: Wrong count for key at 0x%lx, %lu "
1 by brian
clean slate
5992
                              "should be %lu", (long unsigned int)pos,
5993
                              pos->next_key_part->use_count, count);
5994
	return;
5995
      }
5996
      pos->next_key_part->test_use_count(root);
5997
    }
5998
  }
5999
  if (e_count != elements)
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
6000
    errmsg_printf(ERRMSG_LVL_WARN, "Wrong use count: %u (should be %u) for tree at 0x%lx",
1 by brian
clean slate
6001
                      e_count, elements, (long unsigned int) this);
6002
}
6003
6004
#endif
6005
6006
/****************************************************************************
6007
  MRR Range Sequence Interface implementation that walks a SEL_ARG* tree.
6008
 ****************************************************************************/
6009
6010
/* MRR range sequence, SEL_ARG* implementation: stack entry */
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
6011
typedef struct st_range_seq_entry
1 by brian
clean slate
6012
{
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
6013
  /*
1 by brian
clean slate
6014
    Pointers in min and max keys. They point to right-after-end of key
6015
    images. The 0-th entry has these pointing to key tuple start.
6016
  */
481 by Brian Aker
Remove all of uchar.
6017
  unsigned char *min_key, *max_key;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
6018
6019
  /*
1 by brian
clean slate
6020
    Flags, for {keypart0, keypart1, ... this_keypart} subtuple.
6021
    min_key_flag may have NULL_RANGE set.
6022
  */
482 by Brian Aker
Remove uint.
6023
  uint32_t min_key_flag, max_key_flag;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
6024
1 by brian
clean slate
6025
  /* Number of key parts */
482 by Brian Aker
Remove uint.
6026
  uint32_t min_key_parts, max_key_parts;
1 by brian
clean slate
6027
  SEL_ARG *key_tree;
6028
} RANGE_SEQ_ENTRY;
6029
6030
6031
/*
6032
  MRR range sequence, SEL_ARG* implementation: SEL_ARG graph traversal context
6033
*/
6034
typedef struct st_sel_arg_range_seq
6035
{
482 by Brian Aker
Remove uint.
6036
  uint32_t keyno;      /* index of used tree in SEL_TREE structure */
6037
  uint32_t real_keyno; /* Number of the index in tables */
1 by brian
clean slate
6038
  PARAM *param;
6039
  SEL_ARG *start; /* Root node of the traversed SEL_ARG* graph */
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
6040
1 by brian
clean slate
6041
  RANGE_SEQ_ENTRY stack[MAX_REF_PARTS];
6042
  int i; /* Index of last used element in the above array */
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
6043
55 by brian
Update for using real bool types.
6044
  bool at_start; /* true <=> The traversal has just started */
1 by brian
clean slate
6045
} SEL_ARG_RANGE_SEQ;
6046
6047
6048
/*
6049
  Range sequence interface, SEL_ARG* implementation: Initialize the traversal
6050
6051
  SYNOPSIS
6052
    init()
6053
      init_params  SEL_ARG tree traversal context
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
6054
      n_ranges     [ignored] The number of ranges obtained
1 by brian
clean slate
6055
      flags        [ignored] HA_MRR_SINGLE_POINT, HA_MRR_FIXED_KEY
6056
6057
  RETURN
6058
    Value of init_param
6059
*/
6060
655 by Brian Aker
Yet more unused.... damn annoying... (also tossed some prototypes that were
6061
range_seq_t sel_arg_range_seq_init(void *init_param, uint32_t, uint32_t)
1 by brian
clean slate
6062
{
6063
  SEL_ARG_RANGE_SEQ *seq= (SEL_ARG_RANGE_SEQ*)init_param;
55 by brian
Update for using real bool types.
6064
  seq->at_start= true;
1 by brian
clean slate
6065
  seq->stack[0].key_tree= NULL;
6066
  seq->stack[0].min_key= seq->param->min_key;
6067
  seq->stack[0].min_key_flag= 0;
6068
  seq->stack[0].min_key_parts= 0;
6069
6070
  seq->stack[0].max_key= seq->param->max_key;
6071
  seq->stack[0].max_key_flag= 0;
6072
  seq->stack[0].max_key_parts= 0;
6073
  seq->i= 0;
6074
  return init_param;
6075
}
6076
6077
6078
static void step_down_to(SEL_ARG_RANGE_SEQ *arg, SEL_ARG *key_tree)
6079
{
6080
  RANGE_SEQ_ENTRY *cur= &arg->stack[arg->i+1];
6081
  RANGE_SEQ_ENTRY *prev= &arg->stack[arg->i];
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
6082
1 by brian
clean slate
6083
  cur->key_tree= key_tree;
6084
  cur->min_key= prev->min_key;
6085
  cur->max_key= prev->max_key;
6086
  cur->min_key_parts= prev->min_key_parts;
6087
  cur->max_key_parts= prev->max_key_parts;
6088
206 by Brian Aker
Removed final uint dead types.
6089
  uint16_t stor_length= arg->param->key[arg->keyno][key_tree->part].store_length;
1 by brian
clean slate
6090
  cur->min_key_parts += key_tree->store_min(stor_length, &cur->min_key,
6091
                                            prev->min_key_flag);
6092
  cur->max_key_parts += key_tree->store_max(stor_length, &cur->max_key,
6093
                                            prev->max_key_flag);
6094
6095
  cur->min_key_flag= prev->min_key_flag | key_tree->min_flag;
6096
  cur->max_key_flag= prev->max_key_flag | key_tree->max_flag;
6097
6098
  if (key_tree->is_null_interval())
6099
    cur->min_key_flag |= NULL_RANGE;
6100
  (arg->i)++;
6101
}
6102
6103
6104
/*
6105
  Range sequence interface, SEL_ARG* implementation: get the next interval
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
6106
1 by brian
clean slate
6107
  SYNOPSIS
6108
    sel_arg_range_seq_next()
6109
      rseq        Value returned from sel_arg_range_seq_init
6110
      range  OUT  Store information about the range here
6111
6112
  DESCRIPTION
6113
    This is "get_next" function for Range sequence interface implementation
6114
    for SEL_ARG* tree.
6115
6116
  IMPLEMENTATION
6117
    The traversal also updates those param members:
6118
      - is_ror_scan
6119
      - range_count
6120
      - max_key_part
6121
6122
  RETURN
6123
    0  Ok
6124
    1  No more ranges in the sequence
6125
*/
6126
6127
//psergey-merge-todo: support check_quick_keys:max_keypart
482 by Brian Aker
Remove uint.
6128
uint32_t sel_arg_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range)
1 by brian
clean slate
6129
{
6130
  SEL_ARG *key_tree;
6131
  SEL_ARG_RANGE_SEQ *seq= (SEL_ARG_RANGE_SEQ*)rseq;
6132
  if (seq->at_start)
6133
  {
6134
    key_tree= seq->start;
55 by brian
Update for using real bool types.
6135
    seq->at_start= false;
1 by brian
clean slate
6136
    goto walk_up_n_right;
6137
  }
6138
6139
  key_tree= seq->stack[seq->i].key_tree;
6140
  /* Ok, we're at some "full tuple" position in the tree */
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
6141
1 by brian
clean slate
6142
  /* Step down if we can */
6143
  if (key_tree->next && key_tree->next != &null_element)
6144
  {
6145
    //step down; (update the tuple, we'll step right and stay there)
6146
    seq->i--;
6147
    step_down_to(seq, key_tree->next);
6148
    key_tree= key_tree->next;
55 by brian
Update for using real bool types.
6149
    seq->param->is_ror_scan= false;
1 by brian
clean slate
6150
    goto walk_right_n_up;
6151
  }
6152
6153
  /* Ok, can't step down, walk left until we can step down */
6154
  while (1)
6155
  {
6156
    if (seq->i == 1) // can't step left
6157
      return 1;
6158
    /* Step left */
6159
    seq->i--;
6160
    key_tree= seq->stack[seq->i].key_tree;
6161
6162
    /* Step down if we can */
6163
    if (key_tree->next && key_tree->next != &null_element)
6164
    {
6165
      // Step down; update the tuple
6166
      seq->i--;
6167
      step_down_to(seq, key_tree->next);
6168
      key_tree= key_tree->next;
6169
      break;
6170
    }
6171
  }
6172
6173
  /*
6174
    Ok, we've stepped down from the path to previous tuple.
6175
    Walk right-up while we can
6176
  */
6177
walk_right_n_up:
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
6178
  while (key_tree->next_key_part && key_tree->next_key_part != &null_element &&
1 by brian
clean slate
6179
         key_tree->next_key_part->part == key_tree->part + 1 &&
6180
         key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
6181
  {
6182
    {
6183
      RANGE_SEQ_ENTRY *cur= &seq->stack[seq->i];
482 by Brian Aker
Remove uint.
6184
      uint32_t min_key_length= cur->min_key - seq->param->min_key;
6185
      uint32_t max_key_length= cur->max_key - seq->param->max_key;
6186
      uint32_t len= cur->min_key - cur[-1].min_key;
1 by brian
clean slate
6187
      if (!(min_key_length == max_key_length &&
6188
            !memcmp(cur[-1].min_key, cur[-1].max_key, len) &&
6189
            !key_tree->min_flag && !key_tree->max_flag))
6190
      {
55 by brian
Update for using real bool types.
6191
        seq->param->is_ror_scan= false;
1 by brian
clean slate
6192
        if (!key_tree->min_flag)
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
6193
          cur->min_key_parts +=
1 by brian
clean slate
6194
            key_tree->next_key_part->store_min_key(seq->param->key[seq->keyno],
6195
                                                   &cur->min_key,
6196
                                                   &cur->min_key_flag);
6197
        if (!key_tree->max_flag)
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
6198
          cur->max_key_parts +=
1 by brian
clean slate
6199
            key_tree->next_key_part->store_max_key(seq->param->key[seq->keyno],
6200
                                                   &cur->max_key,
6201
                                                   &cur->max_key_flag);
6202
        break;
6203
      }
6204
    }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
6205
1 by brian
clean slate
6206
    /*
6207
      Ok, current atomic interval is in form "t.field=const" and there is
6208
      next_key_part interval. Step right, and walk up from there.
6209
    */
6210
    key_tree= key_tree->next_key_part;
6211
6212
walk_up_n_right:
6213
    while (key_tree->prev && key_tree->prev != &null_element)
6214
    {
6215
      /* Step up */
6216
      key_tree= key_tree->prev;
6217
    }
6218
    step_down_to(seq, key_tree);
6219
  }
6220
6221
  /* Ok got a tuple */
6222
  RANGE_SEQ_ENTRY *cur= &seq->stack[seq->i];
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
6223
1 by brian
clean slate
6224
  range->ptr= (char*)(int)(key_tree->part);
6225
  {
6226
    range->range_flag= cur->min_key_flag | cur->max_key_flag;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
6227
1 by brian
clean slate
6228
    range->start_key.key=    seq->param->min_key;
6229
    range->start_key.length= cur->min_key - seq->param->min_key;
6230
    range->start_key.keypart_map= make_prev_keypart_map(cur->min_key_parts);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
6231
    range->start_key.flag= (cur->min_key_flag & NEAR_MIN ? HA_READ_AFTER_KEY :
1 by brian
clean slate
6232
                                                           HA_READ_KEY_EXACT);
6233
6234
    range->end_key.key=    seq->param->max_key;
6235
    range->end_key.length= cur->max_key - seq->param->max_key;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
6236
    range->end_key.flag= (cur->max_key_flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
1 by brian
clean slate
6237
                                                         HA_READ_AFTER_KEY);
6238
    range->end_key.keypart_map= make_prev_keypart_map(cur->max_key_parts);
6239
6240
    if (!(cur->min_key_flag & ~NULL_RANGE) && !cur->max_key_flag &&
895 by Brian Aker
Completion (?) of uint conversion.
6241
        (uint32_t)key_tree->part+1 == seq->param->table->key_info[seq->real_keyno].key_parts &&
53.2.14 by Monty Taylor
Removed HA_END_SPACE_KEY and references to it. It was _supposed_ to be gone anyway, but the ifdef around it was broken (MYSQL_VERSION_ID was actually undefined.)
6242
        (seq->param->table->key_info[seq->real_keyno].flags & (HA_NOSAME)) ==
1 by brian
clean slate
6243
        HA_NOSAME &&
6244
        range->start_key.length == range->end_key.length &&
6245
        !memcmp(seq->param->min_key,seq->param->max_key,range->start_key.length))
6246
      range->range_flag= UNIQUE_RANGE | (cur->min_key_flag & NULL_RANGE);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
6247
1 by brian
clean slate
6248
    if (seq->param->is_ror_scan)
6249
    {
6250
      /*
6251
        If we get here, the condition on the key was converted to form
6252
        "(keyXpart1 = c1) AND ... AND (keyXpart{key_tree->part - 1} = cN) AND
6253
          somecond(keyXpart{key_tree->part})"
6254
        Check if
6255
          somecond is "keyXpart{key_tree->part} = const" and
6256
          uncovered "tail" of KeyX parts is either empty or is identical to
6257
          first members of clustered primary key.
6258
      */
6259
      if (!(!(cur->min_key_flag & ~NULL_RANGE) && !cur->max_key_flag &&
6260
            (range->start_key.length == range->end_key.length) &&
6261
            !memcmp(range->start_key.key, range->end_key.key, range->start_key.length) &&
6262
            is_key_scan_ror(seq->param, seq->real_keyno, key_tree->part + 1)))
55 by brian
Update for using real bool types.
6263
        seq->param->is_ror_scan= false;
1 by brian
clean slate
6264
    }
6265
  }
6266
  seq->param->range_count++;
895 by Brian Aker
Completion (?) of uint conversion.
6267
  seq->param->max_key_part=cmax(seq->param->max_key_part,(uint32_t)key_tree->part);
1 by brian
clean slate
6268
  return 0;
6269
}
6270
6271
6272
/*
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
6273
  Calculate cost and E(#rows) for a given index and intervals tree
1 by brian
clean slate
6274
6275
  SYNOPSIS
6276
    check_quick_select()
6277
      param             Parameter from test_quick_select
6278
      idx               Number of index to use in PARAM::key SEL_TREE::key
55 by brian
Update for using real bool types.
6279
      index_only        true  - assume only index tuples will be accessed
6280
                        false - assume full table rows will be read
1 by brian
clean slate
6281
      tree              Transformed selection condition, tree->key[idx] holds
6282
                        the intervals for the given index.
55 by brian
Update for using real bool types.
6283
      update_tbl_stats  true <=> update table->quick_* with information
1 by brian
clean slate
6284
                        about range scan we've evaluated.
6285
      mrr_flags   INOUT MRR access flags
6286
      cost        OUT   Scan cost
6287
6288
  NOTES
6289
    param->is_ror_scan is set to reflect if the key scan is a ROR (see
6290
    is_key_scan_ror function for more info)
6291
    param->table->quick_*, param->range_count (and maybe others) are
6292
    updated with data of given key scan, see quick_range_seq_next for details.
6293
6294
  RETURN
6295
    Estimate # of records to be retrieved.
6296
    HA_POS_ERROR if estimate calculation failed due to table handler problems.
6297
*/
6298
6299
static
482 by Brian Aker
Remove uint.
6300
ha_rows check_quick_select(PARAM *param, uint32_t idx, bool index_only,
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
6301
                           SEL_ARG *tree, bool update_tbl_stats,
482 by Brian Aker
Remove uint.
6302
                           uint32_t *mrr_flags, uint32_t *bufsize, COST_VECT *cost)
1 by brian
clean slate
6303
{
6304
  SEL_ARG_RANGE_SEQ seq;
6305
  RANGE_SEQ_IF seq_if = {sel_arg_range_seq_init, sel_arg_range_seq_next};
6306
  handler *file= param->table->file;
6307
  ha_rows rows;
482 by Brian Aker
Remove uint.
6308
  uint32_t keynr= param->real_keynr[idx];
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
6309
1 by brian
clean slate
6310
  /* Handle cases when we don't have a valid non-empty list of range */
6311
  if (!tree)
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
6312
    return(HA_POS_ERROR);
1 by brian
clean slate
6313
  if (tree->type == SEL_ARG::IMPOSSIBLE)
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
6314
    return(0L);
1 by brian
clean slate
6315
  if (tree->type != SEL_ARG::KEY_RANGE || tree->part != 0)
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
6316
    return(HA_POS_ERROR);
1 by brian
clean slate
6317
6318
  seq.keyno= idx;
6319
  seq.real_keyno= keynr;
6320
  seq.param= param;
6321
  seq.start= tree;
6322
6323
  param->range_count=0;
6324
  param->max_key_part=0;
6325
55 by brian
Update for using real bool types.
6326
  param->is_ror_scan= true;
6327
  if (file->index_flags(keynr, 0, true) & HA_KEY_SCAN_NOT_ROR)
6328
    param->is_ror_scan= false;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
6329
1 by brian
clean slate
6330
  *mrr_flags= param->force_default_mrr? HA_MRR_USE_DEFAULT_IMPL: 0;
6331
  *mrr_flags|= HA_MRR_NO_ASSOCIATION;
6332
6333
  bool pk_is_clustered= file->primary_key_is_clustered();
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
6334
  if (index_only &&
1 by brian
clean slate
6335
      (file->index_flags(keynr, param->max_key_part, 1) & HA_KEYREAD_ONLY) &&
6336
      !(pk_is_clustered && keynr == param->table->s->primary_key))
6337
     *mrr_flags |= HA_MRR_INDEX_ONLY;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
6338
520.1.22 by Brian Aker
Second pass of thd cleanup
6339
  if (current_session->lex->sql_command != SQLCOM_SELECT)
1 by brian
clean slate
6340
    *mrr_flags |= HA_MRR_USE_DEFAULT_IMPL;
6341
520.1.22 by Brian Aker
Second pass of thd cleanup
6342
  *bufsize= param->session->variables.read_rnd_buff_size;
1 by brian
clean slate
6343
  rows= file->multi_range_read_info_const(keynr, &seq_if, (void*)&seq, 0,
6344
                                          bufsize, mrr_flags, cost);
6345
  if (rows != HA_POS_ERROR)
6346
  {
6347
    param->table->quick_rows[keynr]=rows;
6348
    if (update_tbl_stats)
6349
    {
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
6350
      param->table->quick_keys.set(keynr);
1 by brian
clean slate
6351
      param->table->quick_key_parts[keynr]=param->max_key_part+1;
6352
      param->table->quick_n_ranges[keynr]= param->range_count;
6353
      param->table->quick_condition_rows=
398.1.4 by Monty Taylor
Renamed max/min.
6354
        cmin(param->table->quick_condition_rows, rows);
1 by brian
clean slate
6355
    }
6356
  }
6357
  /* Figure out if the key scan is ROR (returns rows in ROWID order) or not */
6358
  enum ha_key_alg key_alg= param->table->key_info[seq.real_keyno].algorithm;
6359
  if ((key_alg != HA_KEY_ALG_BTREE) && (key_alg!= HA_KEY_ALG_UNDEF))
6360
  {
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
6361
    /*
1 by brian
clean slate
6362
      All scans are non-ROR scans for those index types.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
6363
      TODO: Don't have this logic here, make table engines return
1 by brian
clean slate
6364
      appropriate flags instead.
6365
    */
55 by brian
Update for using real bool types.
6366
    param->is_ror_scan= false;
1 by brian
clean slate
6367
  }
6368
  else
6369
  {
6370
    /* Clustered PK scan is always a ROR scan (TODO: same as above) */
6371
    if (param->table->s->primary_key == keynr && pk_is_clustered)
55 by brian
Update for using real bool types.
6372
      param->is_ror_scan= true;
1 by brian
clean slate
6373
  }
6374
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
6375
  return(rows); //psergey-merge:todo: maintain first_null_comp.
1 by brian
clean slate
6376
}
6377
6378
6379
/*
6380
  Check if key scan on given index with equality conditions on first n key
6381
  parts is a ROR scan.
6382
6383
  SYNOPSIS
6384
    is_key_scan_ror()
6385
      param  Parameter from test_quick_select
6386
      keynr  Number of key in the table. The key must not be a clustered
6387
             primary key.
6388
      nparts Number of first key parts for which equality conditions
6389
             are present.
6390
6391
  NOTES
6392
    ROR (Rowid Ordered Retrieval) key scan is a key scan that produces
6393
    ordered sequence of rowids (ha_xxx::cmp_ref is the comparison function)
6394
6395
    This function is needed to handle a practically-important special case:
6396
    an index scan is a ROR scan if it is done using a condition in form
6397
6398
        "key1_1=c_1 AND ... AND key1_n=c_n"
6399
6400
    where the index is defined on (key1_1, ..., key1_N [,a_1, ..., a_n])
6401
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
6402
    and the table has a clustered Primary Key defined as
6403
      PRIMARY KEY(a_1, ..., a_n, b1, ..., b_k)
6404
6405
    i.e. the first key parts of it are identical to uncovered parts ot the
1 by brian
clean slate
6406
    key being scanned. This function assumes that the index flags do not
6407
    include HA_KEY_SCAN_NOT_ROR flag (that is checked elsewhere).
6408
6409
    Check (1) is made in quick_range_seq_next()
6410
6411
  RETURN
55 by brian
Update for using real bool types.
6412
    true   The scan is ROR-scan
6413
    false  Otherwise
1 by brian
clean slate
6414
*/
6415
482 by Brian Aker
Remove uint.
6416
static bool is_key_scan_ror(PARAM *param, uint32_t keynr, uint8_t nparts)
1 by brian
clean slate
6417
{
6418
  KEY *table_key= param->table->key_info + keynr;
6419
  KEY_PART_INFO *key_part= table_key->key_part + nparts;
6420
  KEY_PART_INFO *key_part_end= (table_key->key_part +
6421
                                table_key->key_parts);
482 by Brian Aker
Remove uint.
6422
  uint32_t pk_number;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
6423
1 by brian
clean slate
6424
  for (KEY_PART_INFO *kp= table_key->key_part; kp < key_part; kp++)
6425
  {
206 by Brian Aker
Removed final uint dead types.
6426
    uint16_t fieldnr= param->table->key_info[keynr].
1 by brian
clean slate
6427
                    key_part[kp - table_key->key_part].fieldnr - 1;
6428
    if (param->table->field[fieldnr]->key_length() != kp->length)
55 by brian
Update for using real bool types.
6429
      return false;
1 by brian
clean slate
6430
  }
6431
6432
  if (key_part == key_part_end)
55 by brian
Update for using real bool types.
6433
    return true;
1 by brian
clean slate
6434
6435
  key_part= table_key->key_part + nparts;
6436
  pk_number= param->table->s->primary_key;
6437
  if (!param->table->file->primary_key_is_clustered() || pk_number == MAX_KEY)
55 by brian
Update for using real bool types.
6438
    return false;
1 by brian
clean slate
6439
6440
  KEY_PART_INFO *pk_part= param->table->key_info[pk_number].key_part;
6441
  KEY_PART_INFO *pk_part_end= pk_part +
6442
                              param->table->key_info[pk_number].key_parts;
6443
  for (;(key_part!=key_part_end) && (pk_part != pk_part_end);
6444
       ++key_part, ++pk_part)
6445
  {
6446
    if ((key_part->field != pk_part->field) ||
6447
        (key_part->length != pk_part->length))
55 by brian
Update for using real bool types.
6448
      return false;
1 by brian
clean slate
6449
  }
6450
  return (key_part == key_part_end);
6451
}
6452
6453
6454
/*
6455
  Create a QUICK_RANGE_SELECT from given key and SEL_ARG tree for that key.
6456
6457
  SYNOPSIS
6458
    get_quick_select()
6459
      param
6460
      idx            Index of used key in param->key.
6461
      key_tree       SEL_ARG tree for the used key
6462
      mrr_flags      MRR parameter for quick select
6463
      mrr_buf_size   MRR parameter for quick select
6464
      parent_alloc   If not NULL, use it to allocate memory for
6465
                     quick select data. Otherwise use quick->alloc.
6466
  NOTES
6467
    The caller must call QUICK_SELECT::init for returned quick select.
6468
520.1.22 by Brian Aker
Second pass of thd cleanup
6469
    CAUTION! This function may change session->mem_root to a MEM_ROOT which will be
1 by brian
clean slate
6470
    deallocated when the returned quick select is deleted.
6471
6472
  RETURN
6473
    NULL on error
6474
    otherwise created quick select
6475
*/
6476
6477
QUICK_RANGE_SELECT *
482 by Brian Aker
Remove uint.
6478
get_quick_select(PARAM *param,uint32_t idx,SEL_ARG *key_tree, uint32_t mrr_flags,
6479
                 uint32_t mrr_buf_size, MEM_ROOT *parent_alloc)
1 by brian
clean slate
6480
{
6481
  QUICK_RANGE_SELECT *quick;
55 by brian
Update for using real bool types.
6482
  bool create_err= false;
1 by brian
clean slate
6483
520.1.22 by Brian Aker
Second pass of thd cleanup
6484
  quick=new QUICK_RANGE_SELECT(param->session, param->table,
1 by brian
clean slate
6485
                               param->real_keynr[idx],
1005.2.3 by Monty Taylor
Further reversion of P.
6486
                               test(parent_alloc), NULL, &create_err);
1 by brian
clean slate
6487
6488
  if (quick)
6489
  {
6490
    if (create_err ||
6491
	get_quick_keys(param,quick,param->key[idx],key_tree,param->min_key,0,
6492
		       param->max_key,0))
6493
    {
6494
      delete quick;
6495
      quick=0;
6496
    }
6497
    else
6498
    {
6499
      quick->mrr_flags= mrr_flags;
6500
      quick->mrr_buf_size= mrr_buf_size;
6501
      quick->key_parts=(KEY_PART*)
6502
        memdup_root(parent_alloc? parent_alloc : &quick->alloc,
6503
                    (char*) param->key[idx],
6504
                    sizeof(KEY_PART)*
6505
                    param->table->key_info[param->real_keynr[idx]].key_parts);
6506
    }
6507
  }
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
6508
  return quick;
1 by brian
clean slate
6509
}
6510
6511
6512
/*
6513
** Fix this to get all possible sub_ranges
6514
*/
6515
bool
6516
get_quick_keys(PARAM *param,QUICK_RANGE_SELECT *quick,KEY_PART *key,
482 by Brian Aker
Remove uint.
6517
	       SEL_ARG *key_tree, unsigned char *min_key,uint32_t min_key_flag,
6518
	       unsigned char *max_key, uint32_t max_key_flag)
1 by brian
clean slate
6519
{
6520
  QUICK_RANGE *range;
482 by Brian Aker
Remove uint.
6521
  uint32_t flag;
1 by brian
clean slate
6522
  int min_part= key_tree->part-1, // # of keypart values in min_key buffer
6523
      max_part= key_tree->part-1; // # of keypart values in max_key buffer
6524
6525
  if (key_tree->left != &null_element)
6526
  {
6527
    if (get_quick_keys(param,quick,key,key_tree->left,
6528
		       min_key,min_key_flag, max_key, max_key_flag))
6529
      return 1;
6530
  }
481 by Brian Aker
Remove all of uchar.
6531
  unsigned char *tmp_min_key=min_key,*tmp_max_key=max_key;
1 by brian
clean slate
6532
  min_part+= key_tree->store_min(key[key_tree->part].store_length,
6533
                                 &tmp_min_key,min_key_flag);
6534
  max_part+= key_tree->store_max(key[key_tree->part].store_length,
6535
                                 &tmp_max_key,max_key_flag);
6536
6537
  if (key_tree->next_key_part &&
6538
      key_tree->next_key_part->part == key_tree->part+1 &&
6539
      key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
6540
  {						  // const key as prefix
6541
    if ((tmp_min_key - min_key) == (tmp_max_key - max_key) &&
895 by Brian Aker
Completion (?) of uint conversion.
6542
         memcmp(min_key, max_key, (uint32_t)(tmp_max_key - max_key))==0 &&
1 by brian
clean slate
6543
	 key_tree->min_flag==0 && key_tree->max_flag==0)
6544
    {
6545
      if (get_quick_keys(param,quick,key,key_tree->next_key_part,
6546
			 tmp_min_key, min_key_flag | key_tree->min_flag,
6547
			 tmp_max_key, max_key_flag | key_tree->max_flag))
6548
	return 1;
6549
      goto end;					// Ugly, but efficient
6550
    }
6551
    {
482 by Brian Aker
Remove uint.
6552
      uint32_t tmp_min_flag=key_tree->min_flag,tmp_max_flag=key_tree->max_flag;
1 by brian
clean slate
6553
      if (!tmp_min_flag)
6554
        min_part+= key_tree->next_key_part->store_min_key(key, &tmp_min_key,
6555
                                                          &tmp_min_flag);
6556
      if (!tmp_max_flag)
6557
        max_part+= key_tree->next_key_part->store_max_key(key, &tmp_max_key,
6558
                                                          &tmp_max_flag);
6559
      flag=tmp_min_flag | tmp_max_flag;
6560
    }
6561
  }
6562
  else
6563
  {
6564
    flag= key_tree->min_flag | key_tree->max_flag;
6565
  }
6566
6567
  /*
6568
    Ensure that some part of min_key and max_key are used.  If not,
6569
    regard this as no lower/upper range
6570
  */
6571
  {
6572
    if (tmp_min_key != param->min_key)
6573
      flag&= ~NO_MIN_RANGE;
6574
    else
6575
      flag|= NO_MIN_RANGE;
6576
    if (tmp_max_key != param->max_key)
6577
      flag&= ~NO_MAX_RANGE;
6578
    else
6579
      flag|= NO_MAX_RANGE;
6580
  }
6581
  if (flag == 0)
6582
  {
895 by Brian Aker
Completion (?) of uint conversion.
6583
    uint32_t length= (uint32_t) (tmp_min_key - param->min_key);
6584
    if (length == (uint32_t) (tmp_max_key - param->max_key) &&
1 by brian
clean slate
6585
	!memcmp(param->min_key,param->max_key,length))
6586
    {
6587
      KEY *table_key=quick->head->key_info+quick->index;
6588
      flag=EQ_RANGE;
53.2.14 by Monty Taylor
Removed HA_END_SPACE_KEY and references to it. It was _supposed_ to be gone anyway, but the ifdef around it was broken (MYSQL_VERSION_ID was actually undefined.)
6589
      if ((table_key->flags & (HA_NOSAME)) == HA_NOSAME &&
1 by brian
clean slate
6590
	  key->part == table_key->key_parts-1)
6591
      {
6592
	if (!(table_key->flags & HA_NULL_PART_KEY) ||
6593
	    !null_part_in_key(key,
6594
			      param->min_key,
895 by Brian Aker
Completion (?) of uint conversion.
6595
			      (uint32_t) (tmp_min_key - param->min_key)))
1 by brian
clean slate
6596
	  flag|= UNIQUE_RANGE;
6597
	else
6598
	  flag|= NULL_RANGE;
6599
      }
6600
    }
6601
  }
6602
6603
  /* Get range for retrieving rows in QUICK_SELECT::get_next */
6604
  if (!(range= new QUICK_RANGE(param->min_key,
895 by Brian Aker
Completion (?) of uint conversion.
6605
			       (uint32_t) (tmp_min_key - param->min_key),
1 by brian
clean slate
6606
                               min_part >=0 ? make_keypart_map(min_part) : 0,
6607
			       param->max_key,
895 by Brian Aker
Completion (?) of uint conversion.
6608
			       (uint32_t) (tmp_max_key - param->max_key),
1 by brian
clean slate
6609
                               max_part >=0 ? make_keypart_map(max_part) : 0,
6610
			       flag)))
6611
    return 1;			// out of memory
6612
937.2.6 by Stewart Smith
make set_if_bigger typesafe for C and C++. Fix up everywhere.
6613
  set_if_bigger(quick->max_used_key_length, (uint32_t)range->min_length);
6614
  set_if_bigger(quick->max_used_key_length, (uint32_t)range->max_length);
895 by Brian Aker
Completion (?) of uint conversion.
6615
  set_if_bigger(quick->used_key_parts, (uint32_t) key_tree->part+1);
481 by Brian Aker
Remove all of uchar.
6616
  if (insert_dynamic(&quick->ranges, (unsigned char*) &range))
1 by brian
clean slate
6617
    return 1;
6618
6619
 end:
6620
  if (key_tree->right != &null_element)
6621
    return get_quick_keys(param,quick,key,key_tree->right,
6622
			  min_key,min_key_flag,
6623
			  max_key,max_key_flag);
6624
  return 0;
6625
}
6626
6627
/*
6628
  Return 1 if there is only one range and this uses the whole primary key
6629
*/
6630
6631
bool QUICK_RANGE_SELECT::unique_key_range()
6632
{
6633
  if (ranges.elements == 1)
6634
  {
6635
    QUICK_RANGE *tmp= *((QUICK_RANGE**)ranges.buffer);
6636
    if ((tmp->flag & (EQ_RANGE | NULL_RANGE)) == EQ_RANGE)
6637
    {
6638
      KEY *key=head->key_info+index;
53.2.14 by Monty Taylor
Removed HA_END_SPACE_KEY and references to it. It was _supposed_ to be gone anyway, but the ifdef around it was broken (MYSQL_VERSION_ID was actually undefined.)
6639
      return ((key->flags & (HA_NOSAME)) == HA_NOSAME &&
1 by brian
clean slate
6640
	      key->key_length == tmp->min_length);
6641
    }
6642
  }
6643
  return 0;
6644
}
6645
6646
6647
6648
/*
55 by brian
Update for using real bool types.
6649
  Return true if any part of the key is NULL
1 by brian
clean slate
6650
6651
  SYNOPSIS
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
6652
    null_part_in_key()
1 by brian
clean slate
6653
      key_part  Array of key parts (index description)
6654
      key       Key values tuple
6655
      length    Length of key values tuple in bytes.
6656
6657
  RETURN
55 by brian
Update for using real bool types.
6658
    true   The tuple has at least one "keypartX is NULL"
6659
    false  Otherwise
1 by brian
clean slate
6660
*/
6661
482 by Brian Aker
Remove uint.
6662
static bool null_part_in_key(KEY_PART *key_part, const unsigned char *key, uint32_t length)
1 by brian
clean slate
6663
{
481 by Brian Aker
Remove all of uchar.
6664
  for (const unsigned char *end=key+length ;
1 by brian
clean slate
6665
       key < end;
6666
       key+= key_part++->store_length)
6667
  {
6668
    if (key_part->null_bit && *key)
6669
      return 1;
6670
  }
6671
  return 0;
6672
}
6673
6674
1005.2.3 by Monty Taylor
Further reversion of P.
6675
bool QUICK_SELECT_I::is_keys_used(const MY_BITMAP *fields)
1 by brian
clean slate
6676
{
6677
  return is_key_used(head, index, fields);
6678
}
6679
1005.2.3 by Monty Taylor
Further reversion of P.
6680
bool QUICK_INDEX_MERGE_SELECT::is_keys_used(const MY_BITMAP *fields)
6681
{
6682
  QUICK_RANGE_SELECT *quick;
6683
  List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
6684
  while ((quick= it++))
6685
  {
6686
    if (is_key_used(head, quick->index, fields))
6687
      return 1;
6688
  }
6689
  return 0;
6690
}
6691
6692
bool QUICK_ROR_INTERSECT_SELECT::is_keys_used(const MY_BITMAP *fields)
6693
{
6694
  QUICK_RANGE_SELECT *quick;
6695
  List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
6696
  while ((quick= it++))
6697
  {
6698
    if (is_key_used(head, quick->index, fields))
6699
      return 1;
6700
  }
6701
  return 0;
6702
}
6703
6704
bool QUICK_ROR_UNION_SELECT::is_keys_used(const MY_BITMAP *fields)
1 by brian
clean slate
6705
{
6706
  QUICK_SELECT_I *quick;
6707
  List_iterator_fast<QUICK_SELECT_I> it(quick_selects);
6708
  while ((quick= it++))
6709
  {
6710
    if (quick->is_keys_used(fields))
6711
      return 1;
6712
  }
6713
  return 0;
6714
}
6715
6716
6717
/*
6718
  Create quick select from ref/ref_or_null scan.
6719
6720
  SYNOPSIS
6721
    get_quick_select_for_ref()
520.1.22 by Brian Aker
Second pass of thd cleanup
6722
      session      Thread handle
1 by brian
clean slate
6723
      table    Table to access
6724
      ref      ref[_or_null] scan parameters
6725
      records  Estimate of number of records (needed only to construct
6726
               quick select)
6727
  NOTES
6728
    This allocates things in a new memory root, as this may be called many
6729
    times during a query.
6730
6731
  RETURN
6732
    Quick select that retrieves the same rows as passed ref scan
6733
    NULL on error.
6734
*/
6735
520.1.22 by Brian Aker
Second pass of thd cleanup
6736
QUICK_RANGE_SELECT *get_quick_select_for_ref(Session *session, Table *table,
1 by brian
clean slate
6737
                                             TABLE_REF *ref, ha_rows records)
6738
{
6739
  MEM_ROOT *old_root, *alloc;
6740
  QUICK_RANGE_SELECT *quick;
6741
  KEY *key_info = &table->key_info[ref->key];
6742
  KEY_PART *key_part;
6743
  QUICK_RANGE *range;
482 by Brian Aker
Remove uint.
6744
  uint32_t part;
55 by brian
Update for using real bool types.
6745
  bool create_err= false;
1 by brian
clean slate
6746
  COST_VECT cost;
6747
520.1.22 by Brian Aker
Second pass of thd cleanup
6748
  old_root= session->mem_root;
6749
  /* The following call may change session->mem_root */
1005.2.3 by Monty Taylor
Further reversion of P.
6750
  quick= new QUICK_RANGE_SELECT(session, table, ref->key, 0, 0, &create_err);
1 by brian
clean slate
6751
  /* save mem_root set by QUICK_RANGE_SELECT constructor */
520.1.22 by Brian Aker
Second pass of thd cleanup
6752
  alloc= session->mem_root;
1 by brian
clean slate
6753
  /*
520.1.22 by Brian Aker
Second pass of thd cleanup
6754
    return back default mem_root (session->mem_root) changed by
1 by brian
clean slate
6755
    QUICK_RANGE_SELECT constructor
6756
  */
520.1.22 by Brian Aker
Second pass of thd cleanup
6757
  session->mem_root= old_root;
1 by brian
clean slate
6758
6759
  if (!quick || create_err)
6760
    return 0;			/* no ranges found */
6761
  if (quick->init())
6762
    goto err;
6763
  quick->records= records;
6764
520.1.22 by Brian Aker
Second pass of thd cleanup
6765
  if ((cp_buffer_from_ref(session, ref) && session->is_fatal_error) ||
1 by brian
clean slate
6766
      !(range= new(alloc) QUICK_RANGE()))
6767
    goto err;                                   // out of memory
6768
6769
  range->min_key= range->max_key= ref->key_buff;
6770
  range->min_length= range->max_length= ref->key_length;
6771
  range->min_keypart_map= range->max_keypart_map=
6772
    make_prev_keypart_map(ref->key_parts);
6773
  range->flag= ((ref->key_length == key_info->key_length &&
53.2.14 by Monty Taylor
Removed HA_END_SPACE_KEY and references to it. It was _supposed_ to be gone anyway, but the ifdef around it was broken (MYSQL_VERSION_ID was actually undefined.)
6774
		 key_info->flags == 0) ? EQ_RANGE : 0);
1 by brian
clean slate
6775
6776
  if (!(quick->key_parts=key_part=(KEY_PART *)
6777
	alloc_root(&quick->alloc,sizeof(KEY_PART)*ref->key_parts)))
6778
    goto err;
6779
6780
  for (part=0 ; part < ref->key_parts ;part++,key_part++)
6781
  {
6782
    key_part->part=part;
6783
    key_part->field=        key_info->key_part[part].field;
6784
    key_part->length=       key_info->key_part[part].length;
6785
    key_part->store_length= key_info->key_part[part].store_length;
6786
    key_part->null_bit=     key_info->key_part[part].null_bit;
206 by Brian Aker
Removed final uint dead types.
6787
    key_part->flag=         (uint8_t) key_info->key_part[part].key_part_flag;
1 by brian
clean slate
6788
  }
481 by Brian Aker
Remove all of uchar.
6789
  if (insert_dynamic(&quick->ranges,(unsigned char*)&range))
1 by brian
clean slate
6790
    goto err;
6791
6792
  /*
6793
     Add a NULL range if REF_OR_NULL optimization is used.
6794
     For example:
6795
       if we have "WHERE A=2 OR A IS NULL" we created the (A=2) range above
6796
       and have ref->null_ref_key set. Will create a new NULL range here.
6797
  */
6798
  if (ref->null_ref_key)
6799
  {
6800
    QUICK_RANGE *null_range;
6801
6802
    *ref->null_ref_key= 1;		// Set null byte then create a range
6803
    if (!(null_range= new (alloc)
6804
          QUICK_RANGE(ref->key_buff, ref->key_length,
6805
                      make_prev_keypart_map(ref->key_parts),
6806
                      ref->key_buff, ref->key_length,
6807
                      make_prev_keypart_map(ref->key_parts), EQ_RANGE)))
6808
      goto err;
6809
    *ref->null_ref_key= 0;		// Clear null byte
481 by Brian Aker
Remove all of uchar.
6810
    if (insert_dynamic(&quick->ranges,(unsigned char*)&null_range))
1 by brian
clean slate
6811
      goto err;
6812
  }
6813
6814
  /* Call multi_range_read_info() to get the MRR flags and buffer size */
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
6815
  quick->mrr_flags= HA_MRR_NO_ASSOCIATION |
1 by brian
clean slate
6816
                    (table->key_read ? HA_MRR_INDEX_ONLY : 0);
520.1.22 by Brian Aker
Second pass of thd cleanup
6817
  if (session->lex->sql_command != SQLCOM_SELECT)
1 by brian
clean slate
6818
    quick->mrr_flags |= HA_MRR_USE_DEFAULT_IMPL;
6819
520.1.22 by Brian Aker
Second pass of thd cleanup
6820
  quick->mrr_buf_size= session->variables.read_rnd_buff_size;
895 by Brian Aker
Completion (?) of uint conversion.
6821
  if (table->file->multi_range_read_info(quick->index, 1, (uint32_t)records,
1 by brian
clean slate
6822
                                         &quick->mrr_buf_size,
6823
                                         &quick->mrr_flags, &cost))
6824
    goto err;
6825
6826
  return quick;
6827
err:
6828
  delete quick;
6829
  return 0;
6830
}
6831
6832
6833
/*
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
6834
  Perform key scans for all used indexes (except CPK), get rowids and merge
1 by brian
clean slate
6835
  them into an ordered non-recurrent sequence of rowids.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
6836
1 by brian
clean slate
6837
  The merge/duplicate removal is performed using Unique class. We put all
6838
  rowids into Unique, get the sorted sequence and destroy the Unique.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
6839
55 by brian
Update for using real bool types.
6840
  If table has a clustered primary key that covers all rows (true for bdb
1 by brian
clean slate
6841
  and innodb currently) and one of the index_merge scans is a scan on PK,
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
6842
  then rows that will be retrieved by PK scan are not put into Unique and
1 by brian
clean slate
6843
  primary key scan is not performed here, it is performed later separately.
6844
6845
  RETURN
6846
    0     OK
6847
    other error
6848
*/
6849
6850
int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge()
6851
{
6852
  List_iterator_fast<QUICK_RANGE_SELECT> cur_quick_it(quick_selects);
6853
  QUICK_RANGE_SELECT* cur_quick;
6854
  int result;
6855
  Unique *unique;
6856
  handler *file= head->file;
6857
6858
  file->extra(HA_EXTRA_KEYREAD);
6859
  head->prepare_for_position();
6860
6861
  cur_quick_it.rewind();
6862
  cur_quick= cur_quick_it++;
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
6863
  assert(cur_quick != 0);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
6864
1 by brian
clean slate
6865
  /*
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
6866
    We reuse the same instance of handler so we need to call both init and
1 by brian
clean slate
6867
    reset here.
6868
  */
6869
  if (cur_quick->init() || cur_quick->reset())
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
6870
    return 0;
1 by brian
clean slate
6871
6872
  unique= new Unique(refpos_order_cmp, (void *)file,
6873
                     file->ref_length,
520.1.22 by Brian Aker
Second pass of thd cleanup
6874
                     session->variables.sortbuff_size);
1 by brian
clean slate
6875
  if (!unique)
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
6876
    return 0;
1 by brian
clean slate
6877
  for (;;)
6878
  {
6879
    while ((result= cur_quick->get_next()) == HA_ERR_END_OF_FILE)
6880
    {
6881
      cur_quick->range_end();
6882
      cur_quick= cur_quick_it++;
6883
      if (!cur_quick)
6884
        break;
6885
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
6886
      if (cur_quick->file->inited != handler::NONE)
1 by brian
clean slate
6887
        cur_quick->file->ha_index_end();
6888
      if (cur_quick->init() || cur_quick->reset())
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
6889
        return 0;
1 by brian
clean slate
6890
    }
6891
6892
    if (result)
6893
    {
6894
      if (result != HA_ERR_END_OF_FILE)
6895
      {
6896
        cur_quick->range_end();
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
6897
        return result;
1 by brian
clean slate
6898
      }
6899
      break;
6900
    }
6901
520.1.22 by Brian Aker
Second pass of thd cleanup
6902
    if (session->killed)
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
6903
      return 0;
1 by brian
clean slate
6904
6905
    /* skip row if it will be retrieved by clustered PK scan */
6906
    if (pk_quick_select && pk_quick_select->row_in_ranges())
6907
      continue;
6908
6909
    cur_quick->file->position(cur_quick->record);
6910
    result= unique->unique_add((char*)cur_quick->file->ref);
6911
    if (result)
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
6912
      return 0;
1 by brian
clean slate
6913
6914
  }
6915
6916
  /* ok, all row ids are in Unique */
6917
  result= unique->get(head);
6918
  delete unique;
55 by brian
Update for using real bool types.
6919
  doing_pk_scan= false;
1 by brian
clean slate
6920
  /* index_merge currently doesn't support "using index" at all */
6921
  file->extra(HA_EXTRA_NO_KEYREAD);
6922
  /* start table scan */
520.1.22 by Brian Aker
Second pass of thd cleanup
6923
  init_read_record(&read_record, session, head, (SQL_SELECT*) 0, 1, 1);
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
6924
  return result;
1 by brian
clean slate
6925
}
6926
6927
6928
/*
6929
  Get next row for index_merge.
6930
  NOTES
6931
    The rows are read from
6932
      1. rowids stored in Unique.
6933
      2. QUICK_RANGE_SELECT with clustered primary key (if any).
6934
    The sets of rows retrieved in 1) and 2) are guaranteed to be disjoint.
6935
*/
6936
6937
int QUICK_INDEX_MERGE_SELECT::get_next()
6938
{
6939
  int result;
6940
6941
  if (doing_pk_scan)
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
6942
    return(pk_quick_select->get_next());
1 by brian
clean slate
6943
6944
  if ((result= read_record.read_record(&read_record)) == -1)
6945
  {
6946
    result= HA_ERR_END_OF_FILE;
6947
    end_read_record(&read_record);
6948
    /* All rows from Unique have been retrieved, do a clustered PK scan */
6949
    if (pk_quick_select)
6950
    {
55 by brian
Update for using real bool types.
6951
      doing_pk_scan= true;
1 by brian
clean slate
6952
      if ((result= pk_quick_select->init()) ||
6953
          (result= pk_quick_select->reset()))
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
6954
        return result;
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
6955
      return(pk_quick_select->get_next());
1 by brian
clean slate
6956
    }
6957
  }
6958
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
6959
  return result;
1 by brian
clean slate
6960
}
6961
6962
6963
/*
6964
  Retrieve next record.
6965
  SYNOPSIS
6966
     QUICK_ROR_INTERSECT_SELECT::get_next()
6967
6968
  NOTES
6969
    Invariant on enter/exit: all intersected selects have retrieved all index
6970
    records with rowid <= some_rowid_val and no intersected select has
6971
    retrieved any index records with rowid > some_rowid_val.
6972
    We start fresh and loop until we have retrieved the same rowid in each of
6973
    the key scans or we got an error.
6974
6975
    If a Clustered PK scan is present, it is used only to check if row
6976
    satisfies its condition (and never used for row retrieval).
6977
6978
  RETURN
6979
   0     - Ok
6980
   other - Error code if any error occurred.
6981
*/
6982
6983
int QUICK_ROR_INTERSECT_SELECT::get_next()
6984
{
6985
  List_iterator_fast<QUICK_RANGE_SELECT> quick_it(quick_selects);
6986
  QUICK_RANGE_SELECT* quick;
6987
  int error, cmp;
482 by Brian Aker
Remove uint.
6988
  uint32_t last_rowid_count=0;
1 by brian
clean slate
6989
6990
  do
6991
  {
6992
    /* Get a rowid for first quick and save it as a 'candidate' */
6993
    quick= quick_it++;
6994
    error= quick->get_next();
6995
    if (cpk_quick)
6996
    {
6997
      while (!error && !cpk_quick->row_in_ranges())
6998
        error= quick->get_next();
6999
    }
7000
    if (error)
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
7001
      return(error);
1 by brian
clean slate
7002
7003
    quick->file->position(quick->record);
7004
    memcpy(last_rowid, quick->file->ref, head->file->ref_length);
7005
    last_rowid_count= 1;
7006
7007
    while (last_rowid_count < quick_selects.elements)
7008
    {
7009
      if (!(quick= quick_it++))
7010
      {
7011
        quick_it.rewind();
7012
        quick= quick_it++;
7013
      }
7014
7015
      do
7016
      {
7017
        if ((error= quick->get_next()))
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
7018
          return(error);
1 by brian
clean slate
7019
        quick->file->position(quick->record);
7020
        cmp= head->file->cmp_ref(quick->file->ref, last_rowid);
7021
      } while (cmp < 0);
7022
7023
      /* Ok, current select 'caught up' and returned ref >= cur_ref */
7024
      if (cmp > 0)
7025
      {
7026
        /* Found a row with ref > cur_ref. Make it a new 'candidate' */
7027
        if (cpk_quick)
7028
        {
7029
          while (!cpk_quick->row_in_ranges())
7030
          {
7031
            if ((error= quick->get_next()))
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
7032
              return(error);
1 by brian
clean slate
7033
          }
7034
        }
7035
        memcpy(last_rowid, quick->file->ref, head->file->ref_length);
7036
        last_rowid_count= 1;
7037
      }
7038
      else
7039
      {
7040
        /* current 'candidate' row confirmed by this select */
7041
        last_rowid_count++;
7042
      }
7043
    }
7044
7045
    /* We get here if we got the same row ref in all scans. */
7046
    if (need_to_fetch_row)
7047
      error= head->file->rnd_pos(head->record[0], last_rowid);
7048
  } while (error == HA_ERR_RECORD_DELETED);
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
7049
  return(error);
1 by brian
clean slate
7050
}
7051
7052
7053
/*
7054
  Retrieve next record.
7055
  SYNOPSIS
7056
    QUICK_ROR_UNION_SELECT::get_next()
7057
7058
  NOTES
7059
    Enter/exit invariant:
7060
    For each quick select in the queue a {key,rowid} tuple has been
7061
    retrieved but the corresponding row hasn't been passed to output.
7062
7063
  RETURN
7064
   0     - Ok
7065
   other - Error code if any error occurred.
7066
*/
7067
7068
int QUICK_ROR_UNION_SELECT::get_next()
7069
{
7070
  int error, dup_row;
7071
  QUICK_SELECT_I *quick;
481 by Brian Aker
Remove all of uchar.
7072
  unsigned char *tmp;
1 by brian
clean slate
7073
7074
  do
7075
  {
7076
    do
7077
    {
957.1.6 by Padraig O'Sullivan
Fixed function object to ensure it correctly returns a boolean type since
7078
      if (queue->empty())
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
7079
        return(HA_ERR_END_OF_FILE);
1 by brian
clean slate
7080
      /* Ok, we have a queue with >= 1 scans */
7081
957.1.6 by Padraig O'Sullivan
Fixed function object to ensure it correctly returns a boolean type since
7082
      quick= queue->top();
1 by brian
clean slate
7083
      memcpy(cur_rowid, quick->last_rowid, rowid_length);
7084
7085
      /* put into queue rowid from the same stream as top element */
7086
      if ((error= quick->get_next()))
7087
      {
7088
        if (error != HA_ERR_END_OF_FILE)
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
7089
          return(error);
957.1.6 by Padraig O'Sullivan
Fixed function object to ensure it correctly returns a boolean type since
7090
        queue->pop();
1 by brian
clean slate
7091
      }
7092
      else
7093
      {
7094
        quick->save_last_pos();
957.1.6 by Padraig O'Sullivan
Fixed function object to ensure it correctly returns a boolean type since
7095
        queue->pop();
7096
        queue->push(quick);
1 by brian
clean slate
7097
      }
7098
7099
      if (!have_prev_rowid)
7100
      {
7101
        /* No rows have been returned yet */
55 by brian
Update for using real bool types.
7102
        dup_row= false;
7103
        have_prev_rowid= true;
1 by brian
clean slate
7104
      }
7105
      else
7106
        dup_row= !head->file->cmp_ref(cur_rowid, prev_rowid);
7107
    } while (dup_row);
7108
7109
    tmp= cur_rowid;
7110
    cur_rowid= prev_rowid;
7111
    prev_rowid= tmp;
7112
7113
    error= head->file->rnd_pos(quick->record, prev_rowid);
7114
  } while (error == HA_ERR_RECORD_DELETED);
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
7115
  return(error);
1 by brian
clean slate
7116
}
7117
7118
7119
int QUICK_RANGE_SELECT::reset()
7120
{
482 by Brian Aker
Remove uint.
7121
  uint32_t  buf_size;
481 by Brian Aker
Remove all of uchar.
7122
  unsigned char *mrange_buff;
1 by brian
clean slate
7123
  int   error;
7124
  HANDLER_BUFFER empty_buf;
7125
  last_range= NULL;
7126
  cur_range= (QUICK_RANGE**) ranges.buffer;
7127
7128
  if (file->inited == handler::NONE && (error= file->ha_index_init(index,1)))
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
7129
    return(error);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
7130
1 by brian
clean slate
7131
  /* Allocate buffer if we need one but haven't allocated it yet */
7132
  if (mrr_buf_size && !mrr_buf_desc)
7133
  {
7134
    buf_size= mrr_buf_size;
7135
    while (buf_size && !my_multi_malloc(MYF(MY_WME),
7136
                                        &mrr_buf_desc, sizeof(*mrr_buf_desc),
7137
                                        &mrange_buff, buf_size,
461 by Monty Taylor
Removed NullS. bu-bye.
7138
                                        NULL))
1 by brian
clean slate
7139
    {
7140
      /* Try to shrink the buffers until both are 0. */
7141
      buf_size/= 2;
7142
    }
7143
    if (!mrr_buf_desc)
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
7144
      return(HA_ERR_OUT_OF_MEM);
1 by brian
clean slate
7145
7146
    /* Initialize the handler buffer. */
7147
    mrr_buf_desc->buffer= mrange_buff;
7148
    mrr_buf_desc->buffer_end= mrange_buff + buf_size;
7149
    mrr_buf_desc->end_of_used_area= mrange_buff;
7150
  }
7151
7152
  if (!mrr_buf_desc)
7153
    empty_buf.buffer= empty_buf.buffer_end= empty_buf.end_of_used_area= NULL;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
7154
1 by brian
clean slate
7155
  if (sorted)
7156
     mrr_flags |= HA_MRR_SORTED;
7157
  RANGE_SEQ_IF seq_funcs= {quick_range_seq_init, quick_range_seq_next};
7158
  error= file->multi_range_read_init(&seq_funcs, (void*)this, ranges.elements,
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
7159
                                     mrr_flags, mrr_buf_desc? mrr_buf_desc:
1 by brian
clean slate
7160
                                                              &empty_buf);
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
7161
  return(error);
1 by brian
clean slate
7162
}
7163
7164
7165
/*
7166
  Range sequence interface implementation for array<QUICK_RANGE>: initialize
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
7167
1 by brian
clean slate
7168
  SYNOPSIS
7169
    quick_range_seq_init()
7170
      init_param  Caller-opaque paramenter: QUICK_RANGE_SELECT* pointer
7171
      n_ranges    Number of ranges in the sequence (ignored)
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
7172
      flags       MRR flags (currently not used)
1 by brian
clean slate
7173
7174
  RETURN
7175
    Opaque value to be passed to quick_range_seq_next
7176
*/
7177
655 by Brian Aker
Yet more unused.... damn annoying... (also tossed some prototypes that were
7178
range_seq_t quick_range_seq_init(void *init_param, uint32_t, uint32_t)
1 by brian
clean slate
7179
{
7180
  QUICK_RANGE_SELECT *quick= (QUICK_RANGE_SELECT*)init_param;
7181
  quick->qr_traversal_ctx.first=  (QUICK_RANGE**)quick->ranges.buffer;
7182
  quick->qr_traversal_ctx.cur=    (QUICK_RANGE**)quick->ranges.buffer;
77.1.46 by Monty Taylor
Finished the warnings work!
7183
  quick->qr_traversal_ctx.last=   quick->qr_traversal_ctx.cur +
1 by brian
clean slate
7184
                                  quick->ranges.elements;
7185
  return &quick->qr_traversal_ctx;
7186
}
7187
7188
7189
/*
7190
  Range sequence interface implementation for array<QUICK_RANGE>: get next
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
7191
1 by brian
clean slate
7192
  SYNOPSIS
7193
    quick_range_seq_next()
7194
      rseq        Value returned from quick_range_seq_init
7195
      range  OUT  Store information about the range here
7196
7197
  RETURN
7198
    0  Ok
7199
    1  No more ranges in the sequence
7200
*/
7201
482 by Brian Aker
Remove uint.
7202
uint32_t quick_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range)
1 by brian
clean slate
7203
{
7204
  QUICK_RANGE_SEQ_CTX *ctx= (QUICK_RANGE_SEQ_CTX*)rseq;
7205
7206
  if (ctx->cur == ctx->last)
7207
    return 1; /* no more ranges */
7208
7209
  QUICK_RANGE *cur= *(ctx->cur);
7210
  key_range *start_key= &range->start_key;
7211
  key_range *end_key=   &range->end_key;
7212
7213
  start_key->key=    cur->min_key;
7214
  start_key->length= cur->min_length;
7215
  start_key->keypart_map= cur->min_keypart_map;
7216
  start_key->flag=   ((cur->flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
7217
                      (cur->flag & EQ_RANGE) ?
7218
                      HA_READ_KEY_EXACT : HA_READ_KEY_OR_NEXT);
7219
  end_key->key=      cur->max_key;
7220
  end_key->length=   cur->max_length;
7221
  end_key->keypart_map= cur->max_keypart_map;
7222
  /*
7223
    We use HA_READ_AFTER_KEY here because if we are reading on a key
7224
    prefix. We want to find all keys with this prefix.
7225
  */
7226
  end_key->flag=     (cur->flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
7227
                      HA_READ_AFTER_KEY);
7228
  range->range_flag= cur->flag;
7229
  ctx->cur++;
7230
  return 0;
7231
}
7232
7233
7234
/*
7235
  MRR range sequence interface: array<QUICK_RANGE> impl: utility func for NDB
7236
7237
  SYNOPSIS
7238
    mrr_persistent_flag_storage()
7239
      seq  Range sequence being traversed
7240
      idx  Number of range
7241
7242
  DESCRIPTION
7243
    MRR/NDB implementation needs to store some bits for each range. This
7244
    function returns a reference to the "range_flag" associated with the
7245
    range number idx.
7246
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
7247
    This function should be removed when we get a proper MRR/NDB
1 by brian
clean slate
7248
    implementation.
7249
7250
  RETURN
7251
    Reference to range_flag associated with range number #idx
7252
*/
7253
482 by Brian Aker
Remove uint.
7254
uint16_t &mrr_persistent_flag_storage(range_seq_t seq, uint32_t idx)
1 by brian
clean slate
7255
{
7256
  QUICK_RANGE_SEQ_CTX *ctx= (QUICK_RANGE_SEQ_CTX*)seq;
7257
  return ctx->first[idx]->flag;
7258
}
7259
7260
7261
/*
7262
  MRR range sequence interface: array<QUICK_RANGE> impl: utility func for NDB
7263
7264
  SYNOPSIS
7265
    mrr_get_ptr_by_idx()
7266
      seq  Range sequence bening traversed
7267
      idx  Number of the range
7268
7269
  DESCRIPTION
7270
    An extension of MRR range sequence interface needed by NDB: return the
7271
    data associated with the given range.
7272
7273
    A proper MRR interface implementer is supposed to store and return
7274
    range-associated data. NDB stores number of the range instead. So this
7275
    is a helper function that translates range number to range associated
7276
    data.
7277
7278
    This function does nothing, as currrently there is only one user of the
7279
    MRR interface - the quick range select code, and this user doesn't need
7280
    to use range-associated data.
7281
7282
  RETURN
7283
    Reference to range-associated data
7284
*/
7285
655 by Brian Aker
Yet more unused.... damn annoying... (also tossed some prototypes that were
7286
char* &mrr_get_ptr_by_idx(range_seq_t, uint32_t)
1 by brian
clean slate
7287
{
7288
  static char *dummy;
7289
  return dummy;
7290
}
7291
7292
7293
/*
7294
  Get next possible record using quick-struct.
7295
7296
  SYNOPSIS
7297
    QUICK_RANGE_SELECT::get_next()
7298
7299
  NOTES
7300
    Record is read into table->record[0]
7301
7302
  RETURN
7303
    0			Found row
7304
    HA_ERR_END_OF_FILE	No (more) rows in range
7305
    #			Error code
7306
*/
7307
7308
int QUICK_RANGE_SELECT::get_next()
7309
{
7310
  char *dummy;
7311
  if (in_ror_merged_scan)
7312
  {
7313
    /*
7314
      We don't need to signal the bitmap change as the bitmap is always the
7315
      same for this head->file
7316
    */
1005.2.10 by Monty Taylor
Got rid of column_bitmap_signal. Unused.
7317
    head->column_bitmaps_set(&column_bitmap, &column_bitmap);
1 by brian
clean slate
7318
  }
7319
7320
  int result= file->multi_range_read_next(&dummy);
7321
7322
  if (in_ror_merged_scan)
7323
  {
7324
    /* Restore bitmaps set on entry */
1005.2.10 by Monty Taylor
Got rid of column_bitmap_signal. Unused.
7325
    head->column_bitmaps_set(save_read_set, save_write_set);
1 by brian
clean slate
7326
  }
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
7327
  return result;
1 by brian
clean slate
7328
}
7329
7330
7331
/*
7332
  Get the next record with a different prefix.
7333
7334
  SYNOPSIS
7335
    QUICK_RANGE_SELECT::get_next_prefix()
7336
    prefix_length  length of cur_prefix
7337
    cur_prefix     prefix of a key to be searched for
7338
7339
  DESCRIPTION
7340
    Each subsequent call to the method retrieves the first record that has a
7341
    prefix with length prefix_length different from cur_prefix, such that the
7342
    record with the new prefix is within the ranges described by
7343
    this->ranges. The record found is stored into the buffer pointed by
7344
    this->record.
7345
    The method is useful for GROUP-BY queries with range conditions to
7346
    discover the prefix of the next group that satisfies the range conditions.
7347
7348
  TODO
7349
    This method is a modified copy of QUICK_RANGE_SELECT::get_next(), so both
7350
    methods should be unified into a more general one to reduce code
7351
    duplication.
7352
7353
  RETURN
7354
    0                  on success
7355
    HA_ERR_END_OF_FILE if returned all keys
7356
    other              if some error occurred
7357
*/
7358
482 by Brian Aker
Remove uint.
7359
int QUICK_RANGE_SELECT::get_next_prefix(uint32_t prefix_length,
1 by brian
clean slate
7360
                                        key_part_map keypart_map,
481 by Brian Aker
Remove all of uchar.
7361
                                        unsigned char *cur_prefix)
1 by brian
clean slate
7362
{
7363
  for (;;)
7364
  {
7365
    int result;
7366
    key_range start_key, end_key;
7367
    if (last_range)
7368
    {
7369
      /* Read the next record in the same range with prefix after cur_prefix. */
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
7370
      assert(cur_prefix != 0);
1 by brian
clean slate
7371
      result= file->index_read_map(record, cur_prefix, keypart_map,
7372
                                   HA_READ_AFTER_KEY);
7373
      if (result || (file->compare_key(file->end_range) <= 0))
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
7374
        return result;
1 by brian
clean slate
7375
    }
7376
482 by Brian Aker
Remove uint.
7377
    uint32_t count= ranges.elements - (cur_range - (QUICK_RANGE**) ranges.buffer);
1 by brian
clean slate
7378
    if (count == 0)
7379
    {
7380
      /* Ranges have already been used up before. None is left for read. */
7381
      last_range= 0;
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
7382
      return HA_ERR_END_OF_FILE;
1 by brian
clean slate
7383
    }
7384
    last_range= *(cur_range++);
7385
481 by Brian Aker
Remove all of uchar.
7386
    start_key.key=    (const unsigned char*) last_range->min_key;
398.1.4 by Monty Taylor
Renamed max/min.
7387
    start_key.length= cmin(last_range->min_length, (uint16_t)prefix_length);
1 by brian
clean slate
7388
    start_key.keypart_map= last_range->min_keypart_map & keypart_map;
7389
    start_key.flag=   ((last_range->flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
7390
		       (last_range->flag & EQ_RANGE) ?
7391
		       HA_READ_KEY_EXACT : HA_READ_KEY_OR_NEXT);
481 by Brian Aker
Remove all of uchar.
7392
    end_key.key=      (const unsigned char*) last_range->max_key;
398.1.4 by Monty Taylor
Renamed max/min.
7393
    end_key.length=   cmin(last_range->max_length, (uint16_t)prefix_length);
1 by brian
clean slate
7394
    end_key.keypart_map= last_range->max_keypart_map & keypart_map;
7395
    /*
7396
      We use READ_AFTER_KEY here because if we are reading on a key
7397
      prefix we want to find all keys with this prefix
7398
    */
7399
    end_key.flag=     (last_range->flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
7400
		       HA_READ_AFTER_KEY);
7401
7402
    result= file->read_range_first(last_range->min_keypart_map ? &start_key : 0,
7403
				   last_range->max_keypart_map ? &end_key : 0,
7404
                                   test(last_range->flag & EQ_RANGE),
7405
				   sorted);
7406
    if (last_range->flag == (UNIQUE_RANGE | EQ_RANGE))
7407
      last_range= 0;			// Stop searching
7408
7409
    if (result != HA_ERR_END_OF_FILE)
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
7410
      return result;
1 by brian
clean slate
7411
    last_range= 0;			// No matching rows; go to next range
7412
  }
7413
}
7414
7415
7416
/*
7417
  Check if current row will be retrieved by this QUICK_RANGE_SELECT
7418
7419
  NOTES
7420
    It is assumed that currently a scan is being done on another index
7421
    which reads all necessary parts of the index that is scanned by this
7422
    quick select.
7423
    The implementation does a binary search on sorted array of disjoint
7424
    ranges, without taking size of range into account.
7425
7426
    This function is used to filter out clustered PK scan rows in
7427
    index_merge quick select.
7428
7429
  RETURN
55 by brian
Update for using real bool types.
7430
    true  if current row will be retrieved by this quick select
7431
    false if not
1 by brian
clean slate
7432
*/
7433
7434
bool QUICK_RANGE_SELECT::row_in_ranges()
7435
{
7436
  QUICK_RANGE *res;
482 by Brian Aker
Remove uint.
7437
  uint32_t min= 0;
7438
  uint32_t max= ranges.elements - 1;
7439
  uint32_t mid= (max + min)/2;
1 by brian
clean slate
7440
7441
  while (min != max)
7442
  {
7443
    if (cmp_next(*(QUICK_RANGE**)dynamic_array_ptr(&ranges, mid)))
7444
    {
7445
      /* current row value > mid->max */
7446
      min= mid + 1;
7447
    }
7448
    else
7449
      max= mid;
7450
    mid= (min + max) / 2;
7451
  }
7452
  res= *(QUICK_RANGE**)dynamic_array_ptr(&ranges, mid);
7453
  return (!cmp_next(res) && !cmp_prev(res));
7454
}
7455
7456
/*
7457
  This is a hack: we inherit from QUICK_SELECT so that we can use the
7458
  get_next() interface, but we have to hold a pointer to the original
7459
  QUICK_SELECT because its data are used all over the place.  What
7460
  should be done is to factor out the data that is needed into a base
7461
  class (QUICK_SELECT), and then have two subclasses (_ASC and _DESC)
7462
  which handle the ranges and implement the get_next() function.  But
7463
  for now, this seems to work right at least.
7464
 */
7465
655 by Brian Aker
Yet more unused.... damn annoying... (also tossed some prototypes that were
7466
QUICK_SELECT_DESC::QUICK_SELECT_DESC(QUICK_RANGE_SELECT *q, uint32_t, bool *)
1 by brian
clean slate
7467
 :QUICK_RANGE_SELECT(*q), rev_it(rev_ranges)
7468
{
7469
  QUICK_RANGE *r;
7470
7471
  QUICK_RANGE **pr= (QUICK_RANGE**)ranges.buffer;
7472
  QUICK_RANGE **end_range= pr + ranges.elements;
7473
  for (; pr!=end_range; pr++)
7474
    rev_ranges.push_front(*pr);
7475
7476
  /* Remove EQ_RANGE flag for keys that are not using the full key */
7477
  for (r = rev_it++; r; r = rev_it++)
7478
  {
7479
    if ((r->flag & EQ_RANGE) &&
7480
	head->key_info[index].key_length != r->max_length)
7481
      r->flag&= ~EQ_RANGE;
7482
  }
7483
  rev_it.rewind();
7484
  q->dont_free=1;				// Don't free shared mem
7485
  delete q;
7486
}
7487
7488
7489
int QUICK_SELECT_DESC::get_next()
7490
{
7491
  /* The max key is handled as follows:
7492
   *   - if there is NO_MAX_RANGE, start at the end and move backwards
7493
   *   - if it is an EQ_RANGE, which means that max key covers the entire
7494
   *     key, go directly to the key and read through it (sorting backwards is
7495
   *     same as sorting forwards)
7496
   *   - if it is NEAR_MAX, go to the key or next, step back once, and
7497
   *     move backwards
7498
   *   - otherwise (not NEAR_MAX == include the key), go after the key,
7499
   *     step back once, and move backwards
7500
   */
7501
7502
  for (;;)
7503
  {
7504
    int result;
7505
    if (last_range)
7506
    {						// Already read through key
7507
      result = ((last_range->flag & EQ_RANGE)
7508
		? file->index_next_same(record, last_range->min_key,
7509
					last_range->min_length) :
7510
		file->index_prev(record));
7511
      if (!result)
7512
      {
7513
	if (cmp_prev(*rev_it.ref()) == 0)
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
7514
	  return 0;
1 by brian
clean slate
7515
      }
7516
      else if (result != HA_ERR_END_OF_FILE)
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
7517
	return result;
1 by brian
clean slate
7518
    }
7519
7520
    if (!(last_range= rev_it++))
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
7521
      return HA_ERR_END_OF_FILE;		// All ranges used
1 by brian
clean slate
7522
7523
    if (last_range->flag & NO_MAX_RANGE)        // Read last record
7524
    {
7525
      int local_error;
7526
      if ((local_error=file->index_last(record)))
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
7527
	return(local_error);		// Empty table
1 by brian
clean slate
7528
      if (cmp_prev(last_range) == 0)
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
7529
	return 0;
1 by brian
clean slate
7530
      last_range= 0;                            // No match; go to next range
7531
      continue;
7532
    }
7533
7534
    if (last_range->flag & EQ_RANGE)
7535
    {
7536
      result = file->index_read_map(record, last_range->max_key,
7537
                                    last_range->max_keypart_map,
7538
                                    HA_READ_KEY_EXACT);
7539
    }
7540
    else
7541
    {
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
7542
      assert(last_range->flag & NEAR_MAX ||
1 by brian
clean slate
7543
                  range_reads_after_key(last_range));
7544
      result=file->index_read_map(record, last_range->max_key,
7545
                                  last_range->max_keypart_map,
7546
                                  ((last_range->flag & NEAR_MAX) ?
7547
                                   HA_READ_BEFORE_KEY :
7548
                                   HA_READ_PREFIX_LAST_OR_PREV));
7549
    }
7550
    if (result)
7551
    {
7552
      if (result != HA_ERR_KEY_NOT_FOUND && result != HA_ERR_END_OF_FILE)
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
7553
	return result;
1 by brian
clean slate
7554
      last_range= 0;                            // Not found, to next range
7555
      continue;
7556
    }
7557
    if (cmp_prev(last_range) == 0)
7558
    {
7559
      if (last_range->flag == (UNIQUE_RANGE | EQ_RANGE))
7560
	last_range= 0;				// Stop searching
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
7561
      return 0;				// Found key is in range
1 by brian
clean slate
7562
    }
7563
    last_range= 0;                              // To next range
7564
  }
7565
}
7566
7567
7568
/*
7569
  Compare if found key is over max-value
7570
  Returns 0 if key <= range->max_key
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
7571
  TODO: Figure out why can't this function be as simple as cmp_prev().
1 by brian
clean slate
7572
*/
7573
7574
int QUICK_RANGE_SELECT::cmp_next(QUICK_RANGE *range_arg)
7575
{
7576
  if (range_arg->flag & NO_MAX_RANGE)
7577
    return 0;                                   /* key can't be to large */
7578
7579
  KEY_PART *key_part=key_parts;
482 by Brian Aker
Remove uint.
7580
  uint32_t store_length;
1 by brian
clean slate
7581
481 by Brian Aker
Remove all of uchar.
7582
  for (unsigned char *key=range_arg->max_key, *end=key+range_arg->max_length;
1 by brian
clean slate
7583
       key < end;
7584
       key+= store_length, key_part++)
7585
  {
7586
    int cmp;
7587
    store_length= key_part->store_length;
7588
    if (key_part->null_bit)
7589
    {
7590
      if (*key)
7591
      {
7592
        if (!key_part->field->is_null())
7593
          return 1;
7594
        continue;
7595
      }
7596
      else if (key_part->field->is_null())
7597
        return 0;
7598
      key++;					// Skip null byte
7599
      store_length--;
7600
    }
7601
    if ((cmp=key_part->field->key_cmp(key, key_part->length)) < 0)
7602
      return 0;
7603
    if (cmp > 0)
7604
      return 1;
7605
  }
7606
  return (range_arg->flag & NEAR_MAX) ? 1 : 0;          // Exact match
7607
}
7608
7609
7610
/*
7611
  Returns 0 if found key is inside range (found key >= range->min_key).
7612
*/
7613
7614
int QUICK_RANGE_SELECT::cmp_prev(QUICK_RANGE *range_arg)
7615
{
7616
  int cmp;
7617
  if (range_arg->flag & NO_MIN_RANGE)
7618
    return 0;					/* key can't be to small */
7619
7620
  cmp= key_cmp(key_part_info, range_arg->min_key,
7621
               range_arg->min_length);
7622
  if (cmp > 0 || (cmp == 0 && (range_arg->flag & NEAR_MIN) == false))
7623
    return 0;
7624
  return 1;                                     // outside of range
7625
}
7626
7627
7628
/*
55 by brian
Update for using real bool types.
7629
 * true if this range will require using HA_READ_AFTER_KEY
1 by brian
clean slate
7630
   See comment in get_next() about this
7631
 */
7632
7633
bool QUICK_SELECT_DESC::range_reads_after_key(QUICK_RANGE *range_arg)
7634
{
7635
  return ((range_arg->flag & (NO_MAX_RANGE | NEAR_MAX)) ||
7636
	  !(range_arg->flag & EQ_RANGE) ||
7637
	  head->key_info[index].key_length != range_arg->max_length) ? 1 : 0;
7638
}
7639
7640
7641
void QUICK_RANGE_SELECT::add_info_string(String *str)
7642
{
7643
  KEY *key_info= head->key_info + index;
7644
  str->append(key_info->name);
7645
}
7646
7647
void QUICK_INDEX_MERGE_SELECT::add_info_string(String *str)
7648
{
7649
  QUICK_RANGE_SELECT *quick;
55 by brian
Update for using real bool types.
7650
  bool first= true;
1 by brian
clean slate
7651
  List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
7652
  str->append(STRING_WITH_LEN("sort_union("));
7653
  while ((quick= it++))
7654
  {
7655
    if (!first)
7656
      str->append(',');
7657
    else
55 by brian
Update for using real bool types.
7658
      first= false;
1 by brian
clean slate
7659
    quick->add_info_string(str);
7660
  }
7661
  if (pk_quick_select)
7662
  {
7663
    str->append(',');
7664
    pk_quick_select->add_info_string(str);
7665
  }
7666
  str->append(')');
7667
}
7668
7669
void QUICK_ROR_INTERSECT_SELECT::add_info_string(String *str)
7670
{
55 by brian
Update for using real bool types.
7671
  bool first= true;
1 by brian
clean slate
7672
  QUICK_RANGE_SELECT *quick;
7673
  List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
7674
  str->append(STRING_WITH_LEN("intersect("));
7675
  while ((quick= it++))
7676
  {
7677
    KEY *key_info= head->key_info + quick->index;
7678
    if (!first)
7679
      str->append(',');
7680
    else
55 by brian
Update for using real bool types.
7681
      first= false;
1 by brian
clean slate
7682
    str->append(key_info->name);
7683
  }
7684
  if (cpk_quick)
7685
  {
7686
    KEY *key_info= head->key_info + cpk_quick->index;
7687
    str->append(',');
7688
    str->append(key_info->name);
7689
  }
7690
  str->append(')');
7691
}
7692
7693
void QUICK_ROR_UNION_SELECT::add_info_string(String *str)
7694
{
55 by brian
Update for using real bool types.
7695
  bool first= true;
1 by brian
clean slate
7696
  QUICK_SELECT_I *quick;
7697
  List_iterator_fast<QUICK_SELECT_I> it(quick_selects);
7698
  str->append(STRING_WITH_LEN("union("));
7699
  while ((quick= it++))
7700
  {
7701
    if (!first)
7702
      str->append(',');
7703
    else
55 by brian
Update for using real bool types.
7704
      first= false;
1 by brian
clean slate
7705
    quick->add_info_string(str);
7706
  }
7707
  str->append(')');
7708
}
7709
7710
7711
void QUICK_RANGE_SELECT::add_keys_and_lengths(String *key_names,
7712
                                              String *used_lengths)
7713
{
7714
  char buf[64];
482 by Brian Aker
Remove uint.
7715
  uint32_t length;
1 by brian
clean slate
7716
  KEY *key_info= head->key_info + index;
7717
  key_names->append(key_info->name);
152 by Brian Aker
longlong replacement
7718
  length= int64_t2str(max_used_key_length, buf, 10) - buf;
1 by brian
clean slate
7719
  used_lengths->append(buf, length);
7720
}
7721
7722
void QUICK_INDEX_MERGE_SELECT::add_keys_and_lengths(String *key_names,
7723
                                                    String *used_lengths)
7724
{
7725
  char buf[64];
482 by Brian Aker
Remove uint.
7726
  uint32_t length;
55 by brian
Update for using real bool types.
7727
  bool first= true;
1 by brian
clean slate
7728
  QUICK_RANGE_SELECT *quick;
7729
7730
  List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
7731
  while ((quick= it++))
7732
  {
7733
    if (first)
55 by brian
Update for using real bool types.
7734
      first= false;
1 by brian
clean slate
7735
    else
7736
    {
7737
      key_names->append(',');
7738
      used_lengths->append(',');
7739
    }
7740
7741
    KEY *key_info= head->key_info + quick->index;
7742
    key_names->append(key_info->name);
152 by Brian Aker
longlong replacement
7743
    length= int64_t2str(quick->max_used_key_length, buf, 10) - buf;
1 by brian
clean slate
7744
    used_lengths->append(buf, length);
7745
  }
7746
  if (pk_quick_select)
7747
  {
7748
    KEY *key_info= head->key_info + pk_quick_select->index;
7749
    key_names->append(',');
7750
    key_names->append(key_info->name);
152 by Brian Aker
longlong replacement
7751
    length= int64_t2str(pk_quick_select->max_used_key_length, buf, 10) - buf;
1 by brian
clean slate
7752
    used_lengths->append(',');
7753
    used_lengths->append(buf, length);
7754
  }
7755
}
7756
7757
void QUICK_ROR_INTERSECT_SELECT::add_keys_and_lengths(String *key_names,
7758
                                                      String *used_lengths)
7759
{
7760
  char buf[64];
482 by Brian Aker
Remove uint.
7761
  uint32_t length;
55 by brian
Update for using real bool types.
7762
  bool first= true;
1 by brian
clean slate
7763
  QUICK_RANGE_SELECT *quick;
7764
  List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
7765
  while ((quick= it++))
7766
  {
7767
    KEY *key_info= head->key_info + quick->index;
7768
    if (first)
55 by brian
Update for using real bool types.
7769
      first= false;
1 by brian
clean slate
7770
    else
7771
    {
7772
      key_names->append(',');
7773
      used_lengths->append(',');
7774
    }
7775
    key_names->append(key_info->name);
152 by Brian Aker
longlong replacement
7776
    length= int64_t2str(quick->max_used_key_length, buf, 10) - buf;
1 by brian
clean slate
7777
    used_lengths->append(buf, length);
7778
  }
7779
7780
  if (cpk_quick)
7781
  {
7782
    KEY *key_info= head->key_info + cpk_quick->index;
7783
    key_names->append(',');
7784
    key_names->append(key_info->name);
152 by Brian Aker
longlong replacement
7785
    length= int64_t2str(cpk_quick->max_used_key_length, buf, 10) - buf;
1 by brian
clean slate
7786
    used_lengths->append(',');
7787
    used_lengths->append(buf, length);
7788
  }
7789
}
7790
7791
void QUICK_ROR_UNION_SELECT::add_keys_and_lengths(String *key_names,
7792
                                                  String *used_lengths)
7793
{
55 by brian
Update for using real bool types.
7794
  bool first= true;
1 by brian
clean slate
7795
  QUICK_SELECT_I *quick;
7796
  List_iterator_fast<QUICK_SELECT_I> it(quick_selects);
7797
  while ((quick= it++))
7798
  {
7799
    if (first)
55 by brian
Update for using real bool types.
7800
      first= false;
1 by brian
clean slate
7801
    else
7802
    {
7803
      used_lengths->append(',');
7804
      key_names->append(',');
7805
    }
7806
    quick->add_keys_and_lengths(key_names, used_lengths);
7807
  }
7808
}
7809
7810
7811
/*******************************************************************************
7812
* Implementation of QUICK_GROUP_MIN_MAX_SELECT
7813
*******************************************************************************/
7814
482 by Brian Aker
Remove uint.
7815
static inline uint32_t get_field_keypart(KEY *index, Field *field);
7816
static inline SEL_ARG * get_index_range_tree(uint32_t index, SEL_TREE* range_tree,
7817
                                             PARAM *param, uint32_t *param_idx);
1 by brian
clean slate
7818
static bool get_constant_key_infix(KEY *index_info, SEL_ARG *index_range_tree,
7819
                       KEY_PART_INFO *first_non_group_part,
7820
                       KEY_PART_INFO *min_max_arg_part,
520.1.22 by Brian Aker
Second pass of thd cleanup
7821
                       KEY_PART_INFO *last_part, Session *session,
482 by Brian Aker
Remove uint.
7822
                       unsigned char *key_infix, uint32_t *key_infix_len,
1 by brian
clean slate
7823
                       KEY_PART_INFO **first_non_infix_part);
7824
static bool
7825
check_group_min_max_predicates(COND *cond, Item_field *min_max_arg_item,
7826
                               Field::imagetype image_type);
7827
7828
static void
482 by Brian Aker
Remove uint.
7829
cost_group_min_max(Table* table, KEY *index_info, uint32_t used_key_parts,
7830
                   uint32_t group_key_parts, SEL_TREE *range_tree,
1 by brian
clean slate
7831
                   SEL_ARG *index_tree, ha_rows quick_prefix_records,
7832
                   bool have_min, bool have_max,
7833
                   double *read_cost, ha_rows *records);
7834
7835
7836
/*
7837
  Test if this access method is applicable to a GROUP query with MIN/MAX
7838
  functions, and if so, construct a new TRP object.
7839
7840
  SYNOPSIS
7841
    get_best_group_min_max()
7842
    param    Parameter from test_quick_select
7843
    sel_tree Range tree generated by get_mm_tree
7844
7845
  DESCRIPTION
7846
    Test whether a query can be computed via a QUICK_GROUP_MIN_MAX_SELECT.
7847
    Queries computable via a QUICK_GROUP_MIN_MAX_SELECT must satisfy the
7848
    following conditions:
7849
    A) Table T has at least one compound index I of the form:
7850
       I = <A_1, ...,A_k, [B_1,..., B_m], C, [D_1,...,D_n]>
7851
    B) Query conditions:
7852
    B0. Q is over a single table T.
7853
    B1. The attributes referenced by Q are a subset of the attributes of I.
7854
    B2. All attributes QA in Q can be divided into 3 overlapping groups:
7855
        - SA = {S_1, ..., S_l, [C]} - from the SELECT clause, where C is
7856
          referenced by any number of MIN and/or MAX functions if present.
7857
        - WA = {W_1, ..., W_p} - from the WHERE clause
7858
        - GA = <G_1, ..., G_k> - from the GROUP BY clause (if any)
7859
             = SA              - if Q is a DISTINCT query (based on the
7860
                                 equivalence of DISTINCT and GROUP queries.
7861
        - NGA = QA - (GA union C) = {NG_1, ..., NG_m} - the ones not in
7862
          GROUP BY and not referenced by MIN/MAX functions.
7863
        with the following properties specified below.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
7864
    B3. If Q has a GROUP BY WITH ROLLUP clause the access method is not
1 by brian
clean slate
7865
        applicable.
7866
7867
    SA1. There is at most one attribute in SA referenced by any number of
7868
         MIN and/or MAX functions which, which if present, is denoted as C.
7869
    SA2. The position of the C attribute in the index is after the last A_k.
7870
    SA3. The attribute C can be referenced in the WHERE clause only in
7871
         predicates of the forms:
7872
         - (C {< | <= | > | >= | =} const)
7873
         - (const {< | <= | > | >= | =} C)
7874
         - (C between const_i and const_j)
7875
         - C IS NULL
7876
         - C IS NOT NULL
7877
         - C != const
7878
    SA4. If Q has a GROUP BY clause, there are no other aggregate functions
7879
         except MIN and MAX. For queries with DISTINCT, aggregate functions
7880
         are allowed.
7881
    SA5. The select list in DISTINCT queries should not contain expressions.
7882
    GA1. If Q has a GROUP BY clause, then GA is a prefix of I. That is, if
7883
         G_i = A_j => i = j.
7884
    GA2. If Q has a DISTINCT clause, then there is a permutation of SA that
7885
         forms a prefix of I. This permutation is used as the GROUP clause
7886
         when the DISTINCT query is converted to a GROUP query.
7887
    GA3. The attributes in GA may participate in arbitrary predicates, divided
7888
         into two groups:
7889
         - RNG(G_1,...,G_q ; where q <= k) is a range condition over the
7890
           attributes of a prefix of GA
7891
         - PA(G_i1,...G_iq) is an arbitrary predicate over an arbitrary subset
7892
           of GA. Since P is applied to only GROUP attributes it filters some
7893
           groups, and thus can be applied after the grouping.
7894
    GA4. There are no expressions among G_i, just direct column references.
7895
    NGA1.If in the index I there is a gap between the last GROUP attribute G_k,
7896
         and the MIN/MAX attribute C, then NGA must consist of exactly the
7897
         index attributes that constitute the gap. As a result there is a
7898
         permutation of NGA that coincides with the gap in the index
7899
         <B_1, ..., B_m>.
7900
    NGA2.If BA <> {}, then the WHERE clause must contain a conjunction EQ of
7901
         equality conditions for all NG_i of the form (NG_i = const) or
7902
         (const = NG_i), such that each NG_i is referenced in exactly one
7903
         conjunct. Informally, the predicates provide constants to fill the
7904
         gap in the index.
7905
    WA1. There are no other attributes in the WHERE clause except the ones
7906
         referenced in predicates RNG, PA, PC, EQ defined above. Therefore
7907
         WA is subset of (GA union NGA union C) for GA,NGA,C that pass the
7908
         above tests. By transitivity then it also follows that each WA_i
7909
         participates in the index I (if this was already tested for GA, NGA
7910
         and C).
7911
7912
    C) Overall query form:
7913
       SELECT EXPR([A_1,...,A_k], [B_1,...,B_m], [MIN(C)], [MAX(C)])
7914
         FROM T
7915
        WHERE [RNG(A_1,...,A_p ; where p <= k)]
7916
         [AND EQ(B_1,...,B_m)]
7917
         [AND PC(C)]
7918
         [AND PA(A_i1,...,A_iq)]
7919
       GROUP BY A_1,...,A_k
7920
       [HAVING PH(A_1, ..., B_1,..., C)]
7921
    where EXPR(...) is an arbitrary expression over some or all SELECT fields,
7922
    or:
7923
       SELECT DISTINCT A_i1,...,A_ik
7924
         FROM T
7925
        WHERE [RNG(A_1,...,A_p ; where p <= k)]
7926
         [AND PA(A_i1,...,A_iq)];
7927
7928
  NOTES
7929
    If the current query satisfies the conditions above, and if
7930
    (mem_root! = NULL), then the function constructs and returns a new TRP
7931
    object, that is later used to construct a new QUICK_GROUP_MIN_MAX_SELECT.
7932
    If (mem_root == NULL), then the function only tests whether the current
7933
    query satisfies the conditions above, and, if so, sets
55 by brian
Update for using real bool types.
7934
    is_applicable = true.
1 by brian
clean slate
7935
7936
    Queries with DISTINCT for which index access can be used are transformed
7937
    into equivalent group-by queries of the form:
7938
7939
    SELECT A_1,...,A_k FROM T
7940
     WHERE [RNG(A_1,...,A_p ; where p <= k)]
7941
      [AND PA(A_i1,...,A_iq)]
7942
    GROUP BY A_1,...,A_k;
7943
7944
    The group-by list is a permutation of the select attributes, according
7945
    to their order in the index.
7946
7947
  TODO
7948
  - What happens if the query groups by the MIN/MAX field, and there is no
7949
    other field as in: "select min(a) from t1 group by a" ?
7950
  - We assume that the general correctness of the GROUP-BY query was checked
7951
    before this point. Is this correct, or do we have to check it completely?
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
7952
  - Lift the limitation in condition (B3), that is, make this access method
1 by brian
clean slate
7953
    applicable to ROLLUP queries.
7954
7955
  RETURN
7956
    If mem_root != NULL
7957
    - valid TRP_GROUP_MIN_MAX object if this QUICK class can be used for
7958
      the query
7959
    -  NULL o/w.
7960
    If mem_root == NULL
7961
    - NULL
7962
*/
7963
7964
static TRP_GROUP_MIN_MAX *
7965
get_best_group_min_max(PARAM *param, SEL_TREE *tree)
7966
{
520.1.22 by Brian Aker
Second pass of thd cleanup
7967
  Session *session= param->session;
7968
  JOIN *join= session->lex->current_select->join;
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
7969
  Table *table= param->table;
55 by brian
Update for using real bool types.
7970
  bool have_min= false;              /* true if there is a MIN function. */
7971
  bool have_max= false;              /* true if there is a MAX function. */
1 by brian
clean slate
7972
  Item_field *min_max_arg_item= NULL; // The argument of all MIN/MAX functions
7973
  KEY_PART_INFO *min_max_arg_part= NULL; /* The corresponding keypart. */
482 by Brian Aker
Remove uint.
7974
  uint32_t group_prefix_len= 0; /* Length (in bytes) of the key prefix. */
1 by brian
clean slate
7975
  KEY *index_info= NULL;    /* The index chosen for data access. */
482 by Brian Aker
Remove uint.
7976
  uint32_t index= 0;            /* The id of the chosen index. */
7977
  uint32_t group_key_parts= 0;  // Number of index key parts in the group prefix.
7978
  uint32_t used_key_parts= 0;   /* Number of index key parts used for access. */
481 by Brian Aker
Remove all of uchar.
7979
  unsigned char key_infix[MAX_KEY_LENGTH]; /* Constants from equality predicates.*/
482 by Brian Aker
Remove uint.
7980
  uint32_t key_infix_len= 0;          /* Length of key_infix. */
1 by brian
clean slate
7981
  TRP_GROUP_MIN_MAX *read_plan= NULL; /* The eventually constructed TRP. */
482 by Brian Aker
Remove uint.
7982
  uint32_t key_part_nr;
327.2.3 by Brian Aker
Refactoring of class Table
7983
  order_st *tmp_group;
1 by brian
clean slate
7984
  Item *item;
7985
  Item_field *item_field;
7986
7987
  /* Perform few 'cheap' tests whether this access method is applicable. */
7988
  if (!join)
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
7989
    return NULL;        /* This is not a select statement. */
1 by brian
clean slate
7990
  if ((join->tables != 1) ||  /* The query must reference one table. */
7991
      ((!join->group_list) && /* Neither GROUP BY nor a DISTINCT query. */
7992
       (!join->select_distinct)) ||
7993
      (join->select_lex->olap == ROLLUP_TYPE)) /* Check (B3) for ROLLUP */
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
7994
    return NULL;
1 by brian
clean slate
7995
  if (table->s->keys == 0)        /* There are no indexes to use. */
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
7996
    return NULL;
1 by brian
clean slate
7997
7998
  /* Analyze the query in more detail. */
7999
  List_iterator<Item> select_items_it(join->fields_list);
8000
8001
  /* Check (SA1,SA4) and store the only MIN/MAX argument - the C attribute.*/
8002
  if (join->make_sum_func_list(join->all_fields, join->fields_list, 1))
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
8003
    return NULL;
1 by brian
clean slate
8004
  if (join->sum_funcs[0])
8005
  {
8006
    Item_sum *min_max_item;
8007
    Item_sum **func_ptr= join->sum_funcs;
8008
    while ((min_max_item= *(func_ptr++)))
8009
    {
8010
      if (min_max_item->sum_func() == Item_sum::MIN_FUNC)
55 by brian
Update for using real bool types.
8011
        have_min= true;
1 by brian
clean slate
8012
      else if (min_max_item->sum_func() == Item_sum::MAX_FUNC)
55 by brian
Update for using real bool types.
8013
        have_max= true;
1 by brian
clean slate
8014
      else
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
8015
        return NULL;
1 by brian
clean slate
8016
8017
      /* The argument of MIN/MAX. */
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
8018
      Item *expr= min_max_item->args[0]->real_item();
1 by brian
clean slate
8019
      if (expr->type() == Item::FIELD_ITEM) /* Is it an attribute? */
8020
      {
8021
        if (! min_max_arg_item)
8022
          min_max_arg_item= (Item_field*) expr;
8023
        else if (! min_max_arg_item->eq(expr, 1))
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
8024
          return NULL;
1 by brian
clean slate
8025
      }
8026
      else
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
8027
        return NULL;
1 by brian
clean slate
8028
    }
8029
  }
8030
8031
  /* Check (SA5). */
8032
  if (join->select_distinct)
8033
  {
8034
    while ((item= select_items_it++))
8035
    {
8036
      if (item->type() != Item::FIELD_ITEM)
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
8037
        return NULL;
1 by brian
clean slate
8038
    }
8039
  }
8040
8041
  /* Check (GA4) - that there are no expressions among the group attributes. */
8042
  for (tmp_group= join->group_list; tmp_group; tmp_group= tmp_group->next)
8043
  {
8044
    if ((*tmp_group->item)->type() != Item::FIELD_ITEM)
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
8045
      return NULL;
1 by brian
clean slate
8046
  }
8047
8048
  /*
8049
    Check that table has at least one compound index such that the conditions
55 by brian
Update for using real bool types.
8050
    (GA1,GA2) are all true. If there is more than one such index, select the
1 by brian
clean slate
8051
    first one. Here we set the variables: group_prefix_len and index_info.
8052
  */
8053
  KEY *cur_index_info= table->key_info;
8054
  KEY *cur_index_info_end= cur_index_info + table->s->keys;
8055
  KEY_PART_INFO *cur_part= NULL;
8056
  KEY_PART_INFO *end_part; /* Last part for loops. */
8057
  /* Last index part. */
8058
  KEY_PART_INFO *last_part= NULL;
8059
  KEY_PART_INFO *first_non_group_part= NULL;
8060
  KEY_PART_INFO *first_non_infix_part= NULL;
482 by Brian Aker
Remove uint.
8061
  uint32_t key_infix_parts= 0;
8062
  uint32_t cur_group_key_parts= 0;
8063
  uint32_t cur_group_prefix_len= 0;
1 by brian
clean slate
8064
  /* Cost-related variables for the best index so far. */
8065
  double best_read_cost= DBL_MAX;
8066
  ha_rows best_records= 0;
8067
  SEL_ARG *best_index_tree= NULL;
8068
  ha_rows best_quick_prefix_records= 0;
482 by Brian Aker
Remove uint.
8069
  uint32_t best_param_idx= 0;
1 by brian
clean slate
8070
  double cur_read_cost= DBL_MAX;
8071
  ha_rows cur_records;
8072
  SEL_ARG *cur_index_tree= NULL;
8073
  ha_rows cur_quick_prefix_records= 0;
482 by Brian Aker
Remove uint.
8074
  uint32_t cur_param_idx=MAX_KEY;
1 by brian
clean slate
8075
  key_map cur_used_key_parts;
482 by Brian Aker
Remove uint.
8076
  uint32_t pk= param->table->s->primary_key;
1 by brian
clean slate
8077
482 by Brian Aker
Remove uint.
8078
  for (uint32_t cur_index= 0 ; cur_index_info != cur_index_info_end ;
1 by brian
clean slate
8079
       cur_index_info++, cur_index++)
8080
  {
8081
    /* Check (B1) - if current index is covering. */
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
8082
    if (!table->covering_keys.test(cur_index))
1 by brian
clean slate
8083
      goto next_index;
8084
8085
    /*
8086
      If the current storage manager is such that it appends the primary key to
8087
      each index, then the above condition is insufficient to check if the
8088
      index is covering. In such cases it may happen that some fields are
8089
      covered by the PK index, but not by the current index. Since we can't
8090
      use the concatenation of both indexes for index lookup, such an index
8091
      does not qualify as covering in our case. If this is the case, below
8092
      we check that all query fields are indeed covered by 'cur_index'.
8093
    */
8094
    if (pk < MAX_KEY && cur_index != pk &&
8095
        (table->file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX))
8096
    {
8097
      /* For each table field */
482 by Brian Aker
Remove uint.
8098
      for (uint32_t i= 0; i < table->s->fields; i++)
1 by brian
clean slate
8099
      {
8100
        Field *cur_field= table->field[i];
8101
        /*
8102
          If the field is used in the current query ensure that it's
8103
          part of 'cur_index'
8104
        */
1003.1.12 by Brian Aker
Begin of abstract out the bitmap from direct reference.
8105
        if ((cur_field->isReadSet()) &&
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
8106
            !cur_field->part_of_key_not_clustered.test(cur_index))
1 by brian
clean slate
8107
          goto next_index;                  // Field was not part of key
8108
      }
8109
    }
8110
8111
    /*
8112
      Check (GA1) for GROUP BY queries.
8113
    */
8114
    if (join->group_list)
8115
    {
8116
      cur_part= cur_index_info->key_part;
8117
      end_part= cur_part + cur_index_info->key_parts;
8118
      /* Iterate in parallel over the GROUP list and the index parts. */
8119
      for (tmp_group= join->group_list; tmp_group && (cur_part != end_part);
8120
           tmp_group= tmp_group->next, cur_part++)
8121
      {
8122
        /*
8123
          TODO:
8124
          tmp_group::item is an array of Item, is it OK to consider only the
8125
          first Item? If so, then why? What is the array for?
8126
        */
8127
        /* Above we already checked that all group items are fields. */
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
8128
        assert((*tmp_group->item)->type() == Item::FIELD_ITEM);
1 by brian
clean slate
8129
        Item_field *group_field= (Item_field *) (*tmp_group->item);
8130
        if (group_field->field->eq(cur_part->field))
8131
        {
8132
          cur_group_prefix_len+= cur_part->store_length;
8133
          ++cur_group_key_parts;
8134
        }
8135
        else
8136
          goto next_index;
8137
      }
8138
    }
8139
    /*
8140
      Check (GA2) if this is a DISTINCT query.
327.2.3 by Brian Aker
Refactoring of class Table
8141
      If GA2, then Store a new order_st object in group_fields_array at the
8142
      position of the key part of item_field->field. Thus we get the order_st
1 by brian
clean slate
8143
      objects for each field ordered as the corresponding key parts.
327.2.3 by Brian Aker
Refactoring of class Table
8144
      Later group_fields_array of order_st objects is used to convert the query
1 by brian
clean slate
8145
      to a GROUP query.
8146
    */
8147
    else if (join->select_distinct)
8148
    {
8149
      select_items_it.rewind();
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
8150
      cur_used_key_parts.reset();
482 by Brian Aker
Remove uint.
8151
      uint32_t max_key_part= 0;
1 by brian
clean slate
8152
      while ((item= select_items_it++))
8153
      {
8154
        item_field= (Item_field*) item; /* (SA5) already checked above. */
8155
        /* Find the order of the key part in the index. */
8156
        key_part_nr= get_field_keypart(cur_index_info, item_field->field);
8157
        /*
8158
          Check if this attribute was already present in the select list.
8159
          If it was present, then its corresponding key part was alredy used.
8160
        */
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
8161
        if (cur_used_key_parts.test(key_part_nr))
1 by brian
clean slate
8162
          continue;
8163
        if (key_part_nr < 1 || key_part_nr > join->fields_list.elements)
8164
          goto next_index;
8165
        cur_part= cur_index_info->key_part + key_part_nr - 1;
8166
        cur_group_prefix_len+= cur_part->store_length;
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
8167
        cur_used_key_parts.set(key_part_nr);
1 by brian
clean slate
8168
        ++cur_group_key_parts;
398.1.4 by Monty Taylor
Renamed max/min.
8169
        max_key_part= cmax(max_key_part,key_part_nr);
1 by brian
clean slate
8170
      }
8171
      /*
8172
        Check that used key parts forms a prefix of the index.
8173
        To check this we compare bits in all_parts and cur_parts.
8174
        all_parts have all bits set from 0 to (max_key_part-1).
8175
        cur_parts have bits set for only used keyparts.
8176
      */
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
8177
      key_map all_parts, cur_parts;
8178
      for (uint32_t pos= 0; pos < max_key_part; pos++)
8179
        all_parts.set(pos);
8180
      cur_parts= cur_used_key_parts >> 1;
1 by brian
clean slate
8181
      if (all_parts != cur_parts)
8182
        goto next_index;
8183
    }
8184
    else
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
8185
      assert(false);
1 by brian
clean slate
8186
8187
    /* Check (SA2). */
8188
    if (min_max_arg_item)
8189
    {
8190
      key_part_nr= get_field_keypart(cur_index_info, min_max_arg_item->field);
8191
      if (key_part_nr <= cur_group_key_parts)
8192
        goto next_index;
8193
      min_max_arg_part= cur_index_info->key_part + key_part_nr - 1;
8194
    }
8195
8196
    /*
8197
      Check (NGA1, NGA2) and extract a sequence of constants to be used as part
8198
      of all search keys.
8199
    */
8200
8201
    /*
8202
      If there is MIN/MAX, each keypart between the last group part and the
8203
      MIN/MAX part must participate in one equality with constants, and all
8204
      keyparts after the MIN/MAX part must not be referenced in the query.
8205
8206
      If there is no MIN/MAX, the keyparts after the last group part can be
8207
      referenced only in equalities with constants, and the referenced keyparts
8208
      must form a sequence without any gaps that starts immediately after the
8209
      last group keypart.
8210
    */
8211
    last_part= cur_index_info->key_part + cur_index_info->key_parts;
8212
    first_non_group_part= (cur_group_key_parts < cur_index_info->key_parts) ?
8213
                          cur_index_info->key_part + cur_group_key_parts :
8214
                          NULL;
8215
    first_non_infix_part= min_max_arg_part ?
8216
                          (min_max_arg_part < last_part) ?
8217
                             min_max_arg_part :
8218
                             NULL :
8219
                           NULL;
8220
    if (first_non_group_part &&
8221
        (!min_max_arg_part || (min_max_arg_part - first_non_group_part > 0)))
8222
    {
8223
      if (tree)
8224
      {
482 by Brian Aker
Remove uint.
8225
        uint32_t dummy;
1 by brian
clean slate
8226
        SEL_ARG *index_range_tree= get_index_range_tree(cur_index, tree, param,
8227
                                                        &dummy);
8228
        if (!get_constant_key_infix(cur_index_info, index_range_tree,
8229
                                    first_non_group_part, min_max_arg_part,
520.1.22 by Brian Aker
Second pass of thd cleanup
8230
                                    last_part, session, key_infix, &key_infix_len,
1 by brian
clean slate
8231
                                    &first_non_infix_part))
8232
          goto next_index;
8233
      }
8234
      else if (min_max_arg_part &&
8235
               (min_max_arg_part - first_non_group_part > 0))
8236
      {
8237
        /*
8238
          There is a gap but no range tree, thus no predicates at all for the
8239
          non-group keyparts.
8240
        */
8241
        goto next_index;
8242
      }
8243
      else if (first_non_group_part && join->conds)
8244
      {
8245
        /*
8246
          If there is no MIN/MAX function in the query, but some index
8247
          key part is referenced in the WHERE clause, then this index
8248
          cannot be used because the WHERE condition over the keypart's
8249
          field cannot be 'pushed' to the index (because there is no
8250
          range 'tree'), and the WHERE clause must be evaluated before
8251
          GROUP BY/DISTINCT.
8252
        */
8253
        /*
8254
          Store the first and last keyparts that need to be analyzed
8255
          into one array that can be passed as parameter.
8256
        */
8257
        KEY_PART_INFO *key_part_range[2];
8258
        key_part_range[0]= first_non_group_part;
8259
        key_part_range[1]= last_part;
8260
8261
        /* Check if cur_part is referenced in the WHERE clause. */
8262
        if (join->conds->walk(&Item::find_item_in_field_list_processor, 0,
481 by Brian Aker
Remove all of uchar.
8263
                              (unsigned char*) key_part_range))
1 by brian
clean slate
8264
          goto next_index;
8265
      }
8266
    }
8267
8268
    /*
8269
      Test (WA1) partially - that no other keypart after the last infix part is
8270
      referenced in the query.
8271
    */
8272
    if (first_non_infix_part)
8273
    {
8274
      cur_part= first_non_infix_part +
8275
                (min_max_arg_part && (min_max_arg_part < last_part));
8276
      for (; cur_part != last_part; cur_part++)
8277
      {
1003.1.12 by Brian Aker
Begin of abstract out the bitmap from direct reference.
8278
        if (cur_part->field->isReadSet())
1 by brian
clean slate
8279
          goto next_index;
8280
      }
8281
    }
8282
8283
    /* If we got to this point, cur_index_info passes the test. */
8284
    key_infix_parts= key_infix_len ?
8285
                     (first_non_infix_part - first_non_group_part) : 0;
8286
    used_key_parts= cur_group_key_parts + key_infix_parts;
8287
8288
    /* Compute the cost of using this index. */
8289
    if (tree)
8290
    {
8291
      /* Find the SEL_ARG sub-tree that corresponds to the chosen index. */
8292
      cur_index_tree= get_index_range_tree(cur_index, tree, param,
8293
                                           &cur_param_idx);
8294
      /* Check if this range tree can be used for prefix retrieval. */
8295
      COST_VECT dummy_cost;
482 by Brian Aker
Remove uint.
8296
      uint32_t mrr_flags= HA_MRR_USE_DEFAULT_IMPL;
8297
      uint32_t mrr_bufsize=0;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
8298
      cur_quick_prefix_records= check_quick_select(param, cur_param_idx,
8299
                                                   false /*don't care*/,
55 by brian
Update for using real bool types.
8300
                                                   cur_index_tree, true,
1 by brian
clean slate
8301
                                                   &mrr_flags, &mrr_bufsize,
8302
                                                   &dummy_cost);
8303
    }
8304
    cost_group_min_max(table, cur_index_info, used_key_parts,
8305
                       cur_group_key_parts, tree, cur_index_tree,
8306
                       cur_quick_prefix_records, have_min, have_max,
8307
                       &cur_read_cost, &cur_records);
8308
    /*
8309
      If cur_read_cost is lower than best_read_cost use cur_index.
8310
      Do not compare doubles directly because they may have different
8311
      representations (64 vs. 80 bits).
8312
    */
8313
    if (cur_read_cost < best_read_cost - (DBL_EPSILON * cur_read_cost))
8314
    {
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
8315
      assert(tree != 0 || cur_param_idx == MAX_KEY);
1 by brian
clean slate
8316
      index_info= cur_index_info;
8317
      index= cur_index;
8318
      best_read_cost= cur_read_cost;
8319
      best_records= cur_records;
8320
      best_index_tree= cur_index_tree;
8321
      best_quick_prefix_records= cur_quick_prefix_records;
8322
      best_param_idx= cur_param_idx;
8323
      group_key_parts= cur_group_key_parts;
8324
      group_prefix_len= cur_group_prefix_len;
8325
    }
8326
8327
  next_index:
8328
    cur_group_key_parts= 0;
8329
    cur_group_prefix_len= 0;
8330
  }
8331
  if (!index_info) /* No usable index found. */
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
8332
    return NULL;
1 by brian
clean slate
8333
8334
  /* Check (SA3) for the where clause. */
8335
  if (join->conds && min_max_arg_item &&
248 by Brian Aker
Random cleanup in base.h
8336
      !check_group_min_max_predicates(join->conds, min_max_arg_item, Field::itRAW))
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
8337
    return NULL;
1 by brian
clean slate
8338
8339
  /* The query passes all tests, so construct a new TRP object. */
8340
  read_plan= new (param->mem_root)
8341
                 TRP_GROUP_MIN_MAX(have_min, have_max, min_max_arg_part,
8342
                                   group_prefix_len, used_key_parts,
8343
                                   group_key_parts, index_info, index,
8344
                                   key_infix_len,
8345
                                   (key_infix_len > 0) ? key_infix : NULL,
8346
                                   tree, best_index_tree, best_param_idx,
8347
                                   best_quick_prefix_records);
8348
  if (read_plan)
8349
  {
8350
    if (tree && read_plan->quick_prefix_records == 0)
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
8351
      return NULL;
1 by brian
clean slate
8352
8353
    read_plan->read_cost= best_read_cost;
8354
    read_plan->records=   best_records;
8355
  }
8356
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
8357
  return read_plan;
1 by brian
clean slate
8358
}
8359
8360
8361
/*
8362
  Check that the MIN/MAX attribute participates only in range predicates
8363
  with constants.
8364
8365
  SYNOPSIS
8366
    check_group_min_max_predicates()
8367
    cond              tree (or subtree) describing all or part of the WHERE
8368
                      clause being analyzed
8369
    min_max_arg_item  the field referenced by the MIN/MAX function(s)
8370
    min_max_arg_part  the keypart of the MIN/MAX argument if any
8371
8372
  DESCRIPTION
8373
    The function walks recursively over the cond tree representing a WHERE
8374
    clause, and checks condition (SA3) - if a field is referenced by a MIN/MAX
8375
    aggregate function, it is referenced only by one of the following
8376
    predicates: {=, !=, <, <=, >, >=, between, is null, is not null}.
8377
8378
  RETURN
55 by brian
Update for using real bool types.
8379
    true  if cond passes the test
8380
    false o/w
1 by brian
clean slate
8381
*/
8382
8383
static bool
8384
check_group_min_max_predicates(COND *cond, Item_field *min_max_arg_item,
8385
                               Field::imagetype image_type)
8386
{
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
8387
  assert(cond && min_max_arg_item);
1 by brian
clean slate
8388
8389
  cond= cond->real_item();
8390
  Item::Type cond_type= cond->type();
8391
  if (cond_type == Item::COND_ITEM) /* 'AND' or 'OR' */
8392
  {
8393
    List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
8394
    Item *and_or_arg;
8395
    while ((and_or_arg= li++))
8396
    {
8397
      if (!check_group_min_max_predicates(and_or_arg, min_max_arg_item,
8398
                                         image_type))
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
8399
        return false;
1 by brian
clean slate
8400
    }
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
8401
    return true;
1 by brian
clean slate
8402
  }
8403
8404
  /*
8405
    TODO:
8406
    This is a very crude fix to handle sub-selects in the WHERE clause
8407
    (Item_subselect objects). With the test below we rule out from the
8408
    optimization all queries with subselects in the WHERE clause. What has to
8409
    be done, is that here we should analyze whether the subselect references
8410
    the MIN/MAX argument field, and disallow the optimization only if this is
8411
    so.
8412
  */
8413
  if (cond_type == Item::SUBSELECT_ITEM)
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
8414
    return false;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
8415
1 by brian
clean slate
8416
  /* We presume that at this point there are no other Items than functions. */
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
8417
  assert(cond_type == Item::FUNC_ITEM);
1 by brian
clean slate
8418
8419
  /* Test if cond references only group-by or non-group fields. */
8420
  Item_func *pred= (Item_func*) cond;
8421
  Item **arguments= pred->arguments();
8422
  Item *cur_arg;
482 by Brian Aker
Remove uint.
8423
  for (uint32_t arg_idx= 0; arg_idx < pred->argument_count (); arg_idx++)
1 by brian
clean slate
8424
  {
8425
    cur_arg= arguments[arg_idx]->real_item();
8426
    if (cur_arg->type() == Item::FIELD_ITEM)
8427
    {
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
8428
      if (min_max_arg_item->eq(cur_arg, 1))
1 by brian
clean slate
8429
      {
8430
       /*
8431
         If pred references the MIN/MAX argument, check whether pred is a range
8432
         condition that compares the MIN/MAX argument with a constant.
8433
       */
8434
        Item_func::Functype pred_type= pred->functype();
8435
        if (pred_type != Item_func::EQUAL_FUNC     &&
8436
            pred_type != Item_func::LT_FUNC        &&
8437
            pred_type != Item_func::LE_FUNC        &&
8438
            pred_type != Item_func::GT_FUNC        &&
8439
            pred_type != Item_func::GE_FUNC        &&
8440
            pred_type != Item_func::BETWEEN        &&
8441
            pred_type != Item_func::ISNULL_FUNC    &&
8442
            pred_type != Item_func::ISNOTNULL_FUNC &&
8443
            pred_type != Item_func::EQ_FUNC        &&
8444
            pred_type != Item_func::NE_FUNC)
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
8445
          return false;
1 by brian
clean slate
8446
8447
        /* Check that pred compares min_max_arg_item with a constant. */
8448
        Item *args[3];
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
8449
        memset(args, 0, 3 * sizeof(Item*));
1 by brian
clean slate
8450
        bool inv;
8451
        /* Test if this is a comparison of a field and a constant. */
8452
        if (!simple_pred(pred, args, &inv))
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
8453
          return false;
1 by brian
clean slate
8454
8455
        /* Check for compatible string comparisons - similar to get_mm_leaf. */
8456
        if (args[0] && args[1] && !args[2] && // this is a binary function
8457
            min_max_arg_item->result_type() == STRING_RESULT &&
8458
            /*
8459
              Don't use an index when comparing strings of different collations.
8460
            */
8461
            ((args[1]->result_type() == STRING_RESULT &&
8462
              image_type == Field::itRAW &&
8463
              ((Field_str*) min_max_arg_item->field)->charset() !=
8464
              pred->compare_collation())
8465
             ||
8466
             /*
8467
               We can't always use indexes when comparing a string index to a
8468
               number.
8469
             */
8470
             (args[1]->result_type() != STRING_RESULT &&
8471
              min_max_arg_item->field->cmp_type() != args[1]->result_type())))
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
8472
          return false;
1 by brian
clean slate
8473
      }
8474
    }
8475
    else if (cur_arg->type() == Item::FUNC_ITEM)
8476
    {
8477
      if (!check_group_min_max_predicates(cur_arg, min_max_arg_item,
8478
                                         image_type))
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
8479
        return false;
1 by brian
clean slate
8480
    }
8481
    else if (cur_arg->const_item())
8482
    {
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
8483
      return true;
1 by brian
clean slate
8484
    }
8485
    else
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
8486
      return false;
1 by brian
clean slate
8487
  }
8488
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
8489
  return true;
1 by brian
clean slate
8490
}
8491
8492
8493
/*
8494
  Extract a sequence of constants from a conjunction of equality predicates.
8495
8496
  SYNOPSIS
8497
    get_constant_key_infix()
8498
    index_info             [in]  Descriptor of the chosen index.
8499
    index_range_tree       [in]  Range tree for the chosen index
8500
    first_non_group_part   [in]  First index part after group attribute parts
8501
    min_max_arg_part       [in]  The keypart of the MIN/MAX argument if any
8502
    last_part              [in]  Last keypart of the index
520.1.22 by Brian Aker
Second pass of thd cleanup
8503
    session                    [in]  Current thread
1 by brian
clean slate
8504
    key_infix              [out] Infix of constants to be used for index lookup
8505
    key_infix_len          [out] Lenghth of the infix
8506
    first_non_infix_part   [out] The first keypart after the infix (if any)
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
8507
1 by brian
clean slate
8508
  DESCRIPTION
8509
    Test conditions (NGA1, NGA2) from get_best_group_min_max(). Namely,
8510
    for each keypart field NGF_i not in GROUP-BY, check that there is a
8511
    constant equality predicate among conds with the form (NGF_i = const_ci) or
8512
    (const_ci = NGF_i).
8513
    Thus all the NGF_i attributes must fill the 'gap' between the last group-by
8514
    attribute and the MIN/MAX attribute in the index (if present). If these
8515
    conditions hold, copy each constant from its corresponding predicate into
8516
    key_infix, in the order its NG_i attribute appears in the index, and update
8517
    key_infix_len with the total length of the key parts in key_infix.
8518
8519
  RETURN
55 by brian
Update for using real bool types.
8520
    true  if the index passes the test
8521
    false o/w
1 by brian
clean slate
8522
*/
8523
8524
static bool
655 by Brian Aker
Yet more unused.... damn annoying... (also tossed some prototypes that were
8525
get_constant_key_infix(KEY *, SEL_ARG *index_range_tree,
1 by brian
clean slate
8526
                       KEY_PART_INFO *first_non_group_part,
8527
                       KEY_PART_INFO *min_max_arg_part,
77.1.46 by Monty Taylor
Finished the warnings work!
8528
                       KEY_PART_INFO *last_part,
655 by Brian Aker
Yet more unused.... damn annoying... (also tossed some prototypes that were
8529
                       Session *, unsigned char *key_infix, uint32_t *key_infix_len,
1 by brian
clean slate
8530
                       KEY_PART_INFO **first_non_infix_part)
8531
{
8532
  SEL_ARG       *cur_range;
8533
  KEY_PART_INFO *cur_part;
8534
  /* End part for the first loop below. */
8535
  KEY_PART_INFO *end_part= min_max_arg_part ? min_max_arg_part : last_part;
8536
8537
  *key_infix_len= 0;
481 by Brian Aker
Remove all of uchar.
8538
  unsigned char *key_ptr= key_infix;
1 by brian
clean slate
8539
  for (cur_part= first_non_group_part; cur_part != end_part; cur_part++)
8540
  {
8541
    /*
8542
      Find the range tree for the current keypart. We assume that
8543
      index_range_tree points to the leftmost keypart in the index.
8544
    */
8545
    for (cur_range= index_range_tree; cur_range;
8546
         cur_range= cur_range->next_key_part)
8547
    {
8548
      if (cur_range->field->eq(cur_part->field))
8549
        break;
8550
    }
8551
    if (!cur_range)
8552
    {
8553
      if (min_max_arg_part)
55 by brian
Update for using real bool types.
8554
        return false; /* The current keypart has no range predicates at all. */
1 by brian
clean slate
8555
      else
8556
      {
8557
        *first_non_infix_part= cur_part;
55 by brian
Update for using real bool types.
8558
        return true;
1 by brian
clean slate
8559
      }
8560
    }
8561
8562
    /* Check that the current range tree is a single point interval. */
8563
    if (cur_range->prev || cur_range->next)
55 by brian
Update for using real bool types.
8564
      return false; /* This is not the only range predicate for the field. */
1 by brian
clean slate
8565
    if ((cur_range->min_flag & NO_MIN_RANGE) ||
8566
        (cur_range->max_flag & NO_MAX_RANGE) ||
8567
        (cur_range->min_flag & NEAR_MIN) || (cur_range->max_flag & NEAR_MAX))
55 by brian
Update for using real bool types.
8568
      return false;
1 by brian
clean slate
8569
482 by Brian Aker
Remove uint.
8570
    uint32_t field_length= cur_part->store_length;
1 by brian
clean slate
8571
    if ((cur_range->maybe_null &&
8572
         cur_range->min_value[0] && cur_range->max_value[0]) ||
8573
        !memcmp(cur_range->min_value, cur_range->max_value, field_length))
8574
    {
8575
      /* cur_range specifies 'IS NULL' or an equality condition. */
8576
      memcpy(key_ptr, cur_range->min_value, field_length);
8577
      key_ptr+= field_length;
8578
      *key_infix_len+= field_length;
8579
    }
8580
    else
55 by brian
Update for using real bool types.
8581
      return false;
1 by brian
clean slate
8582
  }
8583
8584
  if (!min_max_arg_part && (cur_part == last_part))
8585
    *first_non_infix_part= last_part;
8586
55 by brian
Update for using real bool types.
8587
  return true;
1 by brian
clean slate
8588
}
8589
8590
8591
/*
8592
  Find the key part referenced by a field.
8593
8594
  SYNOPSIS
8595
    get_field_keypart()
8596
    index  descriptor of an index
8597
    field  field that possibly references some key part in index
8598
8599
  NOTES
8600
    The return value can be used to get a KEY_PART_INFO pointer by
8601
    part= index->key_part + get_field_keypart(...) - 1;
8602
8603
  RETURN
8604
    Positive number which is the consecutive number of the key part, or
8605
    0 if field does not reference any index field.
8606
*/
8607
8608
static inline uint
8609
get_field_keypart(KEY *index, Field *field)
8610
{
8611
  KEY_PART_INFO *part, *end;
8612
8613
  for (part= index->key_part, end= part + index->key_parts; part < end; part++)
8614
  {
8615
    if (field->eq(part->field))
8616
      return part - index->key_part + 1;
8617
  }
8618
  return 0;
8619
}
8620
8621
8622
/*
8623
  Find the SEL_ARG sub-tree that corresponds to the chosen index.
8624
8625
  SYNOPSIS
8626
    get_index_range_tree()
8627
    index     [in]  The ID of the index being looked for
8628
    range_tree[in]  Tree of ranges being searched
8629
    param     [in]  PARAM from SQL_SELECT::test_quick_select
8630
    param_idx [out] Index in the array PARAM::key that corresponds to 'index'
8631
8632
  DESCRIPTION
8633
8634
    A SEL_TREE contains range trees for all usable indexes. This procedure
8635
    finds the SEL_ARG sub-tree for 'index'. The members of a SEL_TREE are
8636
    ordered in the same way as the members of PARAM::key, thus we first find
8637
    the corresponding index in the array PARAM::key. This index is returned
8638
    through the variable param_idx, to be used later as argument of
8639
    check_quick_select().
8640
8641
  RETURN
8642
    Pointer to the SEL_ARG subtree that corresponds to index.
8643
*/
8644
482 by Brian Aker
Remove uint.
8645
SEL_ARG * get_index_range_tree(uint32_t index, SEL_TREE* range_tree, PARAM *param,
8646
                               uint32_t *param_idx)
1 by brian
clean slate
8647
{
482 by Brian Aker
Remove uint.
8648
  uint32_t idx= 0; /* Index nr in param->key_parts */
1 by brian
clean slate
8649
  while (idx < param->keys)
8650
  {
8651
    if (index == param->real_keynr[idx])
8652
      break;
8653
    idx++;
8654
  }
8655
  *param_idx= idx;
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
8656
  return range_tree->keys[idx];
1 by brian
clean slate
8657
}
8658
8659
8660
/*
8661
  Compute the cost of a quick_group_min_max_select for a particular index.
8662
8663
  SYNOPSIS
8664
    cost_group_min_max()
8665
    table                [in] The table being accessed
8666
    index_info           [in] The index used to access the table
8667
    used_key_parts       [in] Number of key parts used to access the index
8668
    group_key_parts      [in] Number of index key parts in the group prefix
8669
    range_tree           [in] Tree of ranges for all indexes
8670
    index_tree           [in] The range tree for the current index
8671
    quick_prefix_records [in] Number of records retrieved by the internally
8672
			      used quick range select if any
8673
    have_min             [in] True if there is a MIN function
8674
    have_max             [in] True if there is a MAX function
8675
    read_cost           [out] The cost to retrieve rows via this quick select
8676
    records             [out] The number of rows retrieved
8677
8678
  DESCRIPTION
8679
    This method computes the access cost of a TRP_GROUP_MIN_MAX instance and
8680
    the number of rows returned. It updates this->read_cost and this->records.
8681
8682
  NOTES
8683
    The cost computation distinguishes several cases:
8684
    1) No equality predicates over non-group attributes (thus no key_infix).
8685
       If groups are bigger than blocks on the average, then we assume that it
8686
       is very unlikely that block ends are aligned with group ends, thus even
8687
       if we look for both MIN and MAX keys, all pairs of neighbor MIN/MAX
8688
       keys, except for the first MIN and the last MAX keys, will be in the
8689
       same block.  If groups are smaller than blocks, then we are going to
8690
       read all blocks.
8691
    2) There are equality predicates over non-group attributes.
8692
       In this case the group prefix is extended by additional constants, and
8693
       as a result the min/max values are inside sub-groups of the original
8694
       groups. The number of blocks that will be read depends on whether the
8695
       ends of these sub-groups will be contained in the same or in different
8696
       blocks. We compute the probability for the two ends of a subgroup to be
8697
       in two different blocks as the ratio of:
8698
       - the number of positions of the left-end of a subgroup inside a group,
8699
         such that the right end of the subgroup is past the end of the buffer
8700
         containing the left-end, and
8701
       - the total number of possible positions for the left-end of the
8702
         subgroup, which is the number of keys in the containing group.
8703
       We assume it is very unlikely that two ends of subsequent subgroups are
8704
       in the same block.
8705
    3) The are range predicates over the group attributes.
8706
       Then some groups may be filtered by the range predicates. We use the
8707
       selectivity of the range predicates to decide how many groups will be
8708
       filtered.
8709
8710
  TODO
8711
     - Take into account the optional range predicates over the MIN/MAX
8712
       argument.
8713
     - Check if we have a PK index and we use all cols - then each key is a
8714
       group, and it will be better to use an index scan.
8715
8716
  RETURN
8717
    None
8718
*/
8719
482 by Brian Aker
Remove uint.
8720
void cost_group_min_max(Table* table, KEY *index_info, uint32_t used_key_parts,
8721
                        uint32_t group_key_parts, SEL_TREE *range_tree,
655 by Brian Aker
Yet more unused.... damn annoying... (also tossed some prototypes that were
8722
                        SEL_ARG *, ha_rows quick_prefix_records,
1 by brian
clean slate
8723
                        bool have_min, bool have_max,
8724
                        double *read_cost, ha_rows *records)
8725
{
8726
  ha_rows table_records;
482 by Brian Aker
Remove uint.
8727
  uint32_t num_groups;
8728
  uint32_t num_blocks;
8729
  uint32_t keys_per_block;
8730
  uint32_t keys_per_group;
8731
  uint32_t keys_per_subgroup; /* Average number of keys in sub-groups */
1 by brian
clean slate
8732
                          /* formed by a key infix. */
8733
  double p_overlap; /* Probability that a sub-group overlaps two blocks. */
8734
  double quick_prefix_selectivity;
8735
  double io_cost;
8736
  double cpu_cost= 0; /* TODO: CPU cost of index_read calls? */
8737
8738
  table_records= table->file->stats.records;
8739
  keys_per_block= (table->file->stats.block_size / 2 /
8740
                   (index_info->key_length + table->file->ref_length)
8741
                        + 1);
895 by Brian Aker
Completion (?) of uint conversion.
8742
  num_blocks= (uint32_t)(table_records / keys_per_block) + 1;
1 by brian
clean slate
8743
8744
  /* Compute the number of keys in a group. */
8745
  keys_per_group= index_info->rec_per_key[group_key_parts - 1];
8746
  if (keys_per_group == 0) /* If there is no statistics try to guess */
8747
    /* each group contains 10% of all records */
895 by Brian Aker
Completion (?) of uint conversion.
8748
    keys_per_group= (uint32_t)(table_records / 10) + 1;
8749
  num_groups= (uint32_t)(table_records / keys_per_group) + 1;
1 by brian
clean slate
8750
8751
  /* Apply the selectivity of the quick select for group prefixes. */
8752
  if (range_tree && (quick_prefix_records != HA_POS_ERROR))
8753
  {
8754
    quick_prefix_selectivity= (double) quick_prefix_records /
8755
                              (double) table_records;
895 by Brian Aker
Completion (?) of uint conversion.
8756
    num_groups= (uint32_t) rint(num_groups * quick_prefix_selectivity);
937.2.6 by Stewart Smith
make set_if_bigger typesafe for C and C++. Fix up everywhere.
8757
    set_if_bigger(num_groups, 1U);
1 by brian
clean slate
8758
  }
8759
8760
  if (used_key_parts > group_key_parts)
8761
  { /*
8762
      Compute the probability that two ends of a subgroup are inside
8763
      different blocks.
8764
    */
8765
    keys_per_subgroup= index_info->rec_per_key[used_key_parts - 1];
8766
    if (keys_per_subgroup >= keys_per_block) /* If a subgroup is bigger than */
8767
      p_overlap= 1.0;       /* a block, it will overlap at least two blocks. */
8768
    else
8769
    {
8770
      double blocks_per_group= (double) num_blocks / (double) num_groups;
8771
      p_overlap= (blocks_per_group * (keys_per_subgroup - 1)) / keys_per_group;
398.1.4 by Monty Taylor
Renamed max/min.
8772
      p_overlap= cmin(p_overlap, 1.0);
1 by brian
clean slate
8773
    }
398.1.4 by Monty Taylor
Renamed max/min.
8774
    io_cost= (double) cmin(num_groups * (1 + p_overlap), (double)num_blocks);
1 by brian
clean slate
8775
  }
8776
  else
8777
    io_cost= (keys_per_group > keys_per_block) ?
8778
             (have_min && have_max) ? (double) (num_groups + 1) :
8779
                                      (double) num_groups :
8780
             (double) num_blocks;
8781
8782
  /*
8783
    TODO: If there is no WHERE clause and no other expressions, there should be
8784
    no CPU cost. We leave it here to make this cost comparable to that of index
8785
    scan as computed in SQL_SELECT::test_quick_select().
8786
  */
8787
  cpu_cost= (double) num_groups / TIME_FOR_COMPARE;
8788
8789
  *read_cost= io_cost + cpu_cost;
8790
  *records= num_groups;
8791
}
8792
8793
8794
/*
8795
  Construct a new quick select object for queries with group by with min/max.
8796
8797
  SYNOPSIS
8798
    TRP_GROUP_MIN_MAX::make_quick()
8799
    param              Parameter from test_quick_select
8800
    retrieve_full_rows ignored
8801
    parent_alloc       Memory pool to use, if any.
8802
8803
  NOTES
8804
    Make_quick ignores the retrieve_full_rows parameter because
8805
    QUICK_GROUP_MIN_MAX_SELECT always performs 'index only' scans.
8806
    The other parameter are ignored as well because all necessary
8807
    data to create the QUICK object is computed at this TRP creation
8808
    time.
8809
8810
  RETURN
8811
    New QUICK_GROUP_MIN_MAX_SELECT object if successfully created,
8812
    NULL otherwise.
8813
*/
8814
8815
QUICK_SELECT_I *
655 by Brian Aker
Yet more unused.... damn annoying... (also tossed some prototypes that were
8816
TRP_GROUP_MIN_MAX::make_quick(PARAM *param, bool, MEM_ROOT *parent_alloc)
1 by brian
clean slate
8817
{
8818
  QUICK_GROUP_MIN_MAX_SELECT *quick;
8819
8820
  quick= new QUICK_GROUP_MIN_MAX_SELECT(param->table,
520.1.22 by Brian Aker
Second pass of thd cleanup
8821
                                        param->session->lex->current_select->join,
1 by brian
clean slate
8822
                                        have_min, have_max, min_max_arg_part,
8823
                                        group_prefix_len, group_key_parts,
8824
                                        used_key_parts, index_info, index,
8825
                                        read_cost, records, key_infix_len,
8826
                                        key_infix, parent_alloc);
8827
  if (!quick)
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
8828
    return NULL;
1 by brian
clean slate
8829
8830
  if (quick->init())
8831
  {
8832
    delete quick;
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
8833
    return NULL;
1 by brian
clean slate
8834
  }
8835
8836
  if (range_tree)
8837
  {
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
8838
    assert(quick_prefix_records > 0);
1 by brian
clean slate
8839
    if (quick_prefix_records == HA_POS_ERROR)
8840
      quick->quick_prefix_select= NULL; /* Can't construct a quick select. */
8841
    else
8842
      /* Make a QUICK_RANGE_SELECT to be used for group prefix retrieval. */
8843
      quick->quick_prefix_select= get_quick_select(param, param_idx,
8844
                                                   index_tree,
8845
                                                   HA_MRR_USE_DEFAULT_IMPL, 0,
8846
                                                   &quick->alloc);
8847
8848
    /*
8849
      Extract the SEL_ARG subtree that contains only ranges for the MIN/MAX
8850
      attribute, and create an array of QUICK_RANGES to be used by the
8851
      new quick select.
8852
    */
8853
    if (min_max_arg_part)
8854
    {
8855
      SEL_ARG *min_max_range= index_tree;
8856
      while (min_max_range) /* Find the tree for the MIN/MAX key part. */
8857
      {
8858
        if (min_max_range->field->eq(min_max_arg_part->field))
8859
          break;
8860
        min_max_range= min_max_range->next_key_part;
8861
      }
8862
      /* Scroll to the leftmost interval for the MIN/MAX argument. */
8863
      while (min_max_range && min_max_range->prev)
8864
        min_max_range= min_max_range->prev;
8865
      /* Create an array of QUICK_RANGEs for the MIN/MAX argument. */
8866
      while (min_max_range)
8867
      {
8868
        if (quick->add_range(min_max_range))
8869
        {
8870
          delete quick;
8871
          quick= NULL;
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
8872
          return NULL;
1 by brian
clean slate
8873
        }
8874
        min_max_range= min_max_range->next;
8875
      }
8876
    }
8877
  }
8878
  else
8879
    quick->quick_prefix_select= NULL;
8880
8881
  quick->update_key_stat();
8882
  quick->adjust_prefix_ranges();
8883
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
8884
  return quick;
1 by brian
clean slate
8885
}
8886
8887
8888
/*
8889
  Construct new quick select for group queries with min/max.
8890
8891
  SYNOPSIS
8892
    QUICK_GROUP_MIN_MAX_SELECT::QUICK_GROUP_MIN_MAX_SELECT()
8893
    table             The table being accessed
8894
    join              Descriptor of the current query
55 by brian
Update for using real bool types.
8895
    have_min          true if the query selects a MIN function
8896
    have_max          true if the query selects a MAX function
1 by brian
clean slate
8897
    min_max_arg_part  The only argument field of all MIN/MAX functions
8898
    group_prefix_len  Length of all key parts in the group prefix
8899
    prefix_key_parts  All key parts in the group prefix
8900
    index_info        The index chosen for data access
8901
    use_index         The id of index_info
8902
    read_cost         Cost of this access method
8903
    records           Number of records returned
8904
    key_infix_len     Length of the key infix appended to the group prefix
8905
    key_infix         Infix of constants from equality predicates
8906
    parent_alloc      Memory pool for this and quick_prefix_select data
8907
8908
  RETURN
8909
    None
8910
*/
8911
8912
QUICK_GROUP_MIN_MAX_SELECT::
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
8913
QUICK_GROUP_MIN_MAX_SELECT(Table *table, JOIN *join_arg, bool have_min_arg,
1 by brian
clean slate
8914
                           bool have_max_arg,
8915
                           KEY_PART_INFO *min_max_arg_part_arg,
482 by Brian Aker
Remove uint.
8916
                           uint32_t group_prefix_len_arg, uint32_t group_key_parts_arg,
8917
                           uint32_t used_key_parts_arg, KEY *index_info_arg,
8918
                           uint32_t use_index, double read_cost_arg,
8919
                           ha_rows records_arg, uint32_t key_infix_len_arg,
481 by Brian Aker
Remove all of uchar.
8920
                           unsigned char *key_infix_arg, MEM_ROOT *parent_alloc)
1 by brian
clean slate
8921
  :join(join_arg), index_info(index_info_arg),
8922
   group_prefix_len(group_prefix_len_arg),
8923
   group_key_parts(group_key_parts_arg), have_min(have_min_arg),
55 by brian
Update for using real bool types.
8924
   have_max(have_max_arg), seen_first_key(false),
1 by brian
clean slate
8925
   min_max_arg_part(min_max_arg_part_arg), key_infix(key_infix_arg),
8926
   key_infix_len(key_infix_len_arg), min_functions_it(NULL),
8927
   max_functions_it(NULL)
8928
{
8929
  head=       table;
8930
  file=       head->file;
8931
  index=      use_index;
8932
  record=     head->record[0];
8933
  tmp_record= head->record[1];
8934
  read_time= read_cost_arg;
8935
  records= records_arg;
8936
  used_key_parts= used_key_parts_arg;
8937
  real_key_parts= used_key_parts_arg;
8938
  real_prefix_len= group_prefix_len + key_infix_len;
8939
  group_prefix= NULL;
8940
  min_max_arg_len= min_max_arg_part ? min_max_arg_part->store_length : 0;
8941
8942
  /*
8943
    We can't have parent_alloc set as the init function can't handle this case
8944
    yet.
8945
  */
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
8946
  assert(!parent_alloc);
1 by brian
clean slate
8947
  if (!parent_alloc)
8948
  {
520.1.22 by Brian Aker
Second pass of thd cleanup
8949
    init_sql_alloc(&alloc, join->session->variables.range_alloc_block_size, 0);
8950
    join->session->mem_root= &alloc;
1 by brian
clean slate
8951
  }
8952
  else
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
8953
    memset(&alloc, 0, sizeof(MEM_ROOT));  // ensure that it's not used
1 by brian
clean slate
8954
}
8955
8956
8957
/*
8958
  Do post-constructor initialization.
8959
8960
  SYNOPSIS
8961
    QUICK_GROUP_MIN_MAX_SELECT::init()
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
8962
1 by brian
clean slate
8963
  DESCRIPTION
8964
    The method performs initialization that cannot be done in the constructor
8965
    such as memory allocations that may fail. It allocates memory for the
8966
    group prefix and inifix buffers, and for the lists of MIN/MAX item to be
8967
    updated during execution.
8968
8969
  RETURN
8970
    0      OK
8971
    other  Error code
8972
*/
8973
8974
int QUICK_GROUP_MIN_MAX_SELECT::init()
8975
{
8976
  if (group_prefix) /* Already initialized. */
8977
    return 0;
8978
481 by Brian Aker
Remove all of uchar.
8979
  if (!(last_prefix= (unsigned char*) alloc_root(&alloc, group_prefix_len)))
1 by brian
clean slate
8980
      return 1;
8981
  /*
8982
    We may use group_prefix to store keys with all select fields, so allocate
8983
    enough space for it.
8984
  */
481 by Brian Aker
Remove all of uchar.
8985
  if (!(group_prefix= (unsigned char*) alloc_root(&alloc,
1 by brian
clean slate
8986
                                         real_prefix_len + min_max_arg_len)))
8987
    return 1;
8988
8989
  if (key_infix_len > 0)
8990
  {
8991
    /*
8992
      The memory location pointed to by key_infix will be deleted soon, so
8993
      allocate a new buffer and copy the key_infix into it.
8994
    */
481 by Brian Aker
Remove all of uchar.
8995
    unsigned char *tmp_key_infix= (unsigned char*) alloc_root(&alloc, key_infix_len);
1 by brian
clean slate
8996
    if (!tmp_key_infix)
8997
      return 1;
8998
    memcpy(tmp_key_infix, this->key_infix, key_infix_len);
8999
    this->key_infix= tmp_key_infix;
9000
  }
9001
9002
  if (min_max_arg_part)
9003
  {
9004
    if (my_init_dynamic_array(&min_max_ranges, sizeof(QUICK_RANGE*), 16, 16))
9005
      return 1;
9006
9007
    if (have_min)
9008
    {
9009
      if (!(min_functions= new List<Item_sum>))
9010
        return 1;
9011
    }
9012
    else
9013
      min_functions= NULL;
9014
    if (have_max)
9015
    {
9016
      if (!(max_functions= new List<Item_sum>))
9017
        return 1;
9018
    }
9019
    else
9020
      max_functions= NULL;
9021
9022
    Item_sum *min_max_item;
9023
    Item_sum **func_ptr= join->sum_funcs;
9024
    while ((min_max_item= *(func_ptr++)))
9025
    {
9026
      if (have_min && (min_max_item->sum_func() == Item_sum::MIN_FUNC))
9027
        min_functions->push_back(min_max_item);
9028
      else if (have_max && (min_max_item->sum_func() == Item_sum::MAX_FUNC))
9029
        max_functions->push_back(min_max_item);
9030
    }
9031
9032
    if (have_min)
9033
    {
9034
      if (!(min_functions_it= new List_iterator<Item_sum>(*min_functions)))
9035
        return 1;
9036
    }
9037
9038
    if (have_max)
9039
    {
9040
      if (!(max_functions_it= new List_iterator<Item_sum>(*max_functions)))
9041
        return 1;
9042
    }
9043
  }
9044
  else
9045
    min_max_ranges.elements= 0;
9046
9047
  return 0;
9048
}
9049
9050
9051
QUICK_GROUP_MIN_MAX_SELECT::~QUICK_GROUP_MIN_MAX_SELECT()
9052
{
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
9053
  if (file->inited != handler::NONE)
1 by brian
clean slate
9054
    file->ha_index_end();
9055
  if (min_max_arg_part)
9056
    delete_dynamic(&min_max_ranges);
9057
  free_root(&alloc,MYF(0));
9058
  delete min_functions_it;
9059
  delete max_functions_it;
9060
  delete quick_prefix_select;
9061
}
9062
9063
9064
/*
9065
  Eventually create and add a new quick range object.
9066
9067
  SYNOPSIS
9068
    QUICK_GROUP_MIN_MAX_SELECT::add_range()
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
9069
    sel_range  Range object from which a
1 by brian
clean slate
9070
9071
  NOTES
9072
    Construct a new QUICK_RANGE object from a SEL_ARG object, and
9073
    add it to the array min_max_ranges. If sel_arg is an infinite
9074
    range, e.g. (x < 5 or x > 4), then skip it and do not construct
9075
    a quick range.
9076
9077
  RETURN
55 by brian
Update for using real bool types.
9078
    false on success
9079
    true  otherwise
1 by brian
clean slate
9080
*/
9081
9082
bool QUICK_GROUP_MIN_MAX_SELECT::add_range(SEL_ARG *sel_range)
9083
{
9084
  QUICK_RANGE *range;
482 by Brian Aker
Remove uint.
9085
  uint32_t range_flag= sel_range->min_flag | sel_range->max_flag;
1 by brian
clean slate
9086
9087
  /* Skip (-inf,+inf) ranges, e.g. (x < 5 or x > 4). */
9088
  if ((range_flag & NO_MIN_RANGE) && (range_flag & NO_MAX_RANGE))
55 by brian
Update for using real bool types.
9089
    return false;
1 by brian
clean slate
9090
9091
  if (!(sel_range->min_flag & NO_MIN_RANGE) &&
9092
      !(sel_range->max_flag & NO_MAX_RANGE))
9093
  {
9094
    if (sel_range->maybe_null &&
9095
        sel_range->min_value[0] && sel_range->max_value[0])
9096
      range_flag|= NULL_RANGE; /* IS NULL condition */
9097
    else if (memcmp(sel_range->min_value, sel_range->max_value,
9098
                    min_max_arg_len) == 0)
9099
      range_flag|= EQ_RANGE;  /* equality condition */
9100
  }
9101
  range= new QUICK_RANGE(sel_range->min_value, min_max_arg_len,
9102
                         make_keypart_map(sel_range->part),
9103
                         sel_range->max_value, min_max_arg_len,
9104
                         make_keypart_map(sel_range->part),
9105
                         range_flag);
9106
  if (!range)
55 by brian
Update for using real bool types.
9107
    return true;
481 by Brian Aker
Remove all of uchar.
9108
  if (insert_dynamic(&min_max_ranges, (unsigned char*)&range))
55 by brian
Update for using real bool types.
9109
    return true;
9110
  return false;
1 by brian
clean slate
9111
}
9112
9113
9114
/*
9115
  Opens the ranges if there are more conditions in quick_prefix_select than
9116
  the ones used for jumping through the prefixes.
9117
9118
  SYNOPSIS
9119
    QUICK_GROUP_MIN_MAX_SELECT::adjust_prefix_ranges()
9120
9121
  NOTES
9122
    quick_prefix_select is made over the conditions on the whole key.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
9123
    It defines a number of ranges of length x.
9124
    However when jumping through the prefixes we use only the the first
1 by brian
clean slate
9125
    few most significant keyparts in the range key. However if there
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
9126
    are more keyparts to follow the ones we are using we must make the
9127
    condition on the key inclusive (because x < "ab" means
1 by brian
clean slate
9128
    x[0] < 'a' OR (x[0] == 'a' AND x[1] < 'b').
9129
    To achive the above we must turn off the NEAR_MIN/NEAR_MAX
9130
*/
9131
void QUICK_GROUP_MIN_MAX_SELECT::adjust_prefix_ranges ()
9132
{
9133
  if (quick_prefix_select &&
9134
      group_prefix_len < quick_prefix_select->max_used_key_length)
9135
  {
9136
    DYNAMIC_ARRAY *arr;
482 by Brian Aker
Remove uint.
9137
    uint32_t inx;
1 by brian
clean slate
9138
9139
    for (inx= 0, arr= &quick_prefix_select->ranges; inx < arr->elements; inx++)
9140
    {
9141
      QUICK_RANGE *range;
9142
481 by Brian Aker
Remove all of uchar.
9143
      get_dynamic(arr, (unsigned char*)&range, inx);
1 by brian
clean slate
9144
      range->flag &= ~(NEAR_MIN | NEAR_MAX);
9145
    }
9146
  }
9147
}
9148
9149
9150
/*
9151
  Determine the total number and length of the keys that will be used for
9152
  index lookup.
9153
9154
  SYNOPSIS
9155
    QUICK_GROUP_MIN_MAX_SELECT::update_key_stat()
9156
9157
  DESCRIPTION
9158
    The total length of the keys used for index lookup depends on whether
9159
    there are any predicates referencing the min/max argument, and/or if
9160
    the min/max argument field can be NULL.
9161
    This function does an optimistic analysis whether the search key might
9162
    be extended by a constant for the min/max keypart. It is 'optimistic'
9163
    because during actual execution it may happen that a particular range
9164
    is skipped, and then a shorter key will be used. However this is data
9165
    dependent and can't be easily estimated here.
9166
9167
  RETURN
9168
    None
9169
*/
9170
9171
void QUICK_GROUP_MIN_MAX_SELECT::update_key_stat()
9172
{
9173
  max_used_key_length= real_prefix_len;
9174
  if (min_max_ranges.elements > 0)
9175
  {
9176
    QUICK_RANGE *cur_range;
9177
    if (have_min)
9178
    { /* Check if the right-most range has a lower boundary. */
481 by Brian Aker
Remove all of uchar.
9179
      get_dynamic(&min_max_ranges, (unsigned char*)&cur_range,
1 by brian
clean slate
9180
                  min_max_ranges.elements - 1);
9181
      if (!(cur_range->flag & NO_MIN_RANGE))
9182
      {
9183
        max_used_key_length+= min_max_arg_len;
9184
        used_key_parts++;
9185
        return;
9186
      }
9187
    }
9188
    if (have_max)
9189
    { /* Check if the left-most range has an upper boundary. */
481 by Brian Aker
Remove all of uchar.
9190
      get_dynamic(&min_max_ranges, (unsigned char*)&cur_range, 0);
1 by brian
clean slate
9191
      if (!(cur_range->flag & NO_MAX_RANGE))
9192
      {
9193
        max_used_key_length+= min_max_arg_len;
9194
        used_key_parts++;
9195
        return;
9196
      }
9197
    }
9198
  }
9199
  else if (have_min && min_max_arg_part &&
9200
           min_max_arg_part->field->real_maybe_null())
9201
  {
9202
    /*
9203
      If a MIN/MAX argument value is NULL, we can quickly determine
9204
      that we're in the beginning of the next group, because NULLs
9205
      are always < any other value. This allows us to quickly
9206
      determine the end of the current group and jump to the next
9207
      group (see next_min()) and thus effectively increases the
9208
      usable key length.
9209
    */
9210
    max_used_key_length+= min_max_arg_len;
9211
    used_key_parts++;
9212
  }
9213
}
9214
9215
9216
/*
9217
  Initialize a quick group min/max select for key retrieval.
9218
9219
  SYNOPSIS
9220
    QUICK_GROUP_MIN_MAX_SELECT::reset()
9221
9222
  DESCRIPTION
9223
    Initialize the index chosen for access and find and store the prefix
9224
    of the last group. The method is expensive since it performs disk access.
9225
9226
  RETURN
9227
    0      OK
9228
    other  Error code
9229
*/
9230
9231
int QUICK_GROUP_MIN_MAX_SELECT::reset(void)
9232
{
9233
  int result;
9234
9235
  file->extra(HA_EXTRA_KEYREAD); /* We need only the key attributes */
9236
  if ((result= file->ha_index_init(index,1)))
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
9237
    return result;
1 by brian
clean slate
9238
  if (quick_prefix_select && quick_prefix_select->reset())
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
9239
    return 0;
1 by brian
clean slate
9240
  result= file->index_last(record);
9241
  if (result == HA_ERR_END_OF_FILE)
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
9242
    return 0;
1 by brian
clean slate
9243
  /* Save the prefix of the last group. */
9244
  key_copy(last_prefix, record, index_info, group_prefix_len);
9245
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
9246
  return 0;
1 by brian
clean slate
9247
}
9248
9249
9250
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
9251
/*
1 by brian
clean slate
9252
  Get the next key containing the MIN and/or MAX key for the next group.
9253
9254
  SYNOPSIS
9255
    QUICK_GROUP_MIN_MAX_SELECT::get_next()
9256
9257
  DESCRIPTION
9258
    The method finds the next subsequent group of records that satisfies the
9259
    query conditions and finds the keys that contain the MIN/MAX values for
9260
    the key part referenced by the MIN/MAX function(s). Once a group and its
9261
    MIN/MAX values are found, store these values in the Item_sum objects for
9262
    the MIN/MAX functions. The rest of the values in the result row are stored
9263
    in the Item_field::result_field of each select field. If the query does
9264
    not contain MIN and/or MAX functions, then the function only finds the
9265
    group prefix, which is a query answer itself.
9266
9267
  NOTES
9268
    If both MIN and MAX are computed, then we use the fact that if there is
9269
    no MIN key, there can't be a MAX key as well, so we can skip looking
9270
    for a MAX key in this case.
9271
9272
  RETURN
9273
    0                  on success
9274
    HA_ERR_END_OF_FILE if returned all keys
9275
    other              if some error occurred
9276
*/
9277
9278
int QUICK_GROUP_MIN_MAX_SELECT::get_next()
9279
{
9280
  int min_res= 0;
9281
  int max_res= 0;
9282
  int result;
9283
  int is_last_prefix= 0;
9284
9285
  /*
9286
    Loop until a group is found that satisfies all query conditions or the last
9287
    group is reached.
9288
  */
9289
  do
9290
  {
9291
    result= next_prefix();
9292
    /*
9293
      Check if this is the last group prefix. Notice that at this point
9294
      this->record contains the current prefix in record format.
9295
    */
9296
    if (!result)
9297
    {
9298
      is_last_prefix= key_cmp(index_info->key_part, last_prefix,
9299
                              group_prefix_len);
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
9300
      assert(is_last_prefix <= 0);
1 by brian
clean slate
9301
    }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
9302
    else
1 by brian
clean slate
9303
    {
9304
      if (result == HA_ERR_KEY_NOT_FOUND)
9305
        continue;
9306
      break;
9307
    }
9308
9309
    if (have_min)
9310
    {
9311
      min_res= next_min();
9312
      if (min_res == 0)
9313
        update_min_result();
9314
    }
9315
    /* If there is no MIN in the group, there is no MAX either. */
9316
    if ((have_max && !have_min) ||
9317
        (have_max && have_min && (min_res == 0)))
9318
    {
9319
      max_res= next_max();
9320
      if (max_res == 0)
9321
        update_max_result();
9322
      /* If a MIN was found, a MAX must have been found as well. */
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
9323
      assert(((have_max && !have_min) ||
9324
                  (have_max && have_min && (max_res == 0))));
1 by brian
clean slate
9325
    }
9326
    /*
9327
      If this is just a GROUP BY or DISTINCT without MIN or MAX and there
9328
      are equality predicates for the key parts after the group, find the
9329
      first sub-group with the extended prefix.
9330
    */
9331
    if (!have_min && !have_max && key_infix_len > 0)
9332
      result= file->index_read_map(record, group_prefix,
9333
                                   make_prev_keypart_map(real_key_parts),
9334
                                   HA_READ_KEY_EXACT);
9335
9336
    result= have_min ? min_res : have_max ? max_res : result;
9337
  } while ((result == HA_ERR_KEY_NOT_FOUND || result == HA_ERR_END_OF_FILE) &&
9338
           is_last_prefix != 0);
9339
9340
  if (result == 0)
9341
  {
9342
    /*
9343
      Partially mimic the behavior of end_select_send. Copy the
9344
      field data from Item_field::field into Item_field::result_field
9345
      of each non-aggregated field (the group fields, and optionally
9346
      other fields in non-ANSI SQL mode).
9347
    */
9348
    copy_fields(&join->tmp_table_param);
9349
  }
9350
  else if (result == HA_ERR_KEY_NOT_FOUND)
9351
    result= HA_ERR_END_OF_FILE;
9352
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
9353
  return result;
1 by brian
clean slate
9354
}
9355
9356
9357
/*
9358
  Retrieve the minimal key in the next group.
9359
9360
  SYNOPSIS
9361
    QUICK_GROUP_MIN_MAX_SELECT::next_min()
9362
9363
  DESCRIPTION
9364
    Find the minimal key within this group such that the key satisfies the query
9365
    conditions and NULL semantics. The found key is loaded into this->record.
9366
9367
  IMPLEMENTATION
9368
    Depending on the values of min_max_ranges.elements, key_infix_len, and
9369
    whether there is a  NULL in the MIN field, this function may directly
9370
    return without any data access. In this case we use the key loaded into
9371
    this->record by the call to this->next_prefix() just before this call.
9372
9373
  RETURN
9374
    0                    on success
9375
    HA_ERR_KEY_NOT_FOUND if no MIN key was found that fulfills all conditions.
9376
    HA_ERR_END_OF_FILE   - "" -
9377
    other                if some error occurred
9378
*/
9379
9380
int QUICK_GROUP_MIN_MAX_SELECT::next_min()
9381
{
9382
  int result= 0;
9383
9384
  /* Find the MIN key using the eventually extended group prefix. */
9385
  if (min_max_ranges.elements > 0)
9386
  {
9387
    if ((result= next_min_in_range()))
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
9388
      return result;
1 by brian
clean slate
9389
  }
9390
  else
9391
  {
9392
    /* Apply the constant equality conditions to the non-group select fields */
9393
    if (key_infix_len > 0)
9394
    {
9395
      if ((result= file->index_read_map(record, group_prefix,
9396
                                        make_prev_keypart_map(real_key_parts),
9397
                                        HA_READ_KEY_EXACT)))
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
9398
        return result;
1 by brian
clean slate
9399
    }
9400
9401
    /*
9402
      If the min/max argument field is NULL, skip subsequent rows in the same
9403
      group with NULL in it. Notice that:
9404
      - if the first row in a group doesn't have a NULL in the field, no row
9405
      in the same group has (because NULL < any other value),
9406
      - min_max_arg_part->field->ptr points to some place in 'record'.
9407
    */
9408
    if (min_max_arg_part && min_max_arg_part->field->is_null())
9409
    {
9410
      /* Find the first subsequent record without NULL in the MIN/MAX field. */
9411
      key_copy(tmp_record, record, index_info, 0);
9412
      result= file->index_read_map(record, tmp_record,
9413
                                   make_keypart_map(real_key_parts),
9414
                                   HA_READ_AFTER_KEY);
9415
      /*
9416
        Check if the new record belongs to the current group by comparing its
9417
        prefix with the group's prefix. If it is from the next group, then the
9418
        whole group has NULLs in the MIN/MAX field, so use the first record in
9419
        the group as a result.
9420
        TODO:
9421
        It is possible to reuse this new record as the result candidate for the
9422
        next call to next_min(), and to save one lookup in the next call. For
9423
        this add a new member 'this->next_group_prefix'.
9424
      */
9425
      if (!result)
9426
      {
9427
        if (key_cmp(index_info->key_part, group_prefix, real_prefix_len))
9428
          key_restore(record, tmp_record, index_info, 0);
9429
      }
9430
      else if (result == HA_ERR_KEY_NOT_FOUND || result == HA_ERR_END_OF_FILE)
9431
        result= 0; /* There is a result in any case. */
9432
    }
9433
  }
9434
9435
  /*
9436
    If the MIN attribute is non-nullable, this->record already contains the
9437
    MIN key in the group, so just return.
9438
  */
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
9439
  return result;
1 by brian
clean slate
9440
}
9441
9442
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
9443
/*
1 by brian
clean slate
9444
  Retrieve the maximal key in the next group.
9445
9446
  SYNOPSIS
9447
    QUICK_GROUP_MIN_MAX_SELECT::next_max()
9448
9449
  DESCRIPTION
9450
    Lookup the maximal key of the group, and store it into this->record.
9451
9452
  RETURN
9453
    0                    on success
9454
    HA_ERR_KEY_NOT_FOUND if no MAX key was found that fulfills all conditions.
9455
    HA_ERR_END_OF_FILE	 - "" -
9456
    other                if some error occurred
9457
*/
9458
9459
int QUICK_GROUP_MIN_MAX_SELECT::next_max()
9460
{
9461
  int result;
9462
9463
  /* Get the last key in the (possibly extended) group. */
9464
  if (min_max_ranges.elements > 0)
9465
    result= next_max_in_range();
9466
  else
9467
    result= file->index_read_map(record, group_prefix,
9468
                                 make_prev_keypart_map(real_key_parts),
9469
                                 HA_READ_PREFIX_LAST);
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
9470
  return result;
1 by brian
clean slate
9471
}
9472
9473
9474
/*
9475
  Determine the prefix of the next group.
9476
9477
  SYNOPSIS
9478
    QUICK_GROUP_MIN_MAX_SELECT::next_prefix()
9479
9480
  DESCRIPTION
9481
    Determine the prefix of the next group that satisfies the query conditions.
9482
    If there is a range condition referencing the group attributes, use a
9483
    QUICK_RANGE_SELECT object to retrieve the *first* key that satisfies the
9484
    condition. If there is a key infix of constants, append this infix
9485
    immediately after the group attributes. The possibly extended prefix is
9486
    stored in this->group_prefix. The first key of the found group is stored in
9487
    this->record, on which relies this->next_min().
9488
9489
  RETURN
9490
    0                    on success
9491
    HA_ERR_KEY_NOT_FOUND if there is no key with the formed prefix
9492
    HA_ERR_END_OF_FILE   if there are no more keys
9493
    other                if some error occurred
9494
*/
9495
int QUICK_GROUP_MIN_MAX_SELECT::next_prefix()
9496
{
9497
  int result;
9498
9499
  if (quick_prefix_select)
9500
  {
481 by Brian Aker
Remove all of uchar.
9501
    unsigned char *cur_prefix= seen_first_key ? group_prefix : NULL;
1 by brian
clean slate
9502
    if ((result= quick_prefix_select->get_next_prefix(group_prefix_len,
9503
                         make_prev_keypart_map(group_key_parts), cur_prefix)))
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
9504
      return result;
55 by brian
Update for using real bool types.
9505
    seen_first_key= true;
1 by brian
clean slate
9506
  }
9507
  else
9508
  {
9509
    if (!seen_first_key)
9510
    {
9511
      result= file->index_first(record);
9512
      if (result)
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
9513
        return result;
55 by brian
Update for using real bool types.
9514
      seen_first_key= true;
1 by brian
clean slate
9515
    }
9516
    else
9517
    {
9518
      /* Load the first key in this group into record. */
9519
      result= file->index_read_map(record, group_prefix,
9520
                                   make_prev_keypart_map(group_key_parts),
9521
                                   HA_READ_AFTER_KEY);
9522
      if (result)
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
9523
        return result;
1 by brian
clean slate
9524
    }
9525
  }
9526
9527
  /* Save the prefix of this group for subsequent calls. */
9528
  key_copy(group_prefix, record, index_info, group_prefix_len);
9529
  /* Append key_infix to group_prefix. */
9530
  if (key_infix_len > 0)
9531
    memcpy(group_prefix + group_prefix_len,
9532
           key_infix, key_infix_len);
9533
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
9534
  return 0;
1 by brian
clean slate
9535
}
9536
9537
9538
/*
9539
  Find the minimal key in a group that satisfies some range conditions for the
9540
  min/max argument field.
9541
9542
  SYNOPSIS
9543
    QUICK_GROUP_MIN_MAX_SELECT::next_min_in_range()
9544
9545
  DESCRIPTION
9546
    Given the sequence of ranges min_max_ranges, find the minimal key that is
9547
    in the left-most possible range. If there is no such key, then the current
9548
    group does not have a MIN key that satisfies the WHERE clause. If a key is
9549
    found, its value is stored in this->record.
9550
9551
  RETURN
9552
    0                    on success
9553
    HA_ERR_KEY_NOT_FOUND if there is no key with the given prefix in any of
9554
                         the ranges
9555
    HA_ERR_END_OF_FILE   - "" -
9556
    other                if some error
9557
*/
9558
9559
int QUICK_GROUP_MIN_MAX_SELECT::next_min_in_range()
9560
{
9561
  ha_rkey_function find_flag;
9562
  key_part_map keypart_map;
9563
  QUICK_RANGE *cur_range;
55 by brian
Update for using real bool types.
9564
  bool found_null= false;
1 by brian
clean slate
9565
  int result= HA_ERR_KEY_NOT_FOUND;
656.1.1 by Monty Taylor
OOOh doggie. Got rid of my_alloca.
9566
  basic_string<unsigned char> max_key;
660.1.6 by Eric Herman
trailing whitespace fixup
9567
656.1.1 by Monty Taylor
OOOh doggie. Got rid of my_alloca.
9568
  max_key.reserve(real_prefix_len + min_max_arg_len);
1 by brian
clean slate
9569
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
9570
  assert(min_max_ranges.elements > 0);
1 by brian
clean slate
9571
482 by Brian Aker
Remove uint.
9572
  for (uint32_t range_idx= 0; range_idx < min_max_ranges.elements; range_idx++)
1 by brian
clean slate
9573
  { /* Search from the left-most range to the right. */
481 by Brian Aker
Remove all of uchar.
9574
    get_dynamic(&min_max_ranges, (unsigned char*)&cur_range, range_idx);
1 by brian
clean slate
9575
9576
    /*
9577
      If the current value for the min/max argument is bigger than the right
9578
      boundary of cur_range, there is no need to check this range.
9579
    */
9580
    if (range_idx != 0 && !(cur_range->flag & NO_MAX_RANGE) &&
481 by Brian Aker
Remove all of uchar.
9581
        (key_cmp(min_max_arg_part, (const unsigned char*) cur_range->max_key,
1 by brian
clean slate
9582
                 min_max_arg_len) == 1))
9583
      continue;
9584
9585
    if (cur_range->flag & NO_MIN_RANGE)
9586
    {
9587
      keypart_map= make_prev_keypart_map(real_key_parts);
9588
      find_flag= HA_READ_KEY_EXACT;
9589
    }
9590
    else
9591
    {
9592
      /* Extend the search key with the lower boundary for this range. */
9593
      memcpy(group_prefix + real_prefix_len, cur_range->min_key,
9594
             cur_range->min_length);
9595
      keypart_map= make_keypart_map(real_key_parts);
9596
      find_flag= (cur_range->flag & (EQ_RANGE | NULL_RANGE)) ?
9597
                 HA_READ_KEY_EXACT : (cur_range->flag & NEAR_MIN) ?
9598
                 HA_READ_AFTER_KEY : HA_READ_KEY_OR_NEXT;
9599
    }
9600
9601
    result= file->index_read_map(record, group_prefix, keypart_map, find_flag);
9602
    if (result)
9603
    {
9604
      if ((result == HA_ERR_KEY_NOT_FOUND || result == HA_ERR_END_OF_FILE) &&
9605
          (cur_range->flag & (EQ_RANGE | NULL_RANGE)))
9606
        continue; /* Check the next range. */
9607
9608
      /*
9609
        In all other cases (HA_ERR_*, HA_READ_KEY_EXACT with NO_MIN_RANGE,
9610
        HA_READ_AFTER_KEY, HA_READ_KEY_OR_NEXT) if the lookup failed for this
9611
        range, it can't succeed for any other subsequent range.
9612
      */
9613
      break;
9614
    }
9615
9616
    /* A key was found. */
9617
    if (cur_range->flag & EQ_RANGE)
9618
      break; /* No need to perform the checks below for equal keys. */
9619
9620
    if (cur_range->flag & NULL_RANGE)
9621
    {
9622
      /*
9623
        Remember this key, and continue looking for a non-NULL key that
9624
        satisfies some other condition.
9625
      */
9626
      memcpy(tmp_record, record, head->s->rec_buff_length);
55 by brian
Update for using real bool types.
9627
      found_null= true;
1 by brian
clean slate
9628
      continue;
9629
    }
9630
9631
    /* Check if record belongs to the current group. */
9632
    if (key_cmp(index_info->key_part, group_prefix, real_prefix_len))
9633
    {
9634
      result= HA_ERR_KEY_NOT_FOUND;
9635
      continue;
9636
    }
9637
9638
    /* If there is an upper limit, check if the found key is in the range. */
9639
    if ( !(cur_range->flag & NO_MAX_RANGE) )
9640
    {
9641
      /* Compose the MAX key for the range. */
656.1.1 by Monty Taylor
OOOh doggie. Got rid of my_alloca.
9642
      max_key.clear();
9643
      max_key.append(group_prefix, real_prefix_len);
9644
      max_key.append(cur_range->max_key, cur_range->max_length);
1 by brian
clean slate
9645
      /* Compare the found key with max_key. */
656.1.1 by Monty Taylor
OOOh doggie. Got rid of my_alloca.
9646
      int cmp_res= key_cmp(index_info->key_part,
9647
                           max_key.data(),
1 by brian
clean slate
9648
                           real_prefix_len + min_max_arg_len);
9649
      if ((!((cur_range->flag & NEAR_MAX) && (cmp_res == -1)) || (cmp_res <= 0)))
9650
      {
9651
        result= HA_ERR_KEY_NOT_FOUND;
9652
        continue;
9653
      }
9654
    }
9655
    /* If we got to this point, the current key qualifies as MIN. */
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
9656
    assert(result == 0);
1 by brian
clean slate
9657
    break;
9658
  }
9659
  /*
9660
    If there was a key with NULL in the MIN/MAX field, and there was no other
9661
    key without NULL from the same group that satisfies some other condition,
9662
    then use the key with the NULL.
9663
  */
9664
  if (found_null && result)
9665
  {
9666
    memcpy(record, tmp_record, head->s->rec_buff_length);
9667
    result= 0;
9668
  }
9669
  return result;
9670
}
9671
9672
9673
/*
9674
  Find the maximal key in a group that satisfies some range conditions for the
9675
  min/max argument field.
9676
9677
  SYNOPSIS
9678
    QUICK_GROUP_MIN_MAX_SELECT::next_max_in_range()
9679
9680
  DESCRIPTION
9681
    Given the sequence of ranges min_max_ranges, find the maximal key that is
9682
    in the right-most possible range. If there is no such key, then the current
9683
    group does not have a MAX key that satisfies the WHERE clause. If a key is
9684
    found, its value is stored in this->record.
9685
9686
  RETURN
9687
    0                    on success
9688
    HA_ERR_KEY_NOT_FOUND if there is no key with the given prefix in any of
9689
                         the ranges
9690
    HA_ERR_END_OF_FILE   - "" -
9691
    other                if some error
9692
*/
9693
9694
int QUICK_GROUP_MIN_MAX_SELECT::next_max_in_range()
9695
{
9696
  ha_rkey_function find_flag;
9697
  key_part_map keypart_map;
9698
  QUICK_RANGE *cur_range;
9699
  int result;
656.1.1 by Monty Taylor
OOOh doggie. Got rid of my_alloca.
9700
  basic_string<unsigned char> min_key;
9701
  min_key.reserve(real_prefix_len + min_max_arg_len);
1 by brian
clean slate
9702
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
9703
  assert(min_max_ranges.elements > 0);
1 by brian
clean slate
9704
482 by Brian Aker
Remove uint.
9705
  for (uint32_t range_idx= min_max_ranges.elements; range_idx > 0; range_idx--)
1 by brian
clean slate
9706
  { /* Search from the right-most range to the left. */
481 by Brian Aker
Remove all of uchar.
9707
    get_dynamic(&min_max_ranges, (unsigned char*)&cur_range, range_idx - 1);
1 by brian
clean slate
9708
9709
    /*
9710
      If the current value for the min/max argument is smaller than the left
9711
      boundary of cur_range, there is no need to check this range.
9712
    */
9713
    if (range_idx != min_max_ranges.elements &&
9714
        !(cur_range->flag & NO_MIN_RANGE) &&
481 by Brian Aker
Remove all of uchar.
9715
        (key_cmp(min_max_arg_part, (const unsigned char*) cur_range->min_key,
1 by brian
clean slate
9716
                 min_max_arg_len) == -1))
9717
      continue;
9718
9719
    if (cur_range->flag & NO_MAX_RANGE)
9720
    {
9721
      keypart_map= make_prev_keypart_map(real_key_parts);
9722
      find_flag= HA_READ_PREFIX_LAST;
9723
    }
9724
    else
9725
    {
9726
      /* Extend the search key with the upper boundary for this range. */
9727
      memcpy(group_prefix + real_prefix_len, cur_range->max_key,
9728
             cur_range->max_length);
9729
      keypart_map= make_keypart_map(real_key_parts);
9730
      find_flag= (cur_range->flag & EQ_RANGE) ?
9731
                 HA_READ_KEY_EXACT : (cur_range->flag & NEAR_MAX) ?
9732
                 HA_READ_BEFORE_KEY : HA_READ_PREFIX_LAST_OR_PREV;
9733
    }
9734
9735
    result= file->index_read_map(record, group_prefix, keypart_map, find_flag);
9736
9737
    if (result)
9738
    {
9739
      if ((result == HA_ERR_KEY_NOT_FOUND || result == HA_ERR_END_OF_FILE) &&
9740
          (cur_range->flag & EQ_RANGE))
9741
        continue; /* Check the next range. */
9742
9743
      /*
9744
        In no key was found with this upper bound, there certainly are no keys
9745
        in the ranges to the left.
9746
      */
9747
      return result;
9748
    }
9749
    /* A key was found. */
9750
    if (cur_range->flag & EQ_RANGE)
9751
      return 0; /* No need to perform the checks below for equal keys. */
9752
9753
    /* Check if record belongs to the current group. */
9754
    if (key_cmp(index_info->key_part, group_prefix, real_prefix_len))
9755
      continue;                                 // Row not found
9756
9757
    /* If there is a lower limit, check if the found key is in the range. */
9758
    if ( !(cur_range->flag & NO_MIN_RANGE) )
9759
    {
9760
      /* Compose the MIN key for the range. */
656.1.1 by Monty Taylor
OOOh doggie. Got rid of my_alloca.
9761
      min_key.clear();
9762
      min_key.append(group_prefix, real_prefix_len);
9763
      min_key.append(cur_range->min_key, cur_range->min_length);
9764
1 by brian
clean slate
9765
      /* Compare the found key with min_key. */
656.1.1 by Monty Taylor
OOOh doggie. Got rid of my_alloca.
9766
      int cmp_res= key_cmp(index_info->key_part,
9767
                           min_key.data(),
1 by brian
clean slate
9768
                           real_prefix_len + min_max_arg_len);
9769
      if ((!((cur_range->flag & NEAR_MIN) && (cmp_res == 1)) ||
9770
            (cmp_res >= 0)))
9771
        continue;
9772
    }
9773
    /* If we got to this point, the current key qualifies as MAX. */
9774
    return result;
9775
  }
9776
  return HA_ERR_KEY_NOT_FOUND;
9777
}
9778
9779
9780
/*
9781
  Update all MIN function results with the newly found value.
9782
9783
  SYNOPSIS
9784
    QUICK_GROUP_MIN_MAX_SELECT::update_min_result()
9785
9786
  DESCRIPTION
9787
    The method iterates through all MIN functions and updates the result value
9788
    of each function by calling Item_sum::reset(), which in turn picks the new
9789
    result value from this->head->record[0], previously updated by
9790
    next_min(). The updated value is stored in a member variable of each of the
9791
    Item_sum objects, depending on the value type.
9792
9793
  IMPLEMENTATION
9794
    The update must be done separately for MIN and MAX, immediately after
9795
    next_min() was called and before next_max() is called, because both MIN and
9796
    MAX take their result value from the same buffer this->head->record[0]
9797
    (i.e.  this->record).
9798
9799
  RETURN
9800
    None
9801
*/
9802
9803
void QUICK_GROUP_MIN_MAX_SELECT::update_min_result()
9804
{
9805
  Item_sum *min_func;
9806
9807
  min_functions_it->rewind();
9808
  while ((min_func= (*min_functions_it)++))
9809
    min_func->reset();
9810
}
9811
9812
9813
/*
9814
  Update all MAX function results with the newly found value.
9815
9816
  SYNOPSIS
9817
    QUICK_GROUP_MIN_MAX_SELECT::update_max_result()
9818
9819
  DESCRIPTION
9820
    The method iterates through all MAX functions and updates the result value
9821
    of each function by calling Item_sum::reset(), which in turn picks the new
9822
    result value from this->head->record[0], previously updated by
9823
    next_max(). The updated value is stored in a member variable of each of the
9824
    Item_sum objects, depending on the value type.
9825
9826
  IMPLEMENTATION
9827
    The update must be done separately for MIN and MAX, immediately after
9828
    next_max() was called, because both MIN and MAX take their result value
9829
    from the same buffer this->head->record[0] (i.e.  this->record).
9830
9831
  RETURN
9832
    None
9833
*/
9834
9835
void QUICK_GROUP_MIN_MAX_SELECT::update_max_result()
9836
{
9837
  Item_sum *max_func;
9838
9839
  max_functions_it->rewind();
9840
  while ((max_func= (*max_functions_it)++))
9841
    max_func->reset();
9842
}
9843
9844
9845
/*
9846
  Append comma-separated list of keys this quick select uses to key_names;
9847
  append comma-separated list of corresponding used lengths to used_lengths.
9848
9849
  SYNOPSIS
9850
    QUICK_GROUP_MIN_MAX_SELECT::add_keys_and_lengths()
9851
    key_names    [out] Names of used indexes
9852
    used_lengths [out] Corresponding lengths of the index names
9853
9854
  DESCRIPTION
9855
    This method is used by select_describe to extract the names of the
9856
    indexes used by a quick select.
9857
9858
*/
9859
9860
void QUICK_GROUP_MIN_MAX_SELECT::add_keys_and_lengths(String *key_names,
9861
                                                      String *used_lengths)
9862
{
9863
  char buf[64];
482 by Brian Aker
Remove uint.
9864
  uint32_t length;
1 by brian
clean slate
9865
  key_names->append(index_info->name);
152 by Brian Aker
longlong replacement
9866
  length= int64_t2str(max_used_key_length, buf, 10) - buf;
1 by brian
clean slate
9867
  used_lengths->append(buf, length);
9868
}
9869
655 by Brian Aker
Yet more unused.... damn annoying... (also tossed some prototypes that were
9870
static void print_sel_tree(PARAM *param, SEL_TREE *tree, key_map *tree_map, const char *)
1 by brian
clean slate
9871
{
9872
  SEL_ARG **key,**end;
9873
  int idx;
9874
  char buff[1024];
9875
9876
  String tmp(buff,sizeof(buff),&my_charset_bin);
9877
  tmp.length(0);
9878
  for (idx= 0,key=tree->keys, end=key+param->keys ;
9879
       key != end ;
9880
       key++,idx++)
9881
  {
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
9882
    if (tree_map->test(idx))
1 by brian
clean slate
9883
    {
482 by Brian Aker
Remove uint.
9884
      uint32_t keynr= param->real_keynr[idx];
1 by brian
clean slate
9885
      if (tmp.length())
9886
        tmp.append(',');
9887
      tmp.append(param->table->key_info[keynr].name);
9888
    }
9889
  }
9890
  if (!tmp.length())
9891
    tmp.append(STRING_WITH_LEN("(empty)"));
9892
}
9893
9894
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
9895
static void print_ror_scans_arr(Table *table,
655 by Brian Aker
Yet more unused.... damn annoying... (also tossed some prototypes that were
9896
                                const char *, struct st_ror_scan_info **start,
1 by brian
clean slate
9897
                                struct st_ror_scan_info **end)
9898
{
9899
  char buff[1024];
9900
  String tmp(buff,sizeof(buff),&my_charset_bin);
9901
  tmp.length(0);
9902
  for (;start != end; start++)
9903
  {
9904
    if (tmp.length())
9905
      tmp.append(',');
9906
    tmp.append(table->key_info[(*start)->keynr].name);
9907
  }
9908
  if (!tmp.length())
9909
    tmp.append(STRING_WITH_LEN("(empty)"));
9910
}
9911
9912
/*****************************************************************************
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
9913
** Instantiate templates
1 by brian
clean slate
9914
*****************************************************************************/
9915
9916
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
9917
template class List<QUICK_RANGE>;
9918
template class List_iterator<QUICK_RANGE>;
9919
#endif