~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/opt_range.cc

  • Committer: Monty Taylor
  • Date: 2009-03-16 16:56:48 UTC
  • mto: This revision was merged to the branch mainline in revision 938.
  • Revision ID: mordred@inaugust.com-20090316165648-0dsce73jne0qikk0
Addd -Wshadow to PROTOSKIP warnings and turned -Wstrict-aliasing off. Jumped the gun...

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