~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/optimizer/range.cc

Fix merge issues with 1.0 CC fix.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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 */
 
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
 
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
 
3
 *
 
4
 *  Copyright (C) 2008-2009 Sun Microsystems, Inc.
 
5
 *
 
6
 *  This program is free software; you can redistribute it and/or modify
 
7
 *  it under the terms of the GNU General Public License as published by
 
8
 *  the Free Software Foundation; version 2 of the License.
 
9
 *
 
10
 *  This program is distributed in the hope that it will be useful,
 
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 *  GNU General Public License for more details.
 
14
 *
 
15
 *  You should have received a copy of the GNU General Public License
 
16
 *  along with this program; if not, write to the Free Software
 
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
18
 */
15
19
 
16
20
/*
17
21
  TODO:
23
27
*/
24
28
 
25
29
/*
26
 
  This file contains:
 
30
  This cursor contains:
27
31
 
28
32
  RangeAnalysisModule
29
33
    A module that accepts a condition, index (or partitioning) description,
33
37
    The entry point for the range analysis module is get_mm_tree() function.
34
38
 
35
39
    The lists are returned in form of complicated structure of interlinked
36
 
    SEL_TREE/SEL_IMERGE/SEL_ARG objects.
 
40
    optimizer::SEL_TREE/optimizer::SEL_IMERGE/SEL_ARG objects.
37
41
    See quick_range_seq_next, find_used_partitions for examples of how to walk
38
42
    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.
 
43
    All direct "users" of this module are located within this cursor, too.
47
44
 
48
45
 
49
46
  Range/index_merge/groupby-minmax optimizer module
62
59
 
63
60
  KeyTupleFormat
64
61
  ~~~~~~~~~~~~~~
65
 
  The code in this file (and elsewhere) makes operations on key value tuples.
 
62
  The code in this cursor (and elsewhere) makes operations on key value tuples.
66
63
  Those tuples are stored in the following format:
67
64
 
68
65
  The tuple is a sequence of key part values. The length of key part value
87
84
  keypart-value-bytes holds the value. Its format depends on the field type.
88
85
  The length of keypart-value-bytes may or may not depend on the value being
89
86
  stored. The default is that length is static and equal to
90
 
  KEY_PART_INFO::length.
 
87
  KeyPartInfo::length.
91
88
 
92
89
  Key parts with (key_part_flag & HA_BLOB_PART) have length depending of the
93
90
  value:
103
100
           subject and may omit some details.
104
101
*/
105
102
 
106
 
#include <drizzled/server_includes.h>
107
 
#include <drizzled/sql_select.h>
 
103
#include <config.h>
 
104
 
 
105
#include <math.h>
 
106
#include <float.h>
 
107
 
 
108
#include <string>
 
109
#include <vector>
 
110
#include <algorithm>
 
111
 
 
112
#include <boost/dynamic_bitset.hpp>
 
113
 
 
114
#include <drizzled/check_stack_overrun.h>
108
115
#include <drizzled/error.h>
109
 
#include <drizzled/cost_vect.h>
 
116
#include <drizzled/field/num.h>
 
117
#include <drizzled/internal/iocache.h>
 
118
#include <drizzled/internal/my_sys.h>
110
119
#include <drizzled/item/cmpfunc.h>
111
 
#include <drizzled/field/num.h>
112
 
#include <drizzled/check_stack_overrun.h>
113
 
 
114
 
#include <string>
115
 
#include CMATH_H
 
120
#include <drizzled/optimizer/cost_vector.h>
 
121
#include <drizzled/optimizer/quick_group_min_max_select.h>
 
122
#include <drizzled/optimizer/quick_index_merge_select.h>
 
123
#include <drizzled/optimizer/quick_range.h>
 
124
#include <drizzled/optimizer/quick_range_select.h>
 
125
#include <drizzled/optimizer/quick_ror_intersect_select.h>
 
126
#include <drizzled/optimizer/quick_ror_union_select.h>
 
127
#include <drizzled/optimizer/range.h>
 
128
#include <drizzled/optimizer/range_param.h>
 
129
#include <drizzled/optimizer/sel_arg.h>
 
130
#include <drizzled/optimizer/sel_imerge.h>
 
131
#include <drizzled/optimizer/sel_tree.h>
 
132
#include <drizzled/optimizer/sum.h>
 
133
#include <drizzled/optimizer/table_read_plan.h>
 
134
#include <drizzled/plugin/storage_engine.h>
 
135
#include <drizzled/records.h>
 
136
#include <drizzled/sql_base.h>
 
137
#include <drizzled/sql_select.h>
 
138
#include <drizzled/table_reference.h>
 
139
#include <drizzled/session.h>
 
140
#include <drizzled/key.h>
 
141
#include <drizzled/unique.h>
 
142
#include <drizzled/temporal.h> /* Needed in get_mm_leaf() for timestamp -> datetime comparisons */
 
143
#include <drizzled/sql_lex.h>
 
144
#include <drizzled/system_variables.h>
116
145
 
117
146
using namespace std;
118
 
#if defined(CMATH_NAMESPACE)
119
 
using namespace CMATH_NAMESPACE;
120
 
#endif
 
147
 
 
148
namespace drizzled {
 
149
 
 
150
static const int HA_END_SPACE_KEY= 0;
121
151
 
122
152
/*
123
153
  Convert double value to #rows. Currently this does floor(), and we
124
154
  might consider using round() instead.
125
155
*/
126
 
#define double2rows(x) ((ha_rows)(x))
127
 
 
128
 
static int sel_cmp(Field *f,unsigned char *a,unsigned char *b,uint8_t a_flag,uint8_t b_flag);
 
156
static inline ha_rows double2rows(double x)
 
157
{
 
158
    return static_cast<ha_rows>(x);
 
159
}
129
160
 
130
161
static unsigned char is_null_string[2]= {1,0};
131
162
 
132
 
class RANGE_OPT_PARAM;
133
 
/*
134
 
  A construction block of the SEL_ARG-graph.
135
 
 
136
 
  The following description only covers graphs of SEL_ARG objects with
137
 
  sel_arg->type==KEY_RANGE:
138
 
 
139
 
  One SEL_ARG object represents an "elementary interval" in form
140
 
 
141
 
      min_value <=?  table.keypartX  <=? max_value
142
 
 
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
147
 
 
148
 
  SEL_ARG objects are linked together in a graph. The meaning of the graph
149
 
  is better demostrated by an example:
150
 
 
151
 
     tree->keys[i]
152
 
      |
153
 
      |             $              $
154
 
      |    part=1   $     part=2   $    part=3
155
 
      |             $              $
156
 
      |  +-------+  $   +-------+  $   +--------+
157
 
      |  | kp1<1 |--$-->| kp2=5 |--$-->| kp3=10 |
158
 
      |  +-------+  $   +-------+  $   +--------+
159
 
      |      |      $              $       |
160
 
      |      |      $              $   +--------+
161
 
      |      |      $              $   | kp3=12 |
162
 
      |      |      $              $   +--------+
163
 
      |  +-------+  $              $
164
 
      \->| kp1=2 |--$--------------$-+
165
 
         +-------+  $              $ |   +--------+
166
 
             |      $              $  ==>| kp3=11 |
167
 
         +-------+  $              $ |   +--------+
168
 
         | kp1=3 |--$--------------$-+       |
169
 
         +-------+  $              $     +--------+
170
 
             |      $              $     | kp3=14 |
171
 
            ...     $              $     +--------+
172
 
 
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,
177
 
  all intervals in the list form an RB-tree, linked via left/right/parent
178
 
  pointers. The RB-tree root SEL_ARG object will be further called "root of the
179
 
  interval list".
180
 
 
181
 
    In the example pic, there are 4 interval lists:
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.
184
 
 
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).
188
 
 
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".
196
 
 
197
 
  For example, the picture represents the condition in form:
198
 
   (kp1 < 1 AND kp2=5 AND (kp3=10 OR kp3=12)) OR
199
 
   (kp1=2 AND (kp3=11 OR kp3=14)) OR
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
208
 
 
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
 
 
219
 
  4. SPACE COMPLEXITY NOTES
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:
226
 
 
227
 
      (keypart1 IN (1,2, ..., n1)) AND
228
 
      (keypart2 IN (1,2, ..., n2)) AND
229
 
      (keypart3 IN (1,2, ..., n3))
230
 
 
231
 
    For this WHERE clause the list of intervals will have n1*n2*n3 intervals
232
 
    of form
233
 
 
234
 
      (keypart1, keypart2, keypart3) = (k1, k2, k3), where 1 <= k{i} <= n{i}
235
 
 
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
238
 
    beginning of this comment has examples of such sharing). The sharing may
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:
244
 
        (keypartN IN (1,2, ..., n1)) AND
245
 
        ...
246
 
        (keypart2 IN (1,2, ..., n2)) AND
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:
255
 
        (keypart1 IN (1,2, ..., n1)) AND
256
 
        (keypart2 IN (1,2, ..., n2)) AND
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
266
 
 
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) (*)
271
 
 
272
 
        We will obtain this SEL_ARG graph:
273
 
 
274
 
             kp14     $      kp15      $      kp16
275
 
                      $                $
276
 
         +---------+  $   +---------+  $   +---------+
277
 
         | kp14=c1 |--$-->| kp15=c0 |--$-->| kp16=c3 |
278
 
         +---------+  $   +---------+  $   +---------+
279
 
              |       $                $
280
 
         +---------+  $   +---------+  $
281
 
         | kp14=c2 |--$-->| kp15=c0 |  $
282
 
         +---------+  $   +---------+  $
283
 
                      $                $
284
 
 
285
 
       Note that we had to duplicate "kp15=c0" and there was no way to avoid
286
 
       that.
287
 
       The induction step: AND the obtained expression with another "wrapping"
288
 
       expression like (*).
289
 
       When the process ends because of the limit on max. number of keyparts
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:
306
 
  uint8_t min_flag,max_flag,maybe_flag;
307
 
  uint8_t part;                                 // Which key part
308
 
  uint8_t maybe_null;
309
 
  /*
310
 
    Number of children of this element in the RB-tree, plus 1 for this
311
 
    element itself.
312
 
  */
313
 
  uint16_t elements;
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;
322
 
  unsigned char *min_value,*max_value;                  // Pointer to range
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 */
330
 
  SEL_ARG *next_key_part;
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 &);
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,
340
 
          uint8_t min_flag, uint8_t max_flag, uint8_t maybe_flag);
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 */
356
 
  inline bool is_null_interval() { return maybe_null && max_value[0] == 1; }
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
375
 
    unsigned char *new_min,*new_max;
376
 
    uint8_t flag_min,flag_max;
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 */
449
 
  int store_min(uint32_t length, unsigned char **min_key,uint32_t min_key_flag)
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;
458
 
        memset(*min_key+1, 0, length-1);
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 */
468
 
  int store_max(uint32_t length, unsigned char **max_key, uint32_t max_key_flag)
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;
476
 
        memset(*max_key+1, 0, length-1);
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 */
487
 
  int store_min_key(KEY_PART *key, unsigned char **range_key, uint32_t *range_key_flag)
488
 
  {
489
 
    SEL_ARG *key_tree= first();
490
 
    uint32_t res= key_tree->store_min(key[key_tree->part].store_length,
491
 
                                  range_key, *range_key_flag);
492
 
    *range_key_flag|= key_tree->min_flag;
493
 
 
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 */
504
 
  int store_max_key(KEY_PART *key, unsigned char **range_key, uint32_t *range_key_flag)
505
 
  {
506
 
    SEL_ARG *key_tree= last();
507
 
    uint32_t res=key_tree->store_max(key[key_tree->part].store_length,
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()
567
 
 
568
 
    DESCRIPTION
569
 
      Check if this SEL_ARG object (not tree) represents a single-point
570
 
      interval, i.e. if it represents a "keypart = const" or
571
 
      "keypart IS NULL".
572
 
 
573
 
    RETURN
574
 
      true   This SEL_ARG object represents a singlepoint interval
575
 
      false  Otherwise
576
 
  */
577
 
 
578
 
  bool is_singlepoint()
579
 
  {
580
 
    /*
581
 
      Check for NEAR_MIN ("strictly less") and NO_MIN_RANGE (-inf < field)
582
 
      flags, and the same for right edge.
583
 
    */
584
 
    if (min_flag || max_flag)
585
 
      return false;
586
 
    unsigned char *min_val= min_value;
587
 
    unsigned char *max_val= max_value;
588
 
 
589
 
    if (maybe_null)
590
 
    {
591
 
      /* First byte is a NULL value indicator */
592
 
      if (*min_val != *max_val)
593
 
        return false;
594
 
 
595
 
      if (*min_val)
596
 
        return true; /* This "x IS NULL" */
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:
613
 
    (for some i, keys[i]->type == SEL_ARG::IMPOSSIBLE) =>
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();
621
 
    memset(keys, 0, sizeof(keys));
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 */
640
 
  uint32_t    n_ror_scans;     /* number of set bits in ror_scans_map */
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:
650
 
  Session       *session;   /* Current thread handle */
651
 
  Table *table; /* Table being analyzed */
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
 
  */
666
 
  uint32_t keys;
667
 
 
668
 
  /*
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;
674
 
 
675
 
  bool remove_jump_scans;
676
 
 
677
 
  /*
678
 
    used_key_no -> table_key_no translation table. Only makes sense if
679
 
    using_real_indexes==true
680
 
  */
681
 
  uint32_t real_keynr[MAX_KEY];
682
 
  /* Number of SEL_ARG objects allocated by SEL_ARG::clone_tree operations */
683
 
  uint32_t alloced_sel_args;
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 */
691
 
  int64_t baseflag;
692
 
  uint32_t max_key_part;
693
 
  /* Number of ranges in the last checked tree->key */
694
 
  uint32_t range_count;
695
 
  unsigned char min_key[MAX_KEY_LENGTH+MAX_FIELD_WIDTH],
696
 
    max_key[MAX_KEY_LENGTH+MAX_FIELD_WIDTH];
697
 
  bool quick;                           // Don't calulate possible keys
698
 
 
699
 
  uint32_t fields_bitmap_size;
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
 
 
705
 
  uint32_t *imerge_cost_buff;     /* buffer for index_merge cost estimates */
706
 
  uint32_t imerge_cost_buff_size; /* size of the buffer */
707
 
 
708
 
  /* true if last checked tree->key can be used for ROR-scan */
709
 
  bool is_ror_scan;
710
 
  /* Number of ranges in the last checked tree->key */
711
 
  uint32_t n_ranges;
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
 
 
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,
733
 
                                  SEL_ARG *tree, bool update_tbl_stats,
734
 
                                  uint32_t *mrr_flags, uint32_t *bufsize,
735
 
                                  COST_VECT *cost);
736
 
                                  //bool update_tbl_stats);
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);
740
 
*/
741
 
 
742
 
QUICK_RANGE_SELECT *get_quick_select(PARAM *param,uint32_t index,
743
 
                                     SEL_ARG *key_tree, uint32_t mrr_flags,
744
 
                                     uint32_t mrr_buf_size, MEM_ROOT *alloc);
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);
765
 
static void print_ror_scans_arr(Table *table, const char *msg,
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,
774
 
                        uint32_t clone_flag);
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,
777
 
                    SEL_ARG *key_tree, unsigned char *min_key,uint32_t min_key_flag,
778
 
                    unsigned char *max_key,uint32_t max_key_flag);
779
 
static bool eq_tree(SEL_ARG* a,SEL_ARG *b);
780
 
 
781
 
static SEL_ARG null_element(SEL_ARG::IMPOSSIBLE);
782
 
static bool null_part_in_key(KEY_PART *key_part, const unsigned char *key,
 
163
 
 
164
/**
 
165
  Get cost of reading nrows table records in a "disk sweep"
 
166
 
 
167
  A disk sweep read is a sequence of Cursor->rnd_pos(rowid) calls that made
 
168
  for an ordered sequence of rowids.
 
169
 
 
170
  We assume hard disk IO. The read is performed as follows:
 
171
 
 
172
   1. The disk head is moved to the needed cylinder
 
173
   2. The controller waits for the plate to rotate
 
174
   3. The data is transferred
 
175
 
 
176
  Time to do #3 is insignificant compared to #2+#1.
 
177
 
 
178
  Time to move the disk head is proportional to head travel distance.
 
179
 
 
180
  Time to wait for the plate to rotate depends on whether the disk head
 
181
  was moved or not.
 
182
 
 
183
  If disk head wasn't moved, the wait time is proportional to distance
 
184
  between the previous block and the block we're reading.
 
185
 
 
186
  If the head was moved, we don't know how much we'll need to wait for the
 
187
  plate to rotate. We assume the wait time to be a variate with a mean of
 
188
  0.5 of full rotation time.
 
189
 
 
190
  Our cost units are "random disk seeks". The cost of random disk seek is
 
191
  actually not a constant, it depends one range of cylinders we're going
 
192
  to access. We make it constant by introducing a fuzzy concept of "typical
 
193
  datafile length" (it's fuzzy as it's hard to tell whether it should
 
194
  include index cursor, temp.tables etc). Then random seek cost is:
 
195
 
 
196
    1 = half_rotation_cost + move_cost * 1/3 * typical_data_file_length
 
197
 
 
198
  We define half_rotation_cost as DISK_SEEK_BASE_COST=0.9.
 
199
 
 
200
  @param table             Table to be accessed
 
201
  @param nrows             Number of rows to retrieve
 
202
  @param interrupted       true <=> Assume that the disk sweep will be
 
203
                           interrupted by other disk IO. false - otherwise.
 
204
  @param cost         OUT  The cost.
 
205
*/
 
206
 
 
207
static void get_sweep_read_cost(Table *table,
 
208
                                ha_rows nrows,
 
209
                                bool interrupted,
 
210
                                optimizer::CostVector *cost)
 
211
{
 
212
  cost->zero();
 
213
  if (table->cursor->primary_key_is_clustered())
 
214
  {
 
215
    cost->setIOCount(table->cursor->read_time(table->getShare()->getPrimaryKey(),
 
216
                                             static_cast<uint32_t>(nrows),
 
217
                                             nrows));
 
218
  }
 
219
  else
 
220
  {
 
221
    double n_blocks=
 
222
      ceil(static_cast<double>(table->cursor->stats.data_file_length) / IO_SIZE);
 
223
    double busy_blocks=
 
224
      n_blocks * (1.0 - pow(1.0 - 1.0/n_blocks, static_cast<double>(nrows)));
 
225
    if (busy_blocks < 1.0)
 
226
      busy_blocks= 1.0;
 
227
 
 
228
    cost->setIOCount(busy_blocks);
 
229
 
 
230
    if (! interrupted)
 
231
    {
 
232
      /* Assume reading is done in one 'sweep' */
 
233
      cost->setAvgIOCost((DISK_SEEK_BASE_COST +
 
234
                          DISK_SEEK_PROP_COST*n_blocks/busy_blocks));
 
235
    }
 
236
  }
 
237
}
 
238
 
 
239
static optimizer::SEL_TREE * get_mm_parts(optimizer::RangeParameter *param,
 
240
                               COND *cond_func,
 
241
                               Field *field,
 
242
                                                 Item_func::Functype type,
 
243
                               Item *value,
 
244
                                                 Item_result cmp_type);
 
245
 
 
246
static optimizer::SEL_ARG *get_mm_leaf(optimizer::RangeParameter *param,
 
247
                                       COND *cond_func,
 
248
                                       Field *field,
 
249
                                       KEY_PART *key_part,
 
250
                                                         Item_func::Functype type,
 
251
                                       Item *value);
 
252
 
 
253
static optimizer::SEL_TREE *get_mm_tree(optimizer::RangeParameter *param, COND *cond);
 
254
 
 
255
static bool is_key_scan_ror(optimizer::Parameter *param, uint32_t keynr, uint8_t nparts);
 
256
 
 
257
static ha_rows check_quick_select(Session *session,
 
258
                                  optimizer::Parameter *param,
 
259
                                  uint32_t idx,
 
260
                                  bool index_only,
 
261
                                  optimizer::SEL_ARG *tree,
 
262
                                  bool update_tbl_stats,
 
263
                                  uint32_t *mrr_flags,
 
264
                                  uint32_t *bufsize,
 
265
                                  optimizer::CostVector *cost);
 
266
 
 
267
static optimizer::RangeReadPlan *get_key_scans_params(Session *session,
 
268
                                                      optimizer::Parameter *param,
 
269
                                                      optimizer::SEL_TREE *tree,
 
270
                                                      bool index_read_must_be_used,
 
271
                                                      bool update_tbl_stats,
 
272
                                                      double read_time);
 
273
 
 
274
static
 
275
optimizer::RorIntersectReadPlan *get_best_ror_intersect(const optimizer::Parameter *param,
 
276
                                                        optimizer::SEL_TREE *tree,
 
277
                                                        double read_time,
 
278
                                                        bool *are_all_covering);
 
279
 
 
280
static
 
281
optimizer::RorIntersectReadPlan *get_best_covering_ror_intersect(optimizer::Parameter *param,
 
282
                                                                 optimizer::SEL_TREE *tree,
 
283
                                                                 double read_time);
 
284
 
 
285
static
 
286
optimizer::TableReadPlan *get_best_disjunct_quick(Session *session,
 
287
                                                  optimizer::Parameter *param,
 
288
                                                  optimizer::SEL_IMERGE *imerge,
 
289
                                                  double read_time);
 
290
 
 
291
static
 
292
optimizer::GroupMinMaxReadPlan *get_best_group_min_max(optimizer::Parameter *param, optimizer::SEL_TREE *tree);
 
293
 
 
294
static optimizer::SEL_TREE *tree_and(optimizer::RangeParameter *param,
 
295
                                     optimizer::SEL_TREE *tree1,
 
296
                                     optimizer::SEL_TREE *tree2);
 
297
 
 
298
static optimizer::SEL_ARG *sel_add(optimizer::SEL_ARG *key1, optimizer::SEL_ARG *key2);
 
299
 
 
300
static optimizer::SEL_ARG *key_and(optimizer::RangeParameter *param,
 
301
                                   optimizer::SEL_ARG *key1,
 
302
                                   optimizer::SEL_ARG *key2,
 
303
                                   uint32_t clone_flag);
 
304
 
 
305
static bool get_range(optimizer::SEL_ARG **e1, optimizer::SEL_ARG **e2, optimizer::SEL_ARG *root1);
 
306
 
 
307
optimizer::SEL_ARG optimizer::null_element(optimizer::SEL_ARG::IMPOSSIBLE);
 
308
 
 
309
static bool null_part_in_key(KEY_PART *key_part,
 
310
                             const unsigned char *key,
783
311
                             uint32_t length);
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 */
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;
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
914
 
    1 - One of conditions in result is always true and this SEL_IMERGE
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
 
}
 
312
 
 
313
bool sel_trees_can_be_ored(optimizer::SEL_TREE *tree1,
 
314
                           optimizer::SEL_TREE *tree2,
 
315
                           optimizer::RangeParameter *param);
 
316
 
 
317
 
 
318
 
 
319
 
930
320
 
931
321
 
932
322
/*
933
323
  Perform AND operation on two index_merge lists and store result in *im1.
934
324
*/
935
325
 
936
 
inline void imerge_list_and_list(List<SEL_IMERGE> *im1, List<SEL_IMERGE> *im2)
 
326
inline void imerge_list_and_list(List<optimizer::SEL_IMERGE> *im1, List<optimizer::SEL_IMERGE> *im2)
937
327
{
938
328
  im1->concat(im2);
939
329
}
940
330
 
941
331
 
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
 
 
953
 
    If (a_1||b_1) produce a condition that is always true, NULL is returned
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
332
/***************************************************************************
1001
 
** Basic functions for SQL_SELECT and QUICK_RANGE_SELECT
 
333
** Basic functions for SqlSelect and QuickRangeSelect
1002
334
***************************************************************************/
1003
335
 
1004
336
        /* make a select from mysql info
1007
339
           1 = Got some error (out of memory?)
1008
340
           */
1009
341
 
1010
 
SQL_SELECT *make_select(Table *head, table_map const_tables,
1011
 
                        table_map read_tables, COND *conds,
1012
 
                        bool allow_null_cond,
1013
 
                        int *error)
 
342
optimizer::SqlSelect *optimizer::make_select(Table *head,
 
343
                                             table_map const_tables,
 
344
                                             table_map read_tables,
 
345
                                             COND *conds,
 
346
                                             bool allow_null_cond,
 
347
                                             int *error)
1014
348
{
1015
 
  SQL_SELECT *select;
1016
 
 
1017
 
  *error=0;
1018
 
 
1019
 
  if (!conds && !allow_null_cond)
 
349
  *error= 0;
 
350
 
 
351
  if (! conds && ! allow_null_cond)
 
352
  {
1020
353
    return 0;
1021
 
  if (!(select= new SQL_SELECT))
1022
 
  {
1023
 
    *error= 1;                  // out of memory
1024
 
    return 0;           /* purecov: inspected */
1025
354
  }
 
355
  optimizer::SqlSelect* select= new optimizer::SqlSelect;
1026
356
  select->read_tables=read_tables;
1027
357
  select->const_tables=const_tables;
1028
358
  select->head=head;
1030
360
 
1031
361
  if (head->sort.io_cache)
1032
362
  {
1033
 
    select->file= *head->sort.io_cache;
1034
 
    select->records=(ha_rows) (select->file.end_of_file/
1035
 
                               head->file->ref_length);
 
363
    memcpy(select->file, head->sort.io_cache, sizeof(internal::io_cache_st));
 
364
    select->records=(ha_rows) (select->file->end_of_file/
 
365
                               head->cursor->ref_length);
1036
366
    delete head->sort.io_cache;
1037
367
    head->sort.io_cache=0;
1038
368
  }
1040
370
}
1041
371
 
1042
372
 
1043
 
SQL_SELECT::SQL_SELECT() :quick(0),cond(0),free_cond(0)
 
373
optimizer::SqlSelect::SqlSelect()
 
374
  :
 
375
    quick(NULL),
 
376
    cond(NULL),
 
377
    file(static_cast<internal::io_cache_st *>(memory::sql_calloc(sizeof(internal::io_cache_st)))),
 
378
    free_cond(false)
1044
379
{
1045
 
  quick_keys.clear_all(); needed_reg.clear_all();
1046
 
  my_b_clear(&file);
 
380
  quick_keys.reset();
 
381
  needed_reg.reset();
 
382
  file->clear();
1047
383
}
1048
384
 
1049
385
 
1050
 
void SQL_SELECT::cleanup()
 
386
void optimizer::SqlSelect::cleanup()
1051
387
{
1052
388
  delete quick;
1053
 
  quick= 0;
 
389
  quick= NULL;
 
390
 
1054
391
  if (free_cond)
1055
392
  {
1056
 
    free_cond=0;
 
393
    free_cond= 0;
1057
394
    delete cond;
1058
395
    cond= 0;
1059
396
  }
1060
 
  close_cached_file(&file);
 
397
  file->close_cached_file();
1061
398
}
1062
399
 
1063
400
 
1064
 
SQL_SELECT::~SQL_SELECT()
 
401
optimizer::SqlSelect::~SqlSelect()
1065
402
{
1066
403
  cleanup();
1067
404
}
1068
405
 
1069
406
 
1070
 
bool SQL_SELECT::check_quick(Session *session, bool force_quick_range,
1071
 
                             ha_rows limit)
 
407
bool optimizer::SqlSelect::check_quick(Session *session,
 
408
                                       bool force_quick_range,
 
409
                                       ha_rows limit)
1072
410
{
1073
411
  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
 
 
1086
 
QUICK_SELECT_I::QUICK_SELECT_I()
1087
 
  :max_used_key_length(0),
1088
 
   used_key_parts(0)
1089
 
{}
1090
 
 
1091
 
QUICK_RANGE_SELECT::QUICK_RANGE_SELECT(Session *session, Table *table, uint32_t key_nr,
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
 
 
1105
 
  /* 'session' is not accessible in QUICK_RANGE_SELECT::reset(). */
1106
 
  mrr_buf_size= session->variables.read_rnd_buff_size;
1107
 
  mrr_buf_desc= NULL;
1108
 
 
1109
 
  if (!no_alloc && !parent_alloc)
1110
 
  {
1111
 
    // Allocates everything through the internal memroot
1112
 
    init_sql_alloc(&alloc, session->variables.range_alloc_block_size, 0);
1113
 
    session->mem_root= &alloc;
1114
 
  }
1115
 
  else
1116
 
    memset(&alloc, 0, sizeof(alloc));
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?) */
1123
 
  if (!(bitmap= (my_bitmap_map*) malloc(head->s->column_bitmap_size)))
1124
 
  {
1125
 
    column_bitmap.bitmap= 0;
1126
 
    *create_error= 1;
1127
 
  }
1128
 
  else
1129
 
    bitmap_init(&column_bitmap, bitmap, head->s->fields, false);
1130
 
  return;
1131
 
}
1132
 
 
1133
 
 
1134
 
int QUICK_RANGE_SELECT::init()
1135
 
{
1136
 
  if (file->inited != handler::NONE)
1137
 
    file->ha_index_or_rnd_end();
1138
 
  return(file->ha_index_init(index, 1));
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 */
1154
 
    if (file)
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
 
      {
1164
 
        file->ha_external_lock(current_session, F_UNLCK);
1165
 
        file->close();
1166
 
        delete file;
1167
 
      }
1168
 
    }
1169
 
    delete_dynamic(&ranges); /* ranges are allocated in alloc */
1170
 
    free_root(&alloc,MYF(0));
1171
 
    free((char*) column_bitmap.bitmap);
1172
 
  }
1173
 
  head->column_bitmaps_set(save_read_set, save_write_set);
1174
 
  if (mrr_buf_desc)
1175
 
    free(mrr_buf_desc);
1176
 
  return;
1177
 
}
1178
 
 
1179
 
 
1180
 
QUICK_INDEX_MERGE_SELECT::QUICK_INDEX_MERGE_SELECT(Session *session_param,
1181
 
                                                   Table *table)
1182
 
  :pk_quick_select(NULL), session(session_param)
1183
 
{
1184
 
  index= MAX_KEY;
1185
 
  head= table;
1186
 
  memset(&read_record, 0, sizeof(read_record));
1187
 
  init_sql_alloc(&alloc, session->variables.range_alloc_block_size, 0);
1188
 
  return;
1189
 
}
1190
 
 
1191
 
int QUICK_INDEX_MERGE_SELECT::init()
1192
 
{
1193
 
  return 0;
1194
 
}
1195
 
 
1196
 
int QUICK_INDEX_MERGE_SELECT::reset()
1197
 
{
1198
 
  return(read_keys_and_merge());
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));
1226
 
  return;
1227
 
}
1228
 
 
1229
 
 
1230
 
QUICK_ROR_INTERSECT_SELECT::QUICK_ROR_INTERSECT_SELECT(Session *session_param,
1231
 
                                                       Table *table,
1232
 
                                                       bool retrieve_full_rows,
1233
 
                                                       MEM_ROOT *parent_alloc)
1234
 
  : cpk_quick(NULL), session(session_param), need_to_fetch_row(retrieve_full_rows),
1235
 
    scans_inited(false)
1236
 
{
1237
 
  index= MAX_KEY;
1238
 
  head= table;
1239
 
  record= head->record[0];
1240
 
  if (!parent_alloc)
1241
 
    init_sql_alloc(&alloc, session->variables.range_alloc_block_size, 0);
1242
 
  else
1243
 
    memset(&alloc, 0, sizeof(MEM_ROOT));
1244
 
  last_rowid= (unsigned char*) alloc_root(parent_alloc? parent_alloc : &alloc,
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 */
1262
 
  return(!last_rowid);
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()
1271
 
      reuse_handler If true, use head->file, otherwise create a separate
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;
1291
 
  Session *session;
1292
 
 
1293
 
  in_ror_merged_scan= 1;
1294
 
  if (reuse_handler)
1295
 
  {
1296
 
    if (init() || reset())
1297
 
    {
1298
 
      return 0;
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. */
1308
 
    return 0;
1309
 
  }
1310
 
 
1311
 
  session= head->in_use;
1312
 
  if (!(file= head->file->clone(session->mem_root)))
1313
 
  {
1314
 
    /*
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
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.
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
 
 
1328
 
  if (file->ha_external_lock(session, F_RDLCK))
1329
 
    goto failure;
1330
 
 
1331
 
  if (init() || reset())
1332
 
  {
1333
 
    file->ha_external_lock(session, F_UNLCK);
1334
 
    file->close();
1335
 
    goto failure;
1336
 
  }
1337
 
  free_file= true;
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
 
 
1360
 
  return 0;
1361
 
 
1362
 
failure:
1363
 
  head->column_bitmaps_set(save_read_set, save_write_set);
1364
 
  delete file;
1365
 
  file= save_file;
1366
 
  return 0;
1367
 
}
1368
 
 
1369
 
 
1370
 
void QUICK_RANGE_SELECT::save_last_pos()
1371
 
{
1372
 
  file->position(record);
1373
 
}
1374
 
 
1375
 
 
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()
1380
 
      reuse_handler If true, use head->file, otherwise create separate
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 */
1392
 
  assert(!need_to_fetch_row || reuse_handler);
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
 
    */
1400
 
    if (quick->init_ror_merged_scan(true))
1401
 
      return 0;
1402
 
    quick->file->extra(HA_EXTRA_KEYREAD_PRESERVE_FIELDS);
1403
 
  }
1404
 
  while ((quick= quick_it++))
1405
 
  {
1406
 
    if (quick->init_ror_merged_scan(false))
1407
 
      return 0;
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
 
  {
1415
 
    return 0;
1416
 
  }
1417
 
  return 0;
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
 
{
1432
 
  if (!scans_inited && init_ror_merged_scan(true))
1433
 
    return 0;
1434
 
  scans_inited= true;
1435
 
  List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
1436
 
  QUICK_RANGE_SELECT *quick;
1437
 
  while ((quick= it++))
1438
 
    quick->reset();
1439
 
  return 0;
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
1454
 
    false OK
1455
 
    true  Out of memory.
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();
1471
 
  return;
1472
 
}
1473
 
 
1474
 
 
1475
 
QUICK_ROR_UNION_SELECT::QUICK_ROR_UNION_SELECT(Session *session_param,
1476
 
                                               Table *table)
1477
 
  : session(session_param), scans_inited(false)
1478
 
{
1479
 
  index= MAX_KEY;
1480
 
  head= table;
1481
 
  rowid_length= table->file->ref_length;
1482
 
  record= head->record[0];
1483
 
  init_sql_alloc(&alloc, session->variables.range_alloc_block_size, 0);
1484
 
  session_param->mem_root= &alloc;
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,
1501
 
                 false , QUICK_ROR_UNION_SELECT::queue_cmp,
1502
 
                 (void*) this))
1503
 
  {
1504
 
    memset(&queue, 0, sizeof(QUEUE));
1505
 
    return 0;
1506
 
  }
1507
 
 
1508
 
  if (!(cur_rowid= (unsigned char*) alloc_root(&alloc, 2*head->file->ref_length)))
1509
 
    return 0;
1510
 
  prev_rowid= cur_rowid + head->file->ref_length;
1511
 
  return 0;
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
 
 
1526
 
int QUICK_ROR_UNION_SELECT::queue_cmp(void *arg, unsigned char *val1, unsigned char *val2)
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;
1548
 
  have_prev_rowid= false;
1549
 
  if (!scans_inited)
1550
 
  {
1551
 
    List_iterator_fast<QUICK_SELECT_I> it(quick_selects);
1552
 
    while ((quick= it++))
1553
 
    {
1554
 
      if (quick->init_ror_merged_scan(false))
1555
 
        return 0;
1556
 
    }
1557
 
    scans_inited= true;
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())
1568
 
      return 0;
1569
 
    if ((error= quick->get_next()))
1570
 
    {
1571
 
      if (error == HA_ERR_END_OF_FILE)
1572
 
        continue;
1573
 
      return(error);
1574
 
    }
1575
 
    quick->save_last_pos();
1576
 
    queue_insert(&queue, (unsigned char*)quick);
1577
 
  }
1578
 
 
1579
 
  if (head->file->ha_rnd_init(1))
1580
 
  {
1581
 
    return 0;
1582
 
  }
1583
 
 
1584
 
  return 0;
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));
1601
 
  return;
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
 
 
1635
 
SEL_ARG::SEL_ARG(Field *f,const unsigned char *min_value_arg,
1636
 
                 const unsigned char *max_value_arg)
1637
 
  :min_flag(0), max_flag(0), maybe_flag(0), maybe_null(f->real_maybe_null()),
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),
1640
 
   next_key_part(0),color(BLACK),type(KEY_RANGE)
1641
 
{
1642
 
  left=right= &null_element;
1643
 
}
1644
 
 
1645
 
SEL_ARG::SEL_ARG(Field *field_,uint8_t part_,
1646
 
                 unsigned char *min_value_, unsigned char *max_value_,
1647
 
                 uint8_t min_flag_,uint8_t max_flag_,uint8_t maybe_flag_)
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
 
 
1656
 
SEL_ARG *SEL_ARG::clone(RANGE_OPT_PARAM *param, SEL_ARG *new_parent,
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
 
 
1724
 
static int sel_cmp(Field *field, unsigned char *a, unsigned char *b, uint8_t a_flag,
1725
 
                   uint8_t b_flag)
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
 
}
 
412
  tmp.set();
 
413
  return (test_quick_select(session,
 
414
                           tmp,
 
415
                           0,
 
416
                           limit,
 
417
                           force_quick_range,
 
418
                           false) < 0);
 
419
}
 
420
 
 
421
 
 
422
bool optimizer::SqlSelect::skip_record()
 
423
{
 
424
  return (cond ? cond->val_int() == 0 : 0);
 
425
}
 
426
 
 
427
 
 
428
optimizer::QuickSelectInterface::QuickSelectInterface()
 
429
  :
 
430
    max_used_key_length(0),
 
431
    used_key_parts(0)
 
432
{}
1780
433
 
1781
434
 
1782
435
/*
1808
461
    MAX_KEY if no such index was found.
1809
462
*/
1810
463
 
1811
 
uint32_t get_index_for_order(Table *table, order_st *order, ha_rows limit)
 
464
uint32_t optimizer::get_index_for_order(Table *table, Order *order, ha_rows limit)
1812
465
{
1813
466
  uint32_t idx;
1814
467
  uint32_t match_key= MAX_KEY, match_key_len= MAX_KEY_LENGTH + 1;
1815
 
  order_st *ord;
 
468
  Order *ord;
1816
469
 
1817
470
  for (ord= order; ord; ord= ord->next)
1818
471
    if (!ord->asc)
1819
472
      return MAX_KEY;
1820
473
 
1821
 
  for (idx= 0; idx < table->s->keys; idx++)
 
474
  for (idx= 0; idx < table->getShare()->sizeKeys(); idx++)
1822
475
  {
1823
 
    if (!(table->keys_in_use_for_query.is_set(idx)))
 
476
    if (!(table->keys_in_use_for_query.test(idx)))
1824
477
      continue;
1825
 
    KEY_PART_INFO *keyinfo= table->key_info[idx].key_part;
 
478
    KeyPartInfo *keyinfo= table->key_info[idx].key_part;
1826
479
    uint32_t n_parts=  table->key_info[idx].key_parts;
1827
480
    uint32_t partno= 0;
1828
481
 
1831
484
      indexes (records are returned in order for any index prefix) or HASH
1832
485
      indexes (records are not returned in order for any index prefix).
1833
486
    */
1834
 
    if (!(table->file->index_flags(idx, 0, 1) & HA_READ_ORDER))
 
487
    if (! (table->index_flags(idx) & HA_READ_ORDER))
1835
488
      continue;
1836
489
    for (ord= order; ord && partno < n_parts; ord= ord->next, partno++)
1837
490
    {
1838
491
      Item *item= order->item[0];
1839
 
      if (!(item->type() == Item::FIELD_ITEM &&
 
492
      if (! (item->type() == Item::FIELD_ITEM &&
1840
493
           ((Item_field*)item)->field->eq(keyinfo[partno].field)))
1841
494
        break;
1842
495
    }
1843
496
 
1844
 
    if (!ord && table->key_info[idx].key_length < match_key_len)
 
497
    if (! ord && table->key_info[idx].key_length < match_key_len)
1845
498
    {
1846
499
      /*
1847
500
        Ok, the ordering is compatible and this key is shorter then
1860
513
      order. Now we'll check if using the index is cheaper then doing a table
1861
514
      scan.
1862
515
    */
1863
 
    double full_scan_time= table->file->scan_time();
1864
 
    double index_scan_time= table->file->read_time(match_key, 1, limit);
 
516
    double full_scan_time= table->cursor->scan_time();
 
517
    double index_scan_time= table->cursor->read_time(match_key, 1, limit);
1865
518
    if (index_scan_time > full_scan_time)
1866
519
      match_key= MAX_KEY;
1867
520
  }
1869
522
}
1870
523
 
1871
524
 
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
 
  /*
1887
 
    If true, the scan returns rows in rowid order. This is used only for
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
1897
 
       retrieve_full_rows  If true, created quick select will do full record
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)
1914
 
  { return (void*) alloc_root(mem_root, (uint) size); }
1915
 
  static void operator delete(void *, size_t)
1916
 
    { TRASH(ptr, size); }
1917
 
  static void operator delete(void *, MEM_ROOT *)
1918
 
    { /* Never called */ }
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 */
1939
 
  uint32_t     key_idx; /* key number in PARAM::key */
1940
 
  uint32_t     mrr_flags;
1941
 
  uint32_t     mrr_buf_size;
1942
 
 
1943
 
  TRP_RANGE(SEL_ARG *key_arg, uint32_t idx_arg, uint32_t mrr_flags_arg)
1944
 
   : key(key_arg), key_idx(idx_arg), mrr_flags(mrr_flags_arg)
1945
 
  {}
1946
 
  virtual ~TRP_RANGE() {}                     /* Remove gcc warning */
1947
 
 
1948
 
  QUICK_SELECT_I *make_quick(PARAM *param, bool, MEM_ROOT *parent_alloc)
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
 
    }
1957
 
    return quick;
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 */
1976
 
  bool is_covering; /* true if no row retrieval phase is necessary */
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
 
/*
2018
 
  Plan for a QUICK_GROUP_MIN_MAX_SELECT scan.
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;
2026
 
  uint32_t group_prefix_len;
2027
 
  uint32_t used_key_parts;
2028
 
  uint32_t group_key_parts;
2029
 
  KEY *index_info;
2030
 
  uint32_t index;
2031
 
  uint32_t key_infix_len;
2032
 
  unsigned char key_infix[MAX_KEY_LENGTH];
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. */
2035
 
  uint32_t param_idx; /* Index of used key in param->key. */
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,
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,
2045
 
                    unsigned char *key_infix_arg,
2046
 
                    SEL_TREE *tree_arg, SEL_ARG *index_tree_arg,
2047
 
                    uint32_t param_idx_arg, ha_rows quick_prefix_records_arg)
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
525
 
2066
526
/*
2067
527
  Fill param->needed_fields with bitmap of fields used in the query.
2077
537
    1  Out of memory.
2078
538
*/
2079
539
 
2080
 
static int fill_used_fields_bitmap(PARAM *param)
 
540
static int fill_used_fields_bitmap(optimizer::Parameter *param)
2081
541
{
2082
542
  Table *table= param->table;
2083
 
  my_bitmap_map *tmp;
2084
543
  uint32_t pk;
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)) ||
2089
 
      bitmap_init(&param->needed_fields, tmp, table->s->fields, false))
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())
 
544
  param->tmp_covered_fields.clear();
 
545
  param->needed_fields.resize(table->getShare()->sizeFields());
 
546
  param->needed_fields.reset();
 
547
 
 
548
  param->needed_fields|= *table->read_set;
 
549
  param->needed_fields|= *table->write_set;
 
550
 
 
551
  pk= param->table->getShare()->getPrimaryKey();
 
552
  if (pk != MAX_KEY && param->table->cursor->primary_key_is_clustered())
2097
553
  {
2098
554
    /* 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 +
 
555
    KeyPartInfo *key_part= param->table->key_info[pk].key_part;
 
556
    KeyPartInfo *key_part_end= key_part +
2101
557
                                 param->table->key_info[pk].key_parts;
2102
558
    for (;key_part != key_part_end; ++key_part)
2103
 
      bitmap_clear_bit(&param->needed_fields, key_part->fieldnr-1);
 
559
      param->needed_fields.reset(key_part->fieldnr-1);
2104
560
  }
2105
561
  return 0;
2106
562
}
2110
566
  Test if a key can be used in different ranges
2111
567
 
2112
568
  SYNOPSIS
2113
 
    SQL_SELECT::test_quick_select()
 
569
    SqlSelect::test_quick_select()
2114
570
      session               Current thread
2115
571
      keys_to_use       Keys to use for range retrieval
2116
572
      prev_tables       Tables assumed to be already read when the scan is
2172
628
    1 if found usable ranges and quick select has been successfully created.
2173
629
*/
2174
630
 
2175
 
int SQL_SELECT::test_quick_select(Session *session, key_map keys_to_use,
2176
 
                                  table_map prev_tables,
2177
 
                                  ha_rows limit, bool force_quick_range,
2178
 
                                  bool ordered_output)
 
631
int optimizer::SqlSelect::test_quick_select(Session *session,
 
632
                                            key_map keys_to_use,
 
633
                                                                    table_map prev_tables,
 
634
                                                                    ha_rows limit,
 
635
                                            bool force_quick_range,
 
636
                                            bool ordered_output)
2179
637
{
2180
638
  uint32_t idx;
2181
639
  double scan_time;
 
640
 
2182
641
  delete quick;
2183
 
  quick=0;
2184
 
  needed_reg.clear_all();
2185
 
  quick_keys.clear_all();
2186
 
  if (keys_to_use.is_clear_all())
 
642
  quick= NULL;
 
643
 
 
644
  needed_reg.reset();
 
645
  quick_keys.reset();
 
646
  if (keys_to_use.none())
2187
647
    return 0;
2188
 
  records= head->file->stats.records;
 
648
  records= head->cursor->stats.records;
2189
649
  if (!records)
2190
 
    records++;                                  /* purecov: inspected */
 
650
    records++;
2191
651
  scan_time= (double) records / TIME_FOR_COMPARE + 1;
2192
 
  read_time= (double) head->file->scan_time() + scan_time + 1.1;
 
652
  read_time= (double) head->cursor->scan_time() + scan_time + 1.1;
2193
653
  if (head->force_index)
2194
654
    scan_time= read_time= DBL_MAX;
2195
655
  if (limit < records)
2197
657
  else if (read_time <= 2.0 && !force_quick_range)
2198
658
    return 0;                           /* No need for quick select */
2199
659
 
2200
 
  keys_to_use.intersect(head->keys_in_use_for_query);
2201
 
  if (!keys_to_use.is_clear_all())
 
660
  keys_to_use&= head->keys_in_use_for_query;
 
661
  if (keys_to_use.any())
2202
662
  {
2203
 
    MEM_ROOT alloc;
2204
 
    SEL_TREE *tree= NULL;
 
663
    memory::Root alloc;
 
664
    optimizer::SEL_TREE *tree= NULL;
2205
665
    KEY_PART *key_parts;
2206
 
    KEY *key_info;
2207
 
    PARAM param;
 
666
    KeyInfo *key_info;
 
667
    optimizer::Parameter param;
2208
668
 
2209
669
    if (check_stack_overrun(session, 2*STACK_MIN_SIZE, NULL))
2210
670
      return 0;                           // Fatal error flag is set
2211
671
 
2212
672
    /* set up parameter that is passed to all functions */
2213
673
    param.session= session;
2214
 
    param.baseflag= head->file->ha_table_flags();
2215
 
    param.prev_tables=prev_tables | const_tables;
2216
 
    param.read_tables=read_tables;
 
674
    param.prev_tables= prev_tables | const_tables;
 
675
    param.read_tables= read_tables;
2217
676
    param.current_table= head->map;
2218
677
    param.table=head;
2219
678
    param.keys=0;
2226
685
    param.force_default_mrr= ordered_output;
2227
686
 
2228
687
    session->no_errors=1;                               // Don't warn about NULL
2229
 
    init_sql_alloc(&alloc, session->variables.range_alloc_block_size, 0);
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))
 
688
    alloc.init(session->variables.range_alloc_block_size);
 
689
    param.key_parts= new (alloc) KEY_PART[head->getShare()->key_parts];
 
690
    if (fill_used_fields_bitmap(&param))
2234
691
    {
2235
692
      session->no_errors=0;
2236
 
      free_root(&alloc,MYF(0));                 // Return memory & allocator
 
693
      alloc.free_root(MYF(0));                  // Return memory & allocator
 
694
 
2237
695
      return 0;                         // Can't use range
2238
696
    }
2239
697
    key_parts= param.key_parts;
2244
702
      This is used in get_mm_parts function.
2245
703
    */
2246
704
    key_info= head->key_info;
2247
 
    for (idx=0 ; idx < head->s->keys ; idx++, key_info++)
 
705
    for (idx=0 ; idx < head->getShare()->sizeKeys() ; idx++, key_info++)
2248
706
    {
2249
 
      KEY_PART_INFO *key_part_info;
2250
 
      if (!keys_to_use.is_set(idx))
 
707
      KeyPartInfo *key_part_info;
 
708
      if (! keys_to_use.test(idx))
2251
709
        continue;
2252
710
 
2253
711
      param.key[param.keys]=key_parts;
2254
712
      key_part_info= key_info->key_part;
2255
 
      for (uint32_t part=0 ; part < key_info->key_parts ;
2256
 
           part++, key_parts++, key_part_info++)
 
713
      for (uint32_t part=0;
 
714
           part < key_info->key_parts;
 
715
           part++, key_parts++, key_part_info++)
2257
716
      {
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;
 
717
        key_parts->key= param.keys;
 
718
        key_parts->part= part;
 
719
        key_parts->length= key_part_info->length;
 
720
        key_parts->store_length= key_part_info->store_length;
 
721
        key_parts->field= key_part_info->field;
 
722
        key_parts->null_bit= key_part_info->null_bit;
2265
723
        /* Only HA_PART_KEY_SEG is used */
2266
 
        key_parts->flag=         (uint8_t) key_part_info->key_part_flag;
 
724
        key_parts->flag= (uint8_t) key_part_info->key_part_flag;
2267
725
      }
2268
726
      param.real_keynr[param.keys++]=idx;
2269
727
    }
2271
729
    param.alloced_sel_args= 0;
2272
730
 
2273
731
    /* Calculate cost of full index read for the shortest covering index */
2274
 
    if (!head->covering_keys.is_clear_all())
 
732
    if (!head->covering_keys.none())
2275
733
    {
2276
734
      int key_for_use= head->find_shortest_key(&head->covering_keys);
2277
735
      double key_read_time=
2278
 
        param.table->file->index_only_read_time(key_for_use,
2279
 
                                                rows2double(records)) +
 
736
        param.table->cursor->index_only_read_time(key_for_use, records) +
2280
737
        (double) records / TIME_FOR_COMPARE;
2281
738
      if (key_read_time < read_time)
2282
739
        read_time= key_read_time;
2283
740
    }
2284
741
 
2285
 
    TABLE_READ_PLAN *best_trp= NULL;
2286
 
    TRP_GROUP_MIN_MAX *group_trp;
 
742
    optimizer::TableReadPlan *best_trp= NULL;
 
743
    optimizer::GroupMinMaxReadPlan *group_trp= NULL;
2287
744
    double best_read_time= read_time;
2288
745
 
2289
746
    if (cond)
2290
747
    {
2291
748
      if ((tree= get_mm_tree(&param,cond)))
2292
749
      {
2293
 
        if (tree->type == SEL_TREE::IMPOSSIBLE)
 
750
        if (tree->type == optimizer::SEL_TREE::IMPOSSIBLE)
2294
751
        {
2295
752
          records=0L;                      /* Return -1 from this function. */
2296
753
          read_time= (double) HA_POS_ERROR;
2300
757
          If the tree can't be used for range scans, proceed anyway, as we
2301
758
          can construct a group-min-max quick select
2302
759
        */
2303
 
        if (tree->type != SEL_TREE::KEY && tree->type != SEL_TREE::KEY_SMALLER)
 
760
        if (tree->type != optimizer::SEL_TREE::KEY && tree->type != optimizer::SEL_TREE::KEY_SMALLER)
2304
761
          tree= NULL;
2305
762
      }
2306
763
    }
2307
764
 
2308
765
    /*
2309
 
      Try to construct a QUICK_GROUP_MIN_MAX_SELECT.
 
766
      Try to construct a QuickGroupMinMaxSelect.
2310
767
      Notice that it can be constructed no matter if there is a range tree.
2311
768
    */
2312
769
    group_trp= get_best_group_min_max(&param, tree);
2313
770
    if (group_trp)
2314
771
    {
2315
 
      param.table->quick_condition_rows= cmin(group_trp->records,
2316
 
                                             head->file->stats.records);
 
772
      param.table->quick_condition_rows= min(group_trp->records,
 
773
                                             head->cursor->stats.records);
2317
774
      if (group_trp->read_cost < best_read_time)
2318
775
      {
2319
776
        best_trp= group_trp;
2329
786
      */
2330
787
      if (tree->merges.is_empty())
2331
788
      {
2332
 
        TRP_RANGE         *range_trp;
2333
 
        TRP_ROR_INTERSECT *rori_trp;
 
789
        optimizer::RangeReadPlan *range_trp= NULL;
 
790
        optimizer::RorIntersectReadPlan *rori_trp= NULL;
2334
791
        bool can_build_covering= false;
2335
792
 
2336
793
        /* Get best 'range' plan and prepare data for making other plans */
2337
 
        if ((range_trp= get_key_scans_params(&param, tree, false, true,
 
794
        if ((range_trp= get_key_scans_params(session, &param, tree, false, true,
2338
795
                                             best_read_time)))
2339
796
        {
2340
797
          best_trp= range_trp;
2342
799
        }
2343
800
 
2344
801
        /*
2345
 
          Simultaneous key scans and row deletes on several handler
 
802
          Simultaneous key scans and row deletes on several Cursor
2346
803
          objects are not allowed so don't use ROR-intersection for
2347
804
          table deletes.
2348
805
        */
2349
 
        if ((session->lex->sql_command != SQLCOM_DELETE))
 
806
        if ((session->lex().sql_command != SQLCOM_DELETE))
2350
807
        {
2351
808
          /*
2352
809
            Get best non-covering ROR-intersection plan and prepare data for
2371
828
      else
2372
829
      {
2373
830
        /* 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);
 
831
        optimizer::SEL_IMERGE *imerge= NULL;
 
832
        optimizer::TableReadPlan *best_conj_trp= NULL;
 
833
        optimizer::TableReadPlan *new_conj_trp= NULL;
 
834
        List<optimizer::SEL_IMERGE>::iterator it(tree->merges.begin());
2377
835
        while ((imerge= it++))
2378
836
        {
2379
 
          new_conj_trp= get_best_disjunct_quick(&param, imerge, best_read_time);
 
837
          new_conj_trp= get_best_disjunct_quick(session, &param, imerge, best_read_time);
2380
838
          if (new_conj_trp)
2381
839
            set_if_smaller(param.table->quick_condition_rows,
2382
840
                           new_conj_trp->records);
2395
853
    if (best_trp)
2396
854
    {
2397
855
      records= best_trp->records;
2398
 
      if (!(quick= best_trp->make_quick(&param, true)) || quick->init())
 
856
      if (! (quick= best_trp->make_quick(&param, true)) || quick->init())
2399
857
      {
2400
858
        delete quick;
2401
859
        quick= NULL;
2403
861
    }
2404
862
 
2405
863
  free_mem:
2406
 
    free_root(&alloc,MYF(0));                   // Return memory & allocator
 
864
    alloc.free_root(MYF(0));                    // Return memory & allocator
2407
865
    session->mem_root= param.old_root;
2408
866
    session->no_errors=0;
2409
867
  }
2416
874
}
2417
875
 
2418
876
/*
2419
 
  Get best plan for a SEL_IMERGE disjunctive expression.
 
877
  Get best plan for a optimizer::SEL_IMERGE disjunctive expression.
2420
878
  SYNOPSIS
2421
879
    get_best_disjunct_quick()
 
880
      session
2422
881
      param     Parameter from check_quick_select function
2423
882
      imerge    Expression to use
2424
883
      read_time Don't create scans with cost > read_time
2442
901
          {cost of ordinary clustered PK scan with n_ranges=n_rows}
2443
902
 
2444
903
      Otherwise, we use the following model to calculate costs:
2445
 
      We need to retrieve n_rows rows from file that occupies n_blocks blocks.
 
904
      We need to retrieve n_rows rows from cursor that occupies n_blocks blocks.
2446
905
      We assume that offsets of rows we need are independent variates with
2447
906
      uniform distribution in [0..max_file_offset] range.
2448
907
 
2450
909
      and "empty" if doesn't contain rows we need.
2451
910
 
2452
911
      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
 
912
      applies to any block in cursor). Let x_i be a variate taking value 1 if
2454
913
      block #i is empty and 0 otherwise.
2455
914
 
2456
915
      Then E(x_i) = (1 - 1/n_blocks)^n_rows;
2481
940
*/
2482
941
 
2483
942
static
2484
 
TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
2485
 
                                         double read_time)
 
943
optimizer::TableReadPlan *get_best_disjunct_quick(Session *session,
 
944
                                                  optimizer::Parameter *param,
 
945
                                                  optimizer::SEL_IMERGE *imerge,
 
946
                                                  double read_time)
2486
947
{
2487
 
  SEL_TREE **ptree;
2488
 
  TRP_INDEX_MERGE *imerge_trp= NULL;
 
948
  optimizer::SEL_TREE **ptree= NULL;
 
949
  optimizer::IndexMergeReadPlan *imerge_trp= NULL;
2489
950
  uint32_t n_child_scans= imerge->trees_next - imerge->trees;
2490
 
  TRP_RANGE **range_scans;
2491
 
  TRP_RANGE **cur_child;
2492
 
  TRP_RANGE **cpk_scan= NULL;
 
951
  optimizer::RangeReadPlan **range_scans= NULL;
 
952
  optimizer::RangeReadPlan **cur_child= NULL;
 
953
  optimizer::RangeReadPlan **cpk_scan= NULL;
2493
954
  bool imerge_too_expensive= false;
2494
955
  double imerge_cost= 0.0;
2495
956
  ha_rows cpk_scan_records= 0;
2496
957
  ha_rows non_cpk_scan_records= 0;
2497
 
  bool pk_is_clustered= param->table->file->primary_key_is_clustered();
 
958
  bool pk_is_clustered= param->table->cursor->primary_key_is_clustered();
2498
959
  bool all_scans_ror_able= true;
2499
960
  bool all_scans_rors= true;
2500
961
  uint32_t unique_calc_buff_size;
2501
 
  TABLE_READ_PLAN **roru_read_plans;
2502
 
  TABLE_READ_PLAN **cur_roru_plan;
 
962
  optimizer::TableReadPlan **roru_read_plans= NULL;
 
963
  optimizer::TableReadPlan **cur_roru_plan= NULL;
2503
964
  double roru_index_costs;
2504
965
  ha_rows roru_total_records;
2505
966
  double roru_intersect_part= 1.0;
2506
967
 
2507
 
  if (!(range_scans= (TRP_RANGE**)alloc_root(param->mem_root,
2508
 
                                             sizeof(TRP_RANGE*)*
2509
 
                                             n_child_scans)))
2510
 
    return NULL;
 
968
  range_scans= new (*param->mem_root) optimizer::RangeReadPlan*[n_child_scans];
 
969
 
2511
970
  /*
2512
971
    Collect best 'range' scan for each of disjuncts, and, while doing so,
2513
972
    analyze possibility of ROR scans. Also calculate some values needed by
2514
973
    other parts of the code.
2515
974
  */
2516
 
  for (ptree= imerge->trees, cur_child= range_scans;
2517
 
       ptree != imerge->trees_next;
2518
 
       ptree++, cur_child++)
 
975
  for (ptree= imerge->trees, cur_child= range_scans; ptree != imerge->trees_next; ptree++, cur_child++)
2519
976
  {
2520
 
    print_sel_tree(param, *ptree, &(*ptree)->keys_map, "tree in SEL_IMERGE");
2521
 
    if (!(*cur_child= get_key_scans_params(param, *ptree, true, false, read_time)))
 
977
    if (!(*cur_child= get_key_scans_params(session, param, *ptree, true, false, read_time)))
2522
978
    {
2523
979
      /*
2524
980
        One of index scans in this index_merge is more expensive than entire
2525
981
        table read for another available option. The entire index_merge (and
2526
982
        any possible ROR-union) will be more expensive then, too. We continue
2527
 
        here only to update SQL_SELECT members.
 
983
        here only to update SqlSelect members.
2528
984
      */
2529
985
      imerge_too_expensive= true;
2530
986
    }
2536
992
    all_scans_rors &= (*cur_child)->is_ror;
2537
993
    if (pk_is_clustered &&
2538
994
        param->real_keynr[(*cur_child)->key_idx] ==
2539
 
        param->table->s->primary_key)
 
995
        param->table->getShare()->getPrimaryKey())
2540
996
    {
2541
997
      cpk_scan= cur_child;
2542
998
      cpk_scan_records= (*cur_child)->records;
2546
1002
  }
2547
1003
 
2548
1004
  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))
 
1005
      ((non_cpk_scan_records+cpk_scan_records >= param->table->cursor->stats.records) && read_time != DBL_MAX))
2550
1006
  {
2551
1007
    /*
2552
1008
      Bail out if it is obvious that both index_merge and ROR-union will be
2556
1012
  }
2557
1013
  if (all_scans_rors)
2558
1014
  {
2559
 
    roru_read_plans= (TABLE_READ_PLAN**)range_scans;
 
1015
    roru_read_plans= (optimizer::TableReadPlan **) range_scans;
2560
1016
    goto skip_to_ror_scan;
2561
1017
  }
2562
1018
  if (cpk_scan)
2563
1019
  {
2564
1020
    /*
2565
1021
      Add one ROWID comparison for each row retrieved on non-CPK scan.  (it
2566
 
      is done in QUICK_RANGE_SELECT::row_in_ranges)
 
1022
      is done in QuickRangeSelect::row_in_ranges)
2567
1023
     */
2568
1024
    imerge_cost += non_cpk_scan_records / TIME_FOR_COMPARE_ROWID;
2569
1025
  }
2570
1026
 
2571
1027
  /* Calculate cost(rowid_to_row_scan) */
2572
1028
  {
2573
 
    COST_VECT sweep_cost;
2574
 
    JOIN *join= param->session->lex->select_lex.join;
 
1029
    optimizer::CostVector sweep_cost;
 
1030
    Join *join= param->session->lex().select_lex.join;
2575
1031
    bool is_interrupted= test(join && join->tables == 1);
2576
1032
    get_sweep_read_cost(param->table, non_cpk_scan_records, is_interrupted,
2577
1033
                        &sweep_cost);
2583
1039
  /* Add Unique operations cost */
2584
1040
  unique_calc_buff_size=
2585
1041
    Unique::get_cost_calc_buff_size((ulong)non_cpk_scan_records,
2586
 
                                    param->table->file->ref_length,
 
1042
                                    param->table->cursor->ref_length,
2587
1043
                                    param->session->variables.sortbuff_size);
2588
1044
  if (param->imerge_cost_buff_size < unique_calc_buff_size)
2589
1045
  {
2590
 
    if (!(param->imerge_cost_buff= (uint*)alloc_root(param->mem_root,
2591
 
                                                     unique_calc_buff_size)))
2592
 
      return NULL;
 
1046
    param->imerge_cost_buff= (uint*)param->mem_root->alloc(unique_calc_buff_size);
2593
1047
    param->imerge_cost_buff_size= unique_calc_buff_size;
2594
1048
  }
2595
1049
 
2596
1050
  imerge_cost +=
2597
 
    Unique::get_use_cost(param->imerge_cost_buff, (uint)non_cpk_scan_records,
2598
 
                         param->table->file->ref_length,
 
1051
    Unique::get_use_cost(param->imerge_cost_buff, (uint32_t)non_cpk_scan_records,
 
1052
                         param->table->cursor->ref_length,
2599
1053
                         param->session->variables.sortbuff_size);
2600
1054
  if (imerge_cost < read_time)
2601
1055
  {
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;
2606
 
      imerge_trp->records= cmin(imerge_trp->records,
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
 
    }
 
1056
    imerge_trp= new (*param->mem_root) optimizer::IndexMergeReadPlan;
 
1057
    imerge_trp->read_cost= imerge_cost;
 
1058
    imerge_trp->records= non_cpk_scan_records + cpk_scan_records;
 
1059
    imerge_trp->records= min(imerge_trp->records, param->table->cursor->stats.records);
 
1060
    imerge_trp->range_scans= range_scans;
 
1061
    imerge_trp->range_scans_end= range_scans + n_child_scans;
 
1062
    read_time= imerge_cost;
2612
1063
  }
2613
1064
 
2614
1065
build_ror_index_merge:
2615
 
  if (!all_scans_ror_able || param->session->lex->sql_command == SQLCOM_DELETE)
 
1066
  if (!all_scans_ror_able || param->session->lex().sql_command == SQLCOM_DELETE)
2616
1067
    return(imerge_trp);
2617
1068
 
2618
1069
  /* Ok, it is possible to build a ROR-union, try it. */
2619
1070
  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)))
2624
 
    return(imerge_trp);
 
1071
  roru_read_plans= new (*param->mem_root) optimizer::TableReadPlan*[n_child_scans];
2625
1072
skip_to_ror_scan:
2626
1073
  roru_index_costs= 0.0;
2627
1074
  roru_total_records= 0;
2642
1089
    if ((*cur_child)->is_ror)
2643
1090
    {
2644
1091
      /* Ok, we have index_only cost, now get full rows scan cost */
2645
 
      cost= param->table->file->
 
1092
      cost= param->table->cursor->
2646
1093
              read_time(param->real_keynr[(*cur_child)->key_idx], 1,
2647
1094
                        (*cur_child)->records) +
2648
 
              rows2double((*cur_child)->records) / TIME_FOR_COMPARE;
 
1095
              static_cast<double>((*cur_child)->records) / TIME_FOR_COMPARE;
2649
1096
    }
2650
1097
    else
2651
1098
      cost= read_time;
2652
1099
 
2653
 
    TABLE_READ_PLAN *prev_plan= *cur_child;
 
1100
    optimizer::TableReadPlan *prev_plan= *cur_child;
2654
1101
    if (!(*cur_roru_plan= get_best_ror_intersect(param, *ptree, cost,
2655
1102
                                                 &dummy)))
2656
1103
    {
2662
1109
    }
2663
1110
    else
2664
1111
      roru_index_costs +=
2665
 
        ((TRP_ROR_INTERSECT*)(*cur_roru_plan))->index_scan_costs;
 
1112
        ((optimizer::RorIntersectReadPlan*)(*cur_roru_plan))->index_scan_costs;
2666
1113
    roru_total_records += (*cur_roru_plan)->records;
2667
1114
    roru_intersect_part *= (*cur_roru_plan)->records /
2668
 
                           param->table->file->stats.records;
 
1115
                           param->table->cursor->stats.records;
2669
1116
  }
2670
1117
 
2671
1118
  /*
2675
1122
    in disjunction do not share key parts.
2676
1123
  */
2677
1124
  roru_total_records -= (ha_rows)(roru_intersect_part*
2678
 
                                  param->table->file->stats.records);
 
1125
                                  param->table->cursor->stats.records);
2679
1126
  /* ok, got a ROR read plan for each of the disjuncts
2680
1127
    Calculate cost:
2681
1128
    cost(index_union_scan(scan_1, ... scan_n)) =
2686
1133
  */
2687
1134
  double roru_total_cost;
2688
1135
  {
2689
 
    COST_VECT sweep_cost;
2690
 
    JOIN *join= param->session->lex->select_lex.join;
 
1136
    optimizer::CostVector sweep_cost;
 
1137
    Join *join= param->session->lex().select_lex.join;
2691
1138
    bool is_interrupted= test(join && join->tables == 1);
2692
1139
    get_sweep_read_cost(param->table, roru_total_records, is_interrupted,
2693
1140
                        &sweep_cost);
2694
1141
    roru_total_cost= roru_index_costs +
2695
 
                     rows2double(roru_total_records)*log((double)n_child_scans) /
 
1142
                     static_cast<double>(roru_total_records)*log((double)n_child_scans) /
2696
1143
                     (TIME_FOR_COMPARE_ROWID * M_LN2) +
2697
1144
                     sweep_cost.total_cost();
2698
1145
  }
2699
1146
 
2700
 
  TRP_ROR_UNION* roru;
 
1147
  optimizer::RorUnionReadPlan *roru= NULL;
2701
1148
  if (roru_total_cost < read_time)
2702
1149
  {
2703
 
    if ((roru= new (param->mem_root) TRP_ROR_UNION))
 
1150
    if ((roru= new (*param->mem_root) optimizer::RorUnionReadPlan))
2704
1151
    {
2705
1152
      roru->first_ror= roru_read_plans;
2706
1153
      roru->last_ror= roru_read_plans + n_child_scans;
2707
1154
      roru->read_cost= roru_total_cost;
2708
1155
      roru->records= roru_total_records;
2709
 
      return(roru);
 
1156
      return roru;
2710
1157
    }
2711
1158
  }
2712
1159
  return(imerge_trp);
2713
1160
}
2714
1161
 
2715
1162
 
2716
 
typedef struct st_ror_scan_info
2717
 
{
2718
 
  uint32_t      idx;      /* # of used key in param->keys */
2719
 
  uint32_t      keynr;    /* # of used key in table */
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;
2727
 
  uint32_t      used_fields_covered; /* # of set bits in covered_fields */
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;
2735
 
  uint32_t      first_uncovered_field; /* first unused bit in covered_fields */
2736
 
  uint32_t      key_components; /* # of parts in the key */
2737
 
} ROR_SCAN_INFO;
2738
 
 
2739
1163
 
2740
1164
/*
2741
 
  Create ROR_SCAN_INFO* structure with a single ROR scan on index idx using
 
1165
  Create optimizer::RorScanInfo* structure with a single ROR scan on index idx using
2742
1166
  sel_arg set of intervals.
2743
1167
 
2744
1168
  SYNOPSIS
2753
1177
*/
2754
1178
 
2755
1179
static
2756
 
ROR_SCAN_INFO *make_ror_scan(const PARAM *param, int idx, SEL_ARG *sel_arg)
 
1180
optimizer::RorScanInfo *make_ror_scan(const optimizer::Parameter *param, int idx, optimizer::SEL_ARG *sel_arg)
2757
1181
{
2758
 
  ROR_SCAN_INFO *ror_scan;
2759
 
  my_bitmap_map *bitmap_buf;
2760
1182
  uint32_t keynr;
2761
 
 
2762
 
  if (!(ror_scan= (ROR_SCAN_INFO*)alloc_root(param->mem_root,
2763
 
                                             sizeof(ROR_SCAN_INFO))))
2764
 
    return NULL;
 
1183
  optimizer::RorScanInfo* ror_scan= new (*param->mem_root) optimizer::RorScanInfo;
2765
1184
 
2766
1185
  ror_scan->idx= idx;
2767
1186
  ror_scan->keynr= keynr= param->real_keynr[idx];
2768
1187
  ror_scan->key_rec_length= (param->table->key_info[keynr].key_length +
2769
 
                             param->table->file->ref_length);
 
1188
                             param->table->cursor->ref_length);
2770
1189
  ror_scan->sel_arg= sel_arg;
2771
1190
  ror_scan->records= param->table->quick_rows[keynr];
2772
1191
 
2773
 
  if (!(bitmap_buf= (my_bitmap_map*) alloc_root(param->mem_root,
2774
 
                                                param->fields_bitmap_size)))
2775
 
    return NULL;
2776
 
 
2777
 
  if (bitmap_init(&ror_scan->covered_fields, bitmap_buf,
2778
 
                  param->table->s->fields, false))
2779
 
    return NULL;
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 +
 
1192
  ror_scan->covered_fields_size= param->table->getShare()->sizeFields();
 
1193
  boost::dynamic_bitset<> tmp_bitset(param->table->getShare()->sizeFields());
 
1194
  tmp_bitset.reset();
 
1195
 
 
1196
  KeyPartInfo *key_part= param->table->key_info[keynr].key_part;
 
1197
  KeyPartInfo *key_part_end= key_part +
2784
1198
                               param->table->key_info[keynr].key_parts;
2785
 
  for (;key_part != key_part_end; ++key_part)
 
1199
  for (; key_part != key_part_end; ++key_part)
2786
1200
  {
2787
 
    if (bitmap_is_set(&param->needed_fields, key_part->fieldnr-1))
2788
 
      bitmap_set_bit(&ror_scan->covered_fields, key_part->fieldnr-1);
 
1201
    if (param->needed_fields.test(key_part->fieldnr-1))
 
1202
      tmp_bitset.set(key_part->fieldnr-1);
2789
1203
  }
2790
 
  double rows= rows2double(param->table->quick_rows[ror_scan->keynr]);
 
1204
  double rows= param->table->quick_rows[ror_scan->keynr];
2791
1205
  ror_scan->index_read_cost=
2792
 
    param->table->file->index_only_read_time(ror_scan->keynr, rows);
2793
 
  return(ror_scan);
 
1206
    param->table->cursor->index_only_read_time(ror_scan->keynr, rows);
 
1207
  ror_scan->covered_fields= tmp_bitset.to_ulong();
 
1208
  return ror_scan;
2794
1209
}
2795
1210
 
2796
1211
 
2797
1212
/*
2798
 
  Compare two ROR_SCAN_INFO** by  E(#records_matched) * key_record_length.
 
1213
  Compare two optimizer::RorScanInfo** by  E(#records_matched) * key_record_length.
2799
1214
  SYNOPSIS
2800
1215
    cmp_ror_scan_info()
2801
1216
      a ptr to first compared value
2807
1222
    1 a > b
2808
1223
*/
2809
1224
 
2810
 
static int cmp_ror_scan_info(ROR_SCAN_INFO** a, ROR_SCAN_INFO** b)
 
1225
static int cmp_ror_scan_info(optimizer::RorScanInfo** a, optimizer::RorScanInfo** b)
2811
1226
{
2812
 
  double val1= rows2double((*a)->records) * (*a)->key_rec_length;
2813
 
  double val2= rows2double((*b)->records) * (*b)->key_rec_length;
 
1227
  double val1= static_cast<double>((*a)->records) * (*a)->key_rec_length;
 
1228
  double val2= static_cast<double>((*b)->records) * (*b)->key_rec_length;
2814
1229
  return (val1 < val2)? -1: (val1 == val2)? 0 : 1;
2815
1230
}
2816
1231
 
 
1232
 
2817
1233
/*
2818
 
  Compare two ROR_SCAN_INFO** by
 
1234
  Compare two optimizer::RorScanInfo** by
2819
1235
   (#covered fields in F desc,
2820
1236
    #components asc,
2821
1237
    number of first not covered component asc)
2831
1247
    1 a > b
2832
1248
*/
2833
1249
 
2834
 
static int cmp_ror_scan_info_covering(ROR_SCAN_INFO** a, ROR_SCAN_INFO** b)
 
1250
static int cmp_ror_scan_info_covering(optimizer::RorScanInfo** a, optimizer::RorScanInfo** b)
2835
1251
{
2836
1252
  if ((*a)->used_fields_covered > (*b)->used_fields_covered)
2837
1253
    return -1;
2848
1264
  return 0;
2849
1265
}
2850
1266
 
2851
 
 
2852
1267
/* Auxiliary structure for incremental ROR-intersection creation */
2853
 
typedef struct
 
1268
typedef struct st_ror_intersect_info
2854
1269
{
2855
 
  const PARAM *param;
2856
 
  MY_BITMAP covered_fields; /* union of fields covered by all scans */
 
1270
  st_ror_intersect_info()
 
1271
    :
 
1272
      param(NULL),
 
1273
      covered_fields(),
 
1274
      out_rows(0.0),
 
1275
      is_covering(false),
 
1276
      index_records(0),
 
1277
      index_scan_costs(0.0),
 
1278
      total_cost(0.0)
 
1279
  {}
 
1280
 
 
1281
  st_ror_intersect_info(const optimizer::Parameter *in_param)
 
1282
    :
 
1283
      param(in_param),
 
1284
      covered_fields(in_param->table->getShare()->sizeFields()),
 
1285
      out_rows(in_param->table->cursor->stats.records),
 
1286
      is_covering(false),
 
1287
      index_records(0),
 
1288
      index_scan_costs(0.0),
 
1289
      total_cost(0.0)
 
1290
  {
 
1291
    covered_fields.reset();
 
1292
  }
 
1293
 
 
1294
  const optimizer::Parameter *param;
 
1295
  boost::dynamic_bitset<> covered_fields; /* union of fields covered by all scans */
2857
1296
  /*
2858
1297
    Fraction of table records that satisfies conditions of all scans.
2859
1298
    This is the number of full records that will be retrieved if a
2869
1308
} ROR_INTERSECT_INFO;
2870
1309
 
2871
1310
 
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,
2897
 
                  false))
2898
 
    return NULL;
2899
 
  info->is_covering= false;
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)
 
1311
static void ror_intersect_cpy(ROR_INTERSECT_INFO *dst,
 
1312
                              const ROR_INTERSECT_INFO *src)
2908
1313
{
2909
1314
  dst->param= src->param;
2910
 
  memcpy(dst->covered_fields.bitmap, src->covered_fields.bitmap,
2911
 
         no_bytes_in_map(&src->covered_fields));
 
1315
  dst->covered_fields= src->covered_fields;
2912
1316
  dst->out_rows= src->out_rows;
2913
1317
  dst->is_covering= src->is_covering;
2914
1318
  dst->index_records= src->index_records;
3008
1412
*/
3009
1413
 
3010
1414
static double ror_scan_selectivity(const ROR_INTERSECT_INFO *info,
3011
 
                                   const ROR_SCAN_INFO *scan)
 
1415
                                   const optimizer::RorScanInfo *scan)
3012
1416
{
3013
1417
  double selectivity_mult= 1.0;
3014
 
  KEY_PART_INFO *key_part= info->param->table->key_info[scan->keynr].key_part;
 
1418
  KeyPartInfo *key_part= info->param->table->key_info[scan->keynr].key_part;
3015
1419
  unsigned char key_val[MAX_KEY_LENGTH+MAX_FIELD_WIDTH]; /* key values tuple */
3016
1420
  unsigned char *key_ptr= key_val;
3017
 
  SEL_ARG *sel_arg, *tuple_arg= NULL;
 
1421
  optimizer::SEL_ARG *sel_arg= NULL;
 
1422
  optimizer::SEL_ARG *tuple_arg= NULL;
3018
1423
  key_part_map keypart_map= 0;
3019
1424
  bool cur_covered;
3020
 
  bool prev_covered= test(bitmap_is_set(&info->covered_fields,
3021
 
                                        key_part->fieldnr-1));
 
1425
  bool prev_covered= test(info->covered_fields.test(key_part->fieldnr-1));
3022
1426
  key_range min_range;
3023
1427
  key_range max_range;
3024
1428
  min_range.key= key_val;
3025
1429
  min_range.flag= HA_READ_KEY_EXACT;
3026
1430
  max_range.key= key_val;
3027
1431
  max_range.flag= HA_READ_AFTER_KEY;
3028
 
  ha_rows prev_records= info->param->table->file->stats.records;
 
1432
  ha_rows prev_records= info->param->table->cursor->stats.records;
3029
1433
 
3030
1434
  for (sel_arg= scan->sel_arg; sel_arg;
3031
1435
       sel_arg= sel_arg->next_key_part)
3032
1436
  {
3033
 
    cur_covered= test(bitmap_is_set(&info->covered_fields,
3034
 
                                    key_part[sel_arg->part].fieldnr-1));
 
1437
    cur_covered=
 
1438
      test(info->covered_fields.test(key_part[sel_arg->part].fieldnr-1));
3035
1439
    if (cur_covered != prev_covered)
3036
1440
    {
3037
1441
      /* create (part1val, ..., part{n-1}val) tuple. */
3052
1456
      }
3053
1457
      min_range.length= max_range.length= (size_t) (key_ptr - key_val);
3054
1458
      min_range.keypart_map= max_range.keypart_map= keypart_map;
3055
 
      records= (info->param->table->file->
 
1459
      records= (info->param->table->cursor->
3056
1460
                records_in_range(scan->keynr, &min_range, &max_range));
3057
1461
      if (cur_covered)
3058
1462
      {
3059
1463
        /* uncovered -> covered */
3060
 
        double tmp= rows2double(records)/rows2double(prev_records);
3061
 
        selectivity_mult *= tmp;
 
1464
        selectivity_mult *= static_cast<double>(records) / prev_records;
3062
1465
        prev_records= HA_POS_ERROR;
3063
1466
      }
3064
1467
      else
3071
1474
  }
3072
1475
  if (!prev_covered)
3073
1476
  {
3074
 
    double tmp= rows2double(info->param->table->quick_rows[scan->keynr]) /
3075
 
                rows2double(prev_records);
3076
 
    selectivity_mult *= tmp;
 
1477
    selectivity_mult *= static_cast<double>(info->param->table->quick_rows[scan->keynr]) / prev_records;
3077
1478
  }
3078
 
  return(selectivity_mult);
 
1479
  return selectivity_mult;
3079
1480
}
3080
1481
 
3081
1482
 
3116
1517
*/
3117
1518
 
3118
1519
static bool ror_intersect_add(ROR_INTERSECT_INFO *info,
3119
 
                              ROR_SCAN_INFO* ror_scan, bool is_cpk_scan)
 
1520
                              optimizer::RorScanInfo* ror_scan, bool is_cpk_scan)
3120
1521
{
3121
1522
  double selectivity_mult= 1.0;
3122
1523
 
3136
1537
      each record of every scan. Assuming 1/TIME_FOR_COMPARE_ROWID
3137
1538
      per check this gives us:
3138
1539
    */
3139
 
    info->index_scan_costs += rows2double(info->index_records) /
 
1540
    info->index_scan_costs += static_cast<double>(info->index_records) /
3140
1541
                              TIME_FOR_COMPARE_ROWID;
3141
1542
  }
3142
1543
  else
3143
1544
  {
3144
1545
    info->index_records += info->param->table->quick_rows[ror_scan->keynr];
3145
1546
    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))
 
1547
    boost::dynamic_bitset<> tmp_bitset= ror_scan->bitsToBitset();
 
1548
    info->covered_fields|= tmp_bitset;
 
1549
    if (! info->is_covering && info->param->needed_fields.is_subset_of(info->covered_fields))
3149
1550
    {
3150
1551
      info->is_covering= true;
3151
1552
    }
3152
1553
  }
3153
1554
 
3154
1555
  info->total_cost= info->index_scan_costs;
3155
 
  if (!info->is_covering)
 
1556
  if (! info->is_covering)
3156
1557
  {
3157
 
    COST_VECT sweep_cost;
3158
 
    JOIN *join= info->param->session->lex->select_lex.join;
 
1558
    optimizer::CostVector sweep_cost;
 
1559
    Join *join= info->param->session->lex().select_lex.join;
3159
1560
    bool is_interrupted= test(join && join->tables == 1);
3160
1561
    get_sweep_read_cost(info->param->table, double2rows(info->out_rows),
3161
1562
                        is_interrupted, &sweep_cost);
3166
1567
 
3167
1568
 
3168
1569
/*
 
1570
  Get best covering ROR-intersection.
 
1571
  SYNOPSIS
 
1572
    get_best_covering_ror_intersect()
 
1573
      param     Parameter from test_quick_select function.
 
1574
      tree      optimizer::SEL_TREE with sets of intervals for different keys.
 
1575
      read_time Don't return table read plans with cost > read_time.
 
1576
 
 
1577
  RETURN
 
1578
    Best covering ROR-intersection plan
 
1579
    NULL if no plan found.
 
1580
 
 
1581
  NOTES
 
1582
    get_best_ror_intersect must be called for a tree before calling this
 
1583
    function for it.
 
1584
    This function invalidates tree->ror_scans member values.
 
1585
 
 
1586
  The following approximate algorithm is used:
 
1587
    I=set of all covering indexes
 
1588
    F=set of all fields to cover
 
1589
    S={}
 
1590
 
 
1591
    do
 
1592
    {
 
1593
      Order I by (#covered fields in F desc,
 
1594
                  #components asc,
 
1595
                  number of first not covered component asc);
 
1596
      F=F-covered by first(I);
 
1597
      S=S+first(I);
 
1598
      I=I-first(I);
 
1599
    } while F is not empty.
 
1600
*/
 
1601
 
 
1602
static
 
1603
optimizer::RorIntersectReadPlan *get_best_covering_ror_intersect(optimizer::Parameter *param,
 
1604
                                                            optimizer::SEL_TREE *tree,
 
1605
                                                            double read_time)
 
1606
{
 
1607
  optimizer::RorScanInfo **ror_scan_mark;
 
1608
  optimizer::RorScanInfo **ror_scans_end= tree->ror_scans_end;
 
1609
 
 
1610
  for (optimizer::RorScanInfo **scan= tree->ror_scans; scan != ror_scans_end; ++scan)
 
1611
    (*scan)->key_components=
 
1612
      param->table->key_info[(*scan)->keynr].key_parts;
 
1613
 
 
1614
  /*
 
1615
    Run covering-ROR-search algorithm.
 
1616
    Assume set I is [ror_scan .. ror_scans_end)
 
1617
  */
 
1618
 
 
1619
  /*I=set of all covering indexes */
 
1620
  ror_scan_mark= tree->ror_scans;
 
1621
 
 
1622
  boost::dynamic_bitset<> *covered_fields= &param->tmp_covered_fields;
 
1623
  if (covered_fields->empty())
 
1624
  {
 
1625
    covered_fields->resize(param->table->getShare()->sizeFields());
 
1626
  }
 
1627
  covered_fields->reset();
 
1628
 
 
1629
  double total_cost= 0.0f;
 
1630
  ha_rows records=0;
 
1631
  bool all_covered;
 
1632
 
 
1633
  do
 
1634
  {
 
1635
    /*
 
1636
      Update changed sorting info:
 
1637
        #covered fields,
 
1638
        number of first not covered component
 
1639
      Calculate and save these values for each of remaining scans.
 
1640
    */
 
1641
    for (optimizer::RorScanInfo **scan= ror_scan_mark; scan != ror_scans_end; ++scan)
 
1642
    {
 
1643
      /* subtract one bitset from the other */
 
1644
      (*scan)->subtractBitset(*covered_fields);
 
1645
      (*scan)->used_fields_covered=
 
1646
        (*scan)->getBitCount();
 
1647
      (*scan)->first_uncovered_field= (*scan)->findFirstNotSet();
 
1648
    }
 
1649
 
 
1650
    internal::my_qsort(ror_scan_mark, ror_scans_end-ror_scan_mark,
 
1651
                       sizeof(optimizer::RorScanInfo*),
 
1652
                       (qsort_cmp)cmp_ror_scan_info_covering);
 
1653
 
 
1654
    /* I=I-first(I) */
 
1655
    total_cost += (*ror_scan_mark)->index_read_cost;
 
1656
    records += (*ror_scan_mark)->records;
 
1657
    if (total_cost > read_time)
 
1658
      return NULL;
 
1659
    /* F=F-covered by first(I) */
 
1660
    boost::dynamic_bitset<> tmp_bitset= (*ror_scan_mark)->bitsToBitset();
 
1661
    *covered_fields|= tmp_bitset;
 
1662
    all_covered= param->needed_fields.is_subset_of(*covered_fields);
 
1663
  } while ((++ror_scan_mark < ror_scans_end) && ! all_covered);
 
1664
 
 
1665
  if (!all_covered || (ror_scan_mark - tree->ror_scans) == 1)
 
1666
    return NULL;
 
1667
 
 
1668
  /*
 
1669
    Ok, [tree->ror_scans .. ror_scan) holds covering index_intersection with
 
1670
    cost total_cost.
 
1671
  */
 
1672
  /* Add priority queue use cost. */
 
1673
  total_cost += static_cast<double>(records) *
 
1674
                log((double)(ror_scan_mark - tree->ror_scans)) /
 
1675
                (TIME_FOR_COMPARE_ROWID * M_LN2);
 
1676
 
 
1677
  if (total_cost > read_time)
 
1678
    return NULL;
 
1679
 
 
1680
  optimizer::RorIntersectReadPlan* trp= new (*param->mem_root) optimizer::RorIntersectReadPlan;
 
1681
 
 
1682
  uint32_t best_num= (ror_scan_mark - tree->ror_scans);
 
1683
  trp->first_scan= new (*param->mem_root) optimizer::RorScanInfo*[best_num];
 
1684
  memcpy(trp->first_scan, tree->ror_scans, best_num*sizeof(optimizer::RorScanInfo*));
 
1685
  trp->last_scan=  trp->first_scan + best_num;
 
1686
  trp->is_covering= true;
 
1687
  trp->read_cost= total_cost;
 
1688
  trp->records= records;
 
1689
  trp->cpk_scan= NULL;
 
1690
  set_if_smaller(param->table->quick_condition_rows, records);
 
1691
 
 
1692
  return(trp);
 
1693
}
 
1694
 
 
1695
 
 
1696
/*
3169
1697
  Get best ROR-intersection plan using non-covering ROR-intersection search
3170
1698
  algorithm. The returned plan may be covering.
3171
1699
 
3230
1758
*/
3231
1759
 
3232
1760
static
3233
 
TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree,
3234
 
                                          double read_time,
3235
 
                                          bool *are_all_covering)
 
1761
optimizer::RorIntersectReadPlan *get_best_ror_intersect(const optimizer::Parameter *param,
 
1762
                                                   optimizer::SEL_TREE *tree,
 
1763
                                                   double read_time,
 
1764
                                                   bool *are_all_covering)
3236
1765
{
3237
 
  uint32_t idx;
 
1766
  uint32_t idx= 0;
3238
1767
  double min_cost= DBL_MAX;
3239
1768
 
3240
 
  if ((tree->n_ror_scans < 2) || !param->table->file->stats.records)
 
1769
  if ((tree->n_ror_scans < 2) || ! param->table->cursor->stats.records)
3241
1770
    return NULL;
3242
1771
 
3243
1772
  /*
3244
 
    Step1: Collect ROR-able SEL_ARGs and create ROR_SCAN_INFO for each of
 
1773
    Step1: Collect ROR-able SEL_ARGs and create optimizer::RorScanInfo for each of
3245
1774
    them. Also find and save clustered PK scan if there is one.
3246
1775
  */
3247
 
  ROR_SCAN_INFO **cur_ror_scan;
3248
 
  ROR_SCAN_INFO *cpk_scan= NULL;
3249
 
  uint32_t cpk_no;
 
1776
  optimizer::RorScanInfo **cur_ror_scan= NULL;
 
1777
  optimizer::RorScanInfo *cpk_scan= NULL;
 
1778
  uint32_t cpk_no= 0;
3250
1779
  bool cpk_scan_used= false;
3251
1780
 
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);
 
1781
  tree->ror_scans= new (*param->mem_root) optimizer::RorScanInfo*[param->keys];
 
1782
  cpk_no= ((param->table->cursor->primary_key_is_clustered()) ? param->table->getShare()->getPrimaryKey() : MAX_KEY);
3258
1783
 
3259
1784
  for (idx= 0, cur_ror_scan= tree->ror_scans; idx < param->keys; idx++)
3260
1785
  {
3261
 
    ROR_SCAN_INFO *scan;
3262
 
    if (!tree->ror_scans_map.is_set(idx))
 
1786
    optimizer::RorScanInfo *scan;
 
1787
    if (! tree->ror_scans_map.test(idx))
3263
1788
      continue;
3264
 
    if (!(scan= make_ror_scan(param, idx, tree->keys[idx])))
 
1789
    if (! (scan= make_ror_scan(param, idx, tree->keys[idx])))
3265
1790
      return NULL;
3266
1791
    if (param->real_keynr[idx] == cpk_no)
3267
1792
    {
3273
1798
  }
3274
1799
 
3275
1800
  tree->ror_scans_end= cur_ror_scan;
3276
 
  print_ror_scans_arr(param->table, "original",
3277
 
                                          tree->ror_scans,
3278
 
                                          tree->ror_scans_end);
3279
1801
  /*
3280
1802
    Ok, [ror_scans, ror_scans_end) is array of ptrs to initialized
3281
 
    ROR_SCAN_INFO's.
 
1803
    optimizer::RorScanInfo's.
3282
1804
    Step 2: Get best ROR-intersection using an approximate algorithm.
3283
1805
  */
3284
 
  my_qsort(tree->ror_scans, tree->n_ror_scans, sizeof(ROR_SCAN_INFO*),
3285
 
           (qsort_cmp)cmp_ror_scan_info);
3286
 
  print_ror_scans_arr(param->table, "ordered",
3287
 
                                          tree->ror_scans,
3288
 
                                          tree->ror_scans_end);
 
1806
  internal::my_qsort(tree->ror_scans, tree->n_ror_scans, sizeof(optimizer::RorScanInfo*),
 
1807
                     (qsort_cmp)cmp_ror_scan_info);
3289
1808
 
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;
 
1809
  optimizer::RorScanInfo **intersect_scans= NULL; /* ROR scans used in index intersection */
 
1810
  optimizer::RorScanInfo **intersect_scans_end= intersect_scans=  new (*param->mem_root) optimizer::RorScanInfo*[tree->n_ror_scans];
3296
1811
  intersect_scans_end= intersect_scans;
3297
1812
 
3298
1813
  /* Create and incrementally update ROR intersection. */
3299
 
  ROR_INTERSECT_INFO *intersect, *intersect_best;
3300
 
  if (!(intersect= ror_intersect_init(param)) ||
3301
 
      !(intersect_best= ror_intersect_init(param)))
3302
 
    return NULL;
 
1814
  ROR_INTERSECT_INFO intersect(param);
 
1815
  ROR_INTERSECT_INFO intersect_best(param);
3303
1816
 
3304
1817
  /* [intersect_scans,intersect_scans_best) will hold the best intersection */
3305
 
  ROR_SCAN_INFO **intersect_scans_best;
 
1818
  optimizer::RorScanInfo **intersect_scans_best= NULL;
3306
1819
  cur_ror_scan= tree->ror_scans;
3307
1820
  intersect_scans_best= intersect_scans;
3308
 
  while (cur_ror_scan != tree->ror_scans_end && !intersect->is_covering)
 
1821
  while (cur_ror_scan != tree->ror_scans_end && ! intersect.is_covering)
3309
1822
  {
3310
1823
    /* S= S + first(R);  R= R - first(R); */
3311
 
    if (!ror_intersect_add(intersect, *cur_ror_scan, false))
 
1824
    if (! ror_intersect_add(&intersect, *cur_ror_scan, false))
3312
1825
    {
3313
1826
      cur_ror_scan++;
3314
1827
      continue;
3316
1829
 
3317
1830
    *(intersect_scans_end++)= *(cur_ror_scan++);
3318
1831
 
3319
 
    if (intersect->total_cost < min_cost)
 
1832
    if (intersect.total_cost < min_cost)
3320
1833
    {
3321
1834
      /* Local minimum found, save it */
3322
 
      ror_intersect_cpy(intersect_best, intersect);
 
1835
      ror_intersect_cpy(&intersect_best, &intersect);
3323
1836
      intersect_scans_best= intersect_scans_end;
3324
 
      min_cost = intersect->total_cost;
 
1837
      min_cost = intersect.total_cost;
3325
1838
    }
3326
1839
  }
3327
1840
 
3330
1843
    return NULL;
3331
1844
  }
3332
1845
 
3333
 
  print_ror_scans_arr(param->table,
3334
 
                                          "best ROR-intersection",
3335
 
                                          intersect_scans,
3336
 
                                          intersect_scans_best);
3337
 
 
3338
 
  *are_all_covering= intersect->is_covering;
 
1846
  *are_all_covering= intersect.is_covering;
3339
1847
  uint32_t best_num= intersect_scans_best - intersect_scans;
3340
 
  ror_intersect_cpy(intersect, intersect_best);
 
1848
  ror_intersect_cpy(&intersect, &intersect_best);
3341
1849
 
3342
1850
  /*
3343
1851
    Ok, found the best ROR-intersection of non-CPK key scans.
3344
1852
    Check if we should add a CPK scan. If the obtained ROR-intersection is
3345
1853
    covering, it doesn't make sense to add CPK scan.
3346
1854
  */
3347
 
  if (cpk_scan && !intersect->is_covering)
 
1855
  if (cpk_scan && ! intersect.is_covering)
3348
1856
  {
3349
 
    if (ror_intersect_add(intersect, cpk_scan, true) &&
3350
 
        (intersect->total_cost < min_cost))
 
1857
    if (ror_intersect_add(&intersect, cpk_scan, true) &&
 
1858
        (intersect.total_cost < min_cost))
3351
1859
    {
3352
1860
      cpk_scan_used= true;
3353
1861
      intersect_best= intersect; //just set pointer here
3355
1863
  }
3356
1864
 
3357
1865
  /* Ok, return ROR-intersect plan if we have found one */
3358
 
  TRP_ROR_INTERSECT *trp= NULL;
 
1866
  optimizer::RorIntersectReadPlan *trp= NULL;
3359
1867
  if (min_cost < read_time && (cpk_scan_used || best_num > 1))
3360
1868
  {
3361
 
    if (!(trp= new (param->mem_root) TRP_ROR_INTERSECT))
3362
 
      return(trp);
3363
 
    if (!(trp->first_scan=
3364
 
           (ROR_SCAN_INFO**)alloc_root(param->mem_root,
3365
 
                                       sizeof(ROR_SCAN_INFO*)*best_num)))
3366
 
      return NULL;
3367
 
    memcpy(trp->first_scan, intersect_scans, best_num*sizeof(ROR_SCAN_INFO*));
 
1869
    trp= new (*param->mem_root) optimizer::RorIntersectReadPlan;
 
1870
    trp->first_scan= new (*param->mem_root) optimizer::RorScanInfo*[best_num];
 
1871
    memcpy(trp->first_scan, intersect_scans, best_num*sizeof(optimizer::RorScanInfo*));
3368
1872
    trp->last_scan=  trp->first_scan + best_num;
3369
 
    trp->is_covering= intersect_best->is_covering;
3370
 
    trp->read_cost= intersect_best->total_cost;
 
1873
    trp->is_covering= intersect_best.is_covering;
 
1874
    trp->read_cost= intersect_best.total_cost;
3371
1875
    /* Prevent divisons by zero */
3372
 
    ha_rows best_rows = double2rows(intersect_best->out_rows);
3373
 
    if (!best_rows)
 
1876
    ha_rows best_rows = double2rows(intersect_best.out_rows);
 
1877
    if (! best_rows)
3374
1878
      best_rows= 1;
3375
1879
    set_if_smaller(param->table->quick_condition_rows, best_rows);
3376
1880
    trp->records= best_rows;
3377
 
    trp->index_scan_costs= intersect_best->index_scan_costs;
 
1881
    trp->index_scan_costs= intersect_best.index_scan_costs;
3378
1882
    trp->cpk_scan= cpk_scan_used? cpk_scan: NULL;
3379
1883
  }
3380
 
  return(trp);
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;
3438
 
  if (!covered_fields->bitmap)
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,
3443
 
                  param->table->s->fields, false))
3444
 
    return 0;
3445
 
  bitmap_clear_all(covered_fields);
3446
 
 
3447
 
  double total_cost= 0.0f;
3448
 
  ha_rows records=0;
3449
 
  bool all_covered;
3450
 
 
3451
 
  print_ror_scans_arr(param->table,
3452
 
                                           "building covering ROR-I",
3453
 
                                           ror_scan_mark, ror_scans_end);
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
 
 
3474
 
    print_ror_scans_arr(param->table,
3475
 
                                             "remaining scans",
3476
 
                                             ror_scan_mark, ror_scans_end);
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)
3482
 
      return NULL;
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);
3487
 
 
3488
 
  if (!all_covered || (ror_scan_mark - tree->ror_scans) == 1)
3489
 
    return NULL;
3490
 
 
3491
 
  /*
3492
 
    Ok, [tree->ror_scans .. ror_scan) holds covering index_intersection with
3493
 
    cost total_cost.
3494
 
  */
3495
 
  print_ror_scans_arr(param->table,
3496
 
                                           "creating covering ROR-intersect",
3497
 
                                           tree->ror_scans, ror_scan_mark);
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)
3505
 
    return NULL;
3506
 
 
3507
 
  TRP_ROR_INTERSECT *trp;
3508
 
  if (!(trp= new (param->mem_root) TRP_ROR_INTERSECT))
3509
 
    return(trp);
3510
 
  uint32_t best_num= (ror_scan_mark - tree->ror_scans);
3511
 
  if (!(trp->first_scan= (ROR_SCAN_INFO**)alloc_root(param->mem_root,
3512
 
                                                     sizeof(ROR_SCAN_INFO*)*
3513
 
                                                     best_num)))
3514
 
    return NULL;
3515
 
  memcpy(trp->first_scan, tree->ror_scans, best_num*sizeof(ROR_SCAN_INFO*));
3516
 
  trp->last_scan=  trp->first_scan + best_num;
3517
 
  trp->is_covering= true;
3518
 
  trp->read_cost= total_cost;
3519
 
  trp->records= records;
3520
 
  trp->cpk_scan= NULL;
3521
 
  set_if_smaller(param->table->quick_condition_rows, records);
3522
 
 
3523
 
  return(trp);
3524
 
}
3525
 
 
3526
 
 
3527
 
/*
3528
 
  Get best "range" table read plan for given SEL_TREE, also update some info
 
1884
  return trp;
 
1885
}
 
1886
 
 
1887
 
 
1888
/*
 
1889
  Get best "range" table read plan for given optimizer::SEL_TREE, also update some info
3529
1890
 
3530
1891
  SYNOPSIS
3531
1892
    get_key_scans_params()
 
1893
      session
3532
1894
      param                    Parameters from test_quick_select
3533
 
      tree                     Make range select for this SEL_TREE
 
1895
      tree                     Make range select for this optimizer::SEL_TREE
3534
1896
      index_read_must_be_used  true <=> assume 'index only' option will be set
3535
1897
                               (except for clustered PK indexes)
3536
1898
      update_tbl_stats         true <=> update table->quick_* with information
3539
1901
                               cost > read_time.
3540
1902
 
3541
1903
  DESCRIPTION
3542
 
    Find the best "range" table read plan for given SEL_TREE.
 
1904
    Find the best "range" table read plan for given optimizer::SEL_TREE.
3543
1905
    The side effects are
3544
1906
     - tree->ror_scans is updated to indicate which scans are ROR scans.
3545
1907
     - if update_tbl_stats=true then table->quick_* is updated with info
3550
1912
    NULL if no plan found or error occurred
3551
1913
*/
3552
1914
 
3553
 
static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
3554
 
                                       bool index_read_must_be_used,
3555
 
                                       bool update_tbl_stats,
3556
 
                                       double read_time)
 
1915
static optimizer::RangeReadPlan *get_key_scans_params(Session *session,
 
1916
                                                      optimizer::Parameter *param,
 
1917
                                                      optimizer::SEL_TREE *tree,
 
1918
                                                      bool index_read_must_be_used,
 
1919
                                                      bool update_tbl_stats,
 
1920
                                                      double read_time)
3557
1921
{
3558
1922
  uint32_t idx;
3559
 
  SEL_ARG **key,**end, **key_to_read= NULL;
 
1923
  optimizer::SEL_ARG **key= NULL;
 
1924
  optimizer::SEL_ARG **end= NULL;
 
1925
  optimizer::SEL_ARG **key_to_read= NULL;
3560
1926
  ha_rows best_records= 0;
3561
 
  uint32_t    best_mrr_flags= 0, best_buf_size= 0;
3562
 
  TRP_RANGE* read_plan= NULL;
 
1927
  uint32_t best_mrr_flags= 0;
 
1928
  uint32_t best_buf_size= 0;
 
1929
  optimizer::RangeReadPlan *read_plan= NULL;
3563
1930
  /*
3564
 
    Note that there may be trees that have type SEL_TREE::KEY but contain no
 
1931
    Note that there may be trees that have type optimizer::SEL_TREE::KEY but contain no
3565
1932
    key reads at all, e.g. tree for expression "key1 is not null" where key1
3566
1933
    is defined as "not null".
3567
1934
  */
3568
 
  print_sel_tree(param, tree, &tree->keys_map, "tree scans");
3569
 
  tree->ror_scans_map.clear_all();
 
1935
  tree->ror_scans_map.reset();
3570
1936
  tree->n_ror_scans= 0;
3571
1937
  for (idx= 0,key=tree->keys, end=key+param->keys; key != end; key++,idx++)
3572
1938
  {
3573
1939
    if (*key)
3574
1940
    {
3575
1941
      ha_rows found_records;
3576
 
      COST_VECT cost;
3577
 
      double found_read_time;
 
1942
      optimizer::CostVector cost;
 
1943
      double found_read_time= 0.0;
3578
1944
      uint32_t mrr_flags, buf_size;
3579
1945
      uint32_t keynr= param->real_keynr[idx];
3580
 
      if ((*key)->type == SEL_ARG::MAYBE_KEY ||
 
1946
      if ((*key)->type == optimizer::SEL_ARG::MAYBE_KEY ||
3581
1947
          (*key)->maybe_flag)
3582
 
        param->needed_reg->set_bit(keynr);
 
1948
        param->needed_reg->set(keynr);
3583
1949
 
3584
1950
      bool read_index_only= index_read_must_be_used ||
3585
 
                            param->table->covering_keys.is_set(keynr);
 
1951
                            param->table->covering_keys.test(keynr);
3586
1952
 
3587
 
      found_records= check_quick_select(param, idx, read_index_only, *key,
 
1953
      found_records= check_quick_select(session, param, idx, read_index_only, *key,
3588
1954
                                        update_tbl_stats, &mrr_flags,
3589
1955
                                        &buf_size, &cost);
3590
1956
      found_read_time= cost.total_cost();
3591
1957
      if ((found_records != HA_POS_ERROR) && param->is_ror_scan)
3592
1958
      {
3593
1959
        tree->n_ror_scans++;
3594
 
        tree->ror_scans_map.set_bit(idx);
 
1960
        tree->ror_scans_map.set(idx);
3595
1961
      }
3596
1962
      if (read_time > found_read_time && found_records != HA_POS_ERROR)
3597
1963
      {
3604
1970
    }
3605
1971
  }
3606
1972
 
3607
 
  print_sel_tree(param, tree, &tree->ror_scans_map, "ROR scans");
3608
1973
  if (key_to_read)
3609
1974
  {
3610
1975
    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
 
    }
 
1976
    read_plan= new (*param->mem_root) optimizer::RangeReadPlan(*key_to_read, idx, best_mrr_flags);
 
1977
    read_plan->records= best_records;
 
1978
    read_plan->is_ror= tree->ror_scans_map.test(idx);
 
1979
    read_plan->read_cost= read_time;
 
1980
    read_plan->mrr_buf_size= best_buf_size;
3619
1981
  }
3620
 
 
3621
 
  return(read_plan);
 
1982
  return read_plan;
3622
1983
}
3623
1984
 
3624
1985
 
3625
 
QUICK_SELECT_I *TRP_INDEX_MERGE::make_quick(PARAM *param, bool, MEM_ROOT *)
 
1986
optimizer::QuickSelectInterface *optimizer::IndexMergeReadPlan::make_quick(optimizer::Parameter *param, bool, memory::Root *)
3626
1987
{
3627
 
  QUICK_INDEX_MERGE_SELECT *quick_imerge;
3628
 
  QUICK_RANGE_SELECT *quick;
3629
1988
  /* index_merge always retrieves full rows, ignore retrieve_full_rows */
3630
 
  if (!(quick_imerge= new QUICK_INDEX_MERGE_SELECT(param->session, param->table)))
3631
 
    return NULL;
3632
 
 
 
1989
  optimizer::QuickIndexMergeSelect* quick_imerge= new optimizer::QuickIndexMergeSelect(param->session, param->table);
3633
1990
  quick_imerge->records= records;
3634
1991
  quick_imerge->read_time= read_cost;
3635
 
  for (TRP_RANGE **range_scan= range_scans; range_scan != range_scans_end;
3636
 
       range_scan++)
 
1992
  for (optimizer::RangeReadPlan **range_scan= range_scans; range_scan != range_scans_end; range_scan++)
3637
1993
  {
3638
 
    if (!(quick= (QUICK_RANGE_SELECT*)
3639
 
          ((*range_scan)->make_quick(param, false, &quick_imerge->alloc)))||
3640
 
        quick_imerge->push_quick_back(quick))
 
1994
    optimizer::QuickRangeSelect* quick= (optimizer::QuickRangeSelect*)((*range_scan)->make_quick(param, false, &quick_imerge->alloc));
 
1995
    if (not quick)
3641
1996
    {
3642
1997
      delete quick;
3643
1998
      delete quick_imerge;
3644
1999
      return NULL;
3645
2000
    }
 
2001
    quick_imerge->push_quick_back(quick);
3646
2002
  }
3647
2003
  return quick_imerge;
3648
2004
}
3649
2005
 
3650
 
QUICK_SELECT_I *TRP_ROR_INTERSECT::make_quick(PARAM *param,
3651
 
                                              bool retrieve_full_rows,
3652
 
                                              MEM_ROOT *parent_alloc)
 
2006
optimizer::QuickSelectInterface *optimizer::RorIntersectReadPlan::make_quick(optimizer::Parameter *param,
 
2007
                                                                             bool retrieve_full_rows,
 
2008
                                                                             memory::Root *parent_alloc)
3653
2009
{
3654
 
  QUICK_ROR_INTERSECT_SELECT *quick_intrsect;
3655
 
  QUICK_RANGE_SELECT *quick;
3656
 
  MEM_ROOT *alloc;
 
2010
  optimizer::QuickRorIntersectSelect *quick_intersect= NULL;
 
2011
  optimizer::QuickRangeSelect *quick= NULL;
 
2012
  memory::Root *alloc= NULL;
3657
2013
 
3658
 
  if ((quick_intrsect=
3659
 
         new QUICK_ROR_INTERSECT_SELECT(param->session, param->table,
3660
 
                                        (retrieve_full_rows? (!is_covering) :
3661
 
                                         false),
3662
 
                                        parent_alloc)))
 
2014
  if ((quick_intersect=
 
2015
         new optimizer::QuickRorIntersectSelect(param->session,
 
2016
                                                param->table,
 
2017
                                                (retrieve_full_rows? (! is_covering) : false),
 
2018
                                                parent_alloc)))
3663
2019
  {
3664
 
    print_ror_scans_arr(param->table,
3665
 
                                             "creating ROR-intersect",
3666
 
                                             first_scan, last_scan);
3667
 
    alloc= parent_alloc? parent_alloc: &quick_intrsect->alloc;
3668
 
    for (; first_scan != last_scan;++first_scan)
 
2020
    alloc= parent_alloc ? parent_alloc : &quick_intersect->alloc;
 
2021
    for (; first_scan != last_scan; ++first_scan)
3669
2022
    {
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))
 
2023
      if (! (quick= optimizer::get_quick_select(param,
 
2024
                                                (*first_scan)->idx,
 
2025
                                                (*first_scan)->sel_arg,
 
2026
                                                HA_MRR_USE_DEFAULT_IMPL | HA_MRR_SORTED,
 
2027
                                                0,
 
2028
                                                alloc)))
3675
2029
      {
3676
 
        delete quick_intrsect;
 
2030
        delete quick_intersect;
3677
2031
        return NULL;
3678
2032
      }
 
2033
      quick_intersect->push_quick_back(quick);
3679
2034
    }
3680
2035
    if (cpk_scan)
3681
2036
    {
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)))
 
2037
      if (! (quick= optimizer::get_quick_select(param,
 
2038
                                                cpk_scan->idx,
 
2039
                                                cpk_scan->sel_arg,
 
2040
                                                HA_MRR_USE_DEFAULT_IMPL | HA_MRR_SORTED,
 
2041
                                                0,
 
2042
                                                alloc)))
3686
2043
      {
3687
 
        delete quick_intrsect;
 
2044
        delete quick_intersect;
3688
2045
        return NULL;
3689
2046
      }
3690
 
      quick->file= NULL;
3691
 
      quick_intrsect->cpk_quick= quick;
 
2047
      quick->resetCursor();
 
2048
      quick_intersect->cpk_quick= quick;
3692
2049
    }
3693
 
    quick_intrsect->records= records;
3694
 
    quick_intrsect->read_time= read_cost;
 
2050
    quick_intersect->records= records;
 
2051
    quick_intersect->read_time= read_cost;
3695
2052
  }
3696
 
  return(quick_intrsect);
 
2053
  return quick_intersect;
3697
2054
}
3698
2055
 
3699
2056
 
3700
 
QUICK_SELECT_I *TRP_ROR_UNION::make_quick(PARAM *param, bool, MEM_ROOT *)
 
2057
optimizer::QuickSelectInterface *optimizer::RorUnionReadPlan::make_quick(optimizer::Parameter *param, bool, memory::Root *)
3701
2058
{
3702
 
  QUICK_ROR_UNION_SELECT *quick_roru;
3703
 
  TABLE_READ_PLAN **scan;
3704
 
  QUICK_SELECT_I *quick;
3705
2059
  /*
3706
2060
    It is impossible to construct a ROR-union that will not retrieve full
3707
2061
    rows, ignore retrieve_full_rows parameter.
3708
2062
  */
3709
 
  if ((quick_roru= new QUICK_ROR_UNION_SELECT(param->session, param->table)))
 
2063
  optimizer::QuickRorUnionSelect* quick_roru= new optimizer::QuickRorUnionSelect(param->session, param->table);
 
2064
  for (optimizer::TableReadPlan** scan= first_ror; scan != last_ror; scan++)
3710
2065
  {
3711
 
    for (scan= first_ror; scan != last_ror; scan++)
3712
 
    {
3713
 
      if (!(quick= (*scan)->make_quick(param, false, &quick_roru->alloc)) ||
3714
 
          quick_roru->push_quick_back(quick))
3715
 
        return NULL;
3716
 
    }
3717
 
    quick_roru->records= records;
3718
 
    quick_roru->read_time= read_cost;
 
2066
    optimizer::QuickSelectInterface* quick= (*scan)->make_quick(param, false, &quick_roru->alloc);
 
2067
    if (not quick)
 
2068
      return NULL;
 
2069
    quick_roru->push_quick_back(quick);
3719
2070
  }
3720
 
  return(quick_roru);
 
2071
  quick_roru->records= records;
 
2072
  quick_roru->read_time= read_cost;
 
2073
  return quick_roru;
3721
2074
}
3722
2075
 
3723
2076
 
3724
2077
/*
3725
 
  Build a SEL_TREE for <> or NOT BETWEEN predicate
 
2078
  Build a optimizer::SEL_TREE for <> or NOT BETWEEN predicate
3726
2079
 
3727
2080
  SYNOPSIS
3728
2081
    get_ne_mm_tree()
3729
 
      param       PARAM from SQL_SELECT::test_quick_select
 
2082
      param       Parameter from SqlSelect::test_quick_select
3730
2083
      cond_func   item for the predicate
3731
2084
      field       field in the predicate
3732
2085
      lt_value    constant that field should be smaller
3737
2090
    #  Pointer to tree built tree
3738
2091
    0  on error
3739
2092
*/
3740
 
 
3741
 
static SEL_TREE *get_ne_mm_tree(RANGE_OPT_PARAM *param, Item_func *cond_func,
 
2093
static optimizer::SEL_TREE *get_ne_mm_tree(optimizer::RangeParameter *param,
 
2094
                                Item_func *cond_func,
3742
2095
                                Field *field,
3743
2096
                                Item *lt_value, Item *gt_value,
3744
2097
                                Item_result cmp_type)
3745
2098
{
3746
 
  SEL_TREE *tree;
 
2099
  optimizer::SEL_TREE *tree= NULL;
3747
2100
  tree= get_mm_parts(param, cond_func, field, Item_func::LT_FUNC,
3748
2101
                     lt_value, cmp_type);
3749
2102
  if (tree)
3750
2103
  {
3751
 
    tree= tree_or(param, tree, get_mm_parts(param, cond_func, field,
3752
 
                                            Item_func::GT_FUNC,
3753
 
                                            gt_value, cmp_type));
 
2104
    tree= tree_or(param,
 
2105
                  tree,
 
2106
                  get_mm_parts(param, cond_func, field,
 
2107
                                                Item_func::GT_FUNC,
 
2108
                                                gt_value,
 
2109
                  cmp_type));
3754
2110
  }
3755
2111
  return tree;
3756
2112
}
3757
2113
 
3758
2114
 
3759
2115
/*
3760
 
  Build a SEL_TREE for a simple predicate
 
2116
  Build a optimizer::SEL_TREE for a simple predicate
3761
2117
 
3762
2118
  SYNOPSIS
3763
2119
    get_func_mm_tree()
3764
 
      param       PARAM from SQL_SELECT::test_quick_select
 
2120
      param       Parameter from SqlSelect::test_quick_select
3765
2121
      cond_func   item for the predicate
3766
2122
      field       field in the predicate
3767
2123
      value       constant in the predicate
3772
2128
  RETURN
3773
2129
    Pointer to the tree built tree
3774
2130
*/
3775
 
 
3776
 
static SEL_TREE *get_func_mm_tree(RANGE_OPT_PARAM *param, Item_func *cond_func,
3777
 
                                  Field *field, Item *value,
3778
 
                                  Item_result cmp_type, bool inv)
 
2131
static optimizer::SEL_TREE *get_func_mm_tree(optimizer::RangeParameter *param,
 
2132
                                  Item_func *cond_func,
 
2133
                                  Field *field,
 
2134
                                  Item *value,
 
2135
                                  Item_result cmp_type,
 
2136
                                  bool inv)
3779
2137
{
3780
 
  SEL_TREE *tree= 0;
 
2138
  optimizer::SEL_TREE *tree= NULL;
3781
2139
 
3782
 
  switch (cond_func->functype()) {
 
2140
  switch (cond_func->functype())
 
2141
  {
3783
2142
 
3784
2143
  case Item_func::NE_FUNC:
3785
2144
    tree= get_ne_mm_tree(param, cond_func, field, value, value, cmp_type);
3787
2146
 
3788
2147
  case Item_func::BETWEEN:
3789
2148
  {
3790
 
    if (!value)
 
2149
    if (! value)
3791
2150
    {
3792
2151
      if (inv)
3793
2152
      {
3794
 
        tree= get_ne_mm_tree(param, cond_func, field, cond_func->arguments()[1],
3795
 
                             cond_func->arguments()[2], cmp_type);
 
2153
        tree= get_ne_mm_tree(param,
 
2154
                             cond_func,
 
2155
                             field,
 
2156
                             cond_func->arguments()[1],
 
2157
                             cond_func->arguments()[2],
 
2158
                             cmp_type);
3796
2159
      }
3797
2160
      else
3798
2161
      {
3799
 
        tree= get_mm_parts(param, cond_func, field, Item_func::GE_FUNC,
3800
 
                           cond_func->arguments()[1],cmp_type);
 
2162
        tree= get_mm_parts(param,
 
2163
                           cond_func,
 
2164
                           field,
 
2165
                           Item_func::GE_FUNC,
 
2166
                                       cond_func->arguments()[1],
 
2167
                           cmp_type);
3801
2168
        if (tree)
3802
2169
        {
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));
 
2170
          tree= tree_and(param,
 
2171
                         tree,
 
2172
                         get_mm_parts(param, cond_func, field,
 
2173
                                                       Item_func::LE_FUNC,
 
2174
                                                       cond_func->arguments()[2],
 
2175
                         cmp_type));
3807
2176
        }
3808
2177
      }
3809
2178
    }
3810
2179
    else
3811
 
      tree= get_mm_parts(param, cond_func, field,
 
2180
      tree= get_mm_parts(param,
 
2181
                         cond_func,
 
2182
                         field,
3812
2183
                         (inv ?
3813
2184
                          (value == (Item*)1 ? Item_func::GT_FUNC :
3814
2185
                                               Item_func::LT_FUNC):
3815
2186
                          (value == (Item*)1 ? Item_func::LE_FUNC :
3816
2187
                                               Item_func::GE_FUNC)),
3817
 
                         cond_func->arguments()[0], cmp_type);
 
2188
                         cond_func->arguments()[0],
 
2189
                         cmp_type);
3818
2190
    break;
3819
2191
  }
3820
2192
  case Item_func::IN_FUNC:
3821
2193
  {
3822
 
    Item_func_in *func=(Item_func_in*) cond_func;
 
2194
    Item_func_in *func= (Item_func_in*) cond_func;
3823
2195
 
3824
2196
    /*
3825
2197
      Array for IN() is constructed when all values have the same result
3826
2198
      type. Tree won't be built for values with different result types,
3827
2199
      so we check it here to avoid unnecessary work.
3828
2200
    */
3829
 
    if (!func->arg_types_compatible)
 
2201
    if (! func->arg_types_compatible)
3830
2202
      break;
3831
2203
 
3832
2204
    if (inv)
3835
2207
      {
3836
2208
        /*
3837
2209
          We get here for conditions in form "t.key NOT IN (c1, c2, ...)",
3838
 
          where c{i} are constants. Our goal is to produce a SEL_TREE that
 
2210
          where c{i} are constants. Our goal is to produce a optimizer::SEL_TREE that
3839
2211
          represents intervals:
3840
2212
 
3841
2213
          ($MIN<t.key<c1) OR (c1<t.key<c2) OR (c2<t.key<c3) OR ...    (*)
3844
2216
 
3845
2217
          The most straightforward way to produce it is to convert NOT IN
3846
2218
          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
 
2219
          analyzer to build optimizer::SEL_TREE from that. The problem is that the
3848
2220
          range analyzer will use O(N^2) memory (which is probably a bug),
3849
2221
          and people do use big NOT IN lists (e.g. see BUG#15872, BUG#21282),
3850
2222
          will run out of memory.
3857
2229
 
3858
2230
          Considering the above, we'll handle NOT IN as follows:
3859
2231
          * 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.
 
2232
            NOT_IN_IGNORE_THRESHOLD, construct the optimizer::SEL_TREE (*) manually.
 
2233
          * Otherwise, don't produce a optimizer::SEL_TREE.
3862
2234
        */
3863
 
#define NOT_IN_IGNORE_THRESHOLD 1000
3864
 
        MEM_ROOT *tmp_root= param->mem_root;
 
2235
        const unsigned int NOT_IN_IGNORE_THRESHOLD= 1000;
 
2236
        memory::Root *tmp_root= param->mem_root;
3865
2237
        param->session->mem_root= param->old_root;
3866
2238
        /*
3867
2239
          Create one Item_type constant object. We'll need it as
3874
2246
        Item *value_item= func->array->create_item();
3875
2247
        param->session->mem_root= tmp_root;
3876
2248
 
3877
 
        if (func->array->count > NOT_IN_IGNORE_THRESHOLD || !value_item)
 
2249
        if (func->array->count > NOT_IN_IGNORE_THRESHOLD || ! value_item)
3878
2250
          break;
3879
2251
 
3880
 
        /* Get a SEL_TREE for "(-inf|NULL) < X < c_0" interval.  */
 
2252
        /* Get a optimizer::SEL_TREE for "(-inf|NULL) < X < c_0" interval.  */
3881
2253
        uint32_t i=0;
3882
2254
        do
3883
2255
        {
3884
2256
          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)
 
2257
          tree= get_mm_parts(param,
 
2258
                             cond_func,
 
2259
                             field, Item_func::LT_FUNC,
 
2260
                             value_item,
 
2261
                             cmp_type);
 
2262
          if (! tree)
3888
2263
            break;
3889
2264
          i++;
3890
 
        } while (i < func->array->count && tree->type == SEL_TREE::IMPOSSIBLE);
 
2265
        } while (i < func->array->count && tree->type == optimizer::SEL_TREE::IMPOSSIBLE);
3891
2266
 
3892
 
        if (!tree || tree->type == SEL_TREE::IMPOSSIBLE)
 
2267
        if (!tree || tree->type == optimizer::SEL_TREE::IMPOSSIBLE)
3893
2268
        {
3894
2269
          /* We get here in cases like "t.unsigned NOT IN (-1,-2,-3) */
3895
2270
          tree= NULL;
3896
2271
          break;
3897
2272
        }
3898
 
        SEL_TREE *tree2;
 
2273
        optimizer::SEL_TREE *tree2= NULL;
3899
2274
        for (; i < func->array->count; i++)
3900
2275
        {
3901
2276
          if (func->array->compare_elems(i, i-1))
3902
2277
          {
3903
 
            /* Get a SEL_TREE for "-inf < X < c_i" interval */
 
2278
            /* Get a optimizer::SEL_TREE for "-inf < X < c_i" interval */
3904
2279
            func->array->value_to_item(i, value_item);
3905
2280
            tree2= get_mm_parts(param, cond_func, field, Item_func::LT_FUNC,
3906
2281
                                value_item, cmp_type);
3913
2288
            /* Change all intervals to be "c_{i-1} < X < c_i" */
3914
2289
            for (uint32_t idx= 0; idx < param->keys; idx++)
3915
2290
            {
3916
 
              SEL_ARG *new_interval, *last_val;
 
2291
              optimizer::SEL_ARG *new_interval, *last_val;
3917
2292
              if (((new_interval= tree2->keys[idx])) &&
3918
2293
                  (tree->keys[idx]) &&
3919
2294
                  ((last_val= tree->keys[idx]->last())))
3930
2305
          }
3931
2306
        }
3932
2307
 
3933
 
        if (tree && tree->type != SEL_TREE::IMPOSSIBLE)
 
2308
        if (tree && tree->type != optimizer::SEL_TREE::IMPOSSIBLE)
3934
2309
        {
3935
2310
          /*
3936
 
            Get the SEL_TREE for the last "c_last < X < +inf" interval
 
2311
            Get the optimizer::SEL_TREE for the last "c_last < X < +inf" interval
3937
2312
            (value_item cotains c_last already)
3938
2313
          */
3939
2314
          tree2= get_mm_parts(param, cond_func, field, Item_func::GT_FUNC,
3997
2372
 
3998
2373
 
3999
2374
/*
4000
 
  Build conjunction of all SEL_TREEs for a simple predicate applying equalities
 
2375
  Build conjunction of all optimizer::SEL_TREEs for a simple predicate applying equalities
4001
2376
 
4002
2377
  SYNOPSIS
4003
2378
    get_full_func_mm_tree()
4004
 
      param       PARAM from SQL_SELECT::test_quick_select
 
2379
      param       Parameter from SqlSelect::test_quick_select
4005
2380
      cond_func   item for the predicate
4006
2381
      field_item  field in the predicate
4007
2382
      value       constant in the predicate
4012
2387
 
4013
2388
  DESCRIPTION
4014
2389
    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
 
2390
    c is a constant, the function builds a conjunction of all optimizer::SEL_TREES that can
4016
2391
    be obtained by the substitution of f for all different fields equal to f.
4017
2392
 
4018
2393
  NOTES
4022
2397
    each fj belonging to the same multiple equality as fi
4023
2398
    are built as well.
4024
2399
    E.g. for WHERE t1.a=t2.a AND t2.a > 10
4025
 
    a SEL_TREE for t2.a > 10 will be built for quick select from t2
 
2400
    a optimizer::SEL_TREE for t2.a > 10 will be built for quick select from t2
4026
2401
    and
4027
 
    a SEL_TREE for t1.a > 10 will be built for quick select from t1.
 
2402
    a optimizer::SEL_TREE for t1.a > 10 will be built for quick select from t1.
4028
2403
 
4029
2404
    A BETWEEN predicate of the form (fi [NOT] BETWEEN c1 AND c2) is treated
4030
2405
    in a similar way: we build a conjuction of trees for the results
4063
2438
    the form (c IN (c1,...,f,...,cn)).
4064
2439
 
4065
2440
  RETURN
4066
 
    Pointer to the tree representing the built conjunction of SEL_TREEs
 
2441
    Pointer to the tree representing the built conjunction of optimizer::SEL_TREEs
4067
2442
*/
4068
2443
 
4069
 
static SEL_TREE *get_full_func_mm_tree(RANGE_OPT_PARAM *param,
 
2444
static optimizer::SEL_TREE *get_full_func_mm_tree(optimizer::RangeParameter *param,
4070
2445
                                       Item_func *cond_func,
4071
2446
                                       Item_field *field_item, Item *value,
4072
2447
                                       bool inv)
4073
2448
{
4074
 
  SEL_TREE *tree= 0;
4075
 
  SEL_TREE *ftree= 0;
 
2449
  optimizer::SEL_TREE *tree= 0;
 
2450
  optimizer::SEL_TREE *ftree= 0;
4076
2451
  table_map ref_tables= 0;
4077
2452
  table_map param_comp= ~(param->prev_tables | param->read_tables |
4078
2453
                          param->current_table);
4083
2458
    if (arg != field_item)
4084
2459
      ref_tables|= arg->used_tables();
4085
2460
  }
 
2461
 
4086
2462
  Field *field= field_item->field;
 
2463
  field->setWriteSet();
 
2464
 
4087
2465
  Item_result cmp_type= field->cmp_type();
4088
 
  if (!((ref_tables | field->table->map) & param_comp))
 
2466
  if (!((ref_tables | field->getTable()->map) & param_comp))
4089
2467
    ftree= get_func_mm_tree(param, cond_func, field, value, cmp_type, inv);
4090
2468
  Item_equal *item_equal= field_item->item_equal;
4091
2469
  if (item_equal)
4092
2470
  {
4093
 
    Item_equal_iterator it(*item_equal);
 
2471
    Item_equal_iterator it(item_equal->begin());
4094
2472
    Item_field *item;
4095
2473
    while ((item= it++))
4096
2474
    {
4097
2475
      Field *f= item->field;
 
2476
      f->setWriteSet();
 
2477
 
4098
2478
      if (field->eq(f))
4099
2479
        continue;
4100
 
      if (!((ref_tables | f->table->map) & param_comp))
 
2480
      if (!((ref_tables | f->getTable()->map) & param_comp))
4101
2481
      {
4102
2482
        tree= get_func_mm_tree(param, cond_func, f, value, cmp_type, inv);
4103
2483
        ftree= !ftree ? tree : tree_and(param, ftree, tree);
4109
2489
 
4110
2490
        /* make a select tree of all keys in condition */
4111
2491
 
4112
 
static SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param,COND *cond)
 
2492
static optimizer::SEL_TREE *get_mm_tree(optimizer::RangeParameter *param, COND *cond)
4113
2493
{
4114
 
  SEL_TREE *tree=0;
4115
 
  SEL_TREE *ftree= 0;
 
2494
  optimizer::SEL_TREE *tree=0;
 
2495
  optimizer::SEL_TREE *ftree= 0;
4116
2496
  Item_field *field_item= 0;
4117
2497
  bool inv= false;
4118
2498
  Item *value= 0;
4119
2499
 
4120
2500
  if (cond->type() == Item::COND_ITEM)
4121
2501
  {
4122
 
    List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
 
2502
    List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
4123
2503
 
4124
2504
    if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
4125
2505
    {
4126
2506
      tree=0;
4127
 
      Item *item;
4128
 
      while ((item=li++))
 
2507
      while (Item* item=li++)
4129
2508
      {
4130
 
        SEL_TREE *new_tree=get_mm_tree(param,item);
 
2509
        optimizer::SEL_TREE *new_tree= get_mm_tree(param,item);
4131
2510
        if (param->session->is_fatal_error ||
4132
 
            param->alloced_sel_args > SEL_ARG::MAX_SEL_ARGS)
 
2511
            param->alloced_sel_args > optimizer::SEL_ARG::MAX_SEL_ARGS)
4133
2512
          return 0;     // out of memory
4134
2513
        tree=tree_and(param,tree,new_tree);
4135
 
        if (tree && tree->type == SEL_TREE::IMPOSSIBLE)
 
2514
        if (tree && tree->type == optimizer::SEL_TREE::IMPOSSIBLE)
4136
2515
          break;
4137
2516
      }
4138
2517
    }
4139
2518
    else
4140
2519
    {                                           // COND OR
4141
 
      tree=get_mm_tree(param,li++);
 
2520
      tree= get_mm_tree(param,li++);
4142
2521
      if (tree)
4143
2522
      {
4144
 
        Item *item;
4145
 
        while ((item=li++))
 
2523
        while (Item* item= li++)
4146
2524
        {
4147
 
          SEL_TREE *new_tree=get_mm_tree(param,item);
 
2525
          optimizer::SEL_TREE *new_tree= get_mm_tree(param,item);
4148
2526
          if (!new_tree)
4149
2527
            return 0;   // out of memory
4150
2528
          tree=tree_or(param,tree,new_tree);
4151
 
          if (!tree || tree->type == SEL_TREE::ALWAYS)
 
2529
          if (!tree || tree->type == optimizer::SEL_TREE::ALWAYS)
4152
2530
            break;
4153
2531
        }
4154
2532
      }
4155
2533
    }
4156
2534
    return(tree);
4157
2535
  }
4158
 
  /* Here when simple cond */
4159
 
  if (cond->const_item())
 
2536
  /* Here when simple cond
 
2537
     There are limits on what kinds of const items we can evaluate, grep for
 
2538
     DontEvaluateMaterializedSubqueryTooEarly.
 
2539
  */
 
2540
  if (cond->const_item()  && !cond->is_expensive())
4160
2541
  {
4161
2542
    /*
4162
2543
      During the cond->val_int() evaluation we can come across a subselect
4164
2545
      all the memory allocated has the same life span as the subselect
4165
2546
      item itself. So we have to restore the thread's mem_root here.
4166
2547
    */
4167
 
    MEM_ROOT *tmp_root= param->mem_root;
 
2548
    memory::Root *tmp_root= param->mem_root;
4168
2549
    param->session->mem_root= param->old_root;
4169
 
    tree= cond->val_int() ? new(tmp_root) SEL_TREE(SEL_TREE::ALWAYS) :
4170
 
                            new(tmp_root) SEL_TREE(SEL_TREE::IMPOSSIBLE);
 
2550
    tree= cond->val_int() ? new(tmp_root) optimizer::SEL_TREE(optimizer::SEL_TREE::ALWAYS) :
 
2551
                            new(tmp_root) optimizer::SEL_TREE(optimizer::SEL_TREE::IMPOSSIBLE);
4171
2552
    param->session->mem_root= tmp_root;
4172
2553
    return(tree);
4173
2554
  }
4181
2562
    if ((ref_tables & param->current_table) ||
4182
2563
        (ref_tables & ~(param->prev_tables | param->read_tables)))
4183
2564
      return 0;
4184
 
    return(new SEL_TREE(SEL_TREE::MAYBE));
 
2565
    return(new optimizer::SEL_TREE(optimizer::SEL_TREE::MAYBE));
4185
2566
  }
4186
2567
 
4187
2568
  Item_func *cond_func= (Item_func*) cond;
4210
2591
      if (cond_func->arguments()[i]->real_item()->type() == Item::FIELD_ITEM)
4211
2592
      {
4212
2593
        field_item= (Item_field*) (cond_func->arguments()[i]->real_item());
4213
 
        SEL_TREE *tmp= get_full_func_mm_tree(param, cond_func,
 
2594
        optimizer::SEL_TREE *tmp= get_full_func_mm_tree(param, cond_func,
4214
2595
                                    field_item, (Item*)(intptr_t)i, inv);
4215
2596
        if (inv)
4216
2597
          tree= !tree ? tmp : tree_or(param, tree, tmp);
4240
2621
    Item_equal *item_equal= (Item_equal *) cond;
4241
2622
    if (!(value= item_equal->get_const()))
4242
2623
      return 0;
4243
 
    Item_equal_iterator it(*item_equal);
 
2624
    Item_equal_iterator it(item_equal->begin());
4244
2625
    ref_tables= value->used_tables();
4245
2626
    while ((field_item= it++))
4246
2627
    {
4247
2628
      Field *field= field_item->field;
 
2629
      field->setWriteSet();
 
2630
 
4248
2631
      Item_result cmp_type= field->cmp_type();
4249
 
      if (!((ref_tables | field->table->map) & param_comp))
 
2632
      if (!((ref_tables | field->getTable()->map) & param_comp))
4250
2633
      {
4251
2634
        tree= get_mm_parts(param, cond, field, Item_func::EQ_FUNC,
4252
2635
                           value,cmp_type);
4278
2661
}
4279
2662
 
4280
2663
 
4281
 
static SEL_TREE *
4282
 
get_mm_parts(RANGE_OPT_PARAM *param, COND *cond_func, Field *field,
4283
 
             Item_func::Functype type,
4284
 
             Item *value, Item_result)
 
2664
static optimizer::SEL_TREE *
 
2665
get_mm_parts(optimizer::RangeParameter *param,
 
2666
             COND *cond_func,
 
2667
             Field *field,
 
2668
                   Item_func::Functype type,
 
2669
                   Item *value, Item_result)
4285
2670
{
4286
 
  if (field->table != param->table)
 
2671
  if (field->getTable() != param->table)
4287
2672
    return 0;
4288
2673
 
4289
2674
  KEY_PART *key_part = param->key_parts;
4290
2675
  KEY_PART *end = param->key_parts_end;
4291
 
  SEL_TREE *tree=0;
 
2676
  optimizer::SEL_TREE *tree=0;
4292
2677
  if (value &&
4293
2678
      value->used_tables() & ~(param->prev_tables | param->read_tables))
4294
2679
    return 0;
4295
 
  for (; key_part != end ; key_part++)
 
2680
  for (; key_part != end; key_part++)
4296
2681
  {
4297
2682
    if (field->eq(key_part->field))
4298
2683
    {
4299
 
      SEL_ARG *sel_arg=0;
4300
 
      if (!tree && !(tree=new SEL_TREE()))
4301
 
        return 0;                               // OOM
 
2684
      optimizer::SEL_ARG *sel_arg=0;
 
2685
      if (!tree)
 
2686
        tree= new optimizer::SEL_TREE;
4302
2687
      if (!value || !(value->used_tables() & ~param->read_tables))
4303
2688
      {
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;
4311
 
          return(tree);
4312
 
        }
 
2689
        sel_arg= get_mm_leaf(param,cond_func, key_part->field,key_part,type,value);
 
2690
        if (! sel_arg)
 
2691
          continue;
 
2692
        if (sel_arg->type == optimizer::SEL_ARG::IMPOSSIBLE)
 
2693
        {
 
2694
          tree->type=optimizer::SEL_TREE::IMPOSSIBLE;
 
2695
          return(tree);
 
2696
        }
4313
2697
      }
4314
2698
      else
4315
2699
      {
4316
 
        // This key may be used later
4317
 
        if (!(sel_arg= new SEL_ARG(SEL_ARG::MAYBE_KEY)))
4318
 
          return 0;                     // OOM
 
2700
        // This key may be used later
 
2701
        sel_arg= new optimizer::SEL_ARG(optimizer::SEL_ARG::MAYBE_KEY);
4319
2702
      }
4320
2703
      sel_arg->part=(unsigned char) key_part->part;
4321
2704
      tree->keys[key_part->key]=sel_add(tree->keys[key_part->key],sel_arg);
4322
 
      tree->keys_map.set_bit(key_part->key);
 
2705
      tree->keys_map.set(key_part->key);
4323
2706
    }
4324
2707
  }
4325
2708
 
4326
 
  return(tree);
 
2709
  return tree;
4327
2710
}
4328
2711
 
4329
2712
 
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)
 
2713
static optimizer::SEL_ARG *
 
2714
get_mm_leaf(optimizer::RangeParameter *param,
 
2715
            COND *conf_func,
 
2716
            Field *field,
 
2717
            KEY_PART *key_part,
 
2718
            Item_func::Functype type,
 
2719
            Item *value)
4333
2720
{
4334
 
  uint32_t maybe_null=(uint) field->real_maybe_null();
 
2721
  uint32_t maybe_null=(uint32_t) field->real_maybe_null();
4335
2722
  bool optimize_range;
4336
 
  SEL_ARG *tree= 0;
4337
 
  MEM_ROOT *alloc= param->mem_root;
 
2723
  optimizer::SEL_ARG *tree= NULL;
 
2724
  memory::Root *alloc= param->mem_root;
4338
2725
  unsigned char *str;
4339
 
  ulong orig_sql_mode;
4340
 
  int err;
 
2726
  int err= 0;
4341
2727
 
4342
2728
  /*
4343
2729
    We need to restore the runtime mem_root of the thread in this
4345
2731
    the argument can be any, e.g. a subselect. The subselect
4346
2732
    items, in turn, assume that all the memory allocated during
4347
2733
    the evaluation has the same life span as the item itself.
4348
 
    TODO: opt_range.cc should not reset session->mem_root at all.
 
2734
    TODO: opitimizer/range.cc should not reset session->mem_root at all.
4349
2735
  */
4350
2736
  param->session->mem_root= param->old_root;
4351
2737
  if (!value)                                   // IS NULL or IS NOT NULL
4352
2738
  {
4353
 
    if (field->table->maybe_null)               // Can't use a key on this
 
2739
    if (field->getTable()->maybe_null)          // Can't use a key on this
4354
2740
      goto end;
4355
2741
    if (!maybe_null)                            // Not null field
4356
2742
    {
4357
2743
      if (type == Item_func::ISNULL_FUNC)
4358
 
        tree= &null_element;
 
2744
        tree= &optimizer::null_element;
4359
2745
      goto end;
4360
2746
    }
4361
 
    if (!(tree= new (alloc) SEL_ARG(field,is_null_string,is_null_string)))
4362
 
      goto end;                                 // out of memory
 
2747
    tree= new (*alloc) optimizer::SEL_ARG(field,is_null_string,is_null_string);
4363
2748
    if (type == Item_func::ISNOTNULL_FUNC)
4364
2749
    {
4365
2750
      tree->min_flag=NEAR_MIN;              /* IS NOT NULL ->  X > NULL */
4382
2767
  */
4383
2768
  if (field->result_type() == STRING_RESULT &&
4384
2769
      value->result_type() == STRING_RESULT &&
4385
 
      key_part->image_type == Field::itRAW &&
4386
2770
      ((Field_str*)field)->charset() != conf_func->compare_collation() &&
4387
2771
      !(conf_func->compare_collation()->state & MY_CS_BINSORT))
4388
2772
    goto end;
4389
2773
 
4390
2774
  if (param->using_real_indexes)
4391
 
    optimize_range= field->optimize_range(param->real_keynr[key_part->key],
4392
 
                                          key_part->part);
 
2775
    optimize_range= field->optimize_range(param->real_keynr[key_part->key], key_part->part);
4393
2776
  else
4394
2777
    optimize_range= true;
4395
2778
 
4406
2789
      goto end;
4407
2790
    if (!(res= value->val_str(&tmp)))
4408
2791
    {
4409
 
      tree= &null_element;
 
2792
      tree= &optimizer::null_element;
4410
2793
      goto end;
4411
2794
    }
4412
2795
 
4436
2819
    {
4437
2820
      if (unlikely(length < field_length))
4438
2821
      {
4439
 
        /*
4440
 
          This can only happen in a table created with UNIREG where one key
4441
 
          overlaps many fields
4442
 
        */
4443
 
        length= field_length;
 
2822
        /*
 
2823
          This can only happen in a table created with UNIREG where one key
 
2824
          overlaps many fields
 
2825
        */
 
2826
        length= field_length;
4444
2827
      }
4445
2828
      else
4446
 
        field_length= length;
 
2829
        field_length= length;
4447
2830
    }
4448
2831
    length+=offset;
4449
 
    if (!(min_str= (unsigned char*) alloc_root(alloc, length*2)))
4450
 
      goto end;
4451
 
 
 
2832
    min_str= alloc->alloc(length*2);
4452
2833
    max_str=min_str+length;
4453
2834
    if (maybe_null)
4454
2835
      max_str[0]= min_str[0]=0;
4455
2836
 
4456
2837
    field_length-= maybe_null;
 
2838
    int escape_code= make_escape_code(field->charset(), ((Item_func_like*)(param->cond))->escape);
4457
2839
    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);
 
2840
                              res->ptr(), res->length(),
 
2841
                              escape_code,
 
2842
                              internal::wild_one, internal::wild_many,
 
2843
                              field_length,
 
2844
                              (char*) min_str+offset, (char*) max_str+offset,
 
2845
                              &min_length, &max_length);
4464
2846
    if (like_error)                             // Can't optimize with LIKE
4465
2847
      goto end;
4466
2848
 
4469
2851
      int2store(min_str+maybe_null,min_length);
4470
2852
      int2store(max_str+maybe_null,max_length);
4471
2853
    }
4472
 
    tree= new (alloc) SEL_ARG(field, min_str, max_str);
 
2854
    tree= new (alloc) optimizer::SEL_ARG(field, min_str, max_str);
4473
2855
    goto end;
4474
2856
  }
4475
2857
 
4476
 
  if (!optimize_range &&
 
2858
  if (! optimize_range &&
4477
2859
      type != Item_func::EQ_FUNC &&
4478
2860
      type != Item_func::EQUAL_FUNC)
4479
2861
    goto end;                                   // Can't optimize this
4486
2868
      value->result_type() != STRING_RESULT &&
4487
2869
      field->cmp_type() != value->result_type())
4488
2870
    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 &&
4492
 
      (field->type() == DRIZZLE_TYPE_DATE ||
4493
 
       field->type() == DRIZZLE_TYPE_DATETIME))
4494
 
    field->table->in_use->variables.sql_mode|= MODE_INVALID_DATES;
4495
 
  err= value->save_in_field_no_warnings(field, 1);
 
2871
 
 
2872
  /*
 
2873
   * Some notes from Jay...
 
2874
   *
 
2875
   * OK, so previously, and in MySQL, what the optimizer does here is
 
2876
   * override the sql_mode variable to ignore out-of-range or bad date-
 
2877
   * time values.  It does this because the optimizer is populating the
 
2878
   * field variable with the incoming value from the comparison field,
 
2879
   * and the value may exceed the bounds of a proper column type.
 
2880
   *
 
2881
   * For instance, assume the following:
 
2882
   *
 
2883
   * CREATE TABLE t1 (ts TIMESTAMP);
 
2884
   * INSERT INTO t1 ('2009-03-04 00:00:00');
 
2885
   * CREATE TABLE t2 (dt1 DATETIME, dt2 DATETIME);
 
2886
   * INSERT INT t2 ('2003-12-31 00:00:00','2999-12-31 00:00:00');
 
2887
   *
 
2888
   * If we issue this query:
 
2889
   *
 
2890
   * SELECT * FROM t1, t2 WHERE t1.ts BETWEEN t2.dt1 AND t2.dt2;
 
2891
   *
 
2892
   * We will come into bounds issues.  Field_timestamp::store() will be
 
2893
   * called with a datetime value of "2999-12-31 00:00:00" and will throw
 
2894
   * an error for out-of-bounds.  MySQL solves this via a hack with sql_mode
 
2895
   * but Drizzle always throws errors on bad data storage in a Field class.
 
2896
   *
 
2897
   * Therefore, to get around the problem of the Field class being used for
 
2898
   * "storage" here without actually storing anything...we must check to see
 
2899
   * if the value being stored in a Field_timestamp here is out of range.  If
 
2900
   * it is, then we must convert to the highest Timestamp value (or lowest,
 
2901
   * depending on whether the datetime is before or after the epoch.
 
2902
   */
 
2903
  if (field->is_timestamp())
 
2904
  {
 
2905
    /*
 
2906
     * The left-side of the range comparison is a timestamp field.  Therefore,
 
2907
     * we must check to see if the value in the right-hand side is outside the
 
2908
     * range of the UNIX epoch, and cut to the epoch bounds if it is.
 
2909
     */
 
2910
    /* Datetime and date columns are Item::FIELD_ITEM ... and have a result type of STRING_RESULT */
 
2911
    if (value->real_item()->type() == Item::FIELD_ITEM
 
2912
        && value->result_type() == STRING_RESULT)
 
2913
    {
 
2914
      char buff[DateTime::MAX_STRING_LENGTH];
 
2915
      String tmp(buff, sizeof(buff), &my_charset_bin);
 
2916
      String *res= value->val_str(&tmp);
 
2917
 
 
2918
      if (!res)
 
2919
        goto end;
 
2920
      else
 
2921
      {
 
2922
        /*
 
2923
         * Create a datetime from the string and compare to fixed timestamp
 
2924
         * instances representing the epoch boundaries.
 
2925
         */
 
2926
        DateTime value_datetime;
 
2927
 
 
2928
        if (! value_datetime.from_string(res->c_ptr(), (size_t) res->length()))
 
2929
          goto end;
 
2930
 
 
2931
        Timestamp max_timestamp;
 
2932
        Timestamp min_timestamp;
 
2933
 
 
2934
        (void) max_timestamp.from_time_t((time_t) INT32_MAX);
 
2935
        (void) min_timestamp.from_time_t((time_t) 0);
 
2936
 
 
2937
        /* We rely on Temporal class operator overloads to do our comparisons. */
 
2938
        if (value_datetime < min_timestamp)
 
2939
        {
 
2940
          /*
 
2941
           * Datetime in right-hand side column is before UNIX epoch, so adjust to
 
2942
           * lower bound.
 
2943
           */
 
2944
          char new_value_buff[DateTime::MAX_STRING_LENGTH];
 
2945
          int new_value_length;
 
2946
          String new_value_string(new_value_buff, sizeof(new_value_buff), &my_charset_bin);
 
2947
 
 
2948
          new_value_length= min_timestamp.to_string(new_value_string.c_ptr(),
 
2949
                                    DateTime::MAX_STRING_LENGTH);
 
2950
          assert((new_value_length+1) < DateTime::MAX_STRING_LENGTH);
 
2951
          new_value_string.length(new_value_length);
 
2952
          err= value->save_str_value_in_field(field, &new_value_string);
 
2953
        }
 
2954
        else if (value_datetime > max_timestamp)
 
2955
        {
 
2956
          /*
 
2957
           * Datetime in right hand side column is after UNIX epoch, so adjust
 
2958
           * to the higher bound of the epoch.
 
2959
           */
 
2960
          char new_value_buff[DateTime::MAX_STRING_LENGTH];
 
2961
          int new_value_length;
 
2962
          String new_value_string(new_value_buff, sizeof(new_value_buff), &my_charset_bin);
 
2963
 
 
2964
          new_value_length= max_timestamp.to_string(new_value_string.c_ptr(),
 
2965
                                        DateTime::MAX_STRING_LENGTH);
 
2966
          assert((new_value_length+1) < DateTime::MAX_STRING_LENGTH);
 
2967
          new_value_string.length(new_value_length);
 
2968
          err= value->save_str_value_in_field(field, &new_value_string);
 
2969
        }
 
2970
        else
 
2971
          err= value->save_in_field(field, 1);
 
2972
      }
 
2973
    }
 
2974
    else /* Not a datetime -> timestamp comparison */
 
2975
      err= value->save_in_field(field, 1);
 
2976
  }
 
2977
  else /* Not a timestamp comparison */
 
2978
    err= value->save_in_field(field, 1);
 
2979
 
4496
2980
  if (err > 0)
4497
2981
  {
4498
2982
    if (field->cmp_type() != value->result_type())
4501
2985
          value->result_type() == item_cmp_type(field->result_type(),
4502
2986
                                                value->result_type()))
4503
2987
      {
4504
 
        tree= new (alloc) SEL_ARG(field, 0, 0);
4505
 
        tree->type= SEL_ARG::IMPOSSIBLE;
 
2988
        tree= new (alloc) optimizer::SEL_ARG(field, 0, 0);
 
2989
        tree->type= optimizer::SEL_ARG::IMPOSSIBLE;
4506
2990
        goto end;
4507
2991
      }
4508
2992
      else
4555
3039
               (value->val_int() < 0))
4556
3040
        type = Item_func::GE_FUNC;
4557
3041
    }
 
3042
    else if (err == 1)
 
3043
    {
 
3044
      tree= new (alloc) optimizer::SEL_ARG(field, 0, 0);
 
3045
      tree->type= optimizer::SEL_ARG::IMPOSSIBLE;
 
3046
      goto end;
 
3047
    }
4558
3048
  }
4559
3049
  else if (err < 0)
4560
3050
  {
4561
 
    field->table->in_use->variables.sql_mode= orig_sql_mode;
4562
3051
    /* This happens when we try to insert a NULL field in a not null column */
4563
 
    tree= &null_element;                        // cmp with NULL is never true
4564
 
    goto end;
4565
 
  }
4566
 
  field->table->in_use->variables.sql_mode= orig_sql_mode;
4567
 
  str= (unsigned char*) alloc_root(alloc, key_part->store_length+1);
4568
 
  if (!str)
4569
 
    goto end;
 
3052
    tree= &optimizer::null_element;                        // cmp with NULL is never true
 
3053
    goto end;
 
3054
  }
 
3055
 
 
3056
  /*
 
3057
    Any predicate except "<=>"(null-safe equality operator) involving NULL as a
 
3058
    constant is always FALSE
 
3059
    Put IMPOSSIBLE Tree(null_element) here.
 
3060
  */
 
3061
  if (type != Item_func::EQUAL_FUNC && field->is_real_null())
 
3062
  {
 
3063
    tree= &optimizer::null_element;
 
3064
    goto end;
 
3065
  }
 
3066
 
 
3067
  str= alloc->alloc(key_part->store_length+1);
4570
3068
  if (maybe_null)
4571
 
    *str= (unsigned char) field->is_real_null();        // Set to 1 if null
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
 
3069
    *str= field->is_real_null();        // Set to 1 if null
 
3070
  field->get_key_image(str+maybe_null, key_part->length);
 
3071
  tree= new (alloc) optimizer::SEL_ARG(field, str, str);
4576
3072
 
4577
3073
  /*
4578
3074
    Check if we are comparing an UNSIGNED integer with a negative constant.
4594
3090
    {
4595
3091
      if (type == Item_func::LT_FUNC || type == Item_func::LE_FUNC)
4596
3092
      {
4597
 
        tree->type= SEL_ARG::IMPOSSIBLE;
 
3093
        tree->type= optimizer::SEL_ARG::IMPOSSIBLE;
4598
3094
        goto end;
4599
3095
      }
4600
3096
      if (type == Item_func::GT_FUNC || type == Item_func::GE_FUNC)
4655
3151
  This will never be called for same key parts.
4656
3152
*/
4657
3153
 
4658
 
static SEL_ARG *
4659
 
sel_add(SEL_ARG *key1,SEL_ARG *key2)
 
3154
static optimizer::SEL_ARG *
 
3155
sel_add(optimizer::SEL_ARG *key1, optimizer::SEL_ARG *key2)
4660
3156
{
4661
 
  SEL_ARG *root,**key_link;
 
3157
  optimizer::SEL_ARG *root= NULL;
 
3158
  optimizer::SEL_ARG **key_link= NULL;
4662
3159
 
4663
3160
  if (!key1)
4664
3161
    return key2;
4685
3182
  return root;
4686
3183
}
4687
3184
 
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)
 
3185
static const int CLONE_KEY1_MAYBE= 1;
 
3186
static const int CLONE_KEY2_MAYBE= 2;
 
3187
 
 
3188
static uint32_t swap_clone_flag(uint32_t a)
 
3189
{
 
3190
  return ((a & 1) << 1) | ((a & 2) >> 1);
 
3191
}
 
3192
 
 
3193
static optimizer::SEL_TREE *
 
3194
tree_and(optimizer::RangeParameter *param, optimizer::SEL_TREE *tree1, optimizer::SEL_TREE *tree2)
4695
3195
{
4696
3196
  if (!tree1)
4697
3197
    return(tree2);
4698
3198
  if (!tree2)
4699
3199
    return(tree1);
4700
 
  if (tree1->type == SEL_TREE::IMPOSSIBLE || tree2->type == SEL_TREE::ALWAYS)
 
3200
  if (tree1->type == optimizer::SEL_TREE::IMPOSSIBLE || tree2->type == optimizer::SEL_TREE::ALWAYS)
4701
3201
    return(tree1);
4702
 
  if (tree2->type == SEL_TREE::IMPOSSIBLE || tree1->type == SEL_TREE::ALWAYS)
 
3202
  if (tree2->type == optimizer::SEL_TREE::IMPOSSIBLE || tree1->type == optimizer::SEL_TREE::ALWAYS)
4703
3203
    return(tree2);
4704
 
  if (tree1->type == SEL_TREE::MAYBE)
 
3204
  if (tree1->type == optimizer::SEL_TREE::MAYBE)
4705
3205
  {
4706
 
    if (tree2->type == SEL_TREE::KEY)
4707
 
      tree2->type=SEL_TREE::KEY_SMALLER;
 
3206
    if (tree2->type == optimizer::SEL_TREE::KEY)
 
3207
      tree2->type=optimizer::SEL_TREE::KEY_SMALLER;
4708
3208
    return(tree2);
4709
3209
  }
4710
 
  if (tree2->type == SEL_TREE::MAYBE)
 
3210
  if (tree2->type == optimizer::SEL_TREE::MAYBE)
4711
3211
  {
4712
 
    tree1->type=SEL_TREE::KEY_SMALLER;
 
3212
    tree1->type=optimizer::SEL_TREE::KEY_SMALLER;
4713
3213
    return(tree1);
4714
3214
  }
4715
3215
  key_map  result_keys;
4716
 
  result_keys.clear_all();
 
3216
  result_keys.reset();
4717
3217
 
4718
3218
  /* Join the trees key per key */
4719
 
  SEL_ARG **key1,**key2,**end;
 
3219
  optimizer::SEL_ARG **key1,**key2,**end;
4720
3220
  for (key1= tree1->keys,key2= tree2->keys,end=key1+param->keys ;
4721
3221
       key1 != end ; key1++,key2++)
4722
3222
  {
4724
3224
    if (*key1 || *key2)
4725
3225
    {
4726
3226
      if (*key1 && !(*key1)->simple_key())
4727
 
        flag|=CLONE_KEY1_MAYBE;
 
3227
        flag|=CLONE_KEY1_MAYBE;
4728
3228
      if (*key2 && !(*key2)->simple_key())
4729
 
        flag|=CLONE_KEY2_MAYBE;
 
3229
        flag|=CLONE_KEY2_MAYBE;
4730
3230
      *key1=key_and(param, *key1, *key2, flag);
4731
 
      if (*key1 && (*key1)->type == SEL_ARG::IMPOSSIBLE)
 
3231
      if (*key1 && (*key1)->type == optimizer::SEL_ARG::IMPOSSIBLE)
4732
3232
      {
4733
 
        tree1->type= SEL_TREE::IMPOSSIBLE;
 
3233
        tree1->type= optimizer::SEL_TREE::IMPOSSIBLE;
4734
3234
        return(tree1);
4735
3235
      }
4736
 
      result_keys.set_bit(key1 - tree1->keys);
4737
 
#ifdef EXTRA_DEBUG
4738
 
        if (*key1 && param->alloced_sel_args < SEL_ARG::MAX_SEL_ARGS)
4739
 
          (*key1)->test_use_count(*key1);
4740
 
#endif
 
3236
      result_keys.set(key1 - tree1->keys);
4741
3237
    }
4742
3238
  }
4743
3239
  tree1->keys_map= result_keys;
4744
3240
  /* dispose index_merge if there is a "range" option */
4745
 
  if (!result_keys.is_clear_all())
 
3241
  if (result_keys.any())
4746
3242
  {
4747
 
    tree1->merges.empty();
 
3243
    tree1->merges.clear();
4748
3244
    return(tree1);
4749
3245
  }
4750
3246
 
4754
3250
}
4755
3251
 
4756
3252
 
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
 
 
4763
 
bool sel_trees_can_be_ored(SEL_TREE *tree1, SEL_TREE *tree2,
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())
4770
 
    return false;
4771
 
 
4772
 
  /* trees have a common key, check if they refer to same key part */
4773
 
  SEL_ARG **key1,**key2;
4774
 
  for (uint32_t key_no=0; key_no < param->keys; key_no++)
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
 
      {
4782
 
        return true;
4783
 
      }
4784
 
    }
4785
 
  }
4786
 
  return false;
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
4795
 
 
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
4807
 
 
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.
4816
 
 
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
4822
 
    st1 = SEL_TREE {
4823
 
      merges = SEL_IMERGE {
4824
 
                            SEL_TREE(t.key1part1 = 1),
4825
 
                            SEL_TREE(t.key2part2 = 2)   -- (*)
4826
 
                          }
4827
 
                   };
4828
 
    because
4829
 
     - (*) cannot be used to construct quick range select,
4830
 
     - There is no execution path that would cause (*) to be converted to
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
4837
 
    SEL_TREE that has the structure like st1 tree has, and conlcude that
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
 
{
4847
 
  bool res= false;
4848
 
  for (uint32_t i=0; i < param->keys; i++)
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
4858
 
        res= true;
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)
4869
 
    return 0;
4870
 
  if (tree1->type == SEL_TREE::IMPOSSIBLE || tree2->type == SEL_TREE::ALWAYS)
4871
 
    return(tree2);
4872
 
  if (tree2->type == SEL_TREE::IMPOSSIBLE || tree1->type == SEL_TREE::ALWAYS)
4873
 
    return(tree1);
4874
 
  if (tree1->type == SEL_TREE::MAYBE)
4875
 
    return(tree1);                              // Can't use this
4876
 
  if (tree2->type == SEL_TREE::MAYBE)
4877
 
    return(tree2);
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
4895
 
        if (param->alloced_sel_args < SEL_ARG::MAX_SEL_ARGS)
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)
4913
 
          return(new SEL_TREE(SEL_TREE::ALWAYS));
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())
4936
 
        std::swap(tree1, tree2);
4937
 
 
4938
 
      if (param->remove_jump_scans && remove_nonrange_trees(param, tree2))
4939
 
         return(new SEL_TREE(SEL_TREE::ALWAYS));
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
 
  }
4947
 
  return result;
4948
 
}
4949
 
 
4950
3253
 
4951
3254
/* And key trees where key1->part < key2 -> part */
4952
3255
 
4953
 
static SEL_ARG *
4954
 
and_all_keys(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2,
 
3256
static optimizer::SEL_ARG *
 
3257
and_all_keys(optimizer::RangeParameter *param,
 
3258
             optimizer::SEL_ARG *key1,
 
3259
             optimizer::SEL_ARG *key2,
4955
3260
             uint32_t clone_flag)
4956
3261
{
4957
 
  SEL_ARG *next;
 
3262
  optimizer::SEL_ARG *next= NULL;
4958
3263
  ulong use_count=key1->use_count;
4959
3264
 
4960
 
  if (key1->elements != 1)
 
3265
  if (key1->size() != 1)
4961
3266
  {
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);
 
3267
    key2->use_count+=key1->size()-1; //psergey: why we don't count that key1 has n-k-p?
 
3268
    key2->increment_use_count((int) key1->size()-1);
4964
3269
  }
4965
 
  if (key1->type == SEL_ARG::MAYBE_KEY)
 
3270
  if (key1->type == optimizer::SEL_ARG::MAYBE_KEY)
4966
3271
  {
4967
 
    key1->right= key1->left= &null_element;
 
3272
    key1->right= key1->left= &optimizer::null_element;
4968
3273
    key1->next= key1->prev= 0;
4969
3274
  }
4970
 
  for (next=key1->first(); next ; next=next->next)
 
3275
  for (next= key1->first(); next ; next=next->next)
4971
3276
  {
4972
3277
    if (next->next_key_part)
4973
3278
    {
4974
 
      SEL_ARG *tmp= key_and(param, next->next_key_part, key2, clone_flag);
4975
 
      if (tmp && tmp->type == SEL_ARG::IMPOSSIBLE)
 
3279
      optimizer::SEL_ARG *tmp= key_and(param, next->next_key_part, key2, clone_flag);
 
3280
      if (tmp && tmp->type == optimizer::SEL_ARG::IMPOSSIBLE)
4976
3281
      {
4977
 
        key1=key1->tree_delete(next);
4978
 
        continue;
 
3282
        key1=key1->tree_delete(next);
 
3283
        continue;
4979
3284
      }
4980
3285
      next->next_key_part=tmp;
4981
3286
      if (use_count)
4982
 
        next->increment_use_count(use_count);
4983
 
      if (param->alloced_sel_args > SEL_ARG::MAX_SEL_ARGS)
 
3287
        next->increment_use_count(use_count);
 
3288
      if (param->alloced_sel_args > optimizer::SEL_ARG::MAX_SEL_ARGS)
4984
3289
        break;
4985
3290
    }
4986
3291
    else
4987
3292
      next->next_key_part=key2;
4988
3293
  }
4989
 
  if (!key1)
4990
 
    return &null_element;                       // Impossible ranges
 
3294
  if (! key1)
 
3295
    return &optimizer::null_element;                    // Impossible ranges
4991
3296
  key1->use_count++;
4992
3297
  return key1;
4993
3298
}
5008
3313
    NULL if the result of AND operation is an empty interval {0}.
5009
3314
*/
5010
3315
 
5011
 
static SEL_ARG *
5012
 
key_and(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2, uint32_t clone_flag)
 
3316
static optimizer::SEL_ARG *
 
3317
key_and(optimizer::RangeParameter *param,
 
3318
        optimizer::SEL_ARG *key1,
 
3319
        optimizer::SEL_ARG *key2,
 
3320
        uint32_t clone_flag)
5013
3321
{
5014
 
  if (!key1)
 
3322
  if (! key1)
5015
3323
    return key2;
5016
 
  if (!key2)
 
3324
  if (! key2)
5017
3325
    return key1;
5018
3326
  if (key1->part != key2->part)
5019
3327
  {
5025
3333
    // key1->part < key2->part
5026
3334
    key1->use_count--;
5027
3335
    if (key1->use_count > 0)
5028
 
      if (!(key1= key1->clone_tree(param)))
5029
 
        return 0;                               // OOM
 
3336
      if (! (key1= key1->clone_tree(param)))
 
3337
        return 0;                               // OOM
5030
3338
    return and_all_keys(param, key1, key2, clone_flag);
5031
3339
  }
5032
3340
 
5033
3341
  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)
 
3342
       ! (clone_flag & CLONE_KEY1_MAYBE) &&
 
3343
       key2->type != optimizer::SEL_ARG::MAYBE_KEY) ||
 
3344
      key1->type == optimizer::SEL_ARG::MAYBE_KEY)
5037
3345
  {                                             // Put simple key in key2
5038
3346
    std::swap(key1, key2);
5039
 
    clone_flag=swap_clone_flag(clone_flag);
 
3347
    clone_flag= swap_clone_flag(clone_flag);
5040
3348
  }
5041
3349
 
5042
3350
  /* If one of the key is MAYBE_KEY then the found region may be smaller */
5043
 
  if (key2->type == SEL_ARG::MAYBE_KEY)
 
3351
  if (key2->type == optimizer::SEL_ARG::MAYBE_KEY)
5044
3352
  {
5045
3353
    if (key1->use_count > 1)
5046
3354
    {
5047
3355
      key1->use_count--;
5048
 
      if (!(key1=key1->clone_tree(param)))
5049
 
        return 0;                               // OOM
 
3356
      if (! (key1=key1->clone_tree(param)))
 
3357
        return 0;                               // OOM
5050
3358
      key1->use_count++;
5051
3359
    }
5052
 
    if (key1->type == SEL_ARG::MAYBE_KEY)
 
3360
    if (key1->type == optimizer::SEL_ARG::MAYBE_KEY)
5053
3361
    {                                           // Both are maybe key
5054
 
      key1->next_key_part=key_and(param, key1->next_key_part,
5055
 
                                  key2->next_key_part, clone_flag);
 
3362
      key1->next_key_part= key_and(param,
 
3363
                                   key1->next_key_part,
 
3364
                                   key2->next_key_part,
 
3365
                                   clone_flag);
5056
3366
      if (key1->next_key_part &&
5057
 
          key1->next_key_part->type == SEL_ARG::IMPOSSIBLE)
5058
 
        return key1;
 
3367
          key1->next_key_part->type == optimizer::SEL_ARG::IMPOSSIBLE)
 
3368
        return key1;
5059
3369
    }
5060
3370
    else
5061
3371
    {
5062
3372
      key1->maybe_smaller();
5063
3373
      if (key2->next_key_part)
5064
3374
      {
5065
 
        key1->use_count--;                      // Incremented in and_all_keys
5066
 
        return and_all_keys(param, key1, key2, clone_flag);
 
3375
        key1->use_count--;                      // Incremented in and_all_keys
 
3376
        return and_all_keys(param, key1, key2, clone_flag);
5067
3377
      }
5068
3378
      key2->use_count--;                        // Key2 doesn't have a tree
5069
3379
    }
5072
3382
 
5073
3383
  key1->use_count--;
5074
3384
  key2->use_count--;
5075
 
  SEL_ARG *e1=key1->first(), *e2=key2->first(), *new_tree=0;
 
3385
  optimizer::SEL_ARG *e1= key1->first();
 
3386
  optimizer::SEL_ARG *e2= key2->first();
 
3387
  optimizer::SEL_ARG *new_tree= NULL;
5076
3388
 
5077
3389
  while (e1 && e2)
5078
3390
  {
5079
 
    int cmp=e1->cmp_min_to_min(e2);
 
3391
    int cmp= e1->cmp_min_to_min(e2);
5080
3392
    if (cmp < 0)
5081
3393
    {
5082
 
      if (get_range(&e1,&e2,key1))
5083
 
        continue;
 
3394
      if (get_range(&e1, &e2, key1))
 
3395
        continue;
5084
3396
    }
5085
 
    else if (get_range(&e2,&e1,key2))
 
3397
    else if (get_range(&e2, &e1, key2))
5086
3398
      continue;
5087
 
    SEL_ARG *next=key_and(param, e1->next_key_part, e2->next_key_part,
5088
 
                          clone_flag);
 
3399
    optimizer::SEL_ARG *next= key_and(param,
 
3400
                                      e1->next_key_part,
 
3401
                                      e2->next_key_part,
 
3402
                                      clone_flag);
5089
3403
    e1->increment_use_count(1);
5090
3404
    e2->increment_use_count(1);
5091
 
    if (!next || next->type != SEL_ARG::IMPOSSIBLE)
 
3405
    if (! next || next->type != optimizer::SEL_ARG::IMPOSSIBLE)
5092
3406
    {
5093
 
      SEL_ARG *new_arg= e1->clone_and(e2);
5094
 
      if (!new_arg)
5095
 
        return &null_element;                   // End of memory
 
3407
      optimizer::SEL_ARG *new_arg= e1->clone_and(e2);
5096
3408
      new_arg->next_key_part=next;
5097
 
      if (!new_tree)
 
3409
      if (! new_tree)
5098
3410
      {
5099
 
        new_tree=new_arg;
 
3411
        new_tree=new_arg;
5100
3412
      }
5101
3413
      else
5102
 
        new_tree=new_tree->insert(new_arg);
 
3414
        new_tree=new_tree->insert(new_arg);
5103
3415
    }
5104
3416
    if (e1->cmp_max_to_max(e2) < 0)
5105
3417
      e1=e1->next;                              // e1 can't overlapp next e2
5108
3420
  }
5109
3421
  key1->free_tree();
5110
3422
  key2->free_tree();
5111
 
  if (!new_tree)
5112
 
    return &null_element;                       // Impossible range
 
3423
  if (! new_tree)
 
3424
    return &optimizer::null_element;                    // Impossible range
5113
3425
  return new_tree;
5114
3426
}
5115
3427
 
5116
3428
 
5117
3429
static bool
5118
 
get_range(SEL_ARG **e1,SEL_ARG **e2,SEL_ARG *root1)
 
3430
get_range(optimizer::SEL_ARG **e1, optimizer::SEL_ARG **e2, optimizer::SEL_ARG *root1)
5119
3431
{
5120
 
  (*e1)=root1->find_range(*e2);                 // first e1->min < e2->min
 
3432
  (*e1)= root1->find_range(*e2);                        // first e1->min < e2->min
5121
3433
  if ((*e1)->cmp_max_to_min(*e2) < 0)
5122
3434
  {
5123
 
    if (!((*e1)=(*e1)->next))
 
3435
    if (! ((*e1)=(*e1)->next))
5124
3436
      return 1;
5125
3437
    if ((*e1)->cmp_min_to_max(*e2) > 0)
5126
3438
    {
5132
3444
}
5133
3445
 
5134
3446
 
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
 
    {
5181
 
      std::swap(key1,key2);
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
 
 
5266
 
    // tmp.max >= key2.min && tmp.min <= key.cmax(overlapping ranges)
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)
5558
 
    return 0;                           // Maybe root later
5559
 
  if (remove_color == BLACK)
5560
 
    root=rb_delete_fixup(root,nod,fix_par);
5561
 
#ifdef EXTRA_DEBUG
5562
 
  test_rb_tree(root,root->parent);
5563
 
#endif /* EXTRA_DEBUG */
5564
 
 
5565
 
  root->use_count=this->use_count;              // Fix root counters
5566
 
  root->elements=this->elements-1;
5567
 
  root->maybe_flag=this->maybe_flag;
5568
 
  return(root);
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;
5660
 
#ifdef EXTRA_DEBUG
5661
 
  test_rb_tree(root,root->parent);
5662
 
#endif /* EXTRA_DEBUG */
5663
 
 
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
 
  {
5758
 
    errmsg_printf(ERRMSG_LVL_ERROR, "Wrong tree: Parent doesn't point at parent");
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
 
  {
5765
 
    errmsg_printf(ERRMSG_LVL_ERROR, "Wrong tree: Found two red in a row");
5766
 
    return -1;
5767
 
  }
5768
 
  if (element->left == element->right && element->left != &null_element)
5769
 
  {                                             // Dummy test
5770
 
    errmsg_printf(ERRMSG_LVL_ERROR, "Wrong tree: Found right == left");
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);
5779
 
    errmsg_printf(ERRMSG_LVL_ERROR, "Wrong tree: Incorrect black-count: %d - %d",
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"
5788
 
 
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
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
5802
 
       intervals of RB-tree pointed by "root",
5803
 
     - and so on.
5804
 
 
5805
 
    Here is an example (horizontal links represent next_key_part pointers,
5806
 
    vertical links - next/prev prev pointers):
5807
 
 
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
 
                  +---+       $
5826
 
  RETURN
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
 
{
5863
 
  uint32_t e_count=0;
5864
 
  if (this == root && use_count != 1)
5865
 
  {
5866
 
    errmsg_printf(ERRMSG_LVL_INFO, "Use_count: Wrong count %lu for root",use_count);
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
 
      {
5879
 
        errmsg_printf(ERRMSG_LVL_INFO, "Use_count: Wrong count for key at 0x%lx, %lu "
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)
5888
 
    errmsg_printf(ERRMSG_LVL_WARN, "Wrong use count: %u (should be %u) for tree at 0x%lx",
5889
 
                      e_count, elements, (long unsigned int) this);
5890
 
}
5891
 
 
5892
 
#endif
5893
 
 
5894
3447
/****************************************************************************
5895
3448
  MRR Range Sequence Interface implementation that walks a SEL_ARG* tree.
5896
3449
 ****************************************************************************/
5912
3465
 
5913
3466
  /* Number of key parts */
5914
3467
  uint32_t min_key_parts, max_key_parts;
5915
 
  SEL_ARG *key_tree;
 
3468
  optimizer::SEL_ARG *key_tree;
5916
3469
} RANGE_SEQ_ENTRY;
5917
3470
 
5918
3471
 
5921
3474
*/
5922
3475
typedef struct st_sel_arg_range_seq
5923
3476
{
5924
 
  uint32_t keyno;      /* index of used tree in SEL_TREE structure */
 
3477
  uint32_t keyno;      /* index of used tree in optimizer::SEL_TREE structure */
5925
3478
  uint32_t real_keyno; /* Number of the index in tables */
5926
 
  PARAM *param;
5927
 
  SEL_ARG *start; /* Root node of the traversed SEL_ARG* graph */
 
3479
  optimizer::Parameter *param;
 
3480
  optimizer::SEL_ARG *start; /* Root node of the traversed SEL_ARG* graph */
5928
3481
 
5929
3482
  RANGE_SEQ_ENTRY stack[MAX_REF_PARTS];
5930
3483
  int i; /* Index of last used element in the above array */
5946
3499
    Value of init_param
5947
3500
*/
5948
3501
 
5949
 
range_seq_t sel_arg_range_seq_init(void *init_param, uint32_t, uint32_t)
 
3502
static range_seq_t sel_arg_range_seq_init(void *init_param, uint32_t, uint32_t)
5950
3503
{
5951
3504
  SEL_ARG_RANGE_SEQ *seq= (SEL_ARG_RANGE_SEQ*)init_param;
5952
3505
  seq->at_start= true;
5963
3516
}
5964
3517
 
5965
3518
 
5966
 
static void step_down_to(SEL_ARG_RANGE_SEQ *arg, SEL_ARG *key_tree)
 
3519
static void step_down_to(SEL_ARG_RANGE_SEQ *arg, optimizer::SEL_ARG *key_tree)
5967
3520
{
5968
3521
  RANGE_SEQ_ENTRY *cur= &arg->stack[arg->i+1];
5969
3522
  RANGE_SEQ_ENTRY *prev= &arg->stack[arg->i];
6013
3566
*/
6014
3567
 
6015
3568
//psergey-merge-todo: support check_quick_keys:max_keypart
6016
 
uint32_t sel_arg_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range)
 
3569
static uint32_t sel_arg_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range)
6017
3570
{
6018
 
  SEL_ARG *key_tree;
 
3571
  optimizer::SEL_ARG *key_tree;
6019
3572
  SEL_ARG_RANGE_SEQ *seq= (SEL_ARG_RANGE_SEQ*)rseq;
6020
3573
  if (seq->at_start)
6021
3574
  {
6028
3581
  /* Ok, we're at some "full tuple" position in the tree */
6029
3582
 
6030
3583
  /* Step down if we can */
6031
 
  if (key_tree->next && key_tree->next != &null_element)
 
3584
  if (key_tree->next && key_tree->next != &optimizer::null_element)
6032
3585
  {
6033
3586
    //step down; (update the tuple, we'll step right and stay there)
6034
3587
    seq->i--;
6048
3601
    key_tree= seq->stack[seq->i].key_tree;
6049
3602
 
6050
3603
    /* Step down if we can */
6051
 
    if (key_tree->next && key_tree->next != &null_element)
 
3604
    if (key_tree->next && key_tree->next != &optimizer::null_element)
6052
3605
    {
6053
3606
      // Step down; update the tuple
6054
3607
      seq->i--;
6063
3616
    Walk right-up while we can
6064
3617
  */
6065
3618
walk_right_n_up:
6066
 
  while (key_tree->next_key_part && key_tree->next_key_part != &null_element &&
 
3619
  while (key_tree->next_key_part && key_tree->next_key_part != &optimizer::null_element &&
6067
3620
         key_tree->next_key_part->part == key_tree->part + 1 &&
6068
 
         key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
 
3621
         key_tree->next_key_part->type == optimizer::SEL_ARG::KEY_RANGE)
6069
3622
  {
6070
3623
    {
6071
3624
      RANGE_SEQ_ENTRY *cur= &seq->stack[seq->i];
6072
3625
      uint32_t min_key_length= cur->min_key - seq->param->min_key;
6073
3626
      uint32_t max_key_length= cur->max_key - seq->param->max_key;
6074
3627
      uint32_t len= cur->min_key - cur[-1].min_key;
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))
 
3628
      if (! (min_key_length == max_key_length &&
 
3629
          ! memcmp(cur[-1].min_key, cur[-1].max_key, len) &&
 
3630
          ! key_tree->min_flag && !key_tree->max_flag))
6078
3631
      {
6079
3632
        seq->param->is_ror_scan= false;
6080
 
        if (!key_tree->min_flag)
 
3633
        if (! key_tree->min_flag)
6081
3634
          cur->min_key_parts +=
6082
3635
            key_tree->next_key_part->store_min_key(seq->param->key[seq->keyno],
6083
3636
                                                   &cur->min_key,
6084
3637
                                                   &cur->min_key_flag);
6085
 
        if (!key_tree->max_flag)
 
3638
        if (! key_tree->max_flag)
6086
3639
          cur->max_key_parts +=
6087
3640
            key_tree->next_key_part->store_max_key(seq->param->key[seq->keyno],
6088
3641
                                                   &cur->max_key,
6098
3651
    key_tree= key_tree->next_key_part;
6099
3652
 
6100
3653
walk_up_n_right:
6101
 
    while (key_tree->prev && key_tree->prev != &null_element)
 
3654
    while (key_tree->prev && key_tree->prev != &optimizer::null_element)
6102
3655
    {
6103
3656
      /* Step up */
6104
3657
      key_tree= key_tree->prev;
6109
3662
  /* Ok got a tuple */
6110
3663
  RANGE_SEQ_ENTRY *cur= &seq->stack[seq->i];
6111
3664
 
6112
 
  range->ptr= (char*)(int)(key_tree->part);
 
3665
  range->ptr= (char*)(size_t)(key_tree->part);
6113
3666
  {
6114
3667
    range->range_flag= cur->min_key_flag | cur->max_key_flag;
6115
3668
 
6126
3679
    range->end_key.keypart_map= make_prev_keypart_map(cur->max_key_parts);
6127
3680
 
6128
3681
    if (!(cur->min_key_flag & ~NULL_RANGE) && !cur->max_key_flag &&
6129
 
        (uint)key_tree->part+1 == seq->param->table->key_info[seq->real_keyno].key_parts &&
 
3682
        (uint32_t)key_tree->part+1 == seq->param->table->key_info[seq->real_keyno].key_parts &&
6130
3683
        (seq->param->table->key_info[seq->real_keyno].flags & (HA_NOSAME)) ==
6131
3684
        HA_NOSAME &&
6132
3685
        range->start_key.length == range->end_key.length &&
6152
3705
    }
6153
3706
  }
6154
3707
  seq->param->range_count++;
6155
 
  seq->param->max_key_part=cmax(seq->param->max_key_part,(uint)key_tree->part);
 
3708
  seq->param->max_key_part= max(seq->param->max_key_part,(uint32_t)key_tree->part);
6156
3709
  return 0;
6157
3710
}
6158
3711
 
6163
3716
  SYNOPSIS
6164
3717
    check_quick_select()
6165
3718
      param             Parameter from test_quick_select
6166
 
      idx               Number of index to use in PARAM::key SEL_TREE::key
 
3719
      idx               Number of index to use in Parameter::key optimizer::SEL_TREE::key
6167
3720
      index_only        true  - assume only index tuples will be accessed
6168
3721
                        false - assume full table rows will be read
6169
3722
      tree              Transformed selection condition, tree->key[idx] holds
6181
3734
 
6182
3735
  RETURN
6183
3736
    Estimate # of records to be retrieved.
6184
 
    HA_POS_ERROR if estimate calculation failed due to table handler problems.
 
3737
    HA_POS_ERROR if estimate calculation failed due to table Cursor problems.
6185
3738
*/
6186
3739
 
6187
3740
static
6188
 
ha_rows check_quick_select(PARAM *param, uint32_t idx, bool index_only,
6189
 
                           SEL_ARG *tree, bool update_tbl_stats,
6190
 
                           uint32_t *mrr_flags, uint32_t *bufsize, COST_VECT *cost)
 
3741
ha_rows check_quick_select(Session *session,
 
3742
                           optimizer::Parameter *param,
 
3743
                           uint32_t idx,
 
3744
                           bool index_only,
 
3745
                           optimizer::SEL_ARG *tree,
 
3746
                           bool update_tbl_stats,
 
3747
                           uint32_t *mrr_flags,
 
3748
                           uint32_t *bufsize,
 
3749
                           optimizer::CostVector *cost)
6191
3750
{
6192
3751
  SEL_ARG_RANGE_SEQ seq;
6193
3752
  RANGE_SEQ_IF seq_if = {sel_arg_range_seq_init, sel_arg_range_seq_next};
6194
 
  handler *file= param->table->file;
 
3753
  Cursor *cursor= param->table->cursor;
6195
3754
  ha_rows rows;
6196
3755
  uint32_t keynr= param->real_keynr[idx];
6197
3756
 
6198
3757
  /* Handle cases when we don't have a valid non-empty list of range */
6199
 
  if (!tree)
 
3758
  if (! tree)
6200
3759
    return(HA_POS_ERROR);
6201
 
  if (tree->type == SEL_ARG::IMPOSSIBLE)
 
3760
  if (tree->type == optimizer::SEL_ARG::IMPOSSIBLE)
6202
3761
    return(0L);
6203
 
  if (tree->type != SEL_ARG::KEY_RANGE || tree->part != 0)
 
3762
  if (tree->type != optimizer::SEL_ARG::KEY_RANGE || tree->part != 0)
6204
3763
    return(HA_POS_ERROR);
6205
3764
 
6206
3765
  seq.keyno= idx;
6212
3771
  param->max_key_part=0;
6213
3772
 
6214
3773
  param->is_ror_scan= true;
6215
 
  if (file->index_flags(keynr, 0, true) & HA_KEY_SCAN_NOT_ROR)
 
3774
  if (param->table->index_flags(keynr) & HA_KEY_SCAN_NOT_ROR)
6216
3775
    param->is_ror_scan= false;
6217
3776
 
6218
3777
  *mrr_flags= param->force_default_mrr? HA_MRR_USE_DEFAULT_IMPL: 0;
6219
3778
  *mrr_flags|= HA_MRR_NO_ASSOCIATION;
6220
3779
 
6221
 
  bool pk_is_clustered= file->primary_key_is_clustered();
 
3780
  bool pk_is_clustered= cursor->primary_key_is_clustered();
6222
3781
  if (index_only &&
6223
 
      (file->index_flags(keynr, param->max_key_part, 1) & HA_KEYREAD_ONLY) &&
6224
 
      !(pk_is_clustered && keynr == param->table->s->primary_key))
 
3782
      (param->table->index_flags(keynr) & HA_KEYREAD_ONLY) &&
 
3783
      !(pk_is_clustered && keynr == param->table->getShare()->getPrimaryKey()))
6225
3784
     *mrr_flags |= HA_MRR_INDEX_ONLY;
6226
3785
 
6227
 
  if (current_session->lex->sql_command != SQLCOM_SELECT)
 
3786
  if (session->lex().sql_command != SQLCOM_SELECT)
6228
3787
    *mrr_flags |= HA_MRR_USE_DEFAULT_IMPL;
6229
3788
 
6230
3789
  *bufsize= param->session->variables.read_rnd_buff_size;
6231
 
  rows= file->multi_range_read_info_const(keynr, &seq_if, (void*)&seq, 0,
 
3790
  rows= cursor->multi_range_read_info_const(keynr, &seq_if, (void*)&seq, 0,
6232
3791
                                          bufsize, mrr_flags, cost);
6233
3792
  if (rows != HA_POS_ERROR)
6234
3793
  {
6235
3794
    param->table->quick_rows[keynr]=rows;
6236
3795
    if (update_tbl_stats)
6237
3796
    {
6238
 
      param->table->quick_keys.set_bit(keynr);
 
3797
      param->table->quick_keys.set(keynr);
6239
3798
      param->table->quick_key_parts[keynr]=param->max_key_part+1;
6240
3799
      param->table->quick_n_ranges[keynr]= param->range_count;
6241
3800
      param->table->quick_condition_rows=
6242
 
        cmin(param->table->quick_condition_rows, rows);
 
3801
        min(param->table->quick_condition_rows, rows);
6243
3802
    }
6244
3803
  }
6245
3804
  /* Figure out if the key scan is ROR (returns rows in ROWID order) or not */
6256
3815
  else
6257
3816
  {
6258
3817
    /* Clustered PK scan is always a ROR scan (TODO: same as above) */
6259
 
    if (param->table->s->primary_key == keynr && pk_is_clustered)
 
3818
    if (param->table->getShare()->getPrimaryKey() == keynr && pk_is_clustered)
6260
3819
      param->is_ror_scan= true;
6261
3820
  }
6262
3821
 
6301
3860
    false  Otherwise
6302
3861
*/
6303
3862
 
6304
 
static bool is_key_scan_ror(PARAM *param, uint32_t keynr, uint8_t nparts)
 
3863
static bool is_key_scan_ror(optimizer::Parameter *param, uint32_t keynr, uint8_t nparts)
6305
3864
{
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 +
 
3865
  KeyInfo *table_key= param->table->key_info + keynr;
 
3866
  KeyPartInfo *key_part= table_key->key_part + nparts;
 
3867
  KeyPartInfo *key_part_end= (table_key->key_part +
6309
3868
                                table_key->key_parts);
6310
3869
  uint32_t pk_number;
6311
3870
 
6312
 
  for (KEY_PART_INFO *kp= table_key->key_part; kp < key_part; kp++)
 
3871
  for (KeyPartInfo *kp= table_key->key_part; kp < key_part; kp++)
6313
3872
  {
6314
3873
    uint16_t fieldnr= param->table->key_info[keynr].
6315
3874
                    key_part[kp - table_key->key_part].fieldnr - 1;
6316
 
    if (param->table->field[fieldnr]->key_length() != kp->length)
 
3875
    if (param->table->getField(fieldnr)->key_length() != kp->length)
6317
3876
      return false;
6318
3877
  }
6319
3878
 
6321
3880
    return true;
6322
3881
 
6323
3882
  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)
 
3883
  pk_number= param->table->getShare()->getPrimaryKey();
 
3884
  if (!param->table->cursor->primary_key_is_clustered() || pk_number == MAX_KEY)
6326
3885
    return false;
6327
3886
 
6328
 
  KEY_PART_INFO *pk_part= param->table->key_info[pk_number].key_part;
6329
 
  KEY_PART_INFO *pk_part_end= pk_part +
 
3887
  KeyPartInfo *pk_part= param->table->key_info[pk_number].key_part;
 
3888
  KeyPartInfo *pk_part_end= pk_part +
6330
3889
                              param->table->key_info[pk_number].key_parts;
6331
3890
  for (;(key_part!=key_part_end) && (pk_part != pk_part_end);
6332
3891
       ++key_part, ++pk_part)
6339
3898
}
6340
3899
 
6341
3900
 
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
 
 
6357
 
    CAUTION! This function may change session->mem_root to a MEM_ROOT which will be
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 *
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)
 
3901
optimizer::QuickRangeSelect *
 
3902
optimizer::get_quick_select(Parameter *param,
 
3903
                            uint32_t idx,
 
3904
                            optimizer::SEL_ARG *key_tree,
 
3905
                            uint32_t mrr_flags,
 
3906
                            uint32_t mrr_buf_size,
 
3907
                            memory::Root *parent_alloc)
6368
3908
{
6369
 
  QUICK_RANGE_SELECT *quick;
6370
 
  bool create_err= false;
6371
 
 
6372
 
  quick=new QUICK_RANGE_SELECT(param->session, param->table,
6373
 
                               param->real_keynr[idx],
6374
 
                               test(parent_alloc), NULL, &create_err);
 
3909
  optimizer::QuickRangeSelect *quick= new optimizer::QuickRangeSelect(param->session,
 
3910
                                                                      param->table,
 
3911
                                                                      param->real_keynr[idx],
 
3912
                                                                      test(parent_alloc),
 
3913
                                                                      NULL);
6375
3914
 
6376
3915
  if (quick)
6377
3916
  {
6378
 
    if (create_err ||
6379
 
        get_quick_keys(param,quick,param->key[idx],key_tree,param->min_key,0,
6380
 
                       param->max_key,0))
 
3917
          if (get_quick_keys(param,
 
3918
                       quick,
 
3919
                       param->key[idx],
 
3920
                       key_tree,
 
3921
                       param->min_key,
 
3922
                       0,
 
3923
                                   param->max_key,
 
3924
                       0))
6381
3925
    {
6382
3926
      delete quick;
6383
 
      quick=0;
 
3927
      quick= NULL;
6384
3928
    }
6385
3929
    else
6386
3930
    {
6387
3931
      quick->mrr_flags= mrr_flags;
6388
3932
      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);
 
3933
      quick->key_parts= parent_alloc
 
3934
        ? (KEY_PART*)parent_alloc->memdup(param->key[idx], sizeof(KEY_PART)* param->table->key_info[param->real_keynr[idx]].key_parts)
 
3935
        : (KEY_PART*)quick->alloc.memdup(param->key[idx], sizeof(KEY_PART)* param->table->key_info[param->real_keynr[idx]].key_parts);
6394
3936
    }
6395
3937
  }
6396
3938
  return quick;
6401
3943
** Fix this to get all possible sub_ranges
6402
3944
*/
6403
3945
bool
6404
 
get_quick_keys(PARAM *param,QUICK_RANGE_SELECT *quick,KEY_PART *key,
6405
 
               SEL_ARG *key_tree, unsigned char *min_key,uint32_t min_key_flag,
6406
 
               unsigned char *max_key, uint32_t max_key_flag)
 
3946
optimizer::get_quick_keys(optimizer::Parameter *param,
 
3947
                          optimizer::QuickRangeSelect *quick,
 
3948
                          KEY_PART *key,
 
3949
                                optimizer::SEL_ARG *key_tree,
 
3950
                          unsigned char *min_key,
 
3951
                          uint32_t min_key_flag,
 
3952
                                unsigned char *max_key,
 
3953
                          uint32_t max_key_flag)
6407
3954
{
6408
 
  QUICK_RANGE *range;
 
3955
  optimizer::QuickRange *range= NULL;
6409
3956
  uint32_t flag;
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
 
3957
  int min_part= key_tree->part - 1; // # of keypart values in min_key buffer
 
3958
  int max_part= key_tree->part - 1; // # of keypart values in max_key buffer
6412
3959
 
6413
 
  if (key_tree->left != &null_element)
 
3960
  if (key_tree->left != &optimizer::null_element)
6414
3961
  {
6415
 
    if (get_quick_keys(param,quick,key,key_tree->left,
6416
 
                       min_key,min_key_flag, max_key, max_key_flag))
 
3962
    if (get_quick_keys(param,
 
3963
                       quick,
 
3964
                       key,
 
3965
                       key_tree->left,
 
3966
                                   min_key,
 
3967
                       min_key_flag,
 
3968
                       max_key,
 
3969
                       max_key_flag))
 
3970
    {
6417
3971
      return 1;
 
3972
    }
6418
3973
  }
6419
 
  unsigned char *tmp_min_key=min_key,*tmp_max_key=max_key;
 
3974
  unsigned char *tmp_min_key= min_key,*tmp_max_key= max_key;
6420
3975
  min_part+= key_tree->store_min(key[key_tree->part].store_length,
6421
3976
                                 &tmp_min_key,min_key_flag);
6422
3977
  max_part+= key_tree->store_max(key[key_tree->part].store_length,
6424
3979
 
6425
3980
  if (key_tree->next_key_part &&
6426
3981
      key_tree->next_key_part->part == key_tree->part+1 &&
6427
 
      key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
 
3982
      key_tree->next_key_part->type == optimizer::SEL_ARG::KEY_RANGE)
6428
3983
  {                                               // const key as prefix
6429
3984
    if ((tmp_min_key - min_key) == (tmp_max_key - max_key) &&
6430
 
         memcmp(min_key, max_key, (uint)(tmp_max_key - max_key))==0 &&
6431
 
         key_tree->min_flag==0 && key_tree->max_flag==0)
 
3985
        memcmp(min_key, max_key, (uint32_t)(tmp_max_key - max_key))==0 &&
 
3986
        key_tree->min_flag==0 && key_tree->max_flag==0)
6432
3987
    {
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;
 
3988
      if (get_quick_keys(param,
 
3989
                         quick,
 
3990
                         key,
 
3991
                         key_tree->next_key_part,
 
3992
                         tmp_min_key,
 
3993
                         min_key_flag | key_tree->min_flag,
 
3994
                         tmp_max_key,
 
3995
                         max_key_flag | key_tree->max_flag))
 
3996
      {
 
3997
        return 1;
 
3998
      }
6437
3999
      goto end;                                 // Ugly, but efficient
6438
4000
    }
6439
4001
    {
6440
4002
      uint32_t tmp_min_flag=key_tree->min_flag,tmp_max_flag=key_tree->max_flag;
6441
 
      if (!tmp_min_flag)
6442
 
        min_part+= key_tree->next_key_part->store_min_key(key, &tmp_min_key,
 
4003
      if (! tmp_min_flag)
 
4004
      {
 
4005
        min_part+= key_tree->next_key_part->store_min_key(key,
 
4006
                                                          &tmp_min_key,
6443
4007
                                                          &tmp_min_flag);
6444
 
      if (!tmp_max_flag)
6445
 
        max_part+= key_tree->next_key_part->store_max_key(key, &tmp_max_key,
 
4008
      }
 
4009
      if (! tmp_max_flag)
 
4010
      {
 
4011
        max_part+= key_tree->next_key_part->store_max_key(key,
 
4012
                                                          &tmp_max_key,
6446
4013
                                                          &tmp_max_flag);
 
4014
      }
6447
4015
      flag=tmp_min_flag | tmp_max_flag;
6448
4016
    }
6449
4017
  }
6456
4024
    Ensure that some part of min_key and max_key are used.  If not,
6457
4025
    regard this as no lower/upper range
6458
4026
  */
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;
 
4027
  if (tmp_min_key != param->min_key)
 
4028
  {
 
4029
    flag&= ~NO_MIN_RANGE;
 
4030
  }
 
4031
  else
 
4032
  {
 
4033
    flag|= NO_MIN_RANGE;
 
4034
  }
 
4035
  if (tmp_max_key != param->max_key)
 
4036
  {
 
4037
    flag&= ~NO_MAX_RANGE;
 
4038
  }
 
4039
  else
 
4040
  {
 
4041
    flag|= NO_MAX_RANGE;
6468
4042
  }
6469
4043
  if (flag == 0)
6470
4044
  {
6471
 
    uint32_t length= (uint) (tmp_min_key - param->min_key);
6472
 
    if (length == (uint) (tmp_max_key - param->max_key) &&
6473
 
        !memcmp(param->min_key,param->max_key,length))
 
4045
    uint32_t length= (uint32_t) (tmp_min_key - param->min_key);
 
4046
    if (length == (uint32_t) (tmp_max_key - param->max_key) &&
 
4047
              ! memcmp(param->min_key,param->max_key,length))
6474
4048
    {
6475
 
      KEY *table_key=quick->head->key_info+quick->index;
6476
 
      flag=EQ_RANGE;
 
4049
      KeyInfo *table_key= quick->head->key_info+quick->index;
 
4050
      flag= EQ_RANGE;
6477
4051
      if ((table_key->flags & (HA_NOSAME)) == HA_NOSAME &&
6478
 
          key->part == table_key->key_parts-1)
 
4052
                key->part == table_key->key_parts-1)
6479
4053
      {
6480
 
        if (!(table_key->flags & HA_NULL_PART_KEY) ||
6481
 
            !null_part_in_key(key,
6482
 
                              param->min_key,
6483
 
                              (uint) (tmp_min_key - param->min_key)))
6484
 
          flag|= UNIQUE_RANGE;
6485
 
        else
6486
 
          flag|= NULL_RANGE;
 
4054
        if (! (table_key->flags & HA_NULL_PART_KEY) ||
 
4055
            ! null_part_in_key(key,
 
4056
                               param->min_key,
 
4057
                               (uint32_t) (tmp_min_key - param->min_key)))
 
4058
        {
 
4059
          flag|= UNIQUE_RANGE;
 
4060
        }
 
4061
        else
 
4062
        {
 
4063
          flag|= NULL_RANGE;
 
4064
        }
6487
4065
      }
6488
4066
    }
6489
4067
  }
6490
4068
 
6491
4069
  /* Get range for retrieving rows in QUICK_SELECT::get_next */
6492
 
  if (!(range= new QUICK_RANGE(param->min_key,
6493
 
                               (uint) (tmp_min_key - param->min_key),
6494
 
                               min_part >=0 ? make_keypart_map(min_part) : 0,
6495
 
                               param->max_key,
6496
 
                               (uint) (tmp_max_key - param->max_key),
6497
 
                               max_part >=0 ? make_keypart_map(max_part) : 0,
6498
 
                               flag)))
6499
 
    return 1;                   // out of memory
 
4070
  range= new optimizer::QuickRange(param->min_key,
 
4071
                                                             (uint32_t) (tmp_min_key - param->min_key),
 
4072
                                           min_part >=0 ? make_keypart_map(min_part) : 0,
 
4073
                                                             param->max_key,
 
4074
                                                             (uint32_t) (tmp_max_key - param->max_key),
 
4075
                                           max_part >=0 ? make_keypart_map(max_part) : 0,
 
4076
                                                             flag);
6500
4077
 
6501
 
  set_if_bigger(quick->max_used_key_length, range->min_length);
6502
 
  set_if_bigger(quick->max_used_key_length, range->max_length);
6503
 
  set_if_bigger(quick->used_key_parts, (uint) key_tree->part+1);
6504
 
  if (insert_dynamic(&quick->ranges, (unsigned char*) &range))
6505
 
    return 1;
 
4078
  set_if_bigger(quick->max_used_key_length, (uint32_t)range->min_length);
 
4079
  set_if_bigger(quick->max_used_key_length, (uint32_t)range->max_length);
 
4080
  set_if_bigger(quick->used_key_parts, (uint32_t) key_tree->part+1);
 
4081
  quick->ranges.push_back(&range);
6506
4082
 
6507
4083
 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)
 
4084
  if (key_tree->right != &optimizer::null_element)
6522
4085
  {
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;
6527
 
      return ((key->flags & (HA_NOSAME)) == HA_NOSAME &&
6528
 
              key->key_length == tmp->min_length);
6529
 
    }
 
4086
    return get_quick_keys(param,
 
4087
                          quick,
 
4088
                          key,
 
4089
                          key_tree->right,
 
4090
                                            min_key,
 
4091
                          min_key_flag,
 
4092
                                            max_key,
 
4093
                          max_key_flag);
6530
4094
  }
6531
4095
  return 0;
6532
4096
}
6533
4097
 
6534
 
 
6535
 
 
6536
4098
/*
6537
4099
  Return true if any part of the key is NULL
6538
4100
 
6560
4122
}
6561
4123
 
6562
4124
 
6563
 
bool QUICK_SELECT_I::is_keys_used(const MY_BITMAP *fields)
 
4125
bool optimizer::QuickSelectInterface::is_keys_used(const boost::dynamic_bitset<>& fields)
6564
4126
{
6565
4127
  return is_key_used(head, index, fields);
6566
4128
}
6567
4129
 
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
4130
 
6605
4131
/*
6606
4132
  Create quick select from ref/ref_or_null scan.
6621
4147
    NULL on error.
6622
4148
*/
6623
4149
 
6624
 
QUICK_RANGE_SELECT *get_quick_select_for_ref(Session *session, Table *table,
6625
 
                                             TABLE_REF *ref, ha_rows records)
 
4150
optimizer::QuickRangeSelect *optimizer::get_quick_select_for_ref(Session *session,
 
4151
                                                                 Table *table,
 
4152
                                                                 table_reference_st *ref,
 
4153
                                                                 ha_rows records)
6626
4154
{
6627
 
  MEM_ROOT *old_root, *alloc;
6628
 
  QUICK_RANGE_SELECT *quick;
6629
 
  KEY *key_info = &table->key_info[ref->key];
 
4155
  memory::Root *old_root= NULL;
 
4156
  memory::Root *alloc= NULL;
 
4157
  KeyInfo *key_info = &table->key_info[ref->key];
6630
4158
  KEY_PART *key_part;
6631
 
  QUICK_RANGE *range;
 
4159
  optimizer::QuickRange *range= NULL;
6632
4160
  uint32_t part;
6633
 
  bool create_err= false;
6634
 
  COST_VECT cost;
 
4161
  optimizer::CostVector cost;
6635
4162
 
6636
4163
  old_root= session->mem_root;
6637
4164
  /* The following call may change session->mem_root */
6638
 
  quick= new QUICK_RANGE_SELECT(session, table, ref->key, 0, 0, &create_err);
6639
 
  /* save mem_root set by QUICK_RANGE_SELECT constructor */
 
4165
  optimizer::QuickRangeSelect *quick= new optimizer::QuickRangeSelect(session, table, ref->key, 0, 0);
 
4166
  /* save mem_root set by QuickRangeSelect constructor */
6640
4167
  alloc= session->mem_root;
6641
4168
  /*
6642
4169
    return back default mem_root (session->mem_root) changed by
6643
 
    QUICK_RANGE_SELECT constructor
 
4170
    QuickRangeSelect constructor
6644
4171
  */
6645
4172
  session->mem_root= old_root;
6646
4173
 
6647
 
  if (!quick || create_err)
 
4174
  if (! quick)
6648
4175
    return 0;                   /* no ranges found */
6649
4176
  if (quick->init())
6650
4177
    goto err;
6651
4178
  quick->records= records;
6652
4179
 
6653
 
  if ((cp_buffer_from_ref(session, ref) && session->is_fatal_error) ||
6654
 
      !(range= new(alloc) QUICK_RANGE()))
 
4180
  if (cp_buffer_from_ref(session, ref) && session->is_fatal_error)
6655
4181
    goto err;                                   // out of memory
 
4182
  range= new (*alloc) optimizer::QuickRange;
6656
4183
 
6657
4184
  range->min_key= range->max_key= ref->key_buff;
6658
4185
  range->min_length= range->max_length= ref->key_length;
6659
4186
  range->min_keypart_map= range->max_keypart_map=
6660
4187
    make_prev_keypart_map(ref->key_parts);
6661
 
  range->flag= ((ref->key_length == key_info->key_length &&
6662
 
                 key_info->flags == 0) ? EQ_RANGE : 0);
 
4188
  range->flag= (ref->key_length == key_info->key_length && (key_info->flags & HA_END_SPACE_KEY) == 0) ? EQ_RANGE : 0;
6663
4189
 
6664
 
  if (!(quick->key_parts=key_part=(KEY_PART *)
6665
 
        alloc_root(&quick->alloc,sizeof(KEY_PART)*ref->key_parts)))
6666
 
    goto err;
 
4190
  quick->key_parts=key_part= new (quick->alloc) KEY_PART[ref->key_parts];
6667
4191
 
6668
4192
  for (part=0 ; part < ref->key_parts ;part++,key_part++)
6669
4193
  {
6674
4198
    key_part->null_bit=     key_info->key_part[part].null_bit;
6675
4199
    key_part->flag=         (uint8_t) key_info->key_part[part].key_part_flag;
6676
4200
  }
6677
 
  if (insert_dynamic(&quick->ranges,(unsigned char*)&range))
6678
 
    goto err;
 
4201
  quick->ranges.push_back(&range);
6679
4202
 
6680
4203
  /*
6681
4204
     Add a NULL range if REF_OR_NULL optimization is used.
6685
4208
  */
6686
4209
  if (ref->null_ref_key)
6687
4210
  {
6688
 
    QUICK_RANGE *null_range;
 
4211
    optimizer::QuickRange *null_range= NULL;
6689
4212
 
6690
4213
    *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;
 
4214
    null_range= new (alloc)
 
4215
          optimizer::QuickRange(ref->key_buff, ref->key_length,
 
4216
                                 make_prev_keypart_map(ref->key_parts),
 
4217
                                 ref->key_buff, ref->key_length,
 
4218
                                 make_prev_keypart_map(ref->key_parts), EQ_RANGE);
6697
4219
    *ref->null_ref_key= 0;              // Clear null byte
6698
 
    if (insert_dynamic(&quick->ranges,(unsigned char*)&null_range))
6699
 
      goto err;
 
4220
    quick->ranges.push_back(&null_range);
6700
4221
  }
6701
4222
 
6702
4223
  /* Call multi_range_read_info() to get the MRR flags and buffer size */
6703
4224
  quick->mrr_flags= HA_MRR_NO_ASSOCIATION |
6704
4225
                    (table->key_read ? HA_MRR_INDEX_ONLY : 0);
6705
 
  if (session->lex->sql_command != SQLCOM_SELECT)
 
4226
  if (session->lex().sql_command != SQLCOM_SELECT)
6706
4227
    quick->mrr_flags |= HA_MRR_USE_DEFAULT_IMPL;
6707
4228
 
6708
4229
  quick->mrr_buf_size= session->variables.read_rnd_buff_size;
6709
 
  if (table->file->multi_range_read_info(quick->index, 1, (uint)records,
6710
 
                                         &quick->mrr_buf_size,
6711
 
                                         &quick->mrr_flags, &cost))
 
4230
  if (table->cursor->multi_range_read_info(quick->index, 1, (uint32_t)records, &quick->mrr_buf_size, &quick->mrr_flags, &cost))
6712
4231
    goto err;
6713
4232
 
6714
4233
  return quick;
6719
4238
 
6720
4239
 
6721
4240
/*
6722
 
  Perform key scans for all used indexes (except CPK), get rowids and merge
6723
 
  them into an ordered non-recurrent sequence of rowids.
6724
 
 
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.
6727
 
 
6728
 
  If table has a clustered primary key that covers all rows (true for bdb
6729
 
  and innodb currently) and one of the index_merge scans is a scan on PK,
6730
 
  then rows that will be retrieved by PK scan are not put into Unique and
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++;
6751
 
  assert(cur_quick != 0);
6752
 
 
6753
 
  /*
6754
 
    We reuse the same instance of handler so we need to call both init and
6755
 
    reset here.
6756
 
  */
6757
 
  if (cur_quick->init() || cur_quick->reset())
6758
 
    return 0;
6759
 
 
6760
 
  unique= new Unique(refpos_order_cmp, (void *)file,
6761
 
                     file->ref_length,
6762
 
                     session->variables.sortbuff_size);
6763
 
  if (!unique)
6764
 
    return 0;
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
 
 
6774
 
      if (cur_quick->file->inited != handler::NONE)
6775
 
        cur_quick->file->ha_index_end();
6776
 
      if (cur_quick->init() || cur_quick->reset())
6777
 
        return 0;
6778
 
    }
6779
 
 
6780
 
    if (result)
6781
 
    {
6782
 
      if (result != HA_ERR_END_OF_FILE)
6783
 
      {
6784
 
        cur_quick->range_end();
6785
 
        return result;
6786
 
      }
6787
 
      break;
6788
 
    }
6789
 
 
6790
 
    if (session->killed)
6791
 
      return 0;
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)
6800
 
      return 0;
6801
 
 
6802
 
  }
6803
 
 
6804
 
  /* ok, all row ids are in Unique */
6805
 
  result= unique->get(head);
6806
 
  delete unique;
6807
 
  doing_pk_scan= false;
6808
 
  /* index_merge currently doesn't support "using index" at all */
6809
 
  file->extra(HA_EXTRA_NO_KEYREAD);
6810
 
  /* start table scan */
6811
 
  init_read_record(&read_record, session, head, (SQL_SELECT*) 0, 1, 1);
6812
 
  return result;
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)
6830
 
    return(pk_quick_select->get_next());
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
 
    {
6839
 
      doing_pk_scan= true;
6840
 
      if ((result= pk_quick_select->init()) ||
6841
 
          (result= pk_quick_select->reset()))
6842
 
        return result;
6843
 
      return(pk_quick_select->get_next());
6844
 
    }
6845
 
  }
6846
 
 
6847
 
  return result;
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;
6876
 
  uint32_t last_rowid_count=0;
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)
6889
 
      return(error);
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()))
6906
 
          return(error);
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()))
6920
 
              return(error);
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);
6937
 
  return(error);
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;
6960
 
  unsigned char *tmp;
6961
 
 
6962
 
  do
6963
 
  {
6964
 
    do
6965
 
    {
6966
 
      if (!queue.elements)
6967
 
        return(HA_ERR_END_OF_FILE);
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)
6977
 
          return(error);
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 */
6989
 
        dup_row= false;
6990
 
        have_prev_rowid= true;
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);
7002
 
  return(error);
7003
 
}
7004
 
 
7005
 
 
7006
 
int QUICK_RANGE_SELECT::reset()
7007
 
{
7008
 
  uint32_t  buf_size;
7009
 
  unsigned char *mrange_buff;
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)))
7016
 
    return(error);
7017
 
 
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,
7025
 
                                        NULL))
7026
 
    {
7027
 
      /* Try to shrink the buffers until both are 0. */
7028
 
      buf_size/= 2;
7029
 
    }
7030
 
    if (!mrr_buf_desc)
7031
 
      return(HA_ERR_OUT_OF_MEM);
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;
7041
 
 
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,
7046
 
                                     mrr_flags, mrr_buf_desc? mrr_buf_desc:
7047
 
                                                              &empty_buf);
7048
 
  return(error);
7049
 
}
7050
 
 
7051
 
 
7052
 
/*
7053
 
  Range sequence interface implementation for array<QUICK_RANGE>: initialize
 
4241
  Range sequence interface implementation for array<QuickRange>: initialize
7054
4242
 
7055
4243
  SYNOPSIS
7056
4244
    quick_range_seq_init()
7057
 
      init_param  Caller-opaque paramenter: QUICK_RANGE_SELECT* pointer
 
4245
      init_param  Caller-opaque paramenter: QuickRangeSelect* pointer
7058
4246
      n_ranges    Number of ranges in the sequence (ignored)
7059
4247
      flags       MRR flags (currently not used)
7060
4248
 
7062
4250
    Opaque value to be passed to quick_range_seq_next
7063
4251
*/
7064
4252
 
7065
 
range_seq_t quick_range_seq_init(void *init_param, uint32_t, uint32_t)
 
4253
range_seq_t optimizer::quick_range_seq_init(void *init_param, uint32_t, uint32_t)
7066
4254
{
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;
 
4255
  optimizer::QuickRangeSelect *quick= (optimizer::QuickRangeSelect*)init_param;
 
4256
  quick->qr_traversal_ctx.first=  (optimizer::QuickRange**)quick->ranges.buffer;
 
4257
  quick->qr_traversal_ctx.cur=    (optimizer::QuickRange**)quick->ranges.buffer;
7070
4258
  quick->qr_traversal_ctx.last=   quick->qr_traversal_ctx.cur +
7071
 
                                  quick->ranges.elements;
 
4259
                                  quick->ranges.size();
7072
4260
  return &quick->qr_traversal_ctx;
7073
4261
}
7074
4262
 
7075
4263
 
7076
4264
/*
7077
 
  Range sequence interface implementation for array<QUICK_RANGE>: get next
 
4265
  Range sequence interface implementation for array<QuickRange>: get next
7078
4266
 
7079
4267
  SYNOPSIS
7080
4268
    quick_range_seq_next()
7085
4273
    0  Ok
7086
4274
    1  No more ranges in the sequence
7087
4275
*/
7088
 
 
7089
 
uint32_t quick_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range)
 
4276
uint32_t optimizer::quick_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range)
7090
4277
{
7091
 
  QUICK_RANGE_SEQ_CTX *ctx= (QUICK_RANGE_SEQ_CTX*)rseq;
 
4278
  QuickRangeSequenceContext *ctx= (QuickRangeSequenceContext*) rseq;
7092
4279
 
7093
4280
  if (ctx->cur == ctx->last)
7094
4281
    return 1; /* no more ranges */
7095
4282
 
7096
 
  QUICK_RANGE *cur= *(ctx->cur);
 
4283
  optimizer::QuickRange *cur= *(ctx->cur);
7097
4284
  key_range *start_key= &range->start_key;
7098
 
  key_range *end_key=   &range->end_key;
 
4285
  key_range *end_key= &range->end_key;
7099
4286
 
7100
 
  start_key->key=    cur->min_key;
 
4287
  start_key->key= cur->min_key;
7101
4288
  start_key->length= cur->min_length;
7102
4289
  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;
 
4290
  start_key->flag= ((cur->flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
 
4291
                                             (cur->flag & EQ_RANGE) ?
 
4292
                                             HA_READ_KEY_EXACT : HA_READ_KEY_OR_NEXT);
 
4293
  end_key->key= cur->max_key;
 
4294
  end_key->length= cur->max_length;
7108
4295
  end_key->keypart_map= cur->max_keypart_map;
7109
4296
  /*
7110
4297
    We use HA_READ_AFTER_KEY here because if we are reading on a key
7111
4298
    prefix. We want to find all keys with this prefix.
7112
4299
  */
7113
 
  end_key->flag=     (cur->flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
7114
 
                      HA_READ_AFTER_KEY);
 
4300
  end_key->flag= (cur->flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
 
4301
                                         HA_READ_AFTER_KEY);
7115
4302
  range->range_flag= cur->flag;
7116
4303
  ctx->cur++;
7117
4304
  return 0;
7118
4305
}
7119
4306
 
7120
4307
 
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
 
 
7134
 
    This function should be removed when we get a proper MRR/NDB
7135
 
    implementation.
7136
 
 
7137
 
  RETURN
7138
 
    Reference to range_flag associated with range number #idx
7139
 
*/
7140
 
 
7141
 
uint16_t &mrr_persistent_flag_storage(range_seq_t seq, uint32_t idx)
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
 
 
7173
 
char* &mrr_get_ptr_by_idx(range_seq_t, uint32_t)
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
 
  }
7214
 
  return result;
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
 
 
7246
 
int QUICK_RANGE_SELECT::get_next_prefix(uint32_t prefix_length,
7247
 
                                        key_part_map keypart_map,
7248
 
                                        unsigned char *cur_prefix)
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. */
7257
 
      assert(cur_prefix != 0);
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))
7261
 
        return result;
7262
 
    }
7263
 
 
7264
 
    uint32_t count= ranges.elements - (cur_range - (QUICK_RANGE**) ranges.buffer);
7265
 
    if (count == 0)
7266
 
    {
7267
 
      /* Ranges have already been used up before. None is left for read. */
7268
 
      last_range= 0;
7269
 
      return HA_ERR_END_OF_FILE;
7270
 
    }
7271
 
    last_range= *(cur_range++);
7272
 
 
7273
 
    start_key.key=    (const unsigned char*) last_range->min_key;
7274
 
    start_key.length= cmin(last_range->min_length, (uint16_t)prefix_length);
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);
7279
 
    end_key.key=      (const unsigned char*) last_range->max_key;
7280
 
    end_key.length=   cmin(last_range->max_length, (uint16_t)prefix_length);
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)
7297
 
      return result;
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
7317
 
    true  if current row will be retrieved by this quick select
7318
 
    false if not
7319
 
*/
7320
 
 
7321
 
bool QUICK_RANGE_SELECT::row_in_ranges()
7322
 
{
7323
 
  QUICK_RANGE *res;
7324
 
  uint32_t min= 0;
7325
 
  uint32_t max= ranges.elements - 1;
7326
 
  uint32_t mid= (max + min)/2;
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
 
 
7353
 
QUICK_SELECT_DESC::QUICK_SELECT_DESC(QUICK_RANGE_SELECT *q, uint32_t, bool *)
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)
7401
 
          return 0;
7402
 
      }
7403
 
      else if (result != HA_ERR_END_OF_FILE)
7404
 
        return result;
7405
 
    }
7406
 
 
7407
 
    if (!(last_range= rev_it++))
7408
 
      return HA_ERR_END_OF_FILE;                // All ranges used
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)))
7414
 
        return(local_error);            // Empty table
7415
 
      if (cmp_prev(last_range) == 0)
7416
 
        return 0;
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
 
    {
7429
 
      assert(last_range->flag & NEAR_MAX ||
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)
7440
 
        return result;
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
7448
 
      return 0;                         // Found key is in range
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
7458
 
  TODO: Figure out why can't this function be as simple as cmp_prev().
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;
7467
 
  uint32_t store_length;
7468
 
 
7469
 
  for (unsigned char *key=range_arg->max_key, *end=key+range_arg->max_length;
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
 
/*
7516
 
 * true if this range will require using HA_READ_AFTER_KEY
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;
7537
 
  bool first= true;
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
7545
 
      first= false;
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
 
{
7558
 
  bool first= true;
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
7568
 
      first= false;
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
 
{
7582
 
  bool first= true;
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
7591
 
      first= false;
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];
7602
 
  uint32_t length;
7603
 
  KEY *key_info= head->key_info + index;
7604
 
  key_names->append(key_info->name);
7605
 
  length= int64_t2str(max_used_key_length, buf, 10) - buf;
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];
7613
 
  uint32_t length;
7614
 
  bool first= true;
7615
 
  QUICK_RANGE_SELECT *quick;
7616
 
 
7617
 
  List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
7618
 
  while ((quick= it++))
7619
 
  {
7620
 
    if (first)
7621
 
      first= false;
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);
7630
 
    length= int64_t2str(quick->max_used_key_length, buf, 10) - buf;
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);
7638
 
    length= int64_t2str(pk_quick_select->max_used_key_length, buf, 10) - buf;
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];
7648
 
  uint32_t length;
7649
 
  bool first= true;
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)
7656
 
      first= false;
7657
 
    else
7658
 
    {
7659
 
      key_names->append(',');
7660
 
      used_lengths->append(',');
7661
 
    }
7662
 
    key_names->append(key_info->name);
7663
 
    length= int64_t2str(quick->max_used_key_length, buf, 10) - buf;
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);
7672
 
    length= int64_t2str(cpk_quick->max_used_key_length, buf, 10) - buf;
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
 
{
7681
 
  bool first= true;
7682
 
  QUICK_SELECT_I *quick;
7683
 
  List_iterator_fast<QUICK_SELECT_I> it(quick_selects);
7684
 
  while ((quick= it++))
7685
 
  {
7686
 
    if (first)
7687
 
      first= false;
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
 
 
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);
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,
7708
 
                       KEY_PART_INFO *last_part, Session *session,
7709
 
                       unsigned char *key_infix, uint32_t *key_infix_len,
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);
 
4308
static inline uint32_t get_field_keypart(KeyInfo *index, Field *field);
 
4309
 
 
4310
static inline optimizer::SEL_ARG * get_index_range_tree(uint32_t index,
 
4311
                                                        optimizer::SEL_TREE *range_tree,
 
4312
                                                        optimizer::Parameter *param,
 
4313
                                                        uint32_t *param_idx);
 
4314
 
 
4315
static bool get_constant_key_infix(KeyInfo *index_info,
 
4316
                                   optimizer::SEL_ARG *index_range_tree,
 
4317
                                   KeyPartInfo *first_non_group_part,
 
4318
                                   KeyPartInfo *min_max_arg_part,
 
4319
                                   KeyPartInfo *last_part,
 
4320
                                   Session *session,
 
4321
                                   unsigned char *key_infix,
 
4322
                                   uint32_t *key_infix_len,
 
4323
                                   KeyPartInfo **first_non_infix_part);
 
4324
 
 
4325
static bool check_group_min_max_predicates(COND *cond, Item_field *min_max_arg_item);
7714
4326
 
7715
4327
static void
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,
7718
 
                   SEL_ARG *index_tree, ha_rows quick_prefix_records,
7719
 
                   bool have_min, bool have_max,
7720
 
                   double *read_cost, ha_rows *records);
 
4328
cost_group_min_max(Table* table,
 
4329
                   KeyInfo *index_info,
 
4330
                   uint32_t used_key_parts,
 
4331
                   uint32_t group_key_parts,
 
4332
                   optimizer::SEL_TREE *range_tree,
 
4333
                   optimizer::SEL_ARG *index_tree,
 
4334
                   ha_rows quick_prefix_records,
 
4335
                   bool have_min,
 
4336
                   bool have_max,
 
4337
                   double *read_cost,
 
4338
                   ha_rows *records);
7721
4339
 
7722
4340
 
7723
4341
/*
7730
4348
    sel_tree Range tree generated by get_mm_tree
7731
4349
 
7732
4350
  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
 
4351
    Test whether a query can be computed via a QuickGroupMinMaxSelect.
 
4352
    Queries computable via a QuickGroupMinMaxSelect must satisfy the
7735
4353
    following conditions:
7736
4354
    A) Table T has at least one compound index I of the form:
7737
4355
       I = <A_1, ...,A_k, [B_1,..., B_m], C, [D_1,...,D_n]>
7815
4433
  NOTES
7816
4434
    If the current query satisfies the conditions above, and if
7817
4435
    (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.
 
4436
    object, that is later used to construct a new QuickGroupMinMaxSelect.
7819
4437
    If (mem_root == NULL), then the function only tests whether the current
7820
4438
    query satisfies the conditions above, and, if so, sets
7821
4439
    is_applicable = true.
7841
4459
 
7842
4460
  RETURN
7843
4461
    If mem_root != NULL
7844
 
    - valid TRP_GROUP_MIN_MAX object if this QUICK class can be used for
 
4462
    - valid GroupMinMaxReadPlan object if this QUICK class can be used for
7845
4463
      the query
7846
4464
    -  NULL o/w.
7847
4465
    If mem_root == NULL
7848
4466
    - NULL
7849
4467
*/
7850
 
 
7851
 
static TRP_GROUP_MIN_MAX *
7852
 
get_best_group_min_max(PARAM *param, SEL_TREE *tree)
 
4468
static optimizer::GroupMinMaxReadPlan *
 
4469
get_best_group_min_max(optimizer::Parameter *param, optimizer::SEL_TREE *tree)
7853
4470
{
7854
4471
  Session *session= param->session;
7855
 
  JOIN *join= session->lex->current_select->join;
 
4472
  Join *join= session->lex().current_select->join;
7856
4473
  Table *table= param->table;
7857
4474
  bool have_min= false;              /* true if there is a MIN function. */
7858
4475
  bool have_max= false;              /* true if there is a MAX function. */
7859
4476
  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. */
 
4477
  KeyPartInfo *min_max_arg_part= NULL; /* The corresponding keypart. */
7861
4478
  uint32_t group_prefix_len= 0; /* Length (in bytes) of the key prefix. */
7862
 
  KEY *index_info= NULL;    /* The index chosen for data access. */
 
4479
  KeyInfo *index_info= NULL;    /* The index chosen for data access. */
7863
4480
  uint32_t index= 0;            /* The id of the chosen index. */
7864
4481
  uint32_t group_key_parts= 0;  // Number of index key parts in the group prefix.
7865
4482
  uint32_t used_key_parts= 0;   /* Number of index key parts used for access. */
7866
4483
  unsigned char key_infix[MAX_KEY_LENGTH]; /* Constants from equality predicates.*/
7867
4484
  uint32_t key_infix_len= 0;          /* Length of key_infix. */
7868
 
  TRP_GROUP_MIN_MAX *read_plan= NULL; /* The eventually constructed TRP. */
 
4485
  optimizer::GroupMinMaxReadPlan *read_plan= NULL; /* The eventually constructed TRP. */
7869
4486
  uint32_t key_part_nr;
7870
 
  order_st *tmp_group;
7871
 
  Item *item;
7872
 
  Item_field *item_field;
 
4487
  Order *tmp_group= NULL;
 
4488
  Item *item= NULL;
 
4489
  Item_field *item_field= NULL;
7873
4490
 
7874
4491
  /* Perform few 'cheap' tests whether this access method is applicable. */
7875
 
  if (!join)
 
4492
  if (! join)
7876
4493
    return NULL;        /* This is not a select statement. */
 
4494
 
7877
4495
  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)) ||
 
4496
      ((! join->group_list) && /* Neither GROUP BY nor a DISTINCT query. */
 
4497
       (! join->select_distinct)) ||
7880
4498
      (join->select_lex->olap == ROLLUP_TYPE)) /* Check (B3) for ROLLUP */
7881
4499
    return NULL;
7882
 
  if (table->s->keys == 0)        /* There are no indexes to use. */
 
4500
  if (table->getShare()->sizeKeys() == 0)        /* There are no indexes to use. */
7883
4501
    return NULL;
7884
4502
 
7885
4503
  /* Analyze the query in more detail. */
7886
 
  List_iterator<Item> select_items_it(join->fields_list);
 
4504
  List<Item>::iterator select_items_it(join->fields_list.begin());
7887
4505
 
7888
4506
  /* Check (SA1,SA4) and store the only MIN/MAX argument - the C attribute.*/
7889
4507
  if (join->make_sum_func_list(join->all_fields, join->fields_list, 1))
7890
4508
    return NULL;
 
4509
 
7891
4510
  if (join->sum_funcs[0])
7892
4511
  {
7893
 
    Item_sum *min_max_item;
 
4512
    Item_sum *min_max_item= NULL;
7894
4513
    Item_sum **func_ptr= join->sum_funcs;
7895
4514
    while ((min_max_item= *(func_ptr++)))
7896
4515
    {
7937
4556
    (GA1,GA2) are all true. If there is more than one such index, select the
7938
4557
    first one. Here we set the variables: group_prefix_len and index_info.
7939
4558
  */
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. */
 
4559
  KeyInfo *cur_index_info= table->key_info;
 
4560
  KeyInfo *cur_index_info_end= cur_index_info + table->getShare()->sizeKeys();
 
4561
  KeyPartInfo *cur_part= NULL;
 
4562
  KeyPartInfo *end_part= NULL; /* Last part for loops. */
7944
4563
  /* 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;
 
4564
  KeyPartInfo *last_part= NULL;
 
4565
  KeyPartInfo *first_non_group_part= NULL;
 
4566
  KeyPartInfo *first_non_infix_part= NULL;
7948
4567
  uint32_t key_infix_parts= 0;
7949
4568
  uint32_t cur_group_key_parts= 0;
7950
4569
  uint32_t cur_group_prefix_len= 0;
7951
4570
  /* Cost-related variables for the best index so far. */
7952
4571
  double best_read_cost= DBL_MAX;
7953
4572
  ha_rows best_records= 0;
7954
 
  SEL_ARG *best_index_tree= NULL;
 
4573
  optimizer::SEL_ARG *best_index_tree= NULL;
7955
4574
  ha_rows best_quick_prefix_records= 0;
7956
4575
  uint32_t best_param_idx= 0;
7957
4576
  double cur_read_cost= DBL_MAX;
7958
4577
  ha_rows cur_records;
7959
 
  SEL_ARG *cur_index_tree= NULL;
 
4578
  optimizer::SEL_ARG *cur_index_tree= NULL;
7960
4579
  ha_rows cur_quick_prefix_records= 0;
7961
 
  uint32_t cur_param_idx=MAX_KEY;
7962
 
  key_map cur_used_key_parts;
7963
 
  uint32_t pk= param->table->s->primary_key;
 
4580
  uint32_t cur_param_idx= MAX_KEY;
 
4581
  key_map used_key_parts_map;
 
4582
  uint32_t cur_key_infix_len= 0;
 
4583
  unsigned char cur_key_infix[MAX_KEY_LENGTH];
 
4584
  uint32_t cur_used_key_parts= 0;
 
4585
  uint32_t pk= param->table->getShare()->getPrimaryKey();
7964
4586
 
7965
 
  for (uint32_t cur_index= 0 ; cur_index_info != cur_index_info_end ;
 
4587
  for (uint32_t cur_index= 0;
 
4588
       cur_index_info != cur_index_info_end;
7966
4589
       cur_index_info++, cur_index++)
7967
4590
  {
7968
4591
    /* Check (B1) - if current index is covering. */
7969
 
    if (!table->covering_keys.is_set(cur_index))
 
4592
    if (! table->covering_keys.test(cur_index))
7970
4593
      goto next_index;
7971
4594
 
7972
4595
    /*
7979
4602
      we check that all query fields are indeed covered by 'cur_index'.
7980
4603
    */
7981
4604
    if (pk < MAX_KEY && cur_index != pk &&
7982
 
        (table->file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX))
 
4605
        (table->cursor->getEngine()->check_flag(HTON_BIT_PRIMARY_KEY_IN_READ_INDEX)))
7983
4606
    {
7984
4607
      /* For each table field */
7985
 
      for (uint32_t i= 0; i < table->s->fields; i++)
 
4608
      for (uint32_t i= 0; i < table->getShare()->sizeFields(); i++)
7986
4609
      {
7987
 
        Field *cur_field= table->field[i];
 
4610
        Field *cur_field= table->getField(i);
7988
4611
        /*
7989
4612
          If the field is used in the current query ensure that it's
7990
4613
          part of 'cur_index'
7991
4614
        */
7992
 
        if (bitmap_is_set(table->read_set, cur_field->field_index) &&
7993
 
            !cur_field->part_of_key_not_clustered.is_set(cur_index))
 
4615
        if ((cur_field->isReadSet()) &&
 
4616
            ! cur_field->part_of_key_not_clustered.test(cur_index))
7994
4617
          goto next_index;                  // Field was not part of key
7995
4618
      }
7996
4619
    }
8003
4626
      cur_part= cur_index_info->key_part;
8004
4627
      end_part= cur_part + cur_index_info->key_parts;
8005
4628
      /* Iterate in parallel over the GROUP list and the index parts. */
8006
 
      for (tmp_group= join->group_list; tmp_group && (cur_part != end_part);
 
4629
      for (tmp_group= join->group_list;
 
4630
           tmp_group && (cur_part != end_part);
8007
4631
           tmp_group= tmp_group->next, cur_part++)
8008
4632
      {
8009
4633
        /*
8033
4657
    */
8034
4658
    else if (join->select_distinct)
8035
4659
    {
8036
 
      select_items_it.rewind();
8037
 
      cur_used_key_parts.clear_all();
 
4660
      select_items_it= join->fields_list.begin();
 
4661
      used_key_parts_map.reset();
8038
4662
      uint32_t max_key_part= 0;
8039
4663
      while ((item= select_items_it++))
8040
4664
      {
8045
4669
          Check if this attribute was already present in the select list.
8046
4670
          If it was present, then its corresponding key part was alredy used.
8047
4671
        */
8048
 
        if (cur_used_key_parts.is_set(key_part_nr))
 
4672
        if (used_key_parts_map.test(key_part_nr))
8049
4673
          continue;
8050
 
        if (key_part_nr < 1 || key_part_nr > join->fields_list.elements)
 
4674
        if (key_part_nr < 1 || key_part_nr > join->fields_list.size())
8051
4675
          goto next_index;
8052
4676
        cur_part= cur_index_info->key_part + key_part_nr - 1;
8053
4677
        cur_group_prefix_len+= cur_part->store_length;
8054
 
        cur_used_key_parts.set_bit(key_part_nr);
 
4678
        used_key_parts_map.set(key_part_nr);
8055
4679
        ++cur_group_key_parts;
8056
 
        max_key_part= cmax(max_key_part,key_part_nr);
 
4680
        max_key_part= max(max_key_part,key_part_nr);
8057
4681
      }
8058
4682
      /*
8059
4683
        Check that used key parts forms a prefix of the index.
8061
4685
        all_parts have all bits set from 0 to (max_key_part-1).
8062
4686
        cur_parts have bits set for only used keyparts.
8063
4687
      */
8064
 
      uint64_t all_parts, cur_parts;
8065
 
      all_parts= (1<<max_key_part) - 1;
8066
 
      cur_parts= cur_used_key_parts.to_uint64_t() >> 1;
 
4688
      key_map all_parts;
 
4689
      key_map cur_parts;
 
4690
      for (uint32_t pos= 0; pos < max_key_part; pos++)
 
4691
        all_parts.set(pos);
 
4692
      cur_parts= used_key_parts_map >> 1;
8067
4693
      if (all_parts != cur_parts)
8068
4694
        goto next_index;
8069
4695
    }
8104
4730
                             NULL :
8105
4731
                           NULL;
8106
4732
    if (first_non_group_part &&
8107
 
        (!min_max_arg_part || (min_max_arg_part - first_non_group_part > 0)))
 
4733
        (! min_max_arg_part || (min_max_arg_part - first_non_group_part > 0)))
8108
4734
    {
8109
4735
      if (tree)
8110
4736
      {
8111
4737
        uint32_t dummy;
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,
8116
 
                                    last_part, session, key_infix, &key_infix_len,
8117
 
                                    &first_non_infix_part))
 
4738
        optimizer::SEL_ARG *index_range_tree= get_index_range_tree(cur_index,
 
4739
                                                                   tree,
 
4740
                                                                   param,
 
4741
                                                                   &dummy);
 
4742
        if (! get_constant_key_infix(cur_index_info,
 
4743
                                     index_range_tree,
 
4744
                                     first_non_group_part,
 
4745
                                     min_max_arg_part,
 
4746
                                     last_part,
 
4747
                                     session,
 
4748
                                     cur_key_infix,
 
4749
                                     &cur_key_infix_len,
 
4750
                                     &first_non_infix_part))
 
4751
        {
8118
4752
          goto next_index;
 
4753
        }
8119
4754
      }
8120
4755
      else if (min_max_arg_part &&
8121
4756
               (min_max_arg_part - first_non_group_part > 0))
8140
4775
          Store the first and last keyparts that need to be analyzed
8141
4776
          into one array that can be passed as parameter.
8142
4777
        */
8143
 
        KEY_PART_INFO *key_part_range[2];
 
4778
        KeyPartInfo *key_part_range[2];
8144
4779
        key_part_range[0]= first_non_group_part;
8145
4780
        key_part_range[1]= last_part;
8146
4781
 
8147
4782
        /* Check if cur_part is referenced in the WHERE clause. */
8148
 
        if (join->conds->walk(&Item::find_item_in_field_list_processor, 0,
 
4783
        if (join->conds->walk(&Item::find_item_in_field_list_processor,
 
4784
                              0,
8149
4785
                              (unsigned char*) key_part_range))
8150
4786
          goto next_index;
8151
4787
      }
8161
4797
                (min_max_arg_part && (min_max_arg_part < last_part));
8162
4798
      for (; cur_part != last_part; cur_part++)
8163
4799
      {
8164
 
        if (bitmap_is_set(table->read_set, cur_part->field->field_index))
 
4800
        if (cur_part->field->isReadSet())
8165
4801
          goto next_index;
8166
4802
      }
8167
4803
    }
8168
4804
 
8169
4805
    /* If we got to this point, cur_index_info passes the test. */
8170
 
    key_infix_parts= key_infix_len ?
 
4806
    key_infix_parts= cur_key_infix_len ?
8171
4807
                     (first_non_infix_part - first_non_group_part) : 0;
8172
 
    used_key_parts= cur_group_key_parts + key_infix_parts;
 
4808
    cur_used_key_parts= cur_group_key_parts + key_infix_parts;
8173
4809
 
8174
4810
    /* Compute the cost of using this index. */
8175
4811
    if (tree)
8176
4812
    {
8177
4813
      /* Find the SEL_ARG sub-tree that corresponds to the chosen index. */
8178
 
      cur_index_tree= get_index_range_tree(cur_index, tree, param,
 
4814
      cur_index_tree= get_index_range_tree(cur_index,
 
4815
                                           tree,
 
4816
                                           param,
8179
4817
                                           &cur_param_idx);
8180
4818
      /* Check if this range tree can be used for prefix retrieval. */
8181
 
      COST_VECT dummy_cost;
 
4819
      optimizer::CostVector dummy_cost;
8182
4820
      uint32_t mrr_flags= HA_MRR_USE_DEFAULT_IMPL;
8183
 
      uint32_t mrr_bufsize=0;
8184
 
      cur_quick_prefix_records= check_quick_select(param, cur_param_idx,
 
4821
      uint32_t mrr_bufsize= 0;
 
4822
      cur_quick_prefix_records= check_quick_select(session,
 
4823
                                                   param,
 
4824
                                                   cur_param_idx,
8185
4825
                                                   false /*don't care*/,
8186
 
                                                   cur_index_tree, true,
8187
 
                                                   &mrr_flags, &mrr_bufsize,
 
4826
                                                   cur_index_tree,
 
4827
                                                   true,
 
4828
                                                   &mrr_flags,
 
4829
                                                   &mrr_bufsize,
8188
4830
                                                   &dummy_cost);
8189
4831
    }
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);
 
4832
    cost_group_min_max(table,
 
4833
                       cur_index_info,
 
4834
                       cur_used_key_parts,
 
4835
                       cur_group_key_parts,
 
4836
                       tree,
 
4837
                       cur_index_tree,
 
4838
                       cur_quick_prefix_records,
 
4839
                       have_min,
 
4840
                       have_max,
 
4841
                       &cur_read_cost,
 
4842
                       &cur_records);
8194
4843
    /*
8195
4844
      If cur_read_cost is lower than best_read_cost use cur_index.
8196
4845
      Do not compare doubles directly because they may have different
8208
4857
      best_param_idx= cur_param_idx;
8209
4858
      group_key_parts= cur_group_key_parts;
8210
4859
      group_prefix_len= cur_group_prefix_len;
 
4860
      key_infix_len= cur_key_infix_len;
 
4861
 
 
4862
      if (key_infix_len)
 
4863
      {
 
4864
        memcpy(key_infix, cur_key_infix, sizeof (key_infix));
 
4865
      }
 
4866
 
 
4867
      used_key_parts= cur_used_key_parts;
8211
4868
    }
8212
4869
 
8213
4870
  next_index:
8214
4871
    cur_group_key_parts= 0;
8215
4872
    cur_group_prefix_len= 0;
 
4873
    cur_key_infix_len= 0;
8216
4874
  }
8217
 
  if (!index_info) /* No usable index found. */
 
4875
  if (! index_info) /* No usable index found. */
8218
4876
    return NULL;
8219
4877
 
8220
4878
  /* Check (SA3) for the where clause. */
8221
4879
  if (join->conds && min_max_arg_item &&
8222
 
      !check_group_min_max_predicates(join->conds, min_max_arg_item, Field::itRAW))
 
4880
      ! check_group_min_max_predicates(join->conds, min_max_arg_item))
8223
4881
    return NULL;
8224
4882
 
8225
4883
  /* 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)
8237
 
      return NULL;
8238
 
 
8239
 
    read_plan->read_cost= best_read_cost;
8240
 
    read_plan->records=   best_records;
8241
 
  }
8242
 
 
 
4884
  read_plan= new (*param->mem_root) optimizer::GroupMinMaxReadPlan(have_min,
 
4885
                                                        have_max,
 
4886
                                                        min_max_arg_part,
 
4887
                                                        group_prefix_len,
 
4888
                                                        used_key_parts,
 
4889
                                                        group_key_parts,
 
4890
                                                        index_info,
 
4891
                                                        index,
 
4892
                                                        key_infix_len,
 
4893
                                                        (key_infix_len > 0) ? key_infix : NULL,
 
4894
                                                        tree,
 
4895
                                                        best_index_tree,
 
4896
                                                        best_param_idx,
 
4897
                                                        best_quick_prefix_records);
 
4898
  if (tree && read_plan->quick_prefix_records == 0)
 
4899
    return NULL;
 
4900
  read_plan->read_cost= best_read_cost;
 
4901
  read_plan->records= best_records;
8243
4902
  return read_plan;
8244
4903
}
8245
4904
 
8265
4924
    true  if cond passes the test
8266
4925
    false o/w
8267
4926
*/
8268
 
 
8269
 
static bool
8270
 
check_group_min_max_predicates(COND *cond, Item_field *min_max_arg_item,
8271
 
                               Field::imagetype image_type)
 
4927
static bool check_group_min_max_predicates(COND *cond, Item_field *min_max_arg_item)
8272
4928
{
8273
4929
  assert(cond && min_max_arg_item);
8274
4930
 
8276
4932
  Item::Type cond_type= cond->type();
8277
4933
  if (cond_type == Item::COND_ITEM) /* 'AND' or 'OR' */
8278
4934
  {
8279
 
    List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
8280
 
    Item *and_or_arg;
 
4935
    List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
 
4936
    Item *and_or_arg= NULL;
8281
4937
    while ((and_or_arg= li++))
8282
4938
    {
8283
 
      if (!check_group_min_max_predicates(and_or_arg, min_max_arg_item,
8284
 
                                         image_type))
 
4939
      if (! check_group_min_max_predicates(and_or_arg, min_max_arg_item))
8285
4940
        return false;
8286
4941
    }
8287
4942
    return true;
8305
4960
  /* Test if cond references only group-by or non-group fields. */
8306
4961
  Item_func *pred= (Item_func*) cond;
8307
4962
  Item **arguments= pred->arguments();
8308
 
  Item *cur_arg;
 
4963
  Item *cur_arg= NULL;
8309
4964
  for (uint32_t arg_idx= 0; arg_idx < pred->argument_count (); arg_idx++)
8310
4965
  {
8311
4966
    cur_arg= arguments[arg_idx]->real_item();
8333
4988
        /* Check that pred compares min_max_arg_item with a constant. */
8334
4989
        Item *args[3];
8335
4990
        memset(args, 0, 3 * sizeof(Item*));
8336
 
        bool inv;
 
4991
        bool inv= false;
8337
4992
        /* Test if this is a comparison of a field and a constant. */
8338
 
        if (!simple_pred(pred, args, &inv))
 
4993
        if (! optimizer::simple_pred(pred, args, inv))
8339
4994
          return false;
8340
4995
 
8341
4996
        /* Check for compatible string comparisons - similar to get_mm_leaf. */
8345
5000
              Don't use an index when comparing strings of different collations.
8346
5001
            */
8347
5002
            ((args[1]->result_type() == STRING_RESULT &&
8348
 
              image_type == Field::itRAW &&
8349
5003
              ((Field_str*) min_max_arg_item->field)->charset() !=
8350
5004
              pred->compare_collation())
8351
5005
             ||
8355
5009
             */
8356
5010
             (args[1]->result_type() != STRING_RESULT &&
8357
5011
              min_max_arg_item->field->cmp_type() != args[1]->result_type())))
 
5012
        {
8358
5013
          return false;
 
5014
        }
8359
5015
      }
8360
5016
    }
8361
5017
    else if (cur_arg->type() == Item::FUNC_ITEM)
8362
5018
    {
8363
 
      if (!check_group_min_max_predicates(cur_arg, min_max_arg_item,
8364
 
                                         image_type))
 
5019
      if (! check_group_min_max_predicates(cur_arg, min_max_arg_item))
8365
5020
        return false;
8366
5021
    }
8367
5022
    else if (cur_arg->const_item())
8406
5061
    true  if the index passes the test
8407
5062
    false o/w
8408
5063
*/
8409
 
 
8410
5064
static bool
8411
 
get_constant_key_infix(KEY *, SEL_ARG *index_range_tree,
8412
 
                       KEY_PART_INFO *first_non_group_part,
8413
 
                       KEY_PART_INFO *min_max_arg_part,
8414
 
                       KEY_PART_INFO *last_part,
8415
 
                       Session *, unsigned char *key_infix, uint32_t *key_infix_len,
8416
 
                       KEY_PART_INFO **first_non_infix_part)
 
5065
get_constant_key_infix(KeyInfo *,
 
5066
                       optimizer::SEL_ARG *index_range_tree,
 
5067
                       KeyPartInfo *first_non_group_part,
 
5068
                       KeyPartInfo *min_max_arg_part,
 
5069
                       KeyPartInfo *last_part,
 
5070
                       Session *,
 
5071
                       unsigned char *key_infix,
 
5072
                       uint32_t *key_infix_len,
 
5073
                       KeyPartInfo **first_non_infix_part)
8417
5074
{
8418
 
  SEL_ARG       *cur_range;
8419
 
  KEY_PART_INFO *cur_part;
 
5075
  optimizer::SEL_ARG *cur_range= NULL;
 
5076
  KeyPartInfo *cur_part= NULL;
8420
5077
  /* End part for the first loop below. */
8421
 
  KEY_PART_INFO *end_part= min_max_arg_part ? min_max_arg_part : last_part;
 
5078
  KeyPartInfo *end_part= min_max_arg_part ? min_max_arg_part : last_part;
8422
5079
 
8423
5080
  *key_infix_len= 0;
8424
5081
  unsigned char *key_ptr= key_infix;
8434
5091
      if (cur_range->field->eq(cur_part->field))
8435
5092
        break;
8436
5093
    }
8437
 
    if (!cur_range)
 
5094
    if (! cur_range)
8438
5095
    {
8439
5096
      if (min_max_arg_part)
8440
5097
        return false; /* The current keypart has no range predicates at all. */
8450
5107
      return false; /* This is not the only range predicate for the field. */
8451
5108
    if ((cur_range->min_flag & NO_MIN_RANGE) ||
8452
5109
        (cur_range->max_flag & NO_MAX_RANGE) ||
8453
 
        (cur_range->min_flag & NEAR_MIN) || (cur_range->max_flag & NEAR_MAX))
 
5110
        (cur_range->min_flag & NEAR_MIN) ||
 
5111
        (cur_range->max_flag & NEAR_MAX))
8454
5112
      return false;
8455
5113
 
8456
5114
    uint32_t field_length= cur_part->store_length;
8483
5141
    field  field that possibly references some key part in index
8484
5142
 
8485
5143
  NOTES
8486
 
    The return value can be used to get a KEY_PART_INFO pointer by
 
5144
    The return value can be used to get a KeyPartInfo pointer by
8487
5145
    part= index->key_part + get_field_keypart(...) - 1;
8488
5146
 
8489
5147
  RETURN
8490
5148
    Positive number which is the consecutive number of the key part, or
8491
5149
    0 if field does not reference any index field.
8492
5150
*/
8493
 
 
8494
5151
static inline uint
8495
 
get_field_keypart(KEY *index, Field *field)
 
5152
get_field_keypart(KeyInfo *index, Field *field)
8496
5153
{
8497
 
  KEY_PART_INFO *part, *end;
 
5154
  KeyPartInfo *part= NULL;
 
5155
  KeyPartInfo *end= NULL;
8498
5156
 
8499
5157
  for (part= index->key_part, end= part + index->key_parts; part < end; part++)
8500
5158
  {
8512
5170
    get_index_range_tree()
8513
5171
    index     [in]  The ID of the index being looked for
8514
5172
    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'
 
5173
    param     [in]  Parameter from SqlSelect::test_quick_select
 
5174
    param_idx [out] Index in the array Parameter::key that corresponds to 'index'
8517
5175
 
8518
5176
  DESCRIPTION
8519
5177
 
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
 
5178
    A optimizer::SEL_TREE contains range trees for all usable indexes. This procedure
 
5179
    finds the SEL_ARG sub-tree for 'index'. The members of a optimizer::SEL_TREE are
 
5180
    ordered in the same way as the members of Parameter::key, thus we first find
 
5181
    the corresponding index in the array Parameter::key. This index is returned
8524
5182
    through the variable param_idx, to be used later as argument of
8525
5183
    check_quick_select().
8526
5184
 
8527
5185
  RETURN
8528
5186
    Pointer to the SEL_ARG subtree that corresponds to index.
8529
5187
*/
8530
 
 
8531
 
SEL_ARG * get_index_range_tree(uint32_t index, SEL_TREE* range_tree, PARAM *param,
8532
 
                               uint32_t *param_idx)
 
5188
optimizer::SEL_ARG *get_index_range_tree(uint32_t index,
 
5189
                                         optimizer::SEL_TREE* range_tree,
 
5190
                                         optimizer::Parameter *param,
 
5191
                                         uint32_t *param_idx)
8533
5192
{
8534
5193
  uint32_t idx= 0; /* Index nr in param->key_parts */
8535
5194
  while (idx < param->keys)
8562
5221
    records             [out] The number of rows retrieved
8563
5222
 
8564
5223
  DESCRIPTION
8565
 
    This method computes the access cost of a TRP_GROUP_MIN_MAX instance and
 
5224
    This method computes the access cost of a GroupMinMaxReadPlan instance and
8566
5225
    the number of rows returned. It updates this->read_cost and this->records.
8567
5226
 
8568
5227
  NOTES
8602
5261
  RETURN
8603
5262
    None
8604
5263
*/
8605
 
 
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,
8608
 
                        SEL_ARG *, ha_rows quick_prefix_records,
8609
 
                        bool have_min, bool have_max,
8610
 
                        double *read_cost, ha_rows *records)
 
5264
void cost_group_min_max(Table* table,
 
5265
                        KeyInfo *index_info,
 
5266
                        uint32_t used_key_parts,
 
5267
                        uint32_t group_key_parts,
 
5268
                        optimizer::SEL_TREE *range_tree,
 
5269
                        optimizer::SEL_ARG *,
 
5270
                        ha_rows quick_prefix_records,
 
5271
                        bool have_min,
 
5272
                        bool have_max,
 
5273
                        double *read_cost,
 
5274
                        ha_rows *records)
8611
5275
{
8612
5276
  ha_rows table_records;
8613
5277
  uint32_t num_groups;
8621
5285
  double io_cost;
8622
5286
  double cpu_cost= 0; /* TODO: CPU cost of index_read calls? */
8623
5287
 
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)
 
5288
  table_records= table->cursor->stats.records;
 
5289
  keys_per_block= (table->cursor->stats.block_size / 2 /
 
5290
                   (index_info->key_length + table->cursor->ref_length)
8627
5291
                        + 1);
8628
 
  num_blocks= (uint)(table_records / keys_per_block) + 1;
 
5292
  num_blocks= (uint32_t) (table_records / keys_per_block) + 1;
8629
5293
 
8630
5294
  /* Compute the number of keys in a group. */
8631
5295
  keys_per_group= index_info->rec_per_key[group_key_parts - 1];
8632
5296
  if (keys_per_group == 0) /* If there is no statistics try to guess */
8633
5297
    /* each group contains 10% of all records */
8634
 
    keys_per_group= (uint)(table_records / 10) + 1;
8635
 
  num_groups= (uint)(table_records / keys_per_group) + 1;
 
5298
    keys_per_group= (uint32_t)(table_records / 10) + 1;
 
5299
  num_groups= (uint32_t)(table_records / keys_per_group) + 1;
8636
5300
 
8637
5301
  /* Apply the selectivity of the quick select for group prefixes. */
8638
5302
  if (range_tree && (quick_prefix_records != HA_POS_ERROR))
8639
5303
  {
8640
5304
    quick_prefix_selectivity= (double) quick_prefix_records /
8641
5305
                              (double) table_records;
8642
 
    num_groups= (uint) rint(num_groups * quick_prefix_selectivity);
8643
 
    set_if_bigger(num_groups, 1);
 
5306
    num_groups= (uint32_t) rint(num_groups * quick_prefix_selectivity);
 
5307
    set_if_bigger(num_groups, 1U);
8644
5308
  }
8645
5309
 
8646
5310
  if (used_key_parts > group_key_parts)
8655
5319
    {
8656
5320
      double blocks_per_group= (double) num_blocks / (double) num_groups;
8657
5321
      p_overlap= (blocks_per_group * (keys_per_subgroup - 1)) / keys_per_group;
8658
 
      p_overlap= cmin(p_overlap, 1.0);
 
5322
      p_overlap= min(p_overlap, 1.0);
8659
5323
    }
8660
 
    io_cost= (double) cmin(num_groups * (1 + p_overlap), (double)num_blocks);
 
5324
    io_cost= (double) min(num_groups * (1 + p_overlap), (double)num_blocks);
8661
5325
  }
8662
5326
  else
8663
5327
    io_cost= (keys_per_group > keys_per_block) ?
8668
5332
  /*
8669
5333
    TODO: If there is no WHERE clause and no other expressions, there should be
8670
5334
    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().
 
5335
    scan as computed in SqlSelect::test_quick_select().
8672
5336
  */
8673
5337
  cpu_cost= (double) num_groups / TIME_FOR_COMPARE;
8674
5338
 
8681
5345
  Construct a new quick select object for queries with group by with min/max.
8682
5346
 
8683
5347
  SYNOPSIS
8684
 
    TRP_GROUP_MIN_MAX::make_quick()
 
5348
    GroupMinMaxReadPlan::make_quick()
8685
5349
    param              Parameter from test_quick_select
8686
5350
    retrieve_full_rows ignored
8687
5351
    parent_alloc       Memory pool to use, if any.
8688
5352
 
8689
5353
  NOTES
8690
5354
    Make_quick ignores the retrieve_full_rows parameter because
8691
 
    QUICK_GROUP_MIN_MAX_SELECT always performs 'index only' scans.
 
5355
    QuickGroupMinMaxSelect always performs 'index only' scans.
8692
5356
    The other parameter are ignored as well because all necessary
8693
5357
    data to create the QUICK object is computed at this TRP creation
8694
5358
    time.
8695
5359
 
8696
5360
  RETURN
8697
 
    New QUICK_GROUP_MIN_MAX_SELECT object if successfully created,
 
5361
    New QuickGroupMinMaxSelect object if successfully created,
8698
5362
    NULL otherwise.
8699
5363
*/
8700
 
 
8701
 
QUICK_SELECT_I *
8702
 
TRP_GROUP_MIN_MAX::make_quick(PARAM *param, bool, MEM_ROOT *parent_alloc)
 
5364
optimizer::QuickSelectInterface *
 
5365
optimizer::GroupMinMaxReadPlan::make_quick(optimizer::Parameter *param, bool, memory::Root *parent_alloc)
8703
5366
{
8704
 
  QUICK_GROUP_MIN_MAX_SELECT *quick;
8705
 
 
8706
 
  quick= new QUICK_GROUP_MIN_MAX_SELECT(param->table,
8707
 
                                        param->session->lex->current_select->join,
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)
8714
 
    return NULL;
8715
 
 
 
5367
  optimizer::QuickGroupMinMaxSelect *quick= new optimizer::QuickGroupMinMaxSelect(param->table,
 
5368
                                               param->session->lex().current_select->join,
 
5369
                                               have_min,
 
5370
                                               have_max,
 
5371
                                               min_max_arg_part,
 
5372
                                               group_prefix_len,
 
5373
                                               group_key_parts,
 
5374
                                               used_key_parts,
 
5375
                                               index_info,
 
5376
                                               index,
 
5377
                                               read_cost,
 
5378
                                               records,
 
5379
                                               key_infix_len,
 
5380
                                               key_infix,
 
5381
                                               parent_alloc);
8716
5382
  if (quick->init())
8717
5383
  {
8718
5384
    delete quick;
8723
5389
  {
8724
5390
    assert(quick_prefix_records > 0);
8725
5391
    if (quick_prefix_records == HA_POS_ERROR)
 
5392
    {
8726
5393
      quick->quick_prefix_select= NULL; /* Can't construct a quick select. */
 
5394
    }
8727
5395
    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);
 
5396
    {
 
5397
      /* Make a QuickRangeSelect to be used for group prefix retrieval. */
 
5398
      quick->quick_prefix_select= optimizer::get_quick_select(param,
 
5399
                                                              param_idx,
 
5400
                                                              index_tree,
 
5401
                                                              HA_MRR_USE_DEFAULT_IMPL,
 
5402
                                                              0,
 
5403
                                                              &quick->alloc);
 
5404
    }
8733
5405
 
8734
5406
    /*
8735
5407
      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
 
5408
      attribute, and create an array of QuickRanges to be used by the
8737
5409
      new quick select.
8738
5410
    */
8739
5411
    if (min_max_arg_part)
8740
5412
    {
8741
 
      SEL_ARG *min_max_range= index_tree;
 
5413
      optimizer::SEL_ARG *min_max_range= index_tree;
8742
5414
      while (min_max_range) /* Find the tree for the MIN/MAX key part. */
8743
5415
      {
8744
5416
        if (min_max_range->field->eq(min_max_arg_part->field))
8748
5420
      /* Scroll to the leftmost interval for the MIN/MAX argument. */
8749
5421
      while (min_max_range && min_max_range->prev)
8750
5422
        min_max_range= min_max_range->prev;
8751
 
      /* Create an array of QUICK_RANGEs for the MIN/MAX argument. */
 
5423
      /* Create an array of QuickRanges for the MIN/MAX argument. */
8752
5424
      while (min_max_range)
8753
5425
      {
8754
5426
        if (quick->add_range(min_max_range))
8771
5443
}
8772
5444
 
8773
5445
 
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
8781
 
    have_min          true if the query selects a MIN function
8782
 
    have_max          true if the query selects a MAX function
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::
8799
 
QUICK_GROUP_MIN_MAX_SELECT(Table *table, JOIN *join_arg, bool have_min_arg,
8800
 
                           bool have_max_arg,
8801
 
                           KEY_PART_INFO *min_max_arg_part_arg,
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,
8806
 
                           unsigned char *key_infix_arg, MEM_ROOT *parent_alloc)
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),
8810
 
   have_max(have_max_arg), seen_first_key(false),
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
 
  */
8832
 
  assert(!parent_alloc);
8833
 
  if (!parent_alloc)
8834
 
  {
8835
 
    init_sql_alloc(&alloc, join->session->variables.range_alloc_block_size, 0);
8836
 
    join->session->mem_root= &alloc;
8837
 
  }
8838
 
  else
8839
 
    memset(&alloc, 0, sizeof(MEM_ROOT));  // ensure that it's not used
8840
 
}
8841
 
 
8842
 
 
8843
 
/*
8844
 
  Do post-constructor initialization.
8845
 
 
8846
 
  SYNOPSIS
8847
 
    QUICK_GROUP_MIN_MAX_SELECT::init()
8848
 
 
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
 
 
8865
 
  if (!(last_prefix= (unsigned char*) alloc_root(&alloc, group_prefix_len)))
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
 
  */
8871
 
  if (!(group_prefix= (unsigned char*) alloc_root(&alloc,
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
 
    */
8881
 
    unsigned char *tmp_key_infix= (unsigned char*) alloc_root(&alloc, key_infix_len);
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
 
{
8939
 
  if (file->inited != handler::NONE)
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()
8955
 
    sel_range  Range object from which a
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
8964
 
    false on success
8965
 
    true  otherwise
8966
 
*/
8967
 
 
8968
 
bool QUICK_GROUP_MIN_MAX_SELECT::add_range(SEL_ARG *sel_range)
8969
 
{
8970
 
  QUICK_RANGE *range;
8971
 
  uint32_t range_flag= sel_range->min_flag | sel_range->max_flag;
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))
8975
 
    return false;
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)
8993
 
    return true;
8994
 
  if (insert_dynamic(&min_max_ranges, (unsigned char*)&range))
8995
 
    return true;
8996
 
  return false;
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.
9009
 
    It defines a number of ranges of length x.
9010
 
    However when jumping through the prefixes we use only the the first
9011
 
    few most significant keyparts in the range key. However if there
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
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;
9023
 
    uint32_t inx;
9024
 
 
9025
 
    for (inx= 0, arr= &quick_prefix_select->ranges; inx < arr->elements; inx++)
9026
 
    {
9027
 
      QUICK_RANGE *range;
9028
 
 
9029
 
      get_dynamic(arr, (unsigned char*)&range, inx);
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. */
9065
 
      get_dynamic(&min_max_ranges, (unsigned char*)&cur_range,
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. */
9076
 
      get_dynamic(&min_max_ranges, (unsigned char*)&cur_range, 0);
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)))
9123
 
    return result;
9124
 
  if (quick_prefix_select && quick_prefix_select->reset())
9125
 
    return 0;
9126
 
  result= file->index_last(record);
9127
 
  if (result == HA_ERR_END_OF_FILE)
9128
 
    return 0;
9129
 
  /* Save the prefix of the last group. */
9130
 
  key_copy(last_prefix, record, index_info, group_prefix_len);
9131
 
 
9132
 
  return 0;
9133
 
}
9134
 
 
9135
 
 
9136
 
 
9137
 
/*
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);
9186
 
      assert(is_last_prefix <= 0);
9187
 
    }
9188
 
    else
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. */
9209
 
      assert(((have_max && !have_min) ||
9210
 
                  (have_max && have_min && (max_res == 0))));
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
 
 
9239
 
  return result;
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()))
9274
 
      return result;
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)))
9284
 
        return result;
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
 
  */
9325
 
  return result;
9326
 
}
9327
 
 
9328
 
 
9329
 
/*
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);
9356
 
  return result;
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
 
  {
9387
 
    unsigned char *cur_prefix= seen_first_key ? group_prefix : NULL;
9388
 
    if ((result= quick_prefix_select->get_next_prefix(group_prefix_len,
9389
 
                         make_prev_keypart_map(group_key_parts), cur_prefix)))
9390
 
      return result;
9391
 
    seen_first_key= true;
9392
 
  }
9393
 
  else
9394
 
  {
9395
 
    if (!seen_first_key)
9396
 
    {
9397
 
      result= file->index_first(record);
9398
 
      if (result)
9399
 
        return result;
9400
 
      seen_first_key= true;
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)
9409
 
        return result;
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
 
 
9420
 
  return 0;
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;
9450
 
  bool found_null= false;
9451
 
  int result= HA_ERR_KEY_NOT_FOUND;
9452
 
  basic_string<unsigned char> max_key;
9453
 
 
9454
 
  max_key.reserve(real_prefix_len + min_max_arg_len);
9455
 
 
9456
 
  assert(min_max_ranges.elements > 0);
9457
 
 
9458
 
  for (uint32_t range_idx= 0; range_idx < min_max_ranges.elements; range_idx++)
9459
 
  { /* Search from the left-most range to the right. */
9460
 
    get_dynamic(&min_max_ranges, (unsigned char*)&cur_range, range_idx);
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) &&
9467
 
        (key_cmp(min_max_arg_part, (const unsigned char*) cur_range->max_key,
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);
9513
 
      found_null= true;
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. */
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);
9531
 
      /* Compare the found key with max_key. */
9532
 
      int cmp_res= key_cmp(index_info->key_part,
9533
 
                           max_key.data(),
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. */
9542
 
    assert(result == 0);
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;
9586
 
  basic_string<unsigned char> min_key;
9587
 
  min_key.reserve(real_prefix_len + min_max_arg_len);
9588
 
 
9589
 
  assert(min_max_ranges.elements > 0);
9590
 
 
9591
 
  for (uint32_t range_idx= min_max_ranges.elements; range_idx > 0; range_idx--)
9592
 
  { /* Search from the right-most range to the left. */
9593
 
    get_dynamic(&min_max_ranges, (unsigned char*)&cur_range, range_idx - 1);
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) &&
9601
 
        (key_cmp(min_max_arg_part, (const unsigned char*) cur_range->min_key,
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. */
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
 
 
9651
 
      /* Compare the found key with min_key. */
9652
 
      int cmp_res= key_cmp(index_info->key_part,
9653
 
                           min_key.data(),
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];
9750
 
  uint32_t length;
9751
 
  key_names->append(index_info->name);
9752
 
  length= int64_t2str(max_used_key_length, buf, 10) - buf;
9753
 
  used_lengths->append(buf, length);
9754
 
}
9755
 
 
9756
 
static void print_sel_tree(PARAM *param, SEL_TREE *tree, key_map *tree_map, const char *)
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
 
    {
9770
 
      uint32_t keynr= param->real_keynr[idx];
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
 
 
9781
 
static void print_ror_scans_arr(Table *table,
9782
 
                                const char *, struct st_ror_scan_info **start,
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
 
/*****************************************************************************
9799
 
** Instantiate templates
9800
 
*****************************************************************************/
9801
 
 
9802
 
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
9803
 
template class List<QUICK_RANGE>;
9804
 
template class List_iterator<QUICK_RANGE>;
9805
 
#endif
 
5446
optimizer::QuickSelectInterface *optimizer::RangeReadPlan::make_quick(optimizer::Parameter *param, bool, memory::Root *parent_alloc)
 
5447
{
 
5448
  optimizer::QuickRangeSelect *quick= optimizer::get_quick_select(param, key_idx, key, mrr_flags, mrr_buf_size, parent_alloc);
 
5449
  if (quick)
 
5450
  {
 
5451
    quick->records= records;
 
5452
    quick->read_time= read_cost;
 
5453
  }
 
5454
  return quick;
 
5455
}
 
5456
 
 
5457
 
 
5458
uint32_t optimizer::RorScanInfo::findFirstNotSet() const
 
5459
{
 
5460
  boost::dynamic_bitset<> map= bitsToBitset();
 
5461
  for (boost::dynamic_bitset<>::size_type i= 0; i < map.size(); i++)
 
5462
  {
 
5463
    if (not map.test(i))
 
5464
      return i;
 
5465
  }
 
5466
  return map.size();
 
5467
}
 
5468
 
 
5469
 
 
5470
size_t optimizer::RorScanInfo::getBitCount() const
 
5471
{
 
5472
  boost::dynamic_bitset<> tmp_bitset= bitsToBitset();
 
5473
  return tmp_bitset.count();
 
5474
}
 
5475
 
 
5476
 
 
5477
void optimizer::RorScanInfo::subtractBitset(const boost::dynamic_bitset<>& in_bitset)
 
5478
{
 
5479
  boost::dynamic_bitset<> tmp_bitset= bitsToBitset();
 
5480
  tmp_bitset-= in_bitset;
 
5481
  covered_fields= tmp_bitset.to_ulong();
 
5482
}
 
5483
 
 
5484
 
 
5485
boost::dynamic_bitset<> optimizer::RorScanInfo::bitsToBitset() const
 
5486
{
 
5487
  string res;
 
5488
  uint64_t conv= covered_fields;
 
5489
  while (conv)
 
5490
  {
 
5491
    res.push_back((conv & 1) + '0');
 
5492
    conv>>= 1;
 
5493
  }
 
5494
  if (! res.empty())
 
5495
  {
 
5496
    std::reverse(res.begin(), res.end());
 
5497
  }
 
5498
  string final(covered_fields_size - res.length(), '0');
 
5499
  final.append(res);
 
5500
  return boost::dynamic_bitset<>(final);
 
5501
}
 
5502
 
 
5503
 
 
5504
} /* namespace drizzled */