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