~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/opt_range.cc

  • Committer: Mark Atwood
  • Date: 2009-03-04 01:02:00 UTC
  • mto: (968.2.20 mordred)
  • mto: This revision was merged to the branch mainline in revision 971.
  • Revision ID: me@mark.atwood.name-20090304010200-t1n4xxdoil2yae9a
add gearman logging plugin

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>
107
 
 
108
 
#include <string>
109
 
#include <vector>
110
 
#include <algorithm>
111
 
 
112
 
#include <boost/dynamic_bitset.hpp>
113
 
 
114
 
#include <drizzled/check_stack_overrun.h>
 
106
#include <drizzled/server_includes.h>
 
107
#include <drizzled/sql_select.h>
115
108
#include <drizzled/error.h>
 
109
#include <drizzled/cost_vect.h>
 
110
#include <drizzled/item/cmpfunc.h>
116
111
#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
 
#include <drizzled/session.h>
140
 
 
141
 
#include <drizzled/unique.h>
142
 
 
143
 
#include <drizzled/temporal.h> /* Needed in get_mm_leaf() for timestamp -> datetime comparisons */
 
112
#include <drizzled/check_stack_overrun.h>
 
113
 
 
114
#include <string>
 
115
#include CMATH_H
144
116
 
145
117
using namespace std;
146
 
namespace drizzled
147
 
{
148
 
 
149
 
#define HA_END_SPACE_KEY 0
 
118
#if defined(CMATH_NAMESPACE)
 
119
using namespace CMATH_NAMESPACE;
 
120
#endif
150
121
 
151
122
/*
152
123
  Convert double value to #rows. Currently this does floor(), and we
153
124
  might consider using round() instead.
154
125
*/
155
 
static inline ha_rows double2rows(double x)
156
 
{
157
 
    return static_cast<ha_rows>(x);
158
 
}
 
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);
159
129
 
160
130
static unsigned char is_null_string[2]= {1,0};
161
131
 
162
 
 
163
 
/**
164
 
  Get cost of reading nrows table records in a "disk sweep"
165
 
 
166
 
  A disk sweep read is a sequence of Cursor->rnd_pos(rowid) calls that made
167
 
  for an ordered sequence of rowids.
168
 
 
169
 
  We assume hard disk IO. The read is performed as follows:
170
 
 
171
 
   1. The disk head is moved to the needed cylinder
172
 
   2. The controller waits for the plate to rotate
173
 
   3. The data is transferred
174
 
 
175
 
  Time to do #3 is insignificant compared to #2+#1.
176
 
 
177
 
  Time to move the disk head is proportional to head travel distance.
178
 
 
179
 
  Time to wait for the plate to rotate depends on whether the disk head
180
 
  was moved or not.
181
 
 
182
 
  If disk head wasn't moved, the wait time is proportional to distance
183
 
  between the previous block and the block we're reading.
184
 
 
185
 
  If the head was moved, we don't know how much we'll need to wait for the
186
 
  plate to rotate. We assume the wait time to be a variate with a mean of
187
 
  0.5 of full rotation time.
188
 
 
189
 
  Our cost units are "random disk seeks". The cost of random disk seek is
190
 
  actually not a constant, it depends one range of cylinders we're going
191
 
  to access. We make it constant by introducing a fuzzy concept of "typical
192
 
  datafile length" (it's fuzzy as it's hard to tell whether it should
193
 
  include index cursor, temp.tables etc). Then random seek cost is:
194
 
 
195
 
    1 = half_rotation_cost + move_cost * 1/3 * typical_data_file_length
196
 
 
197
 
  We define half_rotation_cost as DISK_SEEK_BASE_COST=0.9.
198
 
 
199
 
  @param table             Table to be accessed
200
 
  @param nrows             Number of rows to retrieve
201
 
  @param interrupted       true <=> Assume that the disk sweep will be
202
 
                           interrupted by other disk IO. false - otherwise.
203
 
  @param cost         OUT  The cost.
204
 
*/
205
 
 
206
 
static void get_sweep_read_cost(Table *table,
207
 
                                ha_rows nrows,
208
 
                                bool interrupted,
209
 
                                optimizer::CostVector *cost)
210
 
{
211
 
  cost->zero();
212
 
  if (table->cursor->primary_key_is_clustered())
213
 
  {
214
 
    cost->setIOCount(table->cursor->read_time(table->getShare()->getPrimaryKey(),
215
 
                                             static_cast<uint32_t>(nrows),
216
 
                                             nrows));
217
 
  }
218
 
  else
219
 
  {
220
 
    double n_blocks=
221
 
      ceil(static_cast<double>(table->cursor->stats.data_file_length) / IO_SIZE);
222
 
    double busy_blocks=
223
 
      n_blocks * (1.0 - pow(1.0 - 1.0/n_blocks, static_cast<double>(nrows)));
224
 
    if (busy_blocks < 1.0)
225
 
      busy_blocks= 1.0;
226
 
 
227
 
    cost->setIOCount(busy_blocks);
228
 
 
229
 
    if (! interrupted)
230
 
    {
231
 
      /* Assume reading is done in one 'sweep' */
232
 
      cost->setAvgIOCost((DISK_SEEK_BASE_COST +
233
 
                          DISK_SEEK_PROP_COST*n_blocks/busy_blocks));
234
 
    }
235
 
  }
236
 
}
237
 
 
238
 
static optimizer::SEL_TREE * get_mm_parts(optimizer::RangeParameter *param,
239
 
                               COND *cond_func,
240
 
                               Field *field,
241
 
                                                 Item_func::Functype type,
242
 
                               Item *value,
243
 
                                                 Item_result cmp_type);
244
 
 
245
 
static optimizer::SEL_ARG *get_mm_leaf(optimizer::RangeParameter *param,
246
 
                                       COND *cond_func,
247
 
                                       Field *field,
248
 
                                       KEY_PART *key_part,
249
 
                                                         Item_func::Functype type,
250
 
                                       Item *value);
251
 
 
252
 
static optimizer::SEL_TREE *get_mm_tree(optimizer::RangeParameter *param, COND *cond);
253
 
 
254
 
static bool is_key_scan_ror(optimizer::Parameter *param, uint32_t keynr, uint8_t nparts);
255
 
 
256
 
static ha_rows check_quick_select(Session *session,
257
 
                                  optimizer::Parameter *param,
258
 
                                  uint32_t idx,
259
 
                                  bool index_only,
260
 
                                  optimizer::SEL_ARG *tree,
261
 
                                  bool update_tbl_stats,
262
 
                                  uint32_t *mrr_flags,
263
 
                                  uint32_t *bufsize,
264
 
                                  optimizer::CostVector *cost);
265
 
 
266
 
static optimizer::RangeReadPlan *get_key_scans_params(Session *session,
267
 
                                                      optimizer::Parameter *param,
268
 
                                                      optimizer::SEL_TREE *tree,
269
 
                                                      bool index_read_must_be_used,
270
 
                                                      bool update_tbl_stats,
271
 
                                                      double read_time);
272
 
 
273
 
static
274
 
optimizer::RorIntersectReadPlan *get_best_ror_intersect(const optimizer::Parameter *param,
275
 
                                                        optimizer::SEL_TREE *tree,
276
 
                                                        double read_time,
277
 
                                                        bool *are_all_covering);
278
 
 
279
 
static
280
 
optimizer::RorIntersectReadPlan *get_best_covering_ror_intersect(optimizer::Parameter *param,
281
 
                                                                 optimizer::SEL_TREE *tree,
282
 
                                                                 double read_time);
283
 
 
284
 
static
285
 
optimizer::TableReadPlan *get_best_disjunct_quick(Session *session,
286
 
                                                  optimizer::Parameter *param,
287
 
                                                  optimizer::SEL_IMERGE *imerge,
288
 
                                                  double read_time);
289
 
 
290
 
static
291
 
optimizer::GroupMinMaxReadPlan *get_best_group_min_max(optimizer::Parameter *param, optimizer::SEL_TREE *tree);
292
 
 
293
 
static optimizer::SEL_TREE *tree_and(optimizer::RangeParameter *param, 
294
 
                                     optimizer::SEL_TREE *tree1, 
295
 
                                     optimizer::SEL_TREE *tree2);
296
 
 
297
 
static optimizer::SEL_ARG *sel_add(optimizer::SEL_ARG *key1, optimizer::SEL_ARG *key2);
298
 
 
299
 
static optimizer::SEL_ARG *key_and(optimizer::RangeParameter *param,
300
 
                                   optimizer::SEL_ARG *key1,
301
 
                                   optimizer::SEL_ARG *key2,
302
 
                                   uint32_t clone_flag);
303
 
 
304
 
static bool get_range(optimizer::SEL_ARG **e1, optimizer::SEL_ARG **e2, optimizer::SEL_ARG *root1);
305
 
 
306
 
optimizer::SEL_ARG optimizer::null_element(optimizer::SEL_ARG::IMPOSSIBLE);
307
 
 
308
 
static bool null_part_in_key(KEY_PART *key_part,
309
 
                             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,
310
783
                             uint32_t length);
311
 
 
312
 
bool sel_trees_can_be_ored(optimizer::SEL_TREE *tree1, 
313
 
                           optimizer::SEL_TREE *tree2, 
314
 
                           optimizer::RangeParameter *param);
315
 
 
316
 
 
317
 
 
318
 
 
 
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
}
319
930
 
320
931
 
321
932
/*
322
933
  Perform AND operation on two index_merge lists and store result in *im1.
323
934
*/
324
935
 
325
 
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)
326
937
{
327
938
  im1->concat(im2);
328
939
}
329
940
 
330
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
 
331
1000
/***************************************************************************
332
 
** Basic functions for SqlSelect and QuickRangeSelect
 
1001
** Basic functions for SQL_SELECT and QUICK_RANGE_SELECT
333
1002
***************************************************************************/
334
1003
 
335
1004
        /* make a select from mysql info
338
1007
           1 = Got some error (out of memory?)
339
1008
           */
340
1009
 
341
 
optimizer::SqlSelect *optimizer::make_select(Table *head,
342
 
                                             table_map const_tables,
343
 
                                             table_map read_tables,
344
 
                                             COND *conds,
345
 
                                             bool allow_null_cond,
346
 
                                             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)
347
1014
{
348
 
  optimizer::SqlSelect *select= NULL;
349
 
 
350
 
  *error= 0;
351
 
 
352
 
  if (! conds && ! allow_null_cond)
353
 
  {
 
1015
  SQL_SELECT *select;
 
1016
 
 
1017
  *error=0;
 
1018
 
 
1019
  if (!conds && !allow_null_cond)
354
1020
    return 0;
355
 
  }
356
 
  if (! (select= new optimizer::SqlSelect()))
 
1021
  if (!(select= new SQL_SELECT))
357
1022
  {
358
1023
    *error= 1;                  // out of memory
359
 
    return 0;
 
1024
    return 0;           /* purecov: inspected */
360
1025
  }
361
1026
  select->read_tables=read_tables;
362
1027
  select->const_tables=const_tables;
365
1030
 
366
1031
  if (head->sort.io_cache)
367
1032
  {
368
 
    memcpy(select->file, head->sort.io_cache, sizeof(internal::IO_CACHE));
369
 
    select->records=(ha_rows) (select->file->end_of_file/
370
 
                               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);
371
1036
    delete head->sort.io_cache;
372
1037
    head->sort.io_cache=0;
373
1038
  }
375
1040
}
376
1041
 
377
1042
 
378
 
optimizer::SqlSelect::SqlSelect() 
379
 
  :
380
 
    quick(NULL),
381
 
    cond(NULL),
382
 
    file(static_cast<internal::IO_CACHE *>(memory::sql_calloc(sizeof(internal::IO_CACHE)))),
383
 
    free_cond(false)
 
1043
SQL_SELECT::SQL_SELECT() :quick(0),cond(0),free_cond(0)
384
1044
{
385
 
  quick_keys.reset();
386
 
  needed_reg.reset();
387
 
  my_b_clear(file);
 
1045
  quick_keys.clear_all(); needed_reg.clear_all();
 
1046
  my_b_clear(&file);
388
1047
}
389
1048
 
390
1049
 
391
 
void optimizer::SqlSelect::cleanup()
 
1050
void SQL_SELECT::cleanup()
392
1051
{
393
 
  if (quick)
394
 
  {
395
 
    delete quick;
396
 
    quick= NULL;
397
 
  }
398
 
 
 
1052
  delete quick;
 
1053
  quick= 0;
399
1054
  if (free_cond)
400
1055
  {
401
 
    free_cond= 0;
 
1056
    free_cond=0;
402
1057
    delete cond;
403
1058
    cond= 0;
404
1059
  }
405
 
  file->close_cached_file();
 
1060
  close_cached_file(&file);
406
1061
}
407
1062
 
408
1063
 
409
 
optimizer::SqlSelect::~SqlSelect()
 
1064
SQL_SELECT::~SQL_SELECT()
410
1065
{
411
1066
  cleanup();
412
1067
}
413
1068
 
414
1069
 
415
 
bool optimizer::SqlSelect::check_quick(Session *session, 
416
 
                                       bool force_quick_range,
417
 
                                       ha_rows limit)
 
1070
bool SQL_SELECT::check_quick(Session *session, bool force_quick_range,
 
1071
                             ha_rows limit)
418
1072
{
419
1073
  key_map tmp;
420
 
  tmp.set();
421
 
  return (test_quick_select(session, 
422
 
                           tmp, 
423
 
                           0, 
424
 
                           limit,
425
 
                           force_quick_range, 
426
 
                           false) < 0);
427
 
}
428
 
 
429
 
 
430
 
bool optimizer::SqlSelect::skip_record()
431
 
{
432
 
  return (cond ? cond->val_int() == 0 : 0);
433
 
}
434
 
 
435
 
 
436
 
optimizer::QuickSelectInterface::QuickSelectInterface()
437
 
  :
438
 
    max_used_key_length(0),
439
 
    used_key_parts(0)
440
 
{}
 
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
}
441
1780
 
442
1781
 
443
1782
/*
469
1808
    MAX_KEY if no such index was found.
470
1809
*/
471
1810
 
472
 
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)
473
1812
{
474
1813
  uint32_t idx;
475
1814
  uint32_t match_key= MAX_KEY, match_key_len= MAX_KEY_LENGTH + 1;
476
 
  Order *ord;
 
1815
  order_st *ord;
477
1816
 
478
1817
  for (ord= order; ord; ord= ord->next)
479
1818
    if (!ord->asc)
480
1819
      return MAX_KEY;
481
1820
 
482
 
  for (idx= 0; idx < table->getShare()->sizeKeys(); idx++)
 
1821
  for (idx= 0; idx < table->s->keys; idx++)
483
1822
  {
484
 
    if (!(table->keys_in_use_for_query.test(idx)))
 
1823
    if (!(table->keys_in_use_for_query.is_set(idx)))
485
1824
      continue;
486
 
    KeyPartInfo *keyinfo= table->key_info[idx].key_part;
 
1825
    KEY_PART_INFO *keyinfo= table->key_info[idx].key_part;
487
1826
    uint32_t n_parts=  table->key_info[idx].key_parts;
488
1827
    uint32_t partno= 0;
489
1828
 
492
1831
      indexes (records are returned in order for any index prefix) or HASH
493
1832
      indexes (records are not returned in order for any index prefix).
494
1833
    */
495
 
    if (! (table->index_flags(idx) & HA_READ_ORDER))
 
1834
    if (!(table->file->index_flags(idx, 0, 1) & HA_READ_ORDER))
496
1835
      continue;
497
1836
    for (ord= order; ord && partno < n_parts; ord= ord->next, partno++)
498
1837
    {
499
1838
      Item *item= order->item[0];
500
 
      if (! (item->type() == Item::FIELD_ITEM &&
 
1839
      if (!(item->type() == Item::FIELD_ITEM &&
501
1840
           ((Item_field*)item)->field->eq(keyinfo[partno].field)))
502
1841
        break;
503
1842
    }
504
1843
 
505
 
    if (! ord && table->key_info[idx].key_length < match_key_len)
 
1844
    if (!ord && table->key_info[idx].key_length < match_key_len)
506
1845
    {
507
1846
      /*
508
1847
        Ok, the ordering is compatible and this key is shorter then
521
1860
      order. Now we'll check if using the index is cheaper then doing a table
522
1861
      scan.
523
1862
    */
524
 
    double full_scan_time= table->cursor->scan_time();
525
 
    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);
526
1865
    if (index_scan_time > full_scan_time)
527
1866
      match_key= MAX_KEY;
528
1867
  }
530
1869
}
531
1870
 
532
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, (uint32_t) 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
 
533
2065
 
534
2066
/*
535
2067
  Fill param->needed_fields with bitmap of fields used in the query.
545
2077
    1  Out of memory.
546
2078
*/
547
2079
 
548
 
static int fill_used_fields_bitmap(optimizer::Parameter *param)
 
2080
static int fill_used_fields_bitmap(PARAM *param)
549
2081
{
550
2082
  Table *table= param->table;
 
2083
  my_bitmap_map *tmp;
551
2084
  uint32_t pk;
552
 
  param->tmp_covered_fields.clear();
553
 
  param->needed_fields.resize(table->getShare()->sizeFields());
554
 
  param->needed_fields.reset();
555
 
 
556
 
  param->needed_fields|= *table->read_set;
557
 
  param->needed_fields|= *table->write_set;
558
 
 
559
 
  pk= param->table->getShare()->getPrimaryKey();
560
 
  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())
561
2097
  {
562
2098
    /* The table uses clustered PK and it is not internally generated */
563
 
    KeyPartInfo *key_part= param->table->key_info[pk].key_part;
564
 
    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 +
565
2101
                                 param->table->key_info[pk].key_parts;
566
2102
    for (;key_part != key_part_end; ++key_part)
567
 
      param->needed_fields.reset(key_part->fieldnr-1);
 
2103
      bitmap_clear_bit(&param->needed_fields, key_part->fieldnr-1);
568
2104
  }
569
2105
  return 0;
570
2106
}
574
2110
  Test if a key can be used in different ranges
575
2111
 
576
2112
  SYNOPSIS
577
 
    SqlSelect::test_quick_select()
 
2113
    SQL_SELECT::test_quick_select()
578
2114
      session               Current thread
579
2115
      keys_to_use       Keys to use for range retrieval
580
2116
      prev_tables       Tables assumed to be already read when the scan is
636
2172
    1 if found usable ranges and quick select has been successfully created.
637
2173
*/
638
2174
 
639
 
int optimizer::SqlSelect::test_quick_select(Session *session,
640
 
                                            key_map keys_to_use,
641
 
                                                                    table_map prev_tables,
642
 
                                                                    ha_rows limit,
643
 
                                            bool force_quick_range,
644
 
                                            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)
645
2179
{
646
2180
  uint32_t idx;
647
2181
  double scan_time;
648
 
  if (quick)
649
 
  {
650
 
    delete quick;
651
 
    quick= NULL;
652
 
  }
653
 
  needed_reg.reset();
654
 
  quick_keys.reset();
655
 
  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())
656
2187
    return 0;
657
 
  records= head->cursor->stats.records;
 
2188
  records= head->file->stats.records;
658
2189
  if (!records)
659
 
    records++;
 
2190
    records++;                                  /* purecov: inspected */
660
2191
  scan_time= (double) records / TIME_FOR_COMPARE + 1;
661
 
  read_time= (double) head->cursor->scan_time() + scan_time + 1.1;
 
2192
  read_time= (double) head->file->scan_time() + scan_time + 1.1;
662
2193
  if (head->force_index)
663
2194
    scan_time= read_time= DBL_MAX;
664
2195
  if (limit < records)
666
2197
  else if (read_time <= 2.0 && !force_quick_range)
667
2198
    return 0;                           /* No need for quick select */
668
2199
 
669
 
  keys_to_use&= head->keys_in_use_for_query;
670
 
  if (keys_to_use.any())
 
2200
  keys_to_use.intersect(head->keys_in_use_for_query);
 
2201
  if (!keys_to_use.is_clear_all())
671
2202
  {
672
 
    memory::Root alloc;
673
 
    optimizer::SEL_TREE *tree= NULL;
 
2203
    MEM_ROOT alloc;
 
2204
    SEL_TREE *tree= NULL;
674
2205
    KEY_PART *key_parts;
675
 
    KeyInfo *key_info;
676
 
    optimizer::Parameter param;
 
2206
    KEY *key_info;
 
2207
    PARAM param;
677
2208
 
678
2209
    if (check_stack_overrun(session, 2*STACK_MIN_SIZE, NULL))
679
2210
      return 0;                           // Fatal error flag is set
680
2211
 
681
2212
    /* set up parameter that is passed to all functions */
682
2213
    param.session= session;
683
 
    param.prev_tables= prev_tables | const_tables;
684
 
    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;
685
2217
    param.current_table= head->map;
686
2218
    param.table=head;
687
2219
    param.keys=0;
694
2226
    param.force_default_mrr= ordered_output;
695
2227
 
696
2228
    session->no_errors=1;                               // Don't warn about NULL
697
 
    memory::init_sql_alloc(&alloc, session->variables.range_alloc_block_size, 0);
698
 
    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)) ||
699
2233
        fill_used_fields_bitmap(&param))
700
2234
    {
701
2235
      session->no_errors=0;
702
 
      alloc.free_root(MYF(0));                  // Return memory & allocator
703
 
 
 
2236
      free_root(&alloc,MYF(0));                 // Return memory & allocator
704
2237
      return 0;                         // Can't use range
705
2238
    }
706
2239
    key_parts= param.key_parts;
711
2244
      This is used in get_mm_parts function.
712
2245
    */
713
2246
    key_info= head->key_info;
714
 
    for (idx=0 ; idx < head->getShare()->sizeKeys() ; idx++, key_info++)
 
2247
    for (idx=0 ; idx < head->s->keys ; idx++, key_info++)
715
2248
    {
716
 
      KeyPartInfo *key_part_info;
717
 
      if (! keys_to_use.test(idx))
 
2249
      KEY_PART_INFO *key_part_info;
 
2250
      if (!keys_to_use.is_set(idx))
718
2251
        continue;
719
2252
 
720
2253
      param.key[param.keys]=key_parts;
721
2254
      key_part_info= key_info->key_part;
722
 
      for (uint32_t part=0;
723
 
           part < key_info->key_parts;
724
 
           part++, key_parts++, key_part_info++)
 
2255
      for (uint32_t part=0 ; part < key_info->key_parts ;
 
2256
           part++, key_parts++, key_part_info++)
725
2257
      {
726
 
        key_parts->key= param.keys;
727
 
        key_parts->part= part;
728
 
        key_parts->length= key_part_info->length;
729
 
        key_parts->store_length= key_part_info->store_length;
730
 
        key_parts->field= key_part_info->field;
731
 
        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;
732
2265
        /* Only HA_PART_KEY_SEG is used */
733
 
        key_parts->flag= (uint8_t) key_part_info->key_part_flag;
 
2266
        key_parts->flag=         (uint8_t) key_part_info->key_part_flag;
734
2267
      }
735
2268
      param.real_keynr[param.keys++]=idx;
736
2269
    }
738
2271
    param.alloced_sel_args= 0;
739
2272
 
740
2273
    /* Calculate cost of full index read for the shortest covering index */
741
 
    if (!head->covering_keys.none())
 
2274
    if (!head->covering_keys.is_clear_all())
742
2275
    {
743
2276
      int key_for_use= head->find_shortest_key(&head->covering_keys);
744
2277
      double key_read_time=
745
 
        param.table->cursor->index_only_read_time(key_for_use, records) +
 
2278
        param.table->file->index_only_read_time(key_for_use,
 
2279
                                                rows2double(records)) +
746
2280
        (double) records / TIME_FOR_COMPARE;
747
2281
      if (key_read_time < read_time)
748
2282
        read_time= key_read_time;
749
2283
    }
750
2284
 
751
 
    optimizer::TableReadPlan *best_trp= NULL;
752
 
    optimizer::GroupMinMaxReadPlan *group_trp= NULL;
 
2285
    TABLE_READ_PLAN *best_trp= NULL;
 
2286
    TRP_GROUP_MIN_MAX *group_trp;
753
2287
    double best_read_time= read_time;
754
2288
 
755
2289
    if (cond)
756
2290
    {
757
2291
      if ((tree= get_mm_tree(&param,cond)))
758
2292
      {
759
 
        if (tree->type == optimizer::SEL_TREE::IMPOSSIBLE)
 
2293
        if (tree->type == SEL_TREE::IMPOSSIBLE)
760
2294
        {
761
2295
          records=0L;                      /* Return -1 from this function. */
762
2296
          read_time= (double) HA_POS_ERROR;
766
2300
          If the tree can't be used for range scans, proceed anyway, as we
767
2301
          can construct a group-min-max quick select
768
2302
        */
769
 
        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)
770
2304
          tree= NULL;
771
2305
      }
772
2306
    }
773
2307
 
774
2308
    /*
775
 
      Try to construct a QuickGroupMinMaxSelect.
 
2309
      Try to construct a QUICK_GROUP_MIN_MAX_SELECT.
776
2310
      Notice that it can be constructed no matter if there is a range tree.
777
2311
    */
778
2312
    group_trp= get_best_group_min_max(&param, tree);
779
2313
    if (group_trp)
780
2314
    {
781
 
      param.table->quick_condition_rows= min(group_trp->records,
782
 
                                             head->cursor->stats.records);
 
2315
      param.table->quick_condition_rows= cmin(group_trp->records,
 
2316
                                             head->file->stats.records);
783
2317
      if (group_trp->read_cost < best_read_time)
784
2318
      {
785
2319
        best_trp= group_trp;
795
2329
      */
796
2330
      if (tree->merges.is_empty())
797
2331
      {
798
 
        optimizer::RangeReadPlan *range_trp= NULL;
799
 
        optimizer::RorIntersectReadPlan *rori_trp= NULL;
 
2332
        TRP_RANGE         *range_trp;
 
2333
        TRP_ROR_INTERSECT *rori_trp;
800
2334
        bool can_build_covering= false;
801
2335
 
802
2336
        /* Get best 'range' plan and prepare data for making other plans */
803
 
        if ((range_trp= get_key_scans_params(session, &param, tree, false, true,
 
2337
        if ((range_trp= get_key_scans_params(&param, tree, false, true,
804
2338
                                             best_read_time)))
805
2339
        {
806
2340
          best_trp= range_trp;
808
2342
        }
809
2343
 
810
2344
        /*
811
 
          Simultaneous key scans and row deletes on several Cursor
 
2345
          Simultaneous key scans and row deletes on several handler
812
2346
          objects are not allowed so don't use ROR-intersection for
813
2347
          table deletes.
814
2348
        */
815
 
        if ((session->getLex()->sql_command != SQLCOM_DELETE))
 
2349
        if ((session->lex->sql_command != SQLCOM_DELETE))
816
2350
        {
817
2351
          /*
818
2352
            Get best non-covering ROR-intersection plan and prepare data for
837
2371
      else
838
2372
      {
839
2373
        /* Try creating index_merge/ROR-union scan. */
840
 
        optimizer::SEL_IMERGE *imerge= NULL;
841
 
        optimizer::TableReadPlan *best_conj_trp= NULL;
842
 
        optimizer::TableReadPlan *new_conj_trp= NULL;
843
 
        List<optimizer::SEL_IMERGE>::iterator it(tree->merges.begin());
 
2374
        SEL_IMERGE *imerge;
 
2375
        TABLE_READ_PLAN *best_conj_trp= NULL, *new_conj_trp;
 
2376
        List_iterator_fast<SEL_IMERGE> it(tree->merges);
844
2377
        while ((imerge= it++))
845
2378
        {
846
 
          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);
847
2380
          if (new_conj_trp)
848
2381
            set_if_smaller(param.table->quick_condition_rows,
849
2382
                           new_conj_trp->records);
862
2395
    if (best_trp)
863
2396
    {
864
2397
      records= best_trp->records;
865
 
      if (! (quick= best_trp->make_quick(&param, true)) || quick->init())
 
2398
      if (!(quick= best_trp->make_quick(&param, true)) || quick->init())
866
2399
      {
867
 
        /* quick can already be free here */
868
 
        if (quick)
869
 
        {
870
 
          delete quick;
871
 
          quick= NULL;
872
 
        }
 
2400
        delete quick;
 
2401
        quick= NULL;
873
2402
      }
874
2403
    }
875
2404
 
876
2405
  free_mem:
877
 
    alloc.free_root(MYF(0));                    // Return memory & allocator
 
2406
    free_root(&alloc,MYF(0));                   // Return memory & allocator
878
2407
    session->mem_root= param.old_root;
879
2408
    session->no_errors=0;
880
2409
  }
887
2416
}
888
2417
 
889
2418
/*
890
 
  Get best plan for a optimizer::SEL_IMERGE disjunctive expression.
 
2419
  Get best plan for a SEL_IMERGE disjunctive expression.
891
2420
  SYNOPSIS
892
2421
    get_best_disjunct_quick()
893
 
      session
894
2422
      param     Parameter from check_quick_select function
895
2423
      imerge    Expression to use
896
2424
      read_time Don't create scans with cost > read_time
914
2442
          {cost of ordinary clustered PK scan with n_ranges=n_rows}
915
2443
 
916
2444
      Otherwise, we use the following model to calculate costs:
917
 
      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.
918
2446
      We assume that offsets of rows we need are independent variates with
919
2447
      uniform distribution in [0..max_file_offset] range.
920
2448
 
922
2450
      and "empty" if doesn't contain rows we need.
923
2451
 
924
2452
      Probability that a block is empty is (1 - 1/n_blocks)^n_rows (this
925
 
      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
926
2454
      block #i is empty and 0 otherwise.
927
2455
 
928
2456
      Then E(x_i) = (1 - 1/n_blocks)^n_rows;
953
2481
*/
954
2482
 
955
2483
static
956
 
optimizer::TableReadPlan *get_best_disjunct_quick(Session *session,
957
 
                                                  optimizer::Parameter *param,
958
 
                                                  optimizer::SEL_IMERGE *imerge,
959
 
                                                  double read_time)
 
2484
TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
 
2485
                                         double read_time)
960
2486
{
961
 
  optimizer::SEL_TREE **ptree= NULL;
962
 
  optimizer::IndexMergeReadPlan *imerge_trp= NULL;
 
2487
  SEL_TREE **ptree;
 
2488
  TRP_INDEX_MERGE *imerge_trp= NULL;
963
2489
  uint32_t n_child_scans= imerge->trees_next - imerge->trees;
964
 
  optimizer::RangeReadPlan **range_scans= NULL;
965
 
  optimizer::RangeReadPlan **cur_child= NULL;
966
 
  optimizer::RangeReadPlan **cpk_scan= NULL;
 
2490
  TRP_RANGE **range_scans;
 
2491
  TRP_RANGE **cur_child;
 
2492
  TRP_RANGE **cpk_scan= NULL;
967
2493
  bool imerge_too_expensive= false;
968
2494
  double imerge_cost= 0.0;
969
2495
  ha_rows cpk_scan_records= 0;
970
2496
  ha_rows non_cpk_scan_records= 0;
971
 
  bool pk_is_clustered= param->table->cursor->primary_key_is_clustered();
 
2497
  bool pk_is_clustered= param->table->file->primary_key_is_clustered();
972
2498
  bool all_scans_ror_able= true;
973
2499
  bool all_scans_rors= true;
974
2500
  uint32_t unique_calc_buff_size;
975
 
  optimizer::TableReadPlan **roru_read_plans= NULL;
976
 
  optimizer::TableReadPlan **cur_roru_plan= NULL;
 
2501
  TABLE_READ_PLAN **roru_read_plans;
 
2502
  TABLE_READ_PLAN **cur_roru_plan;
977
2503
  double roru_index_costs;
978
2504
  ha_rows roru_total_records;
979
2505
  double roru_intersect_part= 1.0;
980
2506
 
981
 
  if (! (range_scans= (optimizer::RangeReadPlan**)param->mem_root->alloc_root(sizeof(optimizer::RangeReadPlan*)* n_child_scans)))
982
 
  {
 
2507
  if (!(range_scans= (TRP_RANGE**)alloc_root(param->mem_root,
 
2508
                                             sizeof(TRP_RANGE*)*
 
2509
                                             n_child_scans)))
983
2510
    return NULL;
984
 
  }
985
 
 
986
2511
  /*
987
2512
    Collect best 'range' scan for each of disjuncts, and, while doing so,
988
2513
    analyze possibility of ROR scans. Also calculate some values needed by
992
2517
       ptree != imerge->trees_next;
993
2518
       ptree++, cur_child++)
994
2519
  {
995
 
    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)))
996
2522
    {
997
2523
      /*
998
2524
        One of index scans in this index_merge is more expensive than entire
999
2525
        table read for another available option. The entire index_merge (and
1000
2526
        any possible ROR-union) will be more expensive then, too. We continue
1001
 
        here only to update SqlSelect members.
 
2527
        here only to update SQL_SELECT members.
1002
2528
      */
1003
2529
      imerge_too_expensive= true;
1004
2530
    }
1010
2536
    all_scans_rors &= (*cur_child)->is_ror;
1011
2537
    if (pk_is_clustered &&
1012
2538
        param->real_keynr[(*cur_child)->key_idx] ==
1013
 
        param->table->getShare()->getPrimaryKey())
 
2539
        param->table->s->primary_key)
1014
2540
    {
1015
2541
      cpk_scan= cur_child;
1016
2542
      cpk_scan_records= (*cur_child)->records;
1020
2546
  }
1021
2547
 
1022
2548
  if (imerge_too_expensive || (imerge_cost > read_time) ||
1023
 
      ((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))
1024
2550
  {
1025
2551
    /*
1026
2552
      Bail out if it is obvious that both index_merge and ROR-union will be
1030
2556
  }
1031
2557
  if (all_scans_rors)
1032
2558
  {
1033
 
    roru_read_plans= (optimizer::TableReadPlan **) range_scans;
 
2559
    roru_read_plans= (TABLE_READ_PLAN**)range_scans;
1034
2560
    goto skip_to_ror_scan;
1035
2561
  }
1036
2562
  if (cpk_scan)
1037
2563
  {
1038
2564
    /*
1039
2565
      Add one ROWID comparison for each row retrieved on non-CPK scan.  (it
1040
 
      is done in QuickRangeSelect::row_in_ranges)
 
2566
      is done in QUICK_RANGE_SELECT::row_in_ranges)
1041
2567
     */
1042
2568
    imerge_cost += non_cpk_scan_records / TIME_FOR_COMPARE_ROWID;
1043
2569
  }
1044
2570
 
1045
2571
  /* Calculate cost(rowid_to_row_scan) */
1046
2572
  {
1047
 
    optimizer::CostVector sweep_cost;
1048
 
    Join *join= param->session->getLex()->select_lex.join;
 
2573
    COST_VECT sweep_cost;
 
2574
    JOIN *join= param->session->lex->select_lex.join;
1049
2575
    bool is_interrupted= test(join && join->tables == 1);
1050
2576
    get_sweep_read_cost(param->table, non_cpk_scan_records, is_interrupted,
1051
2577
                        &sweep_cost);
1057
2583
  /* Add Unique operations cost */
1058
2584
  unique_calc_buff_size=
1059
2585
    Unique::get_cost_calc_buff_size((ulong)non_cpk_scan_records,
1060
 
                                    param->table->cursor->ref_length,
 
2586
                                    param->table->file->ref_length,
1061
2587
                                    param->session->variables.sortbuff_size);
1062
2588
  if (param->imerge_cost_buff_size < unique_calc_buff_size)
1063
2589
  {
1064
 
    if (!(param->imerge_cost_buff= (uint*)param->mem_root->alloc_root(unique_calc_buff_size)))
1065
 
    {
 
2590
    if (!(param->imerge_cost_buff= (uint*)alloc_root(param->mem_root,
 
2591
                                                     unique_calc_buff_size)))
1066
2592
      return NULL;
1067
 
    }
1068
 
 
1069
2593
    param->imerge_cost_buff_size= unique_calc_buff_size;
1070
2594
  }
1071
2595
 
1072
2596
  imerge_cost +=
1073
2597
    Unique::get_use_cost(param->imerge_cost_buff, (uint32_t)non_cpk_scan_records,
1074
 
                         param->table->cursor->ref_length,
 
2598
                         param->table->file->ref_length,
1075
2599
                         param->session->variables.sortbuff_size);
1076
2600
  if (imerge_cost < read_time)
1077
2601
  {
1078
 
    if ((imerge_trp= new (param->mem_root) optimizer::IndexMergeReadPlan))
 
2602
    if ((imerge_trp= new (param->mem_root)TRP_INDEX_MERGE))
1079
2603
    {
1080
2604
      imerge_trp->read_cost= imerge_cost;
1081
2605
      imerge_trp->records= non_cpk_scan_records + cpk_scan_records;
1082
 
      imerge_trp->records= min(imerge_trp->records,
1083
 
                               param->table->cursor->stats.records);
 
2606
      imerge_trp->records= cmin(imerge_trp->records,
 
2607
                               param->table->file->stats.records);
1084
2608
      imerge_trp->range_scans= range_scans;
1085
2609
      imerge_trp->range_scans_end= range_scans + n_child_scans;
1086
2610
      read_time= imerge_cost;
1088
2612
  }
1089
2613
 
1090
2614
build_ror_index_merge:
1091
 
  if (!all_scans_ror_able || param->session->getLex()->sql_command == SQLCOM_DELETE)
 
2615
  if (!all_scans_ror_able || param->session->lex->sql_command == SQLCOM_DELETE)
1092
2616
    return(imerge_trp);
1093
2617
 
1094
2618
  /* Ok, it is possible to build a ROR-union, try it. */
1095
2619
  bool dummy;
1096
 
  if (! (roru_read_plans=
1097
 
          (optimizer::TableReadPlan **) param->mem_root->alloc_root(sizeof(optimizer::TableReadPlan*) * n_child_scans)))
1098
 
  {
1099
 
    return imerge_trp;
1100
 
  }
 
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);
1101
2625
skip_to_ror_scan:
1102
2626
  roru_index_costs= 0.0;
1103
2627
  roru_total_records= 0;
1118
2642
    if ((*cur_child)->is_ror)
1119
2643
    {
1120
2644
      /* Ok, we have index_only cost, now get full rows scan cost */
1121
 
      cost= param->table->cursor->
 
2645
      cost= param->table->file->
1122
2646
              read_time(param->real_keynr[(*cur_child)->key_idx], 1,
1123
2647
                        (*cur_child)->records) +
1124
 
              static_cast<double>((*cur_child)->records) / TIME_FOR_COMPARE;
 
2648
              rows2double((*cur_child)->records) / TIME_FOR_COMPARE;
1125
2649
    }
1126
2650
    else
1127
2651
      cost= read_time;
1128
2652
 
1129
 
    optimizer::TableReadPlan *prev_plan= *cur_child;
 
2653
    TABLE_READ_PLAN *prev_plan= *cur_child;
1130
2654
    if (!(*cur_roru_plan= get_best_ror_intersect(param, *ptree, cost,
1131
2655
                                                 &dummy)))
1132
2656
    {
1138
2662
    }
1139
2663
    else
1140
2664
      roru_index_costs +=
1141
 
        ((optimizer::RorIntersectReadPlan*)(*cur_roru_plan))->index_scan_costs;
 
2665
        ((TRP_ROR_INTERSECT*)(*cur_roru_plan))->index_scan_costs;
1142
2666
    roru_total_records += (*cur_roru_plan)->records;
1143
2667
    roru_intersect_part *= (*cur_roru_plan)->records /
1144
 
                           param->table->cursor->stats.records;
 
2668
                           param->table->file->stats.records;
1145
2669
  }
1146
2670
 
1147
2671
  /*
1151
2675
    in disjunction do not share key parts.
1152
2676
  */
1153
2677
  roru_total_records -= (ha_rows)(roru_intersect_part*
1154
 
                                  param->table->cursor->stats.records);
 
2678
                                  param->table->file->stats.records);
1155
2679
  /* ok, got a ROR read plan for each of the disjuncts
1156
2680
    Calculate cost:
1157
2681
    cost(index_union_scan(scan_1, ... scan_n)) =
1162
2686
  */
1163
2687
  double roru_total_cost;
1164
2688
  {
1165
 
    optimizer::CostVector sweep_cost;
1166
 
    Join *join= param->session->getLex()->select_lex.join;
 
2689
    COST_VECT sweep_cost;
 
2690
    JOIN *join= param->session->lex->select_lex.join;
1167
2691
    bool is_interrupted= test(join && join->tables == 1);
1168
2692
    get_sweep_read_cost(param->table, roru_total_records, is_interrupted,
1169
2693
                        &sweep_cost);
1170
2694
    roru_total_cost= roru_index_costs +
1171
 
                     static_cast<double>(roru_total_records)*log((double)n_child_scans) /
 
2695
                     rows2double(roru_total_records)*log((double)n_child_scans) /
1172
2696
                     (TIME_FOR_COMPARE_ROWID * M_LN2) +
1173
2697
                     sweep_cost.total_cost();
1174
2698
  }
1175
2699
 
1176
 
  optimizer::RorUnionReadPlan *roru= NULL;
 
2700
  TRP_ROR_UNION* roru;
1177
2701
  if (roru_total_cost < read_time)
1178
2702
  {
1179
 
    if ((roru= new (param->mem_root) optimizer::RorUnionReadPlan))
 
2703
    if ((roru= new (param->mem_root) TRP_ROR_UNION))
1180
2704
    {
1181
2705
      roru->first_ror= roru_read_plans;
1182
2706
      roru->last_ror= roru_read_plans + n_child_scans;
1183
2707
      roru->read_cost= roru_total_cost;
1184
2708
      roru->records= roru_total_records;
1185
 
      return roru;
 
2709
      return(roru);
1186
2710
    }
1187
2711
  }
1188
2712
  return(imerge_trp);
1189
2713
}
1190
2714
 
1191
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
 
1192
2739
 
1193
2740
/*
1194
 
  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
1195
2742
  sel_arg set of intervals.
1196
2743
 
1197
2744
  SYNOPSIS
1206
2753
*/
1207
2754
 
1208
2755
static
1209
 
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)
1210
2757
{
1211
 
  optimizer::RorScanInfo *ror_scan= NULL;
1212
 
 
 
2758
  ROR_SCAN_INFO *ror_scan;
 
2759
  my_bitmap_map *bitmap_buf;
1213
2760
  uint32_t keynr;
1214
2761
 
1215
 
  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))))
1216
2764
    return NULL;
1217
2765
 
1218
2766
  ror_scan->idx= idx;
1219
2767
  ror_scan->keynr= keynr= param->real_keynr[idx];
1220
2768
  ror_scan->key_rec_length= (param->table->key_info[keynr].key_length +
1221
 
                             param->table->cursor->ref_length);
 
2769
                             param->table->file->ref_length);
1222
2770
  ror_scan->sel_arg= sel_arg;
1223
2771
  ror_scan->records= param->table->quick_rows[keynr];
1224
2772
 
1225
 
  ror_scan->covered_fields_size= param->table->getShare()->sizeFields();
1226
 
  boost::dynamic_bitset<> tmp_bitset(param->table->getShare()->sizeFields());
1227
 
  tmp_bitset.reset();
1228
 
 
1229
 
  KeyPartInfo *key_part= param->table->key_info[keynr].key_part;
1230
 
  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 +
1231
2784
                               param->table->key_info[keynr].key_parts;
1232
 
  for (; key_part != key_part_end; ++key_part)
 
2785
  for (;key_part != key_part_end; ++key_part)
1233
2786
  {
1234
 
    if (param->needed_fields.test(key_part->fieldnr-1))
1235
 
      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);
1236
2789
  }
1237
 
  double rows= param->table->quick_rows[ror_scan->keynr];
 
2790
  double rows= rows2double(param->table->quick_rows[ror_scan->keynr]);
1238
2791
  ror_scan->index_read_cost=
1239
 
    param->table->cursor->index_only_read_time(ror_scan->keynr, rows);
1240
 
  ror_scan->covered_fields= tmp_bitset.to_ulong();
1241
 
  return ror_scan;
 
2792
    param->table->file->index_only_read_time(ror_scan->keynr, rows);
 
2793
  return(ror_scan);
1242
2794
}
1243
2795
 
1244
2796
 
1245
2797
/*
1246
 
  Compare two optimizer::RorScanInfo** by  E(#records_matched) * key_record_length.
 
2798
  Compare two ROR_SCAN_INFO** by  E(#records_matched) * key_record_length.
1247
2799
  SYNOPSIS
1248
2800
    cmp_ror_scan_info()
1249
2801
      a ptr to first compared value
1255
2807
    1 a > b
1256
2808
*/
1257
2809
 
1258
 
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)
1259
2811
{
1260
 
  double val1= static_cast<double>((*a)->records) * (*a)->key_rec_length;
1261
 
  double val2= static_cast<double>((*b)->records) * (*b)->key_rec_length;
 
2812
  double val1= rows2double((*a)->records) * (*a)->key_rec_length;
 
2813
  double val2= rows2double((*b)->records) * (*b)->key_rec_length;
1262
2814
  return (val1 < val2)? -1: (val1 == val2)? 0 : 1;
1263
2815
}
1264
2816
 
1265
 
 
1266
2817
/*
1267
 
  Compare two optimizer::RorScanInfo** by
 
2818
  Compare two ROR_SCAN_INFO** by
1268
2819
   (#covered fields in F desc,
1269
2820
    #components asc,
1270
2821
    number of first not covered component asc)
1280
2831
    1 a > b
1281
2832
*/
1282
2833
 
1283
 
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)
1284
2835
{
1285
2836
  if ((*a)->used_fields_covered > (*b)->used_fields_covered)
1286
2837
    return -1;
1297
2848
  return 0;
1298
2849
}
1299
2850
 
 
2851
 
1300
2852
/* Auxiliary structure for incremental ROR-intersection creation */
1301
 
typedef struct st_ror_intersect_info
 
2853
typedef struct
1302
2854
{
1303
 
  st_ror_intersect_info()
1304
 
    :
1305
 
      param(NULL),
1306
 
      covered_fields(),
1307
 
      out_rows(0.0),
1308
 
      is_covering(false),
1309
 
      index_records(0),
1310
 
      index_scan_costs(0.0),
1311
 
      total_cost(0.0)
1312
 
  {}
1313
 
 
1314
 
  st_ror_intersect_info(const optimizer::Parameter *in_param)
1315
 
    :
1316
 
      param(in_param),
1317
 
      covered_fields(in_param->table->getShare()->sizeFields()),
1318
 
      out_rows(in_param->table->cursor->stats.records),
1319
 
      is_covering(false),
1320
 
      index_records(0),
1321
 
      index_scan_costs(0.0),
1322
 
      total_cost(0.0)
1323
 
  {
1324
 
    covered_fields.reset();
1325
 
  }
1326
 
 
1327
 
  const optimizer::Parameter *param;
1328
 
  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 */
1329
2857
  /*
1330
2858
    Fraction of table records that satisfies conditions of all scans.
1331
2859
    This is the number of full records that will be retrieved if a
1341
2869
} ROR_INTERSECT_INFO;
1342
2870
 
1343
2871
 
1344
 
static void ror_intersect_cpy(ROR_INTERSECT_INFO *dst,
1345
 
                              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)
1346
2908
{
1347
2909
  dst->param= src->param;
1348
 
  dst->covered_fields= src->covered_fields;
 
2910
  memcpy(dst->covered_fields.bitmap, src->covered_fields.bitmap,
 
2911
         no_bytes_in_map(&src->covered_fields));
1349
2912
  dst->out_rows= src->out_rows;
1350
2913
  dst->is_covering= src->is_covering;
1351
2914
  dst->index_records= src->index_records;
1445
3008
*/
1446
3009
 
1447
3010
static double ror_scan_selectivity(const ROR_INTERSECT_INFO *info,
1448
 
                                   const optimizer::RorScanInfo *scan)
 
3011
                                   const ROR_SCAN_INFO *scan)
1449
3012
{
1450
3013
  double selectivity_mult= 1.0;
1451
 
  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;
1452
3015
  unsigned char key_val[MAX_KEY_LENGTH+MAX_FIELD_WIDTH]; /* key values tuple */
1453
3016
  unsigned char *key_ptr= key_val;
1454
 
  optimizer::SEL_ARG *sel_arg= NULL;
1455
 
  optimizer::SEL_ARG *tuple_arg= NULL;
 
3017
  SEL_ARG *sel_arg, *tuple_arg= NULL;
1456
3018
  key_part_map keypart_map= 0;
1457
3019
  bool cur_covered;
1458
 
  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));
1459
3022
  key_range min_range;
1460
3023
  key_range max_range;
1461
3024
  min_range.key= key_val;
1462
3025
  min_range.flag= HA_READ_KEY_EXACT;
1463
3026
  max_range.key= key_val;
1464
3027
  max_range.flag= HA_READ_AFTER_KEY;
1465
 
  ha_rows prev_records= info->param->table->cursor->stats.records;
 
3028
  ha_rows prev_records= info->param->table->file->stats.records;
1466
3029
 
1467
3030
  for (sel_arg= scan->sel_arg; sel_arg;
1468
3031
       sel_arg= sel_arg->next_key_part)
1469
3032
  {
1470
 
    cur_covered=
1471
 
      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));
1472
3035
    if (cur_covered != prev_covered)
1473
3036
    {
1474
3037
      /* create (part1val, ..., part{n-1}val) tuple. */
1489
3052
      }
1490
3053
      min_range.length= max_range.length= (size_t) (key_ptr - key_val);
1491
3054
      min_range.keypart_map= max_range.keypart_map= keypart_map;
1492
 
      records= (info->param->table->cursor->
 
3055
      records= (info->param->table->file->
1493
3056
                records_in_range(scan->keynr, &min_range, &max_range));
1494
3057
      if (cur_covered)
1495
3058
      {
1496
3059
        /* uncovered -> covered */
1497
 
        selectivity_mult *= static_cast<double>(records) / prev_records;
 
3060
        double tmp= rows2double(records)/rows2double(prev_records);
 
3061
        selectivity_mult *= tmp;
1498
3062
        prev_records= HA_POS_ERROR;
1499
3063
      }
1500
3064
      else
1507
3071
  }
1508
3072
  if (!prev_covered)
1509
3073
  {
1510
 
    selectivity_mult *= static_cast<double>(info->param->table->quick_rows[scan->keynr]) / prev_records;
 
3074
    double tmp= rows2double(info->param->table->quick_rows[scan->keynr]) /
 
3075
                rows2double(prev_records);
 
3076
    selectivity_mult *= tmp;
1511
3077
  }
1512
 
  return selectivity_mult;
 
3078
  return(selectivity_mult);
1513
3079
}
1514
3080
 
1515
3081
 
1550
3116
*/
1551
3117
 
1552
3118
static bool ror_intersect_add(ROR_INTERSECT_INFO *info,
1553
 
                              optimizer::RorScanInfo* ror_scan, bool is_cpk_scan)
 
3119
                              ROR_SCAN_INFO* ror_scan, bool is_cpk_scan)
1554
3120
{
1555
3121
  double selectivity_mult= 1.0;
1556
3122
 
1570
3136
      each record of every scan. Assuming 1/TIME_FOR_COMPARE_ROWID
1571
3137
      per check this gives us:
1572
3138
    */
1573
 
    info->index_scan_costs += static_cast<double>(info->index_records) /
 
3139
    info->index_scan_costs += rows2double(info->index_records) /
1574
3140
                              TIME_FOR_COMPARE_ROWID;
1575
3141
  }
1576
3142
  else
1577
3143
  {
1578
3144
    info->index_records += info->param->table->quick_rows[ror_scan->keynr];
1579
3145
    info->index_scan_costs += ror_scan->index_read_cost;
1580
 
    boost::dynamic_bitset<> tmp_bitset= ror_scan->bitsToBitset();
1581
 
    info->covered_fields|= tmp_bitset;
1582
 
    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))
1583
3149
    {
1584
3150
      info->is_covering= true;
1585
3151
    }
1586
3152
  }
1587
3153
 
1588
3154
  info->total_cost= info->index_scan_costs;
1589
 
  if (! info->is_covering)
 
3155
  if (!info->is_covering)
1590
3156
  {
1591
 
    optimizer::CostVector sweep_cost;
1592
 
    Join *join= info->param->session->getLex()->select_lex.join;
 
3157
    COST_VECT sweep_cost;
 
3158
    JOIN *join= info->param->session->lex->select_lex.join;
1593
3159
    bool is_interrupted= test(join && join->tables == 1);
1594
3160
    get_sweep_read_cost(info->param->table, double2rows(info->out_rows),
1595
3161
                        is_interrupted, &sweep_cost);
1600
3166
 
1601
3167
 
1602
3168
/*
1603
 
  Get best covering ROR-intersection.
1604
 
  SYNOPSIS
1605
 
    get_best_covering_ror_intersect()
1606
 
      param     Parameter from test_quick_select function.
1607
 
      tree      optimizer::SEL_TREE with sets of intervals for different keys.
1608
 
      read_time Don't return table read plans with cost > read_time.
1609
 
 
1610
 
  RETURN
1611
 
    Best covering ROR-intersection plan
1612
 
    NULL if no plan found.
1613
 
 
1614
 
  NOTES
1615
 
    get_best_ror_intersect must be called for a tree before calling this
1616
 
    function for it.
1617
 
    This function invalidates tree->ror_scans member values.
1618
 
 
1619
 
  The following approximate algorithm is used:
1620
 
    I=set of all covering indexes
1621
 
    F=set of all fields to cover
1622
 
    S={}
1623
 
 
1624
 
    do
1625
 
    {
1626
 
      Order I by (#covered fields in F desc,
1627
 
                  #components asc,
1628
 
                  number of first not covered component asc);
1629
 
      F=F-covered by first(I);
1630
 
      S=S+first(I);
1631
 
      I=I-first(I);
1632
 
    } while F is not empty.
1633
 
*/
1634
 
 
1635
 
static
1636
 
optimizer::RorIntersectReadPlan *get_best_covering_ror_intersect(optimizer::Parameter *param,
1637
 
                                                            optimizer::SEL_TREE *tree,
1638
 
                                                            double read_time)
1639
 
{
1640
 
  optimizer::RorScanInfo **ror_scan_mark;
1641
 
  optimizer::RorScanInfo **ror_scans_end= tree->ror_scans_end;
1642
 
 
1643
 
  for (optimizer::RorScanInfo **scan= tree->ror_scans; scan != ror_scans_end; ++scan)
1644
 
    (*scan)->key_components=
1645
 
      param->table->key_info[(*scan)->keynr].key_parts;
1646
 
 
1647
 
  /*
1648
 
    Run covering-ROR-search algorithm.
1649
 
    Assume set I is [ror_scan .. ror_scans_end)
1650
 
  */
1651
 
 
1652
 
  /*I=set of all covering indexes */
1653
 
  ror_scan_mark= tree->ror_scans;
1654
 
 
1655
 
  boost::dynamic_bitset<> *covered_fields= &param->tmp_covered_fields;
1656
 
  if (covered_fields->empty())
1657
 
  {
1658
 
    covered_fields->resize(param->table->getShare()->sizeFields());
1659
 
  }
1660
 
  covered_fields->reset();
1661
 
 
1662
 
  double total_cost= 0.0f;
1663
 
  ha_rows records=0;
1664
 
  bool all_covered;
1665
 
 
1666
 
  do
1667
 
  {
1668
 
    /*
1669
 
      Update changed sorting info:
1670
 
        #covered fields,
1671
 
        number of first not covered component
1672
 
      Calculate and save these values for each of remaining scans.
1673
 
    */
1674
 
    for (optimizer::RorScanInfo **scan= ror_scan_mark; scan != ror_scans_end; ++scan)
1675
 
    {
1676
 
      /* subtract one bitset from the other */
1677
 
      (*scan)->subtractBitset(*covered_fields);
1678
 
      (*scan)->used_fields_covered=
1679
 
        (*scan)->getBitCount();
1680
 
      (*scan)->first_uncovered_field= (*scan)->findFirstNotSet();
1681
 
    }
1682
 
 
1683
 
    internal::my_qsort(ror_scan_mark, ror_scans_end-ror_scan_mark,
1684
 
                       sizeof(optimizer::RorScanInfo*),
1685
 
                       (qsort_cmp)cmp_ror_scan_info_covering);
1686
 
 
1687
 
    /* I=I-first(I) */
1688
 
    total_cost += (*ror_scan_mark)->index_read_cost;
1689
 
    records += (*ror_scan_mark)->records;
1690
 
    if (total_cost > read_time)
1691
 
      return NULL;
1692
 
    /* F=F-covered by first(I) */
1693
 
    boost::dynamic_bitset<> tmp_bitset= (*ror_scan_mark)->bitsToBitset();
1694
 
    *covered_fields|= tmp_bitset;
1695
 
    all_covered= param->needed_fields.is_subset_of(*covered_fields);
1696
 
  } while ((++ror_scan_mark < ror_scans_end) && ! all_covered);
1697
 
 
1698
 
  if (!all_covered || (ror_scan_mark - tree->ror_scans) == 1)
1699
 
    return NULL;
1700
 
 
1701
 
  /*
1702
 
    Ok, [tree->ror_scans .. ror_scan) holds covering index_intersection with
1703
 
    cost total_cost.
1704
 
  */
1705
 
  /* Add priority queue use cost. */
1706
 
  total_cost += static_cast<double>(records) *
1707
 
                log((double)(ror_scan_mark - tree->ror_scans)) /
1708
 
                (TIME_FOR_COMPARE_ROWID * M_LN2);
1709
 
 
1710
 
  if (total_cost > read_time)
1711
 
    return NULL;
1712
 
 
1713
 
  optimizer::RorIntersectReadPlan *trp= NULL;
1714
 
  if (! (trp= new (param->mem_root) optimizer::RorIntersectReadPlan))
1715
 
  {
1716
 
    return trp;
1717
 
  }
1718
 
 
1719
 
  uint32_t best_num= (ror_scan_mark - tree->ror_scans);
1720
 
  if (!(trp->first_scan= (optimizer::RorScanInfo**)param->mem_root->alloc_root(sizeof(optimizer::RorScanInfo*)* best_num)))
1721
 
    return NULL;
1722
 
  memcpy(trp->first_scan, tree->ror_scans, best_num*sizeof(optimizer::RorScanInfo*));
1723
 
  trp->last_scan=  trp->first_scan + best_num;
1724
 
  trp->is_covering= true;
1725
 
  trp->read_cost= total_cost;
1726
 
  trp->records= records;
1727
 
  trp->cpk_scan= NULL;
1728
 
  set_if_smaller(param->table->quick_condition_rows, records);
1729
 
 
1730
 
  return(trp);
1731
 
}
1732
 
 
1733
 
 
1734
 
/*
1735
3169
  Get best ROR-intersection plan using non-covering ROR-intersection search
1736
3170
  algorithm. The returned plan may be covering.
1737
3171
 
1796
3230
*/
1797
3231
 
1798
3232
static
1799
 
optimizer::RorIntersectReadPlan *get_best_ror_intersect(const optimizer::Parameter *param,
1800
 
                                                   optimizer::SEL_TREE *tree,
1801
 
                                                   double read_time,
1802
 
                                                   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)
1803
3236
{
1804
 
  uint32_t idx= 0;
 
3237
  uint32_t idx;
1805
3238
  double min_cost= DBL_MAX;
1806
3239
 
1807
 
  if ((tree->n_ror_scans < 2) || ! param->table->cursor->stats.records)
 
3240
  if ((tree->n_ror_scans < 2) || !param->table->file->stats.records)
1808
3241
    return NULL;
1809
3242
 
1810
3243
  /*
1811
 
    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
1812
3245
    them. Also find and save clustered PK scan if there is one.
1813
3246
  */
1814
 
  optimizer::RorScanInfo **cur_ror_scan= NULL;
1815
 
  optimizer::RorScanInfo *cpk_scan= NULL;
1816
 
  uint32_t cpk_no= 0;
 
3247
  ROR_SCAN_INFO **cur_ror_scan;
 
3248
  ROR_SCAN_INFO *cpk_scan= NULL;
 
3249
  uint32_t cpk_no;
1817
3250
  bool cpk_scan_used= false;
1818
3251
 
1819
 
  if (! (tree->ror_scans= (optimizer::RorScanInfo**)param->mem_root->alloc_root(sizeof(optimizer::RorScanInfo*)* param->keys)))
1820
 
  {
 
3252
  if (!(tree->ror_scans= (ROR_SCAN_INFO**)alloc_root(param->mem_root,
 
3253
                                                     sizeof(ROR_SCAN_INFO*)*
 
3254
                                                     param->keys)))
1821
3255
    return NULL;
1822
 
  }
1823
 
  cpk_no= ((param->table->cursor->primary_key_is_clustered()) ?
1824
 
           param->table->getShare()->getPrimaryKey() : MAX_KEY);
 
3256
  cpk_no= ((param->table->file->primary_key_is_clustered()) ?
 
3257
           param->table->s->primary_key : MAX_KEY);
1825
3258
 
1826
3259
  for (idx= 0, cur_ror_scan= tree->ror_scans; idx < param->keys; idx++)
1827
3260
  {
1828
 
    optimizer::RorScanInfo *scan;
1829
 
    if (! tree->ror_scans_map.test(idx))
 
3261
    ROR_SCAN_INFO *scan;
 
3262
    if (!tree->ror_scans_map.is_set(idx))
1830
3263
      continue;
1831
 
    if (! (scan= make_ror_scan(param, idx, tree->keys[idx])))
 
3264
    if (!(scan= make_ror_scan(param, idx, tree->keys[idx])))
1832
3265
      return NULL;
1833
3266
    if (param->real_keynr[idx] == cpk_no)
1834
3267
    {
1840
3273
  }
1841
3274
 
1842
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);
1843
3279
  /*
1844
3280
    Ok, [ror_scans, ror_scans_end) is array of ptrs to initialized
1845
 
    optimizer::RorScanInfo's.
 
3281
    ROR_SCAN_INFO's.
1846
3282
    Step 2: Get best ROR-intersection using an approximate algorithm.
1847
3283
  */
1848
 
  internal::my_qsort(tree->ror_scans, tree->n_ror_scans, sizeof(optimizer::RorScanInfo*),
1849
 
                     (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);
1850
3289
 
1851
 
  optimizer::RorScanInfo **intersect_scans= NULL; /* ROR scans used in index intersection */
1852
 
  optimizer::RorScanInfo **intersect_scans_end= NULL;
1853
 
  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)))
1854
3295
    return NULL;
1855
3296
  intersect_scans_end= intersect_scans;
1856
3297
 
1857
3298
  /* Create and incrementally update ROR intersection. */
1858
 
  ROR_INTERSECT_INFO intersect(param);
1859
 
  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;
1860
3303
 
1861
3304
  /* [intersect_scans,intersect_scans_best) will hold the best intersection */
1862
 
  optimizer::RorScanInfo **intersect_scans_best= NULL;
 
3305
  ROR_SCAN_INFO **intersect_scans_best;
1863
3306
  cur_ror_scan= tree->ror_scans;
1864
3307
  intersect_scans_best= intersect_scans;
1865
 
  while (cur_ror_scan != tree->ror_scans_end && ! intersect.is_covering)
 
3308
  while (cur_ror_scan != tree->ror_scans_end && !intersect->is_covering)
1866
3309
  {
1867
3310
    /* S= S + first(R);  R= R - first(R); */
1868
 
    if (! ror_intersect_add(&intersect, *cur_ror_scan, false))
 
3311
    if (!ror_intersect_add(intersect, *cur_ror_scan, false))
1869
3312
    {
1870
3313
      cur_ror_scan++;
1871
3314
      continue;
1873
3316
 
1874
3317
    *(intersect_scans_end++)= *(cur_ror_scan++);
1875
3318
 
1876
 
    if (intersect.total_cost < min_cost)
 
3319
    if (intersect->total_cost < min_cost)
1877
3320
    {
1878
3321
      /* Local minimum found, save it */
1879
 
      ror_intersect_cpy(&intersect_best, &intersect);
 
3322
      ror_intersect_cpy(intersect_best, intersect);
1880
3323
      intersect_scans_best= intersect_scans_end;
1881
 
      min_cost = intersect.total_cost;
 
3324
      min_cost = intersect->total_cost;
1882
3325
    }
1883
3326
  }
1884
3327
 
1887
3330
    return NULL;
1888
3331
  }
1889
3332
 
1890
 
  *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;
1891
3339
  uint32_t best_num= intersect_scans_best - intersect_scans;
1892
 
  ror_intersect_cpy(&intersect, &intersect_best);
 
3340
  ror_intersect_cpy(intersect, intersect_best);
1893
3341
 
1894
3342
  /*
1895
3343
    Ok, found the best ROR-intersection of non-CPK key scans.
1896
3344
    Check if we should add a CPK scan. If the obtained ROR-intersection is
1897
3345
    covering, it doesn't make sense to add CPK scan.
1898
3346
  */
1899
 
  if (cpk_scan && ! intersect.is_covering)
 
3347
  if (cpk_scan && !intersect->is_covering)
1900
3348
  {
1901
 
    if (ror_intersect_add(&intersect, cpk_scan, true) &&
1902
 
        (intersect.total_cost < min_cost))
 
3349
    if (ror_intersect_add(intersect, cpk_scan, true) &&
 
3350
        (intersect->total_cost < min_cost))
1903
3351
    {
1904
3352
      cpk_scan_used= true;
1905
3353
      intersect_best= intersect; //just set pointer here
1907
3355
  }
1908
3356
 
1909
3357
  /* Ok, return ROR-intersect plan if we have found one */
1910
 
  optimizer::RorIntersectReadPlan *trp= NULL;
 
3358
  TRP_ROR_INTERSECT *trp= NULL;
1911
3359
  if (min_cost < read_time && (cpk_scan_used || best_num > 1))
1912
3360
  {
1913
 
    if (! (trp= new (param->mem_root) optimizer::RorIntersectReadPlan))
1914
 
      return trp;
1915
 
 
1916
 
    if (! (trp->first_scan=
1917
 
           (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)))
1918
3366
      return NULL;
1919
 
    memcpy(trp->first_scan, intersect_scans, best_num*sizeof(optimizer::RorScanInfo*));
 
3367
    memcpy(trp->first_scan, intersect_scans, best_num*sizeof(ROR_SCAN_INFO*));
1920
3368
    trp->last_scan=  trp->first_scan + best_num;
1921
 
    trp->is_covering= intersect_best.is_covering;
1922
 
    trp->read_cost= intersect_best.total_cost;
 
3369
    trp->is_covering= intersect_best->is_covering;
 
3370
    trp->read_cost= intersect_best->total_cost;
1923
3371
    /* Prevent divisons by zero */
1924
 
    ha_rows best_rows = double2rows(intersect_best.out_rows);
1925
 
    if (! best_rows)
 
3372
    ha_rows best_rows = double2rows(intersect_best->out_rows);
 
3373
    if (!best_rows)
1926
3374
      best_rows= 1;
1927
3375
    set_if_smaller(param->table->quick_condition_rows, best_rows);
1928
3376
    trp->records= best_rows;
1929
 
    trp->index_scan_costs= intersect_best.index_scan_costs;
 
3377
    trp->index_scan_costs= intersect_best->index_scan_costs;
1930
3378
    trp->cpk_scan= cpk_scan_used? cpk_scan: NULL;
1931
3379
  }
1932
 
  return trp;
1933
 
}
1934
 
 
1935
 
 
1936
 
/*
1937
 
  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
1938
3529
 
1939
3530
  SYNOPSIS
1940
3531
    get_key_scans_params()
1941
 
      session
1942
3532
      param                    Parameters from test_quick_select
1943
 
      tree                     Make range select for this optimizer::SEL_TREE
 
3533
      tree                     Make range select for this SEL_TREE
1944
3534
      index_read_must_be_used  true <=> assume 'index only' option will be set
1945
3535
                               (except for clustered PK indexes)
1946
3536
      update_tbl_stats         true <=> update table->quick_* with information
1949
3539
                               cost > read_time.
1950
3540
 
1951
3541
  DESCRIPTION
1952
 
    Find the best "range" table read plan for given optimizer::SEL_TREE.
 
3542
    Find the best "range" table read plan for given SEL_TREE.
1953
3543
    The side effects are
1954
3544
     - tree->ror_scans is updated to indicate which scans are ROR scans.
1955
3545
     - if update_tbl_stats=true then table->quick_* is updated with info
1960
3550
    NULL if no plan found or error occurred
1961
3551
*/
1962
3552
 
1963
 
static optimizer::RangeReadPlan *get_key_scans_params(Session *session,
1964
 
                                                      optimizer::Parameter *param,
1965
 
                                                      optimizer::SEL_TREE *tree,
1966
 
                                                      bool index_read_must_be_used,
1967
 
                                                      bool update_tbl_stats,
1968
 
                                                      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)
1969
3557
{
1970
3558
  uint32_t idx;
1971
 
  optimizer::SEL_ARG **key= NULL;
1972
 
  optimizer::SEL_ARG **end= NULL;
1973
 
  optimizer::SEL_ARG **key_to_read= NULL;
 
3559
  SEL_ARG **key,**end, **key_to_read= NULL;
1974
3560
  ha_rows best_records= 0;
1975
 
  uint32_t best_mrr_flags= 0;
1976
 
  uint32_t best_buf_size= 0;
1977
 
  optimizer::RangeReadPlan *read_plan= NULL;
 
3561
  uint32_t    best_mrr_flags= 0, best_buf_size= 0;
 
3562
  TRP_RANGE* read_plan= NULL;
1978
3563
  /*
1979
 
    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
1980
3565
    key reads at all, e.g. tree for expression "key1 is not null" where key1
1981
3566
    is defined as "not null".
1982
3567
  */
1983
 
  tree->ror_scans_map.reset();
 
3568
  print_sel_tree(param, tree, &tree->keys_map, "tree scans");
 
3569
  tree->ror_scans_map.clear_all();
1984
3570
  tree->n_ror_scans= 0;
1985
3571
  for (idx= 0,key=tree->keys, end=key+param->keys; key != end; key++,idx++)
1986
3572
  {
1987
3573
    if (*key)
1988
3574
    {
1989
3575
      ha_rows found_records;
1990
 
      optimizer::CostVector cost;
1991
 
      double found_read_time= 0.0;
 
3576
      COST_VECT cost;
 
3577
      double found_read_time;
1992
3578
      uint32_t mrr_flags, buf_size;
1993
3579
      uint32_t keynr= param->real_keynr[idx];
1994
 
      if ((*key)->type == optimizer::SEL_ARG::MAYBE_KEY ||
 
3580
      if ((*key)->type == SEL_ARG::MAYBE_KEY ||
1995
3581
          (*key)->maybe_flag)
1996
 
        param->needed_reg->set(keynr);
 
3582
        param->needed_reg->set_bit(keynr);
1997
3583
 
1998
3584
      bool read_index_only= index_read_must_be_used ||
1999
 
                            param->table->covering_keys.test(keynr);
 
3585
                            param->table->covering_keys.is_set(keynr);
2000
3586
 
2001
 
      found_records= check_quick_select(session, param, idx, read_index_only, *key,
 
3587
      found_records= check_quick_select(param, idx, read_index_only, *key,
2002
3588
                                        update_tbl_stats, &mrr_flags,
2003
3589
                                        &buf_size, &cost);
2004
3590
      found_read_time= cost.total_cost();
2005
3591
      if ((found_records != HA_POS_ERROR) && param->is_ror_scan)
2006
3592
      {
2007
3593
        tree->n_ror_scans++;
2008
 
        tree->ror_scans_map.set(idx);
 
3594
        tree->ror_scans_map.set_bit(idx);
2009
3595
      }
2010
3596
      if (read_time > found_read_time && found_records != HA_POS_ERROR)
2011
3597
      {
2018
3604
    }
2019
3605
  }
2020
3606
 
 
3607
  print_sel_tree(param, tree, &tree->ror_scans_map, "ROR scans");
2021
3608
  if (key_to_read)
2022
3609
  {
2023
3610
    idx= key_to_read - tree->keys;
2024
 
    if ((read_plan= new (param->mem_root) optimizer::RangeReadPlan(*key_to_read, idx,
2025
 
                                                                   best_mrr_flags)))
 
3611
    if ((read_plan= new (param->mem_root) TRP_RANGE(*key_to_read, idx,
 
3612
                                                    best_mrr_flags)))
2026
3613
    {
2027
3614
      read_plan->records= best_records;
2028
 
      read_plan->is_ror= tree->ror_scans_map.test(idx);
 
3615
      read_plan->is_ror= tree->ror_scans_map.is_set(idx);
2029
3616
      read_plan->read_cost= read_time;
2030
3617
      read_plan->mrr_buf_size= best_buf_size;
2031
3618
    }
2035
3622
}
2036
3623
 
2037
3624
 
2038
 
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 *)
2039
3626
{
2040
 
  optimizer::QuickIndexMergeSelect *quick_imerge;
2041
 
  optimizer::QuickRangeSelect *quick= NULL;
 
3627
  QUICK_INDEX_MERGE_SELECT *quick_imerge;
 
3628
  QUICK_RANGE_SELECT *quick;
2042
3629
  /* index_merge always retrieves full rows, ignore retrieve_full_rows */
2043
 
  if (! (quick_imerge= new optimizer::QuickIndexMergeSelect(param->session, param->table)))
2044
 
  {
 
3630
  if (!(quick_imerge= new QUICK_INDEX_MERGE_SELECT(param->session, param->table)))
2045
3631
    return NULL;
2046
 
  }
2047
3632
 
2048
3633
  quick_imerge->records= records;
2049
3634
  quick_imerge->read_time= read_cost;
2050
 
  for (optimizer::RangeReadPlan **range_scan= range_scans; 
2051
 
       range_scan != range_scans_end;
 
3635
  for (TRP_RANGE **range_scan= range_scans; range_scan != range_scans_end;
2052
3636
       range_scan++)
2053
3637
  {
2054
 
    if (! (quick= (optimizer::QuickRangeSelect*)
2055
 
          ((*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)))||
2056
3640
        quick_imerge->push_quick_back(quick))
2057
3641
    {
2058
3642
      delete quick;
2063
3647
  return quick_imerge;
2064
3648
}
2065
3649
 
2066
 
optimizer::QuickSelectInterface *optimizer::RorIntersectReadPlan::make_quick(optimizer::Parameter *param,
2067
 
                                                                             bool retrieve_full_rows,
2068
 
                                                                             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)
2069
3653
{
2070
 
  optimizer::QuickRorIntersectSelect *quick_intersect= NULL;
2071
 
  optimizer::QuickRangeSelect *quick= NULL;
2072
 
  memory::Root *alloc= NULL;
 
3654
  QUICK_ROR_INTERSECT_SELECT *quick_intrsect;
 
3655
  QUICK_RANGE_SELECT *quick;
 
3656
  MEM_ROOT *alloc;
2073
3657
 
2074
 
  if ((quick_intersect=
2075
 
         new optimizer::QuickRorIntersectSelect(param->session,
2076
 
                                                param->table,
2077
 
                                                (retrieve_full_rows? (! is_covering) : false),
2078
 
                                                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)))
2079
3663
  {
2080
 
    alloc= parent_alloc ? parent_alloc : &quick_intersect->alloc;
2081
 
    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)
2082
3669
    {
2083
 
      if (! (quick= optimizer::get_quick_select(param,
2084
 
                                                (*first_scan)->idx,
2085
 
                                                (*first_scan)->sel_arg,
2086
 
                                                HA_MRR_USE_DEFAULT_IMPL | HA_MRR_SORTED,
2087
 
                                                0,
2088
 
                                                alloc)) ||
2089
 
          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))
2090
3675
      {
2091
 
        delete quick_intersect;
 
3676
        delete quick_intrsect;
2092
3677
        return NULL;
2093
3678
      }
2094
3679
    }
2095
3680
    if (cpk_scan)
2096
3681
    {
2097
 
      if (! (quick= optimizer::get_quick_select(param,
2098
 
                                                cpk_scan->idx,
2099
 
                                                cpk_scan->sel_arg,
2100
 
                                                HA_MRR_USE_DEFAULT_IMPL | HA_MRR_SORTED,
2101
 
                                                0,
2102
 
                                                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)))
2103
3686
      {
2104
 
        delete quick_intersect;
 
3687
        delete quick_intrsect;
2105
3688
        return NULL;
2106
3689
      }
2107
 
      quick->resetCursor();
2108
 
      quick_intersect->cpk_quick= quick;
 
3690
      quick->file= NULL;
 
3691
      quick_intrsect->cpk_quick= quick;
2109
3692
    }
2110
 
    quick_intersect->records= records;
2111
 
    quick_intersect->read_time= read_cost;
 
3693
    quick_intrsect->records= records;
 
3694
    quick_intrsect->read_time= read_cost;
2112
3695
  }
2113
 
  return quick_intersect;
 
3696
  return(quick_intrsect);
2114
3697
}
2115
3698
 
2116
3699
 
2117
 
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 *)
2118
3701
{
2119
 
  optimizer::QuickRorUnionSelect *quick_roru= NULL;
2120
 
  optimizer::TableReadPlan **scan= NULL;
2121
 
  optimizer::QuickSelectInterface *quick= NULL;
 
3702
  QUICK_ROR_UNION_SELECT *quick_roru;
 
3703
  TABLE_READ_PLAN **scan;
 
3704
  QUICK_SELECT_I *quick;
2122
3705
  /*
2123
3706
    It is impossible to construct a ROR-union that will not retrieve full
2124
3707
    rows, ignore retrieve_full_rows parameter.
2125
3708
  */
2126
 
  if ((quick_roru= new optimizer::QuickRorUnionSelect(param->session, param->table)))
 
3709
  if ((quick_roru= new QUICK_ROR_UNION_SELECT(param->session, param->table)))
2127
3710
  {
2128
3711
    for (scan= first_ror; scan != last_ror; scan++)
2129
3712
    {
2130
 
      if (! (quick= (*scan)->make_quick(param, false, &quick_roru->alloc)) ||
 
3713
      if (!(quick= (*scan)->make_quick(param, false, &quick_roru->alloc)) ||
2131
3714
          quick_roru->push_quick_back(quick))
2132
 
      {
2133
3715
        return NULL;
2134
 
      }
2135
3716
    }
2136
3717
    quick_roru->records= records;
2137
3718
    quick_roru->read_time= read_cost;
2138
3719
  }
2139
 
  return quick_roru;
 
3720
  return(quick_roru);
2140
3721
}
2141
3722
 
2142
3723
 
2143
3724
/*
2144
 
  Build a optimizer::SEL_TREE for <> or NOT BETWEEN predicate
 
3725
  Build a SEL_TREE for <> or NOT BETWEEN predicate
2145
3726
 
2146
3727
  SYNOPSIS
2147
3728
    get_ne_mm_tree()
2148
 
      param       Parameter from SqlSelect::test_quick_select
 
3729
      param       PARAM from SQL_SELECT::test_quick_select
2149
3730
      cond_func   item for the predicate
2150
3731
      field       field in the predicate
2151
3732
      lt_value    constant that field should be smaller
2156
3737
    #  Pointer to tree built tree
2157
3738
    0  on error
2158
3739
*/
2159
 
static optimizer::SEL_TREE *get_ne_mm_tree(optimizer::RangeParameter *param,
2160
 
                                Item_func *cond_func,
 
3740
 
 
3741
static SEL_TREE *get_ne_mm_tree(RANGE_OPT_PARAM *param, Item_func *cond_func,
2161
3742
                                Field *field,
2162
3743
                                Item *lt_value, Item *gt_value,
2163
3744
                                Item_result cmp_type)
2164
3745
{
2165
 
  optimizer::SEL_TREE *tree= NULL;
 
3746
  SEL_TREE *tree;
2166
3747
  tree= get_mm_parts(param, cond_func, field, Item_func::LT_FUNC,
2167
3748
                     lt_value, cmp_type);
2168
3749
  if (tree)
2169
3750
  {
2170
 
    tree= tree_or(param,
2171
 
                  tree,
2172
 
                  get_mm_parts(param, cond_func, field,
2173
 
                                                Item_func::GT_FUNC,
2174
 
                                                gt_value,
2175
 
                  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));
2176
3754
  }
2177
3755
  return tree;
2178
3756
}
2179
3757
 
2180
3758
 
2181
3759
/*
2182
 
  Build a optimizer::SEL_TREE for a simple predicate
 
3760
  Build a SEL_TREE for a simple predicate
2183
3761
 
2184
3762
  SYNOPSIS
2185
3763
    get_func_mm_tree()
2186
 
      param       Parameter from SqlSelect::test_quick_select
 
3764
      param       PARAM from SQL_SELECT::test_quick_select
2187
3765
      cond_func   item for the predicate
2188
3766
      field       field in the predicate
2189
3767
      value       constant in the predicate
2194
3772
  RETURN
2195
3773
    Pointer to the tree built tree
2196
3774
*/
2197
 
static optimizer::SEL_TREE *get_func_mm_tree(optimizer::RangeParameter *param,
2198
 
                                  Item_func *cond_func,
2199
 
                                  Field *field, 
2200
 
                                  Item *value,
2201
 
                                  Item_result cmp_type, 
2202
 
                                  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)
2203
3779
{
2204
 
  optimizer::SEL_TREE *tree= NULL;
 
3780
  SEL_TREE *tree= 0;
2205
3781
 
2206
 
  switch (cond_func->functype()) 
2207
 
  {
 
3782
  switch (cond_func->functype()) {
2208
3783
 
2209
3784
  case Item_func::NE_FUNC:
2210
3785
    tree= get_ne_mm_tree(param, cond_func, field, value, value, cmp_type);
2212
3787
 
2213
3788
  case Item_func::BETWEEN:
2214
3789
  {
2215
 
    if (! value)
 
3790
    if (!value)
2216
3791
    {
2217
3792
      if (inv)
2218
3793
      {
2219
 
        tree= get_ne_mm_tree(param, 
2220
 
                             cond_func, 
2221
 
                             field, 
2222
 
                             cond_func->arguments()[1],
2223
 
                             cond_func->arguments()[2], 
2224
 
                             cmp_type);
 
3794
        tree= get_ne_mm_tree(param, cond_func, field, cond_func->arguments()[1],
 
3795
                             cond_func->arguments()[2], cmp_type);
2225
3796
      }
2226
3797
      else
2227
3798
      {
2228
 
        tree= get_mm_parts(param, 
2229
 
                           cond_func, 
2230
 
                           field, 
2231
 
                           Item_func::GE_FUNC,
2232
 
                                       cond_func->arguments()[1],
2233
 
                           cmp_type);
 
3799
        tree= get_mm_parts(param, cond_func, field, Item_func::GE_FUNC,
 
3800
                           cond_func->arguments()[1],cmp_type);
2234
3801
        if (tree)
2235
3802
        {
2236
 
          tree= tree_and(param, 
2237
 
                         tree, 
2238
 
                         get_mm_parts(param, cond_func, field,
2239
 
                                                       Item_func::LE_FUNC,
2240
 
                                                       cond_func->arguments()[2],
2241
 
                         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));
2242
3807
        }
2243
3808
      }
2244
3809
    }
2245
3810
    else
2246
 
      tree= get_mm_parts(param, 
2247
 
                         cond_func, 
2248
 
                         field,
 
3811
      tree= get_mm_parts(param, cond_func, field,
2249
3812
                         (inv ?
2250
3813
                          (value == (Item*)1 ? Item_func::GT_FUNC :
2251
3814
                                               Item_func::LT_FUNC):
2252
3815
                          (value == (Item*)1 ? Item_func::LE_FUNC :
2253
3816
                                               Item_func::GE_FUNC)),
2254
 
                         cond_func->arguments()[0], 
2255
 
                         cmp_type);
 
3817
                         cond_func->arguments()[0], cmp_type);
2256
3818
    break;
2257
3819
  }
2258
3820
  case Item_func::IN_FUNC:
2259
3821
  {
2260
 
    Item_func_in *func= (Item_func_in*) cond_func;
 
3822
    Item_func_in *func=(Item_func_in*) cond_func;
2261
3823
 
2262
3824
    /*
2263
3825
      Array for IN() is constructed when all values have the same result
2264
3826
      type. Tree won't be built for values with different result types,
2265
3827
      so we check it here to avoid unnecessary work.
2266
3828
    */
2267
 
    if (! func->arg_types_compatible)
 
3829
    if (!func->arg_types_compatible)
2268
3830
      break;
2269
3831
 
2270
3832
    if (inv)
2273
3835
      {
2274
3836
        /*
2275
3837
          We get here for conditions in form "t.key NOT IN (c1, c2, ...)",
2276
 
          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
2277
3839
          represents intervals:
2278
3840
 
2279
3841
          ($MIN<t.key<c1) OR (c1<t.key<c2) OR (c2<t.key<c3) OR ...    (*)
2282
3844
 
2283
3845
          The most straightforward way to produce it is to convert NOT IN
2284
3846
          into "(t.key != c1) AND (t.key != c2) AND ... " and let the range
2285
 
          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
2286
3848
          range analyzer will use O(N^2) memory (which is probably a bug),
2287
3849
          and people do use big NOT IN lists (e.g. see BUG#15872, BUG#21282),
2288
3850
          will run out of memory.
2295
3857
 
2296
3858
          Considering the above, we'll handle NOT IN as follows:
2297
3859
          * if the number of entries in the NOT IN list is less than
2298
 
            NOT_IN_IGNORE_THRESHOLD, construct the optimizer::SEL_TREE (*) manually.
2299
 
          * 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.
2300
3862
        */
2301
3863
#define NOT_IN_IGNORE_THRESHOLD 1000
2302
 
        memory::Root *tmp_root= param->mem_root;
 
3864
        MEM_ROOT *tmp_root= param->mem_root;
2303
3865
        param->session->mem_root= param->old_root;
2304
3866
        /*
2305
3867
          Create one Item_type constant object. We'll need it as
2312
3874
        Item *value_item= func->array->create_item();
2313
3875
        param->session->mem_root= tmp_root;
2314
3876
 
2315
 
        if (func->array->count > NOT_IN_IGNORE_THRESHOLD || ! value_item)
 
3877
        if (func->array->count > NOT_IN_IGNORE_THRESHOLD || !value_item)
2316
3878
          break;
2317
3879
 
2318
 
        /* Get a optimizer::SEL_TREE for "(-inf|NULL) < X < c_0" interval.  */
 
3880
        /* Get a SEL_TREE for "(-inf|NULL) < X < c_0" interval.  */
2319
3881
        uint32_t i=0;
2320
3882
        do
2321
3883
        {
2322
3884
          func->array->value_to_item(i, value_item);
2323
 
          tree= get_mm_parts(param, 
2324
 
                             cond_func, 
2325
 
                             field, Item_func::LT_FUNC,
2326
 
                             value_item, 
2327
 
                             cmp_type);
2328
 
          if (! tree)
 
3885
          tree= get_mm_parts(param, cond_func, field, Item_func::LT_FUNC,
 
3886
                             value_item, cmp_type);
 
3887
          if (!tree)
2329
3888
            break;
2330
3889
          i++;
2331
 
        } while (i < func->array->count && tree->type == optimizer::SEL_TREE::IMPOSSIBLE);
 
3890
        } while (i < func->array->count && tree->type == SEL_TREE::IMPOSSIBLE);
2332
3891
 
2333
 
        if (!tree || tree->type == optimizer::SEL_TREE::IMPOSSIBLE)
 
3892
        if (!tree || tree->type == SEL_TREE::IMPOSSIBLE)
2334
3893
        {
2335
3894
          /* We get here in cases like "t.unsigned NOT IN (-1,-2,-3) */
2336
3895
          tree= NULL;
2337
3896
          break;
2338
3897
        }
2339
 
        optimizer::SEL_TREE *tree2= NULL;
 
3898
        SEL_TREE *tree2;
2340
3899
        for (; i < func->array->count; i++)
2341
3900
        {
2342
3901
          if (func->array->compare_elems(i, i-1))
2343
3902
          {
2344
 
            /* Get a optimizer::SEL_TREE for "-inf < X < c_i" interval */
 
3903
            /* Get a SEL_TREE for "-inf < X < c_i" interval */
2345
3904
            func->array->value_to_item(i, value_item);
2346
3905
            tree2= get_mm_parts(param, cond_func, field, Item_func::LT_FUNC,
2347
3906
                                value_item, cmp_type);
2354
3913
            /* Change all intervals to be "c_{i-1} < X < c_i" */
2355
3914
            for (uint32_t idx= 0; idx < param->keys; idx++)
2356
3915
            {
2357
 
              optimizer::SEL_ARG *new_interval, *last_val;
 
3916
              SEL_ARG *new_interval, *last_val;
2358
3917
              if (((new_interval= tree2->keys[idx])) &&
2359
3918
                  (tree->keys[idx]) &&
2360
3919
                  ((last_val= tree->keys[idx]->last())))
2371
3930
          }
2372
3931
        }
2373
3932
 
2374
 
        if (tree && tree->type != optimizer::SEL_TREE::IMPOSSIBLE)
 
3933
        if (tree && tree->type != SEL_TREE::IMPOSSIBLE)
2375
3934
        {
2376
3935
          /*
2377
 
            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
2378
3937
            (value_item cotains c_last already)
2379
3938
          */
2380
3939
          tree2= get_mm_parts(param, cond_func, field, Item_func::GT_FUNC,
2438
3997
 
2439
3998
 
2440
3999
/*
2441
 
  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
2442
4001
 
2443
4002
  SYNOPSIS
2444
4003
    get_full_func_mm_tree()
2445
 
      param       Parameter from SqlSelect::test_quick_select
 
4004
      param       PARAM from SQL_SELECT::test_quick_select
2446
4005
      cond_func   item for the predicate
2447
4006
      field_item  field in the predicate
2448
4007
      value       constant in the predicate
2453
4012
 
2454
4013
  DESCRIPTION
2455
4014
    For a simple SARGable predicate of the form (f op c), where f is a field and
2456
 
    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
2457
4016
    be obtained by the substitution of f for all different fields equal to f.
2458
4017
 
2459
4018
  NOTES
2463
4022
    each fj belonging to the same multiple equality as fi
2464
4023
    are built as well.
2465
4024
    E.g. for WHERE t1.a=t2.a AND t2.a > 10
2466
 
    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
2467
4026
    and
2468
 
    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.
2469
4028
 
2470
4029
    A BETWEEN predicate of the form (fi [NOT] BETWEEN c1 AND c2) is treated
2471
4030
    in a similar way: we build a conjuction of trees for the results
2504
4063
    the form (c IN (c1,...,f,...,cn)).
2505
4064
 
2506
4065
  RETURN
2507
 
    Pointer to the tree representing the built conjunction of optimizer::SEL_TREEs
 
4066
    Pointer to the tree representing the built conjunction of SEL_TREEs
2508
4067
*/
2509
4068
 
2510
 
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,
2511
4070
                                       Item_func *cond_func,
2512
4071
                                       Item_field *field_item, Item *value,
2513
4072
                                       bool inv)
2514
4073
{
2515
 
  optimizer::SEL_TREE *tree= 0;
2516
 
  optimizer::SEL_TREE *ftree= 0;
 
4074
  SEL_TREE *tree= 0;
 
4075
  SEL_TREE *ftree= 0;
2517
4076
  table_map ref_tables= 0;
2518
4077
  table_map param_comp= ~(param->prev_tables | param->read_tables |
2519
4078
                          param->current_table);
2524
4083
    if (arg != field_item)
2525
4084
      ref_tables|= arg->used_tables();
2526
4085
  }
2527
 
 
2528
4086
  Field *field= field_item->field;
2529
 
  field->setWriteSet();
2530
 
 
2531
4087
  Item_result cmp_type= field->cmp_type();
2532
 
  if (!((ref_tables | field->getTable()->map) & param_comp))
 
4088
  if (!((ref_tables | field->table->map) & param_comp))
2533
4089
    ftree= get_func_mm_tree(param, cond_func, field, value, cmp_type, inv);
2534
4090
  Item_equal *item_equal= field_item->item_equal;
2535
4091
  if (item_equal)
2539
4095
    while ((item= it++))
2540
4096
    {
2541
4097
      Field *f= item->field;
2542
 
      f->setWriteSet();
2543
 
 
2544
4098
      if (field->eq(f))
2545
4099
        continue;
2546
 
      if (!((ref_tables | f->getTable()->map) & param_comp))
 
4100
      if (!((ref_tables | f->table->map) & param_comp))
2547
4101
      {
2548
4102
        tree= get_func_mm_tree(param, cond_func, f, value, cmp_type, inv);
2549
4103
        ftree= !ftree ? tree : tree_and(param, ftree, tree);
2555
4109
 
2556
4110
        /* make a select tree of all keys in condition */
2557
4111
 
2558
 
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)
2559
4113
{
2560
 
  optimizer::SEL_TREE *tree=0;
2561
 
  optimizer::SEL_TREE *ftree= 0;
 
4114
  SEL_TREE *tree=0;
 
4115
  SEL_TREE *ftree= 0;
2562
4116
  Item_field *field_item= 0;
2563
4117
  bool inv= false;
2564
4118
  Item *value= 0;
2565
4119
 
2566
4120
  if (cond->type() == Item::COND_ITEM)
2567
4121
  {
2568
 
    List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
 
4122
    List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
2569
4123
 
2570
4124
    if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
2571
4125
    {
2573
4127
      Item *item;
2574
4128
      while ((item=li++))
2575
4129
      {
2576
 
        optimizer::SEL_TREE *new_tree= get_mm_tree(param,item);
 
4130
        SEL_TREE *new_tree=get_mm_tree(param,item);
2577
4131
        if (param->session->is_fatal_error ||
2578
 
            param->alloced_sel_args > optimizer::SEL_ARG::MAX_SEL_ARGS)
 
4132
            param->alloced_sel_args > SEL_ARG::MAX_SEL_ARGS)
2579
4133
          return 0;     // out of memory
2580
4134
        tree=tree_and(param,tree,new_tree);
2581
 
        if (tree && tree->type == optimizer::SEL_TREE::IMPOSSIBLE)
 
4135
        if (tree && tree->type == SEL_TREE::IMPOSSIBLE)
2582
4136
          break;
2583
4137
      }
2584
4138
    }
2585
4139
    else
2586
4140
    {                                           // COND OR
2587
 
      tree= get_mm_tree(param,li++);
 
4141
      tree=get_mm_tree(param,li++);
2588
4142
      if (tree)
2589
4143
      {
2590
4144
        Item *item;
2591
4145
        while ((item=li++))
2592
4146
        {
2593
 
          optimizer::SEL_TREE *new_tree= get_mm_tree(param,item);
 
4147
          SEL_TREE *new_tree=get_mm_tree(param,item);
2594
4148
          if (!new_tree)
2595
4149
            return 0;   // out of memory
2596
4150
          tree=tree_or(param,tree,new_tree);
2597
 
          if (!tree || tree->type == optimizer::SEL_TREE::ALWAYS)
 
4151
          if (!tree || tree->type == SEL_TREE::ALWAYS)
2598
4152
            break;
2599
4153
        }
2600
4154
      }
2601
4155
    }
2602
4156
    return(tree);
2603
4157
  }
2604
 
  /* Here when simple cond
2605
 
     There are limits on what kinds of const items we can evaluate, grep for
2606
 
     DontEvaluateMaterializedSubqueryTooEarly.
2607
 
  */
2608
 
  if (cond->const_item()  && !cond->is_expensive())
 
4158
  /* Here when simple cond */
 
4159
  if (cond->const_item())
2609
4160
  {
2610
4161
    /*
2611
4162
      During the cond->val_int() evaluation we can come across a subselect
2613
4164
      all the memory allocated has the same life span as the subselect
2614
4165
      item itself. So we have to restore the thread's mem_root here.
2615
4166
    */
2616
 
    memory::Root *tmp_root= param->mem_root;
 
4167
    MEM_ROOT *tmp_root= param->mem_root;
2617
4168
    param->session->mem_root= param->old_root;
2618
 
    tree= cond->val_int() ? new(tmp_root) optimizer::SEL_TREE(optimizer::SEL_TREE::ALWAYS) :
2619
 
                            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);
2620
4171
    param->session->mem_root= tmp_root;
2621
4172
    return(tree);
2622
4173
  }
2630
4181
    if ((ref_tables & param->current_table) ||
2631
4182
        (ref_tables & ~(param->prev_tables | param->read_tables)))
2632
4183
      return 0;
2633
 
    return(new optimizer::SEL_TREE(optimizer::SEL_TREE::MAYBE));
 
4184
    return(new SEL_TREE(SEL_TREE::MAYBE));
2634
4185
  }
2635
4186
 
2636
4187
  Item_func *cond_func= (Item_func*) cond;
2659
4210
      if (cond_func->arguments()[i]->real_item()->type() == Item::FIELD_ITEM)
2660
4211
      {
2661
4212
        field_item= (Item_field*) (cond_func->arguments()[i]->real_item());
2662
 
        optimizer::SEL_TREE *tmp= get_full_func_mm_tree(param, cond_func,
 
4213
        SEL_TREE *tmp= get_full_func_mm_tree(param, cond_func,
2663
4214
                                    field_item, (Item*)(intptr_t)i, inv);
2664
4215
        if (inv)
2665
4216
          tree= !tree ? tmp : tree_or(param, tree, tmp);
2694
4245
    while ((field_item= it++))
2695
4246
    {
2696
4247
      Field *field= field_item->field;
2697
 
      field->setWriteSet();
2698
 
 
2699
4248
      Item_result cmp_type= field->cmp_type();
2700
 
      if (!((ref_tables | field->getTable()->map) & param_comp))
 
4249
      if (!((ref_tables | field->table->map) & param_comp))
2701
4250
      {
2702
4251
        tree= get_mm_parts(param, cond, field, Item_func::EQ_FUNC,
2703
4252
                           value,cmp_type);
2729
4278
}
2730
4279
 
2731
4280
 
2732
 
static optimizer::SEL_TREE *
2733
 
get_mm_parts(optimizer::RangeParameter *param,
2734
 
             COND *cond_func,
2735
 
             Field *field,
2736
 
                   Item_func::Functype type,
2737
 
                   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)
2738
4285
{
2739
 
  if (field->getTable() != param->table)
 
4286
  if (field->table != param->table)
2740
4287
    return 0;
2741
4288
 
2742
4289
  KEY_PART *key_part = param->key_parts;
2743
4290
  KEY_PART *end = param->key_parts_end;
2744
 
  optimizer::SEL_TREE *tree=0;
 
4291
  SEL_TREE *tree=0;
2745
4292
  if (value &&
2746
4293
      value->used_tables() & ~(param->prev_tables | param->read_tables))
2747
4294
    return 0;
2748
 
  for (; key_part != end; key_part++)
 
4295
  for (; key_part != end ; key_part++)
2749
4296
  {
2750
4297
    if (field->eq(key_part->field))
2751
4298
    {
2752
 
      optimizer::SEL_ARG *sel_arg=0;
2753
 
      if (!tree && !(tree=new optimizer::SEL_TREE()))
2754
 
        return 0;                               // OOM
 
4299
      SEL_ARG *sel_arg=0;
 
4300
      if (!tree && !(tree=new SEL_TREE()))
 
4301
        return 0;                               // OOM
2755
4302
      if (!value || !(value->used_tables() & ~param->read_tables))
2756
4303
      {
2757
 
        sel_arg= get_mm_leaf(param,cond_func,
2758
 
            key_part->field,key_part,type,value);
2759
 
        if (! sel_arg)
2760
 
          continue;
2761
 
        if (sel_arg->type == optimizer::SEL_ARG::IMPOSSIBLE)
2762
 
        {
2763
 
          tree->type=optimizer::SEL_TREE::IMPOSSIBLE;
2764
 
          return(tree);
2765
 
        }
 
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
        }
2766
4313
      }
2767
4314
      else
2768
4315
      {
2769
 
        // This key may be used later
2770
 
        if (! (sel_arg= new optimizer::SEL_ARG(optimizer::SEL_ARG::MAYBE_KEY)))
2771
 
          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
2772
4319
      }
2773
4320
      sel_arg->part=(unsigned char) key_part->part;
2774
4321
      tree->keys[key_part->key]=sel_add(tree->keys[key_part->key],sel_arg);
2775
 
      tree->keys_map.set(key_part->key);
 
4322
      tree->keys_map.set_bit(key_part->key);
2776
4323
    }
2777
4324
  }
2778
4325
 
2779
 
  return tree;
 
4326
  return(tree);
2780
4327
}
2781
4328
 
2782
4329
 
2783
 
static optimizer::SEL_ARG *
2784
 
get_mm_leaf(optimizer::RangeParameter *param,
2785
 
            COND *conf_func,
2786
 
            Field *field,
2787
 
            KEY_PART *key_part,
2788
 
            Item_func::Functype type,
2789
 
            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)
2790
4333
{
2791
4334
  uint32_t maybe_null=(uint32_t) field->real_maybe_null();
2792
4335
  bool optimize_range;
2793
 
  optimizer::SEL_ARG *tree= NULL;
2794
 
  memory::Root *alloc= param->mem_root;
 
4336
  SEL_ARG *tree= 0;
 
4337
  MEM_ROOT *alloc= param->mem_root;
2795
4338
  unsigned char *str;
2796
 
  int err= 0;
 
4339
  ulong orig_sql_mode;
 
4340
  int err;
2797
4341
 
2798
4342
  /*
2799
4343
    We need to restore the runtime mem_root of the thread in this
2801
4345
    the argument can be any, e.g. a subselect. The subselect
2802
4346
    items, in turn, assume that all the memory allocated during
2803
4347
    the evaluation has the same life span as the item itself.
2804
 
    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.
2805
4349
  */
2806
4350
  param->session->mem_root= param->old_root;
2807
4351
  if (!value)                                   // IS NULL or IS NOT NULL
2808
4352
  {
2809
 
    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
2810
4354
      goto end;
2811
4355
    if (!maybe_null)                            // Not null field
2812
4356
    {
2813
4357
      if (type == Item_func::ISNULL_FUNC)
2814
 
        tree= &optimizer::null_element;
 
4358
        tree= &null_element;
2815
4359
      goto end;
2816
4360
    }
2817
 
    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)))
2818
4362
      goto end;                                 // out of memory
2819
4363
    if (type == Item_func::ISNOTNULL_FUNC)
2820
4364
    {
2838
4382
  */
2839
4383
  if (field->result_type() == STRING_RESULT &&
2840
4384
      value->result_type() == STRING_RESULT &&
 
4385
      key_part->image_type == Field::itRAW &&
2841
4386
      ((Field_str*)field)->charset() != conf_func->compare_collation() &&
2842
4387
      !(conf_func->compare_collation()->state & MY_CS_BINSORT))
2843
4388
    goto end;
2861
4406
      goto end;
2862
4407
    if (!(res= value->val_str(&tmp)))
2863
4408
    {
2864
 
      tree= &optimizer::null_element;
 
4409
      tree= &null_element;
2865
4410
      goto end;
2866
4411
    }
2867
4412
 
2891
4436
    {
2892
4437
      if (unlikely(length < field_length))
2893
4438
      {
2894
 
        /*
2895
 
          This can only happen in a table created with UNIREG where one key
2896
 
          overlaps many fields
2897
 
        */
2898
 
        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;
2899
4444
      }
2900
4445
      else
2901
 
        field_length= length;
 
4446
        field_length= length;
2902
4447
    }
2903
4448
    length+=offset;
2904
 
    if (!(min_str= (unsigned char*) alloc->alloc_root(length*2)))
2905
 
    {
 
4449
    if (!(min_str= (unsigned char*) alloc_root(alloc, length*2)))
2906
4450
      goto end;
2907
 
    }
2908
4451
 
2909
4452
    max_str=min_str+length;
2910
4453
    if (maybe_null)
2911
4454
      max_str[0]= min_str[0]=0;
2912
4455
 
2913
4456
    field_length-= maybe_null;
2914
 
    int escape_code= make_escape_code(field->charset(),
2915
 
                                      ((Item_func_like*)(param->cond))->escape);
2916
4457
    like_error= my_like_range(field->charset(),
2917
 
                              res->ptr(), res->length(),
2918
 
                              escape_code,
2919
 
                              internal::wild_one, internal::wild_many,
2920
 
                              field_length,
2921
 
                              (char*) min_str+offset, (char*) max_str+offset,
2922
 
                              &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);
2923
4464
    if (like_error)                             // Can't optimize with LIKE
2924
4465
      goto end;
2925
4466
 
2928
4469
      int2store(min_str+maybe_null,min_length);
2929
4470
      int2store(max_str+maybe_null,max_length);
2930
4471
    }
2931
 
    tree= new (alloc) optimizer::SEL_ARG(field, min_str, max_str);
 
4472
    tree= new (alloc) SEL_ARG(field, min_str, max_str);
2932
4473
    goto end;
2933
4474
  }
2934
4475
 
2935
 
  if (! optimize_range &&
 
4476
  if (!optimize_range &&
2936
4477
      type != Item_func::EQ_FUNC &&
2937
4478
      type != Item_func::EQUAL_FUNC)
2938
4479
    goto end;                                   // Can't optimize this
2945
4486
      value->result_type() != STRING_RESULT &&
2946
4487
      field->cmp_type() != value->result_type())
2947
4488
    goto end;
2948
 
 
2949
 
  /*
2950
 
   * Some notes from Jay...
2951
 
   *
2952
 
   * OK, so previously, and in MySQL, what the optimizer does here is
2953
 
   * override the sql_mode variable to ignore out-of-range or bad date-
2954
 
   * time values.  It does this because the optimizer is populating the
2955
 
   * field variable with the incoming value from the comparison field,
2956
 
   * and the value may exceed the bounds of a proper column type.
2957
 
   *
2958
 
   * For instance, assume the following:
2959
 
   *
2960
 
   * CREATE TABLE t1 (ts TIMESTAMP);
2961
 
   * INSERT INTO t1 ('2009-03-04 00:00:00');
2962
 
   * CREATE TABLE t2 (dt1 DATETIME, dt2 DATETIME);
2963
 
   * INSERT INT t2 ('2003-12-31 00:00:00','2999-12-31 00:00:00');
2964
 
   *
2965
 
   * If we issue this query:
2966
 
   *
2967
 
   * SELECT * FROM t1, t2 WHERE t1.ts BETWEEN t2.dt1 AND t2.dt2;
2968
 
   *
2969
 
   * We will come into bounds issues.  Field_timestamp::store() will be
2970
 
   * called with a datetime value of "2999-12-31 00:00:00" and will throw
2971
 
   * an error for out-of-bounds.  MySQL solves this via a hack with sql_mode
2972
 
   * but Drizzle always throws errors on bad data storage in a Field class.
2973
 
   *
2974
 
   * Therefore, to get around the problem of the Field class being used for
2975
 
   * "storage" here without actually storing anything...we must check to see
2976
 
   * if the value being stored in a Field_timestamp here is out of range.  If
2977
 
   * it is, then we must convert to the highest Timestamp value (or lowest,
2978
 
   * depending on whether the datetime is before or after the epoch.
2979
 
   */
2980
 
  if (field->is_timestamp())
2981
 
  {
2982
 
    /*
2983
 
     * The left-side of the range comparison is a timestamp field.  Therefore,
2984
 
     * we must check to see if the value in the right-hand side is outside the
2985
 
     * range of the UNIX epoch, and cut to the epoch bounds if it is.
2986
 
     */
2987
 
    /* Datetime and date columns are Item::FIELD_ITEM ... and have a result type of STRING_RESULT */
2988
 
    if (value->real_item()->type() == Item::FIELD_ITEM
2989
 
        && value->result_type() == STRING_RESULT)
2990
 
    {
2991
 
      char buff[DateTime::MAX_STRING_LENGTH];
2992
 
      String tmp(buff, sizeof(buff), &my_charset_bin);
2993
 
      String *res= value->val_str(&tmp);
2994
 
 
2995
 
      if (!res)
2996
 
        goto end;
2997
 
      else
2998
 
      {
2999
 
        /*
3000
 
         * Create a datetime from the string and compare to fixed timestamp
3001
 
         * instances representing the epoch boundaries.
3002
 
         */
3003
 
        DateTime value_datetime;
3004
 
 
3005
 
        if (! value_datetime.from_string(res->c_ptr(), (size_t) res->length()))
3006
 
          goto end;
3007
 
 
3008
 
        Timestamp max_timestamp;
3009
 
        Timestamp min_timestamp;
3010
 
 
3011
 
        (void) max_timestamp.from_time_t((time_t) INT32_MAX);
3012
 
        (void) min_timestamp.from_time_t((time_t) 0);
3013
 
 
3014
 
        /* We rely on Temporal class operator overloads to do our comparisons. */
3015
 
        if (value_datetime < min_timestamp)
3016
 
        {
3017
 
          /*
3018
 
           * Datetime in right-hand side column is before UNIX epoch, so adjust to
3019
 
           * lower bound.
3020
 
           */
3021
 
          char new_value_buff[DateTime::MAX_STRING_LENGTH];
3022
 
          int new_value_length;
3023
 
          String new_value_string(new_value_buff, sizeof(new_value_buff), &my_charset_bin);
3024
 
 
3025
 
          new_value_length= min_timestamp.to_string(new_value_string.c_ptr(),
3026
 
                                    DateTime::MAX_STRING_LENGTH);
3027
 
          assert((new_value_length+1) < DateTime::MAX_STRING_LENGTH);
3028
 
          new_value_string.length(new_value_length);
3029
 
          err= value->save_str_value_in_field(field, &new_value_string);
3030
 
        }
3031
 
        else if (value_datetime > max_timestamp)
3032
 
        {
3033
 
          /*
3034
 
           * Datetime in right hand side column is after UNIX epoch, so adjust
3035
 
           * to the higher bound of the epoch.
3036
 
           */
3037
 
          char new_value_buff[DateTime::MAX_STRING_LENGTH];
3038
 
          int new_value_length;
3039
 
          String new_value_string(new_value_buff, sizeof(new_value_buff), &my_charset_bin);
3040
 
 
3041
 
          new_value_length= max_timestamp.to_string(new_value_string.c_ptr(),
3042
 
                                        DateTime::MAX_STRING_LENGTH);
3043
 
          assert((new_value_length+1) < DateTime::MAX_STRING_LENGTH);
3044
 
          new_value_string.length(new_value_length);
3045
 
          err= value->save_str_value_in_field(field, &new_value_string);
3046
 
        }
3047
 
        else
3048
 
          err= value->save_in_field(field, 1);
3049
 
      }
3050
 
    }
3051
 
    else /* Not a datetime -> timestamp comparison */
3052
 
      err= value->save_in_field(field, 1);
3053
 
  }
3054
 
  else /* Not a timestamp comparison */
3055
 
    err= value->save_in_field(field, 1);
3056
 
 
 
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);
3057
4496
  if (err > 0)
3058
4497
  {
3059
4498
    if (field->cmp_type() != value->result_type())
3062
4501
          value->result_type() == item_cmp_type(field->result_type(),
3063
4502
                                                value->result_type()))
3064
4503
      {
3065
 
        tree= new (alloc) optimizer::SEL_ARG(field, 0, 0);
3066
 
        tree->type= optimizer::SEL_ARG::IMPOSSIBLE;
 
4504
        tree= new (alloc) SEL_ARG(field, 0, 0);
 
4505
        tree->type= SEL_ARG::IMPOSSIBLE;
3067
4506
        goto end;
3068
4507
      }
3069
4508
      else
3119
4558
  }
3120
4559
  else if (err < 0)
3121
4560
  {
 
4561
    field->table->in_use->variables.sql_mode= orig_sql_mode;
3122
4562
    /* This happens when we try to insert a NULL field in a not null column */
3123
 
    tree= &optimizer::null_element;                        // cmp with NULL is never true
3124
 
    goto end;
3125
 
  }
3126
 
 
3127
 
  /*
3128
 
    Any predicate except "<=>"(null-safe equality operator) involving NULL as a
3129
 
    constant is always FALSE
3130
 
    Put IMPOSSIBLE Tree(null_element) here.
3131
 
  */  
3132
 
  if (type != Item_func::EQUAL_FUNC && field->is_real_null())
3133
 
  {
3134
 
    tree= &optimizer::null_element;
3135
 
    goto end;
3136
 
  }
3137
 
 
3138
 
  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);
3139
4568
  if (!str)
3140
4569
    goto end;
3141
4570
  if (maybe_null)
3142
4571
    *str= (unsigned char) field->is_real_null();        // Set to 1 if null
3143
 
  field->get_key_image(str+maybe_null, key_part->length);
3144
 
  if (! (tree= new (alloc) optimizer::SEL_ARG(field, str, str)))
3145
 
    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
3146
4576
 
3147
4577
  /*
3148
4578
    Check if we are comparing an UNSIGNED integer with a negative constant.
3164
4594
    {
3165
4595
      if (type == Item_func::LT_FUNC || type == Item_func::LE_FUNC)
3166
4596
      {
3167
 
        tree->type= optimizer::SEL_ARG::IMPOSSIBLE;
 
4597
        tree->type= SEL_ARG::IMPOSSIBLE;
3168
4598
        goto end;
3169
4599
      }
3170
4600
      if (type == Item_func::GT_FUNC || type == Item_func::GE_FUNC)
3225
4655
  This will never be called for same key parts.
3226
4656
*/
3227
4657
 
3228
 
static optimizer::SEL_ARG *
3229
 
sel_add(optimizer::SEL_ARG *key1, optimizer::SEL_ARG *key2)
 
4658
static SEL_ARG *
 
4659
sel_add(SEL_ARG *key1,SEL_ARG *key2)
3230
4660
{
3231
 
  optimizer::SEL_ARG *root= NULL;
3232
 
  optimizer::SEL_ARG **key_link= NULL;
 
4661
  SEL_ARG *root,**key_link;
3233
4662
 
3234
4663
  if (!key1)
3235
4664
    return key2;
3258
4687
 
3259
4688
#define CLONE_KEY1_MAYBE 1
3260
4689
#define CLONE_KEY2_MAYBE 2
3261
 
 
3262
 
static uint32_t swap_clone_flag(uint32_t a)
3263
 
{
3264
 
  return ((a & 1) << 1) | ((a & 2) >> 1);
3265
 
}
3266
 
 
3267
 
static optimizer::SEL_TREE *
3268
 
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)
3269
4695
{
3270
4696
  if (!tree1)
3271
4697
    return(tree2);
3272
4698
  if (!tree2)
3273
4699
    return(tree1);
3274
 
  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)
3275
4701
    return(tree1);
3276
 
  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)
3277
4703
    return(tree2);
3278
 
  if (tree1->type == optimizer::SEL_TREE::MAYBE)
 
4704
  if (tree1->type == SEL_TREE::MAYBE)
3279
4705
  {
3280
 
    if (tree2->type == optimizer::SEL_TREE::KEY)
3281
 
      tree2->type=optimizer::SEL_TREE::KEY_SMALLER;
 
4706
    if (tree2->type == SEL_TREE::KEY)
 
4707
      tree2->type=SEL_TREE::KEY_SMALLER;
3282
4708
    return(tree2);
3283
4709
  }
3284
 
  if (tree2->type == optimizer::SEL_TREE::MAYBE)
 
4710
  if (tree2->type == SEL_TREE::MAYBE)
3285
4711
  {
3286
 
    tree1->type=optimizer::SEL_TREE::KEY_SMALLER;
 
4712
    tree1->type=SEL_TREE::KEY_SMALLER;
3287
4713
    return(tree1);
3288
4714
  }
3289
4715
  key_map  result_keys;
3290
 
  result_keys.reset();
 
4716
  result_keys.clear_all();
3291
4717
 
3292
4718
  /* Join the trees key per key */
3293
 
  optimizer::SEL_ARG **key1,**key2,**end;
 
4719
  SEL_ARG **key1,**key2,**end;
3294
4720
  for (key1= tree1->keys,key2= tree2->keys,end=key1+param->keys ;
3295
4721
       key1 != end ; key1++,key2++)
3296
4722
  {
3298
4724
    if (*key1 || *key2)
3299
4725
    {
3300
4726
      if (*key1 && !(*key1)->simple_key())
3301
 
        flag|=CLONE_KEY1_MAYBE;
 
4727
        flag|=CLONE_KEY1_MAYBE;
3302
4728
      if (*key2 && !(*key2)->simple_key())
3303
 
        flag|=CLONE_KEY2_MAYBE;
 
4729
        flag|=CLONE_KEY2_MAYBE;
3304
4730
      *key1=key_and(param, *key1, *key2, flag);
3305
 
      if (*key1 && (*key1)->type == optimizer::SEL_ARG::IMPOSSIBLE)
 
4731
      if (*key1 && (*key1)->type == SEL_ARG::IMPOSSIBLE)
3306
4732
      {
3307
 
        tree1->type= optimizer::SEL_TREE::IMPOSSIBLE;
 
4733
        tree1->type= SEL_TREE::IMPOSSIBLE;
3308
4734
        return(tree1);
3309
4735
      }
3310
 
      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
3311
4741
    }
3312
4742
  }
3313
4743
  tree1->keys_map= result_keys;
3314
4744
  /* dispose index_merge if there is a "range" option */
3315
 
  if (result_keys.any())
 
4745
  if (!result_keys.is_clear_all())
3316
4746
  {
3317
 
    tree1->merges.clear();
 
4747
    tree1->merges.empty();
3318
4748
    return(tree1);
3319
4749
  }
3320
4750
 
3324
4754
}
3325
4755
 
3326
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
 
3327
4950
 
3328
4951
/* And key trees where key1->part < key2 -> part */
3329
4952
 
3330
 
static optimizer::SEL_ARG *
3331
 
and_all_keys(optimizer::RangeParameter *param,
3332
 
             optimizer::SEL_ARG *key1,
3333
 
             optimizer::SEL_ARG *key2,
 
4953
static SEL_ARG *
 
4954
and_all_keys(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2,
3334
4955
             uint32_t clone_flag)
3335
4956
{
3336
 
  optimizer::SEL_ARG *next= NULL;
 
4957
  SEL_ARG *next;
3337
4958
  ulong use_count=key1->use_count;
3338
4959
 
3339
4960
  if (key1->elements != 1)
3341
4962
    key2->use_count+=key1->elements-1; //psergey: why we don't count that key1 has n-k-p?
3342
4963
    key2->increment_use_count((int) key1->elements-1);
3343
4964
  }
3344
 
  if (key1->type == optimizer::SEL_ARG::MAYBE_KEY)
 
4965
  if (key1->type == SEL_ARG::MAYBE_KEY)
3345
4966
  {
3346
 
    key1->right= key1->left= &optimizer::null_element;
 
4967
    key1->right= key1->left= &null_element;
3347
4968
    key1->next= key1->prev= 0;
3348
4969
  }
3349
 
  for (next= key1->first(); next ; next=next->next)
 
4970
  for (next=key1->first(); next ; next=next->next)
3350
4971
  {
3351
4972
    if (next->next_key_part)
3352
4973
    {
3353
 
      optimizer::SEL_ARG *tmp= key_and(param, next->next_key_part, key2, clone_flag);
3354
 
      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)
3355
4976
      {
3356
 
        key1=key1->tree_delete(next);
3357
 
        continue;
 
4977
        key1=key1->tree_delete(next);
 
4978
        continue;
3358
4979
      }
3359
4980
      next->next_key_part=tmp;
3360
4981
      if (use_count)
3361
 
        next->increment_use_count(use_count);
3362
 
      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)
3363
4984
        break;
3364
4985
    }
3365
4986
    else
3366
4987
      next->next_key_part=key2;
3367
4988
  }
3368
 
  if (! key1)
3369
 
    return &optimizer::null_element;                    // Impossible ranges
 
4989
  if (!key1)
 
4990
    return &null_element;                       // Impossible ranges
3370
4991
  key1->use_count++;
3371
4992
  return key1;
3372
4993
}
3387
5008
    NULL if the result of AND operation is an empty interval {0}.
3388
5009
*/
3389
5010
 
3390
 
static optimizer::SEL_ARG *
3391
 
key_and(optimizer::RangeParameter *param,
3392
 
        optimizer::SEL_ARG *key1,
3393
 
        optimizer::SEL_ARG *key2,
3394
 
        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)
3395
5013
{
3396
 
  if (! key1)
 
5014
  if (!key1)
3397
5015
    return key2;
3398
 
  if (! key2)
 
5016
  if (!key2)
3399
5017
    return key1;
3400
5018
  if (key1->part != key2->part)
3401
5019
  {
3407
5025
    // key1->part < key2->part
3408
5026
    key1->use_count--;
3409
5027
    if (key1->use_count > 0)
3410
 
      if (! (key1= key1->clone_tree(param)))
3411
 
        return 0;                               // OOM
 
5028
      if (!(key1= key1->clone_tree(param)))
 
5029
        return 0;                               // OOM
3412
5030
    return and_all_keys(param, key1, key2, clone_flag);
3413
5031
  }
3414
5032
 
3415
5033
  if (((clone_flag & CLONE_KEY2_MAYBE) &&
3416
 
       ! (clone_flag & CLONE_KEY1_MAYBE) &&
3417
 
       key2->type != optimizer::SEL_ARG::MAYBE_KEY) ||
3418
 
      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)
3419
5037
  {                                             // Put simple key in key2
3420
5038
    std::swap(key1, key2);
3421
 
    clone_flag= swap_clone_flag(clone_flag);
 
5039
    clone_flag=swap_clone_flag(clone_flag);
3422
5040
  }
3423
5041
 
3424
5042
  /* If one of the key is MAYBE_KEY then the found region may be smaller */
3425
 
  if (key2->type == optimizer::SEL_ARG::MAYBE_KEY)
 
5043
  if (key2->type == SEL_ARG::MAYBE_KEY)
3426
5044
  {
3427
5045
    if (key1->use_count > 1)
3428
5046
    {
3429
5047
      key1->use_count--;
3430
 
      if (! (key1=key1->clone_tree(param)))
3431
 
        return 0;                               // OOM
 
5048
      if (!(key1=key1->clone_tree(param)))
 
5049
        return 0;                               // OOM
3432
5050
      key1->use_count++;
3433
5051
    }
3434
 
    if (key1->type == optimizer::SEL_ARG::MAYBE_KEY)
 
5052
    if (key1->type == SEL_ARG::MAYBE_KEY)
3435
5053
    {                                           // Both are maybe key
3436
 
      key1->next_key_part= key_and(param,
3437
 
                                   key1->next_key_part,
3438
 
                                   key2->next_key_part,
3439
 
                                   clone_flag);
 
5054
      key1->next_key_part=key_and(param, key1->next_key_part,
 
5055
                                  key2->next_key_part, clone_flag);
3440
5056
      if (key1->next_key_part &&
3441
 
          key1->next_key_part->type == optimizer::SEL_ARG::IMPOSSIBLE)
3442
 
        return key1;
 
5057
          key1->next_key_part->type == SEL_ARG::IMPOSSIBLE)
 
5058
        return key1;
3443
5059
    }
3444
5060
    else
3445
5061
    {
3446
5062
      key1->maybe_smaller();
3447
5063
      if (key2->next_key_part)
3448
5064
      {
3449
 
        key1->use_count--;                      // Incremented in and_all_keys
3450
 
        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);
3451
5067
      }
3452
5068
      key2->use_count--;                        // Key2 doesn't have a tree
3453
5069
    }
3456
5072
 
3457
5073
  key1->use_count--;
3458
5074
  key2->use_count--;
3459
 
  optimizer::SEL_ARG *e1= key1->first();
3460
 
  optimizer::SEL_ARG *e2= key2->first();
3461
 
  optimizer::SEL_ARG *new_tree= NULL;
 
5075
  SEL_ARG *e1=key1->first(), *e2=key2->first(), *new_tree=0;
3462
5076
 
3463
5077
  while (e1 && e2)
3464
5078
  {
3465
 
    int cmp= e1->cmp_min_to_min(e2);
 
5079
    int cmp=e1->cmp_min_to_min(e2);
3466
5080
    if (cmp < 0)
3467
5081
    {
3468
 
      if (get_range(&e1, &e2, key1))
3469
 
        continue;
 
5082
      if (get_range(&e1,&e2,key1))
 
5083
        continue;
3470
5084
    }
3471
 
    else if (get_range(&e2, &e1, key2))
 
5085
    else if (get_range(&e2,&e1,key2))
3472
5086
      continue;
3473
 
    optimizer::SEL_ARG *next= key_and(param,
3474
 
                                      e1->next_key_part,
3475
 
                                      e2->next_key_part,
3476
 
                                      clone_flag);
 
5087
    SEL_ARG *next=key_and(param, e1->next_key_part, e2->next_key_part,
 
5088
                          clone_flag);
3477
5089
    e1->increment_use_count(1);
3478
5090
    e2->increment_use_count(1);
3479
 
    if (! next || next->type != optimizer::SEL_ARG::IMPOSSIBLE)
 
5091
    if (!next || next->type != SEL_ARG::IMPOSSIBLE)
3480
5092
    {
3481
 
      optimizer::SEL_ARG *new_arg= e1->clone_and(e2);
3482
 
      if (! new_arg)
3483
 
        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
3484
5096
      new_arg->next_key_part=next;
3485
 
      if (! new_tree)
 
5097
      if (!new_tree)
3486
5098
      {
3487
 
        new_tree=new_arg;
 
5099
        new_tree=new_arg;
3488
5100
      }
3489
5101
      else
3490
 
        new_tree=new_tree->insert(new_arg);
 
5102
        new_tree=new_tree->insert(new_arg);
3491
5103
    }
3492
5104
    if (e1->cmp_max_to_max(e2) < 0)
3493
5105
      e1=e1->next;                              // e1 can't overlapp next e2
3496
5108
  }
3497
5109
  key1->free_tree();
3498
5110
  key2->free_tree();
3499
 
  if (! new_tree)
3500
 
    return &optimizer::null_element;                    // Impossible range
 
5111
  if (!new_tree)
 
5112
    return &null_element;                       // Impossible range
3501
5113
  return new_tree;
3502
5114
}
3503
5115
 
3504
5116
 
3505
5117
static bool
3506
 
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)
3507
5119
{
3508
 
  (*e1)= root1->find_range(*e2);                        // first e1->min < e2->min
 
5120
  (*e1)=root1->find_range(*e2);                 // first e1->min < e2->min
3509
5121
  if ((*e1)->cmp_max_to_min(*e2) < 0)
3510
5122
  {
3511
 
    if (! ((*e1)=(*e1)->next))
 
5123
    if (!((*e1)=(*e1)->next))
3512
5124
      return 1;
3513
5125
    if ((*e1)->cmp_min_to_max(*e2) > 0)
3514
5126
    {
3520
5132
}
3521
5133
 
3522
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
 
3523
5894
/****************************************************************************
3524
5895
  MRR Range Sequence Interface implementation that walks a SEL_ARG* tree.
3525
5896
 ****************************************************************************/
3541
5912
 
3542
5913
  /* Number of key parts */
3543
5914
  uint32_t min_key_parts, max_key_parts;
3544
 
  optimizer::SEL_ARG *key_tree;
 
5915
  SEL_ARG *key_tree;
3545
5916
} RANGE_SEQ_ENTRY;
3546
5917
 
3547
5918
 
3550
5921
*/
3551
5922
typedef struct st_sel_arg_range_seq
3552
5923
{
3553
 
  uint32_t keyno;      /* index of used tree in optimizer::SEL_TREE structure */
 
5924
  uint32_t keyno;      /* index of used tree in SEL_TREE structure */
3554
5925
  uint32_t real_keyno; /* Number of the index in tables */
3555
 
  optimizer::Parameter *param;
3556
 
  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 */
3557
5928
 
3558
5929
  RANGE_SEQ_ENTRY stack[MAX_REF_PARTS];
3559
5930
  int i; /* Index of last used element in the above array */
3575
5946
    Value of init_param
3576
5947
*/
3577
5948
 
3578
 
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)
3579
5950
{
3580
5951
  SEL_ARG_RANGE_SEQ *seq= (SEL_ARG_RANGE_SEQ*)init_param;
3581
5952
  seq->at_start= true;
3592
5963
}
3593
5964
 
3594
5965
 
3595
 
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)
3596
5967
{
3597
5968
  RANGE_SEQ_ENTRY *cur= &arg->stack[arg->i+1];
3598
5969
  RANGE_SEQ_ENTRY *prev= &arg->stack[arg->i];
3642
6013
*/
3643
6014
 
3644
6015
//psergey-merge-todo: support check_quick_keys:max_keypart
3645
 
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)
3646
6017
{
3647
 
  optimizer::SEL_ARG *key_tree;
 
6018
  SEL_ARG *key_tree;
3648
6019
  SEL_ARG_RANGE_SEQ *seq= (SEL_ARG_RANGE_SEQ*)rseq;
3649
6020
  if (seq->at_start)
3650
6021
  {
3657
6028
  /* Ok, we're at some "full tuple" position in the tree */
3658
6029
 
3659
6030
  /* Step down if we can */
3660
 
  if (key_tree->next && key_tree->next != &optimizer::null_element)
 
6031
  if (key_tree->next && key_tree->next != &null_element)
3661
6032
  {
3662
6033
    //step down; (update the tuple, we'll step right and stay there)
3663
6034
    seq->i--;
3677
6048
    key_tree= seq->stack[seq->i].key_tree;
3678
6049
 
3679
6050
    /* Step down if we can */
3680
 
    if (key_tree->next && key_tree->next != &optimizer::null_element)
 
6051
    if (key_tree->next && key_tree->next != &null_element)
3681
6052
    {
3682
6053
      // Step down; update the tuple
3683
6054
      seq->i--;
3692
6063
    Walk right-up while we can
3693
6064
  */
3694
6065
walk_right_n_up:
3695
 
  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 &&
3696
6067
         key_tree->next_key_part->part == key_tree->part + 1 &&
3697
 
         key_tree->next_key_part->type == optimizer::SEL_ARG::KEY_RANGE)
 
6068
         key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
3698
6069
  {
3699
6070
    {
3700
6071
      RANGE_SEQ_ENTRY *cur= &seq->stack[seq->i];
3701
6072
      uint32_t min_key_length= cur->min_key - seq->param->min_key;
3702
6073
      uint32_t max_key_length= cur->max_key - seq->param->max_key;
3703
6074
      uint32_t len= cur->min_key - cur[-1].min_key;
3704
 
      if (! (min_key_length == max_key_length &&
3705
 
          ! memcmp(cur[-1].min_key, cur[-1].max_key, len) &&
3706
 
          ! 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))
3707
6078
      {
3708
6079
        seq->param->is_ror_scan= false;
3709
 
        if (! key_tree->min_flag)
 
6080
        if (!key_tree->min_flag)
3710
6081
          cur->min_key_parts +=
3711
6082
            key_tree->next_key_part->store_min_key(seq->param->key[seq->keyno],
3712
6083
                                                   &cur->min_key,
3713
6084
                                                   &cur->min_key_flag);
3714
 
        if (! key_tree->max_flag)
 
6085
        if (!key_tree->max_flag)
3715
6086
          cur->max_key_parts +=
3716
6087
            key_tree->next_key_part->store_max_key(seq->param->key[seq->keyno],
3717
6088
                                                   &cur->max_key,
3727
6098
    key_tree= key_tree->next_key_part;
3728
6099
 
3729
6100
walk_up_n_right:
3730
 
    while (key_tree->prev && key_tree->prev != &optimizer::null_element)
 
6101
    while (key_tree->prev && key_tree->prev != &null_element)
3731
6102
    {
3732
6103
      /* Step up */
3733
6104
      key_tree= key_tree->prev;
3738
6109
  /* Ok got a tuple */
3739
6110
  RANGE_SEQ_ENTRY *cur= &seq->stack[seq->i];
3740
6111
 
3741
 
  range->ptr= (char*)(size_t)(key_tree->part);
 
6112
  range->ptr= (char*)(int)(key_tree->part);
3742
6113
  {
3743
6114
    range->range_flag= cur->min_key_flag | cur->max_key_flag;
3744
6115
 
3781
6152
    }
3782
6153
  }
3783
6154
  seq->param->range_count++;
3784
 
  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,(uint32_t)key_tree->part);
3785
6156
  return 0;
3786
6157
}
3787
6158
 
3792
6163
  SYNOPSIS
3793
6164
    check_quick_select()
3794
6165
      param             Parameter from test_quick_select
3795
 
      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
3796
6167
      index_only        true  - assume only index tuples will be accessed
3797
6168
                        false - assume full table rows will be read
3798
6169
      tree              Transformed selection condition, tree->key[idx] holds
3810
6181
 
3811
6182
  RETURN
3812
6183
    Estimate # of records to be retrieved.
3813
 
    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.
3814
6185
*/
3815
6186
 
3816
6187
static
3817
 
ha_rows check_quick_select(Session *session,
3818
 
                           optimizer::Parameter *param,
3819
 
                           uint32_t idx,
3820
 
                           bool index_only,
3821
 
                           optimizer::SEL_ARG *tree,
3822
 
                           bool update_tbl_stats,
3823
 
                           uint32_t *mrr_flags,
3824
 
                           uint32_t *bufsize,
3825
 
                           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)
3826
6191
{
3827
6192
  SEL_ARG_RANGE_SEQ seq;
3828
6193
  RANGE_SEQ_IF seq_if = {sel_arg_range_seq_init, sel_arg_range_seq_next};
3829
 
  Cursor *cursor= param->table->cursor;
 
6194
  handler *file= param->table->file;
3830
6195
  ha_rows rows;
3831
6196
  uint32_t keynr= param->real_keynr[idx];
3832
6197
 
3833
6198
  /* Handle cases when we don't have a valid non-empty list of range */
3834
 
  if (! tree)
 
6199
  if (!tree)
3835
6200
    return(HA_POS_ERROR);
3836
 
  if (tree->type == optimizer::SEL_ARG::IMPOSSIBLE)
 
6201
  if (tree->type == SEL_ARG::IMPOSSIBLE)
3837
6202
    return(0L);
3838
 
  if (tree->type != optimizer::SEL_ARG::KEY_RANGE || tree->part != 0)
 
6203
  if (tree->type != SEL_ARG::KEY_RANGE || tree->part != 0)
3839
6204
    return(HA_POS_ERROR);
3840
6205
 
3841
6206
  seq.keyno= idx;
3847
6212
  param->max_key_part=0;
3848
6213
 
3849
6214
  param->is_ror_scan= true;
3850
 
  if (param->table->index_flags(keynr) & HA_KEY_SCAN_NOT_ROR)
 
6215
  if (file->index_flags(keynr, 0, true) & HA_KEY_SCAN_NOT_ROR)
3851
6216
    param->is_ror_scan= false;
3852
6217
 
3853
6218
  *mrr_flags= param->force_default_mrr? HA_MRR_USE_DEFAULT_IMPL: 0;
3854
6219
  *mrr_flags|= HA_MRR_NO_ASSOCIATION;
3855
6220
 
3856
 
  bool pk_is_clustered= cursor->primary_key_is_clustered();
 
6221
  bool pk_is_clustered= file->primary_key_is_clustered();
3857
6222
  if (index_only &&
3858
 
      (param->table->index_flags(keynr) & HA_KEYREAD_ONLY) &&
3859
 
      !(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))
3860
6225
     *mrr_flags |= HA_MRR_INDEX_ONLY;
3861
6226
 
3862
 
  if (session->getLex()->sql_command != SQLCOM_SELECT)
 
6227
  if (current_session->lex->sql_command != SQLCOM_SELECT)
3863
6228
    *mrr_flags |= HA_MRR_USE_DEFAULT_IMPL;
3864
6229
 
3865
6230
  *bufsize= param->session->variables.read_rnd_buff_size;
3866
 
  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,
3867
6232
                                          bufsize, mrr_flags, cost);
3868
6233
  if (rows != HA_POS_ERROR)
3869
6234
  {
3870
6235
    param->table->quick_rows[keynr]=rows;
3871
6236
    if (update_tbl_stats)
3872
6237
    {
3873
 
      param->table->quick_keys.set(keynr);
 
6238
      param->table->quick_keys.set_bit(keynr);
3874
6239
      param->table->quick_key_parts[keynr]=param->max_key_part+1;
3875
6240
      param->table->quick_n_ranges[keynr]= param->range_count;
3876
6241
      param->table->quick_condition_rows=
3877
 
        min(param->table->quick_condition_rows, rows);
 
6242
        cmin(param->table->quick_condition_rows, rows);
3878
6243
    }
3879
6244
  }
3880
6245
  /* Figure out if the key scan is ROR (returns rows in ROWID order) or not */
3891
6256
  else
3892
6257
  {
3893
6258
    /* Clustered PK scan is always a ROR scan (TODO: same as above) */
3894
 
    if (param->table->getShare()->getPrimaryKey() == keynr && pk_is_clustered)
 
6259
    if (param->table->s->primary_key == keynr && pk_is_clustered)
3895
6260
      param->is_ror_scan= true;
3896
6261
  }
3897
6262
 
3936
6301
    false  Otherwise
3937
6302
*/
3938
6303
 
3939
 
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)
3940
6305
{
3941
 
  KeyInfo *table_key= param->table->key_info + keynr;
3942
 
  KeyPartInfo *key_part= table_key->key_part + nparts;
3943
 
  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 +
3944
6309
                                table_key->key_parts);
3945
6310
  uint32_t pk_number;
3946
6311
 
3947
 
  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++)
3948
6313
  {
3949
6314
    uint16_t fieldnr= param->table->key_info[keynr].
3950
6315
                    key_part[kp - table_key->key_part].fieldnr - 1;
3951
 
    if (param->table->getField(fieldnr)->key_length() != kp->length)
 
6316
    if (param->table->field[fieldnr]->key_length() != kp->length)
3952
6317
      return false;
3953
6318
  }
3954
6319
 
3956
6321
    return true;
3957
6322
 
3958
6323
  key_part= table_key->key_part + nparts;
3959
 
  pk_number= param->table->getShare()->getPrimaryKey();
3960
 
  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)
3961
6326
    return false;
3962
6327
 
3963
 
  KeyPartInfo *pk_part= param->table->key_info[pk_number].key_part;
3964
 
  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 +
3965
6330
                              param->table->key_info[pk_number].key_parts;
3966
6331
  for (;(key_part!=key_part_end) && (pk_part != pk_part_end);
3967
6332
       ++key_part, ++pk_part)
3974
6339
}
3975
6340
 
3976
6341
 
3977
 
optimizer::QuickRangeSelect *
3978
 
optimizer::get_quick_select(Parameter *param,
3979
 
                            uint32_t idx,
3980
 
                            optimizer::SEL_ARG *key_tree,
3981
 
                            uint32_t mrr_flags,
3982
 
                            uint32_t mrr_buf_size,
3983
 
                            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)
3984
6368
{
3985
 
  optimizer::QuickRangeSelect *quick= new optimizer::QuickRangeSelect(param->session,
3986
 
                                                                      param->table,
3987
 
                                                                      param->real_keynr[idx],
3988
 
                                                                      test(parent_alloc),
3989
 
                                                                      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);
3990
6375
 
3991
6376
  if (quick)
3992
6377
  {
3993
 
          if (get_quick_keys(param,
3994
 
                       quick,
3995
 
                       param->key[idx],
3996
 
                       key_tree,
3997
 
                       param->min_key,
3998
 
                       0,
3999
 
                                   param->max_key,
4000
 
                       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))
4001
6381
    {
4002
6382
      delete quick;
4003
 
      quick= NULL;
 
6383
      quick=0;
4004
6384
    }
4005
6385
    else
4006
6386
    {
4007
6387
      quick->mrr_flags= mrr_flags;
4008
6388
      quick->mrr_buf_size= mrr_buf_size;
4009
 
      if (parent_alloc)
4010
 
      {
4011
 
        quick->key_parts=(KEY_PART*)
4012
 
          parent_alloc->memdup_root( (char*) param->key[idx], sizeof(KEY_PART)* param->table->key_info[param->real_keynr[idx]].key_parts);
4013
 
      }
4014
 
      else
4015
 
      {
4016
 
        quick->key_parts=(KEY_PART*)
4017
 
          quick->alloc.memdup_root((char*) param->key[idx], sizeof(KEY_PART)* param->table->key_info[param->real_keynr[idx]].key_parts);
4018
 
      }
 
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);
4019
6394
    }
4020
6395
  }
4021
6396
  return quick;
4026
6401
** Fix this to get all possible sub_ranges
4027
6402
*/
4028
6403
bool
4029
 
optimizer::get_quick_keys(optimizer::Parameter *param,
4030
 
                          optimizer::QuickRangeSelect *quick,
4031
 
                          KEY_PART *key,
4032
 
                                optimizer::SEL_ARG *key_tree,
4033
 
                          unsigned char *min_key,
4034
 
                          uint32_t min_key_flag,
4035
 
                                unsigned char *max_key,
4036
 
                          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)
4037
6407
{
4038
 
  optimizer::QuickRange *range= NULL;
 
6408
  QUICK_RANGE *range;
4039
6409
  uint32_t flag;
4040
 
  int min_part= key_tree->part - 1; // # of keypart values in min_key buffer
4041
 
  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
4042
6412
 
4043
 
  if (key_tree->left != &optimizer::null_element)
 
6413
  if (key_tree->left != &null_element)
4044
6414
  {
4045
 
    if (get_quick_keys(param,
4046
 
                       quick,
4047
 
                       key,
4048
 
                       key_tree->left,
4049
 
                                   min_key,
4050
 
                       min_key_flag,
4051
 
                       max_key,
4052
 
                       max_key_flag))
4053
 
    {
 
6415
    if (get_quick_keys(param,quick,key,key_tree->left,
 
6416
                       min_key,min_key_flag, max_key, max_key_flag))
4054
6417
      return 1;
4055
 
    }
4056
6418
  }
4057
 
  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;
4058
6420
  min_part+= key_tree->store_min(key[key_tree->part].store_length,
4059
6421
                                 &tmp_min_key,min_key_flag);
4060
6422
  max_part+= key_tree->store_max(key[key_tree->part].store_length,
4062
6424
 
4063
6425
  if (key_tree->next_key_part &&
4064
6426
      key_tree->next_key_part->part == key_tree->part+1 &&
4065
 
      key_tree->next_key_part->type == optimizer::SEL_ARG::KEY_RANGE)
 
6427
      key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
4066
6428
  {                                               // const key as prefix
4067
6429
    if ((tmp_min_key - min_key) == (tmp_max_key - max_key) &&
4068
 
        memcmp(min_key, max_key, (uint32_t)(tmp_max_key - max_key))==0 &&
4069
 
        key_tree->min_flag==0 && key_tree->max_flag==0)
 
6430
         memcmp(min_key, max_key, (uint32_t)(tmp_max_key - max_key))==0 &&
 
6431
         key_tree->min_flag==0 && key_tree->max_flag==0)
4070
6432
    {
4071
 
      if (get_quick_keys(param,
4072
 
                         quick,
4073
 
                         key,
4074
 
                         key_tree->next_key_part,
4075
 
                         tmp_min_key,
4076
 
                         min_key_flag | key_tree->min_flag,
4077
 
                         tmp_max_key,
4078
 
                         max_key_flag | key_tree->max_flag))
4079
 
      {
4080
 
        return 1;
4081
 
      }
 
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;
4082
6437
      goto end;                                 // Ugly, but efficient
4083
6438
    }
4084
6439
    {
4085
6440
      uint32_t tmp_min_flag=key_tree->min_flag,tmp_max_flag=key_tree->max_flag;
4086
 
      if (! tmp_min_flag)
4087
 
      {
4088
 
        min_part+= key_tree->next_key_part->store_min_key(key,
4089
 
                                                          &tmp_min_key,
 
6441
      if (!tmp_min_flag)
 
6442
        min_part+= key_tree->next_key_part->store_min_key(key, &tmp_min_key,
4090
6443
                                                          &tmp_min_flag);
4091
 
      }
4092
 
      if (! tmp_max_flag)
4093
 
      {
4094
 
        max_part+= key_tree->next_key_part->store_max_key(key,
4095
 
                                                          &tmp_max_key,
 
6444
      if (!tmp_max_flag)
 
6445
        max_part+= key_tree->next_key_part->store_max_key(key, &tmp_max_key,
4096
6446
                                                          &tmp_max_flag);
4097
 
      }
4098
6447
      flag=tmp_min_flag | tmp_max_flag;
4099
6448
    }
4100
6449
  }
4107
6456
    Ensure that some part of min_key and max_key are used.  If not,
4108
6457
    regard this as no lower/upper range
4109
6458
  */
4110
 
  if (tmp_min_key != param->min_key)
4111
 
  {
4112
 
    flag&= ~NO_MIN_RANGE;
4113
 
  }
4114
 
  else
4115
 
  {
4116
 
    flag|= NO_MIN_RANGE;
4117
 
  }
4118
 
  if (tmp_max_key != param->max_key)
4119
 
  {
4120
 
    flag&= ~NO_MAX_RANGE;
4121
 
  }
4122
 
  else
4123
 
  {
4124
 
    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;
4125
6468
  }
4126
6469
  if (flag == 0)
4127
6470
  {
4128
6471
    uint32_t length= (uint32_t) (tmp_min_key - param->min_key);
4129
6472
    if (length == (uint32_t) (tmp_max_key - param->max_key) &&
4130
 
              ! memcmp(param->min_key,param->max_key,length))
 
6473
        !memcmp(param->min_key,param->max_key,length))
4131
6474
    {
4132
 
      KeyInfo *table_key= quick->head->key_info+quick->index;
4133
 
      flag= EQ_RANGE;
 
6475
      KEY *table_key=quick->head->key_info+quick->index;
 
6476
      flag=EQ_RANGE;
4134
6477
      if ((table_key->flags & (HA_NOSAME)) == HA_NOSAME &&
4135
 
                key->part == table_key->key_parts-1)
 
6478
          key->part == table_key->key_parts-1)
4136
6479
      {
4137
 
        if (! (table_key->flags & HA_NULL_PART_KEY) ||
4138
 
            ! null_part_in_key(key,
4139
 
                               param->min_key,
4140
 
                               (uint32_t) (tmp_min_key - param->min_key)))
4141
 
        {
4142
 
          flag|= UNIQUE_RANGE;
4143
 
        }
4144
 
        else
4145
 
        {
4146
 
          flag|= NULL_RANGE;
4147
 
        }
 
6480
        if (!(table_key->flags & HA_NULL_PART_KEY) ||
 
6481
            !null_part_in_key(key,
 
6482
                              param->min_key,
 
6483
                              (uint32_t) (tmp_min_key - param->min_key)))
 
6484
          flag|= UNIQUE_RANGE;
 
6485
        else
 
6486
          flag|= NULL_RANGE;
4148
6487
      }
4149
6488
    }
4150
6489
  }
4151
6490
 
4152
6491
  /* Get range for retrieving rows in QUICK_SELECT::get_next */
4153
 
  if (! (range= new optimizer::QuickRange(param->min_key,
4154
 
                                                             (uint32_t) (tmp_min_key - param->min_key),
4155
 
                                           min_part >=0 ? make_keypart_map(min_part) : 0,
4156
 
                                                             param->max_key,
4157
 
                                                             (uint32_t) (tmp_max_key - param->max_key),
4158
 
                                           max_part >=0 ? make_keypart_map(max_part) : 0,
4159
 
                                                             flag)))
4160
 
  {
 
6492
  if (!(range= new QUICK_RANGE(param->min_key,
 
6493
                               (uint32_t) (tmp_min_key - param->min_key),
 
6494
                               min_part >=0 ? make_keypart_map(min_part) : 0,
 
6495
                               param->max_key,
 
6496
                               (uint32_t) (tmp_max_key - param->max_key),
 
6497
                               max_part >=0 ? make_keypart_map(max_part) : 0,
 
6498
                               flag)))
4161
6499
    return 1;                   // out of memory
4162
 
  }
4163
6500
 
4164
 
  set_if_bigger(quick->max_used_key_length, (uint32_t)range->min_length);
4165
 
  set_if_bigger(quick->max_used_key_length, (uint32_t)range->max_length);
 
6501
  set_if_bigger(quick->max_used_key_length, range->min_length);
 
6502
  set_if_bigger(quick->max_used_key_length, range->max_length);
4166
6503
  set_if_bigger(quick->used_key_parts, (uint32_t) key_tree->part+1);
4167
6504
  if (insert_dynamic(&quick->ranges, (unsigned char*) &range))
4168
 
  {
4169
6505
    return 1;
4170
 
  }
4171
6506
 
4172
6507
 end:
4173
 
  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)
4174
6522
  {
4175
 
    return get_quick_keys(param,
4176
 
                          quick,
4177
 
                          key,
4178
 
                          key_tree->right,
4179
 
                                            min_key,
4180
 
                          min_key_flag,
4181
 
                                            max_key,
4182
 
                          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
    }
4183
6530
  }
4184
6531
  return 0;
4185
6532
}
4186
6533
 
 
6534
 
 
6535
 
4187
6536
/*
4188
6537
  Return true if any part of the key is NULL
4189
6538
 
4211
6560
}
4212
6561
 
4213
6562
 
4214
 
bool optimizer::QuickSelectInterface::is_keys_used(const boost::dynamic_bitset<>& fields)
 
6563
bool QUICK_SELECT_I::is_keys_used(const MY_BITMAP *fields)
4215
6564
{
4216
6565
  return is_key_used(head, index, fields);
4217
6566
}
4218
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
 
4219
6604
 
4220
6605
/*
4221
6606
  Create quick select from ref/ref_or_null scan.
4236
6621
    NULL on error.
4237
6622
*/
4238
6623
 
4239
 
optimizer::QuickRangeSelect *optimizer::get_quick_select_for_ref(Session *session,
4240
 
                                                                 Table *table,
4241
 
                                                                 table_reference_st *ref,
4242
 
                                                                 ha_rows records)
 
6624
QUICK_RANGE_SELECT *get_quick_select_for_ref(Session *session, Table *table,
 
6625
                                             TABLE_REF *ref, ha_rows records)
4243
6626
{
4244
 
  memory::Root *old_root= NULL;
4245
 
  memory::Root *alloc= NULL;
4246
 
  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];
4247
6630
  KEY_PART *key_part;
4248
 
  optimizer::QuickRange *range= NULL;
 
6631
  QUICK_RANGE *range;
4249
6632
  uint32_t part;
4250
 
  optimizer::CostVector cost;
 
6633
  bool create_err= false;
 
6634
  COST_VECT cost;
4251
6635
 
4252
6636
  old_root= session->mem_root;
4253
6637
  /* The following call may change session->mem_root */
4254
 
  optimizer::QuickRangeSelect *quick= new optimizer::QuickRangeSelect(session, table, ref->key, 0, 0);
4255
 
  /* 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 */
4256
6640
  alloc= session->mem_root;
4257
6641
  /*
4258
6642
    return back default mem_root (session->mem_root) changed by
4259
 
    QuickRangeSelect constructor
 
6643
    QUICK_RANGE_SELECT constructor
4260
6644
  */
4261
6645
  session->mem_root= old_root;
4262
6646
 
4263
 
  if (! quick)
 
6647
  if (!quick || create_err)
4264
6648
    return 0;                   /* no ranges found */
4265
6649
  if (quick->init())
4266
6650
    goto err;
4267
6651
  quick->records= records;
4268
6652
 
4269
6653
  if ((cp_buffer_from_ref(session, ref) && session->is_fatal_error) ||
4270
 
      !(range= new(alloc) optimizer::QuickRange()))
 
6654
      !(range= new(alloc) QUICK_RANGE()))
4271
6655
    goto err;                                   // out of memory
4272
6656
 
4273
6657
  range->min_key= range->max_key= ref->key_buff;
4275
6659
  range->min_keypart_map= range->max_keypart_map=
4276
6660
    make_prev_keypart_map(ref->key_parts);
4277
6661
  range->flag= ((ref->key_length == key_info->key_length &&
4278
 
                 (key_info->flags & HA_END_SPACE_KEY) == 0) ? EQ_RANGE : 0);
4279
 
 
 
6662
                 key_info->flags == 0) ? EQ_RANGE : 0);
4280
6663
 
4281
6664
  if (!(quick->key_parts=key_part=(KEY_PART *)
4282
 
        quick->alloc.alloc_root(sizeof(KEY_PART)*ref->key_parts)))
 
6665
        alloc_root(&quick->alloc,sizeof(KEY_PART)*ref->key_parts)))
4283
6666
    goto err;
4284
6667
 
4285
6668
  for (part=0 ; part < ref->key_parts ;part++,key_part++)
4302
6685
  */
4303
6686
  if (ref->null_ref_key)
4304
6687
  {
4305
 
    optimizer::QuickRange *null_range= NULL;
 
6688
    QUICK_RANGE *null_range;
4306
6689
 
4307
6690
    *ref->null_ref_key= 1;              // Set null byte then create a range
4308
6691
    if (!(null_range= new (alloc)
4309
 
          optimizer::QuickRange(ref->key_buff, ref->key_length,
4310
 
                                 make_prev_keypart_map(ref->key_parts),
4311
 
                                 ref->key_buff, ref->key_length,
4312
 
                                 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)))
4313
6696
      goto err;
4314
6697
    *ref->null_ref_key= 0;              // Clear null byte
4315
6698
    if (insert_dynamic(&quick->ranges,(unsigned char*)&null_range))
4319
6702
  /* Call multi_range_read_info() to get the MRR flags and buffer size */
4320
6703
  quick->mrr_flags= HA_MRR_NO_ASSOCIATION |
4321
6704
                    (table->key_read ? HA_MRR_INDEX_ONLY : 0);
4322
 
  if (session->getLex()->sql_command != SQLCOM_SELECT)
 
6705
  if (session->lex->sql_command != SQLCOM_SELECT)
4323
6706
    quick->mrr_flags |= HA_MRR_USE_DEFAULT_IMPL;
4324
6707
 
4325
6708
  quick->mrr_buf_size= session->variables.read_rnd_buff_size;
4326
 
  if (table->cursor->multi_range_read_info(quick->index, 1, (uint32_t)records,
4327
 
                                           &quick->mrr_buf_size,
4328
 
                                           &quick->mrr_flags, &cost))
 
6709
  if (table->file->multi_range_read_info(quick->index, 1, (uint32_t)records,
 
6710
                                         &quick->mrr_buf_size,
 
6711
                                         &quick->mrr_flags, &cost))
4329
6712
    goto err;
4330
6713
 
4331
6714
  return quick;
4336
6719
 
4337
6720
 
4338
6721
/*
4339
 
  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
4340
7054
 
4341
7055
  SYNOPSIS
4342
7056
    quick_range_seq_init()
4343
 
      init_param  Caller-opaque paramenter: QuickRangeSelect* pointer
 
7057
      init_param  Caller-opaque paramenter: QUICK_RANGE_SELECT* pointer
4344
7058
      n_ranges    Number of ranges in the sequence (ignored)
4345
7059
      flags       MRR flags (currently not used)
4346
7060
 
4348
7062
    Opaque value to be passed to quick_range_seq_next
4349
7063
*/
4350
7064
 
4351
 
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)
4352
7066
{
4353
 
  optimizer::QuickRangeSelect *quick= (optimizer::QuickRangeSelect*)init_param;
4354
 
  quick->qr_traversal_ctx.first=  (optimizer::QuickRange**)quick->ranges.buffer;
4355
 
  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;
4356
7070
  quick->qr_traversal_ctx.last=   quick->qr_traversal_ctx.cur +
4357
7071
                                  quick->ranges.elements;
4358
7072
  return &quick->qr_traversal_ctx;
4360
7074
 
4361
7075
 
4362
7076
/*
4363
 
  Range sequence interface implementation for array<QuickRange>: get next
 
7077
  Range sequence interface implementation for array<QUICK_RANGE>: get next
4364
7078
 
4365
7079
  SYNOPSIS
4366
7080
    quick_range_seq_next()
4371
7085
    0  Ok
4372
7086
    1  No more ranges in the sequence
4373
7087
*/
4374
 
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)
4375
7090
{
4376
 
  QuickRangeSequenceContext *ctx= (QuickRangeSequenceContext*) rseq;
 
7091
  QUICK_RANGE_SEQ_CTX *ctx= (QUICK_RANGE_SEQ_CTX*)rseq;
4377
7092
 
4378
7093
  if (ctx->cur == ctx->last)
4379
7094
    return 1; /* no more ranges */
4380
7095
 
4381
 
  optimizer::QuickRange *cur= *(ctx->cur);
 
7096
  QUICK_RANGE *cur= *(ctx->cur);
4382
7097
  key_range *start_key= &range->start_key;
4383
 
  key_range *end_key= &range->end_key;
 
7098
  key_range *end_key=   &range->end_key;
4384
7099
 
4385
 
  start_key->key= cur->min_key;
 
7100
  start_key->key=    cur->min_key;
4386
7101
  start_key->length= cur->min_length;
4387
7102
  start_key->keypart_map= cur->min_keypart_map;
4388
 
  start_key->flag= ((cur->flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
4389
 
                                             (cur->flag & EQ_RANGE) ?
4390
 
                                             HA_READ_KEY_EXACT : HA_READ_KEY_OR_NEXT);
4391
 
  end_key->key= cur->max_key;
4392
 
  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;
4393
7108
  end_key->keypart_map= cur->max_keypart_map;
4394
7109
  /*
4395
7110
    We use HA_READ_AFTER_KEY here because if we are reading on a key
4396
7111
    prefix. We want to find all keys with this prefix.
4397
7112
  */
4398
 
  end_key->flag= (cur->flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
4399
 
                                         HA_READ_AFTER_KEY);
 
7113
  end_key->flag=     (cur->flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
 
7114
                      HA_READ_AFTER_KEY);
4400
7115
  range->range_flag= cur->flag;
4401
7116
  ctx->cur++;
4402
7117
  return 0;
4403
7118
}
4404
7119
 
4405
7120
 
4406
 
static inline uint32_t get_field_keypart(KeyInfo *index, Field *field);
4407
 
 
4408
 
static inline optimizer::SEL_ARG * get_index_range_tree(uint32_t index,
4409
 
                                                        optimizer::SEL_TREE *range_tree,
4410
 
                                                        optimizer::Parameter *param,
4411
 
                                                        uint32_t *param_idx);
4412
 
 
4413
 
static bool get_constant_key_infix(KeyInfo *index_info,
4414
 
                                   optimizer::SEL_ARG *index_range_tree,
4415
 
                                   KeyPartInfo *first_non_group_part,
4416
 
                                   KeyPartInfo *min_max_arg_part,
4417
 
                                   KeyPartInfo *last_part,
4418
 
                                   Session *session,
4419
 
                                   unsigned char *key_infix,
4420
 
                                   uint32_t *key_infix_len,
4421
 
                                   KeyPartInfo **first_non_infix_part);
4422
 
 
4423
 
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);
4424
7714
 
4425
7715
static void
4426
 
cost_group_min_max(Table* table,
4427
 
                   KeyInfo *index_info,
4428
 
                   uint32_t used_key_parts,
4429
 
                   uint32_t group_key_parts,
4430
 
                   optimizer::SEL_TREE *range_tree,
4431
 
                   optimizer::SEL_ARG *index_tree,
4432
 
                   ha_rows quick_prefix_records,
4433
 
                   bool have_min,
4434
 
                   bool have_max,
4435
 
                   double *read_cost,
4436
 
                   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);
4437
7721
 
4438
7722
 
4439
7723
/*
4446
7730
    sel_tree Range tree generated by get_mm_tree
4447
7731
 
4448
7732
  DESCRIPTION
4449
 
    Test whether a query can be computed via a QuickGroupMinMaxSelect.
4450
 
    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
4451
7735
    following conditions:
4452
7736
    A) Table T has at least one compound index I of the form:
4453
7737
       I = <A_1, ...,A_k, [B_1,..., B_m], C, [D_1,...,D_n]>
4531
7815
  NOTES
4532
7816
    If the current query satisfies the conditions above, and if
4533
7817
    (mem_root! = NULL), then the function constructs and returns a new TRP
4534
 
    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.
4535
7819
    If (mem_root == NULL), then the function only tests whether the current
4536
7820
    query satisfies the conditions above, and, if so, sets
4537
7821
    is_applicable = true.
4557
7841
 
4558
7842
  RETURN
4559
7843
    If mem_root != NULL
4560
 
    - 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
4561
7845
      the query
4562
7846
    -  NULL o/w.
4563
7847
    If mem_root == NULL
4564
7848
    - NULL
4565
7849
*/
4566
 
static optimizer::GroupMinMaxReadPlan *
4567
 
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)
4568
7853
{
4569
7854
  Session *session= param->session;
4570
 
  Join *join= session->getLex()->current_select->join;
 
7855
  JOIN *join= session->lex->current_select->join;
4571
7856
  Table *table= param->table;
4572
7857
  bool have_min= false;              /* true if there is a MIN function. */
4573
7858
  bool have_max= false;              /* true if there is a MAX function. */
4574
7859
  Item_field *min_max_arg_item= NULL; // The argument of all MIN/MAX functions
4575
 
  KeyPartInfo *min_max_arg_part= NULL; /* The corresponding keypart. */
 
7860
  KEY_PART_INFO *min_max_arg_part= NULL; /* The corresponding keypart. */
4576
7861
  uint32_t group_prefix_len= 0; /* Length (in bytes) of the key prefix. */
4577
 
  KeyInfo *index_info= NULL;    /* The index chosen for data access. */
 
7862
  KEY *index_info= NULL;    /* The index chosen for data access. */
4578
7863
  uint32_t index= 0;            /* The id of the chosen index. */
4579
7864
  uint32_t group_key_parts= 0;  // Number of index key parts in the group prefix.
4580
7865
  uint32_t used_key_parts= 0;   /* Number of index key parts used for access. */
4581
7866
  unsigned char key_infix[MAX_KEY_LENGTH]; /* Constants from equality predicates.*/
4582
7867
  uint32_t key_infix_len= 0;          /* Length of key_infix. */
4583
 
  optimizer::GroupMinMaxReadPlan *read_plan= NULL; /* The eventually constructed TRP. */
 
7868
  TRP_GROUP_MIN_MAX *read_plan= NULL; /* The eventually constructed TRP. */
4584
7869
  uint32_t key_part_nr;
4585
 
  Order *tmp_group= NULL;
4586
 
  Item *item= NULL;
4587
 
  Item_field *item_field= NULL;
 
7870
  order_st *tmp_group;
 
7871
  Item *item;
 
7872
  Item_field *item_field;
4588
7873
 
4589
7874
  /* Perform few 'cheap' tests whether this access method is applicable. */
4590
 
  if (! join)
 
7875
  if (!join)
4591
7876
    return NULL;        /* This is not a select statement. */
4592
 
 
4593
7877
  if ((join->tables != 1) ||  /* The query must reference one table. */
4594
 
      ((! join->group_list) && /* Neither GROUP BY nor a DISTINCT query. */
4595
 
       (! join->select_distinct)) ||
 
7878
      ((!join->group_list) && /* Neither GROUP BY nor a DISTINCT query. */
 
7879
       (!join->select_distinct)) ||
4596
7880
      (join->select_lex->olap == ROLLUP_TYPE)) /* Check (B3) for ROLLUP */
4597
7881
    return NULL;
4598
 
  if (table->getShare()->sizeKeys() == 0)        /* There are no indexes to use. */
 
7882
  if (table->s->keys == 0)        /* There are no indexes to use. */
4599
7883
    return NULL;
4600
7884
 
4601
7885
  /* Analyze the query in more detail. */
4602
 
  List<Item>::iterator select_items_it(join->fields_list.begin());
 
7886
  List_iterator<Item> select_items_it(join->fields_list);
4603
7887
 
4604
7888
  /* Check (SA1,SA4) and store the only MIN/MAX argument - the C attribute.*/
4605
7889
  if (join->make_sum_func_list(join->all_fields, join->fields_list, 1))
4606
7890
    return NULL;
4607
 
 
4608
7891
  if (join->sum_funcs[0])
4609
7892
  {
4610
 
    Item_sum *min_max_item= NULL;
 
7893
    Item_sum *min_max_item;
4611
7894
    Item_sum **func_ptr= join->sum_funcs;
4612
7895
    while ((min_max_item= *(func_ptr++)))
4613
7896
    {
4654
7937
    (GA1,GA2) are all true. If there is more than one such index, select the
4655
7938
    first one. Here we set the variables: group_prefix_len and index_info.
4656
7939
  */
4657
 
  KeyInfo *cur_index_info= table->key_info;
4658
 
  KeyInfo *cur_index_info_end= cur_index_info + table->getShare()->sizeKeys();
4659
 
  KeyPartInfo *cur_part= NULL;
4660
 
  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. */
4661
7944
  /* Last index part. */
4662
 
  KeyPartInfo *last_part= NULL;
4663
 
  KeyPartInfo *first_non_group_part= NULL;
4664
 
  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;
4665
7948
  uint32_t key_infix_parts= 0;
4666
7949
  uint32_t cur_group_key_parts= 0;
4667
7950
  uint32_t cur_group_prefix_len= 0;
4668
7951
  /* Cost-related variables for the best index so far. */
4669
7952
  double best_read_cost= DBL_MAX;
4670
7953
  ha_rows best_records= 0;
4671
 
  optimizer::SEL_ARG *best_index_tree= NULL;
 
7954
  SEL_ARG *best_index_tree= NULL;
4672
7955
  ha_rows best_quick_prefix_records= 0;
4673
7956
  uint32_t best_param_idx= 0;
4674
7957
  double cur_read_cost= DBL_MAX;
4675
7958
  ha_rows cur_records;
4676
 
  optimizer::SEL_ARG *cur_index_tree= NULL;
 
7959
  SEL_ARG *cur_index_tree= NULL;
4677
7960
  ha_rows cur_quick_prefix_records= 0;
4678
 
  uint32_t cur_param_idx= MAX_KEY;
4679
 
  key_map used_key_parts_map;
4680
 
  uint32_t cur_key_infix_len= 0;
4681
 
  unsigned char cur_key_infix[MAX_KEY_LENGTH];
4682
 
  uint32_t cur_used_key_parts= 0;
4683
 
  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;
4684
7964
 
4685
 
  for (uint32_t cur_index= 0;
4686
 
       cur_index_info != cur_index_info_end;
 
7965
  for (uint32_t cur_index= 0 ; cur_index_info != cur_index_info_end ;
4687
7966
       cur_index_info++, cur_index++)
4688
7967
  {
4689
7968
    /* Check (B1) - if current index is covering. */
4690
 
    if (! table->covering_keys.test(cur_index))
 
7969
    if (!table->covering_keys.is_set(cur_index))
4691
7970
      goto next_index;
4692
7971
 
4693
7972
    /*
4700
7979
      we check that all query fields are indeed covered by 'cur_index'.
4701
7980
    */
4702
7981
    if (pk < MAX_KEY && cur_index != pk &&
4703
 
        (table->cursor->getEngine()->check_flag(HTON_BIT_PRIMARY_KEY_IN_READ_INDEX)))
 
7982
        (table->file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX))
4704
7983
    {
4705
7984
      /* For each table field */
4706
 
      for (uint32_t i= 0; i < table->getShare()->sizeFields(); i++)
 
7985
      for (uint32_t i= 0; i < table->s->fields; i++)
4707
7986
      {
4708
 
        Field *cur_field= table->getField(i);
 
7987
        Field *cur_field= table->field[i];
4709
7988
        /*
4710
7989
          If the field is used in the current query ensure that it's
4711
7990
          part of 'cur_index'
4712
7991
        */
4713
 
        if ((cur_field->isReadSet()) &&
4714
 
            ! 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))
4715
7994
          goto next_index;                  // Field was not part of key
4716
7995
      }
4717
7996
    }
4724
8003
      cur_part= cur_index_info->key_part;
4725
8004
      end_part= cur_part + cur_index_info->key_parts;
4726
8005
      /* Iterate in parallel over the GROUP list and the index parts. */
4727
 
      for (tmp_group= join->group_list;
4728
 
           tmp_group && (cur_part != end_part);
 
8006
      for (tmp_group= join->group_list; tmp_group && (cur_part != end_part);
4729
8007
           tmp_group= tmp_group->next, cur_part++)
4730
8008
      {
4731
8009
        /*
4755
8033
    */
4756
8034
    else if (join->select_distinct)
4757
8035
    {
4758
 
      select_items_it= join->fields_list.begin();
4759
 
      used_key_parts_map.reset();
 
8036
      select_items_it.rewind();
 
8037
      cur_used_key_parts.clear_all();
4760
8038
      uint32_t max_key_part= 0;
4761
8039
      while ((item= select_items_it++))
4762
8040
      {
4767
8045
          Check if this attribute was already present in the select list.
4768
8046
          If it was present, then its corresponding key part was alredy used.
4769
8047
        */
4770
 
        if (used_key_parts_map.test(key_part_nr))
 
8048
        if (cur_used_key_parts.is_set(key_part_nr))
4771
8049
          continue;
4772
8050
        if (key_part_nr < 1 || key_part_nr > join->fields_list.elements)
4773
8051
          goto next_index;
4774
8052
        cur_part= cur_index_info->key_part + key_part_nr - 1;
4775
8053
        cur_group_prefix_len+= cur_part->store_length;
4776
 
        used_key_parts_map.set(key_part_nr);
 
8054
        cur_used_key_parts.set_bit(key_part_nr);
4777
8055
        ++cur_group_key_parts;
4778
 
        max_key_part= max(max_key_part,key_part_nr);
 
8056
        max_key_part= cmax(max_key_part,key_part_nr);
4779
8057
      }
4780
8058
      /*
4781
8059
        Check that used key parts forms a prefix of the index.
4783
8061
        all_parts have all bits set from 0 to (max_key_part-1).
4784
8062
        cur_parts have bits set for only used keyparts.
4785
8063
      */
4786
 
      key_map all_parts;
4787
 
      key_map cur_parts;
4788
 
      for (uint32_t pos= 0; pos < max_key_part; pos++)
4789
 
        all_parts.set(pos);
4790
 
      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;
4791
8067
      if (all_parts != cur_parts)
4792
8068
        goto next_index;
4793
8069
    }
4828
8104
                             NULL :
4829
8105
                           NULL;
4830
8106
    if (first_non_group_part &&
4831
 
        (! 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)))
4832
8108
    {
4833
8109
      if (tree)
4834
8110
      {
4835
8111
        uint32_t dummy;
4836
 
        optimizer::SEL_ARG *index_range_tree= get_index_range_tree(cur_index,
4837
 
                                                                   tree,
4838
 
                                                                   param,
4839
 
                                                                   &dummy);
4840
 
        if (! get_constant_key_infix(cur_index_info,
4841
 
                                     index_range_tree,
4842
 
                                     first_non_group_part,
4843
 
                                     min_max_arg_part,
4844
 
                                     last_part,
4845
 
                                     session,
4846
 
                                     cur_key_infix,
4847
 
                                     &cur_key_infix_len,
4848
 
                                     &first_non_infix_part))
4849
 
        {
 
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))
4850
8118
          goto next_index;
4851
 
        }
4852
8119
      }
4853
8120
      else if (min_max_arg_part &&
4854
8121
               (min_max_arg_part - first_non_group_part > 0))
4873
8140
          Store the first and last keyparts that need to be analyzed
4874
8141
          into one array that can be passed as parameter.
4875
8142
        */
4876
 
        KeyPartInfo *key_part_range[2];
 
8143
        KEY_PART_INFO *key_part_range[2];
4877
8144
        key_part_range[0]= first_non_group_part;
4878
8145
        key_part_range[1]= last_part;
4879
8146
 
4880
8147
        /* Check if cur_part is referenced in the WHERE clause. */
4881
 
        if (join->conds->walk(&Item::find_item_in_field_list_processor,
4882
 
                              0,
 
8148
        if (join->conds->walk(&Item::find_item_in_field_list_processor, 0,
4883
8149
                              (unsigned char*) key_part_range))
4884
8150
          goto next_index;
4885
8151
      }
4895
8161
                (min_max_arg_part && (min_max_arg_part < last_part));
4896
8162
      for (; cur_part != last_part; cur_part++)
4897
8163
      {
4898
 
        if (cur_part->field->isReadSet())
 
8164
        if (bitmap_is_set(table->read_set, cur_part->field->field_index))
4899
8165
          goto next_index;
4900
8166
      }
4901
8167
    }
4902
8168
 
4903
8169
    /* If we got to this point, cur_index_info passes the test. */
4904
 
    key_infix_parts= cur_key_infix_len ?
 
8170
    key_infix_parts= key_infix_len ?
4905
8171
                     (first_non_infix_part - first_non_group_part) : 0;
4906
 
    cur_used_key_parts= cur_group_key_parts + key_infix_parts;
 
8172
    used_key_parts= cur_group_key_parts + key_infix_parts;
4907
8173
 
4908
8174
    /* Compute the cost of using this index. */
4909
8175
    if (tree)
4910
8176
    {
4911
8177
      /* Find the SEL_ARG sub-tree that corresponds to the chosen index. */
4912
 
      cur_index_tree= get_index_range_tree(cur_index,
4913
 
                                           tree,
4914
 
                                           param,
 
8178
      cur_index_tree= get_index_range_tree(cur_index, tree, param,
4915
8179
                                           &cur_param_idx);
4916
8180
      /* Check if this range tree can be used for prefix retrieval. */
4917
 
      optimizer::CostVector dummy_cost;
 
8181
      COST_VECT dummy_cost;
4918
8182
      uint32_t mrr_flags= HA_MRR_USE_DEFAULT_IMPL;
4919
 
      uint32_t mrr_bufsize= 0;
4920
 
      cur_quick_prefix_records= check_quick_select(session,
4921
 
                                                   param,
4922
 
                                                   cur_param_idx,
 
8183
      uint32_t mrr_bufsize=0;
 
8184
      cur_quick_prefix_records= check_quick_select(param, cur_param_idx,
4923
8185
                                                   false /*don't care*/,
4924
 
                                                   cur_index_tree,
4925
 
                                                   true,
4926
 
                                                   &mrr_flags,
4927
 
                                                   &mrr_bufsize,
 
8186
                                                   cur_index_tree, true,
 
8187
                                                   &mrr_flags, &mrr_bufsize,
4928
8188
                                                   &dummy_cost);
4929
8189
    }
4930
 
    cost_group_min_max(table,
4931
 
                       cur_index_info,
4932
 
                       cur_used_key_parts,
4933
 
                       cur_group_key_parts,
4934
 
                       tree,
4935
 
                       cur_index_tree,
4936
 
                       cur_quick_prefix_records,
4937
 
                       have_min,
4938
 
                       have_max,
4939
 
                       &cur_read_cost,
4940
 
                       &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);
4941
8194
    /*
4942
8195
      If cur_read_cost is lower than best_read_cost use cur_index.
4943
8196
      Do not compare doubles directly because they may have different
4955
8208
      best_param_idx= cur_param_idx;
4956
8209
      group_key_parts= cur_group_key_parts;
4957
8210
      group_prefix_len= cur_group_prefix_len;
4958
 
      key_infix_len= cur_key_infix_len;
4959
 
 
4960
 
      if (key_infix_len)
4961
 
      {
4962
 
        memcpy(key_infix, cur_key_infix, sizeof (key_infix));
4963
 
      }
4964
 
 
4965
 
      used_key_parts= cur_used_key_parts;
4966
8211
    }
4967
8212
 
4968
8213
  next_index:
4969
8214
    cur_group_key_parts= 0;
4970
8215
    cur_group_prefix_len= 0;
4971
 
    cur_key_infix_len= 0;
4972
8216
  }
4973
 
  if (! index_info) /* No usable index found. */
 
8217
  if (!index_info) /* No usable index found. */
4974
8218
    return NULL;
4975
8219
 
4976
8220
  /* Check (SA3) for the where clause. */
4977
8221
  if (join->conds && min_max_arg_item &&
4978
 
      ! 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))
4979
8223
    return NULL;
4980
8224
 
4981
8225
  /* The query passes all tests, so construct a new TRP object. */
4982
 
  read_plan=
4983
 
    new(param->mem_root) optimizer::GroupMinMaxReadPlan(have_min,
4984
 
                                                        have_max,
4985
 
                                                        min_max_arg_part,
4986
 
                                                        group_prefix_len,
4987
 
                                                        used_key_parts,
4988
 
                                                        group_key_parts,
4989
 
                                                        index_info,
4990
 
                                                        index,
4991
 
                                                        key_infix_len,
4992
 
                                                        (key_infix_len > 0) ? key_infix : NULL,
4993
 
                                                        tree,
4994
 
                                                        best_index_tree,
4995
 
                                                        best_param_idx,
4996
 
                                                        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);
4997
8234
  if (read_plan)
4998
8235
  {
4999
8236
    if (tree && read_plan->quick_prefix_records == 0)
5000
8237
      return NULL;
5001
8238
 
5002
8239
    read_plan->read_cost= best_read_cost;
5003
 
    read_plan->records= best_records;
 
8240
    read_plan->records=   best_records;
5004
8241
  }
5005
8242
 
5006
8243
  return read_plan;
5028
8265
    true  if cond passes the test
5029
8266
    false o/w
5030
8267
*/
5031
 
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)
5032
8272
{
5033
8273
  assert(cond && min_max_arg_item);
5034
8274
 
5036
8276
  Item::Type cond_type= cond->type();
5037
8277
  if (cond_type == Item::COND_ITEM) /* 'AND' or 'OR' */
5038
8278
  {
5039
 
    List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
5040
 
    Item *and_or_arg= NULL;
 
8279
    List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
 
8280
    Item *and_or_arg;
5041
8281
    while ((and_or_arg= li++))
5042
8282
    {
5043
 
      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))
5044
8285
        return false;
5045
8286
    }
5046
8287
    return true;
5064
8305
  /* Test if cond references only group-by or non-group fields. */
5065
8306
  Item_func *pred= (Item_func*) cond;
5066
8307
  Item **arguments= pred->arguments();
5067
 
  Item *cur_arg= NULL;
 
8308
  Item *cur_arg;
5068
8309
  for (uint32_t arg_idx= 0; arg_idx < pred->argument_count (); arg_idx++)
5069
8310
  {
5070
8311
    cur_arg= arguments[arg_idx]->real_item();
5092
8333
        /* Check that pred compares min_max_arg_item with a constant. */
5093
8334
        Item *args[3];
5094
8335
        memset(args, 0, 3 * sizeof(Item*));
5095
 
        bool inv= false;
 
8336
        bool inv;
5096
8337
        /* Test if this is a comparison of a field and a constant. */
5097
 
        if (! optimizer::simple_pred(pred, args, inv))
 
8338
        if (!simple_pred(pred, args, &inv))
5098
8339
          return false;
5099
8340
 
5100
8341
        /* Check for compatible string comparisons - similar to get_mm_leaf. */
5104
8345
              Don't use an index when comparing strings of different collations.
5105
8346
            */
5106
8347
            ((args[1]->result_type() == STRING_RESULT &&
 
8348
              image_type == Field::itRAW &&
5107
8349
              ((Field_str*) min_max_arg_item->field)->charset() !=
5108
8350
              pred->compare_collation())
5109
8351
             ||
5113
8355
             */
5114
8356
             (args[1]->result_type() != STRING_RESULT &&
5115
8357
              min_max_arg_item->field->cmp_type() != args[1]->result_type())))
5116
 
        {
5117
8358
          return false;
5118
 
        }
5119
8359
      }
5120
8360
    }
5121
8361
    else if (cur_arg->type() == Item::FUNC_ITEM)
5122
8362
    {
5123
 
      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))
5124
8365
        return false;
5125
8366
    }
5126
8367
    else if (cur_arg->const_item())
5165
8406
    true  if the index passes the test
5166
8407
    false o/w
5167
8408
*/
 
8409
 
5168
8410
static bool
5169
 
get_constant_key_infix(KeyInfo *,
5170
 
                       optimizer::SEL_ARG *index_range_tree,
5171
 
                       KeyPartInfo *first_non_group_part,
5172
 
                       KeyPartInfo *min_max_arg_part,
5173
 
                       KeyPartInfo *last_part,
5174
 
                       Session *,
5175
 
                       unsigned char *key_infix,
5176
 
                       uint32_t *key_infix_len,
5177
 
                       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)
5178
8417
{
5179
 
  optimizer::SEL_ARG *cur_range= NULL;
5180
 
  KeyPartInfo *cur_part= NULL;
 
8418
  SEL_ARG       *cur_range;
 
8419
  KEY_PART_INFO *cur_part;
5181
8420
  /* End part for the first loop below. */
5182
 
  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;
5183
8422
 
5184
8423
  *key_infix_len= 0;
5185
8424
  unsigned char *key_ptr= key_infix;
5195
8434
      if (cur_range->field->eq(cur_part->field))
5196
8435
        break;
5197
8436
    }
5198
 
    if (! cur_range)
 
8437
    if (!cur_range)
5199
8438
    {
5200
8439
      if (min_max_arg_part)
5201
8440
        return false; /* The current keypart has no range predicates at all. */
5211
8450
      return false; /* This is not the only range predicate for the field. */
5212
8451
    if ((cur_range->min_flag & NO_MIN_RANGE) ||
5213
8452
        (cur_range->max_flag & NO_MAX_RANGE) ||
5214
 
        (cur_range->min_flag & NEAR_MIN) ||
5215
 
        (cur_range->max_flag & NEAR_MAX))
 
8453
        (cur_range->min_flag & NEAR_MIN) || (cur_range->max_flag & NEAR_MAX))
5216
8454
      return false;
5217
8455
 
5218
8456
    uint32_t field_length= cur_part->store_length;
5245
8483
    field  field that possibly references some key part in index
5246
8484
 
5247
8485
  NOTES
5248
 
    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
5249
8487
    part= index->key_part + get_field_keypart(...) - 1;
5250
8488
 
5251
8489
  RETURN
5252
8490
    Positive number which is the consecutive number of the key part, or
5253
8491
    0 if field does not reference any index field.
5254
8492
*/
 
8493
 
5255
8494
static inline uint
5256
 
get_field_keypart(KeyInfo *index, Field *field)
 
8495
get_field_keypart(KEY *index, Field *field)
5257
8496
{
5258
 
  KeyPartInfo *part= NULL;
5259
 
  KeyPartInfo *end= NULL;
 
8497
  KEY_PART_INFO *part, *end;
5260
8498
 
5261
8499
  for (part= index->key_part, end= part + index->key_parts; part < end; part++)
5262
8500
  {
5274
8512
    get_index_range_tree()
5275
8513
    index     [in]  The ID of the index being looked for
5276
8514
    range_tree[in]  Tree of ranges being searched
5277
 
    param     [in]  Parameter from SqlSelect::test_quick_select
5278
 
    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'
5279
8517
 
5280
8518
  DESCRIPTION
5281
8519
 
5282
 
    A optimizer::SEL_TREE contains range trees for all usable indexes. This procedure
5283
 
    finds the SEL_ARG sub-tree for 'index'. The members of a optimizer::SEL_TREE are
5284
 
    ordered in the same way as the members of Parameter::key, thus we first find
5285
 
    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
5286
8524
    through the variable param_idx, to be used later as argument of
5287
8525
    check_quick_select().
5288
8526
 
5289
8527
  RETURN
5290
8528
    Pointer to the SEL_ARG subtree that corresponds to index.
5291
8529
*/
5292
 
optimizer::SEL_ARG *get_index_range_tree(uint32_t index,
5293
 
                                         optimizer::SEL_TREE* range_tree,
5294
 
                                         optimizer::Parameter *param,
5295
 
                                         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)
5296
8533
{
5297
8534
  uint32_t idx= 0; /* Index nr in param->key_parts */
5298
8535
  while (idx < param->keys)
5325
8562
    records             [out] The number of rows retrieved
5326
8563
 
5327
8564
  DESCRIPTION
5328
 
    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
5329
8566
    the number of rows returned. It updates this->read_cost and this->records.
5330
8567
 
5331
8568
  NOTES
5365
8602
  RETURN
5366
8603
    None
5367
8604
*/
5368
 
void cost_group_min_max(Table* table,
5369
 
                        KeyInfo *index_info,
5370
 
                        uint32_t used_key_parts,
5371
 
                        uint32_t group_key_parts,
5372
 
                        optimizer::SEL_TREE *range_tree,
5373
 
                        optimizer::SEL_ARG *,
5374
 
                        ha_rows quick_prefix_records,
5375
 
                        bool have_min,
5376
 
                        bool have_max,
5377
 
                        double *read_cost,
5378
 
                        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)
5379
8611
{
5380
8612
  ha_rows table_records;
5381
8613
  uint32_t num_groups;
5389
8621
  double io_cost;
5390
8622
  double cpu_cost= 0; /* TODO: CPU cost of index_read calls? */
5391
8623
 
5392
 
  table_records= table->cursor->stats.records;
5393
 
  keys_per_block= (table->cursor->stats.block_size / 2 /
5394
 
                   (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)
5395
8627
                        + 1);
5396
 
  num_blocks= (uint32_t) (table_records / keys_per_block) + 1;
 
8628
  num_blocks= (uint32_t)(table_records / keys_per_block) + 1;
5397
8629
 
5398
8630
  /* Compute the number of keys in a group. */
5399
8631
  keys_per_group= index_info->rec_per_key[group_key_parts - 1];
5408
8640
    quick_prefix_selectivity= (double) quick_prefix_records /
5409
8641
                              (double) table_records;
5410
8642
    num_groups= (uint32_t) rint(num_groups * quick_prefix_selectivity);
5411
 
    set_if_bigger(num_groups, 1U);
 
8643
    set_if_bigger(num_groups, 1);
5412
8644
  }
5413
8645
 
5414
8646
  if (used_key_parts > group_key_parts)
5423
8655
    {
5424
8656
      double blocks_per_group= (double) num_blocks / (double) num_groups;
5425
8657
      p_overlap= (blocks_per_group * (keys_per_subgroup - 1)) / keys_per_group;
5426
 
      p_overlap= min(p_overlap, 1.0);
 
8658
      p_overlap= cmin(p_overlap, 1.0);
5427
8659
    }
5428
 
    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);
5429
8661
  }
5430
8662
  else
5431
8663
    io_cost= (keys_per_group > keys_per_block) ?
5436
8668
  /*
5437
8669
    TODO: If there is no WHERE clause and no other expressions, there should be
5438
8670
    no CPU cost. We leave it here to make this cost comparable to that of index
5439
 
    scan as computed in SqlSelect::test_quick_select().
 
8671
    scan as computed in SQL_SELECT::test_quick_select().
5440
8672
  */
5441
8673
  cpu_cost= (double) num_groups / TIME_FOR_COMPARE;
5442
8674
 
5449
8681
  Construct a new quick select object for queries with group by with min/max.
5450
8682
 
5451
8683
  SYNOPSIS
5452
 
    GroupMinMaxReadPlan::make_quick()
 
8684
    TRP_GROUP_MIN_MAX::make_quick()
5453
8685
    param              Parameter from test_quick_select
5454
8686
    retrieve_full_rows ignored
5455
8687
    parent_alloc       Memory pool to use, if any.
5456
8688
 
5457
8689
  NOTES
5458
8690
    Make_quick ignores the retrieve_full_rows parameter because
5459
 
    QuickGroupMinMaxSelect always performs 'index only' scans.
 
8691
    QUICK_GROUP_MIN_MAX_SELECT always performs 'index only' scans.
5460
8692
    The other parameter are ignored as well because all necessary
5461
8693
    data to create the QUICK object is computed at this TRP creation
5462
8694
    time.
5463
8695
 
5464
8696
  RETURN
5465
 
    New QuickGroupMinMaxSelect object if successfully created,
 
8697
    New QUICK_GROUP_MIN_MAX_SELECT object if successfully created,
5466
8698
    NULL otherwise.
5467
8699
*/
5468
 
optimizer::QuickSelectInterface *
5469
 
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)
5470
8703
{
5471
 
  optimizer::QuickGroupMinMaxSelect *quick= NULL;
 
8704
  QUICK_GROUP_MIN_MAX_SELECT *quick;
5472
8705
 
5473
 
  quick= new optimizer::QuickGroupMinMaxSelect(param->table,
5474
 
                                               param->session->getLex()->current_select->join,
5475
 
                                               have_min,
5476
 
                                               have_max,
5477
 
                                               min_max_arg_part,
5478
 
                                               group_prefix_len,
5479
 
                                               group_key_parts,
5480
 
                                               used_key_parts,
5481
 
                                               index_info,
5482
 
                                               index,
5483
 
                                               read_cost,
5484
 
                                               records,
5485
 
                                               key_infix_len,
5486
 
                                               key_infix,
5487
 
                                               parent_alloc);
5488
 
  if (! quick)
5489
 
  {
 
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)
5490
8714
    return NULL;
5491
 
  }
5492
8715
 
5493
8716
  if (quick->init())
5494
8717
  {
5500
8723
  {
5501
8724
    assert(quick_prefix_records > 0);
5502
8725
    if (quick_prefix_records == HA_POS_ERROR)
5503
 
    {
5504
8726
      quick->quick_prefix_select= NULL; /* Can't construct a quick select. */
5505
 
    }
5506
8727
    else
5507
 
    {
5508
 
      /* Make a QuickRangeSelect to be used for group prefix retrieval. */
5509
 
      quick->quick_prefix_select= optimizer::get_quick_select(param,
5510
 
                                                              param_idx,
5511
 
                                                              index_tree,
5512
 
                                                              HA_MRR_USE_DEFAULT_IMPL,
5513
 
                                                              0,
5514
 
                                                              &quick->alloc);
5515
 
    }
 
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);
5516
8733
 
5517
8734
    /*
5518
8735
      Extract the SEL_ARG subtree that contains only ranges for the MIN/MAX
5519
 
      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
5520
8737
      new quick select.
5521
8738
    */
5522
8739
    if (min_max_arg_part)
5523
8740
    {
5524
 
      optimizer::SEL_ARG *min_max_range= index_tree;
 
8741
      SEL_ARG *min_max_range= index_tree;
5525
8742
      while (min_max_range) /* Find the tree for the MIN/MAX key part. */
5526
8743
      {
5527
8744
        if (min_max_range->field->eq(min_max_arg_part->field))
5531
8748
      /* Scroll to the leftmost interval for the MIN/MAX argument. */
5532
8749
      while (min_max_range && min_max_range->prev)
5533
8750
        min_max_range= min_max_range->prev;
5534
 
      /* Create an array of QuickRanges for the MIN/MAX argument. */
 
8751
      /* Create an array of QUICK_RANGEs for the MIN/MAX argument. */
5535
8752
      while (min_max_range)
5536
8753
      {
5537
8754
        if (quick->add_range(min_max_range))
5554
8771
}
5555
8772
 
5556
8773
 
5557
 
optimizer::QuickSelectInterface *optimizer::RangeReadPlan::make_quick(optimizer::Parameter *param, bool, memory::Root *parent_alloc)
5558
 
{
5559
 
  optimizer::QuickRangeSelect *quick= NULL;
5560
 
  if ((quick= optimizer::get_quick_select(param,
5561
 
                                          key_idx,
5562
 
                                          key,
5563
 
                                          mrr_flags,
5564
 
                                          mrr_buf_size,
5565
 
                                          parent_alloc)))
5566
 
  {
5567
 
    quick->records= records;
5568
 
    quick->read_time= read_cost;
5569
 
  }
5570
 
  return quick;
5571
 
}
5572
 
 
5573
 
 
5574
 
uint32_t optimizer::RorScanInfo::findFirstNotSet() const
5575
 
{
5576
 
  boost::dynamic_bitset<> map= bitsToBitset();
5577
 
  for (boost::dynamic_bitset<>::size_type i= 0; i < map.size(); i++)
5578
 
  {
5579
 
    if (! map.test(i))
5580
 
    {
5581
 
      return i;
5582
 
    }
5583
 
  }
5584
 
  return map.size();
5585
 
}
5586
 
 
5587
 
 
5588
 
size_t optimizer::RorScanInfo::getBitCount() const
5589
 
{
5590
 
  boost::dynamic_bitset<> tmp_bitset= bitsToBitset();
5591
 
  return tmp_bitset.count();
5592
 
}
5593
 
 
5594
 
 
5595
 
void optimizer::RorScanInfo::subtractBitset(const boost::dynamic_bitset<>& in_bitset)
5596
 
{
5597
 
  boost::dynamic_bitset<> tmp_bitset= bitsToBitset();
5598
 
  tmp_bitset-= in_bitset;
5599
 
  covered_fields= tmp_bitset.to_ulong();
5600
 
}
5601
 
 
5602
 
 
5603
 
boost::dynamic_bitset<> optimizer::RorScanInfo::bitsToBitset() const
5604
 
{
5605
 
  string res;
5606
 
  uint64_t conv= covered_fields;
5607
 
  while (conv)
5608
 
  {
5609
 
    res.push_back((conv & 1) + '0');
5610
 
    conv>>= 1;
5611
 
  }
5612
 
  if (! res.empty())
5613
 
  {
5614
 
    std::reverse(res.begin(), res.end());
5615
 
  }
5616
 
  string final(covered_fields_size - res.length(), '0');
5617
 
  final.append(res);
5618
 
  return (boost::dynamic_bitset<>(final));
5619
 
}
5620
 
 
5621
 
 
5622
 
} /* 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