~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/opt_range.cc

  • Committer: Jay Pipes
  • Date: 2009-01-30 04:01:12 UTC
  • mto: This revision was merged to the branch mainline in revision 830.
  • Revision ID: jpipes@serialcoder-20090130040112-svbn774guj98pwi4
To remain in compatibility with MySQL, added ability to interpret
decimal arguments as datetime strings for temporal functions.

Fixed YEAR(), MONTH(), DAYOFMONTH(), DAYOFYEAR(), HOUR(), MINUTE(), SECOND(), and MICROSECOND()
to accept decimal parameters and interpret them the same way as MySQL.

Fixed an issue with the TemporalFormat::matches() method which was 
incorrectly assuming all microsecond arguments were specified as 6 digits.
Added power of 10 multiplier to usecond calculation. This fixes issues with
failures in type_date and func_sapdb test cases.

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