~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/opt_range.cc

Replace MAX_(DATE|TIME).*_WIDTH defines in definitions.h with real (and correct) static const members to Temporal types.

This fixes the buffer overflow in https://bugs.launchpad.net/drizzle/+bug/373468

It also removes a handwritten snprintf in field/datetime.cc
However... this caused us to have to change Temporal to have a way to not
"convert" the int64_t value (so 20090101 becomes 20090101000000 etc) as it
has already been converted and we just want the Temporal type to do the
to_string conversion.

This still causes a failure in 'metadata' test due to size of timestamp type. I need feedback from Jay on when the usecond code comes into play to know the correct fix for this.

Show diffs side-by-side

added added

removed removed

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