~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to sql/opt_range.cc

  • Committer: brian
  • Date: 2008-06-25 05:29:13 UTC
  • Revision ID: brian@localhost.localdomain-20080625052913-6upwo0jsrl4lnapl
clean slate

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