~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/opt_range.cc

  • Committer: Eric Day
  • Date: 2009-11-10 21:50:22 UTC
  • mto: This revision was merged to the branch mainline in revision 1218.
  • Revision ID: eday@oddments.org-20091110215022-0b2nqmurv7b2l6wo
Duplicated oldlibdrizzle module, one for Drizzle protocol and one for MySQL, per Brian's request from merge proposal. Port options are now --drizzle-protocol-port and --mysql-protocol-port.

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