~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/opt_range.cc

  • Committer: Padraig O'Sullivan
  • Date: 2009-09-17 00:08:20 UTC
  • mto: (1126.9.3 captain-20090915-01)
  • mto: This revision was merged to the branch mainline in revision 1133.
  • Revision ID: osullivan.padraig@gmail.com-20090917000820-urd6p46qngi1okjp
Updated calls to some dtrace probes to cast the parameter to const char *
appropriately. Also, removed the additional variable in places that I was
using.

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_base.h>
 
108
#include <drizzled/sql_select.h>
 
109
#include <drizzled/error.h>
 
110
#include <drizzled/cost_vect.h>
 
111
#include <drizzled/item/cmpfunc.h>
 
112
#include <drizzled/field/num.h>
 
113
#include <drizzled/check_stack_overrun.h>
104
114
 
105
 
#include <math.h>
106
 
#include <float.h>
 
115
#include "drizzled/temporal.h" /* Needed in get_mm_leaf() for timestamp -> datetime comparisons */
107
116
 
108
117
#include <string>
109
118
#include <vector>
110
119
#include <algorithm>
111
120
 
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
 
 
140
121
using namespace std;
141
 
namespace drizzled
142
 
{
143
122
 
144
123
#define HA_END_SPACE_KEY 0
145
124
 
152
131
    return static_cast<ha_rows>(x);
153
132
}
154
133
 
 
134
extern "C" int refpos_order_cmp(void* arg, const void *a,const void *b)
 
135
{
 
136
  handler *file= (handler*)arg;
 
137
  return file->cmp_ref((const unsigned char*)a, (const unsigned char*)b);
 
138
}
 
139
 
 
140
static int sel_cmp(Field *f,unsigned char *a,unsigned char *b,uint8_t a_flag,uint8_t b_flag);
 
141
 
155
142
static unsigned char is_null_string[2]= {1,0};
156
143
 
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.
 
144
class RANGE_OPT_PARAM;
 
145
/*
 
146
  A construction block of the SEL_ARG-graph.
 
147
 
 
148
  The following description only covers graphs of SEL_ARG objects with
 
149
  sel_arg->type==KEY_RANGE:
 
150
 
 
151
  One SEL_ARG object represents an "elementary interval" in form
 
152
 
 
153
      min_value <=?  table.keypartX  <=? max_value
 
154
 
 
155
  The interval is a non-empty interval of any kind: with[out] minimum/maximum
 
156
  bound, [half]open/closed, single-point interval, etc.
 
157
 
 
158
  1. SEL_ARG GRAPH STRUCTURE
 
159
 
 
160
  SEL_ARG objects are linked together in a graph. The meaning of the graph
 
161
  is better demostrated by an example:
 
162
 
 
163
     tree->keys[i]
 
164
      |
 
165
      |             $              $
 
166
      |    part=1   $     part=2   $    part=3
 
167
      |             $              $
 
168
      |  +-------+  $   +-------+  $   +--------+
 
169
      |  | kp1<1 |--$-->| kp2=5 |--$-->| kp3=10 |
 
170
      |  +-------+  $   +-------+  $   +--------+
 
171
      |      |      $              $       |
 
172
      |      |      $              $   +--------+
 
173
      |      |      $              $   | kp3=12 |
 
174
      |      |      $              $   +--------+
 
175
      |  +-------+  $              $
 
176
      \->| kp1=2 |--$--------------$-+
 
177
         +-------+  $              $ |   +--------+
 
178
             |      $              $  ==>| kp3=11 |
 
179
         +-------+  $              $ |   +--------+
 
180
         | kp1=3 |--$--------------$-+       |
 
181
         +-------+  $              $     +--------+
 
182
             |      $              $     | kp3=14 |
 
183
            ...     $              $     +--------+
 
184
 
 
185
  The entire graph is partitioned into "interval lists".
 
186
 
 
187
  An interval list is a sequence of ordered disjoint intervals over the same
 
188
  key part. SEL_ARG are linked via "next" and "prev" pointers. Additionally,
 
189
  all intervals in the list form an RB-tree, linked via left/right/parent
 
190
  pointers. The RB-tree root SEL_ARG object will be further called "root of the
 
191
  interval list".
 
192
 
 
193
    In the example pic, there are 4 interval lists:
 
194
    "kp<1 OR kp1=2 OR kp1=3", "kp2=5", "kp3=10 OR kp3=12", "kp3=11 OR kp3=13".
 
195
    The vertical lines represent SEL_ARG::next/prev pointers.
 
196
 
 
197
  In an interval list, each member X may have SEL_ARG::next_key_part pointer
 
198
  pointing to the root of another interval list Y. The pointed interval list
 
199
  must cover a key part with greater number (i.e. Y->part > X->part).
 
200
 
 
201
    In the example pic, the next_key_part pointers are represented by
 
202
    horisontal lines.
 
203
 
 
204
  2. SEL_ARG GRAPH SEMANTICS
 
205
 
 
206
  It represents a condition in a special form (we don't have a name for it ATM)
 
207
  The SEL_ARG::next/prev is "OR", and next_key_part is "AND".
 
208
 
 
209
  For example, the picture represents the condition in form:
 
210
   (kp1 < 1 AND kp2=5 AND (kp3=10 OR kp3=12)) OR
 
211
   (kp1=2 AND (kp3=11 OR kp3=14)) OR
 
212
   (kp1=3 AND (kp3=11 OR kp3=14))
 
213
 
 
214
 
 
215
  3. SEL_ARG GRAPH USE
 
216
 
 
217
  Use get_mm_tree() to construct SEL_ARG graph from WHERE condition.
 
218
  Then walk the SEL_ARG graph and get a list of dijsoint ordered key
 
219
  intervals (i.e. intervals in form
 
220
 
 
221
   (constA1, .., const1_K) < (keypart1,.., keypartK) < (constB1, .., constB_K)
 
222
 
 
223
  Those intervals can be used to access the index. The uses are in:
 
224
   - check_quick_select() - Walk the SEL_ARG graph and find an estimate of
 
225
                            how many table records are contained within all
 
226
                            intervals.
 
227
   - get_quick_select()   - Walk the SEL_ARG, materialize the key intervals,
 
228
                            and create QUICK_RANGE_SELECT object that will
 
229
                            read records within these intervals.
 
230
 
 
231
  4. SPACE COMPLEXITY NOTES
 
232
 
 
233
    SEL_ARG graph is a representation of an ordered disjoint sequence of
 
234
    intervals over the ordered set of index tuple values.
 
235
 
 
236
    For multi-part keys, one can construct a WHERE expression such that its
 
237
    list of intervals will be of combinatorial size. Here is an example:
 
238
 
 
239
      (keypart1 IN (1,2, ..., n1)) AND
 
240
      (keypart2 IN (1,2, ..., n2)) AND
 
241
      (keypart3 IN (1,2, ..., n3))
 
242
 
 
243
    For this WHERE clause the list of intervals will have n1*n2*n3 intervals
 
244
    of form
 
245
 
 
246
      (keypart1, keypart2, keypart3) = (k1, k2, k3), where 1 <= k{i} <= n{i}
 
247
 
 
248
    SEL_ARG graph structure aims to reduce the amount of required space by
 
249
    "sharing" the elementary intervals when possible (the pic at the
 
250
    beginning of this comment has examples of such sharing). The sharing may
 
251
    prevent combinatorial blowup:
 
252
 
 
253
      There are WHERE clauses that have combinatorial-size interval lists but
 
254
      will be represented by a compact SEL_ARG graph.
 
255
      Example:
 
256
        (keypartN IN (1,2, ..., n1)) AND
 
257
        ...
 
258
        (keypart2 IN (1,2, ..., n2)) AND
 
259
        (keypart1 IN (1,2, ..., n3))
 
260
 
 
261
    but not in all cases:
 
262
 
 
263
    - There are WHERE clauses that do have a compact SEL_ARG-graph
 
264
      representation but get_mm_tree() and its callees will construct a
 
265
      graph of combinatorial size.
 
266
      Example:
 
267
        (keypart1 IN (1,2, ..., n1)) AND
 
268
        (keypart2 IN (1,2, ..., n2)) AND
 
269
        ...
 
270
        (keypartN IN (1,2, ..., n3))
 
271
 
 
272
    - There are WHERE clauses for which the minimal possible SEL_ARG graph
 
273
      representation will have combinatorial size.
 
274
      Example:
 
275
        By induction: Let's take any interval on some keypart in the middle:
 
276
 
 
277
           kp15=c0
 
278
 
 
279
        Then let's AND it with this interval 'structure' from preceding and
 
280
        following keyparts:
 
281
 
 
282
          (kp14=c1 AND kp16=c3) OR keypart14=c2) (*)
 
283
 
 
284
        We will obtain this SEL_ARG graph:
 
285
 
 
286
             kp14     $      kp15      $      kp16
 
287
                      $                $
 
288
         +---------+  $   +---------+  $   +---------+
 
289
         | kp14=c1 |--$-->| kp15=c0 |--$-->| kp16=c3 |
 
290
         +---------+  $   +---------+  $   +---------+
 
291
              |       $                $
 
292
         +---------+  $   +---------+  $
 
293
         | kp14=c2 |--$-->| kp15=c0 |  $
 
294
         +---------+  $   +---------+  $
 
295
                      $                $
 
296
 
 
297
       Note that we had to duplicate "kp15=c0" and there was no way to avoid
 
298
       that.
 
299
       The induction step: AND the obtained expression with another "wrapping"
 
300
       expression like (*).
 
301
       When the process ends because of the limit on max. number of keyparts
 
302
       we'll have:
 
303
 
 
304
         WHERE clause length  is O(3*#max_keyparts)
 
305
         SEL_ARG graph size   is O(2^(#max_keyparts/2))
 
306
 
 
307
       (it is also possible to construct a case where instead of 2 in 2^n we
 
308
        have a bigger constant, e.g. 4, and get a graph with 4^(31/2)= 2^31
 
309
        nodes)
 
310
 
 
311
    We avoid consuming too much memory by setting a limit on the number of
 
312
    SEL_ARG object we can construct during one range analysis invocation.
199
313
*/
200
314
 
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
 
}
 
315
class SEL_ARG :public Sql_alloc
 
316
{
 
317
public:
 
318
  uint8_t min_flag,max_flag,maybe_flag;
 
319
  uint8_t part;                                 // Which key part
 
320
  uint8_t maybe_null;
 
321
  /*
 
322
    Number of children of this element in the RB-tree, plus 1 for this
 
323
    element itself.
 
324
  */
 
325
  uint16_t elements;
 
326
  /*
 
327
    Valid only for elements which are RB-tree roots: Number of times this
 
328
    RB-tree is referred to (it is referred by SEL_ARG::next_key_part or by
 
329
    SEL_TREE::keys[i] or by a temporary SEL_ARG* variable)
 
330
  */
 
331
  ulong use_count;
 
332
 
 
333
  Field *field;
 
334
  unsigned char *min_value,*max_value;                  // Pointer to range
 
335
 
 
336
  /*
 
337
    eq_tree() requires that left == right == 0 if the type is MAYBE_KEY.
 
338
   */
 
339
  SEL_ARG *left,*right;   /* R-B tree children */
 
340
  SEL_ARG *next,*prev;    /* Links for bi-directional interval list */
 
341
  SEL_ARG *parent;        /* R-B tree parent */
 
342
  SEL_ARG *next_key_part;
 
343
  enum leaf_color { BLACK,RED } color;
 
344
  enum Type { IMPOSSIBLE, MAYBE, MAYBE_KEY, KEY_RANGE } type;
 
345
 
 
346
  enum { MAX_SEL_ARGS = 16000 };
 
347
 
 
348
  SEL_ARG() {}
 
349
  SEL_ARG(SEL_ARG &);
 
350
  SEL_ARG(Field *,const unsigned char *, const unsigned char *);
 
351
  SEL_ARG(Field *field, uint8_t part, unsigned char *min_value, unsigned char *max_value,
 
352
          uint8_t min_flag, uint8_t max_flag, uint8_t maybe_flag);
 
353
  SEL_ARG(enum Type type_arg)
 
354
    :min_flag(0),elements(1),use_count(1),left(0),right(0),next_key_part(0),
 
355
    color(BLACK), type(type_arg)
 
356
  {}
 
357
  inline bool is_same(SEL_ARG *arg)
 
358
  {
 
359
    if (type != arg->type || part != arg->part)
 
360
      return 0;
 
361
    if (type != KEY_RANGE)
 
362
      return 1;
 
363
    return cmp_min_to_min(arg) == 0 && cmp_max_to_max(arg) == 0;
 
364
  }
 
365
  inline void merge_flags(SEL_ARG *arg) { maybe_flag|=arg->maybe_flag; }
 
366
  inline void maybe_smaller() { maybe_flag=1; }
 
367
  /* Return true iff it's a single-point null interval */
 
368
  inline bool is_null_interval() { return maybe_null && max_value[0] == 1; }
 
369
  inline int cmp_min_to_min(SEL_ARG* arg)
 
370
  {
 
371
    return sel_cmp(field,min_value, arg->min_value, min_flag, arg->min_flag);
 
372
  }
 
373
  inline int cmp_min_to_max(SEL_ARG* arg)
 
374
  {
 
375
    return sel_cmp(field,min_value, arg->max_value, min_flag, arg->max_flag);
 
376
  }
 
377
  inline int cmp_max_to_max(SEL_ARG* arg)
 
378
  {
 
379
    return sel_cmp(field,max_value, arg->max_value, max_flag, arg->max_flag);
 
380
  }
 
381
  inline int cmp_max_to_min(SEL_ARG* arg)
 
382
  {
 
383
    return sel_cmp(field,max_value, arg->min_value, max_flag, arg->min_flag);
 
384
  }
 
385
  SEL_ARG *clone_and(SEL_ARG* arg)
 
386
  {                                             // Get overlapping range
 
387
    unsigned char *new_min,*new_max;
 
388
    uint8_t flag_min,flag_max;
 
389
    if (cmp_min_to_min(arg) >= 0)
 
390
    {
 
391
      new_min=min_value; flag_min=min_flag;
 
392
    }
 
393
    else
 
394
    {
 
395
      new_min=arg->min_value; flag_min=arg->min_flag; /* purecov: deadcode */
 
396
    }
 
397
    if (cmp_max_to_max(arg) <= 0)
 
398
    {
 
399
      new_max=max_value; flag_max=max_flag;
 
400
    }
 
401
    else
 
402
    {
 
403
      new_max=arg->max_value; flag_max=arg->max_flag;
 
404
    }
 
405
    return new SEL_ARG(field, part, new_min, new_max, flag_min, flag_max,
 
406
                       test(maybe_flag && arg->maybe_flag));
 
407
  }
 
408
  SEL_ARG *clone_first(SEL_ARG *arg)
 
409
  {                                             // min <= X < arg->min
 
410
    return new SEL_ARG(field,part, min_value, arg->min_value,
 
411
                       min_flag, arg->min_flag & NEAR_MIN ? 0 : NEAR_MAX,
 
412
                       maybe_flag | arg->maybe_flag);
 
413
  }
 
414
  SEL_ARG *clone_last(SEL_ARG *arg)
 
415
  {                                             // min <= X <= key_max
 
416
    return new SEL_ARG(field, part, min_value, arg->max_value,
 
417
                       min_flag, arg->max_flag, maybe_flag | arg->maybe_flag);
 
418
  }
 
419
  SEL_ARG *clone(RANGE_OPT_PARAM *param, SEL_ARG *new_parent, SEL_ARG **next);
 
420
 
 
421
  bool copy_min(SEL_ARG* arg)
 
422
  {                                             // Get overlapping range
 
423
    if (cmp_min_to_min(arg) > 0)
 
424
    {
 
425
      min_value=arg->min_value; min_flag=arg->min_flag;
 
426
      if ((max_flag & (NO_MAX_RANGE | NO_MIN_RANGE)) ==
 
427
          (NO_MAX_RANGE | NO_MIN_RANGE))
 
428
        return 1;                               // Full range
 
429
    }
 
430
    maybe_flag|=arg->maybe_flag;
 
431
    return 0;
 
432
  }
 
433
  bool copy_max(SEL_ARG* arg)
 
434
  {                                             // Get overlapping range
 
435
    if (cmp_max_to_max(arg) <= 0)
 
436
    {
 
437
      max_value=arg->max_value; max_flag=arg->max_flag;
 
438
      if ((max_flag & (NO_MAX_RANGE | NO_MIN_RANGE)) ==
 
439
          (NO_MAX_RANGE | NO_MIN_RANGE))
 
440
        return 1;                               // Full range
 
441
    }
 
442
    maybe_flag|=arg->maybe_flag;
 
443
    return 0;
 
444
  }
 
445
 
 
446
  void copy_min_to_min(SEL_ARG *arg)
 
447
  {
 
448
    min_value=arg->min_value; min_flag=arg->min_flag;
 
449
  }
 
450
  void copy_min_to_max(SEL_ARG *arg)
 
451
  {
 
452
    max_value=arg->min_value;
 
453
    max_flag=arg->min_flag & NEAR_MIN ? 0 : NEAR_MAX;
 
454
  }
 
455
  void copy_max_to_min(SEL_ARG *arg)
 
456
  {
 
457
    min_value=arg->max_value;
 
458
    min_flag=arg->max_flag & NEAR_MAX ? 0 : NEAR_MIN;
 
459
  }
 
460
  /* returns a number of keypart values (0 or 1) appended to the key buffer */
 
461
  int store_min(uint32_t length, unsigned char **min_key,uint32_t min_key_flag)
 
462
  {
 
463
    /* "(kp1 > c1) AND (kp2 OP c2) AND ..." -> (kp1 > c1) */
 
464
    if ((!(min_flag & NO_MIN_RANGE) &&
 
465
        !(min_key_flag & (NO_MIN_RANGE | NEAR_MIN))))
 
466
    {
 
467
      if (maybe_null && *min_value)
 
468
      {
 
469
        **min_key=1;
 
470
        memset(*min_key+1, 0, length-1);
 
471
      }
 
472
      else
 
473
        memcpy(*min_key,min_value,length);
 
474
      (*min_key)+= length;
 
475
      return 1;
 
476
    }
 
477
    return 0;
 
478
  }
 
479
  /* returns a number of keypart values (0 or 1) appended to the key buffer */
 
480
  int store_max(uint32_t length, unsigned char **max_key, uint32_t max_key_flag)
 
481
  {
 
482
    if (!(max_flag & NO_MAX_RANGE) &&
 
483
        !(max_key_flag & (NO_MAX_RANGE | NEAR_MAX)))
 
484
    {
 
485
      if (maybe_null && *max_value)
 
486
      {
 
487
        **max_key=1;
 
488
        memset(*max_key+1, 0, length-1);
 
489
      }
 
490
      else
 
491
        memcpy(*max_key,max_value,length);
 
492
      (*max_key)+= length;
 
493
      return 1;
 
494
    }
 
495
    return 0;
 
496
  }
 
497
 
 
498
  /* returns a number of keypart values appended to the key buffer */
 
499
  int store_min_key(KEY_PART *key, unsigned char **range_key, uint32_t *range_key_flag)
 
500
  {
 
501
    SEL_ARG *key_tree= first();
 
502
    uint32_t res= key_tree->store_min(key[key_tree->part].store_length,
 
503
                                  range_key, *range_key_flag);
 
504
    *range_key_flag|= key_tree->min_flag;
 
505
 
 
506
    if (key_tree->next_key_part &&
 
507
        key_tree->next_key_part->part == key_tree->part+1 &&
 
508
        !(*range_key_flag & (NO_MIN_RANGE | NEAR_MIN)) &&
 
509
        key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
 
510
      res+= key_tree->next_key_part->store_min_key(key, range_key,
 
511
                                                   range_key_flag);
 
512
    return res;
 
513
  }
 
514
 
 
515
  /* returns a number of keypart values appended to the key buffer */
 
516
  int store_max_key(KEY_PART *key, unsigned char **range_key, uint32_t *range_key_flag)
 
517
  {
 
518
    SEL_ARG *key_tree= last();
 
519
    uint32_t res=key_tree->store_max(key[key_tree->part].store_length,
 
520
                                 range_key, *range_key_flag);
 
521
    (*range_key_flag)|= key_tree->max_flag;
 
522
    if (key_tree->next_key_part &&
 
523
        key_tree->next_key_part->part == key_tree->part+1 &&
 
524
        !(*range_key_flag & (NO_MAX_RANGE | NEAR_MAX)) &&
 
525
        key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
 
526
      res+= key_tree->next_key_part->store_max_key(key, range_key,
 
527
                                                   range_key_flag);
 
528
    return res;
 
529
  }
 
530
 
 
531
  SEL_ARG *insert(SEL_ARG *key);
 
532
  SEL_ARG *tree_delete(SEL_ARG *key);
 
533
  SEL_ARG *find_range(SEL_ARG *key);
 
534
  SEL_ARG *rb_insert(SEL_ARG *leaf);
 
535
  friend SEL_ARG *rb_delete_fixup(SEL_ARG *root,SEL_ARG *key, SEL_ARG *par);
 
536
#ifdef EXTRA_DEBUG
 
537
  friend int test_rb_tree(SEL_ARG *element,SEL_ARG *parent);
 
538
  void test_use_count(SEL_ARG *root);
 
539
#endif
 
540
  SEL_ARG *first();
 
541
  SEL_ARG *last();
 
542
  void make_root();
 
543
  inline bool simple_key()
 
544
  {
 
545
    return !next_key_part && elements == 1;
 
546
  }
 
547
  void increment_use_count(long count)
 
548
  {
 
549
    if (next_key_part)
 
550
    {
 
551
      next_key_part->use_count+=count;
 
552
      count*= (next_key_part->use_count-count);
 
553
      for (SEL_ARG *pos=next_key_part->first(); pos ; pos=pos->next)
 
554
        if (pos->next_key_part)
 
555
          pos->increment_use_count(count);
 
556
    }
 
557
  }
 
558
  void free_tree()
 
559
  {
 
560
    for (SEL_ARG *pos=first(); pos ; pos=pos->next)
 
561
      if (pos->next_key_part)
 
562
      {
 
563
        pos->next_key_part->use_count--;
 
564
        pos->next_key_part->free_tree();
 
565
      }
 
566
  }
 
567
 
 
568
  inline SEL_ARG **parent_ptr()
 
569
  {
 
570
    return parent->left == this ? &parent->left : &parent->right;
 
571
  }
 
572
 
 
573
 
 
574
  /*
 
575
    Check if this SEL_ARG object represents a single-point interval
 
576
 
 
577
    SYNOPSIS
 
578
      is_singlepoint()
 
579
 
 
580
    DESCRIPTION
 
581
      Check if this SEL_ARG object (not tree) represents a single-point
 
582
      interval, i.e. if it represents a "keypart = const" or
 
583
      "keypart IS NULL".
 
584
 
 
585
    RETURN
 
586
      true   This SEL_ARG object represents a singlepoint interval
 
587
      false  Otherwise
 
588
  */
 
589
 
 
590
  bool is_singlepoint()
 
591
  {
 
592
    /*
 
593
      Check for NEAR_MIN ("strictly less") and NO_MIN_RANGE (-inf < field)
 
594
      flags, and the same for right edge.
 
595
    */
 
596
    if (min_flag || max_flag)
 
597
      return false;
 
598
    unsigned char *min_val= min_value;
 
599
    unsigned char *max_val= max_value;
 
600
 
 
601
    if (maybe_null)
 
602
    {
 
603
      /* First byte is a NULL value indicator */
 
604
      if (*min_val != *max_val)
 
605
        return false;
 
606
 
 
607
      if (*min_val)
 
608
        return true; /* This "x IS NULL" */
 
609
      min_val++;
 
610
      max_val++;
 
611
    }
 
612
    return !field->key_cmp(min_val, max_val);
 
613
  }
 
614
  SEL_ARG *clone_tree(RANGE_OPT_PARAM *param);
 
615
};
 
616
 
 
617
class SEL_IMERGE;
 
618
 
 
619
 
 
620
class SEL_TREE :public Sql_alloc
 
621
{
 
622
public:
 
623
  /*
 
624
    Starting an effort to document this field:
 
625
    (for some i, keys[i]->type == SEL_ARG::IMPOSSIBLE) =>
 
626
       (type == SEL_TREE::IMPOSSIBLE)
 
627
  */
 
628
  enum Type { IMPOSSIBLE, ALWAYS, MAYBE, KEY, KEY_SMALLER } type;
 
629
  SEL_TREE(enum Type type_arg) :type(type_arg) {}
 
630
  SEL_TREE() :type(KEY)
 
631
  {
 
632
    keys_map.reset();
 
633
    memset(keys, 0, sizeof(keys));
 
634
  }
 
635
  /*
 
636
    Note: there may exist SEL_TREE objects with sel_tree->type=KEY and
 
637
    keys[i]=0 for all i. (SergeyP: it is not clear whether there is any
 
638
    merit in range analyzer functions (e.g. get_mm_parts) returning a
 
639
    pointer to such SEL_TREE instead of NULL)
 
640
  */
 
641
  SEL_ARG *keys[MAX_KEY];
 
642
  key_map keys_map;        /* bitmask of non-NULL elements in keys */
 
643
 
 
644
  /*
 
645
    Possible ways to read rows using index_merge. The list is non-empty only
 
646
    if type==KEY. Currently can be non empty only if keys_map.none().
 
647
  */
 
648
  vector<SEL_IMERGE*> merges;
 
649
 
 
650
  /* The members below are filled/used only after get_mm_tree is done */
 
651
  key_map ror_scans_map;   /* bitmask of ROR scan-able elements in keys */
 
652
  uint32_t    n_ror_scans;     /* number of set bits in ror_scans_map */
 
653
 
 
654
  struct st_ror_scan_info **ror_scans;     /* list of ROR key scans */
 
655
  struct st_ror_scan_info **ror_scans_end; /* last ROR scan */
 
656
  /* Note that #records for each key scan is stored in table->quick_rows */
 
657
};
 
658
 
 
659
class RANGE_OPT_PARAM
 
660
{
 
661
public:
 
662
  Session       *session;   /* Current thread handle */
 
663
  Table *table; /* Table being analyzed */
 
664
  COND *cond;   /* Used inside get_mm_tree(). */
 
665
  table_map prev_tables;
 
666
  table_map read_tables;
 
667
  table_map current_table; /* Bit of the table being analyzed */
 
668
 
 
669
  /* Array of parts of all keys for which range analysis is performed */
 
670
  KEY_PART *key_parts;
 
671
  KEY_PART *key_parts_end;
 
672
  MEM_ROOT *mem_root; /* Memory that will be freed when range analysis completes */
 
673
  MEM_ROOT *old_root; /* Memory that will last until the query end */
 
674
  /*
 
675
    Number of indexes used in range analysis (In SEL_TREE::keys only first
 
676
    #keys elements are not empty)
 
677
  */
 
678
  uint32_t keys;
 
679
 
 
680
  /*
 
681
    If true, the index descriptions describe real indexes (and it is ok to
 
682
    call field->optimize_range(real_keynr[...], ...).
 
683
    Otherwise index description describes fake indexes.
 
684
  */
 
685
  bool using_real_indexes;
 
686
 
 
687
  bool remove_jump_scans;
 
688
 
 
689
  /*
 
690
    used_key_no -> table_key_no translation table. Only makes sense if
 
691
    using_real_indexes==true
 
692
  */
 
693
  uint32_t real_keynr[MAX_KEY];
 
694
  /* Number of SEL_ARG objects allocated by SEL_ARG::clone_tree operations */
 
695
  uint32_t alloced_sel_args;
 
696
  bool force_default_mrr;
 
697
};
 
698
 
 
699
class PARAM : public RANGE_OPT_PARAM
 
700
{
 
701
public:
 
702
  KEY_PART *key[MAX_KEY]; /* First key parts of keys used in the query */
 
703
  int64_t baseflag;
 
704
  uint32_t max_key_part;
 
705
  /* Number of ranges in the last checked tree->key */
 
706
  uint32_t range_count;
 
707
  unsigned char min_key[MAX_KEY_LENGTH+MAX_FIELD_WIDTH],
 
708
    max_key[MAX_KEY_LENGTH+MAX_FIELD_WIDTH];
 
709
  bool quick;                           // Don't calulate possible keys
 
710
 
 
711
  uint32_t fields_bitmap_size;
 
712
  MyBitmap needed_fields;    /* bitmask of fields needed by the query */
 
713
  MyBitmap tmp_covered_fields;
 
714
 
 
715
  key_map *needed_reg;        /* ptr to SQL_SELECT::needed_reg */
 
716
 
 
717
  uint32_t *imerge_cost_buff;     /* buffer for index_merge cost estimates */
 
718
  uint32_t imerge_cost_buff_size; /* size of the buffer */
 
719
 
 
720
  /* true if last checked tree->key can be used for ROR-scan */
 
721
  bool is_ror_scan;
 
722
  /* Number of ranges in the last checked tree->key */
 
723
  uint32_t n_ranges;
 
724
};
 
725
 
 
726
class TABLE_READ_PLAN;
 
727
  class TRP_RANGE;
 
728
  class TRP_ROR_INTERSECT;
 
729
  class TRP_ROR_UNION;
 
730
  class TRP_ROR_INDEX_MERGE;
 
731
  class TRP_GROUP_MIN_MAX;
232
732
 
233
733
struct st_ror_scan_info;
234
734
 
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,
 
735
static SEL_TREE * get_mm_parts(RANGE_OPT_PARAM *param,COND *cond_func,Field *field,
 
736
                               Item_func::Functype type,Item *value,
 
737
                               Item_result cmp_type);
 
738
static SEL_ARG *get_mm_leaf(RANGE_OPT_PARAM *param,COND *cond_func,Field *field,
 
739
                            KEY_PART *key_part,
 
740
                            Item_func::Functype type,Item *value);
 
741
static SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param,COND *cond);
 
742
 
 
743
static bool is_key_scan_ror(PARAM *param, uint32_t keynr, uint8_t nparts);
 
744
static ha_rows check_quick_select(PARAM *param, uint32_t idx, bool index_only,
 
745
                                  SEL_ARG *tree, bool update_tbl_stats,
 
746
                                  uint32_t *mrr_flags, uint32_t *bufsize,
 
747
                                  COST_VECT *cost);
 
748
                                  //bool update_tbl_stats);
 
749
/*static ha_rows check_quick_keys(PARAM *param,uint32_t index,SEL_ARG *key_tree,
 
750
                                unsigned char *min_key, uint32_t min_key_flag, int,
 
751
                                unsigned char *max_key, uint32_t max_key_flag, int);
 
752
*/
 
753
 
 
754
QUICK_RANGE_SELECT *get_quick_select(PARAM *param,uint32_t index,
 
755
                                     SEL_ARG *key_tree, uint32_t mrr_flags,
 
756
                                     uint32_t mrr_buf_size, MEM_ROOT *alloc);
 
757
static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
 
758
                                       bool index_read_must_be_used,
 
759
                                       bool update_tbl_stats,
 
760
                                       double read_time);
 
761
static
 
762
TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree,
 
763
                                          double read_time,
 
764
                                          bool *are_all_covering);
 
765
static
 
766
TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param,
 
767
                                                   SEL_TREE *tree,
 
768
                                                   double read_time);
 
769
static
 
770
TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
 
771
                                         double read_time);
 
772
static
 
773
TRP_GROUP_MIN_MAX *get_best_group_min_max(PARAM *param, SEL_TREE *tree);
 
774
 
 
775
static void print_sel_tree(PARAM *param, SEL_TREE *tree, key_map *tree_map,
 
776
                           const char *msg);
 
777
static void print_ror_scans_arr(Table *table, const char *msg,
 
778
                                struct st_ror_scan_info **start,
 
779
                                struct st_ror_scan_info **end);
 
780
 
 
781
static SEL_TREE *tree_and(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2);
 
782
static SEL_TREE *tree_or(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2);
 
783
static SEL_ARG *sel_add(SEL_ARG *key1,SEL_ARG *key2);
 
784
static SEL_ARG *key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2);
 
785
static SEL_ARG *key_and(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2,
 
786
                        uint32_t clone_flag);
 
787
static bool get_range(SEL_ARG **e1,SEL_ARG **e2,SEL_ARG *root1);
 
788
bool get_quick_keys(PARAM *param,QUICK_RANGE_SELECT *quick,KEY_PART *key,
 
789
                    SEL_ARG *key_tree, unsigned char *min_key,uint32_t min_key_flag,
 
790
                    unsigned char *max_key,uint32_t max_key_flag);
 
791
static bool eq_tree(SEL_ARG* a,SEL_ARG *b);
 
792
 
 
793
static SEL_ARG null_element(SEL_ARG::IMPOSSIBLE);
 
794
static bool null_part_in_key(KEY_PART *key_part, const unsigned char *key,
304
795
                             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);
 
796
bool sel_trees_can_be_ored(SEL_TREE *tree1, SEL_TREE *tree2, RANGE_OPT_PARAM* param);
 
797
 
 
798
 
 
799
/*
 
800
  SEL_IMERGE is a list of possible ways to do index merge, i.e. it is
 
801
  a condition in the following form:
 
802
   (t_1||t_2||...||t_N) && (next)
 
803
 
 
804
  where all t_i are SEL_TREEs, next is another SEL_IMERGE and no pair
 
805
  (t_i,t_j) contains SEL_ARGS for the same index.
 
806
 
 
807
  SEL_TREE contained in SEL_IMERGE always has merges=NULL.
 
808
 
 
809
  This class relies on memory manager to do the cleanup.
 
810
*/
 
811
 
 
812
class SEL_IMERGE : public Sql_alloc
 
813
{
 
814
  enum { PREALLOCED_TREES= 10};
 
815
public:
 
816
  SEL_TREE *trees_prealloced[PREALLOCED_TREES];
 
817
  SEL_TREE **trees;             /* trees used to do index_merge   */
 
818
  SEL_TREE **trees_next;        /* last of these trees            */
 
819
  SEL_TREE **trees_end;         /* end of allocated space         */
 
820
 
 
821
  SEL_ARG  ***best_keys;        /* best keys to read in SEL_TREEs */
 
822
 
 
823
  SEL_IMERGE() :
 
824
    trees(&trees_prealloced[0]),
 
825
    trees_next(trees),
 
826
    trees_end(trees + PREALLOCED_TREES)
 
827
  {}
 
828
  int or_sel_tree(RANGE_OPT_PARAM *param, SEL_TREE *tree);
 
829
  int or_sel_tree_with_checks(RANGE_OPT_PARAM *param, SEL_TREE *new_tree);
 
830
  int or_sel_imerge_with_checks(RANGE_OPT_PARAM *param, SEL_IMERGE* imerge);
 
831
};
 
832
 
 
833
 
 
834
/*
 
835
  Add SEL_TREE to this index_merge without any checks,
 
836
 
 
837
  NOTES
 
838
    This function implements the following:
 
839
      (x_1||...||x_N) || t = (x_1||...||x_N||t), where x_i, t are SEL_TREEs
 
840
 
 
841
  RETURN
 
842
     0 - OK
 
843
    -1 - Out of memory.
 
844
*/
 
845
 
 
846
int SEL_IMERGE::or_sel_tree(RANGE_OPT_PARAM *param, SEL_TREE *tree)
 
847
{
 
848
  if (trees_next == trees_end)
 
849
  {
 
850
    const int realloc_ratio= 2;         /* Double size for next round */
 
851
    uint32_t old_elements= (trees_end - trees);
 
852
    uint32_t old_size= sizeof(SEL_TREE**) * old_elements;
 
853
    uint32_t new_size= old_size * realloc_ratio;
 
854
    SEL_TREE **new_trees;
 
855
    if (!(new_trees= (SEL_TREE**)alloc_root(param->mem_root, new_size)))
 
856
      return -1;
 
857
    memcpy(new_trees, trees, old_size);
 
858
    trees=      new_trees;
 
859
    trees_next= trees + old_elements;
 
860
    trees_end=  trees + old_elements * realloc_ratio;
 
861
  }
 
862
  *(trees_next++)= tree;
 
863
  return 0;
 
864
}
 
865
 
 
866
 
 
867
/*
 
868
  Perform OR operation on this SEL_IMERGE and supplied SEL_TREE new_tree,
 
869
  combining new_tree with one of the trees in this SEL_IMERGE if they both
 
870
  have SEL_ARGs for the same key.
 
871
 
 
872
  SYNOPSIS
 
873
    or_sel_tree_with_checks()
 
874
      param    PARAM from SQL_SELECT::test_quick_select
 
875
      new_tree SEL_TREE with type KEY or KEY_SMALLER.
 
876
 
 
877
  NOTES
 
878
    This does the following:
 
879
    (t_1||...||t_k)||new_tree =
 
880
     either
 
881
       = (t_1||...||t_k||new_tree)
 
882
     or
 
883
       = (t_1||....||(t_j|| new_tree)||...||t_k),
 
884
 
 
885
     where t_i, y are SEL_TREEs.
 
886
    new_tree is combined with the first t_j it has a SEL_ARG on common
 
887
    key with. As a consequence of this, choice of keys to do index_merge
 
888
    read may depend on the order of conditions in WHERE part of the query.
 
889
 
 
890
  RETURN
 
891
    0  OK
 
892
    1  One of the trees was combined with new_tree to SEL_TREE::ALWAYS,
 
893
       and (*this) should be discarded.
 
894
   -1  An error occurred.
 
895
*/
 
896
 
 
897
int SEL_IMERGE::or_sel_tree_with_checks(RANGE_OPT_PARAM *param, SEL_TREE *new_tree)
 
898
{
 
899
  for (SEL_TREE** tree = trees;
 
900
       tree != trees_next;
 
901
       tree++)
 
902
  {
 
903
    if (sel_trees_can_be_ored(*tree, new_tree, param))
 
904
    {
 
905
      *tree = tree_or(param, *tree, new_tree);
 
906
      if (!*tree)
 
907
        return 1;
 
908
      if (((*tree)->type == SEL_TREE::MAYBE) ||
 
909
          ((*tree)->type == SEL_TREE::ALWAYS))
 
910
        return 1;
 
911
      /* SEL_TREE::IMPOSSIBLE is impossible here */
 
912
      return 0;
 
913
    }
 
914
  }
 
915
 
 
916
  /* New tree cannot be combined with any of existing trees. */
 
917
  return or_sel_tree(param, new_tree);
 
918
}
 
919
 
 
920
 
 
921
/*
 
922
  Perform OR operation on this index_merge and supplied index_merge list.
 
923
 
 
924
  RETURN
 
925
    0 - OK
 
926
    1 - One of conditions in result is always true and this SEL_IMERGE
 
927
        should be discarded.
 
928
   -1 - An error occurred
 
929
*/
 
930
 
 
931
int SEL_IMERGE::or_sel_imerge_with_checks(RANGE_OPT_PARAM *param, SEL_IMERGE* imerge)
 
932
{
 
933
  for (SEL_TREE** tree= imerge->trees;
 
934
       tree != imerge->trees_next;
 
935
       tree++)
 
936
  {
 
937
    if (or_sel_tree_with_checks(param, *tree))
 
938
      return 1;
 
939
  }
 
940
  return 0;
 
941
}
 
942
 
 
943
 
 
944
/*
 
945
  Perform AND operation on two index_merge lists and store result in im1.
 
946
*/
 
947
 
 
948
inline void imerge_list_and_list(vector<SEL_IMERGE*> &im1, vector<SEL_IMERGE*> &im2)
 
949
{
 
950
  im1.insert(im1.end(), im2.begin(), im2.end());
 
951
  im2.clear();
 
952
}
 
953
 
 
954
 
 
955
/*
 
956
  Perform OR operation on 2 index_merge lists, storing result in first list.
 
957
 
 
958
  NOTES
 
959
    The following conversion is implemented:
 
960
     (a_1 &&...&& a_N)||(b_1 &&...&& b_K) = AND_i,j(a_i || b_j) =>
 
961
      => (a_1||b_1).
 
962
 
 
963
    i.e. all conjuncts except the first one are currently dropped.
 
964
    This is done to avoid producing N*K ways to do index_merge.
 
965
 
 
966
    If (a_1||b_1) produce a condition that is always true, NULL is returned
 
967
    and index_merge is discarded (while it is actually possible to try
 
968
    harder).
 
969
 
 
970
    As a consequence of this, choice of keys to do index_merge read may depend
 
971
    on the order of conditions in WHERE part of the query.
 
972
 
 
973
  RETURN
 
974
    0     OK, result is stored in *im1
 
975
    other Error, both passed lists are unusable
 
976
*/
 
977
 
 
978
static int imerge_list_or_list(RANGE_OPT_PARAM *param,
 
979
                               vector<SEL_IMERGE*> &im1,
 
980
                               vector<SEL_IMERGE*> &im2)
 
981
{
 
982
  SEL_IMERGE *imerge= im1.front();
 
983
  im1.clear();
 
984
  im1.push_back(imerge);
 
985
 
 
986
  return imerge->or_sel_imerge_with_checks(param, im2.front());
 
987
}
 
988
 
 
989
 
 
990
/*
 
991
  Perform OR operation on index_merge list and key tree.
 
992
 
 
993
  RETURN
 
994
    false   OK, result is stored in im1.
 
995
    true    Error
 
996
*/
 
997
 
 
998
static bool imerge_list_or_tree(RANGE_OPT_PARAM *param,
 
999
                                vector<SEL_IMERGE*> &im1,
 
1000
                                SEL_TREE *tree)
 
1001
{
 
1002
  vector<SEL_IMERGE*>::iterator imerge= im1.begin();
 
1003
 
 
1004
  while (imerge != im1.end())
 
1005
  {
 
1006
    if ((*imerge)->or_sel_tree_with_checks(param, tree))
 
1007
      imerge= im1.erase( imerge );
 
1008
    else
 
1009
      ++imerge;
 
1010
  }
 
1011
 
 
1012
  return im1.empty();
322
1013
}
323
1014
 
324
1015
 
325
1016
/***************************************************************************
326
 
** Basic functions for SqlSelect and QuickRangeSelect
 
1017
** Basic functions for SQL_SELECT and QUICK_RANGE_SELECT
327
1018
***************************************************************************/
328
1019
 
329
1020
        /* make a select from mysql info
332
1023
           1 = Got some error (out of memory?)
333
1024
           */
334
1025
 
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)
 
1026
SQL_SELECT *make_select(Table *head, table_map const_tables,
 
1027
                        table_map read_tables, COND *conds,
 
1028
                        bool allow_null_cond,
 
1029
                        int *error)
341
1030
{
342
 
  optimizer::SqlSelect *select= NULL;
343
 
 
344
 
  *error= 0;
345
 
 
346
 
  if (! conds && ! allow_null_cond)
347
 
  {
 
1031
  SQL_SELECT *select;
 
1032
 
 
1033
  *error=0;
 
1034
 
 
1035
  if (!conds && !allow_null_cond)
348
1036
    return 0;
349
 
  }
350
 
  if (! (select= new optimizer::SqlSelect))
 
1037
  if (!(select= new SQL_SELECT))
351
1038
  {
352
1039
    *error= 1;                  // out of memory
353
 
    return 0;
 
1040
    return 0;           /* purecov: inspected */
354
1041
  }
355
1042
  select->read_tables=read_tables;
356
1043
  select->const_tables=const_tables;
359
1046
 
360
1047
  if (head->sort.io_cache)
361
1048
  {
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);
 
1049
    select->file= *head->sort.io_cache;
 
1050
    select->records=(ha_rows) (select->file.end_of_file/
 
1051
                               head->file->ref_length);
365
1052
    delete head->sort.io_cache;
366
1053
    head->sort.io_cache=0;
367
1054
  }
369
1056
}
370
1057
 
371
1058
 
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)
 
1059
SQL_SELECT::SQL_SELECT() :quick(0),cond(0),free_cond(0)
378
1060
{
379
 
  quick_keys.reset();
 
1061
  quick_keys.reset(); 
380
1062
  needed_reg.reset();
381
 
  my_b_clear(file);
 
1063
  my_b_clear(&file);
382
1064
}
383
1065
 
384
1066
 
385
 
void optimizer::SqlSelect::cleanup()
 
1067
void SQL_SELECT::cleanup()
386
1068
{
387
1069
  delete quick;
388
1070
  quick= 0;
389
1071
  if (free_cond)
390
1072
  {
391
 
    free_cond= 0;
 
1073
    free_cond=0;
392
1074
    delete cond;
393
1075
    cond= 0;
394
1076
  }
395
 
  close_cached_file(file);
 
1077
  close_cached_file(&file);
396
1078
}
397
1079
 
398
1080
 
399
 
optimizer::SqlSelect::~SqlSelect()
 
1081
SQL_SELECT::~SQL_SELECT()
400
1082
{
401
1083
  cleanup();
402
1084
}
403
1085
 
404
1086
 
405
 
bool optimizer::SqlSelect::check_quick(Session *session, 
406
 
                                       bool force_quick_range,
407
 
                                       ha_rows limit)
 
1087
bool SQL_SELECT::check_quick(Session *session, bool force_quick_range,
 
1088
                             ha_rows limit)
408
1089
{
409
1090
  key_map tmp;
410
1091
  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
 
{}
 
1092
  return test_quick_select(session, tmp, 0, limit,
 
1093
                           force_quick_range, false) < 0;
 
1094
}
 
1095
 
 
1096
 
 
1097
bool SQL_SELECT::skip_record()
 
1098
{
 
1099
  return cond ? cond->val_int() == 0 : 0;
 
1100
}
 
1101
 
 
1102
 
 
1103
QUICK_SELECT_I::QUICK_SELECT_I()
 
1104
  :max_used_key_length(0),
 
1105
   used_key_parts(0)
 
1106
{}
 
1107
 
 
1108
QUICK_RANGE_SELECT::QUICK_RANGE_SELECT(Session *session, Table *table, uint32_t key_nr,
 
1109
                                       bool no_alloc, MEM_ROOT *parent_alloc,
 
1110
                                       bool *create_error)
 
1111
  :free_file(0),cur_range(NULL),last_range(0),dont_free(0)
 
1112
{
 
1113
  my_bitmap_map *bitmap;
 
1114
 
 
1115
  in_ror_merged_scan= 0;
 
1116
  sorted= 0;
 
1117
  index= key_nr;
 
1118
  head=  table;
 
1119
  key_part_info= head->key_info[index].key_part;
 
1120
  my_init_dynamic_array(&ranges, sizeof(QUICK_RANGE*), 16, 16);
 
1121
 
 
1122
  /* 'session' is not accessible in QUICK_RANGE_SELECT::reset(). */
 
1123
  mrr_buf_size= session->variables.read_rnd_buff_size;
 
1124
  mrr_buf_desc= NULL;
 
1125
 
 
1126
  if (!no_alloc && !parent_alloc)
 
1127
  {
 
1128
    // Allocates everything through the internal memroot
 
1129
    init_sql_alloc(&alloc, session->variables.range_alloc_block_size, 0);
 
1130
    session->mem_root= &alloc;
 
1131
  }
 
1132
  else
 
1133
    memset(&alloc, 0, sizeof(alloc));
 
1134
  file= head->file;
 
1135
  record= head->record[0];
 
1136
  save_read_set= head->read_set;
 
1137
  save_write_set= head->write_set;
 
1138
 
 
1139
  /* Allocate a bitmap for used columns (Q: why not on MEM_ROOT?) */
 
1140
  if (! (bitmap= (my_bitmap_map*) malloc(head->s->column_bitmap_size)))
 
1141
  {
 
1142
    column_bitmap.setBitmap(NULL);
 
1143
    *create_error= 1;
 
1144
  }
 
1145
  else
 
1146
  {
 
1147
    column_bitmap.init(bitmap, head->s->fields);
 
1148
  }
 
1149
}
 
1150
 
 
1151
 
 
1152
int QUICK_RANGE_SELECT::init()
 
1153
{
 
1154
  if (file->inited != handler::NONE)
 
1155
    file->ha_index_or_rnd_end();
 
1156
  return(file->ha_index_init(index, 1));
 
1157
}
 
1158
 
 
1159
 
 
1160
void QUICK_RANGE_SELECT::range_end()
 
1161
{
 
1162
  if (file->inited != handler::NONE)
 
1163
    file->ha_index_or_rnd_end();
 
1164
}
 
1165
 
 
1166
 
 
1167
QUICK_RANGE_SELECT::~QUICK_RANGE_SELECT()
 
1168
{
 
1169
  if (!dont_free)
 
1170
  {
 
1171
    /* file is NULL for CPK scan on covering ROR-intersection */
 
1172
    if (file)
 
1173
    {
 
1174
      range_end();
 
1175
      if (head->key_read)
 
1176
      {
 
1177
        head->key_read= 0;
 
1178
        file->extra(HA_EXTRA_NO_KEYREAD);
 
1179
      }
 
1180
      if (free_file)
 
1181
      {
 
1182
        file->ha_external_lock(current_session, F_UNLCK);
 
1183
        file->close();
 
1184
        delete file;
 
1185
      }
 
1186
    }
 
1187
    delete_dynamic(&ranges); /* ranges are allocated in alloc */
 
1188
    free_root(&alloc,MYF(0));
 
1189
  }
 
1190
  head->column_bitmaps_set(save_read_set, save_write_set);
 
1191
  assert(mrr_buf_desc == NULL);
 
1192
  if (mrr_buf_desc)
 
1193
    free(mrr_buf_desc);
 
1194
}
 
1195
 
 
1196
 
 
1197
QUICK_INDEX_MERGE_SELECT::QUICK_INDEX_MERGE_SELECT(Session *session_param,
 
1198
                                                   Table *table)
 
1199
  :pk_quick_select(NULL), session(session_param)
 
1200
{
 
1201
  index= MAX_KEY;
 
1202
  head= table;
 
1203
  memset(&read_record, 0, sizeof(read_record));
 
1204
  init_sql_alloc(&alloc, session->variables.range_alloc_block_size, 0);
 
1205
  return;
 
1206
}
 
1207
 
 
1208
int QUICK_INDEX_MERGE_SELECT::init()
 
1209
{
 
1210
  return 0;
 
1211
}
 
1212
 
 
1213
int QUICK_INDEX_MERGE_SELECT::reset()
 
1214
{
 
1215
  return(read_keys_and_merge());
 
1216
}
 
1217
 
 
1218
bool
 
1219
QUICK_INDEX_MERGE_SELECT::push_quick_back(QUICK_RANGE_SELECT *quick_sel_range)
 
1220
{
 
1221
  /*
 
1222
    Save quick_select that does scan on clustered primary key as it will be
 
1223
    processed separately.
 
1224
  */
 
1225
  if (head->file->primary_key_is_clustered() &&
 
1226
      quick_sel_range->index == head->s->primary_key)
 
1227
    pk_quick_select= quick_sel_range;
 
1228
  else
 
1229
    return quick_selects.push_back(quick_sel_range);
 
1230
  return 0;
 
1231
}
 
1232
 
 
1233
QUICK_INDEX_MERGE_SELECT::~QUICK_INDEX_MERGE_SELECT()
 
1234
{
 
1235
  List_iterator_fast<QUICK_RANGE_SELECT> quick_it(quick_selects);
 
1236
  QUICK_RANGE_SELECT* quick;
 
1237
  quick_it.rewind();
 
1238
  while ((quick= quick_it++))
 
1239
    quick->file= NULL;
 
1240
  quick_selects.delete_elements();
 
1241
  delete pk_quick_select;
 
1242
  free_root(&alloc,MYF(0));
 
1243
  return;
 
1244
}
 
1245
 
 
1246
 
 
1247
QUICK_ROR_INTERSECT_SELECT::QUICK_ROR_INTERSECT_SELECT(Session *session_param,
 
1248
                                                       Table *table,
 
1249
                                                       bool retrieve_full_rows,
 
1250
                                                       MEM_ROOT *parent_alloc)
 
1251
  : cpk_quick(NULL), session(session_param), need_to_fetch_row(retrieve_full_rows),
 
1252
    scans_inited(false)
 
1253
{
 
1254
  index= MAX_KEY;
 
1255
  head= table;
 
1256
  record= head->record[0];
 
1257
  if (!parent_alloc)
 
1258
    init_sql_alloc(&alloc, session->variables.range_alloc_block_size, 0);
 
1259
  else
 
1260
    memset(&alloc, 0, sizeof(MEM_ROOT));
 
1261
  last_rowid= (unsigned char*) alloc_root(parent_alloc? parent_alloc : &alloc,
 
1262
                                  head->file->ref_length);
 
1263
}
 
1264
 
 
1265
 
 
1266
/*
 
1267
  Do post-constructor initialization.
 
1268
  SYNOPSIS
 
1269
    QUICK_ROR_INTERSECT_SELECT::init()
 
1270
 
 
1271
  RETURN
 
1272
    0      OK
 
1273
    other  Error code
 
1274
*/
 
1275
 
 
1276
int QUICK_ROR_INTERSECT_SELECT::init()
 
1277
{
 
1278
 /* Check if last_rowid was successfully allocated in ctor */
 
1279
  return(!last_rowid);
 
1280
}
 
1281
 
 
1282
 
 
1283
/*
 
1284
  Initialize this quick select to be a ROR-merged scan.
 
1285
 
 
1286
  SYNOPSIS
 
1287
    QUICK_RANGE_SELECT::init_ror_merged_scan()
 
1288
      reuse_handler If true, use head->file, otherwise create a separate
 
1289
                    handler object
 
1290
 
 
1291
  NOTES
 
1292
    This function creates and prepares for subsequent use a separate handler
 
1293
    object if it can't reuse head->file. The reason for this is that during
 
1294
    ROR-merge several key scans are performed simultaneously, and a single
 
1295
    handler is only capable of preserving context of a single key scan.
 
1296
 
 
1297
    In ROR-merge the quick select doing merge does full records retrieval,
 
1298
    merged quick selects read only keys.
 
1299
 
 
1300
  RETURN
 
1301
    0  ROR child scan initialized, ok to use.
 
1302
    1  error
 
1303
*/
 
1304
 
 
1305
int QUICK_RANGE_SELECT::init_ror_merged_scan(bool reuse_handler)
 
1306
{
 
1307
  handler *save_file= file, *org_file;
 
1308
  Session *session;
 
1309
 
 
1310
  in_ror_merged_scan= 1;
 
1311
  if (reuse_handler)
 
1312
  {
 
1313
    if (init() || reset())
 
1314
    {
 
1315
      return 0;
 
1316
    }
 
1317
    head->column_bitmaps_set(&column_bitmap, &column_bitmap);
 
1318
    goto end;
 
1319
  }
 
1320
 
 
1321
  /* Create a separate handler object for this quick select */
 
1322
  if (free_file)
 
1323
  {
 
1324
    /* already have own 'handler' object. */
 
1325
    return 0;
 
1326
  }
 
1327
 
 
1328
  session= head->in_use;
 
1329
  if (!(file= head->file->clone(session->mem_root)))
 
1330
  {
 
1331
    /*
 
1332
      Manually set the error flag. Note: there seems to be quite a few
 
1333
      places where a failure could cause the server to "hang" the client by
 
1334
      sending no response to a query. ATM those are not real errors because
 
1335
      the storage engine calls in question happen to never fail with the
 
1336
      existing storage engines.
 
1337
    */
 
1338
    my_error(ER_OUT_OF_RESOURCES, MYF(0)); /* purecov: inspected */
 
1339
    /* Caller will free the memory */
 
1340
    goto failure;  /* purecov: inspected */
 
1341
  }
 
1342
 
 
1343
  head->column_bitmaps_set(&column_bitmap, &column_bitmap);
 
1344
 
 
1345
  if (file->ha_external_lock(session, F_RDLCK))
 
1346
    goto failure;
 
1347
 
 
1348
  if (init() || reset())
 
1349
  {
 
1350
    file->ha_external_lock(session, F_UNLCK);
 
1351
    file->close();
 
1352
    goto failure;
 
1353
  }
 
1354
  free_file= true;
 
1355
  last_rowid= file->ref;
 
1356
 
 
1357
end:
 
1358
  /*
 
1359
    We are only going to read key fields and call position() on 'file'
 
1360
    The following sets head->tmp_set to only use this key and then updates
 
1361
    head->read_set and head->write_set to use this bitmap.
 
1362
    The now bitmap is stored in 'column_bitmap' which is used in ::get_next()
 
1363
  */
 
1364
  org_file= head->file;
 
1365
  head->file= file;
 
1366
  /* We don't have to set 'head->keyread' here as the 'file' is unique */
 
1367
  if (!head->no_keyread)
 
1368
  {
 
1369
    head->key_read= 1;
 
1370
    head->mark_columns_used_by_index(index);
 
1371
  }
 
1372
  head->prepare_for_position();
 
1373
  head->file= org_file;
 
1374
  column_bitmap= *head->read_set;
 
1375
  head->column_bitmaps_set(&column_bitmap, &column_bitmap);
 
1376
 
 
1377
  return 0;
 
1378
 
 
1379
failure:
 
1380
  head->column_bitmaps_set(save_read_set, save_write_set);
 
1381
  delete file;
 
1382
  file= save_file;
 
1383
  return 0;
 
1384
}
 
1385
 
 
1386
 
 
1387
void QUICK_RANGE_SELECT::save_last_pos()
 
1388
{
 
1389
  file->position(record);
 
1390
}
 
1391
 
 
1392
 
 
1393
/*
 
1394
  Initialize this quick select to be a part of a ROR-merged scan.
 
1395
  SYNOPSIS
 
1396
    QUICK_ROR_INTERSECT_SELECT::init_ror_merged_scan()
 
1397
      reuse_handler If true, use head->file, otherwise create separate
 
1398
                    handler object.
 
1399
  RETURN
 
1400
    0     OK
 
1401
    other error code
 
1402
*/
 
1403
int QUICK_ROR_INTERSECT_SELECT::init_ror_merged_scan(bool reuse_handler)
 
1404
{
 
1405
  List_iterator_fast<QUICK_RANGE_SELECT> quick_it(quick_selects);
 
1406
  QUICK_RANGE_SELECT* quick;
 
1407
 
 
1408
  /* Initialize all merged "children" quick selects */
 
1409
  assert(!need_to_fetch_row || reuse_handler);
 
1410
  if (!need_to_fetch_row && reuse_handler)
 
1411
  {
 
1412
    quick= quick_it++;
 
1413
    /*
 
1414
      There is no use of this->file. Use it for the first of merged range
 
1415
      selects.
 
1416
    */
 
1417
    if (quick->init_ror_merged_scan(true))
 
1418
      return 0;
 
1419
    quick->file->extra(HA_EXTRA_KEYREAD_PRESERVE_FIELDS);
 
1420
  }
 
1421
  while ((quick= quick_it++))
 
1422
  {
 
1423
    if (quick->init_ror_merged_scan(false))
 
1424
      return 0;
 
1425
    quick->file->extra(HA_EXTRA_KEYREAD_PRESERVE_FIELDS);
 
1426
    /* All merged scans share the same record buffer in intersection. */
 
1427
    quick->record= head->record[0];
 
1428
  }
 
1429
 
 
1430
  if (need_to_fetch_row && head->file->ha_rnd_init(1))
 
1431
  {
 
1432
    return 0;
 
1433
  }
 
1434
  return 0;
 
1435
}
 
1436
 
 
1437
 
 
1438
/*
 
1439
  Initialize quick select for row retrieval.
 
1440
  SYNOPSIS
 
1441
    reset()
 
1442
  RETURN
 
1443
    0      OK
 
1444
    other  Error code
 
1445
*/
 
1446
 
 
1447
int QUICK_ROR_INTERSECT_SELECT::reset()
 
1448
{
 
1449
  if (!scans_inited && init_ror_merged_scan(true))
 
1450
    return 0;
 
1451
  scans_inited= true;
 
1452
  List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
 
1453
  QUICK_RANGE_SELECT *quick;
 
1454
  while ((quick= it++))
 
1455
    quick->reset();
 
1456
  return 0;
 
1457
}
 
1458
 
 
1459
 
 
1460
/*
 
1461
  Add a merged quick select to this ROR-intersection quick select.
 
1462
 
 
1463
  SYNOPSIS
 
1464
    QUICK_ROR_INTERSECT_SELECT::push_quick_back()
 
1465
      quick Quick select to be added. The quick select must return
 
1466
            rows in rowid order.
 
1467
  NOTES
 
1468
    This call can only be made before init() is called.
 
1469
 
 
1470
  RETURN
 
1471
    false OK
 
1472
    true  Out of memory.
 
1473
*/
 
1474
 
 
1475
bool
 
1476
QUICK_ROR_INTERSECT_SELECT::push_quick_back(QUICK_RANGE_SELECT *quick)
 
1477
{
 
1478
  return quick_selects.push_back(quick);
 
1479
}
 
1480
 
 
1481
QUICK_ROR_INTERSECT_SELECT::~QUICK_ROR_INTERSECT_SELECT()
 
1482
{
 
1483
  quick_selects.delete_elements();
 
1484
  delete cpk_quick;
 
1485
  free_root(&alloc,MYF(0));
 
1486
  if (need_to_fetch_row && head->file->inited != handler::NONE)
 
1487
    head->file->ha_rnd_end();
 
1488
  return;
 
1489
}
 
1490
 
 
1491
 
 
1492
QUICK_ROR_UNION_SELECT::QUICK_ROR_UNION_SELECT(Session *session_param,
 
1493
                                               Table *table)
 
1494
  : session(session_param), scans_inited(false)
 
1495
{
 
1496
  index= MAX_KEY;
 
1497
  head= table;
 
1498
  rowid_length= table->file->ref_length;
 
1499
  record= head->record[0];
 
1500
  init_sql_alloc(&alloc, session->variables.range_alloc_block_size, 0);
 
1501
  session_param->mem_root= &alloc;
 
1502
}
 
1503
 
 
1504
/*
 
1505
 * Function object that is used as the comparison function
 
1506
 * for the priority queue in the QUICK_ROR_UNION_SELECT
 
1507
 * class.
 
1508
 */
 
1509
class compare_functor
 
1510
{
 
1511
  QUICK_ROR_UNION_SELECT *self;
 
1512
  public:
 
1513
  compare_functor(QUICK_ROR_UNION_SELECT *in_arg)
 
1514
    : self(in_arg) { }
 
1515
  inline bool operator()(const QUICK_SELECT_I *i, const QUICK_SELECT_I *j) const
 
1516
  {
 
1517
    int val= self->head->file->cmp_ref(i->last_rowid,
 
1518
                                       j->last_rowid);
 
1519
    return (val >= 0);
 
1520
  }
 
1521
};
 
1522
 
 
1523
/*
 
1524
  Do post-constructor initialization.
 
1525
  SYNOPSIS
 
1526
    QUICK_ROR_UNION_SELECT::init()
 
1527
 
 
1528
  RETURN
 
1529
    0      OK
 
1530
    other  Error code
 
1531
*/
 
1532
 
 
1533
int QUICK_ROR_UNION_SELECT::init()
 
1534
{
 
1535
  queue= 
 
1536
    new priority_queue<QUICK_SELECT_I *, vector<QUICK_SELECT_I *>, compare_functor >(compare_functor(this));
 
1537
  if (!(cur_rowid= (unsigned char*) alloc_root(&alloc, 2*head->file->ref_length)))
 
1538
    return 0;
 
1539
  prev_rowid= cur_rowid + head->file->ref_length;
 
1540
  return 0;
 
1541
}
 
1542
 
 
1543
 
 
1544
/*
 
1545
  Initialize quick select for row retrieval.
 
1546
  SYNOPSIS
 
1547
    reset()
 
1548
 
 
1549
  RETURN
 
1550
    0      OK
 
1551
    other  Error code
 
1552
*/
 
1553
 
 
1554
int QUICK_ROR_UNION_SELECT::reset()
 
1555
{
 
1556
  QUICK_SELECT_I *quick;
 
1557
  int error;
 
1558
  have_prev_rowid= false;
 
1559
  if (!scans_inited)
 
1560
  {
 
1561
    List_iterator_fast<QUICK_SELECT_I> it(quick_selects);
 
1562
    while ((quick= it++))
 
1563
    {
 
1564
      if (quick->init_ror_merged_scan(false))
 
1565
        return 0;
 
1566
    }
 
1567
    scans_inited= true;
 
1568
  }
 
1569
  while (!queue->empty())
 
1570
    queue->pop();
 
1571
  /*
 
1572
    Initialize scans for merged quick selects and put all merged quick
 
1573
    selects into the queue.
 
1574
  */
 
1575
  List_iterator_fast<QUICK_SELECT_I> it(quick_selects);
 
1576
  while ((quick= it++))
 
1577
  {
 
1578
    if (quick->reset())
 
1579
      return 0;
 
1580
    if ((error= quick->get_next()))
 
1581
    {
 
1582
      if (error == HA_ERR_END_OF_FILE)
 
1583
        continue;
 
1584
      return(error);
 
1585
    }
 
1586
    quick->save_last_pos();
 
1587
    queue->push(quick);
 
1588
  }
 
1589
 
 
1590
  if (head->file->ha_rnd_init(1))
 
1591
  {
 
1592
    return 0;
 
1593
  }
 
1594
 
 
1595
  return 0;
 
1596
}
 
1597
 
 
1598
 
 
1599
bool
 
1600
QUICK_ROR_UNION_SELECT::push_quick_back(QUICK_SELECT_I *quick_sel_range)
 
1601
{
 
1602
  return quick_selects.push_back(quick_sel_range);
 
1603
}
 
1604
 
 
1605
QUICK_ROR_UNION_SELECT::~QUICK_ROR_UNION_SELECT()
 
1606
{
 
1607
  while (!queue->empty())
 
1608
    queue->pop();
 
1609
  delete queue;
 
1610
  quick_selects.delete_elements();
 
1611
  if (head->file->inited != handler::NONE)
 
1612
    head->file->ha_rnd_end();
 
1613
  free_root(&alloc,MYF(0));
 
1614
  return;
 
1615
}
 
1616
 
 
1617
 
 
1618
QUICK_RANGE::QUICK_RANGE()
 
1619
  :min_key(0),max_key(0),min_length(0),max_length(0),
 
1620
   flag(NO_MIN_RANGE | NO_MAX_RANGE),
 
1621
  min_keypart_map(0), max_keypart_map(0)
 
1622
{}
 
1623
 
 
1624
SEL_ARG::SEL_ARG(SEL_ARG &arg) :Sql_alloc()
 
1625
{
 
1626
  type=arg.type;
 
1627
  min_flag=arg.min_flag;
 
1628
  max_flag=arg.max_flag;
 
1629
  maybe_flag=arg.maybe_flag;
 
1630
  maybe_null=arg.maybe_null;
 
1631
  part=arg.part;
 
1632
  field=arg.field;
 
1633
  min_value=arg.min_value;
 
1634
  max_value=arg.max_value;
 
1635
  next_key_part=arg.next_key_part;
 
1636
  use_count=1; elements=1;
 
1637
}
 
1638
 
 
1639
 
 
1640
inline void SEL_ARG::make_root()
 
1641
{
 
1642
  left=right= &null_element;
 
1643
  color=BLACK;
 
1644
  next=prev=0;
 
1645
  use_count=0; elements=1;
 
1646
}
 
1647
 
 
1648
SEL_ARG::SEL_ARG(Field *f,const unsigned char *min_value_arg,
 
1649
                 const unsigned char *max_value_arg)
 
1650
  :min_flag(0), max_flag(0), maybe_flag(0), maybe_null(f->real_maybe_null()),
 
1651
   elements(1), use_count(1), field(f), min_value((unsigned char*) min_value_arg),
 
1652
   max_value((unsigned char*) max_value_arg), next(0),prev(0),
 
1653
   next_key_part(0),color(BLACK),type(KEY_RANGE)
 
1654
{
 
1655
  left=right= &null_element;
 
1656
}
 
1657
 
 
1658
SEL_ARG::SEL_ARG(Field *field_,uint8_t part_,
 
1659
                 unsigned char *min_value_, unsigned char *max_value_,
 
1660
                 uint8_t min_flag_,uint8_t max_flag_,uint8_t maybe_flag_)
 
1661
  :min_flag(min_flag_),max_flag(max_flag_),maybe_flag(maybe_flag_),
 
1662
   part(part_),maybe_null(field_->real_maybe_null()), elements(1),use_count(1),
 
1663
   field(field_), min_value(min_value_), max_value(max_value_),
 
1664
   next(0),prev(0),next_key_part(0),color(BLACK),type(KEY_RANGE)
 
1665
{
 
1666
  left=right= &null_element;
 
1667
}
 
1668
 
 
1669
SEL_ARG *SEL_ARG::clone(RANGE_OPT_PARAM *param, SEL_ARG *new_parent,
 
1670
                        SEL_ARG **next_arg)
 
1671
{
 
1672
  SEL_ARG *tmp;
 
1673
 
 
1674
  /* Bail out if we have already generated too many SEL_ARGs */
 
1675
  if (++param->alloced_sel_args > MAX_SEL_ARGS)
 
1676
    return 0;
 
1677
 
 
1678
  if (type != KEY_RANGE)
 
1679
  {
 
1680
    if (!(tmp= new (param->mem_root) SEL_ARG(type)))
 
1681
      return 0;                                 // out of memory
 
1682
    tmp->prev= *next_arg;                       // Link into next/prev chain
 
1683
    (*next_arg)->next=tmp;
 
1684
    (*next_arg)= tmp;
 
1685
  }
 
1686
  else
 
1687
  {
 
1688
    if (!(tmp= new (param->mem_root) SEL_ARG(field,part, min_value,max_value,
 
1689
                                             min_flag, max_flag, maybe_flag)))
 
1690
      return 0;                                 // OOM
 
1691
    tmp->parent=new_parent;
 
1692
    tmp->next_key_part=next_key_part;
 
1693
    if (left != &null_element)
 
1694
      if (!(tmp->left=left->clone(param, tmp, next_arg)))
 
1695
        return 0;                               // OOM
 
1696
 
 
1697
    tmp->prev= *next_arg;                       // Link into next/prev chain
 
1698
    (*next_arg)->next=tmp;
 
1699
    (*next_arg)= tmp;
 
1700
 
 
1701
    if (right != &null_element)
 
1702
      if (!(tmp->right= right->clone(param, tmp, next_arg)))
 
1703
        return 0;                               // OOM
 
1704
  }
 
1705
  increment_use_count(1);
 
1706
  tmp->color= color;
 
1707
  tmp->elements= this->elements;
 
1708
  return tmp;
 
1709
}
 
1710
 
 
1711
SEL_ARG *SEL_ARG::first()
 
1712
{
 
1713
  SEL_ARG *next_arg=this;
 
1714
  if (!next_arg->left)
 
1715
    return 0;                                   // MAYBE_KEY
 
1716
  while (next_arg->left != &null_element)
 
1717
    next_arg=next_arg->left;
 
1718
  return next_arg;
 
1719
}
 
1720
 
 
1721
SEL_ARG *SEL_ARG::last()
 
1722
{
 
1723
  SEL_ARG *next_arg=this;
 
1724
  if (!next_arg->right)
 
1725
    return 0;                                   // MAYBE_KEY
 
1726
  while (next_arg->right != &null_element)
 
1727
    next_arg=next_arg->right;
 
1728
  return next_arg;
 
1729
}
 
1730
 
 
1731
 
 
1732
/*
 
1733
  Check if a compare is ok, when one takes ranges in account
 
1734
  Returns -2 or 2 if the ranges where 'joined' like  < 2 and >= 2
 
1735
*/
 
1736
 
 
1737
static int sel_cmp(Field *field, unsigned char *a, unsigned char *b, uint8_t a_flag,
 
1738
                   uint8_t b_flag)
 
1739
{
 
1740
  int cmp;
 
1741
  /* First check if there was a compare to a min or max element */
 
1742
  if (a_flag & (NO_MIN_RANGE | NO_MAX_RANGE))
 
1743
  {
 
1744
    if ((a_flag & (NO_MIN_RANGE | NO_MAX_RANGE)) ==
 
1745
        (b_flag & (NO_MIN_RANGE | NO_MAX_RANGE)))
 
1746
      return 0;
 
1747
    return (a_flag & NO_MIN_RANGE) ? -1 : 1;
 
1748
  }
 
1749
  if (b_flag & (NO_MIN_RANGE | NO_MAX_RANGE))
 
1750
    return (b_flag & NO_MIN_RANGE) ? 1 : -1;
 
1751
 
 
1752
  if (field->real_maybe_null())                 // If null is part of key
 
1753
  {
 
1754
    if (*a != *b)
 
1755
    {
 
1756
      return *a ? -1 : 1;
 
1757
    }
 
1758
    if (*a)
 
1759
      goto end;                                 // NULL where equal
 
1760
    a++; b++;                                   // Skip NULL marker
 
1761
  }
 
1762
  cmp=field->key_cmp(a , b);
 
1763
  if (cmp) return cmp < 0 ? -1 : 1;             // The values differed
 
1764
 
 
1765
  // Check if the compared equal arguments was defined with open/closed range
 
1766
 end:
 
1767
  if (a_flag & (NEAR_MIN | NEAR_MAX))
 
1768
  {
 
1769
    if ((a_flag & (NEAR_MIN | NEAR_MAX)) == (b_flag & (NEAR_MIN | NEAR_MAX)))
 
1770
      return 0;
 
1771
    if (!(b_flag & (NEAR_MIN | NEAR_MAX)))
 
1772
      return (a_flag & NEAR_MIN) ? 2 : -2;
 
1773
    return (a_flag & NEAR_MIN) ? 1 : -1;
 
1774
  }
 
1775
  if (b_flag & (NEAR_MIN | NEAR_MAX))
 
1776
    return (b_flag & NEAR_MIN) ? -2 : 2;
 
1777
  return 0;                                     // The elements where equal
 
1778
}
 
1779
 
 
1780
 
 
1781
SEL_ARG *SEL_ARG::clone_tree(RANGE_OPT_PARAM *param)
 
1782
{
 
1783
  SEL_ARG tmp_link,*next_arg,*root;
 
1784
  next_arg= &tmp_link;
 
1785
  if (!(root= clone(param, (SEL_ARG *) 0, &next_arg)))
 
1786
    return 0;
 
1787
  next_arg->next=0;                             // Fix last link
 
1788
  tmp_link.next->prev=0;                        // Fix first link
 
1789
  if (root)                                     // If not OOM
 
1790
    root->use_count= 0;
 
1791
  return root;
 
1792
}
431
1793
 
432
1794
 
433
1795
/*
459
1821
    MAX_KEY if no such index was found.
460
1822
*/
461
1823
 
462
 
uint32_t optimizer::get_index_for_order(Table *table, order_st *order, ha_rows limit)
 
1824
uint32_t get_index_for_order(Table *table, order_st *order, ha_rows limit)
463
1825
{
464
1826
  uint32_t idx;
465
1827
  uint32_t match_key= MAX_KEY, match_key_len= MAX_KEY_LENGTH + 1;
482
1844
      indexes (records are returned in order for any index prefix) or HASH
483
1845
      indexes (records are not returned in order for any index prefix).
484
1846
    */
485
 
    if (! (table->index_flags(idx) & HA_READ_ORDER))
 
1847
    if (!(table->file->index_flags(idx, 0, 1) & HA_READ_ORDER))
486
1848
      continue;
487
1849
    for (ord= order; ord && partno < n_parts; ord= ord->next, partno++)
488
1850
    {
489
1851
      Item *item= order->item[0];
490
 
      if (! (item->type() == Item::FIELD_ITEM &&
 
1852
      if (!(item->type() == Item::FIELD_ITEM &&
491
1853
           ((Item_field*)item)->field->eq(keyinfo[partno].field)))
492
1854
        break;
493
1855
    }
494
1856
 
495
 
    if (! ord && table->key_info[idx].key_length < match_key_len)
 
1857
    if (!ord && table->key_info[idx].key_length < match_key_len)
496
1858
    {
497
1859
      /*
498
1860
        Ok, the ordering is compatible and this key is shorter then
511
1873
      order. Now we'll check if using the index is cheaper then doing a table
512
1874
      scan.
513
1875
    */
514
 
    double full_scan_time= table->cursor->scan_time();
515
 
    double index_scan_time= table->cursor->read_time(match_key, 1, limit);
 
1876
    double full_scan_time= table->file->scan_time();
 
1877
    double index_scan_time= table->file->read_time(match_key, 1, limit);
516
1878
    if (index_scan_time > full_scan_time)
517
1879
      match_key= MAX_KEY;
518
1880
  }
520
1882
}
521
1883
 
522
1884
 
 
1885
/*
 
1886
  Table rows retrieval plan. Range optimizer creates QUICK_SELECT_I-derived
 
1887
  objects from table read plans.
 
1888
*/
 
1889
class TABLE_READ_PLAN
 
1890
{
 
1891
public:
 
1892
  /*
 
1893
    Plan read cost, with or without cost of full row retrieval, depending
 
1894
    on plan creation parameters.
 
1895
  */
 
1896
  double read_cost;
 
1897
  ha_rows records; /* estimate of #rows to be examined */
 
1898
 
 
1899
  /*
 
1900
    If true, the scan returns rows in rowid order. This is used only for
 
1901
    scans that can be both ROR and non-ROR.
 
1902
  */
 
1903
  bool is_ror;
 
1904
 
 
1905
  /*
 
1906
    Create quick select for this plan.
 
1907
    SYNOPSIS
 
1908
     make_quick()
 
1909
       param               Parameter from test_quick_select
 
1910
       retrieve_full_rows  If true, created quick select will do full record
 
1911
                           retrieval.
 
1912
       parent_alloc        Memory pool to use, if any.
 
1913
 
 
1914
    NOTES
 
1915
      retrieve_full_rows is ignored by some implementations.
 
1916
 
 
1917
    RETURN
 
1918
      created quick select
 
1919
      NULL on any error.
 
1920
  */
 
1921
  virtual QUICK_SELECT_I *make_quick(PARAM *param,
 
1922
                                     bool retrieve_full_rows,
 
1923
                                     MEM_ROOT *parent_alloc=NULL) = 0;
 
1924
 
 
1925
  /* Table read plans are allocated on MEM_ROOT and are never deleted */
 
1926
  static void *operator new(size_t size, MEM_ROOT *mem_root)
 
1927
  { return (void*) alloc_root(mem_root, (uint32_t) size); }
 
1928
  static void operator delete(void *, size_t)
 
1929
    { TRASH(ptr, size); }
 
1930
  static void operator delete(void *, MEM_ROOT *)
 
1931
    { /* Never called */ }
 
1932
  virtual ~TABLE_READ_PLAN() {}               /* Remove gcc warning */
 
1933
 
 
1934
};
 
1935
 
 
1936
class TRP_ROR_INTERSECT;
 
1937
class TRP_ROR_UNION;
 
1938
class TRP_INDEX_MERGE;
 
1939
 
 
1940
 
 
1941
/*
 
1942
  Plan for a QUICK_RANGE_SELECT scan.
 
1943
  TRP_RANGE::make_quick ignores retrieve_full_rows parameter because
 
1944
  QUICK_RANGE_SELECT doesn't distinguish between 'index only' scans and full
 
1945
  record retrieval scans.
 
1946
*/
 
1947
 
 
1948
class TRP_RANGE : public TABLE_READ_PLAN
 
1949
{
 
1950
public:
 
1951
  SEL_ARG *key; /* set of intervals to be used in "range" method retrieval */
 
1952
  uint32_t     key_idx; /* key number in PARAM::key */
 
1953
  uint32_t     mrr_flags;
 
1954
  uint32_t     mrr_buf_size;
 
1955
 
 
1956
  TRP_RANGE(SEL_ARG *key_arg, uint32_t idx_arg, uint32_t mrr_flags_arg)
 
1957
   : key(key_arg), key_idx(idx_arg), mrr_flags(mrr_flags_arg)
 
1958
  {}
 
1959
  virtual ~TRP_RANGE() {}                     /* Remove gcc warning */
 
1960
 
 
1961
  QUICK_SELECT_I *make_quick(PARAM *param, bool, MEM_ROOT *parent_alloc)
 
1962
  {
 
1963
    QUICK_RANGE_SELECT *quick;
 
1964
    if ((quick= get_quick_select(param, key_idx, key, mrr_flags, mrr_buf_size,
 
1965
                                 parent_alloc)))
 
1966
    {
 
1967
      quick->records= records;
 
1968
      quick->read_time= read_cost;
 
1969
    }
 
1970
    return quick;
 
1971
  }
 
1972
};
 
1973
 
 
1974
 
 
1975
/* Plan for QUICK_ROR_INTERSECT_SELECT scan. */
 
1976
 
 
1977
class TRP_ROR_INTERSECT : public TABLE_READ_PLAN
 
1978
{
 
1979
public:
 
1980
  TRP_ROR_INTERSECT() {}                      /* Remove gcc warning */
 
1981
  virtual ~TRP_ROR_INTERSECT() {}             /* Remove gcc warning */
 
1982
  QUICK_SELECT_I *make_quick(PARAM *param, bool retrieve_full_rows,
 
1983
                             MEM_ROOT *parent_alloc);
 
1984
 
 
1985
  /* Array of pointers to ROR range scans used in this intersection */
 
1986
  struct st_ror_scan_info **first_scan;
 
1987
  struct st_ror_scan_info **last_scan; /* End of the above array */
 
1988
  struct st_ror_scan_info *cpk_scan;  /* Clustered PK scan, if there is one */
 
1989
  bool is_covering; /* true if no row retrieval phase is necessary */
 
1990
  double index_scan_costs; /* SUM(cost(index_scan)) */
 
1991
};
 
1992
 
 
1993
 
 
1994
/*
 
1995
  Plan for QUICK_ROR_UNION_SELECT scan.
 
1996
  QUICK_ROR_UNION_SELECT always retrieves full rows, so retrieve_full_rows
 
1997
  is ignored by make_quick.
 
1998
*/
 
1999
 
 
2000
class TRP_ROR_UNION : public TABLE_READ_PLAN
 
2001
{
 
2002
public:
 
2003
  TRP_ROR_UNION() {}                          /* Remove gcc warning */
 
2004
  virtual ~TRP_ROR_UNION() {}                 /* Remove gcc warning */
 
2005
  QUICK_SELECT_I *make_quick(PARAM *param, bool retrieve_full_rows,
 
2006
                             MEM_ROOT *parent_alloc);
 
2007
  TABLE_READ_PLAN **first_ror; /* array of ptrs to plans for merged scans */
 
2008
  TABLE_READ_PLAN **last_ror;  /* end of the above array */
 
2009
};
 
2010
 
 
2011
 
 
2012
/*
 
2013
  Plan for QUICK_INDEX_MERGE_SELECT scan.
 
2014
  QUICK_ROR_INTERSECT_SELECT always retrieves full rows, so retrieve_full_rows
 
2015
  is ignored by make_quick.
 
2016
*/
 
2017
 
 
2018
class TRP_INDEX_MERGE : public TABLE_READ_PLAN
 
2019
{
 
2020
public:
 
2021
  TRP_INDEX_MERGE() {}                        /* Remove gcc warning */
 
2022
  virtual ~TRP_INDEX_MERGE() {}               /* Remove gcc warning */
 
2023
  QUICK_SELECT_I *make_quick(PARAM *param, bool retrieve_full_rows,
 
2024
                             MEM_ROOT *parent_alloc);
 
2025
  TRP_RANGE **range_scans; /* array of ptrs to plans of merged scans */
 
2026
  TRP_RANGE **range_scans_end; /* end of the array */
 
2027
};
 
2028
 
 
2029
 
 
2030
/*
 
2031
  Plan for a QUICK_GROUP_MIN_MAX_SELECT scan.
 
2032
*/
 
2033
 
 
2034
class TRP_GROUP_MIN_MAX : public TABLE_READ_PLAN
 
2035
{
 
2036
private:
 
2037
  bool have_min, have_max;
 
2038
  KEY_PART_INFO *min_max_arg_part;
 
2039
  uint32_t group_prefix_len;
 
2040
  uint32_t used_key_parts;
 
2041
  uint32_t group_key_parts;
 
2042
  KEY *index_info;
 
2043
  uint32_t index;
 
2044
  uint32_t key_infix_len;
 
2045
  unsigned char key_infix[MAX_KEY_LENGTH];
 
2046
  SEL_TREE *range_tree; /* Represents all range predicates in the query. */
 
2047
  SEL_ARG  *index_tree; /* The SEL_ARG sub-tree corresponding to index_info. */
 
2048
  uint32_t param_idx; /* Index of used key in param->key. */
 
2049
  /* Number of records selected by the ranges in index_tree. */
 
2050
public:
 
2051
  ha_rows quick_prefix_records;
 
2052
public:
 
2053
  TRP_GROUP_MIN_MAX(bool have_min_arg, bool have_max_arg,
 
2054
                    KEY_PART_INFO *min_max_arg_part_arg,
 
2055
                    uint32_t group_prefix_len_arg, uint32_t used_key_parts_arg,
 
2056
                    uint32_t group_key_parts_arg, KEY *index_info_arg,
 
2057
                    uint32_t index_arg, uint32_t key_infix_len_arg,
 
2058
                    unsigned char *key_infix_arg,
 
2059
                    SEL_TREE *tree_arg, SEL_ARG *index_tree_arg,
 
2060
                    uint32_t param_idx_arg, ha_rows quick_prefix_records_arg)
 
2061
  : have_min(have_min_arg), have_max(have_max_arg),
 
2062
    min_max_arg_part(min_max_arg_part_arg),
 
2063
    group_prefix_len(group_prefix_len_arg), used_key_parts(used_key_parts_arg),
 
2064
    group_key_parts(group_key_parts_arg), index_info(index_info_arg),
 
2065
    index(index_arg), key_infix_len(key_infix_len_arg), range_tree(tree_arg),
 
2066
    index_tree(index_tree_arg), param_idx(param_idx_arg),
 
2067
    quick_prefix_records(quick_prefix_records_arg)
 
2068
    {
 
2069
      if (key_infix_len)
 
2070
        memcpy(this->key_infix, key_infix_arg, key_infix_len);
 
2071
    }
 
2072
  virtual ~TRP_GROUP_MIN_MAX() {}             /* Remove gcc warning */
 
2073
 
 
2074
  QUICK_SELECT_I *make_quick(PARAM *param, bool retrieve_full_rows,
 
2075
                             MEM_ROOT *parent_alloc);
 
2076
};
 
2077
 
523
2078
 
524
2079
/*
525
2080
  Fill param->needed_fields with bitmap of fields used in the query.
535
2090
    1  Out of memory.
536
2091
*/
537
2092
 
538
 
static int fill_used_fields_bitmap(optimizer::Parameter *param)
 
2093
static int fill_used_fields_bitmap(PARAM *param)
539
2094
{
540
2095
  Table *table= param->table;
541
2096
  my_bitmap_map *tmp;
551
2106
  bitmap_union(&param->needed_fields, table->write_set);
552
2107
 
553
2108
  pk= param->table->s->primary_key;
554
 
  if (pk != MAX_KEY && param->table->cursor->primary_key_is_clustered())
 
2109
  if (pk != MAX_KEY && param->table->file->primary_key_is_clustered())
555
2110
  {
556
2111
    /* The table uses clustered PK and it is not internally generated */
557
2112
    KEY_PART_INFO *key_part= param->table->key_info[pk].key_part;
568
2123
  Test if a key can be used in different ranges
569
2124
 
570
2125
  SYNOPSIS
571
 
    SqlSelect::test_quick_select()
 
2126
    SQL_SELECT::test_quick_select()
572
2127
      session               Current thread
573
2128
      keys_to_use       Keys to use for range retrieval
574
2129
      prev_tables       Tables assumed to be already read when the scan is
630
2185
    1 if found usable ranges and quick select has been successfully created.
631
2186
*/
632
2187
 
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)
 
2188
int SQL_SELECT::test_quick_select(Session *session, key_map keys_to_use,
 
2189
                                  table_map prev_tables,
 
2190
                                  ha_rows limit, bool force_quick_range,
 
2191
                                  bool ordered_output)
639
2192
{
640
2193
  uint32_t idx;
641
2194
  double scan_time;
645
2198
  quick_keys.reset();
646
2199
  if (keys_to_use.none())
647
2200
    return 0;
648
 
  records= head->cursor->stats.records;
 
2201
  records= head->file->stats.records;
649
2202
  if (!records)
650
 
    records++;
 
2203
    records++;                                  /* purecov: inspected */
651
2204
  scan_time= (double) records / TIME_FOR_COMPARE + 1;
652
 
  read_time= (double) head->cursor->scan_time() + scan_time + 1.1;
 
2205
  read_time= (double) head->file->scan_time() + scan_time + 1.1;
653
2206
  if (head->force_index)
654
2207
    scan_time= read_time= DBL_MAX;
655
2208
  if (limit < records)
660
2213
  keys_to_use&= head->keys_in_use_for_query;
661
2214
  if (keys_to_use.any())
662
2215
  {
663
 
    memory::Root alloc;
664
 
    optimizer::SEL_TREE *tree= NULL;
 
2216
    MEM_ROOT alloc;
 
2217
    SEL_TREE *tree= NULL;
665
2218
    KEY_PART *key_parts;
666
2219
    KEY *key_info;
667
 
    optimizer::Parameter param;
 
2220
    PARAM param;
668
2221
 
669
2222
    if (check_stack_overrun(session, 2*STACK_MIN_SIZE, NULL))
670
2223
      return 0;                           // Fatal error flag is set
671
2224
 
672
2225
    /* set up parameter that is passed to all functions */
673
2226
    param.session= session;
 
2227
    param.baseflag= head->file->ha_table_flags();
674
2228
    param.prev_tables= prev_tables | const_tables;
675
2229
    param.read_tables= read_tables;
676
2230
    param.current_table= head->map;
685
2239
    param.force_default_mrr= ordered_output;
686
2240
 
687
2241
    session->no_errors=1;                               // Don't warn about NULL
688
 
    memory::init_sql_alloc(&alloc, session->variables.range_alloc_block_size, 0);
 
2242
    init_sql_alloc(&alloc, session->variables.range_alloc_block_size, 0);
689
2243
    if (!(param.key_parts= (KEY_PART*) alloc_root(&alloc,
690
2244
                                                  sizeof(KEY_PART)*
691
2245
                                                  head->s->key_parts)) ||
734
2288
    {
735
2289
      int key_for_use= head->find_shortest_key(&head->covering_keys);
736
2290
      double key_read_time=
737
 
        param.table->cursor->index_only_read_time(key_for_use,
 
2291
        param.table->file->index_only_read_time(key_for_use,
738
2292
                                                rows2double(records)) +
739
2293
        (double) records / TIME_FOR_COMPARE;
740
2294
      if (key_read_time < read_time)
741
2295
        read_time= key_read_time;
742
2296
    }
743
2297
 
744
 
    optimizer::TableReadPlan *best_trp= NULL;
745
 
    optimizer::GroupMinMaxReadPlan *group_trp= NULL;
 
2298
    TABLE_READ_PLAN *best_trp= NULL;
 
2299
    TRP_GROUP_MIN_MAX *group_trp;
746
2300
    double best_read_time= read_time;
747
2301
 
748
2302
    if (cond)
749
2303
    {
750
2304
      if ((tree= get_mm_tree(&param,cond)))
751
2305
      {
752
 
        if (tree->type == optimizer::SEL_TREE::IMPOSSIBLE)
 
2306
        if (tree->type == SEL_TREE::IMPOSSIBLE)
753
2307
        {
754
2308
          records=0L;                      /* Return -1 from this function. */
755
2309
          read_time= (double) HA_POS_ERROR;
759
2313
          If the tree can't be used for range scans, proceed anyway, as we
760
2314
          can construct a group-min-max quick select
761
2315
        */
762
 
        if (tree->type != optimizer::SEL_TREE::KEY && tree->type != optimizer::SEL_TREE::KEY_SMALLER)
 
2316
        if (tree->type != SEL_TREE::KEY && tree->type != SEL_TREE::KEY_SMALLER)
763
2317
          tree= NULL;
764
2318
      }
765
2319
    }
766
2320
 
767
2321
    /*
768
 
      Try to construct a QuickGroupMinMaxSelect.
 
2322
      Try to construct a QUICK_GROUP_MIN_MAX_SELECT.
769
2323
      Notice that it can be constructed no matter if there is a range tree.
770
2324
    */
771
2325
    group_trp= get_best_group_min_max(&param, tree);
772
2326
    if (group_trp)
773
2327
    {
774
2328
      param.table->quick_condition_rows= min(group_trp->records,
775
 
                                             head->cursor->stats.records);
 
2329
                                             head->file->stats.records);
776
2330
      if (group_trp->read_cost < best_read_time)
777
2331
      {
778
2332
        best_trp= group_trp;
786
2340
        It is possible to use a range-based quick select (but it might be
787
2341
        slower than 'all' table scan).
788
2342
      */
789
 
      if (tree->merges.is_empty())
 
2343
      if (tree->merges.empty() == true)
790
2344
      {
791
 
        optimizer::RangeReadPlan *range_trp= NULL;
792
 
        optimizer::RorIntersectReadPlan *rori_trp= NULL;
 
2345
        TRP_RANGE         *range_trp;
 
2346
        TRP_ROR_INTERSECT *rori_trp;
793
2347
        bool can_build_covering= false;
794
2348
 
795
2349
        /* Get best 'range' plan and prepare data for making other plans */
801
2355
        }
802
2356
 
803
2357
        /*
804
 
          Simultaneous key scans and row deletes on several Cursor
 
2358
          Simultaneous key scans and row deletes on several handler
805
2359
          objects are not allowed so don't use ROR-intersection for
806
2360
          table deletes.
807
2361
        */
820
2374
              Try constructing covering ROR-intersect only if it looks possible
821
2375
              and worth doing.
822
2376
            */
823
 
            if (rori_trp->isRowRetrievalNecessary() && can_build_covering &&
 
2377
            if (!rori_trp->is_covering && can_build_covering &&
824
2378
                (rori_trp= get_best_covering_ror_intersect(&param, tree,
825
2379
                                                           best_read_time)))
826
2380
              best_trp= rori_trp;
830
2384
      else
831
2385
      {
832
2386
        /* 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++))
 
2387
        TABLE_READ_PLAN *best_conj_trp= NULL, *new_conj_trp;
 
2388
        vector<SEL_IMERGE*>::iterator imerge= tree->merges.begin();
 
2389
        while (imerge != tree->merges.end())
838
2390
        {
839
 
          new_conj_trp= get_best_disjunct_quick(&param, imerge, best_read_time);
 
2391
          new_conj_trp= get_best_disjunct_quick(&param, *imerge, best_read_time);
840
2392
          if (new_conj_trp)
841
2393
            set_if_smaller(param.table->quick_condition_rows,
842
2394
                           new_conj_trp->records);
 
2395
 
843
2396
          if (!best_conj_trp || (new_conj_trp && new_conj_trp->read_cost <
844
2397
                                 best_conj_trp->read_cost))
845
2398
            best_conj_trp= new_conj_trp;
 
2399
 
 
2400
          ++imerge;
846
2401
        }
847
2402
        if (best_conj_trp)
848
2403
          best_trp= best_conj_trp;
855
2410
    if (best_trp)
856
2411
    {
857
2412
      records= best_trp->records;
858
 
      if (! (quick= best_trp->make_quick(&param, true)) || quick->init())
 
2413
      if (!(quick= best_trp->make_quick(&param, true)) || quick->init())
859
2414
      {
860
2415
        delete quick;
861
2416
        quick= NULL;
876
2431
}
877
2432
 
878
2433
/*
879
 
  Get best plan for a optimizer::SEL_IMERGE disjunctive expression.
 
2434
  Get best plan for a SEL_IMERGE disjunctive expression.
880
2435
  SYNOPSIS
881
2436
    get_best_disjunct_quick()
882
2437
      param     Parameter from check_quick_select function
902
2457
          {cost of ordinary clustered PK scan with n_ranges=n_rows}
903
2458
 
904
2459
      Otherwise, we use the following model to calculate costs:
905
 
      We need to retrieve n_rows rows from cursor that occupies n_blocks blocks.
 
2460
      We need to retrieve n_rows rows from file that occupies n_blocks blocks.
906
2461
      We assume that offsets of rows we need are independent variates with
907
2462
      uniform distribution in [0..max_file_offset] range.
908
2463
 
910
2465
      and "empty" if doesn't contain rows we need.
911
2466
 
912
2467
      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
 
2468
      applies to any block in file). Let x_i be a variate taking value 1 if
914
2469
      block #i is empty and 0 otherwise.
915
2470
 
916
2471
      Then E(x_i) = (1 - 1/n_blocks)^n_rows;
941
2496
*/
942
2497
 
943
2498
static
944
 
optimizer::TableReadPlan *get_best_disjunct_quick(optimizer::Parameter *param,
945
 
                                                  optimizer::SEL_IMERGE *imerge,
946
 
                                                  double read_time)
 
2499
TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
 
2500
                                         double read_time)
947
2501
{
948
 
  optimizer::SEL_TREE **ptree= NULL;
949
 
  optimizer::IndexMergeReadPlan *imerge_trp= NULL;
 
2502
  SEL_TREE **ptree;
 
2503
  TRP_INDEX_MERGE *imerge_trp= NULL;
950
2504
  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;
 
2505
  TRP_RANGE **range_scans;
 
2506
  TRP_RANGE **cur_child;
 
2507
  TRP_RANGE **cpk_scan= NULL;
954
2508
  bool imerge_too_expensive= false;
955
2509
  double imerge_cost= 0.0;
956
2510
  ha_rows cpk_scan_records= 0;
957
2511
  ha_rows non_cpk_scan_records= 0;
958
 
  bool pk_is_clustered= param->table->cursor->primary_key_is_clustered();
 
2512
  bool pk_is_clustered= param->table->file->primary_key_is_clustered();
959
2513
  bool all_scans_ror_able= true;
960
2514
  bool all_scans_rors= true;
961
2515
  uint32_t unique_calc_buff_size;
962
 
  optimizer::TableReadPlan **roru_read_plans= NULL;
963
 
  optimizer::TableReadPlan **cur_roru_plan= NULL;
 
2516
  TABLE_READ_PLAN **roru_read_plans;
 
2517
  TABLE_READ_PLAN **cur_roru_plan;
964
2518
  double roru_index_costs;
965
2519
  ha_rows roru_total_records;
966
2520
  double roru_intersect_part= 1.0;
967
2521
 
968
 
  if (! (range_scans= (optimizer::RangeReadPlan**)alloc_root(param->mem_root,
969
 
                                                             sizeof(optimizer::RangeReadPlan*)*
970
 
                                                             n_child_scans)))
 
2522
  if (!(range_scans= (TRP_RANGE**)alloc_root(param->mem_root,
 
2523
                                             sizeof(TRP_RANGE*)*
 
2524
                                             n_child_scans)))
971
2525
    return NULL;
972
2526
  /*
973
2527
    Collect best 'range' scan for each of disjuncts, and, while doing so,
978
2532
       ptree != imerge->trees_next;
979
2533
       ptree++, cur_child++)
980
2534
  {
 
2535
    print_sel_tree(param, *ptree, &(*ptree)->keys_map, "tree in SEL_IMERGE");
981
2536
    if (!(*cur_child= get_key_scans_params(param, *ptree, true, false, read_time)))
982
2537
    {
983
2538
      /*
984
2539
        One of index scans in this index_merge is more expensive than entire
985
2540
        table read for another available option. The entire index_merge (and
986
2541
        any possible ROR-union) will be more expensive then, too. We continue
987
 
        here only to update SqlSelect members.
 
2542
        here only to update SQL_SELECT members.
988
2543
      */
989
2544
      imerge_too_expensive= true;
990
2545
    }
995
2550
    all_scans_ror_able &= ((*ptree)->n_ror_scans > 0);
996
2551
    all_scans_rors &= (*cur_child)->is_ror;
997
2552
    if (pk_is_clustered &&
998
 
        param->real_keynr[(*cur_child)->getKeyIndex()] ==
 
2553
        param->real_keynr[(*cur_child)->key_idx] ==
999
2554
        param->table->s->primary_key)
1000
2555
    {
1001
2556
      cpk_scan= cur_child;
1006
2561
  }
1007
2562
 
1008
2563
  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))
 
2564
      ((non_cpk_scan_records+cpk_scan_records >= param->table->file->stats.records) && read_time != DBL_MAX))
1010
2565
  {
1011
2566
    /*
1012
2567
      Bail out if it is obvious that both index_merge and ROR-union will be
1016
2571
  }
1017
2572
  if (all_scans_rors)
1018
2573
  {
1019
 
    roru_read_plans= (optimizer::TableReadPlan **) range_scans;
 
2574
    roru_read_plans= (TABLE_READ_PLAN**)range_scans;
1020
2575
    goto skip_to_ror_scan;
1021
2576
  }
1022
2577
  if (cpk_scan)
1023
2578
  {
1024
2579
    /*
1025
2580
      Add one ROWID comparison for each row retrieved on non-CPK scan.  (it
1026
 
      is done in QuickRangeSelect::row_in_ranges)
 
2581
      is done in QUICK_RANGE_SELECT::row_in_ranges)
1027
2582
     */
1028
2583
    imerge_cost += non_cpk_scan_records / TIME_FOR_COMPARE_ROWID;
1029
2584
  }
1030
2585
 
1031
2586
  /* Calculate cost(rowid_to_row_scan) */
1032
2587
  {
1033
 
    optimizer::CostVector sweep_cost;
 
2588
    COST_VECT sweep_cost;
1034
2589
    JOIN *join= param->session->lex->select_lex.join;
1035
2590
    bool is_interrupted= test(join && join->tables == 1);
1036
2591
    get_sweep_read_cost(param->table, non_cpk_scan_records, is_interrupted,
1043
2598
  /* Add Unique operations cost */
1044
2599
  unique_calc_buff_size=
1045
2600
    Unique::get_cost_calc_buff_size((ulong)non_cpk_scan_records,
1046
 
                                    param->table->cursor->ref_length,
 
2601
                                    param->table->file->ref_length,
1047
2602
                                    param->session->variables.sortbuff_size);
1048
2603
  if (param->imerge_cost_buff_size < unique_calc_buff_size)
1049
2604
  {
1055
2610
 
1056
2611
  imerge_cost +=
1057
2612
    Unique::get_use_cost(param->imerge_cost_buff, (uint32_t)non_cpk_scan_records,
1058
 
                         param->table->cursor->ref_length,
 
2613
                         param->table->file->ref_length,
1059
2614
                         param->session->variables.sortbuff_size);
1060
2615
  if (imerge_cost < read_time)
1061
2616
  {
1062
 
    if ((imerge_trp= new (param->mem_root) optimizer::IndexMergeReadPlan))
 
2617
    if ((imerge_trp= new (param->mem_root)TRP_INDEX_MERGE))
1063
2618
    {
1064
2619
      imerge_trp->read_cost= imerge_cost;
1065
2620
      imerge_trp->records= non_cpk_scan_records + cpk_scan_records;
1066
2621
      imerge_trp->records= min(imerge_trp->records,
1067
 
                               param->table->cursor->stats.records);
 
2622
                               param->table->file->stats.records);
1068
2623
      imerge_trp->range_scans= range_scans;
1069
2624
      imerge_trp->range_scans_end= range_scans + n_child_scans;
1070
2625
      read_time= imerge_cost;
1077
2632
 
1078
2633
  /* Ok, it is possible to build a ROR-union, try it. */
1079
2634
  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;
 
2635
  if (!(roru_read_plans=
 
2636
          (TABLE_READ_PLAN**)alloc_root(param->mem_root,
 
2637
                                        sizeof(TABLE_READ_PLAN*)*
 
2638
                                        n_child_scans)))
 
2639
    return(imerge_trp);
1085
2640
skip_to_ror_scan:
1086
2641
  roru_index_costs= 0.0;
1087
2642
  roru_total_records= 0;
1102
2657
    if ((*cur_child)->is_ror)
1103
2658
    {
1104
2659
      /* 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,
 
2660
      cost= param->table->file->
 
2661
              read_time(param->real_keynr[(*cur_child)->key_idx], 1,
1107
2662
                        (*cur_child)->records) +
1108
2663
              rows2double((*cur_child)->records) / TIME_FOR_COMPARE;
1109
2664
    }
1110
2665
    else
1111
2666
      cost= read_time;
1112
2667
 
1113
 
    optimizer::TableReadPlan *prev_plan= *cur_child;
 
2668
    TABLE_READ_PLAN *prev_plan= *cur_child;
1114
2669
    if (!(*cur_roru_plan= get_best_ror_intersect(param, *ptree, cost,
1115
2670
                                                 &dummy)))
1116
2671
    {
1121
2676
      roru_index_costs += (*cur_roru_plan)->read_cost;
1122
2677
    }
1123
2678
    else
1124
 
    {
1125
2679
      roru_index_costs +=
1126
 
        ((optimizer::RorIntersectReadPlan *)(*cur_roru_plan))->getCostOfIndexScans();
1127
 
    }
 
2680
        ((TRP_ROR_INTERSECT*)(*cur_roru_plan))->index_scan_costs;
1128
2681
    roru_total_records += (*cur_roru_plan)->records;
1129
2682
    roru_intersect_part *= (*cur_roru_plan)->records /
1130
 
                           param->table->cursor->stats.records;
 
2683
                           param->table->file->stats.records;
1131
2684
  }
1132
2685
 
1133
2686
  /*
1137
2690
    in disjunction do not share key parts.
1138
2691
  */
1139
2692
  roru_total_records -= (ha_rows)(roru_intersect_part*
1140
 
                                  param->table->cursor->stats.records);
 
2693
                                  param->table->file->stats.records);
1141
2694
  /* ok, got a ROR read plan for each of the disjuncts
1142
2695
    Calculate cost:
1143
2696
    cost(index_union_scan(scan_1, ... scan_n)) =
1148
2701
  */
1149
2702
  double roru_total_cost;
1150
2703
  {
1151
 
    optimizer::CostVector sweep_cost;
 
2704
    COST_VECT sweep_cost;
1152
2705
    JOIN *join= param->session->lex->select_lex.join;
1153
2706
    bool is_interrupted= test(join && join->tables == 1);
1154
2707
    get_sweep_read_cost(param->table, roru_total_records, is_interrupted,
1159
2712
                     sweep_cost.total_cost();
1160
2713
  }
1161
2714
 
1162
 
  optimizer::RorUnionReadPlan *roru= NULL;
 
2715
  TRP_ROR_UNION* roru;
1163
2716
  if (roru_total_cost < read_time)
1164
2717
  {
1165
 
    if ((roru= new (param->mem_root) optimizer::RorUnionReadPlan))
 
2718
    if ((roru= new (param->mem_root) TRP_ROR_UNION))
1166
2719
    {
1167
 
      roru->merged_scans.assign(roru_read_plans, roru_read_plans + n_child_scans);
 
2720
      roru->first_ror= roru_read_plans;
 
2721
      roru->last_ror= roru_read_plans + n_child_scans;
1168
2722
      roru->read_cost= roru_total_cost;
1169
2723
      roru->records= roru_total_records;
1170
 
      return roru;
 
2724
      return(roru);
1171
2725
    }
1172
2726
  }
1173
2727
  return(imerge_trp);
1181
2735
  ha_rows   records;  /* estimate of # records this scan will return */
1182
2736
 
1183
2737
  /* Set of intervals over key fields that will be used for row retrieval. */
1184
 
  optimizer::SEL_ARG   *sel_arg;
 
2738
  SEL_ARG   *sel_arg;
1185
2739
 
1186
2740
  /* Fields used in the query and covered by this ROR scan. */
1187
2741
  MyBitmap covered_fields;
1214
2768
*/
1215
2769
 
1216
2770
static
1217
 
ROR_SCAN_INFO *make_ror_scan(const optimizer::Parameter *param, int idx, optimizer::SEL_ARG *sel_arg)
 
2771
ROR_SCAN_INFO *make_ror_scan(const PARAM *param, int idx, SEL_ARG *sel_arg)
1218
2772
{
1219
2773
  ROR_SCAN_INFO *ror_scan;
1220
2774
  my_bitmap_map *bitmap_buf;
1228
2782
  ror_scan->idx= idx;
1229
2783
  ror_scan->keynr= keynr= param->real_keynr[idx];
1230
2784
  ror_scan->key_rec_length= (param->table->key_info[keynr].key_length +
1231
 
                             param->table->cursor->ref_length);
 
2785
                             param->table->file->ref_length);
1232
2786
  ror_scan->sel_arg= sel_arg;
1233
2787
  ror_scan->records= param->table->quick_rows[keynr];
1234
2788
 
1251
2805
  }
1252
2806
  double rows= rows2double(param->table->quick_rows[ror_scan->keynr]);
1253
2807
  ror_scan->index_read_cost=
1254
 
    param->table->cursor->index_only_read_time(ror_scan->keynr, rows);
 
2808
    param->table->file->index_only_read_time(ror_scan->keynr, rows);
1255
2809
  return(ror_scan);
1256
2810
}
1257
2811
 
1314
2868
/* Auxiliary structure for incremental ROR-intersection creation */
1315
2869
typedef struct
1316
2870
{
1317
 
  const optimizer::Parameter *param;
 
2871
  const PARAM *param;
1318
2872
  MyBitmap covered_fields; /* union of fields covered by all scans */
1319
2873
  /*
1320
2874
    Fraction of table records that satisfies conditions of all scans.
1344
2898
*/
1345
2899
 
1346
2900
static
1347
 
ROR_INTERSECT_INFO* ror_intersect_init(const optimizer::Parameter *param)
 
2901
ROR_INTERSECT_INFO* ror_intersect_init(const PARAM *param)
1348
2902
{
1349
2903
  ROR_INTERSECT_INFO *info;
1350
2904
  my_bitmap_map* buf;
1360
2914
  info->is_covering= false;
1361
2915
  info->index_scan_costs= 0.0;
1362
2916
  info->index_records= 0;
1363
 
  info->out_rows= (double) param->table->cursor->stats.records;
 
2917
  info->out_rows= (double) param->table->file->stats.records;
1364
2918
  info->covered_fields.clearAll();
1365
2919
  return info;
1366
2920
}
1475
3029
  KEY_PART_INFO *key_part= info->param->table->key_info[scan->keynr].key_part;
1476
3030
  unsigned char key_val[MAX_KEY_LENGTH+MAX_FIELD_WIDTH]; /* key values tuple */
1477
3031
  unsigned char *key_ptr= key_val;
1478
 
  optimizer::SEL_ARG *sel_arg= NULL;
1479
 
  optimizer::SEL_ARG *tuple_arg= NULL;
 
3032
  SEL_ARG *sel_arg, *tuple_arg= NULL;
1480
3033
  key_part_map keypart_map= 0;
1481
3034
  bool cur_covered;
1482
3035
  bool prev_covered= test(info->covered_fields.isBitSet(key_part->fieldnr-1));
1486
3039
  min_range.flag= HA_READ_KEY_EXACT;
1487
3040
  max_range.key= key_val;
1488
3041
  max_range.flag= HA_READ_AFTER_KEY;
1489
 
  ha_rows prev_records= info->param->table->cursor->stats.records;
 
3042
  ha_rows prev_records= info->param->table->file->stats.records;
1490
3043
 
1491
3044
  for (sel_arg= scan->sel_arg; sel_arg;
1492
3045
       sel_arg= sel_arg->next_key_part)
1493
3046
  {
1494
 
    cur_covered=
 
3047
    cur_covered= 
1495
3048
      test(info->covered_fields.isBitSet(key_part[sel_arg->part].fieldnr-1));
1496
3049
    if (cur_covered != prev_covered)
1497
3050
    {
1513
3066
      }
1514
3067
      min_range.length= max_range.length= (size_t) (key_ptr - key_val);
1515
3068
      min_range.keypart_map= max_range.keypart_map= keypart_map;
1516
 
      records= (info->param->table->cursor->
 
3069
      records= (info->param->table->file->
1517
3070
                records_in_range(scan->keynr, &min_range, &max_range));
1518
3071
      if (cur_covered)
1519
3072
      {
1615
3168
  info->total_cost= info->index_scan_costs;
1616
3169
  if (!info->is_covering)
1617
3170
  {
1618
 
    optimizer::CostVector sweep_cost;
 
3171
    COST_VECT sweep_cost;
1619
3172
    JOIN *join= info->param->session->lex->select_lex.join;
1620
3173
    bool is_interrupted= test(join && join->tables == 1);
1621
3174
    get_sweep_read_cost(info->param->table, double2rows(info->out_rows),
1691
3244
*/
1692
3245
 
1693
3246
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)
 
3247
TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree,
 
3248
                                          double read_time,
 
3249
                                          bool *are_all_covering)
1698
3250
{
1699
 
  uint32_t idx= 0;
 
3251
  uint32_t idx;
1700
3252
  double min_cost= DBL_MAX;
1701
3253
 
1702
 
  if ((tree->n_ror_scans < 2) || ! param->table->cursor->stats.records)
 
3254
  if ((tree->n_ror_scans < 2) || !param->table->file->stats.records)
1703
3255
    return NULL;
1704
3256
 
1705
3257
  /*
1706
3258
    Step1: Collect ROR-able SEL_ARGs and create ROR_SCAN_INFO for each of
1707
3259
    them. Also find and save clustered PK scan if there is one.
1708
3260
  */
1709
 
  ROR_SCAN_INFO **cur_ror_scan= NULL;
 
3261
  ROR_SCAN_INFO **cur_ror_scan;
1710
3262
  ROR_SCAN_INFO *cpk_scan= NULL;
1711
 
  uint32_t cpk_no= 0;
 
3263
  uint32_t cpk_no;
1712
3264
  bool cpk_scan_used= false;
1713
3265
 
1714
 
  if (! (tree->ror_scans= (ROR_SCAN_INFO**)alloc_root(param->mem_root,
1715
 
                                                      sizeof(ROR_SCAN_INFO*)*
1716
 
                                                      param->keys)))
 
3266
  if (!(tree->ror_scans= (ROR_SCAN_INFO**)alloc_root(param->mem_root,
 
3267
                                                     sizeof(ROR_SCAN_INFO*)*
 
3268
                                                     param->keys)))
1717
3269
    return NULL;
1718
 
  cpk_no= ((param->table->cursor->primary_key_is_clustered()) ?
 
3270
  cpk_no= ((param->table->file->primary_key_is_clustered()) ?
1719
3271
           param->table->s->primary_key : MAX_KEY);
1720
3272
 
1721
3273
  for (idx= 0, cur_ror_scan= tree->ror_scans; idx < param->keys; idx++)
1735
3287
  }
1736
3288
 
1737
3289
  tree->ror_scans_end= cur_ror_scan;
 
3290
  print_ror_scans_arr(param->table, "original",
 
3291
                                          tree->ror_scans,
 
3292
                                          tree->ror_scans_end);
1738
3293
  /*
1739
3294
    Ok, [ror_scans, ror_scans_end) is array of ptrs to initialized
1740
3295
    ROR_SCAN_INFO's.
1741
3296
    Step 2: Get best ROR-intersection using an approximate algorithm.
1742
3297
  */
1743
 
  internal::my_qsort(tree->ror_scans, tree->n_ror_scans, sizeof(ROR_SCAN_INFO*),
1744
 
                     (qsort_cmp)cmp_ror_scan_info);
 
3298
  my_qsort(tree->ror_scans, tree->n_ror_scans, sizeof(ROR_SCAN_INFO*),
 
3299
           (qsort_cmp)cmp_ror_scan_info);
 
3300
  print_ror_scans_arr(param->table, "ordered",
 
3301
                                          tree->ror_scans,
 
3302
                                          tree->ror_scans_end);
1745
3303
 
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)))
 
3304
  ROR_SCAN_INFO **intersect_scans; /* ROR scans used in index intersection */
 
3305
  ROR_SCAN_INFO **intersect_scans_end;
 
3306
  if (!(intersect_scans= (ROR_SCAN_INFO**)alloc_root(param->mem_root,
 
3307
                                                     sizeof(ROR_SCAN_INFO*)*
 
3308
                                                     tree->n_ror_scans)))
1751
3309
    return NULL;
1752
3310
  intersect_scans_end= intersect_scans;
1753
3311
 
1754
3312
  /* 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)))
 
3313
  ROR_INTERSECT_INFO *intersect, *intersect_best;
 
3314
  if (!(intersect= ror_intersect_init(param)) ||
 
3315
      !(intersect_best= ror_intersect_init(param)))
1759
3316
    return NULL;
1760
3317
 
1761
3318
  /* [intersect_scans,intersect_scans_best) will hold the best intersection */
1762
 
  ROR_SCAN_INFO **intersect_scans_best= NULL;
 
3319
  ROR_SCAN_INFO **intersect_scans_best;
1763
3320
  cur_ror_scan= tree->ror_scans;
1764
3321
  intersect_scans_best= intersect_scans;
1765
3322
  while (cur_ror_scan != tree->ror_scans_end && !intersect->is_covering)
1787
3344
    return NULL;
1788
3345
  }
1789
3346
 
 
3347
  print_ror_scans_arr(param->table,
 
3348
                                          "best ROR-intersection",
 
3349
                                          intersect_scans,
 
3350
                                          intersect_scans_best);
 
3351
 
1790
3352
  *are_all_covering= intersect->is_covering;
1791
3353
  uint32_t best_num= intersect_scans_best - intersect_scans;
1792
3354
  ror_intersect_cpy(intersect, intersect_best);
1807
3369
  }
1808
3370
 
1809
3371
  /* Ok, return ROR-intersect plan if we have found one */
1810
 
  optimizer::RorIntersectReadPlan *trp= NULL;
 
3372
  TRP_ROR_INTERSECT *trp= NULL;
1811
3373
  if (min_cost < read_time && (cpk_scan_used || best_num > 1))
1812
3374
  {
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);
 
3375
    if (!(trp= new (param->mem_root) TRP_ROR_INTERSECT))
 
3376
      return(trp);
 
3377
    if (!(trp->first_scan=
 
3378
           (ROR_SCAN_INFO**)alloc_root(param->mem_root,
 
3379
                                       sizeof(ROR_SCAN_INFO*)*best_num)))
 
3380
      return NULL;
 
3381
    memcpy(trp->first_scan, intersect_scans, best_num*sizeof(ROR_SCAN_INFO*));
 
3382
    trp->last_scan=  trp->first_scan + best_num;
 
3383
    trp->is_covering= intersect_best->is_covering;
1818
3384
    trp->read_cost= intersect_best->total_cost;
1819
3385
    /* Prevent divisons by zero */
1820
3386
    ha_rows best_rows = double2rows(intersect_best->out_rows);
1821
 
    if (! best_rows)
 
3387
    if (!best_rows)
1822
3388
      best_rows= 1;
1823
3389
    set_if_smaller(param->table->quick_condition_rows, best_rows);
1824
3390
    trp->records= best_rows;
1825
 
    trp->setCostOfIndexScans(intersect_best->index_scan_costs);
 
3391
    trp->index_scan_costs= intersect_best->index_scan_costs;
1826
3392
    trp->cpk_scan= cpk_scan_used? cpk_scan: NULL;
1827
3393
  }
1828
 
  return trp;
 
3394
  return(trp);
1829
3395
}
1830
3396
 
1831
3397
 
1834
3400
  SYNOPSIS
1835
3401
    get_best_covering_ror_intersect()
1836
3402
      param     Parameter from test_quick_select function.
1837
 
      tree      optimizer::SEL_TREE with sets of intervals for different keys.
 
3403
      tree      SEL_TREE with sets of intervals for different keys.
1838
3404
      read_time Don't return table read plans with cost > read_time.
1839
3405
 
1840
3406
  RETURN
1863
3429
*/
1864
3430
 
1865
3431
static
1866
 
optimizer::RorIntersectReadPlan *get_best_covering_ror_intersect(optimizer::Parameter *param,
1867
 
                                                            optimizer::SEL_TREE *tree,
1868
 
                                                            double read_time)
 
3432
TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param,
 
3433
                                                   SEL_TREE *tree,
 
3434
                                                   double read_time)
1869
3435
{
1870
3436
  ROR_SCAN_INFO **ror_scan_mark;
1871
3437
  ROR_SCAN_INFO **ror_scans_end= tree->ror_scans_end;
1899
3465
  ha_rows records=0;
1900
3466
  bool all_covered;
1901
3467
 
 
3468
  print_ror_scans_arr(param->table,
 
3469
                                           "building covering ROR-I",
 
3470
                                           ror_scan_mark, ror_scans_end);
1902
3471
  do
1903
3472
  {
1904
3473
    /*
1916
3485
        (*scan)->covered_fields.getFirst();
1917
3486
    }
1918
3487
 
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);
 
3488
    my_qsort(ror_scan_mark, ror_scans_end-ror_scan_mark, sizeof(ROR_SCAN_INFO*),
 
3489
             (qsort_cmp)cmp_ror_scan_info_covering);
 
3490
 
 
3491
    print_ror_scans_arr(param->table,
 
3492
                                             "remaining scans",
 
3493
                                             ror_scan_mark, ror_scans_end);
1922
3494
 
1923
3495
    /* I=I-first(I) */
1924
3496
    total_cost += (*ror_scan_mark)->index_read_cost;
1937
3509
    Ok, [tree->ror_scans .. ror_scan) holds covering index_intersection with
1938
3510
    cost total_cost.
1939
3511
  */
 
3512
  print_ror_scans_arr(param->table,
 
3513
                                           "creating covering ROR-intersect",
 
3514
                                           tree->ror_scans, ror_scan_mark);
 
3515
 
1940
3516
  /* Add priority queue use cost. */
1941
3517
  total_cost += rows2double(records)*
1942
3518
                log((double)(ror_scan_mark - tree->ror_scans)) /
1945
3521
  if (total_cost > read_time)
1946
3522
    return NULL;
1947
3523
 
1948
 
  optimizer::RorIntersectReadPlan *trp= NULL;
1949
 
  if (! (trp= new (param->mem_root) optimizer::RorIntersectReadPlan))
1950
 
  {
1951
 
    return trp;
1952
 
  }
1953
 
 
 
3524
  TRP_ROR_INTERSECT *trp;
 
3525
  if (!(trp= new (param->mem_root) TRP_ROR_INTERSECT))
 
3526
    return(trp);
1954
3527
  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);
 
3528
  if (!(trp->first_scan= (ROR_SCAN_INFO**)alloc_root(param->mem_root,
 
3529
                                                     sizeof(ROR_SCAN_INFO*)*
 
3530
                                                     best_num)))
 
3531
    return NULL;
 
3532
  memcpy(trp->first_scan, tree->ror_scans, best_num*sizeof(ROR_SCAN_INFO*));
 
3533
  trp->last_scan=  trp->first_scan + best_num;
 
3534
  trp->is_covering= true;
1957
3535
  trp->read_cost= total_cost;
1958
3536
  trp->records= records;
1959
3537
  trp->cpk_scan= NULL;
1964
3542
 
1965
3543
 
1966
3544
/*
1967
 
  Get best "range" table read plan for given optimizer::SEL_TREE, also update some info
 
3545
  Get best "range" table read plan for given SEL_TREE, also update some info
1968
3546
 
1969
3547
  SYNOPSIS
1970
3548
    get_key_scans_params()
1971
3549
      param                    Parameters from test_quick_select
1972
 
      tree                     Make range select for this optimizer::SEL_TREE
 
3550
      tree                     Make range select for this SEL_TREE
1973
3551
      index_read_must_be_used  true <=> assume 'index only' option will be set
1974
3552
                               (except for clustered PK indexes)
1975
3553
      update_tbl_stats         true <=> update table->quick_* with information
1978
3556
                               cost > read_time.
1979
3557
 
1980
3558
  DESCRIPTION
1981
 
    Find the best "range" table read plan for given optimizer::SEL_TREE.
 
3559
    Find the best "range" table read plan for given SEL_TREE.
1982
3560
    The side effects are
1983
3561
     - tree->ror_scans is updated to indicate which scans are ROR scans.
1984
3562
     - if update_tbl_stats=true then table->quick_* is updated with info
1989
3567
    NULL if no plan found or error occurred
1990
3568
*/
1991
3569
 
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)
 
3570
static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
 
3571
                                       bool index_read_must_be_used,
 
3572
                                       bool update_tbl_stats,
 
3573
                                       double read_time)
1997
3574
{
1998
3575
  uint32_t idx;
1999
 
  optimizer::SEL_ARG **key= NULL;
2000
 
  optimizer::SEL_ARG **end= NULL;
2001
 
  optimizer::SEL_ARG **key_to_read= NULL;
 
3576
  SEL_ARG **key,**end, **key_to_read= NULL;
2002
3577
  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;
 
3578
  uint32_t    best_mrr_flags= 0, best_buf_size= 0;
 
3579
  TRP_RANGE* read_plan= NULL;
2006
3580
  /*
2007
 
    Note that there may be trees that have type optimizer::SEL_TREE::KEY but contain no
 
3581
    Note that there may be trees that have type SEL_TREE::KEY but contain no
2008
3582
    key reads at all, e.g. tree for expression "key1 is not null" where key1
2009
3583
    is defined as "not null".
2010
3584
  */
 
3585
  print_sel_tree(param, tree, &tree->keys_map, "tree scans");
2011
3586
  tree->ror_scans_map.reset();
2012
3587
  tree->n_ror_scans= 0;
2013
3588
  for (idx= 0,key=tree->keys, end=key+param->keys; key != end; key++,idx++)
2015
3590
    if (*key)
2016
3591
    {
2017
3592
      ha_rows found_records;
2018
 
      optimizer::CostVector cost;
2019
 
      double found_read_time= 0.0;
 
3593
      COST_VECT cost;
 
3594
      double found_read_time;
2020
3595
      uint32_t mrr_flags, buf_size;
2021
3596
      uint32_t keynr= param->real_keynr[idx];
2022
 
      if ((*key)->type == optimizer::SEL_ARG::MAYBE_KEY ||
 
3597
      if ((*key)->type == SEL_ARG::MAYBE_KEY ||
2023
3598
          (*key)->maybe_flag)
2024
3599
        param->needed_reg->set(keynr);
2025
3600
 
2046
3621
    }
2047
3622
  }
2048
3623
 
 
3624
  print_sel_tree(param, tree, &tree->ror_scans_map, "ROR scans");
2049
3625
  if (key_to_read)
2050
3626
  {
2051
3627
    idx= key_to_read - tree->keys;
2052
 
    if ((read_plan= new (param->mem_root) optimizer::RangeReadPlan(*key_to_read, idx,
2053
 
                                                                   best_mrr_flags)))
 
3628
    if ((read_plan= new (param->mem_root) TRP_RANGE(*key_to_read, idx,
 
3629
                                                    best_mrr_flags)))
2054
3630
    {
2055
3631
      read_plan->records= best_records;
2056
3632
      read_plan->is_ror= tree->ror_scans_map.test(idx);
2057
3633
      read_plan->read_cost= read_time;
2058
 
      read_plan->setMRRBufferSize(best_buf_size);
 
3634
      read_plan->mrr_buf_size= best_buf_size;
2059
3635
    }
2060
3636
  }
2061
3637
 
2063
3639
}
2064
3640
 
2065
3641
 
2066
 
optimizer::QuickSelectInterface *optimizer::IndexMergeReadPlan::make_quick(optimizer::Parameter *param, bool, memory::Root *)
 
3642
QUICK_SELECT_I *TRP_INDEX_MERGE::make_quick(PARAM *param, bool, MEM_ROOT *)
2067
3643
{
2068
 
  optimizer::QuickIndexMergeSelect *quick_imerge;
2069
 
  optimizer::QuickRangeSelect *quick= NULL;
 
3644
  QUICK_INDEX_MERGE_SELECT *quick_imerge;
 
3645
  QUICK_RANGE_SELECT *quick;
2070
3646
  /* index_merge always retrieves full rows, ignore retrieve_full_rows */
2071
 
  if (! (quick_imerge= new optimizer::QuickIndexMergeSelect(param->session, param->table)))
2072
 
  {
 
3647
  if (!(quick_imerge= new QUICK_INDEX_MERGE_SELECT(param->session, param->table)))
2073
3648
    return NULL;
2074
 
  }
2075
3649
 
2076
3650
  quick_imerge->records= records;
2077
3651
  quick_imerge->read_time= read_cost;
2078
 
  for (optimizer::RangeReadPlan **range_scan= range_scans; 
2079
 
       range_scan != range_scans_end;
 
3652
  for (TRP_RANGE **range_scan= range_scans; range_scan != range_scans_end;
2080
3653
       range_scan++)
2081
3654
  {
2082
 
    if (! (quick= (optimizer::QuickRangeSelect*)
2083
 
          ((*range_scan)->make_quick(param, false, &quick_imerge->alloc))) ||
 
3655
    if (!(quick= (QUICK_RANGE_SELECT*)
 
3656
          ((*range_scan)->make_quick(param, false, &quick_imerge->alloc)))||
2084
3657
        quick_imerge->push_quick_back(quick))
2085
3658
    {
2086
3659
      delete quick;
2091
3664
  return quick_imerge;
2092
3665
}
2093
3666
 
2094
 
optimizer::QuickSelectInterface *optimizer::RorIntersectReadPlan::make_quick(optimizer::Parameter *param,
2095
 
                                                                             bool retrieve_full_rows,
2096
 
                                                                             memory::Root *parent_alloc)
 
3667
QUICK_SELECT_I *TRP_ROR_INTERSECT::make_quick(PARAM *param,
 
3668
                                              bool retrieve_full_rows,
 
3669
                                              MEM_ROOT *parent_alloc)
2097
3670
{
2098
 
  optimizer::QuickRorIntersectSelect *quick_intersect= NULL;
2099
 
  optimizer::QuickRangeSelect *quick= NULL;
2100
 
  memory::Root *alloc= NULL;
 
3671
  QUICK_ROR_INTERSECT_SELECT *quick_intrsect;
 
3672
  QUICK_RANGE_SELECT *quick;
 
3673
  MEM_ROOT *alloc;
2101
3674
 
2102
 
  if ((quick_intersect=
2103
 
         new optimizer::QuickRorIntersectSelect(param->session,
2104
 
                                                param->table,
2105
 
                                                (retrieve_full_rows? (! is_covering) : false),
2106
 
                                                parent_alloc)))
 
3675
  if ((quick_intrsect=
 
3676
         new QUICK_ROR_INTERSECT_SELECT(param->session, param->table,
 
3677
                                        (retrieve_full_rows? (!is_covering) :
 
3678
                                         false),
 
3679
                                        parent_alloc)))
2107
3680
  {
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)
 
3681
    print_ror_scans_arr(param->table,
 
3682
                                             "creating ROR-intersect",
 
3683
                                             first_scan, last_scan);
 
3684
    alloc= parent_alloc? parent_alloc: &quick_intrsect->alloc;
 
3685
    for (; first_scan != last_scan;++first_scan)
2112
3686
    {
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))
 
3687
      if (!(quick= get_quick_select(param, (*first_scan)->idx,
 
3688
                                    (*first_scan)->sel_arg,
 
3689
                                    HA_MRR_USE_DEFAULT_IMPL | HA_MRR_SORTED,
 
3690
                                    0, alloc)) ||
 
3691
          quick_intrsect->push_quick_back(quick))
2120
3692
      {
2121
 
        delete quick_intersect;
 
3693
        delete quick_intrsect;
2122
3694
        return NULL;
2123
3695
      }
2124
3696
    }
2125
3697
    if (cpk_scan)
2126
3698
    {
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)))
 
3699
      if (!(quick= get_quick_select(param, cpk_scan->idx,
 
3700
                                    cpk_scan->sel_arg,
 
3701
                                    HA_MRR_USE_DEFAULT_IMPL | HA_MRR_SORTED,
 
3702
                                    0, alloc)))
2133
3703
      {
2134
 
        delete quick_intersect;
 
3704
        delete quick_intrsect;
2135
3705
        return NULL;
2136
3706
      }
2137
 
      quick->resetCursor();
2138
 
      quick_intersect->cpk_quick= quick;
 
3707
      quick->file= NULL;
 
3708
      quick_intrsect->cpk_quick= quick;
2139
3709
    }
2140
 
    quick_intersect->records= records;
2141
 
    quick_intersect->read_time= read_cost;
 
3710
    quick_intrsect->records= records;
 
3711
    quick_intrsect->read_time= read_cost;
2142
3712
  }
2143
 
  return quick_intersect;
 
3713
  return(quick_intrsect);
2144
3714
}
2145
3715
 
2146
3716
 
2147
 
optimizer::QuickSelectInterface *optimizer::RorUnionReadPlan::make_quick(optimizer::Parameter *param, bool, memory::Root *)
 
3717
QUICK_SELECT_I *TRP_ROR_UNION::make_quick(PARAM *param, bool, MEM_ROOT *)
2148
3718
{
2149
 
  optimizer::QuickRorUnionSelect *quick_roru= NULL;
2150
 
  optimizer::QuickSelectInterface *quick= NULL;
 
3719
  QUICK_ROR_UNION_SELECT *quick_roru;
 
3720
  TABLE_READ_PLAN **scan;
 
3721
  QUICK_SELECT_I *quick;
2151
3722
  /*
2152
3723
    It is impossible to construct a ROR-union that will not retrieve full
2153
3724
    rows, ignore retrieve_full_rows parameter.
2154
3725
  */
2155
 
  if ((quick_roru= new optimizer::QuickRorUnionSelect(param->session, param->table)))
 
3726
  if ((quick_roru= new QUICK_ROR_UNION_SELECT(param->session, param->table)))
2156
3727
  {
2157
 
    for (vector<optimizer::TableReadPlan *>::iterator it= merged_scans.begin();
2158
 
         it != merged_scans.end();
2159
 
         ++it)
 
3728
    for (scan= first_ror; scan != last_ror; scan++)
2160
3729
    {
2161
 
      if (! (quick= (*it)->make_quick(param, false, &quick_roru->alloc)) ||
 
3730
      if (!(quick= (*scan)->make_quick(param, false, &quick_roru->alloc)) ||
2162
3731
          quick_roru->push_quick_back(quick))
2163
 
      {
2164
3732
        return NULL;
2165
 
      }
2166
3733
    }
2167
3734
    quick_roru->records= records;
2168
3735
    quick_roru->read_time= read_cost;
2169
3736
  }
2170
 
  return quick_roru;
 
3737
  return(quick_roru);
2171
3738
}
2172
3739
 
2173
3740
 
2174
3741
/*
2175
 
  Build a optimizer::SEL_TREE for <> or NOT BETWEEN predicate
 
3742
  Build a SEL_TREE for <> or NOT BETWEEN predicate
2176
3743
 
2177
3744
  SYNOPSIS
2178
3745
    get_ne_mm_tree()
2179
 
      param       Parameter from SqlSelect::test_quick_select
 
3746
      param       PARAM from SQL_SELECT::test_quick_select
2180
3747
      cond_func   item for the predicate
2181
3748
      field       field in the predicate
2182
3749
      lt_value    constant that field should be smaller
2187
3754
    #  Pointer to tree built tree
2188
3755
    0  on error
2189
3756
*/
2190
 
static optimizer::SEL_TREE *get_ne_mm_tree(optimizer::RangeParameter *param,
2191
 
                                Item_func *cond_func,
 
3757
 
 
3758
static SEL_TREE *get_ne_mm_tree(RANGE_OPT_PARAM *param, Item_func *cond_func,
2192
3759
                                Field *field,
2193
3760
                                Item *lt_value, Item *gt_value,
2194
3761
                                Item_result cmp_type)
2195
3762
{
2196
 
  optimizer::SEL_TREE *tree= NULL;
 
3763
  SEL_TREE *tree;
2197
3764
  tree= get_mm_parts(param, cond_func, field, Item_func::LT_FUNC,
2198
3765
                     lt_value, cmp_type);
2199
3766
  if (tree)
2200
3767
  {
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));
 
3768
    tree= tree_or(param, tree, get_mm_parts(param, cond_func, field,
 
3769
                                            Item_func::GT_FUNC,
 
3770
                                            gt_value, cmp_type));
2207
3771
  }
2208
3772
  return tree;
2209
3773
}
2210
3774
 
2211
3775
 
2212
3776
/*
2213
 
  Build a optimizer::SEL_TREE for a simple predicate
 
3777
  Build a SEL_TREE for a simple predicate
2214
3778
 
2215
3779
  SYNOPSIS
2216
3780
    get_func_mm_tree()
2217
 
      param       Parameter from SqlSelect::test_quick_select
 
3781
      param       PARAM from SQL_SELECT::test_quick_select
2218
3782
      cond_func   item for the predicate
2219
3783
      field       field in the predicate
2220
3784
      value       constant in the predicate
2225
3789
  RETURN
2226
3790
    Pointer to the tree built tree
2227
3791
*/
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)
 
3792
 
 
3793
static SEL_TREE *get_func_mm_tree(RANGE_OPT_PARAM *param, Item_func *cond_func,
 
3794
                                  Field *field, Item *value,
 
3795
                                  Item_result cmp_type, bool inv)
2234
3796
{
2235
 
  optimizer::SEL_TREE *tree= NULL;
 
3797
  SEL_TREE *tree= 0;
2236
3798
 
2237
 
  switch (cond_func->functype()) 
2238
 
  {
 
3799
  switch (cond_func->functype()) {
2239
3800
 
2240
3801
  case Item_func::NE_FUNC:
2241
3802
    tree= get_ne_mm_tree(param, cond_func, field, value, value, cmp_type);
2243
3804
 
2244
3805
  case Item_func::BETWEEN:
2245
3806
  {
2246
 
    if (! value)
 
3807
    if (!value)
2247
3808
    {
2248
3809
      if (inv)
2249
3810
      {
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);
 
3811
        tree= get_ne_mm_tree(param, cond_func, field, cond_func->arguments()[1],
 
3812
                             cond_func->arguments()[2], cmp_type);
2256
3813
      }
2257
3814
      else
2258
3815
      {
2259
 
        tree= get_mm_parts(param, 
2260
 
                           cond_func, 
2261
 
                           field, 
2262
 
                           Item_func::GE_FUNC,
2263
 
                                       cond_func->arguments()[1],
2264
 
                           cmp_type);
 
3816
        tree= get_mm_parts(param, cond_func, field, Item_func::GE_FUNC,
 
3817
                           cond_func->arguments()[1],cmp_type);
2265
3818
        if (tree)
2266
3819
        {
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));
 
3820
          tree= tree_and(param, tree, get_mm_parts(param, cond_func, field,
 
3821
                                                   Item_func::LE_FUNC,
 
3822
                                                   cond_func->arguments()[2],
 
3823
                                                   cmp_type));
2273
3824
        }
2274
3825
      }
2275
3826
    }
2276
3827
    else
2277
 
      tree= get_mm_parts(param, 
2278
 
                         cond_func, 
2279
 
                         field,
 
3828
      tree= get_mm_parts(param, cond_func, field,
2280
3829
                         (inv ?
2281
3830
                          (value == (Item*)1 ? Item_func::GT_FUNC :
2282
3831
                                               Item_func::LT_FUNC):
2283
3832
                          (value == (Item*)1 ? Item_func::LE_FUNC :
2284
3833
                                               Item_func::GE_FUNC)),
2285
 
                         cond_func->arguments()[0], 
2286
 
                         cmp_type);
 
3834
                         cond_func->arguments()[0], cmp_type);
2287
3835
    break;
2288
3836
  }
2289
3837
  case Item_func::IN_FUNC:
2290
3838
  {
2291
 
    Item_func_in *func= (Item_func_in*) cond_func;
 
3839
    Item_func_in *func=(Item_func_in*) cond_func;
2292
3840
 
2293
3841
    /*
2294
3842
      Array for IN() is constructed when all values have the same result
2295
3843
      type. Tree won't be built for values with different result types,
2296
3844
      so we check it here to avoid unnecessary work.
2297
3845
    */
2298
 
    if (! func->arg_types_compatible)
 
3846
    if (!func->arg_types_compatible)
2299
3847
      break;
2300
3848
 
2301
3849
    if (inv)
2304
3852
      {
2305
3853
        /*
2306
3854
          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
 
3855
          where c{i} are constants. Our goal is to produce a SEL_TREE that
2308
3856
          represents intervals:
2309
3857
 
2310
3858
          ($MIN<t.key<c1) OR (c1<t.key<c2) OR (c2<t.key<c3) OR ...    (*)
2313
3861
 
2314
3862
          The most straightforward way to produce it is to convert NOT IN
2315
3863
          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
 
3864
          analyzer to build SEL_TREE from that. The problem is that the
2317
3865
          range analyzer will use O(N^2) memory (which is probably a bug),
2318
3866
          and people do use big NOT IN lists (e.g. see BUG#15872, BUG#21282),
2319
3867
          will run out of memory.
2326
3874
 
2327
3875
          Considering the above, we'll handle NOT IN as follows:
2328
3876
          * 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.
 
3877
            NOT_IN_IGNORE_THRESHOLD, construct the SEL_TREE (*) manually.
 
3878
          * Otherwise, don't produce a SEL_TREE.
2331
3879
        */
2332
3880
#define NOT_IN_IGNORE_THRESHOLD 1000
2333
 
        memory::Root *tmp_root= param->mem_root;
 
3881
        MEM_ROOT *tmp_root= param->mem_root;
2334
3882
        param->session->mem_root= param->old_root;
2335
3883
        /*
2336
3884
          Create one Item_type constant object. We'll need it as
2343
3891
        Item *value_item= func->array->create_item();
2344
3892
        param->session->mem_root= tmp_root;
2345
3893
 
2346
 
        if (func->array->count > NOT_IN_IGNORE_THRESHOLD || ! value_item)
 
3894
        if (func->array->count > NOT_IN_IGNORE_THRESHOLD || !value_item)
2347
3895
          break;
2348
3896
 
2349
 
        /* Get a optimizer::SEL_TREE for "(-inf|NULL) < X < c_0" interval.  */
 
3897
        /* Get a SEL_TREE for "(-inf|NULL) < X < c_0" interval.  */
2350
3898
        uint32_t i=0;
2351
3899
        do
2352
3900
        {
2353
3901
          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)
 
3902
          tree= get_mm_parts(param, cond_func, field, Item_func::LT_FUNC,
 
3903
                             value_item, cmp_type);
 
3904
          if (!tree)
2360
3905
            break;
2361
3906
          i++;
2362
 
        } while (i < func->array->count && tree->type == optimizer::SEL_TREE::IMPOSSIBLE);
 
3907
        } while (i < func->array->count && tree->type == SEL_TREE::IMPOSSIBLE);
2363
3908
 
2364
 
        if (!tree || tree->type == optimizer::SEL_TREE::IMPOSSIBLE)
 
3909
        if (!tree || tree->type == SEL_TREE::IMPOSSIBLE)
2365
3910
        {
2366
3911
          /* We get here in cases like "t.unsigned NOT IN (-1,-2,-3) */
2367
3912
          tree= NULL;
2368
3913
          break;
2369
3914
        }
2370
 
        optimizer::SEL_TREE *tree2= NULL;
 
3915
        SEL_TREE *tree2;
2371
3916
        for (; i < func->array->count; i++)
2372
3917
        {
2373
3918
          if (func->array->compare_elems(i, i-1))
2374
3919
          {
2375
 
            /* Get a optimizer::SEL_TREE for "-inf < X < c_i" interval */
 
3920
            /* Get a SEL_TREE for "-inf < X < c_i" interval */
2376
3921
            func->array->value_to_item(i, value_item);
2377
3922
            tree2= get_mm_parts(param, cond_func, field, Item_func::LT_FUNC,
2378
3923
                                value_item, cmp_type);
2385
3930
            /* Change all intervals to be "c_{i-1} < X < c_i" */
2386
3931
            for (uint32_t idx= 0; idx < param->keys; idx++)
2387
3932
            {
2388
 
              optimizer::SEL_ARG *new_interval, *last_val;
 
3933
              SEL_ARG *new_interval, *last_val;
2389
3934
              if (((new_interval= tree2->keys[idx])) &&
2390
3935
                  (tree->keys[idx]) &&
2391
3936
                  ((last_val= tree->keys[idx]->last())))
2402
3947
          }
2403
3948
        }
2404
3949
 
2405
 
        if (tree && tree->type != optimizer::SEL_TREE::IMPOSSIBLE)
 
3950
        if (tree && tree->type != SEL_TREE::IMPOSSIBLE)
2406
3951
        {
2407
3952
          /*
2408
 
            Get the optimizer::SEL_TREE for the last "c_last < X < +inf" interval
 
3953
            Get the SEL_TREE for the last "c_last < X < +inf" interval
2409
3954
            (value_item cotains c_last already)
2410
3955
          */
2411
3956
          tree2= get_mm_parts(param, cond_func, field, Item_func::GT_FUNC,
2469
4014
 
2470
4015
 
2471
4016
/*
2472
 
  Build conjunction of all optimizer::SEL_TREEs for a simple predicate applying equalities
 
4017
  Build conjunction of all SEL_TREEs for a simple predicate applying equalities
2473
4018
 
2474
4019
  SYNOPSIS
2475
4020
    get_full_func_mm_tree()
2476
 
      param       Parameter from SqlSelect::test_quick_select
 
4021
      param       PARAM from SQL_SELECT::test_quick_select
2477
4022
      cond_func   item for the predicate
2478
4023
      field_item  field in the predicate
2479
4024
      value       constant in the predicate
2484
4029
 
2485
4030
  DESCRIPTION
2486
4031
    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
 
4032
    c is a constant, the function builds a conjunction of all SEL_TREES that can
2488
4033
    be obtained by the substitution of f for all different fields equal to f.
2489
4034
 
2490
4035
  NOTES
2494
4039
    each fj belonging to the same multiple equality as fi
2495
4040
    are built as well.
2496
4041
    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
 
4042
    a SEL_TREE for t2.a > 10 will be built for quick select from t2
2498
4043
    and
2499
 
    a optimizer::SEL_TREE for t1.a > 10 will be built for quick select from t1.
 
4044
    a SEL_TREE for t1.a > 10 will be built for quick select from t1.
2500
4045
 
2501
4046
    A BETWEEN predicate of the form (fi [NOT] BETWEEN c1 AND c2) is treated
2502
4047
    in a similar way: we build a conjuction of trees for the results
2535
4080
    the form (c IN (c1,...,f,...,cn)).
2536
4081
 
2537
4082
  RETURN
2538
 
    Pointer to the tree representing the built conjunction of optimizer::SEL_TREEs
 
4083
    Pointer to the tree representing the built conjunction of SEL_TREEs
2539
4084
*/
2540
4085
 
2541
 
static optimizer::SEL_TREE *get_full_func_mm_tree(optimizer::RangeParameter *param,
 
4086
static SEL_TREE *get_full_func_mm_tree(RANGE_OPT_PARAM *param,
2542
4087
                                       Item_func *cond_func,
2543
4088
                                       Item_field *field_item, Item *value,
2544
4089
                                       bool inv)
2545
4090
{
2546
 
  optimizer::SEL_TREE *tree= 0;
2547
 
  optimizer::SEL_TREE *ftree= 0;
 
4091
  SEL_TREE *tree= 0;
 
4092
  SEL_TREE *ftree= 0;
2548
4093
  table_map ref_tables= 0;
2549
4094
  table_map param_comp= ~(param->prev_tables | param->read_tables |
2550
4095
                          param->current_table);
2586
4131
 
2587
4132
        /* make a select tree of all keys in condition */
2588
4133
 
2589
 
static optimizer::SEL_TREE *get_mm_tree(optimizer::RangeParameter *param, COND *cond)
 
4134
static SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param,COND *cond)
2590
4135
{
2591
 
  optimizer::SEL_TREE *tree=0;
2592
 
  optimizer::SEL_TREE *ftree= 0;
 
4136
  SEL_TREE *tree=0;
 
4137
  SEL_TREE *ftree= 0;
2593
4138
  Item_field *field_item= 0;
2594
4139
  bool inv= false;
2595
4140
  Item *value= 0;
2604
4149
      Item *item;
2605
4150
      while ((item=li++))
2606
4151
      {
2607
 
        optimizer::SEL_TREE *new_tree= get_mm_tree(param,item);
 
4152
        SEL_TREE *new_tree=get_mm_tree(param,item);
2608
4153
        if (param->session->is_fatal_error ||
2609
 
            param->alloced_sel_args > optimizer::SEL_ARG::MAX_SEL_ARGS)
 
4154
            param->alloced_sel_args > SEL_ARG::MAX_SEL_ARGS)
2610
4155
          return 0;     // out of memory
2611
4156
        tree=tree_and(param,tree,new_tree);
2612
 
        if (tree && tree->type == optimizer::SEL_TREE::IMPOSSIBLE)
 
4157
        if (tree && tree->type == SEL_TREE::IMPOSSIBLE)
2613
4158
          break;
2614
4159
      }
2615
4160
    }
2616
4161
    else
2617
4162
    {                                           // COND OR
2618
 
      tree= get_mm_tree(param,li++);
 
4163
      tree=get_mm_tree(param,li++);
2619
4164
      if (tree)
2620
4165
      {
2621
4166
        Item *item;
2622
4167
        while ((item=li++))
2623
4168
        {
2624
 
          optimizer::SEL_TREE *new_tree= get_mm_tree(param,item);
 
4169
          SEL_TREE *new_tree=get_mm_tree(param,item);
2625
4170
          if (!new_tree)
2626
4171
            return 0;   // out of memory
2627
4172
          tree=tree_or(param,tree,new_tree);
2628
 
          if (!tree || tree->type == optimizer::SEL_TREE::ALWAYS)
 
4173
          if (!tree || tree->type == SEL_TREE::ALWAYS)
2629
4174
            break;
2630
4175
        }
2631
4176
      }
2641
4186
      all the memory allocated has the same life span as the subselect
2642
4187
      item itself. So we have to restore the thread's mem_root here.
2643
4188
    */
2644
 
    memory::Root *tmp_root= param->mem_root;
 
4189
    MEM_ROOT *tmp_root= param->mem_root;
2645
4190
    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);
 
4191
    tree= cond->val_int() ? new(tmp_root) SEL_TREE(SEL_TREE::ALWAYS) :
 
4192
                            new(tmp_root) SEL_TREE(SEL_TREE::IMPOSSIBLE);
2648
4193
    param->session->mem_root= tmp_root;
2649
4194
    return(tree);
2650
4195
  }
2658
4203
    if ((ref_tables & param->current_table) ||
2659
4204
        (ref_tables & ~(param->prev_tables | param->read_tables)))
2660
4205
      return 0;
2661
 
    return(new optimizer::SEL_TREE(optimizer::SEL_TREE::MAYBE));
 
4206
    return(new SEL_TREE(SEL_TREE::MAYBE));
2662
4207
  }
2663
4208
 
2664
4209
  Item_func *cond_func= (Item_func*) cond;
2687
4232
      if (cond_func->arguments()[i]->real_item()->type() == Item::FIELD_ITEM)
2688
4233
      {
2689
4234
        field_item= (Item_field*) (cond_func->arguments()[i]->real_item());
2690
 
        optimizer::SEL_TREE *tmp= get_full_func_mm_tree(param, cond_func,
 
4235
        SEL_TREE *tmp= get_full_func_mm_tree(param, cond_func,
2691
4236
                                    field_item, (Item*)(intptr_t)i, inv);
2692
4237
        if (inv)
2693
4238
          tree= !tree ? tmp : tree_or(param, tree, tmp);
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 */
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];
3655
6141
//psergey-merge-todo: support check_quick_keys:max_keypart
3656
6142
static 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;
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
  {
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 MyBitmap *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 MyBitmap *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 MyBitmap *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 MyBitmap *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_reference_st *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;
4313
6812
  */
4314
6813
  if (ref->null_ref_key)
4315
6814
  {
4316
 
    optimizer::QuickRange *null_range= NULL;
 
6815
    QUICK_RANGE *null_range;
4317
6816
 
4318
6817
    *ref->null_ref_key= 1;              // Set null byte then create a range
4319
6818
    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)))
 
6819
          QUICK_RANGE(ref->key_buff, ref->key_length,
 
6820
                      make_prev_keypart_map(ref->key_parts),
 
6821
                      ref->key_buff, ref->key_length,
 
6822
                      make_prev_keypart_map(ref->key_parts), EQ_RANGE)))
4324
6823
      goto err;
4325
6824
    *ref->null_ref_key= 0;              // Clear null byte
4326
6825
    if (insert_dynamic(&quick->ranges,(unsigned char*)&null_range))
4334
6833
    quick->mrr_flags |= HA_MRR_USE_DEFAULT_IMPL;
4335
6834
 
4336
6835
  quick->mrr_buf_size= session->variables.read_rnd_buff_size;
4337
 
  if (table->cursor->multi_range_read_info(quick->index, 1, (uint32_t)records,
 
6836
  if (table->file->multi_range_read_info(quick->index, 1, (uint32_t)records,
4338
6837
                                         &quick->mrr_buf_size,
4339
6838
                                         &quick->mrr_flags, &cost))
4340
6839
    goto err;
4347
6846
 
4348
6847
 
4349
6848
/*
4350
 
  Range sequence interface implementation for array<QuickRange>: initialize
 
6849
  Perform key scans for all used indexes (except CPK), get rowids and merge
 
6850
  them into an ordered non-recurrent sequence of rowids.
 
6851
 
 
6852
  The merge/duplicate removal is performed using Unique class. We put all
 
6853
  rowids into Unique, get the sorted sequence and destroy the Unique.
 
6854
 
 
6855
  If table has a clustered primary key that covers all rows (true for bdb
 
6856
  and innodb currently) and one of the index_merge scans is a scan on PK,
 
6857
  then rows that will be retrieved by PK scan are not put into Unique and
 
6858
  primary key scan is not performed here, it is performed later separately.
 
6859
 
 
6860
  RETURN
 
6861
    0     OK
 
6862
    other error
 
6863
*/
 
6864
 
 
6865
int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge()
 
6866
{
 
6867
  List_iterator_fast<QUICK_RANGE_SELECT> cur_quick_it(quick_selects);
 
6868
  QUICK_RANGE_SELECT* cur_quick;
 
6869
  int result;
 
6870
  Unique *unique;
 
6871
  handler *file= head->file;
 
6872
 
 
6873
  file->extra(HA_EXTRA_KEYREAD);
 
6874
  head->prepare_for_position();
 
6875
 
 
6876
  cur_quick_it.rewind();
 
6877
  cur_quick= cur_quick_it++;
 
6878
  assert(cur_quick != 0);
 
6879
 
 
6880
  /*
 
6881
    We reuse the same instance of handler so we need to call both init and
 
6882
    reset here.
 
6883
  */
 
6884
  if (cur_quick->init() || cur_quick->reset())
 
6885
    return 0;
 
6886
 
 
6887
  unique= new Unique(refpos_order_cmp, (void *)file,
 
6888
                     file->ref_length,
 
6889
                     session->variables.sortbuff_size);
 
6890
  if (!unique)
 
6891
    return 0;
 
6892
  for (;;)
 
6893
  {
 
6894
    while ((result= cur_quick->get_next()) == HA_ERR_END_OF_FILE)
 
6895
    {
 
6896
      cur_quick->range_end();
 
6897
      cur_quick= cur_quick_it++;
 
6898
      if (!cur_quick)
 
6899
        break;
 
6900
 
 
6901
      if (cur_quick->file->inited != handler::NONE)
 
6902
        cur_quick->file->ha_index_end();
 
6903
      if (cur_quick->init() || cur_quick->reset())
 
6904
        return 0;
 
6905
    }
 
6906
 
 
6907
    if (result)
 
6908
    {
 
6909
      if (result != HA_ERR_END_OF_FILE)
 
6910
      {
 
6911
        cur_quick->range_end();
 
6912
        return result;
 
6913
      }
 
6914
      break;
 
6915
    }
 
6916
 
 
6917
    if (session->killed)
 
6918
      return 0;
 
6919
 
 
6920
    /* skip row if it will be retrieved by clustered PK scan */
 
6921
    if (pk_quick_select && pk_quick_select->row_in_ranges())
 
6922
      continue;
 
6923
 
 
6924
    cur_quick->file->position(cur_quick->record);
 
6925
    result= unique->unique_add((char*)cur_quick->file->ref);
 
6926
    if (result)
 
6927
      return 0;
 
6928
 
 
6929
  }
 
6930
 
 
6931
  /* ok, all row ids are in Unique */
 
6932
  result= unique->get(head);
 
6933
  delete unique;
 
6934
  doing_pk_scan= false;
 
6935
  /* index_merge currently doesn't support "using index" at all */
 
6936
  file->extra(HA_EXTRA_NO_KEYREAD);
 
6937
  /* start table scan */
 
6938
  init_read_record(&read_record, session, head, (SQL_SELECT*) 0, 1, 1);
 
6939
  return result;
 
6940
}
 
6941
 
 
6942
 
 
6943
/*
 
6944
  Get next row for index_merge.
 
6945
  NOTES
 
6946
    The rows are read from
 
6947
      1. rowids stored in Unique.
 
6948
      2. QUICK_RANGE_SELECT with clustered primary key (if any).
 
6949
    The sets of rows retrieved in 1) and 2) are guaranteed to be disjoint.
 
6950
*/
 
6951
 
 
6952
int QUICK_INDEX_MERGE_SELECT::get_next()
 
6953
{
 
6954
  int result;
 
6955
 
 
6956
  if (doing_pk_scan)
 
6957
    return(pk_quick_select->get_next());
 
6958
 
 
6959
  if ((result= read_record.read_record(&read_record)) == -1)
 
6960
  {
 
6961
    result= HA_ERR_END_OF_FILE;
 
6962
    end_read_record(&read_record);
 
6963
    /* All rows from Unique have been retrieved, do a clustered PK scan */
 
6964
    if (pk_quick_select)
 
6965
    {
 
6966
      doing_pk_scan= true;
 
6967
      if ((result= pk_quick_select->init()) ||
 
6968
          (result= pk_quick_select->reset()))
 
6969
        return result;
 
6970
      return(pk_quick_select->get_next());
 
6971
    }
 
6972
  }
 
6973
 
 
6974
  return result;
 
6975
}
 
6976
 
 
6977
 
 
6978
/*
 
6979
  Retrieve next record.
 
6980
  SYNOPSIS
 
6981
     QUICK_ROR_INTERSECT_SELECT::get_next()
 
6982
 
 
6983
  NOTES
 
6984
    Invariant on enter/exit: all intersected selects have retrieved all index
 
6985
    records with rowid <= some_rowid_val and no intersected select has
 
6986
    retrieved any index records with rowid > some_rowid_val.
 
6987
    We start fresh and loop until we have retrieved the same rowid in each of
 
6988
    the key scans or we got an error.
 
6989
 
 
6990
    If a Clustered PK scan is present, it is used only to check if row
 
6991
    satisfies its condition (and never used for row retrieval).
 
6992
 
 
6993
  RETURN
 
6994
   0     - Ok
 
6995
   other - Error code if any error occurred.
 
6996
*/
 
6997
 
 
6998
int QUICK_ROR_INTERSECT_SELECT::get_next()
 
6999
{
 
7000
  List_iterator_fast<QUICK_RANGE_SELECT> quick_it(quick_selects);
 
7001
  QUICK_RANGE_SELECT* quick;
 
7002
  int error, cmp;
 
7003
  uint32_t last_rowid_count=0;
 
7004
 
 
7005
  do
 
7006
  {
 
7007
    /* Get a rowid for first quick and save it as a 'candidate' */
 
7008
    quick= quick_it++;
 
7009
    error= quick->get_next();
 
7010
    if (cpk_quick)
 
7011
    {
 
7012
      while (!error && !cpk_quick->row_in_ranges())
 
7013
        error= quick->get_next();
 
7014
    }
 
7015
    if (error)
 
7016
      return(error);
 
7017
 
 
7018
    quick->file->position(quick->record);
 
7019
    memcpy(last_rowid, quick->file->ref, head->file->ref_length);
 
7020
    last_rowid_count= 1;
 
7021
 
 
7022
    while (last_rowid_count < quick_selects.elements)
 
7023
    {
 
7024
      if (!(quick= quick_it++))
 
7025
      {
 
7026
        quick_it.rewind();
 
7027
        quick= quick_it++;
 
7028
      }
 
7029
 
 
7030
      do
 
7031
      {
 
7032
        if ((error= quick->get_next()))
 
7033
          return(error);
 
7034
        quick->file->position(quick->record);
 
7035
        cmp= head->file->cmp_ref(quick->file->ref, last_rowid);
 
7036
      } while (cmp < 0);
 
7037
 
 
7038
      /* Ok, current select 'caught up' and returned ref >= cur_ref */
 
7039
      if (cmp > 0)
 
7040
      {
 
7041
        /* Found a row with ref > cur_ref. Make it a new 'candidate' */
 
7042
        if (cpk_quick)
 
7043
        {
 
7044
          while (!cpk_quick->row_in_ranges())
 
7045
          {
 
7046
            if ((error= quick->get_next()))
 
7047
              return(error);
 
7048
          }
 
7049
        }
 
7050
        memcpy(last_rowid, quick->file->ref, head->file->ref_length);
 
7051
        last_rowid_count= 1;
 
7052
      }
 
7053
      else
 
7054
      {
 
7055
        /* current 'candidate' row confirmed by this select */
 
7056
        last_rowid_count++;
 
7057
      }
 
7058
    }
 
7059
 
 
7060
    /* We get here if we got the same row ref in all scans. */
 
7061
    if (need_to_fetch_row)
 
7062
      error= head->file->rnd_pos(head->record[0], last_rowid);
 
7063
  } while (error == HA_ERR_RECORD_DELETED);
 
7064
  return(error);
 
7065
}
 
7066
 
 
7067
 
 
7068
/*
 
7069
  Retrieve next record.
 
7070
  SYNOPSIS
 
7071
    QUICK_ROR_UNION_SELECT::get_next()
 
7072
 
 
7073
  NOTES
 
7074
    Enter/exit invariant:
 
7075
    For each quick select in the queue a {key,rowid} tuple has been
 
7076
    retrieved but the corresponding row hasn't been passed to output.
 
7077
 
 
7078
  RETURN
 
7079
   0     - Ok
 
7080
   other - Error code if any error occurred.
 
7081
*/
 
7082
 
 
7083
int QUICK_ROR_UNION_SELECT::get_next()
 
7084
{
 
7085
  int error, dup_row;
 
7086
  QUICK_SELECT_I *quick;
 
7087
  unsigned char *tmp;
 
7088
 
 
7089
  do
 
7090
  {
 
7091
    do
 
7092
    {
 
7093
      if (queue->empty())
 
7094
        return(HA_ERR_END_OF_FILE);
 
7095
      /* Ok, we have a queue with >= 1 scans */
 
7096
 
 
7097
      quick= queue->top();
 
7098
      memcpy(cur_rowid, quick->last_rowid, rowid_length);
 
7099
 
 
7100
      /* put into queue rowid from the same stream as top element */
 
7101
      if ((error= quick->get_next()))
 
7102
      {
 
7103
        if (error != HA_ERR_END_OF_FILE)
 
7104
          return(error);
 
7105
        queue->pop();
 
7106
      }
 
7107
      else
 
7108
      {
 
7109
        quick->save_last_pos();
 
7110
        queue->pop();
 
7111
        queue->push(quick);
 
7112
      }
 
7113
 
 
7114
      if (!have_prev_rowid)
 
7115
      {
 
7116
        /* No rows have been returned yet */
 
7117
        dup_row= false;
 
7118
        have_prev_rowid= true;
 
7119
      }
 
7120
      else
 
7121
        dup_row= !head->file->cmp_ref(cur_rowid, prev_rowid);
 
7122
    } while (dup_row);
 
7123
 
 
7124
    tmp= cur_rowid;
 
7125
    cur_rowid= prev_rowid;
 
7126
    prev_rowid= tmp;
 
7127
 
 
7128
    error= head->file->rnd_pos(quick->record, prev_rowid);
 
7129
  } while (error == HA_ERR_RECORD_DELETED);
 
7130
  return(error);
 
7131
}
 
7132
 
 
7133
 
 
7134
int QUICK_RANGE_SELECT::reset()
 
7135
{
 
7136
  uint32_t  buf_size;
 
7137
  unsigned char *mrange_buff;
 
7138
  int   error;
 
7139
  HANDLER_BUFFER empty_buf;
 
7140
  last_range= NULL;
 
7141
  cur_range= (QUICK_RANGE**) ranges.buffer;
 
7142
 
 
7143
  if (file->inited == handler::NONE && (error= file->ha_index_init(index,1)))
 
7144
    return(error);
 
7145
 
 
7146
  /* Allocate buffer if we need one but haven't allocated it yet */
 
7147
  if (mrr_buf_size && !mrr_buf_desc)
 
7148
  {
 
7149
    buf_size= mrr_buf_size;
 
7150
    while (buf_size && !my_multi_malloc(MYF(MY_WME),
 
7151
                                        &mrr_buf_desc, sizeof(*mrr_buf_desc),
 
7152
                                        &mrange_buff, buf_size,
 
7153
                                        NULL))
 
7154
    {
 
7155
      /* Try to shrink the buffers until both are 0. */
 
7156
      buf_size/= 2;
 
7157
    }
 
7158
    if (!mrr_buf_desc)
 
7159
      return(HA_ERR_OUT_OF_MEM);
 
7160
 
 
7161
    /* Initialize the handler buffer. */
 
7162
    mrr_buf_desc->buffer= mrange_buff;
 
7163
    mrr_buf_desc->buffer_end= mrange_buff + buf_size;
 
7164
    mrr_buf_desc->end_of_used_area= mrange_buff;
 
7165
  }
 
7166
 
 
7167
  if (!mrr_buf_desc)
 
7168
    empty_buf.buffer= empty_buf.buffer_end= empty_buf.end_of_used_area= NULL;
 
7169
 
 
7170
  if (sorted)
 
7171
     mrr_flags |= HA_MRR_SORTED;
 
7172
  RANGE_SEQ_IF seq_funcs= {quick_range_seq_init, quick_range_seq_next};
 
7173
  error= file->multi_range_read_init(&seq_funcs, (void*)this, ranges.elements,
 
7174
                                     mrr_flags, mrr_buf_desc? mrr_buf_desc:
 
7175
                                                              &empty_buf);
 
7176
  return(error);
 
7177
}
 
7178
 
 
7179
 
 
7180
/*
 
7181
  Range sequence interface implementation for array<QUICK_RANGE>: initialize
4351
7182
 
4352
7183
  SYNOPSIS
4353
7184
    quick_range_seq_init()
4354
 
      init_param  Caller-opaque paramenter: QuickRangeSelect* pointer
 
7185
      init_param  Caller-opaque paramenter: QUICK_RANGE_SELECT* pointer
4355
7186
      n_ranges    Number of ranges in the sequence (ignored)
4356
7187
      flags       MRR flags (currently not used)
4357
7188
 
4359
7190
    Opaque value to be passed to quick_range_seq_next
4360
7191
*/
4361
7192
 
4362
 
range_seq_t optimizer::quick_range_seq_init(void *init_param, uint32_t, uint32_t)
 
7193
range_seq_t quick_range_seq_init(void *init_param, uint32_t, uint32_t)
4363
7194
{
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;
 
7195
  QUICK_RANGE_SELECT *quick= (QUICK_RANGE_SELECT*)init_param;
 
7196
  quick->qr_traversal_ctx.first=  (QUICK_RANGE**)quick->ranges.buffer;
 
7197
  quick->qr_traversal_ctx.cur=    (QUICK_RANGE**)quick->ranges.buffer;
4367
7198
  quick->qr_traversal_ctx.last=   quick->qr_traversal_ctx.cur +
4368
7199
                                  quick->ranges.elements;
4369
7200
  return &quick->qr_traversal_ctx;
4371
7202
 
4372
7203
 
4373
7204
/*
4374
 
  Range sequence interface implementation for array<QuickRange>: get next
 
7205
  Range sequence interface implementation for array<QUICK_RANGE>: get next
4375
7206
 
4376
7207
  SYNOPSIS
4377
7208
    quick_range_seq_next()
4382
7213
    0  Ok
4383
7214
    1  No more ranges in the sequence
4384
7215
*/
4385
 
uint32_t optimizer::quick_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range)
 
7216
 
 
7217
uint32_t quick_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range)
4386
7218
{
4387
 
  QuickRangeSequenceContext *ctx= (QuickRangeSequenceContext*) rseq;
 
7219
  QUICK_RANGE_SEQ_CTX *ctx= (QUICK_RANGE_SEQ_CTX*)rseq;
4388
7220
 
4389
7221
  if (ctx->cur == ctx->last)
4390
7222
    return 1; /* no more ranges */
4391
7223
 
4392
 
  optimizer::QuickRange *cur= *(ctx->cur);
 
7224
  QUICK_RANGE *cur= *(ctx->cur);
4393
7225
  key_range *start_key= &range->start_key;
4394
 
  key_range *end_key= &range->end_key;
 
7226
  key_range *end_key=   &range->end_key;
4395
7227
 
4396
 
  start_key->key= cur->min_key;
 
7228
  start_key->key=    cur->min_key;
4397
7229
  start_key->length= cur->min_length;
4398
7230
  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;
 
7231
  start_key->flag=   ((cur->flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
 
7232
                      (cur->flag & EQ_RANGE) ?
 
7233
                      HA_READ_KEY_EXACT : HA_READ_KEY_OR_NEXT);
 
7234
  end_key->key=      cur->max_key;
 
7235
  end_key->length=   cur->max_length;
4404
7236
  end_key->keypart_map= cur->max_keypart_map;
4405
7237
  /*
4406
7238
    We use HA_READ_AFTER_KEY here because if we are reading on a key
4407
7239
    prefix. We want to find all keys with this prefix.
4408
7240
  */
4409
 
  end_key->flag= (cur->flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
4410
 
                                         HA_READ_AFTER_KEY);
 
7241
  end_key->flag=     (cur->flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
 
7242
                      HA_READ_AFTER_KEY);
4411
7243
  range->range_flag= cur->flag;
4412
7244
  ctx->cur++;
4413
7245
  return 0;
4414
7246
}
4415
7247
 
4416
7248
 
 
7249
/*
 
7250
  Get next possible record using quick-struct.
 
7251
 
 
7252
  SYNOPSIS
 
7253
    QUICK_RANGE_SELECT::get_next()
 
7254
 
 
7255
  NOTES
 
7256
    Record is read into table->record[0]
 
7257
 
 
7258
  RETURN
 
7259
    0                   Found row
 
7260
    HA_ERR_END_OF_FILE  No (more) rows in range
 
7261
    #                   Error code
 
7262
*/
 
7263
 
 
7264
int QUICK_RANGE_SELECT::get_next()
 
7265
{
 
7266
  char *dummy;
 
7267
  if (in_ror_merged_scan)
 
7268
  {
 
7269
    /*
 
7270
      We don't need to signal the bitmap change as the bitmap is always the
 
7271
      same for this head->file
 
7272
    */
 
7273
    head->column_bitmaps_set(&column_bitmap, &column_bitmap);
 
7274
  }
 
7275
 
 
7276
  int result= file->multi_range_read_next(&dummy);
 
7277
 
 
7278
  if (in_ror_merged_scan)
 
7279
  {
 
7280
    /* Restore bitmaps set on entry */
 
7281
    head->column_bitmaps_set(save_read_set, save_write_set);
 
7282
  }
 
7283
  return result;
 
7284
}
 
7285
 
 
7286
 
 
7287
/*
 
7288
  Get the next record with a different prefix.
 
7289
 
 
7290
  SYNOPSIS
 
7291
    QUICK_RANGE_SELECT::get_next_prefix()
 
7292
    prefix_length  length of cur_prefix
 
7293
    cur_prefix     prefix of a key to be searched for
 
7294
 
 
7295
  DESCRIPTION
 
7296
    Each subsequent call to the method retrieves the first record that has a
 
7297
    prefix with length prefix_length different from cur_prefix, such that the
 
7298
    record with the new prefix is within the ranges described by
 
7299
    this->ranges. The record found is stored into the buffer pointed by
 
7300
    this->record.
 
7301
    The method is useful for GROUP-BY queries with range conditions to
 
7302
    discover the prefix of the next group that satisfies the range conditions.
 
7303
 
 
7304
  TODO
 
7305
    This method is a modified copy of QUICK_RANGE_SELECT::get_next(), so both
 
7306
    methods should be unified into a more general one to reduce code
 
7307
    duplication.
 
7308
 
 
7309
  RETURN
 
7310
    0                  on success
 
7311
    HA_ERR_END_OF_FILE if returned all keys
 
7312
    other              if some error occurred
 
7313
*/
 
7314
 
 
7315
int QUICK_RANGE_SELECT::get_next_prefix(uint32_t prefix_length,
 
7316
                                        key_part_map keypart_map,
 
7317
                                        unsigned char *cur_prefix)
 
7318
{
 
7319
  for (;;)
 
7320
  {
 
7321
    int result;
 
7322
    key_range start_key, end_key;
 
7323
    if (last_range)
 
7324
    {
 
7325
      /* Read the next record in the same range with prefix after cur_prefix. */
 
7326
      assert(cur_prefix != 0);
 
7327
      result= file->index_read_map(record, cur_prefix, keypart_map,
 
7328
                                   HA_READ_AFTER_KEY);
 
7329
      if (result || (file->compare_key(file->end_range) <= 0))
 
7330
        return result;
 
7331
    }
 
7332
 
 
7333
    uint32_t count= ranges.elements - (cur_range - (QUICK_RANGE**) ranges.buffer);
 
7334
    if (count == 0)
 
7335
    {
 
7336
      /* Ranges have already been used up before. None is left for read. */
 
7337
      last_range= 0;
 
7338
      return HA_ERR_END_OF_FILE;
 
7339
    }
 
7340
    last_range= *(cur_range++);
 
7341
 
 
7342
    start_key.key=    (const unsigned char*) last_range->min_key;
 
7343
    start_key.length= min(last_range->min_length, (uint16_t)prefix_length);
 
7344
    start_key.keypart_map= last_range->min_keypart_map & keypart_map;
 
7345
    start_key.flag=   ((last_range->flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
 
7346
                       (last_range->flag & EQ_RANGE) ?
 
7347
                       HA_READ_KEY_EXACT : HA_READ_KEY_OR_NEXT);
 
7348
    end_key.key=      (const unsigned char*) last_range->max_key;
 
7349
    end_key.length=   min(last_range->max_length, (uint16_t)prefix_length);
 
7350
    end_key.keypart_map= last_range->max_keypart_map & keypart_map;
 
7351
    /*
 
7352
      We use READ_AFTER_KEY here because if we are reading on a key
 
7353
      prefix we want to find all keys with this prefix
 
7354
    */
 
7355
    end_key.flag=     (last_range->flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
 
7356
                       HA_READ_AFTER_KEY);
 
7357
 
 
7358
    result= file->read_range_first(last_range->min_keypart_map ? &start_key : 0,
 
7359
                                   last_range->max_keypart_map ? &end_key : 0,
 
7360
                                   test(last_range->flag & EQ_RANGE),
 
7361
                                   sorted);
 
7362
    if (last_range->flag == (UNIQUE_RANGE | EQ_RANGE))
 
7363
      last_range= 0;                    // Stop searching
 
7364
 
 
7365
    if (result != HA_ERR_END_OF_FILE)
 
7366
      return result;
 
7367
    last_range= 0;                      // No matching rows; go to next range
 
7368
  }
 
7369
}
 
7370
 
 
7371
 
 
7372
/*
 
7373
  Check if current row will be retrieved by this QUICK_RANGE_SELECT
 
7374
 
 
7375
  NOTES
 
7376
    It is assumed that currently a scan is being done on another index
 
7377
    which reads all necessary parts of the index that is scanned by this
 
7378
    quick select.
 
7379
    The implementation does a binary search on sorted array of disjoint
 
7380
    ranges, without taking size of range into account.
 
7381
 
 
7382
    This function is used to filter out clustered PK scan rows in
 
7383
    index_merge quick select.
 
7384
 
 
7385
  RETURN
 
7386
    true  if current row will be retrieved by this quick select
 
7387
    false if not
 
7388
*/
 
7389
 
 
7390
bool QUICK_RANGE_SELECT::row_in_ranges()
 
7391
{
 
7392
  QUICK_RANGE *res;
 
7393
  uint32_t min= 0;
 
7394
  uint32_t max= ranges.elements - 1;
 
7395
  uint32_t mid= (max + min)/2;
 
7396
 
 
7397
  while (min != max)
 
7398
  {
 
7399
    if (cmp_next(*(QUICK_RANGE**)dynamic_array_ptr(&ranges, mid)))
 
7400
    {
 
7401
      /* current row value > mid->max */
 
7402
      min= mid + 1;
 
7403
    }
 
7404
    else
 
7405
      max= mid;
 
7406
    mid= (min + max) / 2;
 
7407
  }
 
7408
  res= *(QUICK_RANGE**)dynamic_array_ptr(&ranges, mid);
 
7409
  return (!cmp_next(res) && !cmp_prev(res));
 
7410
}
 
7411
 
 
7412
/*
 
7413
  This is a hack: we inherit from QUICK_SELECT so that we can use the
 
7414
  get_next() interface, but we have to hold a pointer to the original
 
7415
  QUICK_SELECT because its data are used all over the place.  What
 
7416
  should be done is to factor out the data that is needed into a base
 
7417
  class (QUICK_SELECT), and then have two subclasses (_ASC and _DESC)
 
7418
  which handle the ranges and implement the get_next() function.  But
 
7419
  for now, this seems to work right at least.
 
7420
 */
 
7421
 
 
7422
QUICK_SELECT_DESC::QUICK_SELECT_DESC(QUICK_RANGE_SELECT *q, uint32_t, bool *)
 
7423
 :QUICK_RANGE_SELECT(*q), rev_it(rev_ranges)
 
7424
{
 
7425
  QUICK_RANGE *r;
 
7426
 
 
7427
  QUICK_RANGE **pr= (QUICK_RANGE**)ranges.buffer;
 
7428
  QUICK_RANGE **end_range= pr + ranges.elements;
 
7429
  for (; pr!=end_range; pr++)
 
7430
    rev_ranges.push_front(*pr);
 
7431
 
 
7432
  /* Remove EQ_RANGE flag for keys that are not using the full key */
 
7433
  for (r = rev_it++; r; r = rev_it++)
 
7434
  {
 
7435
    if ((r->flag & EQ_RANGE) &&
 
7436
        head->key_info[index].key_length != r->max_length)
 
7437
      r->flag&= ~EQ_RANGE;
 
7438
  }
 
7439
  rev_it.rewind();
 
7440
  q->dont_free=1;                               // Don't free shared mem
 
7441
  delete q;
 
7442
}
 
7443
 
 
7444
 
 
7445
int QUICK_SELECT_DESC::get_next()
 
7446
{
 
7447
  /* The max key is handled as follows:
 
7448
   *   - if there is NO_MAX_RANGE, start at the end and move backwards
 
7449
   *   - if it is an EQ_RANGE, which means that max key covers the entire
 
7450
   *     key, go directly to the key and read through it (sorting backwards is
 
7451
   *     same as sorting forwards)
 
7452
   *   - if it is NEAR_MAX, go to the key or next, step back once, and
 
7453
   *     move backwards
 
7454
   *   - otherwise (not NEAR_MAX == include the key), go after the key,
 
7455
   *     step back once, and move backwards
 
7456
   */
 
7457
 
 
7458
  for (;;)
 
7459
  {
 
7460
    int result;
 
7461
    if (last_range)
 
7462
    {                                           // Already read through key
 
7463
      result = ((last_range->flag & EQ_RANGE)
 
7464
                ? file->index_next_same(record, last_range->min_key,
 
7465
                                        last_range->min_length) :
 
7466
                file->index_prev(record));
 
7467
      if (!result)
 
7468
      {
 
7469
        if (cmp_prev(*rev_it.ref()) == 0)
 
7470
          return 0;
 
7471
      }
 
7472
      else if (result != HA_ERR_END_OF_FILE)
 
7473
        return result;
 
7474
    }
 
7475
 
 
7476
    if (!(last_range= rev_it++))
 
7477
      return HA_ERR_END_OF_FILE;                // All ranges used
 
7478
 
 
7479
    if (last_range->flag & NO_MAX_RANGE)        // Read last record
 
7480
    {
 
7481
      int local_error;
 
7482
      if ((local_error=file->index_last(record)))
 
7483
        return(local_error);            // Empty table
 
7484
      if (cmp_prev(last_range) == 0)
 
7485
        return 0;
 
7486
      last_range= 0;                            // No match; go to next range
 
7487
      continue;
 
7488
    }
 
7489
 
 
7490
    if (last_range->flag & EQ_RANGE)
 
7491
    {
 
7492
      result = file->index_read_map(record, last_range->max_key,
 
7493
                                    last_range->max_keypart_map,
 
7494
                                    HA_READ_KEY_EXACT);
 
7495
    }
 
7496
    else
 
7497
    {
 
7498
      assert(last_range->flag & NEAR_MAX ||
 
7499
                  range_reads_after_key(last_range));
 
7500
      result=file->index_read_map(record, last_range->max_key,
 
7501
                                  last_range->max_keypart_map,
 
7502
                                  ((last_range->flag & NEAR_MAX) ?
 
7503
                                   HA_READ_BEFORE_KEY :
 
7504
                                   HA_READ_PREFIX_LAST_OR_PREV));
 
7505
    }
 
7506
    if (result)
 
7507
    {
 
7508
      if (result != HA_ERR_KEY_NOT_FOUND && result != HA_ERR_END_OF_FILE)
 
7509
        return result;
 
7510
      last_range= 0;                            // Not found, to next range
 
7511
      continue;
 
7512
    }
 
7513
    if (cmp_prev(last_range) == 0)
 
7514
    {
 
7515
      if (last_range->flag == (UNIQUE_RANGE | EQ_RANGE))
 
7516
        last_range= 0;                          // Stop searching
 
7517
      return 0;                         // Found key is in range
 
7518
    }
 
7519
    last_range= 0;                              // To next range
 
7520
  }
 
7521
}
 
7522
 
 
7523
 
 
7524
/*
 
7525
  Compare if found key is over max-value
 
7526
  Returns 0 if key <= range->max_key
 
7527
  TODO: Figure out why can't this function be as simple as cmp_prev().
 
7528
*/
 
7529
 
 
7530
int QUICK_RANGE_SELECT::cmp_next(QUICK_RANGE *range_arg)
 
7531
{
 
7532
  if (range_arg->flag & NO_MAX_RANGE)
 
7533
    return 0;                                   /* key can't be to large */
 
7534
 
 
7535
  KEY_PART *key_part=key_parts;
 
7536
  uint32_t store_length;
 
7537
 
 
7538
  for (unsigned char *key=range_arg->max_key, *end=key+range_arg->max_length;
 
7539
       key < end;
 
7540
       key+= store_length, key_part++)
 
7541
  {
 
7542
    int cmp;
 
7543
    store_length= key_part->store_length;
 
7544
    if (key_part->null_bit)
 
7545
    {
 
7546
      if (*key)
 
7547
      {
 
7548
        if (!key_part->field->is_null())
 
7549
          return 1;
 
7550
        continue;
 
7551
      }
 
7552
      else if (key_part->field->is_null())
 
7553
        return 0;
 
7554
      key++;                                    // Skip null byte
 
7555
      store_length--;
 
7556
    }
 
7557
    if ((cmp=key_part->field->key_cmp(key, key_part->length)) < 0)
 
7558
      return 0;
 
7559
    if (cmp > 0)
 
7560
      return 1;
 
7561
  }
 
7562
  return (range_arg->flag & NEAR_MAX) ? 1 : 0;          // Exact match
 
7563
}
 
7564
 
 
7565
 
 
7566
/*
 
7567
  Returns 0 if found key is inside range (found key >= range->min_key).
 
7568
*/
 
7569
 
 
7570
int QUICK_RANGE_SELECT::cmp_prev(QUICK_RANGE *range_arg)
 
7571
{
 
7572
  int cmp;
 
7573
  if (range_arg->flag & NO_MIN_RANGE)
 
7574
    return 0;                                   /* key can't be to small */
 
7575
 
 
7576
  cmp= key_cmp(key_part_info, range_arg->min_key,
 
7577
               range_arg->min_length);
 
7578
  if (cmp > 0 || (cmp == 0 && (range_arg->flag & NEAR_MIN) == false))
 
7579
    return 0;
 
7580
  return 1;                                     // outside of range
 
7581
}
 
7582
 
 
7583
 
 
7584
/*
 
7585
 * true if this range will require using HA_READ_AFTER_KEY
 
7586
   See comment in get_next() about this
 
7587
 */
 
7588
 
 
7589
bool QUICK_SELECT_DESC::range_reads_after_key(QUICK_RANGE *range_arg)
 
7590
{
 
7591
  return ((range_arg->flag & (NO_MAX_RANGE | NEAR_MAX)) ||
 
7592
          !(range_arg->flag & EQ_RANGE) ||
 
7593
          head->key_info[index].key_length != range_arg->max_length) ? 1 : 0;
 
7594
}
 
7595
 
 
7596
 
 
7597
void QUICK_RANGE_SELECT::add_info_string(String *str)
 
7598
{
 
7599
  KEY *key_info= head->key_info + index;
 
7600
  str->append(key_info->name);
 
7601
}
 
7602
 
 
7603
void QUICK_INDEX_MERGE_SELECT::add_info_string(String *str)
 
7604
{
 
7605
  QUICK_RANGE_SELECT *quick;
 
7606
  bool first= true;
 
7607
  List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
 
7608
  str->append(STRING_WITH_LEN("sort_union("));
 
7609
  while ((quick= it++))
 
7610
  {
 
7611
    if (!first)
 
7612
      str->append(',');
 
7613
    else
 
7614
      first= false;
 
7615
    quick->add_info_string(str);
 
7616
  }
 
7617
  if (pk_quick_select)
 
7618
  {
 
7619
    str->append(',');
 
7620
    pk_quick_select->add_info_string(str);
 
7621
  }
 
7622
  str->append(')');
 
7623
}
 
7624
 
 
7625
void QUICK_ROR_INTERSECT_SELECT::add_info_string(String *str)
 
7626
{
 
7627
  bool first= true;
 
7628
  QUICK_RANGE_SELECT *quick;
 
7629
  List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
 
7630
  str->append(STRING_WITH_LEN("intersect("));
 
7631
  while ((quick= it++))
 
7632
  {
 
7633
    KEY *key_info= head->key_info + quick->index;
 
7634
    if (!first)
 
7635
      str->append(',');
 
7636
    else
 
7637
      first= false;
 
7638
    str->append(key_info->name);
 
7639
  }
 
7640
  if (cpk_quick)
 
7641
  {
 
7642
    KEY *key_info= head->key_info + cpk_quick->index;
 
7643
    str->append(',');
 
7644
    str->append(key_info->name);
 
7645
  }
 
7646
  str->append(')');
 
7647
}
 
7648
 
 
7649
void QUICK_ROR_UNION_SELECT::add_info_string(String *str)
 
7650
{
 
7651
  bool first= true;
 
7652
  QUICK_SELECT_I *quick;
 
7653
  List_iterator_fast<QUICK_SELECT_I> it(quick_selects);
 
7654
  str->append(STRING_WITH_LEN("union("));
 
7655
  while ((quick= it++))
 
7656
  {
 
7657
    if (!first)
 
7658
      str->append(',');
 
7659
    else
 
7660
      first= false;
 
7661
    quick->add_info_string(str);
 
7662
  }
 
7663
  str->append(')');
 
7664
}
 
7665
 
 
7666
 
 
7667
void QUICK_RANGE_SELECT::add_keys_and_lengths(String *key_names,
 
7668
                                              String *used_lengths)
 
7669
{
 
7670
  char buf[64];
 
7671
  uint32_t length;
 
7672
  KEY *key_info= head->key_info + index;
 
7673
  key_names->append(key_info->name);
 
7674
  length= int64_t2str(max_used_key_length, buf, 10) - buf;
 
7675
  used_lengths->append(buf, length);
 
7676
}
 
7677
 
 
7678
void QUICK_INDEX_MERGE_SELECT::add_keys_and_lengths(String *key_names,
 
7679
                                                    String *used_lengths)
 
7680
{
 
7681
  char buf[64];
 
7682
  uint32_t length;
 
7683
  bool first= true;
 
7684
  QUICK_RANGE_SELECT *quick;
 
7685
 
 
7686
  List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
 
7687
  while ((quick= it++))
 
7688
  {
 
7689
    if (first)
 
7690
      first= false;
 
7691
    else
 
7692
    {
 
7693
      key_names->append(',');
 
7694
      used_lengths->append(',');
 
7695
    }
 
7696
 
 
7697
    KEY *key_info= head->key_info + quick->index;
 
7698
    key_names->append(key_info->name);
 
7699
    length= int64_t2str(quick->max_used_key_length, buf, 10) - buf;
 
7700
    used_lengths->append(buf, length);
 
7701
  }
 
7702
  if (pk_quick_select)
 
7703
  {
 
7704
    KEY *key_info= head->key_info + pk_quick_select->index;
 
7705
    key_names->append(',');
 
7706
    key_names->append(key_info->name);
 
7707
    length= int64_t2str(pk_quick_select->max_used_key_length, buf, 10) - buf;
 
7708
    used_lengths->append(',');
 
7709
    used_lengths->append(buf, length);
 
7710
  }
 
7711
}
 
7712
 
 
7713
void QUICK_ROR_INTERSECT_SELECT::add_keys_and_lengths(String *key_names,
 
7714
                                                      String *used_lengths)
 
7715
{
 
7716
  char buf[64];
 
7717
  uint32_t length;
 
7718
  bool first= true;
 
7719
  QUICK_RANGE_SELECT *quick;
 
7720
  List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
 
7721
  while ((quick= it++))
 
7722
  {
 
7723
    KEY *key_info= head->key_info + quick->index;
 
7724
    if (first)
 
7725
      first= false;
 
7726
    else
 
7727
    {
 
7728
      key_names->append(',');
 
7729
      used_lengths->append(',');
 
7730
    }
 
7731
    key_names->append(key_info->name);
 
7732
    length= int64_t2str(quick->max_used_key_length, buf, 10) - buf;
 
7733
    used_lengths->append(buf, length);
 
7734
  }
 
7735
 
 
7736
  if (cpk_quick)
 
7737
  {
 
7738
    KEY *key_info= head->key_info + cpk_quick->index;
 
7739
    key_names->append(',');
 
7740
    key_names->append(key_info->name);
 
7741
    length= int64_t2str(cpk_quick->max_used_key_length, buf, 10) - buf;
 
7742
    used_lengths->append(',');
 
7743
    used_lengths->append(buf, length);
 
7744
  }
 
7745
}
 
7746
 
 
7747
void QUICK_ROR_UNION_SELECT::add_keys_and_lengths(String *key_names,
 
7748
                                                  String *used_lengths)
 
7749
{
 
7750
  bool first= true;
 
7751
  QUICK_SELECT_I *quick;
 
7752
  List_iterator_fast<QUICK_SELECT_I> it(quick_selects);
 
7753
  while ((quick= it++))
 
7754
  {
 
7755
    if (first)
 
7756
      first= false;
 
7757
    else
 
7758
    {
 
7759
      used_lengths->append(',');
 
7760
      key_names->append(',');
 
7761
    }
 
7762
    quick->add_keys_and_lengths(key_names, used_lengths);
 
7763
  }
 
7764
}
 
7765
 
 
7766
 
 
7767
/*******************************************************************************
 
7768
* Implementation of QUICK_GROUP_MIN_MAX_SELECT
 
7769
*******************************************************************************/
 
7770
 
4417
7771
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
 
 
 
7772
static inline SEL_ARG * get_index_range_tree(uint32_t index, SEL_TREE* range_tree,
 
7773
                                             PARAM *param, uint32_t *param_idx);
 
7774
static bool get_constant_key_infix(KEY *index_info, SEL_ARG *index_range_tree,
 
7775
                       KEY_PART_INFO *first_non_group_part,
 
7776
                       KEY_PART_INFO *min_max_arg_part,
 
7777
                       KEY_PART_INFO *last_part, Session *session,
 
7778
                       unsigned char *key_infix, uint32_t *key_infix_len,
 
7779
                       KEY_PART_INFO **first_non_infix_part);
4434
7780
static bool check_group_min_max_predicates(COND *cond, Item_field *min_max_arg_item);
4435
7781
 
4436
7782
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);
 
7783
cost_group_min_max(Table* table, KEY *index_info, uint32_t used_key_parts,
 
7784
                   uint32_t group_key_parts, SEL_TREE *range_tree,
 
7785
                   SEL_ARG *index_tree, ha_rows quick_prefix_records,
 
7786
                   bool have_min, bool have_max,
 
7787
                   double *read_cost, ha_rows *records);
4448
7788
 
4449
7789
 
4450
7790
/*
4457
7797
    sel_tree Range tree generated by get_mm_tree
4458
7798
 
4459
7799
  DESCRIPTION
4460
 
    Test whether a query can be computed via a QuickGroupMinMaxSelect.
4461
 
    Queries computable via a QuickGroupMinMaxSelect must satisfy the
 
7800
    Test whether a query can be computed via a QUICK_GROUP_MIN_MAX_SELECT.
 
7801
    Queries computable via a QUICK_GROUP_MIN_MAX_SELECT must satisfy the
4462
7802
    following conditions:
4463
7803
    A) Table T has at least one compound index I of the form:
4464
7804
       I = <A_1, ...,A_k, [B_1,..., B_m], C, [D_1,...,D_n]>
4542
7882
  NOTES
4543
7883
    If the current query satisfies the conditions above, and if
4544
7884
    (mem_root! = NULL), then the function constructs and returns a new TRP
4545
 
    object, that is later used to construct a new QuickGroupMinMaxSelect.
 
7885
    object, that is later used to construct a new QUICK_GROUP_MIN_MAX_SELECT.
4546
7886
    If (mem_root == NULL), then the function only tests whether the current
4547
7887
    query satisfies the conditions above, and, if so, sets
4548
7888
    is_applicable = true.
4568
7908
 
4569
7909
  RETURN
4570
7910
    If mem_root != NULL
4571
 
    - valid GroupMinMaxReadPlan object if this QUICK class can be used for
 
7911
    - valid TRP_GROUP_MIN_MAX object if this QUICK class can be used for
4572
7912
      the query
4573
7913
    -  NULL o/w.
4574
7914
    If mem_root == NULL
4575
7915
    - NULL
4576
7916
*/
4577
 
static optimizer::GroupMinMaxReadPlan *
4578
 
get_best_group_min_max(optimizer::Parameter *param, optimizer::SEL_TREE *tree)
 
7917
 
 
7918
static TRP_GROUP_MIN_MAX *
 
7919
get_best_group_min_max(PARAM *param, SEL_TREE *tree)
4579
7920
{
4580
7921
  Session *session= param->session;
4581
7922
  JOIN *join= session->lex->current_select->join;
4591
7932
  uint32_t used_key_parts= 0;   /* Number of index key parts used for access. */
4592
7933
  unsigned char key_infix[MAX_KEY_LENGTH]; /* Constants from equality predicates.*/
4593
7934
  uint32_t key_infix_len= 0;          /* Length of key_infix. */
4594
 
  optimizer::GroupMinMaxReadPlan *read_plan= NULL; /* The eventually constructed TRP. */
 
7935
  TRP_GROUP_MIN_MAX *read_plan= NULL; /* The eventually constructed TRP. */
4595
7936
  uint32_t key_part_nr;
4596
 
  order_st *tmp_group= NULL;
4597
 
  Item *item= NULL;
4598
 
  Item_field *item_field= NULL;
 
7937
  order_st *tmp_group;
 
7938
  Item *item;
 
7939
  Item_field *item_field;
4599
7940
 
4600
7941
  /* Perform few 'cheap' tests whether this access method is applicable. */
4601
 
  if (! join)
 
7942
  if (!join)
4602
7943
    return NULL;        /* This is not a select statement. */
4603
 
 
4604
7944
  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)) ||
 
7945
      ((!join->group_list) && /* Neither GROUP BY nor a DISTINCT query. */
 
7946
       (!join->select_distinct)) ||
4607
7947
      (join->select_lex->olap == ROLLUP_TYPE)) /* Check (B3) for ROLLUP */
4608
7948
    return NULL;
4609
7949
  if (table->s->keys == 0)        /* There are no indexes to use. */
4615
7955
  /* Check (SA1,SA4) and store the only MIN/MAX argument - the C attribute.*/
4616
7956
  if (join->make_sum_func_list(join->all_fields, join->fields_list, 1))
4617
7957
    return NULL;
4618
 
 
4619
7958
  if (join->sum_funcs[0])
4620
7959
  {
4621
 
    Item_sum *min_max_item= NULL;
 
7960
    Item_sum *min_max_item;
4622
7961
    Item_sum **func_ptr= join->sum_funcs;
4623
7962
    while ((min_max_item= *(func_ptr++)))
4624
7963
    {
4668
8007
  KEY *cur_index_info= table->key_info;
4669
8008
  KEY *cur_index_info_end= cur_index_info + table->s->keys;
4670
8009
  KEY_PART_INFO *cur_part= NULL;
4671
 
  KEY_PART_INFO *end_part= NULL; /* Last part for loops. */
 
8010
  KEY_PART_INFO *end_part; /* Last part for loops. */
4672
8011
  /* Last index part. */
4673
8012
  KEY_PART_INFO *last_part= NULL;
4674
8013
  KEY_PART_INFO *first_non_group_part= NULL;
4679
8018
  /* Cost-related variables for the best index so far. */
4680
8019
  double best_read_cost= DBL_MAX;
4681
8020
  ha_rows best_records= 0;
4682
 
  optimizer::SEL_ARG *best_index_tree= NULL;
 
8021
  SEL_ARG *best_index_tree= NULL;
4683
8022
  ha_rows best_quick_prefix_records= 0;
4684
8023
  uint32_t best_param_idx= 0;
4685
8024
  double cur_read_cost= DBL_MAX;
4686
8025
  ha_rows cur_records;
4687
 
  optimizer::SEL_ARG *cur_index_tree= NULL;
 
8026
  SEL_ARG *cur_index_tree= NULL;
4688
8027
  ha_rows cur_quick_prefix_records= 0;
4689
 
  uint32_t cur_param_idx= MAX_KEY;
 
8028
  uint32_t cur_param_idx=MAX_KEY;
4690
8029
  key_map used_key_parts_map;
4691
8030
  uint32_t cur_key_infix_len= 0;
4692
8031
  unsigned char cur_key_infix[MAX_KEY_LENGTH];
4693
8032
  uint32_t cur_used_key_parts= 0;
4694
8033
  uint32_t pk= param->table->s->primary_key;
4695
8034
 
4696
 
  for (uint32_t cur_index= 0;
4697
 
       cur_index_info != cur_index_info_end;
 
8035
  for (uint32_t cur_index= 0 ; cur_index_info != cur_index_info_end ;
4698
8036
       cur_index_info++, cur_index++)
4699
8037
  {
4700
8038
    /* Check (B1) - if current index is covering. */
4701
 
    if (! table->covering_keys.test(cur_index))
 
8039
    if (!table->covering_keys.test(cur_index))
4702
8040
      goto next_index;
4703
8041
 
4704
8042
    /*
4711
8049
      we check that all query fields are indeed covered by 'cur_index'.
4712
8050
    */
4713
8051
    if (pk < MAX_KEY && cur_index != pk &&
4714
 
        (table->cursor->getEngine()->check_flag(HTON_BIT_PRIMARY_KEY_IN_READ_INDEX)))
 
8052
        (table->file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX))
4715
8053
    {
4716
8054
      /* For each table field */
4717
8055
      for (uint32_t i= 0; i < table->s->fields; i++)
4722
8060
          part of 'cur_index'
4723
8061
        */
4724
8062
        if ((cur_field->isReadSet()) &&
4725
 
            ! cur_field->part_of_key_not_clustered.test(cur_index))
 
8063
            !cur_field->part_of_key_not_clustered.test(cur_index))
4726
8064
          goto next_index;                  // Field was not part of key
4727
8065
      }
4728
8066
    }
4735
8073
      cur_part= cur_index_info->key_part;
4736
8074
      end_part= cur_part + cur_index_info->key_parts;
4737
8075
      /* 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);
 
8076
      for (tmp_group= join->group_list; tmp_group && (cur_part != end_part);
4740
8077
           tmp_group= tmp_group->next, cur_part++)
4741
8078
      {
4742
8079
        /*
4794
8131
        all_parts have all bits set from 0 to (max_key_part-1).
4795
8132
        cur_parts have bits set for only used keyparts.
4796
8133
      */
4797
 
      key_map all_parts;
4798
 
      key_map cur_parts;
 
8134
      key_map all_parts, cur_parts;
4799
8135
      for (uint32_t pos= 0; pos < max_key_part; pos++)
4800
8136
        all_parts.set(pos);
4801
8137
      cur_parts= used_key_parts_map >> 1;
4839
8175
                             NULL :
4840
8176
                           NULL;
4841
8177
    if (first_non_group_part &&
4842
 
        (! min_max_arg_part || (min_max_arg_part - first_non_group_part > 0)))
 
8178
        (!min_max_arg_part || (min_max_arg_part - first_non_group_part > 0)))
4843
8179
    {
4844
8180
      if (tree)
4845
8181
      {
4846
8182
        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
 
        {
 
8183
        SEL_ARG *index_range_tree= get_index_range_tree(cur_index, tree, param,
 
8184
                                                        &dummy);
 
8185
        if (!get_constant_key_infix(cur_index_info, index_range_tree,
 
8186
                                    first_non_group_part, min_max_arg_part,
 
8187
                                    last_part, session, cur_key_infix, 
 
8188
                                    &cur_key_infix_len,
 
8189
                                    &first_non_infix_part))
4861
8190
          goto next_index;
4862
 
        }
4863
8191
      }
4864
8192
      else if (min_max_arg_part &&
4865
8193
               (min_max_arg_part - first_non_group_part > 0))
4889
8217
        key_part_range[1]= last_part;
4890
8218
 
4891
8219
        /* Check if cur_part is referenced in the WHERE clause. */
4892
 
        if (join->conds->walk(&Item::find_item_in_field_list_processor,
4893
 
                              0,
 
8220
        if (join->conds->walk(&Item::find_item_in_field_list_processor, 0,
4894
8221
                              (unsigned char*) key_part_range))
4895
8222
          goto next_index;
4896
8223
      }
4920
8247
    if (tree)
4921
8248
    {
4922
8249
      /* 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,
 
8250
      cur_index_tree= get_index_range_tree(cur_index, tree, param,
4926
8251
                                           &cur_param_idx);
4927
8252
      /* Check if this range tree can be used for prefix retrieval. */
4928
 
      optimizer::CostVector dummy_cost;
 
8253
      COST_VECT dummy_cost;
4929
8254
      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,
 
8255
      uint32_t mrr_bufsize=0;
 
8256
      cur_quick_prefix_records= check_quick_select(param, cur_param_idx,
4933
8257
                                                   false /*don't care*/,
4934
 
                                                   cur_index_tree,
4935
 
                                                   true,
4936
 
                                                   &mrr_flags,
4937
 
                                                   &mrr_bufsize,
 
8258
                                                   cur_index_tree, true,
 
8259
                                                   &mrr_flags, &mrr_bufsize,
4938
8260
                                                   &dummy_cost);
4939
8261
    }
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);
 
8262
    cost_group_min_max(table, cur_index_info, cur_used_key_parts,
 
8263
                       cur_group_key_parts, tree, cur_index_tree,
 
8264
                       cur_quick_prefix_records, have_min, have_max,
 
8265
                       &cur_read_cost, &cur_records);
4951
8266
    /*
4952
8267
      If cur_read_cost is lower than best_read_cost use cur_index.
4953
8268
      Do not compare doubles directly because they may have different
4966
8281
      group_key_parts= cur_group_key_parts;
4967
8282
      group_prefix_len= cur_group_prefix_len;
4968
8283
      key_infix_len= cur_key_infix_len;
4969
 
 
4970
8284
      if (key_infix_len)
4971
 
      {
4972
 
        memcpy(key_infix, cur_key_infix, sizeof (key_infix));
4973
 
      }
4974
 
 
 
8285
        memcpy (key_infix, cur_key_infix, sizeof (key_infix));
4975
8286
      used_key_parts= cur_used_key_parts;
4976
8287
    }
4977
8288
 
4980
8291
    cur_group_prefix_len= 0;
4981
8292
    cur_key_infix_len= 0;
4982
8293
  }
4983
 
  if (! index_info) /* No usable index found. */
 
8294
  if (!index_info) /* No usable index found. */
4984
8295
    return NULL;
4985
8296
 
4986
8297
  /* Check (SA3) for the where clause. */
4989
8300
    return NULL;
4990
8301
 
4991
8302
  /* 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);
 
8303
  read_plan= new (param->mem_root)
 
8304
                 TRP_GROUP_MIN_MAX(have_min, have_max, min_max_arg_part,
 
8305
                                   group_prefix_len, used_key_parts,
 
8306
                                   group_key_parts, index_info, index,
 
8307
                                   key_infix_len,
 
8308
                                   (key_infix_len > 0) ? key_infix : NULL,
 
8309
                                   tree, best_index_tree, best_param_idx,
 
8310
                                   best_quick_prefix_records);
5007
8311
  if (read_plan)
5008
8312
  {
5009
8313
    if (tree && read_plan->quick_prefix_records == 0)
5010
8314
      return NULL;
5011
8315
 
5012
8316
    read_plan->read_cost= best_read_cost;
5013
 
    read_plan->records= best_records;
 
8317
    read_plan->records=   best_records;
5014
8318
  }
5015
8319
 
5016
8320
  return read_plan;
5047
8351
  if (cond_type == Item::COND_ITEM) /* 'AND' or 'OR' */
5048
8352
  {
5049
8353
    List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
5050
 
    Item *and_or_arg= NULL;
 
8354
    Item *and_or_arg;
5051
8355
    while ((and_or_arg= li++))
5052
8356
    {
5053
 
      if (! check_group_min_max_predicates(and_or_arg, min_max_arg_item))
 
8357
      if (!check_group_min_max_predicates(and_or_arg, min_max_arg_item))
5054
8358
        return false;
5055
8359
    }
5056
8360
    return true;
5074
8378
  /* Test if cond references only group-by or non-group fields. */
5075
8379
  Item_func *pred= (Item_func*) cond;
5076
8380
  Item **arguments= pred->arguments();
5077
 
  Item *cur_arg= NULL;
 
8381
  Item *cur_arg;
5078
8382
  for (uint32_t arg_idx= 0; arg_idx < pred->argument_count (); arg_idx++)
5079
8383
  {
5080
8384
    cur_arg= arguments[arg_idx]->real_item();
5102
8406
        /* Check that pred compares min_max_arg_item with a constant. */
5103
8407
        Item *args[3];
5104
8408
        memset(args, 0, 3 * sizeof(Item*));
5105
 
        bool inv= false;
 
8409
        bool inv;
5106
8410
        /* Test if this is a comparison of a field and a constant. */
5107
 
        if (! optimizer::simple_pred(pred, args, inv))
 
8411
        if (!simple_pred(pred, args, &inv))
5108
8412
          return false;
5109
8413
 
5110
8414
        /* Check for compatible string comparisons - similar to get_mm_leaf. */
5123
8427
             */
5124
8428
             (args[1]->result_type() != STRING_RESULT &&
5125
8429
              min_max_arg_item->field->cmp_type() != args[1]->result_type())))
5126
 
        {
5127
8430
          return false;
5128
 
        }
5129
8431
      }
5130
8432
    }
5131
8433
    else if (cur_arg->type() == Item::FUNC_ITEM)
5175
8477
    true  if the index passes the test
5176
8478
    false o/w
5177
8479
*/
 
8480
 
5178
8481
static bool
5179
 
get_constant_key_infix(KEY *,
5180
 
                       optimizer::SEL_ARG *index_range_tree,
 
8482
get_constant_key_infix(KEY *, SEL_ARG *index_range_tree,
5181
8483
                       KEY_PART_INFO *first_non_group_part,
5182
8484
                       KEY_PART_INFO *min_max_arg_part,
5183
8485
                       KEY_PART_INFO *last_part,
5184
 
                       Session *,
5185
 
                       unsigned char *key_infix,
5186
 
                       uint32_t *key_infix_len,
 
8486
                       Session *, unsigned char *key_infix, uint32_t *key_infix_len,
5187
8487
                       KEY_PART_INFO **first_non_infix_part)
5188
8488
{
5189
 
  optimizer::SEL_ARG *cur_range= NULL;
5190
 
  KEY_PART_INFO *cur_part= NULL;
 
8489
  SEL_ARG       *cur_range;
 
8490
  KEY_PART_INFO *cur_part;
5191
8491
  /* End part for the first loop below. */
5192
8492
  KEY_PART_INFO *end_part= min_max_arg_part ? min_max_arg_part : last_part;
5193
8493
 
5205
8505
      if (cur_range->field->eq(cur_part->field))
5206
8506
        break;
5207
8507
    }
5208
 
    if (! cur_range)
 
8508
    if (!cur_range)
5209
8509
    {
5210
8510
      if (min_max_arg_part)
5211
8511
        return false; /* The current keypart has no range predicates at all. */
5221
8521
      return false; /* This is not the only range predicate for the field. */
5222
8522
    if ((cur_range->min_flag & NO_MIN_RANGE) ||
5223
8523
        (cur_range->max_flag & NO_MAX_RANGE) ||
5224
 
        (cur_range->min_flag & NEAR_MIN) ||
5225
 
        (cur_range->max_flag & NEAR_MAX))
 
8524
        (cur_range->min_flag & NEAR_MIN) || (cur_range->max_flag & NEAR_MAX))
5226
8525
      return false;
5227
8526
 
5228
8527
    uint32_t field_length= cur_part->store_length;
5262
8561
    Positive number which is the consecutive number of the key part, or
5263
8562
    0 if field does not reference any index field.
5264
8563
*/
 
8564
 
5265
8565
static inline uint
5266
8566
get_field_keypart(KEY *index, Field *field)
5267
8567
{
5268
 
  KEY_PART_INFO *part= NULL;
5269
 
  KEY_PART_INFO *end= NULL;
 
8568
  KEY_PART_INFO *part, *end;
5270
8569
 
5271
8570
  for (part= index->key_part, end= part + index->key_parts; part < end; part++)
5272
8571
  {
5284
8583
    get_index_range_tree()
5285
8584
    index     [in]  The ID of the index being looked for
5286
8585
    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'
 
8586
    param     [in]  PARAM from SQL_SELECT::test_quick_select
 
8587
    param_idx [out] Index in the array PARAM::key that corresponds to 'index'
5289
8588
 
5290
8589
  DESCRIPTION
5291
8590
 
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
 
8591
    A SEL_TREE contains range trees for all usable indexes. This procedure
 
8592
    finds the SEL_ARG sub-tree for 'index'. The members of a SEL_TREE are
 
8593
    ordered in the same way as the members of PARAM::key, thus we first find
 
8594
    the corresponding index in the array PARAM::key. This index is returned
5296
8595
    through the variable param_idx, to be used later as argument of
5297
8596
    check_quick_select().
5298
8597
 
5299
8598
  RETURN
5300
8599
    Pointer to the SEL_ARG subtree that corresponds to index.
5301
8600
*/
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)
 
8601
 
 
8602
SEL_ARG * get_index_range_tree(uint32_t index, SEL_TREE* range_tree, PARAM *param,
 
8603
                               uint32_t *param_idx)
5306
8604
{
5307
8605
  uint32_t idx= 0; /* Index nr in param->key_parts */
5308
8606
  while (idx < param->keys)
5335
8633
    records             [out] The number of rows retrieved
5336
8634
 
5337
8635
  DESCRIPTION
5338
 
    This method computes the access cost of a GroupMinMaxReadPlan instance and
 
8636
    This method computes the access cost of a TRP_GROUP_MIN_MAX instance and
5339
8637
    the number of rows returned. It updates this->read_cost and this->records.
5340
8638
 
5341
8639
  NOTES
5375
8673
  RETURN
5376
8674
    None
5377
8675
*/
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)
 
8676
 
 
8677
void cost_group_min_max(Table* table, KEY *index_info, uint32_t used_key_parts,
 
8678
                        uint32_t group_key_parts, SEL_TREE *range_tree,
 
8679
                        SEL_ARG *, ha_rows quick_prefix_records,
 
8680
                        bool have_min, bool have_max,
 
8681
                        double *read_cost, ha_rows *records)
5389
8682
{
5390
8683
  ha_rows table_records;
5391
8684
  uint32_t num_groups;
5399
8692
  double io_cost;
5400
8693
  double cpu_cost= 0; /* TODO: CPU cost of index_read calls? */
5401
8694
 
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)
 
8695
  table_records= table->file->stats.records;
 
8696
  keys_per_block= (table->file->stats.block_size / 2 /
 
8697
                   (index_info->key_length + table->file->ref_length)
5405
8698
                        + 1);
5406
 
  num_blocks= (uint32_t) (table_records / keys_per_block) + 1;
 
8699
  num_blocks= (uint32_t)(table_records / keys_per_block) + 1;
5407
8700
 
5408
8701
  /* Compute the number of keys in a group. */
5409
8702
  keys_per_group= index_info->rec_per_key[group_key_parts - 1];
5446
8739
  /*
5447
8740
    TODO: If there is no WHERE clause and no other expressions, there should be
5448
8741
    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().
 
8742
    scan as computed in SQL_SELECT::test_quick_select().
5450
8743
  */
5451
8744
  cpu_cost= (double) num_groups / TIME_FOR_COMPARE;
5452
8745
 
5459
8752
  Construct a new quick select object for queries with group by with min/max.
5460
8753
 
5461
8754
  SYNOPSIS
5462
 
    GroupMinMaxReadPlan::make_quick()
 
8755
    TRP_GROUP_MIN_MAX::make_quick()
5463
8756
    param              Parameter from test_quick_select
5464
8757
    retrieve_full_rows ignored
5465
8758
    parent_alloc       Memory pool to use, if any.
5466
8759
 
5467
8760
  NOTES
5468
8761
    Make_quick ignores the retrieve_full_rows parameter because
5469
 
    QuickGroupMinMaxSelect always performs 'index only' scans.
 
8762
    QUICK_GROUP_MIN_MAX_SELECT always performs 'index only' scans.
5470
8763
    The other parameter are ignored as well because all necessary
5471
8764
    data to create the QUICK object is computed at this TRP creation
5472
8765
    time.
5473
8766
 
5474
8767
  RETURN
5475
 
    New QuickGroupMinMaxSelect object if successfully created,
 
8768
    New QUICK_GROUP_MIN_MAX_SELECT object if successfully created,
5476
8769
    NULL otherwise.
5477
8770
*/
5478
 
optimizer::QuickSelectInterface *
5479
 
optimizer::GroupMinMaxReadPlan::make_quick(optimizer::Parameter *param, bool, memory::Root *parent_alloc)
 
8771
 
 
8772
QUICK_SELECT_I *
 
8773
TRP_GROUP_MIN_MAX::make_quick(PARAM *param, bool, MEM_ROOT *parent_alloc)
5480
8774
{
5481
 
  optimizer::QuickGroupMinMaxSelect *quick= NULL;
 
8775
  QUICK_GROUP_MIN_MAX_SELECT *quick;
5482
8776
 
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
 
  {
 
8777
  quick= new QUICK_GROUP_MIN_MAX_SELECT(param->table,
 
8778
                                        param->session->lex->current_select->join,
 
8779
                                        have_min, have_max, min_max_arg_part,
 
8780
                                        group_prefix_len, group_key_parts,
 
8781
                                        used_key_parts, index_info, index,
 
8782
                                        read_cost, records, key_infix_len,
 
8783
                                        key_infix, parent_alloc);
 
8784
  if (!quick)
5500
8785
    return NULL;
5501
 
  }
5502
8786
 
5503
8787
  if (quick->init())
5504
8788
  {
5510
8794
  {
5511
8795
    assert(quick_prefix_records > 0);
5512
8796
    if (quick_prefix_records == HA_POS_ERROR)
5513
 
    {
5514
8797
      quick->quick_prefix_select= NULL; /* Can't construct a quick select. */
5515
 
    }
5516
8798
    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
 
    }
 
8799
      /* Make a QUICK_RANGE_SELECT to be used for group prefix retrieval. */
 
8800
      quick->quick_prefix_select= get_quick_select(param, param_idx,
 
8801
                                                   index_tree,
 
8802
                                                   HA_MRR_USE_DEFAULT_IMPL, 0,
 
8803
                                                   &quick->alloc);
5526
8804
 
5527
8805
    /*
5528
8806
      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
 
8807
      attribute, and create an array of QUICK_RANGES to be used by the
5530
8808
      new quick select.
5531
8809
    */
5532
8810
    if (min_max_arg_part)
5533
8811
    {
5534
 
      optimizer::SEL_ARG *min_max_range= index_tree;
 
8812
      SEL_ARG *min_max_range= index_tree;
5535
8813
      while (min_max_range) /* Find the tree for the MIN/MAX key part. */
5536
8814
      {
5537
8815
        if (min_max_range->field->eq(min_max_arg_part->field))
5541
8819
      /* Scroll to the leftmost interval for the MIN/MAX argument. */
5542
8820
      while (min_max_range && min_max_range->prev)
5543
8821
        min_max_range= min_max_range->prev;
5544
 
      /* Create an array of QuickRanges for the MIN/MAX argument. */
 
8822
      /* Create an array of QUICK_RANGEs for the MIN/MAX argument. */
5545
8823
      while (min_max_range)
5546
8824
      {
5547
8825
        if (quick->add_range(min_max_range))
5564
8842
}
5565
8843
 
5566
8844
 
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 */
 
8845
/*
 
8846
  Construct new quick select for group queries with min/max.
 
8847
 
 
8848
  SYNOPSIS
 
8849
    QUICK_GROUP_MIN_MAX_SELECT::QUICK_GROUP_MIN_MAX_SELECT()
 
8850
    table             The table being accessed
 
8851
    join              Descriptor of the current query
 
8852
    have_min          true if the query selects a MIN function
 
8853
    have_max          true if the query selects a MAX function
 
8854
    min_max_arg_part  The only argument field of all MIN/MAX functions
 
8855
    group_prefix_len  Length of all key parts in the group prefix
 
8856
    prefix_key_parts  All key parts in the group prefix
 
8857
    index_info        The index chosen for data access
 
8858
    use_index         The id of index_info
 
8859
    read_cost         Cost of this access method
 
8860
    records           Number of records returned
 
8861
    key_infix_len     Length of the key infix appended to the group prefix
 
8862
    key_infix         Infix of constants from equality predicates
 
8863
    parent_alloc      Memory pool for this and quick_prefix_select data
 
8864
 
 
8865
  RETURN
 
8866
    None
 
8867
*/
 
8868
 
 
8869
QUICK_GROUP_MIN_MAX_SELECT::
 
8870
QUICK_GROUP_MIN_MAX_SELECT(Table *table, JOIN *join_arg, bool have_min_arg,
 
8871
                           bool have_max_arg,
 
8872
                           KEY_PART_INFO *min_max_arg_part_arg,
 
8873
                           uint32_t group_prefix_len_arg, uint32_t group_key_parts_arg,
 
8874
                           uint32_t used_key_parts_arg, KEY *index_info_arg,
 
8875
                           uint32_t use_index, double read_cost_arg,
 
8876
                           ha_rows records_arg, uint32_t key_infix_len_arg,
 
8877
                           unsigned char *key_infix_arg, MEM_ROOT *parent_alloc)
 
8878
  :join(join_arg), index_info(index_info_arg),
 
8879
   group_prefix_len(group_prefix_len_arg),
 
8880
   group_key_parts(group_key_parts_arg), have_min(have_min_arg),
 
8881
   have_max(have_max_arg), seen_first_key(false),
 
8882
   min_max_arg_part(min_max_arg_part_arg), key_infix(key_infix_arg),
 
8883
   key_infix_len(key_infix_len_arg), min_functions_it(NULL),
 
8884
   max_functions_it(NULL)
 
8885
{
 
8886
  head=       table;
 
8887
  file=       head->file;
 
8888
  index=      use_index;
 
8889
  record=     head->record[0];
 
8890
  tmp_record= head->record[1];
 
8891
  read_time= read_cost_arg;
 
8892
  records= records_arg;
 
8893
  used_key_parts= used_key_parts_arg;
 
8894
  real_key_parts= used_key_parts_arg;
 
8895
  real_prefix_len= group_prefix_len + key_infix_len;
 
8896
  group_prefix= NULL;
 
8897
  min_max_arg_len= min_max_arg_part ? min_max_arg_part->store_length : 0;
 
8898
 
 
8899
  /*
 
8900
    We can't have parent_alloc set as the init function can't handle this case
 
8901
    yet.
 
8902
  */
 
8903
  assert(!parent_alloc);
 
8904
  if (!parent_alloc)
 
8905
  {
 
8906
    init_sql_alloc(&alloc, join->session->variables.range_alloc_block_size, 0);
 
8907
    join->session->mem_root= &alloc;
 
8908
  }
 
8909
  else
 
8910
    memset(&alloc, 0, sizeof(MEM_ROOT));  // ensure that it's not used
 
8911
}
 
8912
 
 
8913
 
 
8914
/*
 
8915
  Do post-constructor initialization.
 
8916
 
 
8917
  SYNOPSIS
 
8918
    QUICK_GROUP_MIN_MAX_SELECT::init()
 
8919
 
 
8920
  DESCRIPTION
 
8921
    The method performs initialization that cannot be done in the constructor
 
8922
    such as memory allocations that may fail. It allocates memory for the
 
8923
    group prefix and inifix buffers, and for the lists of MIN/MAX item to be
 
8924
    updated during execution.
 
8925
 
 
8926
  RETURN
 
8927
    0      OK
 
8928
    other  Error code
 
8929
*/
 
8930
 
 
8931
int QUICK_GROUP_MIN_MAX_SELECT::init()
 
8932
{
 
8933
  if (group_prefix) /* Already initialized. */
 
8934
    return 0;
 
8935
 
 
8936
  if (!(last_prefix= (unsigned char*) alloc_root(&alloc, group_prefix_len)))
 
8937
      return 1;
 
8938
  /*
 
8939
    We may use group_prefix to store keys with all select fields, so allocate
 
8940
    enough space for it.
 
8941
  */
 
8942
  if (!(group_prefix= (unsigned char*) alloc_root(&alloc,
 
8943
                                         real_prefix_len + min_max_arg_len)))
 
8944
    return 1;
 
8945
 
 
8946
  if (key_infix_len > 0)
 
8947
  {
 
8948
    /*
 
8949
      The memory location pointed to by key_infix will be deleted soon, so
 
8950
      allocate a new buffer and copy the key_infix into it.
 
8951
    */
 
8952
    unsigned char *tmp_key_infix= (unsigned char*) alloc_root(&alloc, key_infix_len);
 
8953
    if (!tmp_key_infix)
 
8954
      return 1;
 
8955
    memcpy(tmp_key_infix, this->key_infix, key_infix_len);
 
8956
    this->key_infix= tmp_key_infix;
 
8957
  }
 
8958
 
 
8959
  if (min_max_arg_part)
 
8960
  {
 
8961
    if (my_init_dynamic_array(&min_max_ranges, sizeof(QUICK_RANGE*), 16, 16))
 
8962
      return 1;
 
8963
 
 
8964
    if (have_min)
 
8965
    {
 
8966
      if (!(min_functions= new List<Item_sum>))
 
8967
        return 1;
 
8968
    }
 
8969
    else
 
8970
      min_functions= NULL;
 
8971
    if (have_max)
 
8972
    {
 
8973
      if (!(max_functions= new List<Item_sum>))
 
8974
        return 1;
 
8975
    }
 
8976
    else
 
8977
      max_functions= NULL;
 
8978
 
 
8979
    Item_sum *min_max_item;
 
8980
    Item_sum **func_ptr= join->sum_funcs;
 
8981
    while ((min_max_item= *(func_ptr++)))
 
8982
    {
 
8983
      if (have_min && (min_max_item->sum_func() == Item_sum::MIN_FUNC))
 
8984
        min_functions->push_back(min_max_item);
 
8985
      else if (have_max && (min_max_item->sum_func() == Item_sum::MAX_FUNC))
 
8986
        max_functions->push_back(min_max_item);
 
8987
    }
 
8988
 
 
8989
    if (have_min)
 
8990
    {
 
8991
      if (!(min_functions_it= new List_iterator<Item_sum>(*min_functions)))
 
8992
        return 1;
 
8993
    }
 
8994
 
 
8995
    if (have_max)
 
8996
    {
 
8997
      if (!(max_functions_it= new List_iterator<Item_sum>(*max_functions)))
 
8998
        return 1;
 
8999
    }
 
9000
  }
 
9001
  else
 
9002
    min_max_ranges.elements= 0;
 
9003
 
 
9004
  return 0;
 
9005
}
 
9006
 
 
9007
 
 
9008
QUICK_GROUP_MIN_MAX_SELECT::~QUICK_GROUP_MIN_MAX_SELECT()
 
9009
{
 
9010
  if (file->inited != handler::NONE)
 
9011
    file->ha_index_end();
 
9012
  if (min_max_arg_part)
 
9013
    delete_dynamic(&min_max_ranges);
 
9014
  free_root(&alloc,MYF(0));
 
9015
  delete min_functions_it;
 
9016
  delete max_functions_it;
 
9017
  delete quick_prefix_select;
 
9018
}
 
9019
 
 
9020
 
 
9021
/*
 
9022
  Eventually create and add a new quick range object.
 
9023
 
 
9024
  SYNOPSIS
 
9025
    QUICK_GROUP_MIN_MAX_SELECT::add_range()
 
9026
    sel_range  Range object from which a
 
9027
 
 
9028
  NOTES
 
9029
    Construct a new QUICK_RANGE object from a SEL_ARG object, and
 
9030
    add it to the array min_max_ranges. If sel_arg is an infinite
 
9031
    range, e.g. (x < 5 or x > 4), then skip it and do not construct
 
9032
    a quick range.
 
9033
 
 
9034
  RETURN
 
9035
    false on success
 
9036
    true  otherwise
 
9037
*/
 
9038
 
 
9039
bool QUICK_GROUP_MIN_MAX_SELECT::add_range(SEL_ARG *sel_range)
 
9040
{
 
9041
  QUICK_RANGE *range;
 
9042
  uint32_t range_flag= sel_range->min_flag | sel_range->max_flag;
 
9043
 
 
9044
  /* Skip (-inf,+inf) ranges, e.g. (x < 5 or x > 4). */
 
9045
  if ((range_flag & NO_MIN_RANGE) && (range_flag & NO_MAX_RANGE))
 
9046
    return false;
 
9047
 
 
9048
  if (!(sel_range->min_flag & NO_MIN_RANGE) &&
 
9049
      !(sel_range->max_flag & NO_MAX_RANGE))
 
9050
  {
 
9051
    if (sel_range->maybe_null &&
 
9052
        sel_range->min_value[0] && sel_range->max_value[0])
 
9053
      range_flag|= NULL_RANGE; /* IS NULL condition */
 
9054
    else if (memcmp(sel_range->min_value, sel_range->max_value,
 
9055
                    min_max_arg_len) == 0)
 
9056
      range_flag|= EQ_RANGE;  /* equality condition */
 
9057
  }
 
9058
  range= new QUICK_RANGE(sel_range->min_value, min_max_arg_len,
 
9059
                         make_keypart_map(sel_range->part),
 
9060
                         sel_range->max_value, min_max_arg_len,
 
9061
                         make_keypart_map(sel_range->part),
 
9062
                         range_flag);
 
9063
  if (!range)
 
9064
    return true;
 
9065
  if (insert_dynamic(&min_max_ranges, (unsigned char*)&range))
 
9066
    return true;
 
9067
  return false;
 
9068
}
 
9069
 
 
9070
 
 
9071
/*
 
9072
  Opens the ranges if there are more conditions in quick_prefix_select than
 
9073
  the ones used for jumping through the prefixes.
 
9074
 
 
9075
  SYNOPSIS
 
9076
    QUICK_GROUP_MIN_MAX_SELECT::adjust_prefix_ranges()
 
9077
 
 
9078
  NOTES
 
9079
    quick_prefix_select is made over the conditions on the whole key.
 
9080
    It defines a number of ranges of length x.
 
9081
    However when jumping through the prefixes we use only the the first
 
9082
    few most significant keyparts in the range key. However if there
 
9083
    are more keyparts to follow the ones we are using we must make the
 
9084
    condition on the key inclusive (because x < "ab" means
 
9085
    x[0] < 'a' OR (x[0] == 'a' AND x[1] < 'b').
 
9086
    To achive the above we must turn off the NEAR_MIN/NEAR_MAX
 
9087
*/
 
9088
void QUICK_GROUP_MIN_MAX_SELECT::adjust_prefix_ranges ()
 
9089
{
 
9090
  if (quick_prefix_select &&
 
9091
      group_prefix_len < quick_prefix_select->max_used_key_length)
 
9092
  {
 
9093
    DYNAMIC_ARRAY *arr;
 
9094
    uint32_t inx;
 
9095
 
 
9096
    for (inx= 0, arr= &quick_prefix_select->ranges; inx < arr->elements; inx++)
 
9097
    {
 
9098
      QUICK_RANGE *range;
 
9099
 
 
9100
      get_dynamic(arr, (unsigned char*)&range, inx);
 
9101
      range->flag &= ~(NEAR_MIN | NEAR_MAX);
 
9102
    }
 
9103
  }
 
9104
}
 
9105
 
 
9106
 
 
9107
/*
 
9108
  Determine the total number and length of the keys that will be used for
 
9109
  index lookup.
 
9110
 
 
9111
  SYNOPSIS
 
9112
    QUICK_GROUP_MIN_MAX_SELECT::update_key_stat()
 
9113
 
 
9114
  DESCRIPTION
 
9115
    The total length of the keys used for index lookup depends on whether
 
9116
    there are any predicates referencing the min/max argument, and/or if
 
9117
    the min/max argument field can be NULL.
 
9118
    This function does an optimistic analysis whether the search key might
 
9119
    be extended by a constant for the min/max keypart. It is 'optimistic'
 
9120
    because during actual execution it may happen that a particular range
 
9121
    is skipped, and then a shorter key will be used. However this is data
 
9122
    dependent and can't be easily estimated here.
 
9123
 
 
9124
  RETURN
 
9125
    None
 
9126
*/
 
9127
 
 
9128
void QUICK_GROUP_MIN_MAX_SELECT::update_key_stat()
 
9129
{
 
9130
  max_used_key_length= real_prefix_len;
 
9131
  if (min_max_ranges.elements > 0)
 
9132
  {
 
9133
    QUICK_RANGE *cur_range;
 
9134
    if (have_min)
 
9135
    { /* Check if the right-most range has a lower boundary. */
 
9136
      get_dynamic(&min_max_ranges, (unsigned char*)&cur_range,
 
9137
                  min_max_ranges.elements - 1);
 
9138
      if (!(cur_range->flag & NO_MIN_RANGE))
 
9139
      {
 
9140
        max_used_key_length+= min_max_arg_len;
 
9141
        used_key_parts++;
 
9142
        return;
 
9143
      }
 
9144
    }
 
9145
    if (have_max)
 
9146
    { /* Check if the left-most range has an upper boundary. */
 
9147
      get_dynamic(&min_max_ranges, (unsigned char*)&cur_range, 0);
 
9148
      if (!(cur_range->flag & NO_MAX_RANGE))
 
9149
      {
 
9150
        max_used_key_length+= min_max_arg_len;
 
9151
        used_key_parts++;
 
9152
        return;
 
9153
      }
 
9154
    }
 
9155
  }
 
9156
  else if (have_min && min_max_arg_part &&
 
9157
           min_max_arg_part->field->real_maybe_null())
 
9158
  {
 
9159
    /*
 
9160
      If a MIN/MAX argument value is NULL, we can quickly determine
 
9161
      that we're in the beginning of the next group, because NULLs
 
9162
      are always < any other value. This allows us to quickly
 
9163
      determine the end of the current group and jump to the next
 
9164
      group (see next_min()) and thus effectively increases the
 
9165
      usable key length.
 
9166
    */
 
9167
    max_used_key_length+= min_max_arg_len;
 
9168
    used_key_parts++;
 
9169
  }
 
9170
}
 
9171
 
 
9172
 
 
9173
/*
 
9174
  Initialize a quick group min/max select for key retrieval.
 
9175
 
 
9176
  SYNOPSIS
 
9177
    QUICK_GROUP_MIN_MAX_SELECT::reset()
 
9178
 
 
9179
  DESCRIPTION
 
9180
    Initialize the index chosen for access and find and store the prefix
 
9181
    of the last group. The method is expensive since it performs disk access.
 
9182
 
 
9183
  RETURN
 
9184
    0      OK
 
9185
    other  Error code
 
9186
*/
 
9187
 
 
9188
int QUICK_GROUP_MIN_MAX_SELECT::reset(void)
 
9189
{
 
9190
  int result;
 
9191
 
 
9192
  file->extra(HA_EXTRA_KEYREAD); /* We need only the key attributes */
 
9193
  if ((result= file->ha_index_init(index,1)))
 
9194
    return result;
 
9195
  if (quick_prefix_select && quick_prefix_select->reset())
 
9196
    return 0;
 
9197
  result= file->index_last(record);
 
9198
  if (result == HA_ERR_END_OF_FILE)
 
9199
    return 0;
 
9200
  /* Save the prefix of the last group. */
 
9201
  key_copy(last_prefix, record, index_info, group_prefix_len);
 
9202
 
 
9203
  return 0;
 
9204
}
 
9205
 
 
9206
 
 
9207
 
 
9208
/*
 
9209
  Get the next key containing the MIN and/or MAX key for the next group.
 
9210
 
 
9211
  SYNOPSIS
 
9212
    QUICK_GROUP_MIN_MAX_SELECT::get_next()
 
9213
 
 
9214
  DESCRIPTION
 
9215
    The method finds the next subsequent group of records that satisfies the
 
9216
    query conditions and finds the keys that contain the MIN/MAX values for
 
9217
    the key part referenced by the MIN/MAX function(s). Once a group and its
 
9218
    MIN/MAX values are found, store these values in the Item_sum objects for
 
9219
    the MIN/MAX functions. The rest of the values in the result row are stored
 
9220
    in the Item_field::result_field of each select field. If the query does
 
9221
    not contain MIN and/or MAX functions, then the function only finds the
 
9222
    group prefix, which is a query answer itself.
 
9223
 
 
9224
  NOTES
 
9225
    If both MIN and MAX are computed, then we use the fact that if there is
 
9226
    no MIN key, there can't be a MAX key as well, so we can skip looking
 
9227
    for a MAX key in this case.
 
9228
 
 
9229
  RETURN
 
9230
    0                  on success
 
9231
    HA_ERR_END_OF_FILE if returned all keys
 
9232
    other              if some error occurred
 
9233
*/
 
9234
 
 
9235
int QUICK_GROUP_MIN_MAX_SELECT::get_next()
 
9236
{
 
9237
  int min_res= 0;
 
9238
  int max_res= 0;
 
9239
  int result;
 
9240
  int is_last_prefix= 0;
 
9241
 
 
9242
  /*
 
9243
    Loop until a group is found that satisfies all query conditions or the last
 
9244
    group is reached.
 
9245
  */
 
9246
  do
 
9247
  {
 
9248
    result= next_prefix();
 
9249
    /*
 
9250
      Check if this is the last group prefix. Notice that at this point
 
9251
      this->record contains the current prefix in record format.
 
9252
    */
 
9253
    if (!result)
 
9254
    {
 
9255
      is_last_prefix= key_cmp(index_info->key_part, last_prefix,
 
9256
                              group_prefix_len);
 
9257
      assert(is_last_prefix <= 0);
 
9258
    }
 
9259
    else
 
9260
    {
 
9261
      if (result == HA_ERR_KEY_NOT_FOUND)
 
9262
        continue;
 
9263
      break;
 
9264
    }
 
9265
 
 
9266
    if (have_min)
 
9267
    {
 
9268
      min_res= next_min();
 
9269
      if (min_res == 0)
 
9270
        update_min_result();
 
9271
    }
 
9272
    /* If there is no MIN in the group, there is no MAX either. */
 
9273
    if ((have_max && !have_min) ||
 
9274
        (have_max && have_min && (min_res == 0)))
 
9275
    {
 
9276
      max_res= next_max();
 
9277
      if (max_res == 0)
 
9278
        update_max_result();
 
9279
      /* If a MIN was found, a MAX must have been found as well. */
 
9280
      assert(((have_max && !have_min) ||
 
9281
                  (have_max && have_min && (max_res == 0))));
 
9282
    }
 
9283
    /*
 
9284
      If this is just a GROUP BY or DISTINCT without MIN or MAX and there
 
9285
      are equality predicates for the key parts after the group, find the
 
9286
      first sub-group with the extended prefix.
 
9287
    */
 
9288
    if (!have_min && !have_max && key_infix_len > 0)
 
9289
      result= file->index_read_map(record, group_prefix,
 
9290
                                   make_prev_keypart_map(real_key_parts),
 
9291
                                   HA_READ_KEY_EXACT);
 
9292
 
 
9293
    result= have_min ? min_res : have_max ? max_res : result;
 
9294
  } while ((result == HA_ERR_KEY_NOT_FOUND || result == HA_ERR_END_OF_FILE) &&
 
9295
           is_last_prefix != 0);
 
9296
 
 
9297
  if (result == 0)
 
9298
  {
 
9299
    /*
 
9300
      Partially mimic the behavior of end_select_send. Copy the
 
9301
      field data from Item_field::field into Item_field::result_field
 
9302
      of each non-aggregated field (the group fields, and optionally
 
9303
      other fields in non-ANSI SQL mode).
 
9304
    */
 
9305
    copy_fields(&join->tmp_table_param);
 
9306
  }
 
9307
  else if (result == HA_ERR_KEY_NOT_FOUND)
 
9308
    result= HA_ERR_END_OF_FILE;
 
9309
 
 
9310
  return result;
 
9311
}
 
9312
 
 
9313
 
 
9314
/*
 
9315
  Retrieve the minimal key in the next group.
 
9316
 
 
9317
  SYNOPSIS
 
9318
    QUICK_GROUP_MIN_MAX_SELECT::next_min()
 
9319
 
 
9320
  DESCRIPTION
 
9321
    Find the minimal key within this group such that the key satisfies the query
 
9322
    conditions and NULL semantics. The found key is loaded into this->record.
 
9323
 
 
9324
  IMPLEMENTATION
 
9325
    Depending on the values of min_max_ranges.elements, key_infix_len, and
 
9326
    whether there is a  NULL in the MIN field, this function may directly
 
9327
    return without any data access. In this case we use the key loaded into
 
9328
    this->record by the call to this->next_prefix() just before this call.
 
9329
 
 
9330
  RETURN
 
9331
    0                    on success
 
9332
    HA_ERR_KEY_NOT_FOUND if no MIN key was found that fulfills all conditions.
 
9333
    HA_ERR_END_OF_FILE   - "" -
 
9334
    other                if some error occurred
 
9335
*/
 
9336
 
 
9337
int QUICK_GROUP_MIN_MAX_SELECT::next_min()
 
9338
{
 
9339
  int result= 0;
 
9340
 
 
9341
  /* Find the MIN key using the eventually extended group prefix. */
 
9342
  if (min_max_ranges.elements > 0)
 
9343
  {
 
9344
    if ((result= next_min_in_range()))
 
9345
      return result;
 
9346
  }
 
9347
  else
 
9348
  {
 
9349
    /* Apply the constant equality conditions to the non-group select fields */
 
9350
    if (key_infix_len > 0)
 
9351
    {
 
9352
      if ((result= file->index_read_map(record, group_prefix,
 
9353
                                        make_prev_keypart_map(real_key_parts),
 
9354
                                        HA_READ_KEY_EXACT)))
 
9355
        return result;
 
9356
    }
 
9357
 
 
9358
    /*
 
9359
      If the min/max argument field is NULL, skip subsequent rows in the same
 
9360
      group with NULL in it. Notice that:
 
9361
      - if the first row in a group doesn't have a NULL in the field, no row
 
9362
      in the same group has (because NULL < any other value),
 
9363
      - min_max_arg_part->field->ptr points to some place in 'record'.
 
9364
    */
 
9365
    if (min_max_arg_part && min_max_arg_part->field->is_null())
 
9366
    {
 
9367
      /* Find the first subsequent record without NULL in the MIN/MAX field. */
 
9368
      key_copy(tmp_record, record, index_info, 0);
 
9369
      result= file->index_read_map(record, tmp_record,
 
9370
                                   make_keypart_map(real_key_parts),
 
9371
                                   HA_READ_AFTER_KEY);
 
9372
      /*
 
9373
        Check if the new record belongs to the current group by comparing its
 
9374
        prefix with the group's prefix. If it is from the next group, then the
 
9375
        whole group has NULLs in the MIN/MAX field, so use the first record in
 
9376
        the group as a result.
 
9377
        TODO:
 
9378
        It is possible to reuse this new record as the result candidate for the
 
9379
        next call to next_min(), and to save one lookup in the next call. For
 
9380
        this add a new member 'this->next_group_prefix'.
 
9381
      */
 
9382
      if (!result)
 
9383
      {
 
9384
        if (key_cmp(index_info->key_part, group_prefix, real_prefix_len))
 
9385
          key_restore(record, tmp_record, index_info, 0);
 
9386
      }
 
9387
      else if (result == HA_ERR_KEY_NOT_FOUND || result == HA_ERR_END_OF_FILE)
 
9388
        result= 0; /* There is a result in any case. */
 
9389
    }
 
9390
  }
 
9391
 
 
9392
  /*
 
9393
    If the MIN attribute is non-nullable, this->record already contains the
 
9394
    MIN key in the group, so just return.
 
9395
  */
 
9396
  return result;
 
9397
}
 
9398
 
 
9399
 
 
9400
/*
 
9401
  Retrieve the maximal key in the next group.
 
9402
 
 
9403
  SYNOPSIS
 
9404
    QUICK_GROUP_MIN_MAX_SELECT::next_max()
 
9405
 
 
9406
  DESCRIPTION
 
9407
    Lookup the maximal key of the group, and store it into this->record.
 
9408
 
 
9409
  RETURN
 
9410
    0                    on success
 
9411
    HA_ERR_KEY_NOT_FOUND if no MAX key was found that fulfills all conditions.
 
9412
    HA_ERR_END_OF_FILE   - "" -
 
9413
    other                if some error occurred
 
9414
*/
 
9415
 
 
9416
int QUICK_GROUP_MIN_MAX_SELECT::next_max()
 
9417
{
 
9418
  int result;
 
9419
 
 
9420
  /* Get the last key in the (possibly extended) group. */
 
9421
  if (min_max_ranges.elements > 0)
 
9422
    result= next_max_in_range();
 
9423
  else
 
9424
    result= file->index_read_map(record, group_prefix,
 
9425
                                 make_prev_keypart_map(real_key_parts),
 
9426
                                 HA_READ_PREFIX_LAST);
 
9427
  return result;
 
9428
}
 
9429
 
 
9430
 
 
9431
/*
 
9432
  Determine the prefix of the next group.
 
9433
 
 
9434
  SYNOPSIS
 
9435
    QUICK_GROUP_MIN_MAX_SELECT::next_prefix()
 
9436
 
 
9437
  DESCRIPTION
 
9438
    Determine the prefix of the next group that satisfies the query conditions.
 
9439
    If there is a range condition referencing the group attributes, use a
 
9440
    QUICK_RANGE_SELECT object to retrieve the *first* key that satisfies the
 
9441
    condition. If there is a key infix of constants, append this infix
 
9442
    immediately after the group attributes. The possibly extended prefix is
 
9443
    stored in this->group_prefix. The first key of the found group is stored in
 
9444
    this->record, on which relies this->next_min().
 
9445
 
 
9446
  RETURN
 
9447
    0                    on success
 
9448
    HA_ERR_KEY_NOT_FOUND if there is no key with the formed prefix
 
9449
    HA_ERR_END_OF_FILE   if there are no more keys
 
9450
    other                if some error occurred
 
9451
*/
 
9452
int QUICK_GROUP_MIN_MAX_SELECT::next_prefix()
 
9453
{
 
9454
  int result;
 
9455
 
 
9456
  if (quick_prefix_select)
 
9457
  {
 
9458
    unsigned char *cur_prefix= seen_first_key ? group_prefix : NULL;
 
9459
    if ((result= quick_prefix_select->get_next_prefix(group_prefix_len,
 
9460
                         make_prev_keypart_map(group_key_parts), cur_prefix)))
 
9461
      return result;
 
9462
    seen_first_key= true;
 
9463
  }
 
9464
  else
 
9465
  {
 
9466
    if (!seen_first_key)
 
9467
    {
 
9468
      result= file->index_first(record);
 
9469
      if (result)
 
9470
        return result;
 
9471
      seen_first_key= true;
 
9472
    }
 
9473
    else
 
9474
    {
 
9475
      /* Load the first key in this group into record. */
 
9476
      result= file->index_read_map(record, group_prefix,
 
9477
                                   make_prev_keypart_map(group_key_parts),
 
9478
                                   HA_READ_AFTER_KEY);
 
9479
      if (result)
 
9480
        return result;
 
9481
    }
 
9482
  }
 
9483
 
 
9484
  /* Save the prefix of this group for subsequent calls. */
 
9485
  key_copy(group_prefix, record, index_info, group_prefix_len);
 
9486
  /* Append key_infix to group_prefix. */
 
9487
  if (key_infix_len > 0)
 
9488
    memcpy(group_prefix + group_prefix_len,
 
9489
           key_infix, key_infix_len);
 
9490
 
 
9491
  return 0;
 
9492
}
 
9493
 
 
9494
 
 
9495
/*
 
9496
  Find the minimal key in a group that satisfies some range conditions for the
 
9497
  min/max argument field.
 
9498
 
 
9499
  SYNOPSIS
 
9500
    QUICK_GROUP_MIN_MAX_SELECT::next_min_in_range()
 
9501
 
 
9502
  DESCRIPTION
 
9503
    Given the sequence of ranges min_max_ranges, find the minimal key that is
 
9504
    in the left-most possible range. If there is no such key, then the current
 
9505
    group does not have a MIN key that satisfies the WHERE clause. If a key is
 
9506
    found, its value is stored in this->record.
 
9507
 
 
9508
  RETURN
 
9509
    0                    on success
 
9510
    HA_ERR_KEY_NOT_FOUND if there is no key with the given prefix in any of
 
9511
                         the ranges
 
9512
    HA_ERR_END_OF_FILE   - "" -
 
9513
    other                if some error
 
9514
*/
 
9515
 
 
9516
int QUICK_GROUP_MIN_MAX_SELECT::next_min_in_range()
 
9517
{
 
9518
  ha_rkey_function find_flag;
 
9519
  key_part_map keypart_map;
 
9520
  QUICK_RANGE *cur_range;
 
9521
  bool found_null= false;
 
9522
  int result= HA_ERR_KEY_NOT_FOUND;
 
9523
  basic_string<unsigned char> max_key;
 
9524
 
 
9525
  max_key.reserve(real_prefix_len + min_max_arg_len);
 
9526
 
 
9527
  assert(min_max_ranges.elements > 0);
 
9528
 
 
9529
  for (uint32_t range_idx= 0; range_idx < min_max_ranges.elements; range_idx++)
 
9530
  { /* Search from the left-most range to the right. */
 
9531
    get_dynamic(&min_max_ranges, (unsigned char*)&cur_range, range_idx);
 
9532
 
 
9533
    /*
 
9534
      If the current value for the min/max argument is bigger than the right
 
9535
      boundary of cur_range, there is no need to check this range.
 
9536
    */
 
9537
    if (range_idx != 0 && !(cur_range->flag & NO_MAX_RANGE) &&
 
9538
        (key_cmp(min_max_arg_part, (const unsigned char*) cur_range->max_key,
 
9539
                 min_max_arg_len) == 1))
 
9540
      continue;
 
9541
 
 
9542
    if (cur_range->flag & NO_MIN_RANGE)
 
9543
    {
 
9544
      keypart_map= make_prev_keypart_map(real_key_parts);
 
9545
      find_flag= HA_READ_KEY_EXACT;
 
9546
    }
 
9547
    else
 
9548
    {
 
9549
      /* Extend the search key with the lower boundary for this range. */
 
9550
      memcpy(group_prefix + real_prefix_len, cur_range->min_key,
 
9551
             cur_range->min_length);
 
9552
      keypart_map= make_keypart_map(real_key_parts);
 
9553
      find_flag= (cur_range->flag & (EQ_RANGE | NULL_RANGE)) ?
 
9554
                 HA_READ_KEY_EXACT : (cur_range->flag & NEAR_MIN) ?
 
9555
                 HA_READ_AFTER_KEY : HA_READ_KEY_OR_NEXT;
 
9556
    }
 
9557
 
 
9558
    result= file->index_read_map(record, group_prefix, keypart_map, find_flag);
 
9559
    if (result)
 
9560
    {
 
9561
      if ((result == HA_ERR_KEY_NOT_FOUND || result == HA_ERR_END_OF_FILE) &&
 
9562
          (cur_range->flag & (EQ_RANGE | NULL_RANGE)))
 
9563
        continue; /* Check the next range. */
 
9564
 
 
9565
      /*
 
9566
        In all other cases (HA_ERR_*, HA_READ_KEY_EXACT with NO_MIN_RANGE,
 
9567
        HA_READ_AFTER_KEY, HA_READ_KEY_OR_NEXT) if the lookup failed for this
 
9568
        range, it can't succeed for any other subsequent range.
 
9569
      */
 
9570
      break;
 
9571
    }
 
9572
 
 
9573
    /* A key was found. */
 
9574
    if (cur_range->flag & EQ_RANGE)
 
9575
      break; /* No need to perform the checks below for equal keys. */
 
9576
 
 
9577
    if (cur_range->flag & NULL_RANGE)
 
9578
    {
 
9579
      /*
 
9580
        Remember this key, and continue looking for a non-NULL key that
 
9581
        satisfies some other condition.
 
9582
      */
 
9583
      memcpy(tmp_record, record, head->s->rec_buff_length);
 
9584
      found_null= true;
 
9585
      continue;
 
9586
    }
 
9587
 
 
9588
    /* Check if record belongs to the current group. */
 
9589
    if (key_cmp(index_info->key_part, group_prefix, real_prefix_len))
 
9590
    {
 
9591
      result= HA_ERR_KEY_NOT_FOUND;
 
9592
      continue;
 
9593
    }
 
9594
 
 
9595
    /* If there is an upper limit, check if the found key is in the range. */
 
9596
    if ( !(cur_range->flag & NO_MAX_RANGE) )
 
9597
    {
 
9598
      /* Compose the MAX key for the range. */
 
9599
      max_key.clear();
 
9600
      max_key.append(group_prefix, real_prefix_len);
 
9601
      max_key.append(cur_range->max_key, cur_range->max_length);
 
9602
      /* Compare the found key with max_key. */
 
9603
      int cmp_res= key_cmp(index_info->key_part,
 
9604
                           max_key.data(),
 
9605
                           real_prefix_len + min_max_arg_len);
 
9606
      if (!(((cur_range->flag & NEAR_MAX) && (cmp_res == -1)) ||
 
9607
            (cmp_res <= 0)))
 
9608
      {
 
9609
        result= HA_ERR_KEY_NOT_FOUND;
 
9610
        continue;
 
9611
      }
 
9612
    }
 
9613
    /* If we got to this point, the current key qualifies as MIN. */
 
9614
    assert(result == 0);
 
9615
    break;
 
9616
  }
 
9617
  /*
 
9618
    If there was a key with NULL in the MIN/MAX field, and there was no other
 
9619
    key without NULL from the same group that satisfies some other condition,
 
9620
    then use the key with the NULL.
 
9621
  */
 
9622
  if (found_null && result)
 
9623
  {
 
9624
    memcpy(record, tmp_record, head->s->rec_buff_length);
 
9625
    result= 0;
 
9626
  }
 
9627
  return result;
 
9628
}
 
9629
 
 
9630
 
 
9631
/*
 
9632
  Find the maximal key in a group that satisfies some range conditions for the
 
9633
  min/max argument field.
 
9634
 
 
9635
  SYNOPSIS
 
9636
    QUICK_GROUP_MIN_MAX_SELECT::next_max_in_range()
 
9637
 
 
9638
  DESCRIPTION
 
9639
    Given the sequence of ranges min_max_ranges, find the maximal key that is
 
9640
    in the right-most possible range. If there is no such key, then the current
 
9641
    group does not have a MAX key that satisfies the WHERE clause. If a key is
 
9642
    found, its value is stored in this->record.
 
9643
 
 
9644
  RETURN
 
9645
    0                    on success
 
9646
    HA_ERR_KEY_NOT_FOUND if there is no key with the given prefix in any of
 
9647
                         the ranges
 
9648
    HA_ERR_END_OF_FILE   - "" -
 
9649
    other                if some error
 
9650
*/
 
9651
 
 
9652
int QUICK_GROUP_MIN_MAX_SELECT::next_max_in_range()
 
9653
{
 
9654
  ha_rkey_function find_flag;
 
9655
  key_part_map keypart_map;
 
9656
  QUICK_RANGE *cur_range;
 
9657
  int result;
 
9658
  basic_string<unsigned char> min_key;
 
9659
  min_key.reserve(real_prefix_len + min_max_arg_len);
 
9660
 
 
9661
  assert(min_max_ranges.elements > 0);
 
9662
 
 
9663
  for (uint32_t range_idx= min_max_ranges.elements; range_idx > 0; range_idx--)
 
9664
  { /* Search from the right-most range to the left. */
 
9665
    get_dynamic(&min_max_ranges, (unsigned char*)&cur_range, range_idx - 1);
 
9666
 
 
9667
    /*
 
9668
      If the current value for the min/max argument is smaller than the left
 
9669
      boundary of cur_range, there is no need to check this range.
 
9670
    */
 
9671
    if (range_idx != min_max_ranges.elements &&
 
9672
        !(cur_range->flag & NO_MIN_RANGE) &&
 
9673
        (key_cmp(min_max_arg_part, (const unsigned char*) cur_range->min_key,
 
9674
                 min_max_arg_len) == -1))
 
9675
      continue;
 
9676
 
 
9677
    if (cur_range->flag & NO_MAX_RANGE)
 
9678
    {
 
9679
      keypart_map= make_prev_keypart_map(real_key_parts);
 
9680
      find_flag= HA_READ_PREFIX_LAST;
 
9681
    }
 
9682
    else
 
9683
    {
 
9684
      /* Extend the search key with the upper boundary for this range. */
 
9685
      memcpy(group_prefix + real_prefix_len, cur_range->max_key,
 
9686
             cur_range->max_length);
 
9687
      keypart_map= make_keypart_map(real_key_parts);
 
9688
      find_flag= (cur_range->flag & EQ_RANGE) ?
 
9689
                 HA_READ_KEY_EXACT : (cur_range->flag & NEAR_MAX) ?
 
9690
                 HA_READ_BEFORE_KEY : HA_READ_PREFIX_LAST_OR_PREV;
 
9691
    }
 
9692
 
 
9693
    result= file->index_read_map(record, group_prefix, keypart_map, find_flag);
 
9694
 
 
9695
    if (result)
 
9696
    {
 
9697
      if ((result == HA_ERR_KEY_NOT_FOUND || result == HA_ERR_END_OF_FILE) &&
 
9698
          (cur_range->flag & EQ_RANGE))
 
9699
        continue; /* Check the next range. */
 
9700
 
 
9701
      /*
 
9702
        In no key was found with this upper bound, there certainly are no keys
 
9703
        in the ranges to the left.
 
9704
      */
 
9705
      return result;
 
9706
    }
 
9707
    /* A key was found. */
 
9708
    if (cur_range->flag & EQ_RANGE)
 
9709
      return 0; /* No need to perform the checks below for equal keys. */
 
9710
 
 
9711
    /* Check if record belongs to the current group. */
 
9712
    if (key_cmp(index_info->key_part, group_prefix, real_prefix_len))
 
9713
      continue;                                 // Row not found
 
9714
 
 
9715
    /* If there is a lower limit, check if the found key is in the range. */
 
9716
    if ( !(cur_range->flag & NO_MIN_RANGE) )
 
9717
    {
 
9718
      /* Compose the MIN key for the range. */
 
9719
      min_key.clear();
 
9720
      min_key.append(group_prefix, real_prefix_len);
 
9721
      min_key.append(cur_range->min_key, cur_range->min_length);
 
9722
 
 
9723
      /* Compare the found key with min_key. */
 
9724
      int cmp_res= key_cmp(index_info->key_part,
 
9725
                           min_key.data(),
 
9726
                           real_prefix_len + min_max_arg_len);
 
9727
      if (!(((cur_range->flag & NEAR_MIN) && (cmp_res == 1)) ||
 
9728
            (cmp_res >= 0)))
 
9729
        continue;
 
9730
    }
 
9731
    /* If we got to this point, the current key qualifies as MAX. */
 
9732
    return result;
 
9733
  }
 
9734
  return HA_ERR_KEY_NOT_FOUND;
 
9735
}
 
9736
 
 
9737
 
 
9738
/*
 
9739
  Update all MIN function results with the newly found value.
 
9740
 
 
9741
  SYNOPSIS
 
9742
    QUICK_GROUP_MIN_MAX_SELECT::update_min_result()
 
9743
 
 
9744
  DESCRIPTION
 
9745
    The method iterates through all MIN functions and updates the result value
 
9746
    of each function by calling Item_sum::reset(), which in turn picks the new
 
9747
    result value from this->head->record[0], previously updated by
 
9748
    next_min(). The updated value is stored in a member variable of each of the
 
9749
    Item_sum objects, depending on the value type.
 
9750
 
 
9751
  IMPLEMENTATION
 
9752
    The update must be done separately for MIN and MAX, immediately after
 
9753
    next_min() was called and before next_max() is called, because both MIN and
 
9754
    MAX take their result value from the same buffer this->head->record[0]
 
9755
    (i.e.  this->record).
 
9756
 
 
9757
  RETURN
 
9758
    None
 
9759
*/
 
9760
 
 
9761
void QUICK_GROUP_MIN_MAX_SELECT::update_min_result()
 
9762
{
 
9763
  Item_sum *min_func;
 
9764
 
 
9765
  min_functions_it->rewind();
 
9766
  while ((min_func= (*min_functions_it)++))
 
9767
    min_func->reset();
 
9768
}
 
9769
 
 
9770
 
 
9771
/*
 
9772
  Update all MAX function results with the newly found value.
 
9773
 
 
9774
  SYNOPSIS
 
9775
    QUICK_GROUP_MIN_MAX_SELECT::update_max_result()
 
9776
 
 
9777
  DESCRIPTION
 
9778
    The method iterates through all MAX functions and updates the result value
 
9779
    of each function by calling Item_sum::reset(), which in turn picks the new
 
9780
    result value from this->head->record[0], previously updated by
 
9781
    next_max(). The updated value is stored in a member variable of each of the
 
9782
    Item_sum objects, depending on the value type.
 
9783
 
 
9784
  IMPLEMENTATION
 
9785
    The update must be done separately for MIN and MAX, immediately after
 
9786
    next_max() was called, because both MIN and MAX take their result value
 
9787
    from the same buffer this->head->record[0] (i.e.  this->record).
 
9788
 
 
9789
  RETURN
 
9790
    None
 
9791
*/
 
9792
 
 
9793
void QUICK_GROUP_MIN_MAX_SELECT::update_max_result()
 
9794
{
 
9795
  Item_sum *max_func;
 
9796
 
 
9797
  max_functions_it->rewind();
 
9798
  while ((max_func= (*max_functions_it)++))
 
9799
    max_func->reset();
 
9800
}
 
9801
 
 
9802
 
 
9803
/*
 
9804
  Append comma-separated list of keys this quick select uses to key_names;
 
9805
  append comma-separated list of corresponding used lengths to used_lengths.
 
9806
 
 
9807
  SYNOPSIS
 
9808
    QUICK_GROUP_MIN_MAX_SELECT::add_keys_and_lengths()
 
9809
    key_names    [out] Names of used indexes
 
9810
    used_lengths [out] Corresponding lengths of the index names
 
9811
 
 
9812
  DESCRIPTION
 
9813
    This method is used by select_describe to extract the names of the
 
9814
    indexes used by a quick select.
 
9815
 
 
9816
*/
 
9817
 
 
9818
void QUICK_GROUP_MIN_MAX_SELECT::add_keys_and_lengths(String *key_names,
 
9819
                                                      String *used_lengths)
 
9820
{
 
9821
  char buf[64];
 
9822
  uint32_t length;
 
9823
  key_names->append(index_info->name);
 
9824
  length= int64_t2str(max_used_key_length, buf, 10) - buf;
 
9825
  used_lengths->append(buf, length);
 
9826
}
 
9827
 
 
9828
static void print_sel_tree(PARAM *param, SEL_TREE *tree, key_map *tree_map, const char *)
 
9829
{
 
9830
  SEL_ARG **key,**end;
 
9831
  int idx;
 
9832
  char buff[1024];
 
9833
 
 
9834
  String tmp(buff,sizeof(buff),&my_charset_bin);
 
9835
  tmp.length(0);
 
9836
  for (idx= 0,key=tree->keys, end=key+param->keys ;
 
9837
       key != end ;
 
9838
       key++,idx++)
 
9839
  {
 
9840
    if (tree_map->test(idx))
 
9841
    {
 
9842
      uint32_t keynr= param->real_keynr[idx];
 
9843
      if (tmp.length())
 
9844
        tmp.append(',');
 
9845
      tmp.append(param->table->key_info[keynr].name);
 
9846
    }
 
9847
  }
 
9848
  if (!tmp.length())
 
9849
    tmp.append(STRING_WITH_LEN("(empty)"));
 
9850
}
 
9851
 
 
9852
 
 
9853
static void print_ror_scans_arr(Table *table,
 
9854
                                const char *, struct st_ror_scan_info **start,
 
9855
                                struct st_ror_scan_info **end)
 
9856
{
 
9857
  char buff[1024];
 
9858
  String tmp(buff,sizeof(buff),&my_charset_bin);
 
9859
  tmp.length(0);
 
9860
  for (;start != end; start++)
 
9861
  {
 
9862
    if (tmp.length())
 
9863
      tmp.append(',');
 
9864
    tmp.append(table->key_info[(*start)->keynr].name);
 
9865
  }
 
9866
  if (!tmp.length())
 
9867
    tmp.append(STRING_WITH_LEN("(empty)"));
 
9868
}
 
9869
 
 
9870
/*****************************************************************************
 
9871
** Instantiate templates
 
9872
*****************************************************************************/
 
9873
 
 
9874
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
 
9875
template class List<QUICK_RANGE>;
 
9876
template class List_iterator<QUICK_RANGE>;
 
9877
#endif