~drizzle-trunk/drizzle/development

1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 *
1999.6.1 by kalebral at gmail
update Copyright strings to a more common format to help with creating the master debian copyright file
4
 *  Copyright (C) 2008-2009 Sun Microsystems, Inc.
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
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 by brian
clean slate
19
20
/*
21
  TODO:
22
  Fix that MAYBE_KEY are stored in the tree so that we can detect use
23
  of full hash keys for queries like:
24
25
  select s.id, kws.keyword_id from sites as s,kws where s.id=kws.site_id and kws.keyword_id in (204,205);
26
27
*/
28
29
/*
1208.3.2 by brian
Update for Cursor renaming.
30
  This cursor contains:
1 by brian
clean slate
31
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
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
1 by brian
clean slate
36
    intervals.
37
    The entry point for the range analysis module is get_mm_tree() function.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
38
1 by brian
clean slate
39
    The lists are returned in form of complicated structure of interlinked
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
40
    optimizer::SEL_TREE/optimizer::SEL_IMERGE/SEL_ARG objects.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
41
    See quick_range_seq_next, find_used_partitions for examples of how to walk
1 by brian
clean slate
42
    this structure.
1208.3.2 by brian
Update for Cursor renaming.
43
    All direct "users" of this module are located within this cursor, too.
1 by brian
clean slate
44
45
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
46
  Range/index_merge/groupby-minmax optimizer module
47
    A module that accepts a table, condition, and returns
1 by brian
clean slate
48
     - a QUICK_*_SELECT object that can be used to retrieve rows that match
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
49
       the specified condition, or a "no records will match the condition"
1 by brian
clean slate
50
       statement.
51
52
    The module entry points are
53
      test_quick_select()
54
      get_quick_select_for_ref()
55
56
57
  Record retrieval code for range/index_merge/groupby-min-max.
58
    Implementations of QUICK_*_SELECT classes.
59
60
  KeyTupleFormat
61
  ~~~~~~~~~~~~~~
1208.3.2 by brian
Update for Cursor renaming.
62
  The code in this cursor (and elsewhere) makes operations on key value tuples.
1 by brian
clean slate
63
  Those tuples are stored in the following format:
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
64
1 by brian
clean slate
65
  The tuple is a sequence of key part values. The length of key part value
66
  depends only on its type (and not depends on the what value is stored)
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
67
1 by brian
clean slate
68
    KeyTuple: keypart1-data, keypart2-data, ...
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
69
1 by brian
clean slate
70
  The value of each keypart is stored in the following format:
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
71
1 by brian
clean slate
72
    keypart_data: [isnull_byte] keypart-value-bytes
73
74
  If a keypart may have a NULL value (key_part->field->real_maybe_null() can
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
75
  be used to check this), then the first byte is a NULL indicator with the
1 by brian
clean slate
76
  following valid values:
77
    1  - keypart has NULL value.
78
    0  - keypart has non-NULL value.
79
80
  <questionable-statement> If isnull_byte==1 (NULL value), then the following
81
  keypart->length bytes must be 0.
82
  </questionable-statement>
83
84
  keypart-value-bytes holds the value. Its format depends on the field type.
85
  The length of keypart-value-bytes may or may not depend on the value being
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
86
  stored. The default is that length is static and equal to
1534 by Brian Aker
Remove of KeyPartInfo
87
  KeyPartInfo::length.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
88
89
  Key parts with (key_part_flag & HA_BLOB_PART) have length depending of the
1 by brian
clean slate
90
  value:
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
91
1 by brian
clean slate
92
     keypart-value-bytes: value_length value_bytes
93
94
  The value_length part itself occupies HA_KEY_BLOB_LENGTH=2 bytes.
95
96
  See key_copy() and key_restore() for code to move data between index tuple
97
  and table record
98
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
99
  CAUTION: the above description is only sergefp's understanding of the
1 by brian
clean slate
100
           subject and may omit some details.
101
*/
102
1241.9.36 by Monty Taylor
ZOMG. I deleted drizzled/server_includes.h.
103
#include "config.h"
1241.9.1 by Monty Taylor
Removed global.h. Fixed all the headers.
104
105
#include <math.h>
106
#include <float.h>
107
108
#include <string>
109
#include <vector>
110
#include <algorithm>
111
1802.16.2 by Padraig O'Sullivan
Got rid of MyBitmap instance in the range optimizer.
112
#include <boost/dynamic_bitset.hpp>
113
1237.9.1 by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file
114
#include "drizzled/sql_base.h"
115
#include "drizzled/sql_select.h"
116
#include "drizzled/error.h"
1336.3.2 by Djellel E. Difallah
rename class COST_VECT to CostVector and move it to ./drizzled/optimizer directory
117
#include "drizzled/optimizer/cost_vector.h"
1237.9.1 by Padraig O'Sullivan
Moved the opt_sum.cc file into the optimizer directory and renamed it to sum.cc. Added a header file
118
#include "drizzled/item/cmpfunc.h"
119
#include "drizzled/field/num.h"
120
#include "drizzled/check_stack_overrun.h"
121
#include "drizzled/optimizer/sum.h"
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
122
#include "drizzled/optimizer/range.h"
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
123
#include "drizzled/optimizer/quick_range.h"
124
#include "drizzled/optimizer/quick_range_select.h"
1237.13.18 by Padraig O'Sullivan
Split the QUICK_GROUP_MIN_MAX_SELECT class out into its own header and implementation files.
125
#include "drizzled/optimizer/quick_group_min_max_select.h"
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
126
#include "drizzled/optimizer/quick_index_merge_select.h"
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
127
#include "drizzled/optimizer/quick_ror_intersect_select.h"
1237.13.13 by Padraig O'Sullivan
Moved the QUICK_ROR_UNION_SELECT class into its own header and implementation files.
128
#include "drizzled/optimizer/quick_ror_union_select.h"
1237.13.22 by Padraig O'Sullivan
Extracted a number of small classes into the table_read_plan.h header file.
129
#include "drizzled/optimizer/table_read_plan.h"
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
130
#include "drizzled/optimizer/sel_arg.h"
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
131
#include "drizzled/optimizer/sel_imerge.h"
132
#include "drizzled/optimizer/sel_tree.h"
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
133
#include "drizzled/optimizer/range_param.h"
1237.9.4 by Padraig O'Sullivan
Removed the inclusion of drizzled/field.h in the server_includes header file.
134
#include "drizzled/records.h"
1241.9.64 by Monty Taylor
Moved remaining non-public portions of mysys and mystrings to drizzled/internal.
135
#include "drizzled/internal/my_sys.h"
136
#include "drizzled/internal/iocache.h"
575.1.3 by Monty Taylor
Moved some stuff out of handler.h.
137
907.1.7 by Jay Pipes
Merged in remove-timezone work
138
#include "drizzled/temporal.h" /* Needed in get_mm_leaf() for timestamp -> datetime comparisons */
139
656.1.1 by Monty Taylor
OOOh doggie. Got rid of my_alloca.
140
using namespace std;
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
141
namespace drizzled
142
{
1 by brian
clean slate
143
1100.1.1 by Brian Aker
Disable MRR
144
#define HA_END_SPACE_KEY 0
145
1 by brian
clean slate
146
/*
147
  Convert double value to #rows. Currently this does floor(), and we
148
  might consider using round() instead.
149
*/
919.2.11 by Monty Taylor
Removed C99 isnan() usage, which allows us to remove the util/math.{cc,h} workarounds. Yay for standards!
150
static inline ha_rows double2rows(double x)
151
{
152
    return static_cast<ha_rows>(x);
153
}
1 by brian
clean slate
154
481 by Brian Aker
Remove all of uchar.
155
static unsigned char is_null_string[2]= {1,0};
1 by brian
clean slate
156
1183.1.4 by Brian Aker
Minor interface bits around Cursor.
157
158
/**
159
  Get cost of reading nrows table records in a "disk sweep"
160
161
  A disk sweep read is a sequence of Cursor->rnd_pos(rowid) calls that made
162
  for an ordered sequence of rowids.
163
164
  We assume hard disk IO. The read is performed as follows:
165
166
   1. The disk head is moved to the needed cylinder
167
   2. The controller waits for the plate to rotate
168
   3. The data is transferred
169
170
  Time to do #3 is insignificant compared to #2+#1.
171
172
  Time to move the disk head is proportional to head travel distance.
173
174
  Time to wait for the plate to rotate depends on whether the disk head
175
  was moved or not.
176
177
  If disk head wasn't moved, the wait time is proportional to distance
178
  between the previous block and the block we're reading.
179
180
  If the head was moved, we don't know how much we'll need to wait for the
181
  plate to rotate. We assume the wait time to be a variate with a mean of
182
  0.5 of full rotation time.
183
184
  Our cost units are "random disk seeks". The cost of random disk seek is
185
  actually not a constant, it depends one range of cylinders we're going
186
  to access. We make it constant by introducing a fuzzy concept of "typical
187
  datafile length" (it's fuzzy as it's hard to tell whether it should
1208.3.2 by brian
Update for Cursor renaming.
188
  include index cursor, temp.tables etc). Then random seek cost is:
1183.1.4 by Brian Aker
Minor interface bits around Cursor.
189
190
    1 = half_rotation_cost + move_cost * 1/3 * typical_data_file_length
191
192
  We define half_rotation_cost as DISK_SEEK_BASE_COST=0.9.
193
194
  @param table             Table to be accessed
195
  @param nrows             Number of rows to retrieve
196
  @param interrupted       true <=> Assume that the disk sweep will be
197
                           interrupted by other disk IO. false - otherwise.
198
  @param cost         OUT  The cost.
199
*/
200
1240.3.1 by Brian Aker
Merge Padraig.
201
static void get_sweep_read_cost(Table *table,
202
                                ha_rows nrows,
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
203
                                bool interrupted,
1336.3.2 by Djellel E. Difallah
rename class COST_VECT to CostVector and move it to ./drizzled/optimizer directory
204
                                optimizer::CostVector *cost)
1183.1.4 by Brian Aker
Minor interface bits around Cursor.
205
{
206
  cost->zero();
1208.3.2 by brian
Update for Cursor renaming.
207
  if (table->cursor->primary_key_is_clustered())
1183.1.4 by Brian Aker
Minor interface bits around Cursor.
208
  {
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
209
    cost->setIOCount(table->cursor->read_time(table->getShare()->getPrimaryKey(),
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
210
                                             static_cast<uint32_t>(nrows),
1336.3.1 by Djellel E. Difallah
Cleanup & Encapsulate the COST_VECT class, and remove ./drizzled/cursor.h self include
211
                                             nrows));
1183.1.4 by Brian Aker
Minor interface bits around Cursor.
212
  }
213
  else
214
  {
215
    double n_blocks=
1208.3.2 by brian
Update for Cursor renaming.
216
      ceil(uint64_t2double(table->cursor->stats.data_file_length) / IO_SIZE);
1183.1.4 by Brian Aker
Minor interface bits around Cursor.
217
    double busy_blocks=
218
      n_blocks * (1.0 - pow(1.0 - 1.0/n_blocks, rows2double(nrows)));
219
    if (busy_blocks < 1.0)
220
      busy_blocks= 1.0;
221
1336.3.2 by Djellel E. Difallah
rename class COST_VECT to CostVector and move it to ./drizzled/optimizer directory
222
    cost->setIOCount(busy_blocks);
1183.1.4 by Brian Aker
Minor interface bits around Cursor.
223
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
224
    if (! interrupted)
1183.1.4 by Brian Aker
Minor interface bits around Cursor.
225
    {
226
      /* Assume reading is done in one 'sweep' */
1336.3.2 by Djellel E. Difallah
rename class COST_VECT to CostVector and move it to ./drizzled/optimizer directory
227
      cost->setAvgIOCost((DISK_SEEK_BASE_COST +
1336.3.1 by Djellel E. Difallah
Cleanup & Encapsulate the COST_VECT class, and remove ./drizzled/cursor.h self include
228
                          DISK_SEEK_PROP_COST*n_blocks/busy_blocks));
1183.1.4 by Brian Aker
Minor interface bits around Cursor.
229
    }
230
  }
231
}
232
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
233
static optimizer::SEL_TREE * get_mm_parts(optimizer::RangeParameter *param,
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
234
                               COND *cond_func,
235
                               Field *field,
236
			                         Item_func::Functype type,
237
                               Item *value,
238
			                         Item_result cmp_type);
239
1237.13.7 by Padraig O'Sullivan
Renamed PARAM to Parameter and RANGE_OPT_PARAM to RangeParameter.
240
static optimizer::SEL_ARG *get_mm_leaf(optimizer::RangeParameter *param,
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
241
                                       COND *cond_func,
242
                                       Field *field,
243
                                       KEY_PART *key_part,
244
			                                 Item_func::Functype type,
245
                                       Item *value);
246
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
247
static optimizer::SEL_TREE *get_mm_tree(optimizer::RangeParameter *param, COND *cond);
1237.13.7 by Padraig O'Sullivan
Renamed PARAM to Parameter and RANGE_OPT_PARAM to RangeParameter.
248
249
static bool is_key_scan_ror(optimizer::Parameter *param, uint32_t keynr, uint8_t nparts);
250
1578.4.11 by Brian Aker
PAss through the code removing current_session
251
static ha_rows check_quick_select(Session *session,
252
                                  optimizer::Parameter *param,
1240.3.1 by Brian Aker
Merge Padraig.
253
                                  uint32_t idx,
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
254
                                  bool index_only,
1240.3.1 by Brian Aker
Merge Padraig.
255
                                  optimizer::SEL_ARG *tree,
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
256
                                  bool update_tbl_stats,
1240.3.1 by Brian Aker
Merge Padraig.
257
                                  uint32_t *mrr_flags,
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
258
                                  uint32_t *bufsize,
1336.3.2 by Djellel E. Difallah
rename class COST_VECT to CostVector and move it to ./drizzled/optimizer directory
259
                                  optimizer::CostVector *cost);
1 by brian
clean slate
260
1578.4.11 by Brian Aker
PAss through the code removing current_session
261
static optimizer::RangeReadPlan *get_key_scans_params(Session *session,
262
                                                      optimizer::Parameter *param,
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
263
                                                      optimizer::SEL_TREE *tree,
1237.13.28 by Padraig O'Sullivan
Modified classes to have names in camel case instead of all upper case. Added default constructors
264
                                                      bool index_read_must_be_used,
265
                                                      bool update_tbl_stats,
266
                                                      double read_time);
1237.13.22 by Padraig O'Sullivan
Extracted a number of small classes into the table_read_plan.h header file.
267
268
static
1237.13.27 by Padraig O'Sullivan
Correcting the case of a number of classes in the optimizer to adhere to the coding standards. Also
269
optimizer::RorIntersectReadPlan *get_best_ror_intersect(const optimizer::Parameter *param,
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
270
                                                        optimizer::SEL_TREE *tree,
1237.13.27 by Padraig O'Sullivan
Correcting the case of a number of classes in the optimizer to adhere to the coding standards. Also
271
                                                        double read_time,
272
                                                        bool *are_all_covering);
1237.13.22 by Padraig O'Sullivan
Extracted a number of small classes into the table_read_plan.h header file.
273
274
static
1511 by Brian Aker
This should be dead code, but I am going to see if that was the case.
275
optimizer::RorIntersectReadPlan *get_best_covering_ror_intersect(optimizer::Parameter *param,
276
                                                                 optimizer::SEL_TREE *tree,
277
                                                                 double read_time);
278
279
static
1578.4.11 by Brian Aker
PAss through the code removing current_session
280
optimizer::TableReadPlan *get_best_disjunct_quick(Session *session,
281
                                                  optimizer::Parameter *param,
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
282
                                                  optimizer::SEL_IMERGE *imerge,
1237.13.26 by Padraig O'Sullivan
Modified the case of TABLE_READ_PLAN to now be TableReadPlan.
283
                                                  double read_time);
1237.13.22 by Padraig O'Sullivan
Extracted a number of small classes into the table_read_plan.h header file.
284
285
static
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
286
optimizer::GroupMinMaxReadPlan *get_best_group_min_max(optimizer::Parameter *param, optimizer::SEL_TREE *tree);
1 by brian
clean slate
287
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
288
static optimizer::SEL_TREE *tree_and(optimizer::RangeParameter *param, 
289
                                     optimizer::SEL_TREE *tree1, 
290
                                     optimizer::SEL_TREE *tree2);
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
291
292
static optimizer::SEL_ARG *sel_add(optimizer::SEL_ARG *key1, optimizer::SEL_ARG *key2);
293
1240.3.1 by Brian Aker
Merge Padraig.
294
static optimizer::SEL_ARG *key_and(optimizer::RangeParameter *param,
295
                                   optimizer::SEL_ARG *key1,
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
296
                                   optimizer::SEL_ARG *key2,
297
                                   uint32_t clone_flag);
298
299
static bool get_range(optimizer::SEL_ARG **e1, optimizer::SEL_ARG **e2, optimizer::SEL_ARG *root1);
300
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
301
optimizer::SEL_ARG optimizer::null_element(optimizer::SEL_ARG::IMPOSSIBLE);
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
302
1240.3.1 by Brian Aker
Merge Padraig.
303
static bool null_part_in_key(KEY_PART *key_part,
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
304
                             const unsigned char *key,
482 by Brian Aker
Remove uint.
305
                             uint32_t length);
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
306
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
307
bool sel_trees_can_be_ored(optimizer::SEL_TREE *tree1, 
308
                           optimizer::SEL_TREE *tree2, 
309
                           optimizer::RangeParameter *param);
310
311
312
313
1 by brian
clean slate
314
315
316
/*
1211 by Brian Aker
Reverses old patch which introduced memory leaks. Also found a solution
317
  Perform AND operation on two index_merge lists and store result in *im1.
1 by brian
clean slate
318
*/
319
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
320
inline void imerge_list_and_list(List<optimizer::SEL_IMERGE> *im1, List<optimizer::SEL_IMERGE> *im2)
1 by brian
clean slate
321
{
1211 by Brian Aker
Reverses old patch which introduced memory leaks. Also found a solution
322
  im1->concat(im2);
1 by brian
clean slate
323
}
324
325
326
/***************************************************************************
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
327
** Basic functions for SqlSelect and QuickRangeSelect
1 by brian
clean slate
328
***************************************************************************/
329
330
	/* make a select from mysql info
331
	   Error is set as following:
332
	   0 = ok
333
	   1 = Got some error (out of memory?)
334
	   */
335
1240.3.1 by Brian Aker
Merge Padraig.
336
optimizer::SqlSelect *optimizer::make_select(Table *head,
1237.13.12 by Padraig O'Sullivan
Corrected the name of the QUICK_ROR_INTERSECT_CLASS class to adhere to the drizzle coding standards.
337
                                             table_map const_tables,
338
                                             table_map read_tables,
339
                                             COND *conds,
340
                                             bool allow_null_cond,
341
                                             int *error)
1 by brian
clean slate
342
{
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
343
  optimizer::SqlSelect *select= NULL;
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
344
345
  *error= 0;
346
347
  if (! conds && ! allow_null_cond)
348
  {
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
349
    return 0;
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
350
  }
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
351
  if (! (select= new optimizer::SqlSelect))
1 by brian
clean slate
352
  {
353
    *error= 1;			// out of memory
971.6.11 by Eric Day
Removed purecov messages.
354
    return 0;
1 by brian
clean slate
355
  }
356
  select->read_tables=read_tables;
357
  select->const_tables=const_tables;
358
  select->head=head;
359
  select->cond=conds;
360
361
  if (head->sort.io_cache)
362
  {
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
363
    memcpy(select->file, head->sort.io_cache, sizeof(internal::IO_CACHE));
1241.9.48 by Monty Taylor
Made one of the drizzled instances of IO_CACHE a pointer.
364
    select->records=(ha_rows) (select->file->end_of_file/
1208.3.2 by brian
Update for Cursor renaming.
365
			       head->cursor->ref_length);
760.1.3 by Kristian Nielsen
Fix IO_CACHE memory handling, if we allocate with new, we must not
366
    delete head->sort.io_cache;
1 by brian
clean slate
367
    head->sort.io_cache=0;
368
  }
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
369
  return(select);
1 by brian
clean slate
370
}
371
372
1237.13.12 by Padraig O'Sullivan
Corrected the name of the QUICK_ROR_INTERSECT_CLASS class to adhere to the drizzle coding standards.
373
optimizer::SqlSelect::SqlSelect() 
374
  :
375
    quick(NULL),
376
    cond(NULL),
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
377
    file(static_cast<internal::IO_CACHE *>(memory::sql_calloc(sizeof(internal::IO_CACHE)))),
1237.13.19 by Padraig O'Sullivan
Resolved warning on OSX due to initializing a class member in a constructor to an incorrect type.
378
    free_cond(false)
1 by brian
clean slate
379
{
1240.3.1 by Brian Aker
Merge Padraig.
380
  quick_keys.reset();
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
381
  needed_reg.reset();
1241.9.48 by Monty Taylor
Made one of the drizzled instances of IO_CACHE a pointer.
382
  my_b_clear(file);
1 by brian
clean slate
383
}
384
385
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
386
void optimizer::SqlSelect::cleanup()
1 by brian
clean slate
387
{
1746.5.1 by Andrew Hutchings
Fix potential double free in range optimizer cleanup
388
  if (quick)
389
  {
390
    delete quick;
391
    quick= NULL;
392
  }
393
1 by brian
clean slate
394
  if (free_cond)
395
  {
1237.13.12 by Padraig O'Sullivan
Corrected the name of the QUICK_ROR_INTERSECT_CLASS class to adhere to the drizzle coding standards.
396
    free_cond= 0;
1 by brian
clean slate
397
    delete cond;
398
    cond= 0;
399
  }
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
400
  file->close_cached_file();
1 by brian
clean slate
401
}
402
403
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
404
optimizer::SqlSelect::~SqlSelect()
1 by brian
clean slate
405
{
406
  cleanup();
407
}
408
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
409
1237.13.12 by Padraig O'Sullivan
Corrected the name of the QUICK_ROR_INTERSECT_CLASS class to adhere to the drizzle coding standards.
410
bool optimizer::SqlSelect::check_quick(Session *session, 
411
                                       bool force_quick_range,
412
                                       ha_rows limit)
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
413
{
414
  key_map tmp;
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
415
  tmp.set();
1237.13.12 by Padraig O'Sullivan
Corrected the name of the QUICK_ROR_INTERSECT_CLASS class to adhere to the drizzle coding standards.
416
  return (test_quick_select(session, 
417
                           tmp, 
418
                           0, 
419
                           limit,
420
                           force_quick_range, 
421
                           false) < 0);
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
422
}
423
424
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
425
bool optimizer::SqlSelect::skip_record()
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
426
{
1237.13.12 by Padraig O'Sullivan
Corrected the name of the QUICK_ROR_INTERSECT_CLASS class to adhere to the drizzle coding standards.
427
  return (cond ? cond->val_int() == 0 : 0);
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
428
}
429
430
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
431
optimizer::QuickSelectInterface::QuickSelectInterface()
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
432
  :
433
    max_used_key_length(0),
434
    used_key_parts(0)
1 by brian
clean slate
435
{}
436
437
438
/*
439
  Find the best index to retrieve first N records in given order
440
441
  SYNOPSIS
442
    get_index_for_order()
443
      table  Table to be accessed
444
      order  Required ordering
445
      limit  Number of records that will be retrieved
446
447
  DESCRIPTION
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
448
    Find the best index that allows to retrieve first #limit records in the
1 by brian
clean slate
449
    given order cheaper then one would retrieve them using full table scan.
450
451
  IMPLEMENTATION
452
    Run through all table indexes and find the shortest index that allows
453
    records to be retrieved in given order. We look for the shortest index
454
    as we will have fewer index pages to read with it.
455
456
    This function is used only by UPDATE/DELETE, so we take into account how
457
    the UPDATE/DELETE code will work:
458
     * index can only be scanned in forward direction
459
     * HA_EXTRA_KEYREAD will not be used
460
    Perhaps these assumptions could be relaxed.
461
462
  RETURN
463
    Number of the index that produces the required ordering in the cheapest way
464
    MAX_KEY if no such index was found.
465
*/
466
1892.3.3 by tdavies
struct order_st changed and renamed to c++ class named:Order
467
uint32_t optimizer::get_index_for_order(Table *table, Order *order, ha_rows limit)
1 by brian
clean slate
468
{
482 by Brian Aker
Remove uint.
469
  uint32_t idx;
470
  uint32_t match_key= MAX_KEY, match_key_len= MAX_KEY_LENGTH + 1;
1892.3.3 by tdavies
struct order_st changed and renamed to c++ class named:Order
471
  Order *ord;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
472
1 by brian
clean slate
473
  for (ord= order; ord; ord= ord->next)
474
    if (!ord->asc)
475
      return MAX_KEY;
476
1578.2.10 by Brian Aker
keys and fields partial encapsulation.
477
  for (idx= 0; idx < table->getShare()->sizeKeys(); idx++)
1 by brian
clean slate
478
  {
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
479
    if (!(table->keys_in_use_for_query.test(idx)))
1 by brian
clean slate
480
      continue;
1534 by Brian Aker
Remove of KeyPartInfo
481
    KeyPartInfo *keyinfo= table->key_info[idx].key_part;
482 by Brian Aker
Remove uint.
482
    uint32_t n_parts=  table->key_info[idx].key_parts;
483
    uint32_t partno= 0;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
484
485
    /*
486
      The below check is sufficient considering we now have either BTREE
487
      indexes (records are returned in order for any index prefix) or HASH
1 by brian
clean slate
488
      indexes (records are not returned in order for any index prefix).
489
    */
1235.1.14 by Brian Aker
Final move of index flags up to Engine (new interface still needed).
490
    if (! (table->index_flags(idx) & HA_READ_ORDER))
1 by brian
clean slate
491
      continue;
492
    for (ord= order; ord && partno < n_parts; ord= ord->next, partno++)
493
    {
494
      Item *item= order->item[0];
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
495
      if (! (item->type() == Item::FIELD_ITEM &&
1 by brian
clean slate
496
           ((Item_field*)item)->field->eq(keyinfo[partno].field)))
497
        break;
498
    }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
499
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
500
    if (! ord && table->key_info[idx].key_length < match_key_len)
1 by brian
clean slate
501
    {
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
502
      /*
1 by brian
clean slate
503
        Ok, the ordering is compatible and this key is shorter then
504
        previous match (we want shorter keys as we'll have to read fewer
505
        index pages for the same number of records)
506
      */
507
      match_key= idx;
508
      match_key_len= table->key_info[idx].key_length;
509
    }
510
  }
511
512
  if (match_key != MAX_KEY)
513
  {
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
514
    /*
515
      Found an index that allows records to be retrieved in the requested
1 by brian
clean slate
516
      order. Now we'll check if using the index is cheaper then doing a table
517
      scan.
518
    */
1208.3.2 by brian
Update for Cursor renaming.
519
    double full_scan_time= table->cursor->scan_time();
520
    double index_scan_time= table->cursor->read_time(match_key, 1, limit);
1 by brian
clean slate
521
    if (index_scan_time > full_scan_time)
522
      match_key= MAX_KEY;
523
  }
524
  return match_key;
525
}
526
527
528
529
/*
530
  Fill param->needed_fields with bitmap of fields used in the query.
531
  SYNOPSIS
532
    fill_used_fields_bitmap()
533
      param Parameter from test_quick_select function.
534
535
  NOTES
536
    Clustered PK members are not put into the bitmap as they are implicitly
537
    present in all keys (and it is impossible to avoid reading them).
538
  RETURN
539
    0  Ok
540
    1  Out of memory.
541
*/
542
1237.13.7 by Padraig O'Sullivan
Renamed PARAM to Parameter and RANGE_OPT_PARAM to RangeParameter.
543
static int fill_used_fields_bitmap(optimizer::Parameter *param)
1 by brian
clean slate
544
{
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
545
  Table *table= param->table;
482 by Brian Aker
Remove uint.
546
  uint32_t pk;
1802.16.4 by Padraig O'Sullivan
Removal of another MyBitmap in the range optimizer.
547
  param->tmp_covered_fields.clear();
548
  param->needed_fields.resize(table->getShare()->sizeFields());
549
  param->needed_fields.reset();
982.1.4 by Padraig O'Sullivan
More changes to some files to reflect the changes I've made by removing
550
1802.16.11 by Padraig O'Sullivan
Remove cpp and header file with MyBitmap class and associated functions. No longer needed.
551
  param->needed_fields|= *table->read_set;
552
  param->needed_fields|= *table->write_set;
1 by brian
clean slate
553
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
554
  pk= param->table->getShare()->getPrimaryKey();
1208.3.2 by brian
Update for Cursor renaming.
555
  if (pk != MAX_KEY && param->table->cursor->primary_key_is_clustered())
1 by brian
clean slate
556
  {
557
    /* The table uses clustered PK and it is not internally generated */
1534 by Brian Aker
Remove of KeyPartInfo
558
    KeyPartInfo *key_part= param->table->key_info[pk].key_part;
559
    KeyPartInfo *key_part_end= key_part +
1 by brian
clean slate
560
                                 param->table->key_info[pk].key_parts;
561
    for (;key_part != key_part_end; ++key_part)
1802.16.4 by Padraig O'Sullivan
Removal of another MyBitmap in the range optimizer.
562
      param->needed_fields.reset(key_part->fieldnr-1);
1 by brian
clean slate
563
  }
564
  return 0;
565
}
566
567
568
/*
569
  Test if a key can be used in different ranges
570
571
  SYNOPSIS
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
572
    SqlSelect::test_quick_select()
520.1.22 by Brian Aker
Second pass of thd cleanup
573
      session               Current thread
1 by brian
clean slate
574
      keys_to_use       Keys to use for range retrieval
575
      prev_tables       Tables assumed to be already read when the scan is
576
                        performed (but not read at the moment of this call)
577
      limit             Query limit
578
      force_quick_range Prefer to use range (instead of full table scan) even
579
                        if it is more expensive.
580
581
  NOTES
582
    Updates the following in the select parameter:
583
      needed_reg - Bits for keys with may be used if all prev regs are read
584
      quick      - Parameter to use when reading records.
585
586
    In the table struct the following information is updated:
587
      quick_keys           - Which keys can be used
588
      quick_rows           - How many rows the key matches
589
      quick_condition_rows - E(# rows that will satisfy the table condition)
590
591
  IMPLEMENTATION
592
    quick_condition_rows value is obtained as follows:
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
593
1 by brian
clean slate
594
      It is a minimum of E(#output rows) for all considered table access
595
      methods (range and index_merge accesses over various indexes).
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
596
1 by brian
clean slate
597
    The obtained value is not a true E(#rows that satisfy table condition)
598
    but rather a pessimistic estimate. To obtain a true E(#...) one would
599
    need to combine estimates of various access methods, taking into account
600
    correlations between sets of rows they will return.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
601
1 by brian
clean slate
602
    For example, if values of tbl.key1 and tbl.key2 are independent (a right
603
    assumption if we have no information about their correlation) then the
604
    correct estimate will be:
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
605
606
      E(#rows("tbl.key1 < c1 AND tbl.key2 < c2")) =
1 by brian
clean slate
607
      = E(#rows(tbl.key1 < c1)) / total_rows(tbl) * E(#rows(tbl.key2 < c2)
608
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
609
    which is smaller than
610
1 by brian
clean slate
611
       MIN(E(#rows(tbl.key1 < c1), E(#rows(tbl.key2 < c2)))
612
613
    which is currently produced.
614
615
  TODO
616
   * Change the value returned in quick_condition_rows from a pessimistic
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
617
     estimate to true E(#rows that satisfy table condition).
618
     (we can re-use some of E(#rows) calcuation code from index_merge/intersection
1 by brian
clean slate
619
      for this)
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
620
1 by brian
clean slate
621
   * Check if this function really needs to modify keys_to_use, and change the
622
     code to pass it by reference if it doesn't.
623
624
   * In addition to force_quick_range other means can be (an usually are) used
625
     to make this function prefer range over full table scan. Figure out if
626
     force_quick_range is really needed.
627
628
  RETURN
629
   -1 if impossible select (i.e. certainly no rows will be selected)
630
    0 if can't use quick_select
631
    1 if found usable ranges and quick select has been successfully created.
632
*/
633
1240.3.1 by Brian Aker
Merge Padraig.
634
int optimizer::SqlSelect::test_quick_select(Session *session,
1237.13.12 by Padraig O'Sullivan
Corrected the name of the QUICK_ROR_INTERSECT_CLASS class to adhere to the drizzle coding standards.
635
                                            key_map keys_to_use,
636
				                                    table_map prev_tables,
637
				                                    ha_rows limit,
638
                                            bool force_quick_range,
639
                                            bool ordered_output)
1 by brian
clean slate
640
{
482 by Brian Aker
Remove uint.
641
  uint32_t idx;
1 by brian
clean slate
642
  double scan_time;
1746.5.1 by Andrew Hutchings
Fix potential double free in range optimizer cleanup
643
  if (quick)
644
  {
645
    delete quick;
646
    quick= NULL;
647
  }
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
648
  needed_reg.reset();
649
  quick_keys.reset();
650
  if (keys_to_use.none())
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
651
    return 0;
1208.3.2 by brian
Update for Cursor renaming.
652
  records= head->cursor->stats.records;
1 by brian
clean slate
653
  if (!records)
971.6.11 by Eric Day
Removed purecov messages.
654
    records++;
1 by brian
clean slate
655
  scan_time= (double) records / TIME_FOR_COMPARE + 1;
1208.3.2 by brian
Update for Cursor renaming.
656
  read_time= (double) head->cursor->scan_time() + scan_time + 1.1;
1 by brian
clean slate
657
  if (head->force_index)
658
    scan_time= read_time= DBL_MAX;
659
  if (limit < records)
660
    read_time= (double) records + scan_time + 1; // Force to use index
661
  else if (read_time <= 2.0 && !force_quick_range)
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
662
    return 0;				/* No need for quick select */
1 by brian
clean slate
663
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
664
  keys_to_use&= head->keys_in_use_for_query;
665
  if (keys_to_use.any())
1 by brian
clean slate
666
  {
1253.1.3 by Monty Taylor
MEM_ROOT == memory::Root
667
    memory::Root alloc;
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
668
    optimizer::SEL_TREE *tree= NULL;
1 by brian
clean slate
669
    KEY_PART *key_parts;
1535 by Brian Aker
Rename of KEY to KeyInfo
670
    KeyInfo *key_info;
1237.13.7 by Padraig O'Sullivan
Renamed PARAM to Parameter and RANGE_OPT_PARAM to RangeParameter.
671
    optimizer::Parameter param;
1 by brian
clean slate
672
520.1.22 by Brian Aker
Second pass of thd cleanup
673
    if (check_stack_overrun(session, 2*STACK_MIN_SIZE, NULL))
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
674
      return 0;                           // Fatal error flag is set
1 by brian
clean slate
675
676
    /* set up parameter that is passed to all functions */
520.1.22 by Brian Aker
Second pass of thd cleanup
677
    param.session= session;
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
678
    param.prev_tables= prev_tables | const_tables;
679
    param.read_tables= read_tables;
1 by brian
clean slate
680
    param.current_table= head->map;
681
    param.table=head;
682
    param.keys=0;
683
    param.mem_root= &alloc;
520.1.22 by Brian Aker
Second pass of thd cleanup
684
    param.old_root= session->mem_root;
1 by brian
clean slate
685
    param.needed_reg= &needed_reg;
686
    param.imerge_cost_buff_size= 0;
55 by brian
Update for using real bool types.
687
    param.using_real_indexes= true;
688
    param.remove_jump_scans= true;
1 by brian
clean slate
689
    param.force_default_mrr= ordered_output;
690
520.1.22 by Brian Aker
Second pass of thd cleanup
691
    session->no_errors=1;				// Don't warn about NULL
1253.1.6 by Monty Taylor
Moved mem_root functions into drizzled::memory:: namespace.
692
    memory::init_sql_alloc(&alloc, session->variables.range_alloc_block_size, 0);
1532.1.15 by Brian Aker
Partial encapsulation of TableShare from Table.
693
    if (!(param.key_parts= (KEY_PART*) alloc.alloc_root( sizeof(KEY_PART) * head->getShare()->key_parts)) ||
1 by brian
clean slate
694
        fill_used_fields_bitmap(&param))
695
    {
520.1.22 by Brian Aker
Second pass of thd cleanup
696
      session->no_errors=0;
1487 by Brian Aker
More updates for memory::Root
697
      alloc.free_root(MYF(0));			// Return memory & allocator
698
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
699
      return 0;				// Can't use range
1 by brian
clean slate
700
    }
701
    key_parts= param.key_parts;
520.1.22 by Brian Aker
Second pass of thd cleanup
702
    session->mem_root= &alloc;
1 by brian
clean slate
703
704
    /*
705
      Make an array with description of all key parts of all table keys.
706
      This is used in get_mm_parts function.
707
    */
708
    key_info= head->key_info;
1578.2.10 by Brian Aker
keys and fields partial encapsulation.
709
    for (idx=0 ; idx < head->getShare()->sizeKeys() ; idx++, key_info++)
1 by brian
clean slate
710
    {
1534 by Brian Aker
Remove of KeyPartInfo
711
      KeyPartInfo *key_part_info;
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
712
      if (! keys_to_use.test(idx))
1 by brian
clean slate
713
	continue;
714
715
      param.key[param.keys]=key_parts;
716
      key_part_info= key_info->key_part;
1055.2.5 by Jay Pipes
Removal of dead Field::image_type and st_key_part::image_type member variables. Legacy from geometry MyISAM types...
717
      for (uint32_t part=0;
718
           part < key_info->key_parts;
719
           part++, key_parts++, key_part_info++)
1 by brian
clean slate
720
      {
1055.2.5 by Jay Pipes
Removal of dead Field::image_type and st_key_part::image_type member variables. Legacy from geometry MyISAM types...
721
        key_parts->key= param.keys;
722
        key_parts->part= part;
723
        key_parts->length= key_part_info->length;
724
        key_parts->store_length= key_part_info->store_length;
725
        key_parts->field= key_part_info->field;
726
        key_parts->null_bit= key_part_info->null_bit;
1 by brian
clean slate
727
        /* Only HA_PART_KEY_SEG is used */
1055.2.5 by Jay Pipes
Removal of dead Field::image_type and st_key_part::image_type member variables. Legacy from geometry MyISAM types...
728
        key_parts->flag= (uint8_t) key_part_info->key_part_flag;
1 by brian
clean slate
729
      }
730
      param.real_keynr[param.keys++]=idx;
731
    }
732
    param.key_parts_end=key_parts;
733
    param.alloced_sel_args= 0;
734
735
    /* Calculate cost of full index read for the shortest covering index */
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
736
    if (!head->covering_keys.none())
1 by brian
clean slate
737
    {
355 by Brian Aker
More Table cleanup
738
      int key_for_use= head->find_shortest_key(&head->covering_keys);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
739
      double key_read_time=
1208.3.2 by brian
Update for Cursor renaming.
740
        param.table->cursor->index_only_read_time(key_for_use,
1 by brian
clean slate
741
                                                rows2double(records)) +
742
        (double) records / TIME_FOR_COMPARE;
743
      if (key_read_time < read_time)
744
        read_time= key_read_time;
745
    }
746
1237.13.26 by Padraig O'Sullivan
Modified the case of TABLE_READ_PLAN to now be TableReadPlan.
747
    optimizer::TableReadPlan *best_trp= NULL;
1237.13.27 by Padraig O'Sullivan
Correcting the case of a number of classes in the optimizer to adhere to the coding standards. Also
748
    optimizer::GroupMinMaxReadPlan *group_trp= NULL;
1 by brian
clean slate
749
    double best_read_time= read_time;
750
751
    if (cond)
752
    {
753
      if ((tree= get_mm_tree(&param,cond)))
754
      {
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
755
        if (tree->type == optimizer::SEL_TREE::IMPOSSIBLE)
1 by brian
clean slate
756
        {
757
          records=0L;                      /* Return -1 from this function. */
758
          read_time= (double) HA_POS_ERROR;
759
          goto free_mem;
760
        }
761
        /*
762
          If the tree can't be used for range scans, proceed anyway, as we
763
          can construct a group-min-max quick select
764
        */
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
765
        if (tree->type != optimizer::SEL_TREE::KEY && tree->type != optimizer::SEL_TREE::KEY_SMALLER)
1 by brian
clean slate
766
          tree= NULL;
767
      }
768
    }
769
770
    /*
1237.13.21 by Padraig O'Sullivan
Corrected some style issues in the QuickGroupMinMaxSelect class.
771
      Try to construct a QuickGroupMinMaxSelect.
1 by brian
clean slate
772
      Notice that it can be constructed no matter if there is a range tree.
773
    */
774
    group_trp= get_best_group_min_max(&param, tree);
775
    if (group_trp)
776
    {
1067.4.4 by Nathan Williams
The rest of the files in the drizzled directory were purged of the cmin macro and replace with std::min (except for the definition in globals.h and 1 usage in stacktrace.cc).
777
      param.table->quick_condition_rows= min(group_trp->records,
1208.3.2 by brian
Update for Cursor renaming.
778
                                             head->cursor->stats.records);
1 by brian
clean slate
779
      if (group_trp->read_cost < best_read_time)
780
      {
781
        best_trp= group_trp;
782
        best_read_time= best_trp->read_cost;
783
      }
784
    }
785
786
    if (tree)
787
    {
788
      /*
789
        It is possible to use a range-based quick select (but it might be
790
        slower than 'all' table scan).
791
      */
1211 by Brian Aker
Reverses old patch which introduced memory leaks. Also found a solution
792
      if (tree->merges.is_empty())
1 by brian
clean slate
793
      {
1237.13.28 by Padraig O'Sullivan
Modified classes to have names in camel case instead of all upper case. Added default constructors
794
        optimizer::RangeReadPlan *range_trp= NULL;
1237.13.27 by Padraig O'Sullivan
Correcting the case of a number of classes in the optimizer to adhere to the coding standards. Also
795
        optimizer::RorIntersectReadPlan *rori_trp= NULL;
55 by brian
Update for using real bool types.
796
        bool can_build_covering= false;
1 by brian
clean slate
797
798
        /* Get best 'range' plan and prepare data for making other plans */
1578.4.11 by Brian Aker
PAss through the code removing current_session
799
        if ((range_trp= get_key_scans_params(session, &param, tree, false, true,
1 by brian
clean slate
800
                                             best_read_time)))
801
        {
802
          best_trp= range_trp;
803
          best_read_time= best_trp->read_cost;
804
        }
805
806
        /*
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
807
          Simultaneous key scans and row deletes on several Cursor
1 by brian
clean slate
808
          objects are not allowed so don't use ROR-intersection for
809
          table deletes.
810
        */
520.1.22 by Brian Aker
Second pass of thd cleanup
811
        if ((session->lex->sql_command != SQLCOM_DELETE))
1 by brian
clean slate
812
        {
813
          /*
814
            Get best non-covering ROR-intersection plan and prepare data for
815
            building covering ROR-intersection.
816
          */
817
          if ((rori_trp= get_best_ror_intersect(&param, tree, best_read_time,
818
                                                &can_build_covering)))
819
          {
820
            best_trp= rori_trp;
821
            best_read_time= best_trp->read_cost;
1511 by Brian Aker
This should be dead code, but I am going to see if that was the case.
822
            /*
823
              Try constructing covering ROR-intersect only if it looks possible
824
              and worth doing.
825
            */
1513 by Brian Aker
This patch reverts the ROR change which created a memory leak (bzr diff -r 1294..1293)
826
            if (!rori_trp->is_covering && can_build_covering &&
1511 by Brian Aker
This should be dead code, but I am going to see if that was the case.
827
                (rori_trp= get_best_covering_ror_intersect(&param, tree,
828
                                                           best_read_time)))
829
              best_trp= rori_trp;
1 by brian
clean slate
830
          }
831
        }
832
      }
833
      else
834
      {
835
        /* Try creating index_merge/ROR-union scan. */
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
836
        optimizer::SEL_IMERGE *imerge= NULL;
1237.13.26 by Padraig O'Sullivan
Modified the case of TABLE_READ_PLAN to now be TableReadPlan.
837
        optimizer::TableReadPlan *best_conj_trp= NULL;
838
        optimizer::TableReadPlan *new_conj_trp= NULL;
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
839
        List_iterator_fast<optimizer::SEL_IMERGE> it(tree->merges);
1211 by Brian Aker
Reverses old patch which introduced memory leaks. Also found a solution
840
        while ((imerge= it++))
1 by brian
clean slate
841
        {
1578.4.11 by Brian Aker
PAss through the code removing current_session
842
          new_conj_trp= get_best_disjunct_quick(session, &param, imerge, best_read_time);
1 by brian
clean slate
843
          if (new_conj_trp)
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
844
            set_if_smaller(param.table->quick_condition_rows,
1 by brian
clean slate
845
                           new_conj_trp->records);
846
          if (!best_conj_trp || (new_conj_trp && new_conj_trp->read_cost <
847
                                 best_conj_trp->read_cost))
848
            best_conj_trp= new_conj_trp;
849
        }
850
        if (best_conj_trp)
851
          best_trp= best_conj_trp;
852
      }
853
    }
854
520.1.22 by Brian Aker
Second pass of thd cleanup
855
    session->mem_root= param.old_root;
1 by brian
clean slate
856
857
    /* If we got a read plan, create a quick select from it. */
858
    if (best_trp)
859
    {
860
      records= best_trp->records;
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
861
      if (! (quick= best_trp->make_quick(&param, true)) || quick->init())
1 by brian
clean slate
862
      {
1746.5.1 by Andrew Hutchings
Fix potential double free in range optimizer cleanup
863
        /* quick can already be free here */
864
        if (quick)
865
        {
866
          delete quick;
867
          quick= NULL;
868
        }
1 by brian
clean slate
869
      }
870
    }
871
872
  free_mem:
1487 by Brian Aker
More updates for memory::Root
873
    alloc.free_root(MYF(0));			// Return memory & allocator
520.1.22 by Brian Aker
Second pass of thd cleanup
874
    session->mem_root= param.old_root;
875
    session->no_errors=0;
1 by brian
clean slate
876
  }
877
878
  /*
879
    Assume that if the user is using 'limit' we will only need to scan
880
    limit rows if we are using a key
881
  */
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
882
  return(records ? test(quick) : -1);
1 by brian
clean slate
883
}
884
885
/*
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
886
  Get best plan for a optimizer::SEL_IMERGE disjunctive expression.
1 by brian
clean slate
887
  SYNOPSIS
888
    get_best_disjunct_quick()
1578.4.11 by Brian Aker
PAss through the code removing current_session
889
      session
1 by brian
clean slate
890
      param     Parameter from check_quick_select function
891
      imerge    Expression to use
892
      read_time Don't create scans with cost > read_time
893
894
  NOTES
895
    index_merge cost is calculated as follows:
896
    index_merge_cost =
897
      cost(index_reads) +         (see #1)
898
      cost(rowid_to_row_scan) +   (see #2)
899
      cost(unique_use)            (see #3)
900
901
    1. cost(index_reads) =SUM_i(cost(index_read_i))
902
       For non-CPK scans,
903
         cost(index_read_i) = {cost of ordinary 'index only' scan}
904
       For CPK scan,
905
         cost(index_read_i) = {cost of non-'index only' scan}
906
907
    2. cost(rowid_to_row_scan)
908
      If table PK is clustered then
909
        cost(rowid_to_row_scan) =
910
          {cost of ordinary clustered PK scan with n_ranges=n_rows}
911
912
      Otherwise, we use the following model to calculate costs:
1208.3.2 by brian
Update for Cursor renaming.
913
      We need to retrieve n_rows rows from cursor that occupies n_blocks blocks.
1 by brian
clean slate
914
      We assume that offsets of rows we need are independent variates with
915
      uniform distribution in [0..max_file_offset] range.
916
917
      We'll denote block as "busy" if it contains row(s) we need to retrieve
918
      and "empty" if doesn't contain rows we need.
919
920
      Probability that a block is empty is (1 - 1/n_blocks)^n_rows (this
1208.3.2 by brian
Update for Cursor renaming.
921
      applies to any block in cursor). Let x_i be a variate taking value 1 if
1 by brian
clean slate
922
      block #i is empty and 0 otherwise.
923
924
      Then E(x_i) = (1 - 1/n_blocks)^n_rows;
925
926
      E(n_empty_blocks) = E(sum(x_i)) = sum(E(x_i)) =
927
        = n_blocks * ((1 - 1/n_blocks)^n_rows) =
928
       ~= n_blocks * exp(-n_rows/n_blocks).
929
930
      E(n_busy_blocks) = n_blocks*(1 - (1 - 1/n_blocks)^n_rows) =
931
       ~= n_blocks * (1 - exp(-n_rows/n_blocks)).
932
933
      Average size of "hole" between neighbor non-empty blocks is
934
           E(hole_size) = n_blocks/E(n_busy_blocks).
935
936
      The total cost of reading all needed blocks in one "sweep" is:
937
938
      E(n_busy_blocks)*
939
       (DISK_SEEK_BASE_COST + DISK_SEEK_PROP_COST*n_blocks/E(n_busy_blocks)).
940
941
    3. Cost of Unique use is calculated in Unique::get_use_cost function.
942
943
  ROR-union cost is calculated in the same way index_merge, but instead of
944
  Unique a priority queue is used.
945
946
  RETURN
947
    Created read plan
948
    NULL - Out of memory or no read scan could be built.
949
*/
950
951
static
1578.4.11 by Brian Aker
PAss through the code removing current_session
952
optimizer::TableReadPlan *get_best_disjunct_quick(Session *session,
953
                                                  optimizer::Parameter *param,
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
954
                                                  optimizer::SEL_IMERGE *imerge,
1237.13.26 by Padraig O'Sullivan
Modified the case of TABLE_READ_PLAN to now be TableReadPlan.
955
                                                  double read_time)
1 by brian
clean slate
956
{
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
957
  optimizer::SEL_TREE **ptree= NULL;
1237.13.27 by Padraig O'Sullivan
Correcting the case of a number of classes in the optimizer to adhere to the coding standards. Also
958
  optimizer::IndexMergeReadPlan *imerge_trp= NULL;
482 by Brian Aker
Remove uint.
959
  uint32_t n_child_scans= imerge->trees_next - imerge->trees;
1237.13.28 by Padraig O'Sullivan
Modified classes to have names in camel case instead of all upper case. Added default constructors
960
  optimizer::RangeReadPlan **range_scans= NULL;
961
  optimizer::RangeReadPlan **cur_child= NULL;
962
  optimizer::RangeReadPlan **cpk_scan= NULL;
55 by brian
Update for using real bool types.
963
  bool imerge_too_expensive= false;
1 by brian
clean slate
964
  double imerge_cost= 0.0;
965
  ha_rows cpk_scan_records= 0;
966
  ha_rows non_cpk_scan_records= 0;
1208.3.2 by brian
Update for Cursor renaming.
967
  bool pk_is_clustered= param->table->cursor->primary_key_is_clustered();
55 by brian
Update for using real bool types.
968
  bool all_scans_ror_able= true;
969
  bool all_scans_rors= true;
482 by Brian Aker
Remove uint.
970
  uint32_t unique_calc_buff_size;
1237.13.26 by Padraig O'Sullivan
Modified the case of TABLE_READ_PLAN to now be TableReadPlan.
971
  optimizer::TableReadPlan **roru_read_plans= NULL;
972
  optimizer::TableReadPlan **cur_roru_plan= NULL;
1 by brian
clean slate
973
  double roru_index_costs;
974
  ha_rows roru_total_records;
975
  double roru_intersect_part= 1.0;
976
1485 by Brian Aker
Updates to confine memroot
977
  if (! (range_scans= (optimizer::RangeReadPlan**)param->mem_root->alloc_root(sizeof(optimizer::RangeReadPlan*)* n_child_scans)))
978
  {
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
979
    return NULL;
1485 by Brian Aker
Updates to confine memroot
980
  }
981
1 by brian
clean slate
982
  /*
983
    Collect best 'range' scan for each of disjuncts, and, while doing so,
984
    analyze possibility of ROR scans. Also calculate some values needed by
985
    other parts of the code.
986
  */
987
  for (ptree= imerge->trees, cur_child= range_scans;
988
       ptree != imerge->trees_next;
989
       ptree++, cur_child++)
990
  {
1578.4.11 by Brian Aker
PAss through the code removing current_session
991
    if (!(*cur_child= get_key_scans_params(session, param, *ptree, true, false, read_time)))
1 by brian
clean slate
992
    {
993
      /*
994
        One of index scans in this index_merge is more expensive than entire
995
        table read for another available option. The entire index_merge (and
996
        any possible ROR-union) will be more expensive then, too. We continue
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
997
        here only to update SqlSelect members.
1 by brian
clean slate
998
      */
55 by brian
Update for using real bool types.
999
      imerge_too_expensive= true;
1 by brian
clean slate
1000
    }
1001
    if (imerge_too_expensive)
1002
      continue;
1003
1004
    imerge_cost += (*cur_child)->read_cost;
1005
    all_scans_ror_able &= ((*ptree)->n_ror_scans > 0);
1006
    all_scans_rors &= (*cur_child)->is_ror;
1007
    if (pk_is_clustered &&
1513 by Brian Aker
This patch reverts the ROR change which created a memory leak (bzr diff -r 1294..1293)
1008
        param->real_keynr[(*cur_child)->key_idx] ==
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
1009
        param->table->getShare()->getPrimaryKey())
1 by brian
clean slate
1010
    {
1011
      cpk_scan= cur_child;
1012
      cpk_scan_records= (*cur_child)->records;
1013
    }
1014
    else
1015
      non_cpk_scan_records += (*cur_child)->records;
1016
  }
1017
1018
  if (imerge_too_expensive || (imerge_cost > read_time) ||
1208.3.2 by brian
Update for Cursor renaming.
1019
      ((non_cpk_scan_records+cpk_scan_records >= param->table->cursor->stats.records) && read_time != DBL_MAX))
1 by brian
clean slate
1020
  {
1021
    /*
1022
      Bail out if it is obvious that both index_merge and ROR-union will be
1023
      more expensive
1024
    */
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
1025
    return NULL;
1 by brian
clean slate
1026
  }
1027
  if (all_scans_rors)
1028
  {
1237.13.26 by Padraig O'Sullivan
Modified the case of TABLE_READ_PLAN to now be TableReadPlan.
1029
    roru_read_plans= (optimizer::TableReadPlan **) range_scans;
1 by brian
clean slate
1030
    goto skip_to_ror_scan;
1031
  }
1032
  if (cpk_scan)
1033
  {
1034
    /*
1035
      Add one ROWID comparison for each row retrieved on non-CPK scan.  (it
1237.13.2 by Padraig O'Sullivan
Modified the names of 2 classes in the optimizer to adhere to the coding standards.
1036
      is done in QuickRangeSelect::row_in_ranges)
1 by brian
clean slate
1037
     */
1038
    imerge_cost += non_cpk_scan_records / TIME_FOR_COMPARE_ROWID;
1039
  }
1040
1041
  /* Calculate cost(rowid_to_row_scan) */
1042
  {
1336.3.2 by Djellel E. Difallah
rename class COST_VECT to CostVector and move it to ./drizzled/optimizer directory
1043
    optimizer::CostVector sweep_cost;
1541.1.1 by Brian Aker
JOIN -> Join rename
1044
    Join *join= param->session->lex->select_lex.join;
1 by brian
clean slate
1045
    bool is_interrupted= test(join && join->tables == 1);
1046
    get_sweep_read_cost(param->table, non_cpk_scan_records, is_interrupted,
1047
                        &sweep_cost);
1048
    imerge_cost += sweep_cost.total_cost();
1049
  }
1050
  if (imerge_cost > read_time)
1051
    goto build_ror_index_merge;
1052
1053
  /* Add Unique operations cost */
1054
  unique_calc_buff_size=
1055
    Unique::get_cost_calc_buff_size((ulong)non_cpk_scan_records,
1208.3.2 by brian
Update for Cursor renaming.
1056
                                    param->table->cursor->ref_length,
520.1.22 by Brian Aker
Second pass of thd cleanup
1057
                                    param->session->variables.sortbuff_size);
1 by brian
clean slate
1058
  if (param->imerge_cost_buff_size < unique_calc_buff_size)
1059
  {
1485 by Brian Aker
Updates to confine memroot
1060
    if (!(param->imerge_cost_buff= (uint*)param->mem_root->alloc_root(unique_calc_buff_size)))
1061
    {
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
1062
      return NULL;
1485 by Brian Aker
Updates to confine memroot
1063
    }
1064
1 by brian
clean slate
1065
    param->imerge_cost_buff_size= unique_calc_buff_size;
1066
  }
1067
1068
  imerge_cost +=
895 by Brian Aker
Completion (?) of uint conversion.
1069
    Unique::get_use_cost(param->imerge_cost_buff, (uint32_t)non_cpk_scan_records,
1208.3.2 by brian
Update for Cursor renaming.
1070
                         param->table->cursor->ref_length,
520.1.22 by Brian Aker
Second pass of thd cleanup
1071
                         param->session->variables.sortbuff_size);
1 by brian
clean slate
1072
  if (imerge_cost < read_time)
1073
  {
1237.13.27 by Padraig O'Sullivan
Correcting the case of a number of classes in the optimizer to adhere to the coding standards. Also
1074
    if ((imerge_trp= new (param->mem_root) optimizer::IndexMergeReadPlan))
1 by brian
clean slate
1075
    {
1076
      imerge_trp->read_cost= imerge_cost;
1077
      imerge_trp->records= non_cpk_scan_records + cpk_scan_records;
1067.4.4 by Nathan Williams
The rest of the files in the drizzled directory were purged of the cmin macro and replace with std::min (except for the definition in globals.h and 1 usage in stacktrace.cc).
1078
      imerge_trp->records= min(imerge_trp->records,
1208.3.2 by brian
Update for Cursor renaming.
1079
                               param->table->cursor->stats.records);
1 by brian
clean slate
1080
      imerge_trp->range_scans= range_scans;
1081
      imerge_trp->range_scans_end= range_scans + n_child_scans;
1082
      read_time= imerge_cost;
1083
    }
1084
  }
1085
1086
build_ror_index_merge:
520.1.22 by Brian Aker
Second pass of thd cleanup
1087
  if (!all_scans_ror_able || param->session->lex->sql_command == SQLCOM_DELETE)
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
1088
    return(imerge_trp);
1 by brian
clean slate
1089
1090
  /* Ok, it is possible to build a ROR-union, try it. */
1091
  bool dummy;
1237.13.26 by Padraig O'Sullivan
Modified the case of TABLE_READ_PLAN to now be TableReadPlan.
1092
  if (! (roru_read_plans=
1485 by Brian Aker
Updates to confine memroot
1093
          (optimizer::TableReadPlan **) param->mem_root->alloc_root(sizeof(optimizer::TableReadPlan*) * n_child_scans)))
1094
  {
1237.13.26 by Padraig O'Sullivan
Modified the case of TABLE_READ_PLAN to now be TableReadPlan.
1095
    return imerge_trp;
1485 by Brian Aker
Updates to confine memroot
1096
  }
1 by brian
clean slate
1097
skip_to_ror_scan:
1098
  roru_index_costs= 0.0;
1099
  roru_total_records= 0;
1100
  cur_roru_plan= roru_read_plans;
1101
1102
  /* Find 'best' ROR scan for each of trees in disjunction */
1103
  for (ptree= imerge->trees, cur_child= range_scans;
1104
       ptree != imerge->trees_next;
1105
       ptree++, cur_child++, cur_roru_plan++)
1106
  {
1107
    /*
1108
      Assume the best ROR scan is the one that has cheapest full-row-retrieval
1109
      scan cost.
1110
      Also accumulate index_only scan costs as we'll need them to calculate
1111
      overall index_intersection cost.
1112
    */
1113
    double cost;
1114
    if ((*cur_child)->is_ror)
1115
    {
1116
      /* Ok, we have index_only cost, now get full rows scan cost */
1208.3.2 by brian
Update for Cursor renaming.
1117
      cost= param->table->cursor->
1513 by Brian Aker
This patch reverts the ROR change which created a memory leak (bzr diff -r 1294..1293)
1118
              read_time(param->real_keynr[(*cur_child)->key_idx], 1,
1 by brian
clean slate
1119
                        (*cur_child)->records) +
1120
              rows2double((*cur_child)->records) / TIME_FOR_COMPARE;
1121
    }
1122
    else
1123
      cost= read_time;
1124
1237.13.26 by Padraig O'Sullivan
Modified the case of TABLE_READ_PLAN to now be TableReadPlan.
1125
    optimizer::TableReadPlan *prev_plan= *cur_child;
1 by brian
clean slate
1126
    if (!(*cur_roru_plan= get_best_ror_intersect(param, *ptree, cost,
1127
                                                 &dummy)))
1128
    {
1129
      if (prev_plan->is_ror)
1130
        *cur_roru_plan= prev_plan;
1131
      else
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
1132
        return(imerge_trp);
1 by brian
clean slate
1133
      roru_index_costs += (*cur_roru_plan)->read_cost;
1134
    }
1135
    else
1136
      roru_index_costs +=
1513 by Brian Aker
This patch reverts the ROR change which created a memory leak (bzr diff -r 1294..1293)
1137
        ((optimizer::RorIntersectReadPlan*)(*cur_roru_plan))->index_scan_costs;
1 by brian
clean slate
1138
    roru_total_records += (*cur_roru_plan)->records;
1139
    roru_intersect_part *= (*cur_roru_plan)->records /
1208.3.2 by brian
Update for Cursor renaming.
1140
                           param->table->cursor->stats.records;
1 by brian
clean slate
1141
  }
1142
1143
  /*
1144
    rows to retrieve=
1145
      SUM(rows_in_scan_i) - table_rows * PROD(rows_in_scan_i / table_rows).
1146
    This is valid because index_merge construction guarantees that conditions
1147
    in disjunction do not share key parts.
1148
  */
1149
  roru_total_records -= (ha_rows)(roru_intersect_part*
1208.3.2 by brian
Update for Cursor renaming.
1150
                                  param->table->cursor->stats.records);
1 by brian
clean slate
1151
  /* ok, got a ROR read plan for each of the disjuncts
1152
    Calculate cost:
1153
    cost(index_union_scan(scan_1, ... scan_n)) =
1154
      SUM_i(cost_of_index_only_scan(scan_i)) +
1155
      queue_use_cost(rowid_len, n) +
1156
      cost_of_row_retrieval
1157
    See get_merge_buffers_cost function for queue_use_cost formula derivation.
1158
  */
1159
  double roru_total_cost;
1160
  {
1336.3.2 by Djellel E. Difallah
rename class COST_VECT to CostVector and move it to ./drizzled/optimizer directory
1161
    optimizer::CostVector sweep_cost;
1541.1.1 by Brian Aker
JOIN -> Join rename
1162
    Join *join= param->session->lex->select_lex.join;
1 by brian
clean slate
1163
    bool is_interrupted= test(join && join->tables == 1);
1164
    get_sweep_read_cost(param->table, roru_total_records, is_interrupted,
1165
                        &sweep_cost);
1166
    roru_total_cost= roru_index_costs +
1167
                     rows2double(roru_total_records)*log((double)n_child_scans) /
1168
                     (TIME_FOR_COMPARE_ROWID * M_LN2) +
1169
                     sweep_cost.total_cost();
1170
  }
1171
1237.13.28 by Padraig O'Sullivan
Modified classes to have names in camel case instead of all upper case. Added default constructors
1172
  optimizer::RorUnionReadPlan *roru= NULL;
1 by brian
clean slate
1173
  if (roru_total_cost < read_time)
1174
  {
1237.13.28 by Padraig O'Sullivan
Modified classes to have names in camel case instead of all upper case. Added default constructors
1175
    if ((roru= new (param->mem_root) optimizer::RorUnionReadPlan))
1 by brian
clean slate
1176
    {
1513 by Brian Aker
This patch reverts the ROR change which created a memory leak (bzr diff -r 1294..1293)
1177
      roru->first_ror= roru_read_plans;
1178
      roru->last_ror= roru_read_plans + n_child_scans;
1 by brian
clean slate
1179
      roru->read_cost= roru_total_cost;
1180
      roru->records= roru_total_records;
1237.13.22 by Padraig O'Sullivan
Extracted a number of small classes into the table_read_plan.h header file.
1181
      return roru;
1 by brian
clean slate
1182
    }
1183
  }
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
1184
  return(imerge_trp);
1 by brian
clean slate
1185
}
1186
1187
1188
1189
/*
1802.16.16 by Padraig O'Sullivan
Convert struct to class and move it into optimizer namespace.
1190
  Create optimizer::RorScanInfo* structure with a single ROR scan on index idx using
1 by brian
clean slate
1191
  sel_arg set of intervals.
1192
1193
  SYNOPSIS
1194
    make_ror_scan()
1195
      param    Parameter from test_quick_select function
1196
      idx      Index of key in param->keys
1197
      sel_arg  Set of intervals for a given key
1198
1199
  RETURN
1200
    NULL - out of memory
1201
    ROR scan structure containing a scan for {idx, sel_arg}
1202
*/
1203
1204
static
1802.16.16 by Padraig O'Sullivan
Convert struct to class and move it into optimizer namespace.
1205
optimizer::RorScanInfo *make_ror_scan(const optimizer::Parameter *param, int idx, optimizer::SEL_ARG *sel_arg)
1 by brian
clean slate
1206
{
1802.16.16 by Padraig O'Sullivan
Convert struct to class and move it into optimizer namespace.
1207
  optimizer::RorScanInfo *ror_scan= NULL;
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
1208
482 by Brian Aker
Remove uint.
1209
  uint32_t keynr;
1 by brian
clean slate
1210
1802.16.16 by Padraig O'Sullivan
Convert struct to class and move it into optimizer namespace.
1211
  if (!(ror_scan= (optimizer::RorScanInfo*)param->mem_root->alloc_root(sizeof(optimizer::RorScanInfo))))
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
1212
    return NULL;
1 by brian
clean slate
1213
1214
  ror_scan->idx= idx;
1215
  ror_scan->keynr= keynr= param->real_keynr[idx];
1216
  ror_scan->key_rec_length= (param->table->key_info[keynr].key_length +
1208.3.2 by brian
Update for Cursor renaming.
1217
                             param->table->cursor->ref_length);
1 by brian
clean slate
1218
  ror_scan->sel_arg= sel_arg;
1219
  ror_scan->records= param->table->quick_rows[keynr];
1005.2.1 by Monty Taylor
Reverted a crap-ton of padraig's work.
1220
1802.16.17 by Padraig O'Sullivan
Hack to fix memory leak. This is horrible but lets us get rid of MyBitmap. This hack is needed for now to prevent a memory leak that occurs because mem_root does not always call desctructors of the objects it allocates memory for. The long term solution to this is to remove the use of mem_root from the optimizer. Once that is done, this hack can be taken back out again which I will very gladly do...
1221
  ror_scan->covered_fields_size= param->table->getShare()->sizeFields();
1222
  boost::dynamic_bitset<> tmp_bitset(param->table->getShare()->sizeFields());
1223
  tmp_bitset.reset();
1 by brian
clean slate
1224
1534 by Brian Aker
Remove of KeyPartInfo
1225
  KeyPartInfo *key_part= param->table->key_info[keynr].key_part;
1226
  KeyPartInfo *key_part_end= key_part +
1 by brian
clean slate
1227
                               param->table->key_info[keynr].key_parts;
1802.16.2 by Padraig O'Sullivan
Got rid of MyBitmap instance in the range optimizer.
1228
  for (; key_part != key_part_end; ++key_part)
1 by brian
clean slate
1229
  {
1802.16.4 by Padraig O'Sullivan
Removal of another MyBitmap in the range optimizer.
1230
    if (param->needed_fields.test(key_part->fieldnr-1))
1802.16.17 by Padraig O'Sullivan
Hack to fix memory leak. This is horrible but lets us get rid of MyBitmap. This hack is needed for now to prevent a memory leak that occurs because mem_root does not always call desctructors of the objects it allocates memory for. The long term solution to this is to remove the use of mem_root from the optimizer. Once that is done, this hack can be taken back out again which I will very gladly do...
1231
      tmp_bitset.set(key_part->fieldnr-1);
1 by brian
clean slate
1232
  }
1233
  double rows= rows2double(param->table->quick_rows[ror_scan->keynr]);
1234
  ror_scan->index_read_cost=
1208.3.2 by brian
Update for Cursor renaming.
1235
    param->table->cursor->index_only_read_time(ror_scan->keynr, rows);
1802.16.17 by Padraig O'Sullivan
Hack to fix memory leak. This is horrible but lets us get rid of MyBitmap. This hack is needed for now to prevent a memory leak that occurs because mem_root does not always call desctructors of the objects it allocates memory for. The long term solution to this is to remove the use of mem_root from the optimizer. Once that is done, this hack can be taken back out again which I will very gladly do...
1236
  ror_scan->covered_fields= tmp_bitset.to_ulong();
1802.16.2 by Padraig O'Sullivan
Got rid of MyBitmap instance in the range optimizer.
1237
  return ror_scan;
1 by brian
clean slate
1238
}
1239
1240
1241
/*
1802.16.16 by Padraig O'Sullivan
Convert struct to class and move it into optimizer namespace.
1242
  Compare two optimizer::RorScanInfo** by  E(#records_matched) * key_record_length.
1 by brian
clean slate
1243
  SYNOPSIS
1244
    cmp_ror_scan_info()
1245
      a ptr to first compared value
1246
      b ptr to second compared value
1247
1248
  RETURN
1249
   -1 a < b
1250
    0 a = b
1251
    1 a > b
1252
*/
1253
1802.16.16 by Padraig O'Sullivan
Convert struct to class and move it into optimizer namespace.
1254
static int cmp_ror_scan_info(optimizer::RorScanInfo** a, optimizer::RorScanInfo** b)
1 by brian
clean slate
1255
{
1256
  double val1= rows2double((*a)->records) * (*a)->key_rec_length;
1257
  double val2= rows2double((*b)->records) * (*b)->key_rec_length;
1258
  return (val1 < val2)? -1: (val1 == val2)? 0 : 1;
1259
}
1260
1261
1511 by Brian Aker
This should be dead code, but I am going to see if that was the case.
1262
/*
1802.16.16 by Padraig O'Sullivan
Convert struct to class and move it into optimizer namespace.
1263
  Compare two optimizer::RorScanInfo** by
1511 by Brian Aker
This should be dead code, but I am going to see if that was the case.
1264
   (#covered fields in F desc,
1265
    #components asc,
1266
    number of first not covered component asc)
1267
1268
  SYNOPSIS
1269
    cmp_ror_scan_info_covering()
1270
      a ptr to first compared value
1271
      b ptr to second compared value
1272
1273
  RETURN
1274
   -1 a < b
1275
    0 a = b
1276
    1 a > b
1277
*/
1278
1802.16.16 by Padraig O'Sullivan
Convert struct to class and move it into optimizer namespace.
1279
static int cmp_ror_scan_info_covering(optimizer::RorScanInfo** a, optimizer::RorScanInfo** b)
1511 by Brian Aker
This should be dead code, but I am going to see if that was the case.
1280
{
1281
  if ((*a)->used_fields_covered > (*b)->used_fields_covered)
1282
    return -1;
1283
  if ((*a)->used_fields_covered < (*b)->used_fields_covered)
1284
    return 1;
1285
  if ((*a)->key_components < (*b)->key_components)
1286
    return -1;
1287
  if ((*a)->key_components > (*b)->key_components)
1288
    return 1;
1289
  if ((*a)->first_uncovered_field < (*b)->first_uncovered_field)
1290
    return -1;
1291
  if ((*a)->first_uncovered_field > (*b)->first_uncovered_field)
1292
    return 1;
1293
  return 0;
1294
}
1295
1 by brian
clean slate
1296
/* Auxiliary structure for incremental ROR-intersection creation */
1802.16.14 by Padraig O'Sullivan
Resolved memory leaks by freeing memory in destructors of certain structs in the range optimizer.
1297
typedef struct st_ror_intersect_info
1 by brian
clean slate
1298
{
1802.16.14 by Padraig O'Sullivan
Resolved memory leaks by freeing memory in destructors of certain structs in the range optimizer.
1299
  st_ror_intersect_info()
1300
    :
1301
      param(NULL),
1802.16.15 by Padraig O'Sullivan
Fix a memory leak and remove code at the same time. Function for allocating memory for an object was unneeded since it was only ever called once.
1302
      covered_fields(),
1802.16.14 by Padraig O'Sullivan
Resolved memory leaks by freeing memory in destructors of certain structs in the range optimizer.
1303
      out_rows(0.0),
1304
      is_covering(false),
1305
      index_records(0),
1306
      index_scan_costs(0.0),
1307
      total_cost(0.0)
1308
  {}
1309
1802.16.15 by Padraig O'Sullivan
Fix a memory leak and remove code at the same time. Function for allocating memory for an object was unneeded since it was only ever called once.
1310
  st_ror_intersect_info(const optimizer::Parameter *in_param)
1311
    :
1312
      param(in_param),
1313
      covered_fields(in_param->table->getShare()->sizeFields()),
1314
      out_rows(in_param->table->cursor->stats.records),
1315
      is_covering(false),
1316
      index_records(0),
1317
      index_scan_costs(0.0),
1318
      total_cost(0.0)
1802.16.14 by Padraig O'Sullivan
Resolved memory leaks by freeing memory in destructors of certain structs in the range optimizer.
1319
  {
1802.16.15 by Padraig O'Sullivan
Fix a memory leak and remove code at the same time. Function for allocating memory for an object was unneeded since it was only ever called once.
1320
    covered_fields.reset();
1802.16.14 by Padraig O'Sullivan
Resolved memory leaks by freeing memory in destructors of certain structs in the range optimizer.
1321
  }
1322
1237.13.7 by Padraig O'Sullivan
Renamed PARAM to Parameter and RANGE_OPT_PARAM to RangeParameter.
1323
  const optimizer::Parameter *param;
1802.16.15 by Padraig O'Sullivan
Fix a memory leak and remove code at the same time. Function for allocating memory for an object was unneeded since it was only ever called once.
1324
  boost::dynamic_bitset<> covered_fields; /* union of fields covered by all scans */
1 by brian
clean slate
1325
  /*
1326
    Fraction of table records that satisfies conditions of all scans.
1327
    This is the number of full records that will be retrieved if a
1328
    non-index_only index intersection will be employed.
1329
  */
1330
  double out_rows;
55 by brian
Update for using real bool types.
1331
  /* true if covered_fields is a superset of needed_fields */
1 by brian
clean slate
1332
  bool is_covering;
1333
1334
  ha_rows index_records; /* sum(#records to look in indexes) */
1335
  double index_scan_costs; /* SUM(cost of 'index-only' scans) */
1336
  double total_cost;
1337
} ROR_INTERSECT_INFO;
1338
1339
1085.1.2 by Monty Taylor
Fixed -Wmissing-declarations
1340
static void ror_intersect_cpy(ROR_INTERSECT_INFO *dst,
1341
                              const ROR_INTERSECT_INFO *src)
1 by brian
clean slate
1342
{
1343
  dst->param= src->param;
1103.6.2 by Padraig O'Sullivan
Removing references to MY_BITMAP throughout the code base and updating calls
1344
  dst->covered_fields= src->covered_fields;
1 by brian
clean slate
1345
  dst->out_rows= src->out_rows;
1346
  dst->is_covering= src->is_covering;
1347
  dst->index_records= src->index_records;
1348
  dst->index_scan_costs= src->index_scan_costs;
1349
  dst->total_cost= src->total_cost;
1350
}
1351
1352
1353
/*
1354
  Get selectivity of a ROR scan wrt ROR-intersection.
1355
1356
  SYNOPSIS
1357
    ror_scan_selectivity()
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1358
      info  ROR-interection
1 by brian
clean slate
1359
      scan  ROR scan
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1360
1 by brian
clean slate
1361
  NOTES
1362
    Suppose we have a condition on several keys
1363
    cond=k_11=c_11 AND k_12=c_12 AND ...  // parts of first key
1364
         k_21=c_21 AND k_22=c_22 AND ...  // parts of second key
1365
          ...
1366
         k_n1=c_n1 AND k_n3=c_n3 AND ...  (1) //parts of the key used by *scan
1367
1368
    where k_ij may be the same as any k_pq (i.e. keys may have common parts).
1369
1370
    A full row is retrieved if entire condition holds.
1371
1372
    The recursive procedure for finding P(cond) is as follows:
1373
1374
    First step:
1375
    Pick 1st part of 1st key and break conjunction (1) into two parts:
1376
      cond= (k_11=c_11 AND R)
1377
1378
    Here R may still contain condition(s) equivalent to k_11=c_11.
1379
    Nevertheless, the following holds:
1380
1381
      P(k_11=c_11 AND R) = P(k_11=c_11) * P(R | k_11=c_11).
1382
1383
    Mark k_11 as fixed field (and satisfied condition) F, save P(F),
1384
    save R to be cond and proceed to recursion step.
1385
1386
    Recursion step:
1387
    We have a set of fixed fields/satisfied conditions) F, probability P(F),
1388
    and remaining conjunction R
1389
    Pick next key part on current key and its condition "k_ij=c_ij".
1390
    We will add "k_ij=c_ij" into F and update P(F).
1391
    Lets denote k_ij as t,  R = t AND R1, where R1 may still contain t. Then
1392
1393
     P((t AND R1)|F) = P(t|F) * P(R1|t|F) = P(t|F) * P(R1|(t AND F)) (2)
1394
1395
    (where '|' mean conditional probability, not "or")
1396
1397
    Consider the first multiplier in (2). One of the following holds:
1398
    a) F contains condition on field used in t (i.e. t AND F = F).
1399
      Then P(t|F) = 1
1400
1401
    b) F doesn't contain condition on field used in t. Then F and t are
1402
     considered independent.
1403
1404
     P(t|F) = P(t|(fields_before_t_in_key AND other_fields)) =
1405
          = P(t|fields_before_t_in_key).
1406
1407
     P(t|fields_before_t_in_key) = #records(fields_before_t_in_key) /
1408
                                   #records(fields_before_t_in_key, t)
1409
1410
    The second multiplier is calculated by applying this step recursively.
1411
1412
  IMPLEMENTATION
1413
    This function calculates the result of application of the "recursion step"
1414
    described above for all fixed key members of a single key, accumulating set
1415
    of covered fields, selectivity, etc.
1416
1417
    The calculation is conducted as follows:
1418
    Lets denote #records(keypart1, ... keypartK) as n_k. We need to calculate
1419
1420
     n_{k1}      n_{k2}
1421
    --------- * ---------  * .... (3)
1422
     n_{k1-1}    n_{k2-1}
1423
1424
    where k1,k2,... are key parts which fields were not yet marked as fixed
1425
    ( this is result of application of option b) of the recursion step for
1426
      parts of a single key).
1427
    Since it is reasonable to expect that most of the fields are not marked
1428
    as fixed, we calculate (3) as
1429
1430
                                  n_{i1}      n_{i2}
1431
    (3) = n_{max_key_part}  / (   --------- * ---------  * ....  )
1432
                                  n_{i1-1}    n_{i2-1}
1433
1434
    where i1,i2, .. are key parts that were already marked as fixed.
1435
1436
    In order to minimize number of expensive records_in_range calls we group
1437
    and reduce adjacent fractions.
1438
1439
  RETURN
1440
    Selectivity of given ROR scan.
1441
*/
1442
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1443
static double ror_scan_selectivity(const ROR_INTERSECT_INFO *info,
1802.16.16 by Padraig O'Sullivan
Convert struct to class and move it into optimizer namespace.
1444
                                   const optimizer::RorScanInfo *scan)
1 by brian
clean slate
1445
{
1446
  double selectivity_mult= 1.0;
1534 by Brian Aker
Remove of KeyPartInfo
1447
  KeyPartInfo *key_part= info->param->table->key_info[scan->keynr].key_part;
481 by Brian Aker
Remove all of uchar.
1448
  unsigned char key_val[MAX_KEY_LENGTH+MAX_FIELD_WIDTH]; /* key values tuple */
1449
  unsigned char *key_ptr= key_val;
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
1450
  optimizer::SEL_ARG *sel_arg= NULL;
1451
  optimizer::SEL_ARG *tuple_arg= NULL;
1 by brian
clean slate
1452
  key_part_map keypart_map= 0;
1453
  bool cur_covered;
1802.16.15 by Padraig O'Sullivan
Fix a memory leak and remove code at the same time. Function for allocating memory for an object was unneeded since it was only ever called once.
1454
  bool prev_covered= test(info->covered_fields.test(key_part->fieldnr-1));
1 by brian
clean slate
1455
  key_range min_range;
1456
  key_range max_range;
1457
  min_range.key= key_val;
1458
  min_range.flag= HA_READ_KEY_EXACT;
1459
  max_range.key= key_val;
1460
  max_range.flag= HA_READ_AFTER_KEY;
1208.3.2 by brian
Update for Cursor renaming.
1461
  ha_rows prev_records= info->param->table->cursor->stats.records;
1 by brian
clean slate
1462
1463
  for (sel_arg= scan->sel_arg; sel_arg;
1464
       sel_arg= sel_arg->next_key_part)
1465
  {
1240.3.1 by Brian Aker
Merge Padraig.
1466
    cur_covered=
1802.16.15 by Padraig O'Sullivan
Fix a memory leak and remove code at the same time. Function for allocating memory for an object was unneeded since it was only ever called once.
1467
      test(info->covered_fields.test(key_part[sel_arg->part].fieldnr-1));
1 by brian
clean slate
1468
    if (cur_covered != prev_covered)
1469
    {
1470
      /* create (part1val, ..., part{n-1}val) tuple. */
1471
      ha_rows records;
1472
      if (!tuple_arg)
1473
      {
1474
        tuple_arg= scan->sel_arg;
1475
        /* Here we use the length of the first key part */
1476
        tuple_arg->store_min(key_part->store_length, &key_ptr, 0);
1477
        keypart_map= 1;
1478
      }
1479
      while (tuple_arg->next_key_part != sel_arg)
1480
      {
1481
        tuple_arg= tuple_arg->next_key_part;
1482
        tuple_arg->store_min(key_part[tuple_arg->part].store_length,
1483
                             &key_ptr, 0);
1484
        keypart_map= (keypart_map << 1) | 1;
1485
      }
1486
      min_range.length= max_range.length= (size_t) (key_ptr - key_val);
1487
      min_range.keypart_map= max_range.keypart_map= keypart_map;
1208.3.2 by brian
Update for Cursor renaming.
1488
      records= (info->param->table->cursor->
1 by brian
clean slate
1489
                records_in_range(scan->keynr, &min_range, &max_range));
1490
      if (cur_covered)
1491
      {
1492
        /* uncovered -> covered */
1493
        double tmp= rows2double(records)/rows2double(prev_records);
1494
        selectivity_mult *= tmp;
1495
        prev_records= HA_POS_ERROR;
1496
      }
1497
      else
1498
      {
1499
        /* covered -> uncovered */
1500
        prev_records= records;
1501
      }
1502
    }
1503
    prev_covered= cur_covered;
1504
  }
1505
  if (!prev_covered)
1506
  {
1507
    double tmp= rows2double(info->param->table->quick_rows[scan->keynr]) /
1508
                rows2double(prev_records);
1509
    selectivity_mult *= tmp;
1510
  }
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
1511
  return(selectivity_mult);
1 by brian
clean slate
1512
}
1513
1514
1515
/*
1516
  Check if adding a ROR scan to a ROR-intersection reduces its cost of
1517
  ROR-intersection and if yes, update parameters of ROR-intersection,
1518
  including its cost.
1519
1520
  SYNOPSIS
1521
    ror_intersect_add()
1522
      param        Parameter from test_quick_select
1523
      info         ROR-intersection structure to add the scan to.
1524
      ror_scan     ROR scan info to add.
55 by brian
Update for using real bool types.
1525
      is_cpk_scan  If true, add the scan as CPK scan (this can be inferred
1 by brian
clean slate
1526
                   from other parameters and is passed separately only to
1527
                   avoid duplicating the inference code)
1528
1529
  NOTES
1530
    Adding a ROR scan to ROR-intersect "makes sense" iff the cost of ROR-
1531
    intersection decreases. The cost of ROR-intersection is calculated as
1532
    follows:
1533
1534
    cost= SUM_i(key_scan_cost_i) + cost_of_full_rows_retrieval
1535
1536
    When we add a scan the first increases and the second decreases.
1537
1538
    cost_of_full_rows_retrieval=
1539
      (union of indexes used covers all needed fields) ?
1540
        cost_of_sweep_read(E(rows_to_retrieve), rows_in_table) :
1541
        0
1542
1543
    E(rows_to_retrieve) = #rows_in_table * ror_scan_selectivity(null, scan1) *
1544
                           ror_scan_selectivity({scan1}, scan2) * ... *
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1545
                           ror_scan_selectivity({scan1,...}, scanN).
1 by brian
clean slate
1546
  RETURN
55 by brian
Update for using real bool types.
1547
    true   ROR scan added to ROR-intersection, cost updated.
1548
    false  It doesn't make sense to add this ROR scan to this ROR-intersection.
1 by brian
clean slate
1549
*/
1550
1551
static bool ror_intersect_add(ROR_INTERSECT_INFO *info,
1802.16.16 by Padraig O'Sullivan
Convert struct to class and move it into optimizer namespace.
1552
                              optimizer::RorScanInfo* ror_scan, bool is_cpk_scan)
1 by brian
clean slate
1553
{
1554
  double selectivity_mult= 1.0;
1555
1556
  selectivity_mult = ror_scan_selectivity(info, ror_scan);
1557
  if (selectivity_mult == 1.0)
1558
  {
1559
    /* Don't add this scan if it doesn't improve selectivity. */
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
1560
    return false;
1 by brian
clean slate
1561
  }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1562
1 by brian
clean slate
1563
  info->out_rows *= selectivity_mult;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1564
1 by brian
clean slate
1565
  if (is_cpk_scan)
1566
  {
1567
    /*
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1568
      CPK scan is used to filter out rows. We apply filtering for
1 by brian
clean slate
1569
      each record of every scan. Assuming 1/TIME_FOR_COMPARE_ROWID
1570
      per check this gives us:
1571
    */
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1572
    info->index_scan_costs += rows2double(info->index_records) /
1 by brian
clean slate
1573
                              TIME_FOR_COMPARE_ROWID;
1574
  }
1575
  else
1576
  {
1577
    info->index_records += info->param->table->quick_rows[ror_scan->keynr];
1578
    info->index_scan_costs += ror_scan->index_read_cost;
1802.16.19 by Padraig O'Sullivan
Fix for test case failure.
1579
    boost::dynamic_bitset<> tmp_bitset= ror_scan->bitsToBitset();
1802.16.17 by Padraig O'Sullivan
Hack to fix memory leak. This is horrible but lets us get rid of MyBitmap. This hack is needed for now to prevent a memory leak that occurs because mem_root does not always call desctructors of the objects it allocates memory for. The long term solution to this is to remove the use of mem_root from the optimizer. Once that is done, this hack can be taken back out again which I will very gladly do...
1580
    info->covered_fields|= tmp_bitset;
1802.16.15 by Padraig O'Sullivan
Fix a memory leak and remove code at the same time. Function for allocating memory for an object was unneeded since it was only ever called once.
1581
    if (! info->is_covering && info->param->needed_fields.is_subset_of(info->covered_fields))
1 by brian
clean slate
1582
    {
55 by brian
Update for using real bool types.
1583
      info->is_covering= true;
1 by brian
clean slate
1584
    }
1585
  }
1586
1587
  info->total_cost= info->index_scan_costs;
1802.16.4 by Padraig O'Sullivan
Removal of another MyBitmap in the range optimizer.
1588
  if (! info->is_covering)
1 by brian
clean slate
1589
  {
1336.3.2 by Djellel E. Difallah
rename class COST_VECT to CostVector and move it to ./drizzled/optimizer directory
1590
    optimizer::CostVector sweep_cost;
1541.1.1 by Brian Aker
JOIN -> Join rename
1591
    Join *join= info->param->session->lex->select_lex.join;
1 by brian
clean slate
1592
    bool is_interrupted= test(join && join->tables == 1);
1593
    get_sweep_read_cost(info->param->table, double2rows(info->out_rows),
1594
                        is_interrupted, &sweep_cost);
1595
    info->total_cost += sweep_cost.total_cost();
1596
  }
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
1597
  return true;
1 by brian
clean slate
1598
}
1599
1600
1601
/*
1511 by Brian Aker
This should be dead code, but I am going to see if that was the case.
1602
  Get best covering ROR-intersection.
1603
  SYNOPSIS
1604
    get_best_covering_ror_intersect()
1605
      param     Parameter from test_quick_select function.
1606
      tree      optimizer::SEL_TREE with sets of intervals for different keys.
1607
      read_time Don't return table read plans with cost > read_time.
1608
1609
  RETURN
1610
    Best covering ROR-intersection plan
1611
    NULL if no plan found.
1612
1613
  NOTES
1614
    get_best_ror_intersect must be called for a tree before calling this
1615
    function for it.
1616
    This function invalidates tree->ror_scans member values.
1617
1618
  The following approximate algorithm is used:
1619
    I=set of all covering indexes
1620
    F=set of all fields to cover
1621
    S={}
1622
1623
    do
1624
    {
1625
      Order I by (#covered fields in F desc,
1626
                  #components asc,
1627
                  number of first not covered component asc);
1628
      F=F-covered by first(I);
1629
      S=S+first(I);
1630
      I=I-first(I);
1631
    } while F is not empty.
1632
*/
1633
1634
static
1635
optimizer::RorIntersectReadPlan *get_best_covering_ror_intersect(optimizer::Parameter *param,
1636
                                                            optimizer::SEL_TREE *tree,
1637
                                                            double read_time)
1638
{
1802.16.16 by Padraig O'Sullivan
Convert struct to class and move it into optimizer namespace.
1639
  optimizer::RorScanInfo **ror_scan_mark;
1640
  optimizer::RorScanInfo **ror_scans_end= tree->ror_scans_end;
1511 by Brian Aker
This should be dead code, but I am going to see if that was the case.
1641
1802.16.16 by Padraig O'Sullivan
Convert struct to class and move it into optimizer namespace.
1642
  for (optimizer::RorScanInfo **scan= tree->ror_scans; scan != ror_scans_end; ++scan)
1511 by Brian Aker
This should be dead code, but I am going to see if that was the case.
1643
    (*scan)->key_components=
1644
      param->table->key_info[(*scan)->keynr].key_parts;
1645
1646
  /*
1647
    Run covering-ROR-search algorithm.
1648
    Assume set I is [ror_scan .. ror_scans_end)
1649
  */
1650
1651
  /*I=set of all covering indexes */
1652
  ror_scan_mark= tree->ror_scans;
1653
1802.16.4 by Padraig O'Sullivan
Removal of another MyBitmap in the range optimizer.
1654
  boost::dynamic_bitset<> *covered_fields= &param->tmp_covered_fields;
1655
  if (covered_fields->empty())
1511 by Brian Aker
This should be dead code, but I am going to see if that was the case.
1656
  {
1802.16.4 by Padraig O'Sullivan
Removal of another MyBitmap in the range optimizer.
1657
    covered_fields->resize(param->table->getShare()->sizeFields());
1511 by Brian Aker
This should be dead code, but I am going to see if that was the case.
1658
  }
1802.16.4 by Padraig O'Sullivan
Removal of another MyBitmap in the range optimizer.
1659
  covered_fields->reset();
1511 by Brian Aker
This should be dead code, but I am going to see if that was the case.
1660
1661
  double total_cost= 0.0f;
1662
  ha_rows records=0;
1663
  bool all_covered;
1664
1665
  do
1666
  {
1667
    /*
1668
      Update changed sorting info:
1669
        #covered fields,
1670
	number of first not covered component
1671
      Calculate and save these values for each of remaining scans.
1672
    */
1802.16.16 by Padraig O'Sullivan
Convert struct to class and move it into optimizer namespace.
1673
    for (optimizer::RorScanInfo **scan= ror_scan_mark; scan != ror_scans_end; ++scan)
1511 by Brian Aker
This should be dead code, but I am going to see if that was the case.
1674
    {
1802.16.4 by Padraig O'Sullivan
Removal of another MyBitmap in the range optimizer.
1675
      /* subtract one bitset from the other */
1802.16.17 by Padraig O'Sullivan
Hack to fix memory leak. This is horrible but lets us get rid of MyBitmap. This hack is needed for now to prevent a memory leak that occurs because mem_root does not always call desctructors of the objects it allocates memory for. The long term solution to this is to remove the use of mem_root from the optimizer. Once that is done, this hack can be taken back out again which I will very gladly do...
1676
      (*scan)->subtractBitset(*covered_fields);
1511 by Brian Aker
This should be dead code, but I am going to see if that was the case.
1677
      (*scan)->used_fields_covered=
1802.16.17 by Padraig O'Sullivan
Hack to fix memory leak. This is horrible but lets us get rid of MyBitmap. This hack is needed for now to prevent a memory leak that occurs because mem_root does not always call desctructors of the objects it allocates memory for. The long term solution to this is to remove the use of mem_root from the optimizer. Once that is done, this hack can be taken back out again which I will very gladly do...
1678
        (*scan)->getBitCount();
1679
      (*scan)->first_uncovered_field= (*scan)->findFirstNotSet();
1511 by Brian Aker
This should be dead code, but I am going to see if that was the case.
1680
    }
1681
1682
    internal::my_qsort(ror_scan_mark, ror_scans_end-ror_scan_mark,
1802.16.16 by Padraig O'Sullivan
Convert struct to class and move it into optimizer namespace.
1683
                       sizeof(optimizer::RorScanInfo*),
1511 by Brian Aker
This should be dead code, but I am going to see if that was the case.
1684
                       (qsort_cmp)cmp_ror_scan_info_covering);
1685
1686
    /* I=I-first(I) */
1687
    total_cost += (*ror_scan_mark)->index_read_cost;
1688
    records += (*ror_scan_mark)->records;
1689
    if (total_cost > read_time)
1690
      return NULL;
1691
    /* F=F-covered by first(I) */
1802.16.17 by Padraig O'Sullivan
Hack to fix memory leak. This is horrible but lets us get rid of MyBitmap. This hack is needed for now to prevent a memory leak that occurs because mem_root does not always call desctructors of the objects it allocates memory for. The long term solution to this is to remove the use of mem_root from the optimizer. Once that is done, this hack can be taken back out again which I will very gladly do...
1692
    boost::dynamic_bitset<> tmp_bitset= (*ror_scan_mark)->bitsToBitset();
1693
    *covered_fields|= tmp_bitset;
1802.16.4 by Padraig O'Sullivan
Removal of another MyBitmap in the range optimizer.
1694
    all_covered= param->needed_fields.is_subset_of(*covered_fields);
1695
  } while ((++ror_scan_mark < ror_scans_end) && ! all_covered);
1511 by Brian Aker
This should be dead code, but I am going to see if that was the case.
1696
1697
  if (!all_covered || (ror_scan_mark - tree->ror_scans) == 1)
1698
    return NULL;
1699
1700
  /*
1701
    Ok, [tree->ror_scans .. ror_scan) holds covering index_intersection with
1702
    cost total_cost.
1703
  */
1704
  /* Add priority queue use cost. */
1705
  total_cost += rows2double(records)*
1706
                log((double)(ror_scan_mark - tree->ror_scans)) /
1707
                (TIME_FOR_COMPARE_ROWID * M_LN2);
1708
1709
  if (total_cost > read_time)
1710
    return NULL;
1711
1712
  optimizer::RorIntersectReadPlan *trp= NULL;
1713
  if (! (trp= new (param->mem_root) optimizer::RorIntersectReadPlan))
1714
  {
1715
    return trp;
1716
  }
1717
1718
  uint32_t best_num= (ror_scan_mark - tree->ror_scans);
1802.16.16 by Padraig O'Sullivan
Convert struct to class and move it into optimizer namespace.
1719
  if (!(trp->first_scan= (optimizer::RorScanInfo**)param->mem_root->alloc_root(sizeof(optimizer::RorScanInfo*)* best_num)))
1513 by Brian Aker
This patch reverts the ROR change which created a memory leak (bzr diff -r 1294..1293)
1720
    return NULL;
1802.16.16 by Padraig O'Sullivan
Convert struct to class and move it into optimizer namespace.
1721
  memcpy(trp->first_scan, tree->ror_scans, best_num*sizeof(optimizer::RorScanInfo*));
1513 by Brian Aker
This patch reverts the ROR change which created a memory leak (bzr diff -r 1294..1293)
1722
  trp->last_scan=  trp->first_scan + best_num;
1723
  trp->is_covering= true;
1511 by Brian Aker
This should be dead code, but I am going to see if that was the case.
1724
  trp->read_cost= total_cost;
1725
  trp->records= records;
1726
  trp->cpk_scan= NULL;
1727
  set_if_smaller(param->table->quick_condition_rows, records);
1728
1729
  return(trp);
1730
}
1731
1732
1733
/*
1 by brian
clean slate
1734
  Get best ROR-intersection plan using non-covering ROR-intersection search
1735
  algorithm. The returned plan may be covering.
1736
1737
  SYNOPSIS
1738
    get_best_ror_intersect()
1739
      param            Parameter from test_quick_select function.
1740
      tree             Transformed restriction condition to be used to look
1741
                       for ROR scans.
1742
      read_time        Do not return read plans with cost > read_time.
55 by brian
Update for using real bool types.
1743
      are_all_covering [out] set to true if union of all scans covers all
1 by brian
clean slate
1744
                       fields needed by the query (and it is possible to build
1745
                       a covering ROR-intersection)
1746
1747
  NOTES
1748
    get_key_scans_params must be called before this function can be called.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1749
1 by brian
clean slate
1750
    When this function is called by ROR-union construction algorithm it
1751
    assumes it is building an uncovered ROR-intersection (and thus # of full
1752
    records to be retrieved is wrong here). This is a hack.
1753
1754
  IMPLEMENTATION
1755
    The approximate best non-covering plan search algorithm is as follows:
1756
1757
    find_min_ror_intersection_scan()
1758
    {
1759
      R= select all ROR scans;
1760
      order R by (E(#records_matched) * key_record_length).
1761
1762
      S= first(R); -- set of scans that will be used for ROR-intersection
1763
      R= R-first(S);
1764
      min_cost= cost(S);
1765
      min_scan= make_scan(S);
1766
      while (R is not empty)
1767
      {
1768
        firstR= R - first(R);
1769
        if (!selectivity(S + firstR < selectivity(S)))
1770
          continue;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1771
1 by brian
clean slate
1772
        S= S + first(R);
1773
        if (cost(S) < min_cost)
1774
        {
1775
          min_cost= cost(S);
1776
          min_scan= make_scan(S);
1777
        }
1778
      }
1779
      return min_scan;
1780
    }
1781
1782
    See ror_intersect_add function for ROR intersection costs.
1783
1784
    Special handling for Clustered PK scans
1785
    Clustered PK contains all table fields, so using it as a regular scan in
1786
    index intersection doesn't make sense: a range scan on CPK will be less
1787
    expensive in this case.
1788
    Clustered PK scan has special handling in ROR-intersection: it is not used
1789
    to retrieve rows, instead its condition is used to filter row references
1790
    we get from scans on other keys.
1791
1792
  RETURN
1793
    ROR-intersection table read plan
1794
    NULL if out of memory or no suitable plan found.
1795
*/
1796
1797
static
1237.13.27 by Padraig O'Sullivan
Correcting the case of a number of classes in the optimizer to adhere to the coding standards. Also
1798
optimizer::RorIntersectReadPlan *get_best_ror_intersect(const optimizer::Parameter *param,
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
1799
                                                   optimizer::SEL_TREE *tree,
1237.13.27 by Padraig O'Sullivan
Correcting the case of a number of classes in the optimizer to adhere to the coding standards. Also
1800
                                                   double read_time,
1801
                                                   bool *are_all_covering)
1 by brian
clean slate
1802
{
1237.13.46 by Padraig O'Sullivan
Clear up a vector in a class desctructor to attempt to remove a memory leak.
1803
  uint32_t idx= 0;
1 by brian
clean slate
1804
  double min_cost= DBL_MAX;
1805
1237.13.46 by Padraig O'Sullivan
Clear up a vector in a class desctructor to attempt to remove a memory leak.
1806
  if ((tree->n_ror_scans < 2) || ! param->table->cursor->stats.records)
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
1807
    return NULL;
1 by brian
clean slate
1808
1809
  /*
1802.16.16 by Padraig O'Sullivan
Convert struct to class and move it into optimizer namespace.
1810
    Step1: Collect ROR-able SEL_ARGs and create optimizer::RorScanInfo for each of
1 by brian
clean slate
1811
    them. Also find and save clustered PK scan if there is one.
1812
  */
1802.16.16 by Padraig O'Sullivan
Convert struct to class and move it into optimizer namespace.
1813
  optimizer::RorScanInfo **cur_ror_scan= NULL;
1814
  optimizer::RorScanInfo *cpk_scan= NULL;
1237.13.46 by Padraig O'Sullivan
Clear up a vector in a class desctructor to attempt to remove a memory leak.
1815
  uint32_t cpk_no= 0;
55 by brian
Update for using real bool types.
1816
  bool cpk_scan_used= false;
1 by brian
clean slate
1817
1802.16.16 by Padraig O'Sullivan
Convert struct to class and move it into optimizer namespace.
1818
  if (! (tree->ror_scans= (optimizer::RorScanInfo**)param->mem_root->alloc_root(sizeof(optimizer::RorScanInfo*)* param->keys)))
1485 by Brian Aker
Updates to confine memroot
1819
  {
1 by brian
clean slate
1820
    return NULL;
1485 by Brian Aker
Updates to confine memroot
1821
  }
1208.3.2 by brian
Update for Cursor renaming.
1822
  cpk_no= ((param->table->cursor->primary_key_is_clustered()) ?
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
1823
           param->table->getShare()->getPrimaryKey() : MAX_KEY);
1 by brian
clean slate
1824
1825
  for (idx= 0, cur_ror_scan= tree->ror_scans; idx < param->keys; idx++)
1826
  {
1802.16.16 by Padraig O'Sullivan
Convert struct to class and move it into optimizer namespace.
1827
    optimizer::RorScanInfo *scan;
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
1828
    if (! tree->ror_scans_map.test(idx))
1 by brian
clean slate
1829
      continue;
1802.16.15 by Padraig O'Sullivan
Fix a memory leak and remove code at the same time. Function for allocating memory for an object was unneeded since it was only ever called once.
1830
    if (! (scan= make_ror_scan(param, idx, tree->keys[idx])))
1 by brian
clean slate
1831
      return NULL;
1832
    if (param->real_keynr[idx] == cpk_no)
1833
    {
1834
      cpk_scan= scan;
1835
      tree->n_ror_scans--;
1836
    }
1837
    else
1838
      *(cur_ror_scan++)= scan;
1839
  }
1840
1841
  tree->ror_scans_end= cur_ror_scan;
1842
  /*
1843
    Ok, [ror_scans, ror_scans_end) is array of ptrs to initialized
1802.16.16 by Padraig O'Sullivan
Convert struct to class and move it into optimizer namespace.
1844
    optimizer::RorScanInfo's.
1 by brian
clean slate
1845
    Step 2: Get best ROR-intersection using an approximate algorithm.
1846
  */
1802.16.16 by Padraig O'Sullivan
Convert struct to class and move it into optimizer namespace.
1847
  internal::my_qsort(tree->ror_scans, tree->n_ror_scans, sizeof(optimizer::RorScanInfo*),
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
1848
                     (qsort_cmp)cmp_ror_scan_info);
1 by brian
clean slate
1849
1802.16.16 by Padraig O'Sullivan
Convert struct to class and move it into optimizer namespace.
1850
  optimizer::RorScanInfo **intersect_scans= NULL; /* ROR scans used in index intersection */
1851
  optimizer::RorScanInfo **intersect_scans_end= NULL;
1852
  if (! (intersect_scans= (optimizer::RorScanInfo**)param->mem_root->alloc_root(sizeof(optimizer::RorScanInfo*) * tree->n_ror_scans)))
1 by brian
clean slate
1853
    return NULL;
1854
  intersect_scans_end= intersect_scans;
1855
1856
  /* Create and incrementally update ROR intersection. */
1802.16.15 by Padraig O'Sullivan
Fix a memory leak and remove code at the same time. Function for allocating memory for an object was unneeded since it was only ever called once.
1857
  ROR_INTERSECT_INFO intersect(param);
1858
  ROR_INTERSECT_INFO intersect_best(param);
1 by brian
clean slate
1859
1860
  /* [intersect_scans,intersect_scans_best) will hold the best intersection */
1802.16.16 by Padraig O'Sullivan
Convert struct to class and move it into optimizer namespace.
1861
  optimizer::RorScanInfo **intersect_scans_best= NULL;
1 by brian
clean slate
1862
  cur_ror_scan= tree->ror_scans;
1863
  intersect_scans_best= intersect_scans;
1802.16.15 by Padraig O'Sullivan
Fix a memory leak and remove code at the same time. Function for allocating memory for an object was unneeded since it was only ever called once.
1864
  while (cur_ror_scan != tree->ror_scans_end && ! intersect.is_covering)
1 by brian
clean slate
1865
  {
1866
    /* S= S + first(R);  R= R - first(R); */
1802.16.15 by Padraig O'Sullivan
Fix a memory leak and remove code at the same time. Function for allocating memory for an object was unneeded since it was only ever called once.
1867
    if (! ror_intersect_add(&intersect, *cur_ror_scan, false))
1 by brian
clean slate
1868
    {
1869
      cur_ror_scan++;
1870
      continue;
1871
    }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1872
1 by brian
clean slate
1873
    *(intersect_scans_end++)= *(cur_ror_scan++);
1874
1802.16.15 by Padraig O'Sullivan
Fix a memory leak and remove code at the same time. Function for allocating memory for an object was unneeded since it was only ever called once.
1875
    if (intersect.total_cost < min_cost)
1 by brian
clean slate
1876
    {
1877
      /* Local minimum found, save it */
1802.16.15 by Padraig O'Sullivan
Fix a memory leak and remove code at the same time. Function for allocating memory for an object was unneeded since it was only ever called once.
1878
      ror_intersect_cpy(&intersect_best, &intersect);
1 by brian
clean slate
1879
      intersect_scans_best= intersect_scans_end;
1802.16.15 by Padraig O'Sullivan
Fix a memory leak and remove code at the same time. Function for allocating memory for an object was unneeded since it was only ever called once.
1880
      min_cost = intersect.total_cost;
1 by brian
clean slate
1881
    }
1882
  }
1883
1884
  if (intersect_scans_best == intersect_scans)
1885
  {
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
1886
    return NULL;
1 by brian
clean slate
1887
  }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1888
1802.16.15 by Padraig O'Sullivan
Fix a memory leak and remove code at the same time. Function for allocating memory for an object was unneeded since it was only ever called once.
1889
  *are_all_covering= intersect.is_covering;
482 by Brian Aker
Remove uint.
1890
  uint32_t best_num= intersect_scans_best - intersect_scans;
1802.16.15 by Padraig O'Sullivan
Fix a memory leak and remove code at the same time. Function for allocating memory for an object was unneeded since it was only ever called once.
1891
  ror_intersect_cpy(&intersect, &intersect_best);
1 by brian
clean slate
1892
1893
  /*
1894
    Ok, found the best ROR-intersection of non-CPK key scans.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1895
    Check if we should add a CPK scan. If the obtained ROR-intersection is
1 by brian
clean slate
1896
    covering, it doesn't make sense to add CPK scan.
1897
  */
1802.16.15 by Padraig O'Sullivan
Fix a memory leak and remove code at the same time. Function for allocating memory for an object was unneeded since it was only ever called once.
1898
  if (cpk_scan && ! intersect.is_covering)
1 by brian
clean slate
1899
  {
1802.16.15 by Padraig O'Sullivan
Fix a memory leak and remove code at the same time. Function for allocating memory for an object was unneeded since it was only ever called once.
1900
    if (ror_intersect_add(&intersect, cpk_scan, true) &&
1901
        (intersect.total_cost < min_cost))
1 by brian
clean slate
1902
    {
55 by brian
Update for using real bool types.
1903
      cpk_scan_used= true;
1 by brian
clean slate
1904
      intersect_best= intersect; //just set pointer here
1905
    }
1906
  }
1907
1908
  /* Ok, return ROR-intersect plan if we have found one */
1237.13.27 by Padraig O'Sullivan
Correcting the case of a number of classes in the optimizer to adhere to the coding standards. Also
1909
  optimizer::RorIntersectReadPlan *trp= NULL;
1 by brian
clean slate
1910
  if (min_cost < read_time && (cpk_scan_used || best_num > 1))
1911
  {
1237.13.27 by Padraig O'Sullivan
Correcting the case of a number of classes in the optimizer to adhere to the coding standards. Also
1912
    if (! (trp= new (param->mem_root) optimizer::RorIntersectReadPlan))
1237.13.22 by Padraig O'Sullivan
Extracted a number of small classes into the table_read_plan.h header file.
1913
      return trp;
1914
1513 by Brian Aker
This patch reverts the ROR change which created a memory leak (bzr diff -r 1294..1293)
1915
    if (! (trp->first_scan=
1802.16.16 by Padraig O'Sullivan
Convert struct to class and move it into optimizer namespace.
1916
           (optimizer::RorScanInfo**)param->mem_root->alloc_root(sizeof(optimizer::RorScanInfo*)*best_num)))
1513 by Brian Aker
This patch reverts the ROR change which created a memory leak (bzr diff -r 1294..1293)
1917
      return NULL;
1802.16.16 by Padraig O'Sullivan
Convert struct to class and move it into optimizer namespace.
1918
    memcpy(trp->first_scan, intersect_scans, best_num*sizeof(optimizer::RorScanInfo*));
1513 by Brian Aker
This patch reverts the ROR change which created a memory leak (bzr diff -r 1294..1293)
1919
    trp->last_scan=  trp->first_scan + best_num;
1802.16.15 by Padraig O'Sullivan
Fix a memory leak and remove code at the same time. Function for allocating memory for an object was unneeded since it was only ever called once.
1920
    trp->is_covering= intersect_best.is_covering;
1921
    trp->read_cost= intersect_best.total_cost;
1 by brian
clean slate
1922
    /* Prevent divisons by zero */
1802.16.15 by Padraig O'Sullivan
Fix a memory leak and remove code at the same time. Function for allocating memory for an object was unneeded since it was only ever called once.
1923
    ha_rows best_rows = double2rows(intersect_best.out_rows);
1237.13.46 by Padraig O'Sullivan
Clear up a vector in a class desctructor to attempt to remove a memory leak.
1924
    if (! best_rows)
1 by brian
clean slate
1925
      best_rows= 1;
1926
    set_if_smaller(param->table->quick_condition_rows, best_rows);
1927
    trp->records= best_rows;
1802.16.15 by Padraig O'Sullivan
Fix a memory leak and remove code at the same time. Function for allocating memory for an object was unneeded since it was only ever called once.
1928
    trp->index_scan_costs= intersect_best.index_scan_costs;
1 by brian
clean slate
1929
    trp->cpk_scan= cpk_scan_used? cpk_scan: NULL;
1930
  }
1237.13.46 by Padraig O'Sullivan
Clear up a vector in a class desctructor to attempt to remove a memory leak.
1931
  return trp;
1 by brian
clean slate
1932
}
1933
1005.2.3 by Monty Taylor
Further reversion of P.
1934
982.1.7 by Padraig O'Sullivan
Added a new helper function for testing and setting a bit in a bitset. Also,
1935
/*
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
1936
  Get best "range" table read plan for given optimizer::SEL_TREE, also update some info
1 by brian
clean slate
1937
1938
  SYNOPSIS
1939
    get_key_scans_params()
1578.4.11 by Brian Aker
PAss through the code removing current_session
1940
      session
1 by brian
clean slate
1941
      param                    Parameters from test_quick_select
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
1942
      tree                     Make range select for this optimizer::SEL_TREE
55 by brian
Update for using real bool types.
1943
      index_read_must_be_used  true <=> assume 'index only' option will be set
1 by brian
clean slate
1944
                               (except for clustered PK indexes)
55 by brian
Update for using real bool types.
1945
      update_tbl_stats         true <=> update table->quick_* with information
1 by brian
clean slate
1946
                               about range scans we've evaluated.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1947
      read_time                Maximum cost. i.e. don't create read plans with
1 by brian
clean slate
1948
                               cost > read_time.
1949
1950
  DESCRIPTION
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
1951
    Find the best "range" table read plan for given optimizer::SEL_TREE.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1952
    The side effects are
1 by brian
clean slate
1953
     - tree->ror_scans is updated to indicate which scans are ROR scans.
55 by brian
Update for using real bool types.
1954
     - if update_tbl_stats=true then table->quick_* is updated with info
1 by brian
clean slate
1955
       about every possible range scan.
1956
1957
  RETURN
1958
    Best range read plan
1959
    NULL if no plan found or error occurred
1960
*/
1961
1578.4.11 by Brian Aker
PAss through the code removing current_session
1962
static optimizer::RangeReadPlan *get_key_scans_params(Session *session,
1963
                                                      optimizer::Parameter *param,
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
1964
                                                      optimizer::SEL_TREE *tree,
1237.13.28 by Padraig O'Sullivan
Modified classes to have names in camel case instead of all upper case. Added default constructors
1965
                                                      bool index_read_must_be_used,
1966
                                                      bool update_tbl_stats,
1967
                                                      double read_time)
1 by brian
clean slate
1968
{
482 by Brian Aker
Remove uint.
1969
  uint32_t idx;
1237.13.22 by Padraig O'Sullivan
Extracted a number of small classes into the table_read_plan.h header file.
1970
  optimizer::SEL_ARG **key= NULL;
1971
  optimizer::SEL_ARG **end= NULL;
1972
  optimizer::SEL_ARG **key_to_read= NULL;
1 by brian
clean slate
1973
  ha_rows best_records= 0;
1237.13.22 by Padraig O'Sullivan
Extracted a number of small classes into the table_read_plan.h header file.
1974
  uint32_t best_mrr_flags= 0;
1975
  uint32_t best_buf_size= 0;
1237.13.28 by Padraig O'Sullivan
Modified classes to have names in camel case instead of all upper case. Added default constructors
1976
  optimizer::RangeReadPlan *read_plan= NULL;
1 by brian
clean slate
1977
  /*
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
1978
    Note that there may be trees that have type optimizer::SEL_TREE::KEY but contain no
1 by brian
clean slate
1979
    key reads at all, e.g. tree for expression "key1 is not null" where key1
1980
    is defined as "not null".
1981
  */
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
1982
  tree->ror_scans_map.reset();
1 by brian
clean slate
1983
  tree->n_ror_scans= 0;
1984
  for (idx= 0,key=tree->keys, end=key+param->keys; key != end; key++,idx++)
1985
  {
1986
    if (*key)
1987
    {
1988
      ha_rows found_records;
1336.3.2 by Djellel E. Difallah
rename class COST_VECT to CostVector and move it to ./drizzled/optimizer directory
1989
      optimizer::CostVector cost;
1221.1.1 by Jay Pipes
Fixes some valgrind warnings regarding conditionals depending on unintialized variables. Use initializer lists properly, dang it. :) Also, removed the new_Cached_item() function's use_result_field, as this was only used for views and was producing a valgrind warning unnecessarily.
1990
      double found_read_time= 0.0;
482 by Brian Aker
Remove uint.
1991
      uint32_t mrr_flags, buf_size;
1992
      uint32_t keynr= param->real_keynr[idx];
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
1993
      if ((*key)->type == optimizer::SEL_ARG::MAYBE_KEY ||
1 by brian
clean slate
1994
          (*key)->maybe_flag)
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
1995
        param->needed_reg->set(keynr);
1 by brian
clean slate
1996
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1997
      bool read_index_only= index_read_must_be_used ||
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
1998
                            param->table->covering_keys.test(keynr);
1 by brian
clean slate
1999
1578.4.11 by Brian Aker
PAss through the code removing current_session
2000
      found_records= check_quick_select(session, param, idx, read_index_only, *key,
1 by brian
clean slate
2001
                                        update_tbl_stats, &mrr_flags,
2002
                                        &buf_size, &cost);
2003
      found_read_time= cost.total_cost();
2004
      if ((found_records != HA_POS_ERROR) && param->is_ror_scan)
2005
      {
2006
        tree->n_ror_scans++;
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
2007
        tree->ror_scans_map.set(idx);
1 by brian
clean slate
2008
      }
2009
      if (read_time > found_read_time && found_records != HA_POS_ERROR)
2010
      {
2011
        read_time=    found_read_time;
2012
        best_records= found_records;
2013
        key_to_read=  key;
2014
        best_mrr_flags= mrr_flags;
2015
        best_buf_size=  buf_size;
2016
      }
2017
    }
2018
  }
2019
2020
  if (key_to_read)
2021
  {
2022
    idx= key_to_read - tree->keys;
1237.13.28 by Padraig O'Sullivan
Modified classes to have names in camel case instead of all upper case. Added default constructors
2023
    if ((read_plan= new (param->mem_root) optimizer::RangeReadPlan(*key_to_read, idx,
2024
                                                                   best_mrr_flags)))
1 by brian
clean slate
2025
    {
2026
      read_plan->records= best_records;
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
2027
      read_plan->is_ror= tree->ror_scans_map.test(idx);
1 by brian
clean slate
2028
      read_plan->read_cost= read_time;
1513 by Brian Aker
This patch reverts the ROR change which created a memory leak (bzr diff -r 1294..1293)
2029
      read_plan->mrr_buf_size= best_buf_size;
1 by brian
clean slate
2030
    }
2031
  }
2032
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
2033
  return(read_plan);
1 by brian
clean slate
2034
}
2035
2036
1237.13.27 by Padraig O'Sullivan
Correcting the case of a number of classes in the optimizer to adhere to the coding standards. Also
2037
optimizer::QuickSelectInterface *optimizer::IndexMergeReadPlan::make_quick(optimizer::Parameter *param, bool, memory::Root *)
1 by brian
clean slate
2038
{
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
2039
  optimizer::QuickIndexMergeSelect *quick_imerge;
2040
  optimizer::QuickRangeSelect *quick= NULL;
1 by brian
clean slate
2041
  /* index_merge always retrieves full rows, ignore retrieve_full_rows */
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
2042
  if (! (quick_imerge= new optimizer::QuickIndexMergeSelect(param->session, param->table)))
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
2043
  {
1 by brian
clean slate
2044
    return NULL;
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
2045
  }
1 by brian
clean slate
2046
2047
  quick_imerge->records= records;
2048
  quick_imerge->read_time= read_cost;
1237.13.28 by Padraig O'Sullivan
Modified classes to have names in camel case instead of all upper case. Added default constructors
2049
  for (optimizer::RangeReadPlan **range_scan= range_scans; 
1237.13.22 by Padraig O'Sullivan
Extracted a number of small classes into the table_read_plan.h header file.
2050
       range_scan != range_scans_end;
1 by brian
clean slate
2051
       range_scan++)
2052
  {
1237.13.15 by Padraig O'Sullivan
Used std::vector instead of List in the QuickRorUnionSelect class.
2053
    if (! (quick= (optimizer::QuickRangeSelect*)
2054
          ((*range_scan)->make_quick(param, false, &quick_imerge->alloc))) ||
1 by brian
clean slate
2055
        quick_imerge->push_quick_back(quick))
2056
    {
2057
      delete quick;
2058
      delete quick_imerge;
2059
      return NULL;
2060
    }
2061
  }
2062
  return quick_imerge;
2063
}
2064
1237.13.27 by Padraig O'Sullivan
Correcting the case of a number of classes in the optimizer to adhere to the coding standards. Also
2065
optimizer::QuickSelectInterface *optimizer::RorIntersectReadPlan::make_quick(optimizer::Parameter *param,
2066
                                                                             bool retrieve_full_rows,
2067
                                                                             memory::Root *parent_alloc)
1 by brian
clean slate
2068
{
1237.13.12 by Padraig O'Sullivan
Corrected the name of the QUICK_ROR_INTERSECT_CLASS class to adhere to the drizzle coding standards.
2069
  optimizer::QuickRorIntersectSelect *quick_intersect= NULL;
1237.13.2 by Padraig O'Sullivan
Modified the names of 2 classes in the optimizer to adhere to the coding standards.
2070
  optimizer::QuickRangeSelect *quick= NULL;
1253.1.3 by Monty Taylor
MEM_ROOT == memory::Root
2071
  memory::Root *alloc= NULL;
1 by brian
clean slate
2072
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
2073
  if ((quick_intersect=
1237.13.12 by Padraig O'Sullivan
Corrected the name of the QUICK_ROR_INTERSECT_CLASS class to adhere to the drizzle coding standards.
2074
         new optimizer::QuickRorIntersectSelect(param->session,
2075
                                                param->table,
2076
                                                (retrieve_full_rows? (! is_covering) : false),
2077
                                                parent_alloc)))
1 by brian
clean slate
2078
  {
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
2079
    alloc= parent_alloc ? parent_alloc : &quick_intersect->alloc;
1513 by Brian Aker
This patch reverts the ROR change which created a memory leak (bzr diff -r 1294..1293)
2080
    for (; first_scan != last_scan; ++first_scan)
1 by brian
clean slate
2081
    {
1240.3.1 by Brian Aker
Merge Padraig.
2082
      if (! (quick= optimizer::get_quick_select(param,
1513 by Brian Aker
This patch reverts the ROR change which created a memory leak (bzr diff -r 1294..1293)
2083
                                                (*first_scan)->idx,
2084
                                                (*first_scan)->sel_arg,
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
2085
                                                HA_MRR_USE_DEFAULT_IMPL | HA_MRR_SORTED,
1240.3.1 by Brian Aker
Merge Padraig.
2086
                                                0,
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
2087
                                                alloc)) ||
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
2088
          quick_intersect->push_quick_back(quick))
1 by brian
clean slate
2089
      {
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
2090
        delete quick_intersect;
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
2091
        return NULL;
1 by brian
clean slate
2092
      }
2093
    }
2094
    if (cpk_scan)
2095
    {
1240.3.1 by Brian Aker
Merge Padraig.
2096
      if (! (quick= optimizer::get_quick_select(param,
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
2097
                                                cpk_scan->idx,
2098
                                                cpk_scan->sel_arg,
2099
                                                HA_MRR_USE_DEFAULT_IMPL | HA_MRR_SORTED,
1240.3.1 by Brian Aker
Merge Padraig.
2100
                                                0,
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
2101
                                                alloc)))
1 by brian
clean slate
2102
      {
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
2103
        delete quick_intersect;
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
2104
        return NULL;
1 by brian
clean slate
2105
      }
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
2106
      quick->resetCursor();
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
2107
      quick_intersect->cpk_quick= quick;
1 by brian
clean slate
2108
    }
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
2109
    quick_intersect->records= records;
2110
    quick_intersect->read_time= read_cost;
1 by brian
clean slate
2111
  }
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
2112
  return quick_intersect;
1 by brian
clean slate
2113
}
2114
2115
1237.13.28 by Padraig O'Sullivan
Modified classes to have names in camel case instead of all upper case. Added default constructors
2116
optimizer::QuickSelectInterface *optimizer::RorUnionReadPlan::make_quick(optimizer::Parameter *param, bool, memory::Root *)
1 by brian
clean slate
2117
{
1237.13.14 by Padraig O'Sullivan
Corrected some style issues in quick_ror_union_select.[cc,h] and range.cc
2118
  optimizer::QuickRorUnionSelect *quick_roru= NULL;
1513 by Brian Aker
This patch reverts the ROR change which created a memory leak (bzr diff -r 1294..1293)
2119
  optimizer::TableReadPlan **scan= NULL;
1237.13.14 by Padraig O'Sullivan
Corrected some style issues in quick_ror_union_select.[cc,h] and range.cc
2120
  optimizer::QuickSelectInterface *quick= NULL;
1 by brian
clean slate
2121
  /*
2122
    It is impossible to construct a ROR-union that will not retrieve full
2123
    rows, ignore retrieve_full_rows parameter.
2124
  */
1237.13.14 by Padraig O'Sullivan
Corrected some style issues in quick_ror_union_select.[cc,h] and range.cc
2125
  if ((quick_roru= new optimizer::QuickRorUnionSelect(param->session, param->table)))
1 by brian
clean slate
2126
  {
1513 by Brian Aker
This patch reverts the ROR change which created a memory leak (bzr diff -r 1294..1293)
2127
    for (scan= first_ror; scan != last_ror; scan++)
1 by brian
clean slate
2128
    {
1513 by Brian Aker
This patch reverts the ROR change which created a memory leak (bzr diff -r 1294..1293)
2129
      if (! (quick= (*scan)->make_quick(param, false, &quick_roru->alloc)) ||
1 by brian
clean slate
2130
          quick_roru->push_quick_back(quick))
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
2131
      {
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
2132
        return NULL;
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
2133
      }
1 by brian
clean slate
2134
    }
2135
    quick_roru->records= records;
2136
    quick_roru->read_time= read_cost;
2137
  }
1237.13.14 by Padraig O'Sullivan
Corrected some style issues in quick_ror_union_select.[cc,h] and range.cc
2138
  return quick_roru;
1 by brian
clean slate
2139
}
2140
2141
2142
/*
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
2143
  Build a optimizer::SEL_TREE for <> or NOT BETWEEN predicate
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2144
1 by brian
clean slate
2145
  SYNOPSIS
2146
    get_ne_mm_tree()
1237.13.7 by Padraig O'Sullivan
Renamed PARAM to Parameter and RANGE_OPT_PARAM to RangeParameter.
2147
      param       Parameter from SqlSelect::test_quick_select
1 by brian
clean slate
2148
      cond_func   item for the predicate
2149
      field       field in the predicate
2150
      lt_value    constant that field should be smaller
2151
      gt_value    constant that field should be greaterr
2152
      cmp_type    compare type for the field
2153
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2154
  RETURN
1 by brian
clean slate
2155
    #  Pointer to tree built tree
2156
    0  on error
2157
*/
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
2158
static optimizer::SEL_TREE *get_ne_mm_tree(optimizer::RangeParameter *param,
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
2159
                                Item_func *cond_func,
1 by brian
clean slate
2160
                                Field *field,
2161
                                Item *lt_value, Item *gt_value,
2162
                                Item_result cmp_type)
2163
{
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
2164
  optimizer::SEL_TREE *tree= NULL;
1 by brian
clean slate
2165
  tree= get_mm_parts(param, cond_func, field, Item_func::LT_FUNC,
2166
                     lt_value, cmp_type);
2167
  if (tree)
2168
  {
1240.3.1 by Brian Aker
Merge Padraig.
2169
    tree= tree_or(param,
2170
                  tree,
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
2171
                  get_mm_parts(param, cond_func, field,
2172
					        Item_func::GT_FUNC,
1240.3.1 by Brian Aker
Merge Padraig.
2173
					        gt_value,
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
2174
                  cmp_type));
1 by brian
clean slate
2175
  }
2176
  return tree;
2177
}
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2178
1 by brian
clean slate
2179
2180
/*
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
2181
  Build a optimizer::SEL_TREE for a simple predicate
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2182
1 by brian
clean slate
2183
  SYNOPSIS
2184
    get_func_mm_tree()
1237.13.7 by Padraig O'Sullivan
Renamed PARAM to Parameter and RANGE_OPT_PARAM to RangeParameter.
2185
      param       Parameter from SqlSelect::test_quick_select
1 by brian
clean slate
2186
      cond_func   item for the predicate
2187
      field       field in the predicate
2188
      value       constant in the predicate
2189
      cmp_type    compare type for the field
55 by brian
Update for using real bool types.
2190
      inv         true <> NOT cond_func is considered
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2191
                  (makes sense only when cond_func is BETWEEN or IN)
1 by brian
clean slate
2192
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2193
  RETURN
1 by brian
clean slate
2194
    Pointer to the tree built tree
2195
*/
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
2196
static optimizer::SEL_TREE *get_func_mm_tree(optimizer::RangeParameter *param,
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
2197
                                  Item_func *cond_func,
1237.13.14 by Padraig O'Sullivan
Corrected some style issues in quick_ror_union_select.[cc,h] and range.cc
2198
                                  Field *field, 
2199
                                  Item *value,
2200
                                  Item_result cmp_type, 
2201
                                  bool inv)
1 by brian
clean slate
2202
{
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
2203
  optimizer::SEL_TREE *tree= NULL;
1 by brian
clean slate
2204
1237.13.14 by Padraig O'Sullivan
Corrected some style issues in quick_ror_union_select.[cc,h] and range.cc
2205
  switch (cond_func->functype()) 
2206
  {
1 by brian
clean slate
2207
2208
  case Item_func::NE_FUNC:
2209
    tree= get_ne_mm_tree(param, cond_func, field, value, value, cmp_type);
2210
    break;
2211
2212
  case Item_func::BETWEEN:
2213
  {
1237.13.14 by Padraig O'Sullivan
Corrected some style issues in quick_ror_union_select.[cc,h] and range.cc
2214
    if (! value)
1 by brian
clean slate
2215
    {
2216
      if (inv)
2217
      {
1237.13.14 by Padraig O'Sullivan
Corrected some style issues in quick_ror_union_select.[cc,h] and range.cc
2218
        tree= get_ne_mm_tree(param, 
2219
                             cond_func, 
2220
                             field, 
2221
                             cond_func->arguments()[1],
2222
                             cond_func->arguments()[2], 
2223
                             cmp_type);
1 by brian
clean slate
2224
      }
2225
      else
2226
      {
1237.13.14 by Padraig O'Sullivan
Corrected some style issues in quick_ror_union_select.[cc,h] and range.cc
2227
        tree= get_mm_parts(param, 
2228
                           cond_func, 
2229
                           field, 
2230
                           Item_func::GE_FUNC,
2231
		                       cond_func->arguments()[1],
2232
                           cmp_type);
1 by brian
clean slate
2233
        if (tree)
2234
        {
1237.13.14 by Padraig O'Sullivan
Corrected some style issues in quick_ror_union_select.[cc,h] and range.cc
2235
          tree= tree_and(param, 
2236
                         tree, 
2237
                         get_mm_parts(param, cond_func, field,
2238
					               Item_func::LE_FUNC,
2239
					               cond_func->arguments()[2],
2240
                         cmp_type));
1 by brian
clean slate
2241
        }
2242
      }
2243
    }
2244
    else
1237.13.14 by Padraig O'Sullivan
Corrected some style issues in quick_ror_union_select.[cc,h] and range.cc
2245
      tree= get_mm_parts(param, 
2246
                         cond_func, 
2247
                         field,
1 by brian
clean slate
2248
                         (inv ?
2249
                          (value == (Item*)1 ? Item_func::GT_FUNC :
2250
                                               Item_func::LT_FUNC):
2251
                          (value == (Item*)1 ? Item_func::LE_FUNC :
2252
                                               Item_func::GE_FUNC)),
1237.13.14 by Padraig O'Sullivan
Corrected some style issues in quick_ror_union_select.[cc,h] and range.cc
2253
                         cond_func->arguments()[0], 
2254
                         cmp_type);
1 by brian
clean slate
2255
    break;
2256
  }
2257
  case Item_func::IN_FUNC:
2258
  {
1237.13.14 by Padraig O'Sullivan
Corrected some style issues in quick_ror_union_select.[cc,h] and range.cc
2259
    Item_func_in *func= (Item_func_in*) cond_func;
1 by brian
clean slate
2260
2261
    /*
2262
      Array for IN() is constructed when all values have the same result
2263
      type. Tree won't be built for values with different result types,
2264
      so we check it here to avoid unnecessary work.
2265
    */
1237.13.14 by Padraig O'Sullivan
Corrected some style issues in quick_ror_union_select.[cc,h] and range.cc
2266
    if (! func->arg_types_compatible)
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2267
      break;
1 by brian
clean slate
2268
2269
    if (inv)
2270
    {
2271
      if (func->array && func->array->result_type() != ROW_RESULT)
2272
      {
2273
        /*
2274
          We get here for conditions in form "t.key NOT IN (c1, c2, ...)",
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
2275
          where c{i} are constants. Our goal is to produce a optimizer::SEL_TREE that
1 by brian
clean slate
2276
          represents intervals:
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2277
1 by brian
clean slate
2278
          ($MIN<t.key<c1) OR (c1<t.key<c2) OR (c2<t.key<c3) OR ...    (*)
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2279
1 by brian
clean slate
2280
          where $MIN is either "-inf" or NULL.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2281
1 by brian
clean slate
2282
          The most straightforward way to produce it is to convert NOT IN
2283
          into "(t.key != c1) AND (t.key != c2) AND ... " and let the range
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
2284
          analyzer to build optimizer::SEL_TREE from that. The problem is that the
1 by brian
clean slate
2285
          range analyzer will use O(N^2) memory (which is probably a bug),
2286
          and people do use big NOT IN lists (e.g. see BUG#15872, BUG#21282),
2287
          will run out of memory.
2288
2289
          Another problem with big lists like (*) is that a big list is
2290
          unlikely to produce a good "range" access, while considering that
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2291
          range access will require expensive CPU calculations (and for
1 by brian
clean slate
2292
          MyISAM even index accesses). In short, big NOT IN lists are rarely
2293
          worth analyzing.
2294
2295
          Considering the above, we'll handle NOT IN as follows:
2296
          * if the number of entries in the NOT IN list is less than
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
2297
            NOT_IN_IGNORE_THRESHOLD, construct the optimizer::SEL_TREE (*) manually.
2298
          * Otherwise, don't produce a optimizer::SEL_TREE.
1 by brian
clean slate
2299
        */
2300
#define NOT_IN_IGNORE_THRESHOLD 1000
1253.1.3 by Monty Taylor
MEM_ROOT == memory::Root
2301
        memory::Root *tmp_root= param->mem_root;
520.1.22 by Brian Aker
Second pass of thd cleanup
2302
        param->session->mem_root= param->old_root;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2303
        /*
1 by brian
clean slate
2304
          Create one Item_type constant object. We'll need it as
2305
          get_mm_parts only accepts constant values wrapped in Item_Type
2306
          objects.
2307
          We create the Item on param->mem_root which points to
520.1.22 by Brian Aker
Second pass of thd cleanup
2308
          per-statement mem_root (while session->mem_root is currently pointing
1 by brian
clean slate
2309
          to mem_root local to range optimizer).
2310
        */
2311
        Item *value_item= func->array->create_item();
520.1.22 by Brian Aker
Second pass of thd cleanup
2312
        param->session->mem_root= tmp_root;
1 by brian
clean slate
2313
1237.13.14 by Padraig O'Sullivan
Corrected some style issues in quick_ror_union_select.[cc,h] and range.cc
2314
        if (func->array->count > NOT_IN_IGNORE_THRESHOLD || ! value_item)
1 by brian
clean slate
2315
          break;
2316
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
2317
        /* Get a optimizer::SEL_TREE for "(-inf|NULL) < X < c_0" interval.  */
482 by Brian Aker
Remove uint.
2318
        uint32_t i=0;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2319
        do
1 by brian
clean slate
2320
        {
2321
          func->array->value_to_item(i, value_item);
1237.13.14 by Padraig O'Sullivan
Corrected some style issues in quick_ror_union_select.[cc,h] and range.cc
2322
          tree= get_mm_parts(param, 
2323
                             cond_func, 
2324
                             field, Item_func::LT_FUNC,
2325
                             value_item, 
2326
                             cmp_type);
2327
          if (! tree)
1 by brian
clean slate
2328
            break;
2329
          i++;
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
2330
        } while (i < func->array->count && tree->type == optimizer::SEL_TREE::IMPOSSIBLE);
1 by brian
clean slate
2331
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
2332
        if (!tree || tree->type == optimizer::SEL_TREE::IMPOSSIBLE)
1 by brian
clean slate
2333
        {
2334
          /* We get here in cases like "t.unsigned NOT IN (-1,-2,-3) */
2335
          tree= NULL;
2336
          break;
2337
        }
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
2338
        optimizer::SEL_TREE *tree2= NULL;
1 by brian
clean slate
2339
        for (; i < func->array->count; i++)
2340
        {
2341
          if (func->array->compare_elems(i, i-1))
2342
          {
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
2343
            /* Get a optimizer::SEL_TREE for "-inf < X < c_i" interval */
1 by brian
clean slate
2344
            func->array->value_to_item(i, value_item);
2345
            tree2= get_mm_parts(param, cond_func, field, Item_func::LT_FUNC,
2346
                                value_item, cmp_type);
2347
            if (!tree2)
2348
            {
2349
              tree= NULL;
2350
              break;
2351
            }
2352
2353
            /* Change all intervals to be "c_{i-1} < X < c_i" */
482 by Brian Aker
Remove uint.
2354
            for (uint32_t idx= 0; idx < param->keys; idx++)
1 by brian
clean slate
2355
            {
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
2356
              optimizer::SEL_ARG *new_interval, *last_val;
1 by brian
clean slate
2357
              if (((new_interval= tree2->keys[idx])) &&
2358
                  (tree->keys[idx]) &&
2359
                  ((last_val= tree->keys[idx]->last())))
2360
              {
2361
                new_interval->min_value= last_val->max_value;
2362
                new_interval->min_flag= NEAR_MIN;
2363
              }
2364
            }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2365
            /*
1 by brian
clean slate
2366
              The following doesn't try to allocate memory so no need to
2367
              check for NULL.
2368
            */
2369
            tree= tree_or(param, tree, tree2);
2370
          }
2371
        }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2372
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
2373
        if (tree && tree->type != optimizer::SEL_TREE::IMPOSSIBLE)
1 by brian
clean slate
2374
        {
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2375
          /*
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
2376
            Get the optimizer::SEL_TREE for the last "c_last < X < +inf" interval
1 by brian
clean slate
2377
            (value_item cotains c_last already)
2378
          */
2379
          tree2= get_mm_parts(param, cond_func, field, Item_func::GT_FUNC,
2380
                              value_item, cmp_type);
2381
          tree= tree_or(param, tree, tree2);
2382
        }
2383
      }
2384
      else
2385
      {
2386
        tree= get_ne_mm_tree(param, cond_func, field,
2387
                             func->arguments()[1], func->arguments()[1],
2388
                             cmp_type);
2389
        if (tree)
2390
        {
2391
          Item **arg, **end;
2392
          for (arg= func->arguments()+2, end= arg+func->argument_count()-2;
2393
               arg < end ; arg++)
2394
          {
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2395
            tree=  tree_and(param, tree, get_ne_mm_tree(param, cond_func, field,
1 by brian
clean slate
2396
                                                        *arg, *arg, cmp_type));
2397
          }
2398
        }
2399
      }
2400
    }
2401
    else
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2402
    {
1 by brian
clean slate
2403
      tree= get_mm_parts(param, cond_func, field, Item_func::EQ_FUNC,
2404
                         func->arguments()[1], cmp_type);
2405
      if (tree)
2406
      {
2407
        Item **arg, **end;
2408
        for (arg= func->arguments()+2, end= arg+func->argument_count()-2;
2409
             arg < end ; arg++)
2410
        {
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2411
          tree= tree_or(param, tree, get_mm_parts(param, cond_func, field,
1 by brian
clean slate
2412
                                                  Item_func::EQ_FUNC,
2413
                                                  *arg, cmp_type));
2414
        }
2415
      }
2416
    }
2417
    break;
2418
  }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2419
  default:
1 by brian
clean slate
2420
  {
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2421
    /*
1 by brian
clean slate
2422
       Here the function for the following predicates are processed:
2423
       <, <=, =, >=, >, LIKE, IS NULL, IS NOT NULL.
2424
       If the predicate is of the form (value op field) it is handled
2425
       as the equivalent predicate (field rev_op value), e.g.
2426
       2 <= a is handled as a >= 2.
2427
    */
2428
    Item_func::Functype func_type=
2429
      (value != cond_func->arguments()[0]) ? cond_func->functype() :
2430
        ((Item_bool_func2*) cond_func)->rev_functype();
2431
    tree= get_mm_parts(param, cond_func, field, func_type, value, cmp_type);
2432
  }
2433
  }
2434
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
2435
  return(tree);
1 by brian
clean slate
2436
}
2437
2438
2439
/*
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
2440
  Build conjunction of all optimizer::SEL_TREEs for a simple predicate applying equalities
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2441
1 by brian
clean slate
2442
  SYNOPSIS
2443
    get_full_func_mm_tree()
1237.13.7 by Padraig O'Sullivan
Renamed PARAM to Parameter and RANGE_OPT_PARAM to RangeParameter.
2444
      param       Parameter from SqlSelect::test_quick_select
1 by brian
clean slate
2445
      cond_func   item for the predicate
2446
      field_item  field in the predicate
2447
      value       constant in the predicate
2448
                  (for BETWEEN it contains the number of the field argument,
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2449
                   for IN it's always 0)
55 by brian
Update for using real bool types.
2450
      inv         true <> NOT cond_func is considered
1 by brian
clean slate
2451
                  (makes sense only when cond_func is BETWEEN or IN)
2452
2453
  DESCRIPTION
2454
    For a simple SARGable predicate of the form (f op c), where f is a field and
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
2455
    c is a constant, the function builds a conjunction of all optimizer::SEL_TREES that can
1 by brian
clean slate
2456
    be obtained by the substitution of f for all different fields equal to f.
2457
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2458
  NOTES
1 by brian
clean slate
2459
    If the WHERE condition contains a predicate (fi op c),
2460
    then not only SELL_TREE for this predicate is built, but
2461
    the trees for the results of substitution of fi for
2462
    each fj belonging to the same multiple equality as fi
2463
    are built as well.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2464
    E.g. for WHERE t1.a=t2.a AND t2.a > 10
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
2465
    a optimizer::SEL_TREE for t2.a > 10 will be built for quick select from t2
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2466
    and
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
2467
    a optimizer::SEL_TREE for t1.a > 10 will be built for quick select from t1.
1 by brian
clean slate
2468
2469
    A BETWEEN predicate of the form (fi [NOT] BETWEEN c1 AND c2) is treated
2470
    in a similar way: we build a conjuction of trees for the results
2471
    of all substitutions of fi for equal fj.
2472
    Yet a predicate of the form (c BETWEEN f1i AND f2i) is processed
2473
    differently. It is considered as a conjuction of two SARGable
2474
    predicates (f1i <= c) and (f2i <=c) and the function get_full_func_mm_tree
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2475
    is called for each of them separately producing trees for
2476
       AND j (f1j <=c ) and AND j (f2j <= c)
1 by brian
clean slate
2477
    After this these two trees are united in one conjunctive tree.
2478
    It's easy to see that the same tree is obtained for
2479
       AND j,k (f1j <=c AND f2k<=c)
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2480
    which is equivalent to
1 by brian
clean slate
2481
       AND j,k (c BETWEEN f1j AND f2k).
2482
    The validity of the processing of the predicate (c NOT BETWEEN f1i AND f2i)
2483
    which equivalent to (f1i > c OR f2i < c) is not so obvious. Here the
2484
    function get_full_func_mm_tree is called for (f1i > c) and (f2i < c)
2485
    producing trees for AND j (f1j > c) and AND j (f2j < c). Then this two
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2486
    trees are united in one OR-tree. The expression
1 by brian
clean slate
2487
      (AND j (f1j > c) OR AND j (f2j < c)
2488
    is equivalent to the expression
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2489
      AND j,k (f1j > c OR f2k < c)
2490
    which is just a translation of
1 by brian
clean slate
2491
      AND j,k (c NOT BETWEEN f1j AND f2k)
2492
2493
    In the cases when one of the items f1, f2 is a constant c1 we do not create
2494
    a tree for it at all. It works for BETWEEN predicates but does not
2495
    work for NOT BETWEEN predicates as we have to evaluate the expression
55 by brian
Update for using real bool types.
2496
    with it. If it is true then the other tree can be completely ignored.
1 by brian
clean slate
2497
    We do not do it now and no trees are built in these cases for
2498
    NOT BETWEEN predicates.
2499
2500
    As to IN predicates only ones of the form (f IN (c1,...,cn)),
2501
    where f1 is a field and c1,...,cn are constant, are considered as
2502
    SARGable. We never try to narrow the index scan using predicates of
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2503
    the form (c IN (c1,...,f,...,cn)).
2504
2505
  RETURN
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
2506
    Pointer to the tree representing the built conjunction of optimizer::SEL_TREEs
1 by brian
clean slate
2507
*/
2508
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
2509
static optimizer::SEL_TREE *get_full_func_mm_tree(optimizer::RangeParameter *param,
1 by brian
clean slate
2510
                                       Item_func *cond_func,
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2511
                                       Item_field *field_item, Item *value,
1 by brian
clean slate
2512
                                       bool inv)
2513
{
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
2514
  optimizer::SEL_TREE *tree= 0;
2515
  optimizer::SEL_TREE *ftree= 0;
1 by brian
clean slate
2516
  table_map ref_tables= 0;
2517
  table_map param_comp= ~(param->prev_tables | param->read_tables |
2518
		          param->current_table);
2519
482 by Brian Aker
Remove uint.
2520
  for (uint32_t i= 0; i < cond_func->arg_count; i++)
1 by brian
clean slate
2521
  {
2522
    Item *arg= cond_func->arguments()[i]->real_item();
2523
    if (arg != field_item)
2524
      ref_tables|= arg->used_tables();
2525
  }
1089.1.3 by Brian Aker
Fix protobuf to release memory. Add in assert() for wrong column usage. Fix
2526
1 by brian
clean slate
2527
  Field *field= field_item->field;
1089.1.3 by Brian Aker
Fix protobuf to release memory. Add in assert() for wrong column usage. Fix
2528
  field->setWriteSet();
2529
1 by brian
clean slate
2530
  Item_result cmp_type= field->cmp_type();
1660.1.3 by Brian Aker
Encapsulate Table in field
2531
  if (!((ref_tables | field->getTable()->map) & param_comp))
1 by brian
clean slate
2532
    ftree= get_func_mm_tree(param, cond_func, field, value, cmp_type, inv);
2533
  Item_equal *item_equal= field_item->item_equal;
2534
  if (item_equal)
2535
  {
2536
    Item_equal_iterator it(*item_equal);
2537
    Item_field *item;
2538
    while ((item= it++))
2539
    {
2540
      Field *f= item->field;
1089.1.3 by Brian Aker
Fix protobuf to release memory. Add in assert() for wrong column usage. Fix
2541
      f->setWriteSet();
2542
1 by brian
clean slate
2543
      if (field->eq(f))
2544
        continue;
1660.1.3 by Brian Aker
Encapsulate Table in field
2545
      if (!((ref_tables | f->getTable()->map) & param_comp))
1 by brian
clean slate
2546
      {
2547
        tree= get_func_mm_tree(param, cond_func, f, value, cmp_type, inv);
2548
        ftree= !ftree ? tree : tree_and(param, ftree, tree);
2549
      }
2550
    }
2551
  }
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
2552
  return(ftree);
1 by brian
clean slate
2553
}
2554
2555
	/* make a select tree of all keys in condition */
2556
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
2557
static optimizer::SEL_TREE *get_mm_tree(optimizer::RangeParameter *param, COND *cond)
1 by brian
clean slate
2558
{
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
2559
  optimizer::SEL_TREE *tree=0;
2560
  optimizer::SEL_TREE *ftree= 0;
1 by brian
clean slate
2561
  Item_field *field_item= 0;
55 by brian
Update for using real bool types.
2562
  bool inv= false;
1 by brian
clean slate
2563
  Item *value= 0;
2564
2565
  if (cond->type() == Item::COND_ITEM)
2566
  {
2567
    List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
2568
2569
    if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
2570
    {
2571
      tree=0;
2572
      Item *item;
2573
      while ((item=li++))
2574
      {
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
2575
	optimizer::SEL_TREE *new_tree= get_mm_tree(param,item);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2576
	if (param->session->is_fatal_error ||
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
2577
            param->alloced_sel_args > optimizer::SEL_ARG::MAX_SEL_ARGS)
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
2578
	  return 0;	// out of memory
1 by brian
clean slate
2579
	tree=tree_and(param,tree,new_tree);
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
2580
	if (tree && tree->type == optimizer::SEL_TREE::IMPOSSIBLE)
1 by brian
clean slate
2581
	  break;
2582
      }
2583
    }
2584
    else
2585
    {						// COND OR
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
2586
      tree= get_mm_tree(param,li++);
1 by brian
clean slate
2587
      if (tree)
2588
      {
2589
	Item *item;
2590
	while ((item=li++))
2591
	{
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
2592
	  optimizer::SEL_TREE *new_tree= get_mm_tree(param,item);
1 by brian
clean slate
2593
	  if (!new_tree)
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
2594
	    return 0;	// out of memory
1 by brian
clean slate
2595
	  tree=tree_or(param,tree,new_tree);
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
2596
	  if (!tree || tree->type == optimizer::SEL_TREE::ALWAYS)
1 by brian
clean slate
2597
	    break;
2598
	}
2599
      }
2600
    }
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
2601
    return(tree);
1 by brian
clean slate
2602
  }
1637.5.6 by Prafulla Tekawade
This bug is simillar to mysql bug 36133
2603
  /* Here when simple cond
2604
     There are limits on what kinds of const items we can evaluate, grep for
2605
     DontEvaluateMaterializedSubqueryTooEarly.
2606
  */
2607
  if (cond->const_item()  && !cond->is_expensive())
1 by brian
clean slate
2608
  {
2609
    /*
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2610
      During the cond->val_int() evaluation we can come across a subselect
2611
      item which may allocate memory on the session->mem_root and assumes
2612
      all the memory allocated has the same life span as the subselect
1 by brian
clean slate
2613
      item itself. So we have to restore the thread's mem_root here.
2614
    */
1253.1.3 by Monty Taylor
MEM_ROOT == memory::Root
2615
    memory::Root *tmp_root= param->mem_root;
520.1.22 by Brian Aker
Second pass of thd cleanup
2616
    param->session->mem_root= param->old_root;
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
2617
    tree= cond->val_int() ? new(tmp_root) optimizer::SEL_TREE(optimizer::SEL_TREE::ALWAYS) :
2618
                            new(tmp_root) optimizer::SEL_TREE(optimizer::SEL_TREE::IMPOSSIBLE);
520.1.22 by Brian Aker
Second pass of thd cleanup
2619
    param->session->mem_root= tmp_root;
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
2620
    return(tree);
1 by brian
clean slate
2621
  }
2622
2623
  table_map ref_tables= 0;
2624
  table_map param_comp= ~(param->prev_tables | param->read_tables |
2625
		          param->current_table);
2626
  if (cond->type() != Item::FUNC_ITEM)
2627
  {						// Should be a field
2628
    ref_tables= cond->used_tables();
2629
    if ((ref_tables & param->current_table) ||
2630
	(ref_tables & ~(param->prev_tables | param->read_tables)))
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
2631
      return 0;
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
2632
    return(new optimizer::SEL_TREE(optimizer::SEL_TREE::MAYBE));
1 by brian
clean slate
2633
  }
2634
2635
  Item_func *cond_func= (Item_func*) cond;
2636
  if (cond_func->functype() == Item_func::BETWEEN ||
2637
      cond_func->functype() == Item_func::IN_FUNC)
2638
    inv= ((Item_func_opt_neg *) cond_func)->negated;
2639
  else if (cond_func->select_optimize() == Item_func::OPTIMIZE_NONE)
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
2640
    return 0;
1 by brian
clean slate
2641
2642
  param->cond= cond;
2643
2644
  switch (cond_func->functype()) {
2645
  case Item_func::BETWEEN:
2646
    if (cond_func->arguments()[0]->real_item()->type() == Item::FIELD_ITEM)
2647
    {
2648
      field_item= (Item_field*) (cond_func->arguments()[0]->real_item());
2649
      ftree= get_full_func_mm_tree(param, cond_func, field_item, NULL, inv);
2650
    }
2651
2652
    /*
2653
      Concerning the code below see the NOTES section in
2654
      the comments for the function get_full_func_mm_tree()
2655
    */
482 by Brian Aker
Remove uint.
2656
    for (uint32_t i= 1 ; i < cond_func->arg_count ; i++)
1 by brian
clean slate
2657
    {
2658
      if (cond_func->arguments()[i]->real_item()->type() == Item::FIELD_ITEM)
2659
      {
2660
        field_item= (Item_field*) (cond_func->arguments()[i]->real_item());
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
2661
        optimizer::SEL_TREE *tmp= get_full_func_mm_tree(param, cond_func,
157 by Brian Aker
Second pass cleanup on removal of my_uint types
2662
                                    field_item, (Item*)(intptr_t)i, inv);
1 by brian
clean slate
2663
        if (inv)
2664
          tree= !tree ? tmp : tree_or(param, tree, tmp);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2665
        else
1 by brian
clean slate
2666
          tree= tree_and(param, tree, tmp);
2667
      }
2668
      else if (inv)
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2669
      {
1 by brian
clean slate
2670
        tree= 0;
2671
        break;
2672
      }
2673
    }
2674
2675
    ftree = tree_and(param, ftree, tree);
2676
    break;
2677
  case Item_func::IN_FUNC:
2678
  {
2679
    Item_func_in *func=(Item_func_in*) cond_func;
2680
    if (func->key_item()->real_item()->type() != Item::FIELD_ITEM)
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
2681
      return 0;
1 by brian
clean slate
2682
    field_item= (Item_field*) (func->key_item()->real_item());
2683
    ftree= get_full_func_mm_tree(param, cond_func, field_item, NULL, inv);
2684
    break;
2685
  }
2686
  case Item_func::MULT_EQUAL_FUNC:
2687
  {
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2688
    Item_equal *item_equal= (Item_equal *) cond;
1 by brian
clean slate
2689
    if (!(value= item_equal->get_const()))
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
2690
      return 0;
1 by brian
clean slate
2691
    Item_equal_iterator it(*item_equal);
2692
    ref_tables= value->used_tables();
2693
    while ((field_item= it++))
2694
    {
2695
      Field *field= field_item->field;
1089.1.3 by Brian Aker
Fix protobuf to release memory. Add in assert() for wrong column usage. Fix
2696
      field->setWriteSet();
2697
1 by brian
clean slate
2698
      Item_result cmp_type= field->cmp_type();
1660.1.3 by Brian Aker
Encapsulate Table in field
2699
      if (!((ref_tables | field->getTable()->map) & param_comp))
1 by brian
clean slate
2700
      {
2701
        tree= get_mm_parts(param, cond, field, Item_func::EQ_FUNC,
2702
		           value,cmp_type);
2703
        ftree= !ftree ? tree : tree_and(param, ftree, tree);
2704
      }
2705
    }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2706
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
2707
    return(ftree);
1 by brian
clean slate
2708
  }
2709
  default:
2710
    if (cond_func->arguments()[0]->real_item()->type() == Item::FIELD_ITEM)
2711
    {
2712
      field_item= (Item_field*) (cond_func->arguments()[0]->real_item());
2713
      value= cond_func->arg_count > 1 ? cond_func->arguments()[1] : 0;
2714
    }
2715
    else if (cond_func->have_rev_func() &&
2716
             cond_func->arguments()[1]->real_item()->type() ==
2717
                                                            Item::FIELD_ITEM)
2718
    {
2719
      field_item= (Item_field*) (cond_func->arguments()[1]->real_item());
2720
      value= cond_func->arguments()[0];
2721
    }
2722
    else
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
2723
      return 0;
1 by brian
clean slate
2724
    ftree= get_full_func_mm_tree(param, cond_func, field_item, value, inv);
2725
  }
2726
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
2727
  return(ftree);
1 by brian
clean slate
2728
}
2729
2730
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
2731
static optimizer::SEL_TREE *
1240.3.1 by Brian Aker
Merge Padraig.
2732
get_mm_parts(optimizer::RangeParameter *param,
2733
             COND *cond_func,
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
2734
             Field *field,
2735
	           Item_func::Functype type,
2736
	           Item *value, Item_result)
1 by brian
clean slate
2737
{
1660.1.3 by Brian Aker
Encapsulate Table in field
2738
  if (field->getTable() != param->table)
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
2739
    return 0;
1 by brian
clean slate
2740
2741
  KEY_PART *key_part = param->key_parts;
2742
  KEY_PART *end = param->key_parts_end;
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
2743
  optimizer::SEL_TREE *tree=0;
1 by brian
clean slate
2744
  if (value &&
2745
      value->used_tables() & ~(param->prev_tables | param->read_tables))
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
2746
    return 0;
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
2747
  for (; key_part != end; key_part++)
1 by brian
clean slate
2748
  {
2749
    if (field->eq(key_part->field))
2750
    {
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
2751
      optimizer::SEL_ARG *sel_arg=0;
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
2752
      if (!tree && !(tree=new optimizer::SEL_TREE()))
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
2753
        return 0;				// OOM
1 by brian
clean slate
2754
      if (!value || !(value->used_tables() & ~param->read_tables))
2755
      {
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
2756
        sel_arg= get_mm_leaf(param,cond_func,
2757
            key_part->field,key_part,type,value);
2758
        if (! sel_arg)
2759
          continue;
2760
        if (sel_arg->type == optimizer::SEL_ARG::IMPOSSIBLE)
2761
        {
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
2762
          tree->type=optimizer::SEL_TREE::IMPOSSIBLE;
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
2763
          return(tree);
2764
        }
1 by brian
clean slate
2765
      }
2766
      else
2767
      {
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
2768
        // This key may be used later
2769
        if (! (sel_arg= new optimizer::SEL_ARG(optimizer::SEL_ARG::MAYBE_KEY)))
2770
          return 0;			// OOM
1 by brian
clean slate
2771
      }
481 by Brian Aker
Remove all of uchar.
2772
      sel_arg->part=(unsigned char) key_part->part;
1 by brian
clean slate
2773
      tree->keys[key_part->key]=sel_add(tree->keys[key_part->key],sel_arg);
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
2774
      tree->keys_map.set(key_part->key);
1 by brian
clean slate
2775
    }
2776
  }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2777
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
2778
  return tree;
1 by brian
clean slate
2779
}
2780
2781
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
2782
static optimizer::SEL_ARG *
1240.3.1 by Brian Aker
Merge Padraig.
2783
get_mm_leaf(optimizer::RangeParameter *param,
2784
            COND *conf_func,
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
2785
            Field *field,
1240.3.1 by Brian Aker
Merge Padraig.
2786
            KEY_PART *key_part,
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
2787
            Item_func::Functype type,
2788
            Item *value)
1 by brian
clean slate
2789
{
895 by Brian Aker
Completion (?) of uint conversion.
2790
  uint32_t maybe_null=(uint32_t) field->real_maybe_null();
1 by brian
clean slate
2791
  bool optimize_range;
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
2792
  optimizer::SEL_ARG *tree= NULL;
1253.1.3 by Monty Taylor
MEM_ROOT == memory::Root
2793
  memory::Root *alloc= param->mem_root;
481 by Brian Aker
Remove all of uchar.
2794
  unsigned char *str;
910.2.7 by Monty Taylor
Merged from Jay.
2795
  int err= 0;
1 by brian
clean slate
2796
2797
  /*
2798
    We need to restore the runtime mem_root of the thread in this
2799
    function because it evaluates the value of its argument, while
2800
    the argument can be any, e.g. a subselect. The subselect
2801
    items, in turn, assume that all the memory allocated during
2802
    the evaluation has the same life span as the item itself.
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
2803
    TODO: opitimizer/range.cc should not reset session->mem_root at all.
1 by brian
clean slate
2804
  */
520.1.22 by Brian Aker
Second pass of thd cleanup
2805
  param->session->mem_root= param->old_root;
1 by brian
clean slate
2806
  if (!value)					// IS NULL or IS NOT NULL
2807
  {
1660.1.3 by Brian Aker
Encapsulate Table in field
2808
    if (field->getTable()->maybe_null)		// Can't use a key on this
1 by brian
clean slate
2809
      goto end;
2810
    if (!maybe_null)				// Not null field
2811
    {
2812
      if (type == Item_func::ISNULL_FUNC)
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
2813
        tree= &optimizer::null_element;
1 by brian
clean slate
2814
      goto end;
2815
    }
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
2816
    if (!(tree= new (alloc) optimizer::SEL_ARG(field,is_null_string,is_null_string)))
1 by brian
clean slate
2817
      goto end;                                 // out of memory
2818
    if (type == Item_func::ISNOTNULL_FUNC)
2819
    {
2820
      tree->min_flag=NEAR_MIN;		    /* IS NOT NULL ->  X > NULL */
2821
      tree->max_flag=NO_MAX_RANGE;
2822
    }
2823
    goto end;
2824
  }
2825
2826
  /*
2827
    1. Usually we can't use an index if the column collation
2828
       differ from the operation collation.
2829
2830
    2. However, we can reuse a case insensitive index for
2831
       the binary searches:
2832
2833
       WHERE latin1_swedish_ci_column = 'a' COLLATE lati1_bin;
2834
2835
       WHERE latin1_swedish_ci_colimn = BINARY 'a '
2836
2837
  */
2838
  if (field->result_type() == STRING_RESULT &&
2839
      value->result_type() == STRING_RESULT &&
2840
      ((Field_str*)field)->charset() != conf_func->compare_collation() &&
2841
      !(conf_func->compare_collation()->state & MY_CS_BINSORT))
2842
    goto end;
2843
2844
  if (param->using_real_indexes)
2845
    optimize_range= field->optimize_range(param->real_keynr[key_part->key],
2846
                                          key_part->part);
2847
  else
55 by brian
Update for using real bool types.
2848
    optimize_range= true;
1 by brian
clean slate
2849
2850
  if (type == Item_func::LIKE_FUNC)
2851
  {
2852
    bool like_error;
2853
    char buff1[MAX_FIELD_WIDTH];
481 by Brian Aker
Remove all of uchar.
2854
    unsigned char *min_str,*max_str;
1 by brian
clean slate
2855
    String tmp(buff1,sizeof(buff1),value->collation.collation),*res;
2856
    size_t length, offset, min_length, max_length;
482 by Brian Aker
Remove uint.
2857
    uint32_t field_length= field->pack_length()+maybe_null;
1 by brian
clean slate
2858
2859
    if (!optimize_range)
2860
      goto end;
2861
    if (!(res= value->val_str(&tmp)))
2862
    {
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
2863
      tree= &optimizer::null_element;
1 by brian
clean slate
2864
      goto end;
2865
    }
2866
2867
    /*
2868
      TODO:
2869
      Check if this was a function. This should have be optimized away
2870
      in the sql_select.cc
2871
    */
2872
    if (res != &tmp)
2873
    {
2874
      tmp.copy(*res);				// Get own copy
2875
      res= &tmp;
2876
    }
2877
    if (field->cmp_type() != STRING_RESULT)
2878
      goto end;                                 // Can only optimize strings
2879
2880
    offset=maybe_null;
2881
    length=key_part->store_length;
2882
2883
    if (length != key_part->length  + maybe_null)
2884
    {
2885
      /* key packed with length prefix */
2886
      offset+= HA_KEY_BLOB_LENGTH;
2887
      field_length= length - HA_KEY_BLOB_LENGTH;
2888
    }
2889
    else
2890
    {
2891
      if (unlikely(length < field_length))
2892
      {
1485 by Brian Aker
Updates to confine memroot
2893
        /*
2894
          This can only happen in a table created with UNIREG where one key
2895
          overlaps many fields
2896
        */
2897
        length= field_length;
1 by brian
clean slate
2898
      }
2899
      else
1485 by Brian Aker
Updates to confine memroot
2900
        field_length= length;
1 by brian
clean slate
2901
    }
2902
    length+=offset;
1485 by Brian Aker
Updates to confine memroot
2903
    if (!(min_str= (unsigned char*) alloc->alloc_root(length*2)))
2904
    {
1 by brian
clean slate
2905
      goto end;
1485 by Brian Aker
Updates to confine memroot
2906
    }
1 by brian
clean slate
2907
2908
    max_str=min_str+length;
2909
    if (maybe_null)
2910
      max_str[0]= min_str[0]=0;
2911
2912
    field_length-= maybe_null;
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
2913
    int escape_code= make_escape_code(field->charset(),
2914
                                      ((Item_func_like*)(param->cond))->escape);
1 by brian
clean slate
2915
    like_error= my_like_range(field->charset(),
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
2916
                              res->ptr(), res->length(),
1054.2.11 by Monty Taylor
Removed copy_and_convert.
2917
                              escape_code,
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
2918
                              internal::wild_one, internal::wild_many,
2919
                              field_length,
2920
                              (char*) min_str+offset, (char*) max_str+offset,
2921
                              &min_length, &max_length);
1 by brian
clean slate
2922
    if (like_error)				// Can't optimize with LIKE
2923
      goto end;
2924
2925
    if (offset != maybe_null)			// BLOB or VARCHAR
2926
    {
2927
      int2store(min_str+maybe_null,min_length);
2928
      int2store(max_str+maybe_null,max_length);
2929
    }
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
2930
    tree= new (alloc) optimizer::SEL_ARG(field, min_str, max_str);
1 by brian
clean slate
2931
    goto end;
2932
  }
2933
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
2934
  if (! optimize_range &&
1 by brian
clean slate
2935
      type != Item_func::EQ_FUNC &&
2936
      type != Item_func::EQUAL_FUNC)
2937
    goto end;                                   // Can't optimize this
2938
2939
  /*
2940
    We can't always use indexes when comparing a string index to a number
2941
    cmp_type() is checked to allow compare of dates to numbers
2942
  */
2943
  if (field->result_type() == STRING_RESULT &&
2944
      value->result_type() != STRING_RESULT &&
2945
      field->cmp_type() != value->result_type())
2946
    goto end;
907.1.7 by Jay Pipes
Merged in remove-timezone work
2947
2948
  /*
2949
   * Some notes from Jay...
2950
   *
2951
   * OK, so previously, and in MySQL, what the optimizer does here is
2952
   * override the sql_mode variable to ignore out-of-range or bad date-
2953
   * time values.  It does this because the optimizer is populating the
1240.3.1 by Brian Aker
Merge Padraig.
2954
   * field variable with the incoming value from the comparison field,
907.1.7 by Jay Pipes
Merged in remove-timezone work
2955
   * and the value may exceed the bounds of a proper column type.
2956
   *
2957
   * For instance, assume the following:
2958
   *
1240.3.1 by Brian Aker
Merge Padraig.
2959
   * CREATE TABLE t1 (ts TIMESTAMP);
907.1.7 by Jay Pipes
Merged in remove-timezone work
2960
   * INSERT INTO t1 ('2009-03-04 00:00:00');
1240.3.1 by Brian Aker
Merge Padraig.
2961
   * CREATE TABLE t2 (dt1 DATETIME, dt2 DATETIME);
907.1.7 by Jay Pipes
Merged in remove-timezone work
2962
   * INSERT INT t2 ('2003-12-31 00:00:00','2999-12-31 00:00:00');
2963
   *
2964
   * If we issue this query:
2965
   *
2966
   * SELECT * FROM t1, t2 WHERE t1.ts BETWEEN t2.dt1 AND t2.dt2;
2967
   *
2968
   * We will come into bounds issues.  Field_timestamp::store() will be
2969
   * called with a datetime value of "2999-12-31 00:00:00" and will throw
2970
   * an error for out-of-bounds.  MySQL solves this via a hack with sql_mode
2971
   * but Drizzle always throws errors on bad data storage in a Field class.
2972
   *
2973
   * Therefore, to get around the problem of the Field class being used for
1240.3.1 by Brian Aker
Merge Padraig.
2974
   * "storage" here without actually storing anything...we must check to see
907.1.7 by Jay Pipes
Merged in remove-timezone work
2975
   * if the value being stored in a Field_timestamp here is out of range.  If
2976
   * it is, then we must convert to the highest Timestamp value (or lowest,
2977
   * depending on whether the datetime is before or after the epoch.
2978
   */
2979
  if (field->type() == DRIZZLE_TYPE_TIMESTAMP)
2980
  {
1240.3.1 by Brian Aker
Merge Padraig.
2981
    /*
2982
     * The left-side of the range comparison is a timestamp field.  Therefore,
907.1.7 by Jay Pipes
Merged in remove-timezone work
2983
     * we must check to see if the value in the right-hand side is outside the
2984
     * range of the UNIX epoch, and cut to the epoch bounds if it is.
2985
     */
2986
    /* Datetime and date columns are Item::FIELD_ITEM ... and have a result type of STRING_RESULT */
2987
    if (value->real_item()->type() == Item::FIELD_ITEM
2988
        && value->result_type() == STRING_RESULT)
2989
    {
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
2990
      char buff[DateTime::MAX_STRING_LENGTH];
907.1.7 by Jay Pipes
Merged in remove-timezone work
2991
      String tmp(buff, sizeof(buff), &my_charset_bin);
2992
      String *res= value->val_str(&tmp);
2993
2994
      if (!res)
2995
        goto end;
2996
      else
2997
      {
1240.3.1 by Brian Aker
Merge Padraig.
2998
        /*
907.1.7 by Jay Pipes
Merged in remove-timezone work
2999
         * Create a datetime from the string and compare to fixed timestamp
3000
         * instances representing the epoch boundaries.
3001
         */
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
3002
        DateTime value_datetime;
907.1.7 by Jay Pipes
Merged in remove-timezone work
3003
3004
        if (! value_datetime.from_string(res->c_ptr(), (size_t) res->length()))
3005
          goto end;
3006
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
3007
        Timestamp max_timestamp;
3008
        Timestamp min_timestamp;
907.1.7 by Jay Pipes
Merged in remove-timezone work
3009
3010
        (void) max_timestamp.from_time_t((time_t) INT32_MAX);
3011
        (void) min_timestamp.from_time_t((time_t) 0);
3012
3013
        /* We rely on Temporal class operator overloads to do our comparisons. */
3014
        if (value_datetime < min_timestamp)
3015
        {
1240.3.1 by Brian Aker
Merge Padraig.
3016
          /*
907.1.7 by Jay Pipes
Merged in remove-timezone work
3017
           * Datetime in right-hand side column is before UNIX epoch, so adjust to
3018
           * lower bound.
3019
           */
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
3020
          char new_value_buff[DateTime::MAX_STRING_LENGTH];
1079.3.2 by Stewart Smith
Replace MAX_(DATE|TIME).*_WIDTH defines in definitions.h with real (and correct) static const members to Temporal types.
3021
          int new_value_length;
907.1.7 by Jay Pipes
Merged in remove-timezone work
3022
          String new_value_string(new_value_buff, sizeof(new_value_buff), &my_charset_bin);
3023
1079.3.1 by Stewart Smith
Change temporal to_string routines to use snprintf instead of sprintf.
3024
          new_value_length= min_timestamp.to_string(new_value_string.c_ptr(),
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
3025
				    DateTime::MAX_STRING_LENGTH);
3026
	  assert((new_value_length+1) < DateTime::MAX_STRING_LENGTH);
907.1.7 by Jay Pipes
Merged in remove-timezone work
3027
          new_value_string.length(new_value_length);
3028
          err= value->save_str_value_in_field(field, &new_value_string);
3029
        }
3030
        else if (value_datetime > max_timestamp)
3031
        {
3032
          /*
3033
           * Datetime in right hand side column is after UNIX epoch, so adjust
3034
           * to the higher bound of the epoch.
3035
           */
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
3036
          char new_value_buff[DateTime::MAX_STRING_LENGTH];
1079.3.1 by Stewart Smith
Change temporal to_string routines to use snprintf instead of sprintf.
3037
          int new_value_length;
907.1.7 by Jay Pipes
Merged in remove-timezone work
3038
          String new_value_string(new_value_buff, sizeof(new_value_buff), &my_charset_bin);
3039
1079.3.1 by Stewart Smith
Change temporal to_string routines to use snprintf instead of sprintf.
3040
          new_value_length= max_timestamp.to_string(new_value_string.c_ptr(),
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
3041
					DateTime::MAX_STRING_LENGTH);
3042
	  assert((new_value_length+1) < DateTime::MAX_STRING_LENGTH);
907.1.7 by Jay Pipes
Merged in remove-timezone work
3043
          new_value_string.length(new_value_length);
3044
          err= value->save_str_value_in_field(field, &new_value_string);
3045
        }
3046
        else
3047
          err= value->save_in_field(field, 1);
3048
      }
3049
    }
3050
    else /* Not a datetime -> timestamp comparison */
3051
      err= value->save_in_field(field, 1);
3052
  }
3053
  else /* Not a timestamp comparison */
3054
    err= value->save_in_field(field, 1);
3055
1 by brian
clean slate
3056
  if (err > 0)
3057
  {
3058
    if (field->cmp_type() != value->result_type())
3059
    {
3060
      if ((type == Item_func::EQ_FUNC || type == Item_func::EQUAL_FUNC) &&
3061
          value->result_type() == item_cmp_type(field->result_type(),
3062
                                                value->result_type()))
3063
      {
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3064
        tree= new (alloc) optimizer::SEL_ARG(field, 0, 0);
3065
        tree->type= optimizer::SEL_ARG::IMPOSSIBLE;
1 by brian
clean slate
3066
        goto end;
3067
      }
3068
      else
3069
      {
3070
        /*
3071
          TODO: We should return trees of the type SEL_ARG::IMPOSSIBLE
3072
          for the cases like int_field > 999999999999999999999999 as well.
3073
        */
3074
        tree= 0;
575.5.1 by David Axmark
Changed NEWDATE to DATE. One failing test but I think its somewhere else in the code
3075
        if (err == 3 && field->type() == DRIZZLE_TYPE_DATE &&
1 by brian
clean slate
3076
            (type == Item_func::GT_FUNC || type == Item_func::GE_FUNC ||
3077
             type == Item_func::LT_FUNC || type == Item_func::LE_FUNC) )
3078
        {
3079
          /*
3080
            We were saving DATETIME into a DATE column, the conversion went ok
3081
            but a non-zero time part was cut off.
3082
3083
            In MySQL's SQL dialect, DATE and DATETIME are compared as datetime
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3084
            values. Index over a DATE column uses DATE comparison. Changing
1 by brian
clean slate
3085
            from one comparison to the other is possible:
3086
3087
            datetime(date_col)< '2007-12-10 12:34:55' -> date_col<='2007-12-10'
3088
            datetime(date_col)<='2007-12-10 12:34:55' -> date_col<='2007-12-10'
3089
3090
            datetime(date_col)> '2007-12-10 12:34:55' -> date_col>='2007-12-10'
3091
            datetime(date_col)>='2007-12-10 12:34:55' -> date_col>='2007-12-10'
3092
3093
            but we'll need to convert '>' to '>=' and '<' to '<='. This will
3094
            be done together with other types at the end of this function
3095
            (grep for field_is_equal_to_item)
3096
          */
3097
        }
3098
        else
3099
          goto end;
3100
      }
3101
    }
3102
3103
    /*
3104
      guaranteed at this point:  err > 0; field and const of same type
3105
      If an integer got bounded (e.g. to within 0..255 / -128..127)
3106
      for < or >, set flags as for <= or >= (no NEAR_MAX / NEAR_MIN)
3107
    */
3108
    else if (err == 1 && field->result_type() == INT_RESULT)
3109
    {
3110
      if (type == Item_func::LT_FUNC && (value->val_int() > 0))
3111
        type = Item_func::LE_FUNC;
3112
      else if (type == Item_func::GT_FUNC &&
3113
               !((Field_num*)field)->unsigned_flag &&
3114
               !((Item_int*)value)->unsigned_flag &&
3115
               (value->val_int() < 0))
3116
        type = Item_func::GE_FUNC;
3117
    }
3118
  }
3119
  else if (err < 0)
3120
  {
3121
    /* This happens when we try to insert a NULL field in a not null column */
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3122
    tree= &optimizer::null_element;                        // cmp with NULL is never true
1 by brian
clean slate
3123
    goto end;
3124
  }
1685.7.1 by Prafulla Tekawade
Fix for Bug 586051
3125
3126
  /*
3127
    Any predicate except "<=>"(null-safe equality operator) involving NULL as a
3128
    constant is always FALSE
3129
    Put IMPOSSIBLE Tree(null_element) here.
3130
  */  
3131
  if (type != Item_func::EQUAL_FUNC && field->is_real_null())
3132
  {
3133
    tree= &optimizer::null_element;
3134
    goto end;
3135
  }
3136
1485 by Brian Aker
Updates to confine memroot
3137
  str= (unsigned char*) alloc->alloc_root(key_part->store_length+1);
1 by brian
clean slate
3138
  if (!str)
3139
    goto end;
3140
  if (maybe_null)
481 by Brian Aker
Remove all of uchar.
3141
    *str= (unsigned char) field->is_real_null();        // Set to 1 if null
1055.2.5 by Jay Pipes
Removal of dead Field::image_type and st_key_part::image_type member variables. Legacy from geometry MyISAM types...
3142
  field->get_key_image(str+maybe_null, key_part->length);
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3143
  if (! (tree= new (alloc) optimizer::SEL_ARG(field, str, str)))
3144
    goto end; // out of memory
1 by brian
clean slate
3145
3146
  /*
3147
    Check if we are comparing an UNSIGNED integer with a negative constant.
3148
    In this case we know that:
55 by brian
Update for using real bool types.
3149
    (a) (unsigned_int [< | <=] negative_constant) == false
3150
    (b) (unsigned_int [> | >=] negative_constant) == true
1 by brian
clean slate
3151
    In case (a) the condition is false for all values, and in case (b) it
3152
    is true for all values, so we can avoid unnecessary retrieval and condition
3153
    testing, and we also get correct comparison of unsinged integers with
3154
    negative integers (which otherwise fails because at query execution time
3155
    negative integers are cast to unsigned if compared with unsigned).
3156
   */
3157
  if (field->result_type() == INT_RESULT &&
3158
      value->result_type() == INT_RESULT &&
3159
      ((Field_num*)field)->unsigned_flag && !((Item_int*)value)->unsigned_flag)
3160
  {
152 by Brian Aker
longlong replacement
3161
    int64_t item_val= value->val_int();
1 by brian
clean slate
3162
    if (item_val < 0)
3163
    {
3164
      if (type == Item_func::LT_FUNC || type == Item_func::LE_FUNC)
3165
      {
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3166
        tree->type= optimizer::SEL_ARG::IMPOSSIBLE;
1 by brian
clean slate
3167
        goto end;
3168
      }
3169
      if (type == Item_func::GT_FUNC || type == Item_func::GE_FUNC)
3170
      {
3171
        tree= 0;
3172
        goto end;
3173
      }
3174
    }
3175
  }
3176
3177
  switch (type) {
3178
  case Item_func::LT_FUNC:
3179
    if (field_is_equal_to_item(field,value))
3180
      tree->max_flag=NEAR_MAX;
3181
    /* fall through */
3182
  case Item_func::LE_FUNC:
3183
    if (!maybe_null)
3184
      tree->min_flag=NO_MIN_RANGE;		/* From start */
3185
    else
3186
    {						// > NULL
3187
      tree->min_value=is_null_string;
3188
      tree->min_flag=NEAR_MIN;
3189
    }
3190
    break;
3191
  case Item_func::GT_FUNC:
3192
    /* Don't use open ranges for partial key_segments */
3193
    if (field_is_equal_to_item(field,value) &&
3194
        !(key_part->flag & HA_PART_KEY_SEG))
3195
      tree->min_flag=NEAR_MIN;
3196
    /* fall through */
3197
  case Item_func::GE_FUNC:
3198
    tree->max_flag=NO_MAX_RANGE;
3199
    break;
3200
  default:
3201
    break;
3202
  }
3203
3204
end:
520.1.22 by Brian Aker
Second pass of thd cleanup
3205
  param->session->mem_root= alloc;
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
3206
  return(tree);
1 by brian
clean slate
3207
}
3208
3209
3210
/******************************************************************************
3211
** Tree manipulation functions
3212
** If tree is 0 it means that the condition can't be tested. It refers
3213
** to a non existent table or to a field in current table with isn't a key.
3214
** The different tree flags:
55 by brian
Update for using real bool types.
3215
** IMPOSSIBLE:	 Condition is never true
3216
** ALWAYS:	 Condition is always true
1 by brian
clean slate
3217
** MAYBE:	 Condition may exists when tables are read
3218
** MAYBE_KEY:	 Condition refers to a key that may be used in join loop
3219
** KEY_RANGE:	 Condition uses a key
3220
******************************************************************************/
3221
3222
/*
3223
  Add a new key test to a key when scanning through all keys
3224
  This will never be called for same key parts.
3225
*/
3226
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3227
static optimizer::SEL_ARG *
3228
sel_add(optimizer::SEL_ARG *key1, optimizer::SEL_ARG *key2)
1 by brian
clean slate
3229
{
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3230
  optimizer::SEL_ARG *root= NULL;
3231
  optimizer::SEL_ARG **key_link= NULL;
1 by brian
clean slate
3232
3233
  if (!key1)
3234
    return key2;
3235
  if (!key2)
3236
    return key1;
3237
3238
  key_link= &root;
3239
  while (key1 && key2)
3240
  {
3241
    if (key1->part < key2->part)
3242
    {
3243
      *key_link= key1;
3244
      key_link= &key1->next_key_part;
3245
      key1=key1->next_key_part;
3246
    }
3247
    else
3248
    {
3249
      *key_link= key2;
3250
      key_link= &key2->next_key_part;
3251
      key2=key2->next_key_part;
3252
    }
3253
  }
3254
  *key_link=key1 ? key1 : key2;
3255
  return root;
3256
}
3257
3258
#define CLONE_KEY1_MAYBE 1
3259
#define CLONE_KEY2_MAYBE 2
3260
#define swap_clone_flag(A) ((A & 1) << 1) | ((A & 2) >> 1)
3261
3262
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
3263
static optimizer::SEL_TREE *
3264
tree_and(optimizer::RangeParameter *param, optimizer::SEL_TREE *tree1, optimizer::SEL_TREE *tree2)
1 by brian
clean slate
3265
{
3266
  if (!tree1)
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
3267
    return(tree2);
1 by brian
clean slate
3268
  if (!tree2)
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
3269
    return(tree1);
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
3270
  if (tree1->type == optimizer::SEL_TREE::IMPOSSIBLE || tree2->type == optimizer::SEL_TREE::ALWAYS)
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
3271
    return(tree1);
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
3272
  if (tree2->type == optimizer::SEL_TREE::IMPOSSIBLE || tree1->type == optimizer::SEL_TREE::ALWAYS)
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
3273
    return(tree2);
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
3274
  if (tree1->type == optimizer::SEL_TREE::MAYBE)
1 by brian
clean slate
3275
  {
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
3276
    if (tree2->type == optimizer::SEL_TREE::KEY)
3277
      tree2->type=optimizer::SEL_TREE::KEY_SMALLER;
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
3278
    return(tree2);
1 by brian
clean slate
3279
  }
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
3280
  if (tree2->type == optimizer::SEL_TREE::MAYBE)
1 by brian
clean slate
3281
  {
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
3282
    tree1->type=optimizer::SEL_TREE::KEY_SMALLER;
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
3283
    return(tree1);
1 by brian
clean slate
3284
  }
3285
  key_map  result_keys;
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
3286
  result_keys.reset();
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3287
1 by brian
clean slate
3288
  /* Join the trees key per key */
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3289
  optimizer::SEL_ARG **key1,**key2,**end;
1 by brian
clean slate
3290
  for (key1= tree1->keys,key2= tree2->keys,end=key1+param->keys ;
3291
       key1 != end ; key1++,key2++)
3292
  {
482 by Brian Aker
Remove uint.
3293
    uint32_t flag=0;
1 by brian
clean slate
3294
    if (*key1 || *key2)
3295
    {
3296
      if (*key1 && !(*key1)->simple_key())
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3297
        flag|=CLONE_KEY1_MAYBE;
1 by brian
clean slate
3298
      if (*key2 && !(*key2)->simple_key())
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3299
        flag|=CLONE_KEY2_MAYBE;
1 by brian
clean slate
3300
      *key1=key_and(param, *key1, *key2, flag);
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3301
      if (*key1 && (*key1)->type == optimizer::SEL_ARG::IMPOSSIBLE)
1 by brian
clean slate
3302
      {
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
3303
        tree1->type= optimizer::SEL_TREE::IMPOSSIBLE;
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
3304
        return(tree1);
1 by brian
clean slate
3305
      }
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
3306
      result_keys.set(key1 - tree1->keys);
1 by brian
clean slate
3307
    }
3308
  }
3309
  tree1->keys_map= result_keys;
3310
  /* dispose index_merge if there is a "range" option */
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
3311
  if (result_keys.any())
1 by brian
clean slate
3312
  {
1211 by Brian Aker
Reverses old patch which introduced memory leaks. Also found a solution
3313
    tree1->merges.empty();
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
3314
    return(tree1);
1 by brian
clean slate
3315
  }
3316
3317
  /* ok, both trees are index_merge trees */
1211 by Brian Aker
Reverses old patch which introduced memory leaks. Also found a solution
3318
  imerge_list_and_list(&tree1->merges, &tree2->merges);
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
3319
  return(tree1);
1 by brian
clean slate
3320
}
3321
3322
3323
3324
/* And key trees where key1->part < key2 -> part */
3325
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3326
static optimizer::SEL_ARG *
1240.3.1 by Brian Aker
Merge Padraig.
3327
and_all_keys(optimizer::RangeParameter *param,
3328
             optimizer::SEL_ARG *key1,
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3329
             optimizer::SEL_ARG *key2,
482 by Brian Aker
Remove uint.
3330
             uint32_t clone_flag)
1 by brian
clean slate
3331
{
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3332
  optimizer::SEL_ARG *next= NULL;
1 by brian
clean slate
3333
  ulong use_count=key1->use_count;
3334
3335
  if (key1->elements != 1)
3336
  {
3337
    key2->use_count+=key1->elements-1; //psergey: why we don't count that key1 has n-k-p?
3338
    key2->increment_use_count((int) key1->elements-1);
3339
  }
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3340
  if (key1->type == optimizer::SEL_ARG::MAYBE_KEY)
1 by brian
clean slate
3341
  {
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3342
    key1->right= key1->left= &optimizer::null_element;
1 by brian
clean slate
3343
    key1->next= key1->prev= 0;
3344
  }
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3345
  for (next= key1->first(); next ; next=next->next)
1 by brian
clean slate
3346
  {
3347
    if (next->next_key_part)
3348
    {
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3349
      optimizer::SEL_ARG *tmp= key_and(param, next->next_key_part, key2, clone_flag);
3350
      if (tmp && tmp->type == optimizer::SEL_ARG::IMPOSSIBLE)
1 by brian
clean slate
3351
      {
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3352
        key1=key1->tree_delete(next);
3353
        continue;
1 by brian
clean slate
3354
      }
3355
      next->next_key_part=tmp;
3356
      if (use_count)
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3357
        next->increment_use_count(use_count);
3358
      if (param->alloced_sel_args > optimizer::SEL_ARG::MAX_SEL_ARGS)
1 by brian
clean slate
3359
        break;
3360
    }
3361
    else
3362
      next->next_key_part=key2;
3363
  }
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3364
  if (! key1)
3365
    return &optimizer::null_element;			// Impossible ranges
1 by brian
clean slate
3366
  key1->use_count++;
3367
  return key1;
3368
}
3369
3370
3371
/*
3372
  Produce a SEL_ARG graph that represents "key1 AND key2"
3373
3374
  SYNOPSIS
3375
    key_and()
3376
      param   Range analysis context (needed to track if we have allocated
3377
              too many SEL_ARGs)
3378
      key1    First argument, root of its RB-tree
3379
      key2    Second argument, root of its RB-tree
3380
3381
  RETURN
3382
    RB-tree root of the resulting SEL_ARG graph.
3383
    NULL if the result of AND operation is an empty interval {0}.
3384
*/
3385
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3386
static optimizer::SEL_ARG *
1240.3.1 by Brian Aker
Merge Padraig.
3387
key_and(optimizer::RangeParameter *param,
3388
        optimizer::SEL_ARG *key1,
3389
        optimizer::SEL_ARG *key2,
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3390
        uint32_t clone_flag)
1 by brian
clean slate
3391
{
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3392
  if (! key1)
1 by brian
clean slate
3393
    return key2;
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3394
  if (! key2)
1 by brian
clean slate
3395
    return key1;
3396
  if (key1->part != key2->part)
3397
  {
3398
    if (key1->part > key2->part)
3399
    {
322.2.2 by Mats Kindahl
Hiding THD::proc_info field and providing a setter and getter.
3400
      std::swap(key1, key2);
1 by brian
clean slate
3401
      clone_flag=swap_clone_flag(clone_flag);
3402
    }
3403
    // key1->part < key2->part
3404
    key1->use_count--;
3405
    if (key1->use_count > 0)
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3406
      if (! (key1= key1->clone_tree(param)))
3407
        return 0;				// OOM
1 by brian
clean slate
3408
    return and_all_keys(param, key1, key2, clone_flag);
3409
  }
3410
3411
  if (((clone_flag & CLONE_KEY2_MAYBE) &&
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3412
       ! (clone_flag & CLONE_KEY1_MAYBE) &&
3413
       key2->type != optimizer::SEL_ARG::MAYBE_KEY) ||
3414
      key1->type == optimizer::SEL_ARG::MAYBE_KEY)
1 by brian
clean slate
3415
  {						// Put simple key in key2
322.2.2 by Mats Kindahl
Hiding THD::proc_info field and providing a setter and getter.
3416
    std::swap(key1, key2);
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3417
    clone_flag= swap_clone_flag(clone_flag);
1 by brian
clean slate
3418
  }
3419
3420
  /* If one of the key is MAYBE_KEY then the found region may be smaller */
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3421
  if (key2->type == optimizer::SEL_ARG::MAYBE_KEY)
1 by brian
clean slate
3422
  {
3423
    if (key1->use_count > 1)
3424
    {
3425
      key1->use_count--;
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3426
      if (! (key1=key1->clone_tree(param)))
3427
        return 0;				// OOM
1 by brian
clean slate
3428
      key1->use_count++;
3429
    }
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3430
    if (key1->type == optimizer::SEL_ARG::MAYBE_KEY)
1 by brian
clean slate
3431
    {						// Both are maybe key
1240.3.1 by Brian Aker
Merge Padraig.
3432
      key1->next_key_part= key_and(param,
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3433
                                   key1->next_key_part,
1240.3.1 by Brian Aker
Merge Padraig.
3434
                                   key2->next_key_part,
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3435
                                   clone_flag);
1 by brian
clean slate
3436
      if (key1->next_key_part &&
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3437
          key1->next_key_part->type == optimizer::SEL_ARG::IMPOSSIBLE)
3438
        return key1;
1 by brian
clean slate
3439
    }
3440
    else
3441
    {
3442
      key1->maybe_smaller();
3443
      if (key2->next_key_part)
3444
      {
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3445
        key1->use_count--;			// Incremented in and_all_keys
3446
        return and_all_keys(param, key1, key2, clone_flag);
1 by brian
clean slate
3447
      }
3448
      key2->use_count--;			// Key2 doesn't have a tree
3449
    }
3450
    return key1;
3451
  }
3452
3453
  key1->use_count--;
3454
  key2->use_count--;
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3455
  optimizer::SEL_ARG *e1= key1->first();
3456
  optimizer::SEL_ARG *e2= key2->first();
3457
  optimizer::SEL_ARG *new_tree= NULL;
1 by brian
clean slate
3458
3459
  while (e1 && e2)
3460
  {
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3461
    int cmp= e1->cmp_min_to_min(e2);
1 by brian
clean slate
3462
    if (cmp < 0)
3463
    {
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3464
      if (get_range(&e1, &e2, key1))
3465
        continue;
1 by brian
clean slate
3466
    }
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3467
    else if (get_range(&e2, &e1, key2))
1 by brian
clean slate
3468
      continue;
1240.3.1 by Brian Aker
Merge Padraig.
3469
    optimizer::SEL_ARG *next= key_and(param,
3470
                                      e1->next_key_part,
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3471
                                      e2->next_key_part,
3472
                                      clone_flag);
1 by brian
clean slate
3473
    e1->increment_use_count(1);
3474
    e2->increment_use_count(1);
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3475
    if (! next || next->type != optimizer::SEL_ARG::IMPOSSIBLE)
1 by brian
clean slate
3476
    {
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3477
      optimizer::SEL_ARG *new_arg= e1->clone_and(e2);
3478
      if (! new_arg)
3479
        return &optimizer::null_element;			// End of memory
1 by brian
clean slate
3480
      new_arg->next_key_part=next;
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3481
      if (! new_tree)
1 by brian
clean slate
3482
      {
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3483
        new_tree=new_arg;
1 by brian
clean slate
3484
      }
3485
      else
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3486
        new_tree=new_tree->insert(new_arg);
1 by brian
clean slate
3487
    }
3488
    if (e1->cmp_max_to_max(e2) < 0)
3489
      e1=e1->next;				// e1 can't overlapp next e2
3490
    else
3491
      e2=e2->next;
3492
  }
3493
  key1->free_tree();
3494
  key2->free_tree();
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3495
  if (! new_tree)
3496
    return &optimizer::null_element;			// Impossible range
1 by brian
clean slate
3497
  return new_tree;
3498
}
3499
3500
3501
static bool
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3502
get_range(optimizer::SEL_ARG **e1, optimizer::SEL_ARG **e2, optimizer::SEL_ARG *root1)
1 by brian
clean slate
3503
{
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3504
  (*e1)= root1->find_range(*e2);			// first e1->min < e2->min
1 by brian
clean slate
3505
  if ((*e1)->cmp_max_to_min(*e2) < 0)
3506
  {
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3507
    if (! ((*e1)=(*e1)->next))
1 by brian
clean slate
3508
      return 1;
3509
    if ((*e1)->cmp_min_to_max(*e2) > 0)
3510
    {
3511
      (*e2)=(*e2)->next;
3512
      return 1;
3513
    }
3514
  }
3515
  return 0;
3516
}
3517
3518
3519
/****************************************************************************
3520
  MRR Range Sequence Interface implementation that walks a SEL_ARG* tree.
3521
 ****************************************************************************/
3522
3523
/* MRR range sequence, SEL_ARG* implementation: stack entry */
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3524
typedef struct st_range_seq_entry
1 by brian
clean slate
3525
{
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3526
  /*
1 by brian
clean slate
3527
    Pointers in min and max keys. They point to right-after-end of key
3528
    images. The 0-th entry has these pointing to key tuple start.
3529
  */
481 by Brian Aker
Remove all of uchar.
3530
  unsigned char *min_key, *max_key;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3531
3532
  /*
1 by brian
clean slate
3533
    Flags, for {keypart0, keypart1, ... this_keypart} subtuple.
3534
    min_key_flag may have NULL_RANGE set.
3535
  */
482 by Brian Aker
Remove uint.
3536
  uint32_t min_key_flag, max_key_flag;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3537
1 by brian
clean slate
3538
  /* Number of key parts */
482 by Brian Aker
Remove uint.
3539
  uint32_t min_key_parts, max_key_parts;
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3540
  optimizer::SEL_ARG *key_tree;
1 by brian
clean slate
3541
} RANGE_SEQ_ENTRY;
3542
3543
3544
/*
3545
  MRR range sequence, SEL_ARG* implementation: SEL_ARG graph traversal context
3546
*/
3547
typedef struct st_sel_arg_range_seq
3548
{
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
3549
  uint32_t keyno;      /* index of used tree in optimizer::SEL_TREE structure */
482 by Brian Aker
Remove uint.
3550
  uint32_t real_keyno; /* Number of the index in tables */
1237.13.7 by Padraig O'Sullivan
Renamed PARAM to Parameter and RANGE_OPT_PARAM to RangeParameter.
3551
  optimizer::Parameter *param;
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3552
  optimizer::SEL_ARG *start; /* Root node of the traversed SEL_ARG* graph */
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3553
1 by brian
clean slate
3554
  RANGE_SEQ_ENTRY stack[MAX_REF_PARTS];
3555
  int i; /* Index of last used element in the above array */
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3556
55 by brian
Update for using real bool types.
3557
  bool at_start; /* true <=> The traversal has just started */
1 by brian
clean slate
3558
} SEL_ARG_RANGE_SEQ;
3559
3560
3561
/*
3562
  Range sequence interface, SEL_ARG* implementation: Initialize the traversal
3563
3564
  SYNOPSIS
3565
    init()
3566
      init_params  SEL_ARG tree traversal context
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3567
      n_ranges     [ignored] The number of ranges obtained
1 by brian
clean slate
3568
      flags        [ignored] HA_MRR_SINGLE_POINT, HA_MRR_FIXED_KEY
3569
3570
  RETURN
3571
    Value of init_param
3572
*/
3573
1085.1.2 by Monty Taylor
Fixed -Wmissing-declarations
3574
static range_seq_t sel_arg_range_seq_init(void *init_param, uint32_t, uint32_t)
1 by brian
clean slate
3575
{
3576
  SEL_ARG_RANGE_SEQ *seq= (SEL_ARG_RANGE_SEQ*)init_param;
55 by brian
Update for using real bool types.
3577
  seq->at_start= true;
1 by brian
clean slate
3578
  seq->stack[0].key_tree= NULL;
3579
  seq->stack[0].min_key= seq->param->min_key;
3580
  seq->stack[0].min_key_flag= 0;
3581
  seq->stack[0].min_key_parts= 0;
3582
3583
  seq->stack[0].max_key= seq->param->max_key;
3584
  seq->stack[0].max_key_flag= 0;
3585
  seq->stack[0].max_key_parts= 0;
3586
  seq->i= 0;
3587
  return init_param;
3588
}
3589
3590
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3591
static void step_down_to(SEL_ARG_RANGE_SEQ *arg, optimizer::SEL_ARG *key_tree)
1 by brian
clean slate
3592
{
3593
  RANGE_SEQ_ENTRY *cur= &arg->stack[arg->i+1];
3594
  RANGE_SEQ_ENTRY *prev= &arg->stack[arg->i];
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3595
1 by brian
clean slate
3596
  cur->key_tree= key_tree;
3597
  cur->min_key= prev->min_key;
3598
  cur->max_key= prev->max_key;
3599
  cur->min_key_parts= prev->min_key_parts;
3600
  cur->max_key_parts= prev->max_key_parts;
3601
206 by Brian Aker
Removed final uint dead types.
3602
  uint16_t stor_length= arg->param->key[arg->keyno][key_tree->part].store_length;
1 by brian
clean slate
3603
  cur->min_key_parts += key_tree->store_min(stor_length, &cur->min_key,
3604
                                            prev->min_key_flag);
3605
  cur->max_key_parts += key_tree->store_max(stor_length, &cur->max_key,
3606
                                            prev->max_key_flag);
3607
3608
  cur->min_key_flag= prev->min_key_flag | key_tree->min_flag;
3609
  cur->max_key_flag= prev->max_key_flag | key_tree->max_flag;
3610
3611
  if (key_tree->is_null_interval())
3612
    cur->min_key_flag |= NULL_RANGE;
3613
  (arg->i)++;
3614
}
3615
3616
3617
/*
3618
  Range sequence interface, SEL_ARG* implementation: get the next interval
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3619
1 by brian
clean slate
3620
  SYNOPSIS
3621
    sel_arg_range_seq_next()
3622
      rseq        Value returned from sel_arg_range_seq_init
3623
      range  OUT  Store information about the range here
3624
3625
  DESCRIPTION
3626
    This is "get_next" function for Range sequence interface implementation
3627
    for SEL_ARG* tree.
3628
3629
  IMPLEMENTATION
3630
    The traversal also updates those param members:
3631
      - is_ror_scan
3632
      - range_count
3633
      - max_key_part
3634
3635
  RETURN
3636
    0  Ok
3637
    1  No more ranges in the sequence
3638
*/
3639
3640
//psergey-merge-todo: support check_quick_keys:max_keypart
1085.1.2 by Monty Taylor
Fixed -Wmissing-declarations
3641
static uint32_t sel_arg_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range)
1 by brian
clean slate
3642
{
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3643
  optimizer::SEL_ARG *key_tree;
1 by brian
clean slate
3644
  SEL_ARG_RANGE_SEQ *seq= (SEL_ARG_RANGE_SEQ*)rseq;
3645
  if (seq->at_start)
3646
  {
3647
    key_tree= seq->start;
55 by brian
Update for using real bool types.
3648
    seq->at_start= false;
1 by brian
clean slate
3649
    goto walk_up_n_right;
3650
  }
3651
3652
  key_tree= seq->stack[seq->i].key_tree;
3653
  /* Ok, we're at some "full tuple" position in the tree */
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3654
1 by brian
clean slate
3655
  /* Step down if we can */
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3656
  if (key_tree->next && key_tree->next != &optimizer::null_element)
1 by brian
clean slate
3657
  {
3658
    //step down; (update the tuple, we'll step right and stay there)
3659
    seq->i--;
3660
    step_down_to(seq, key_tree->next);
3661
    key_tree= key_tree->next;
55 by brian
Update for using real bool types.
3662
    seq->param->is_ror_scan= false;
1 by brian
clean slate
3663
    goto walk_right_n_up;
3664
  }
3665
3666
  /* Ok, can't step down, walk left until we can step down */
3667
  while (1)
3668
  {
3669
    if (seq->i == 1) // can't step left
3670
      return 1;
3671
    /* Step left */
3672
    seq->i--;
3673
    key_tree= seq->stack[seq->i].key_tree;
3674
3675
    /* Step down if we can */
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3676
    if (key_tree->next && key_tree->next != &optimizer::null_element)
1 by brian
clean slate
3677
    {
3678
      // Step down; update the tuple
3679
      seq->i--;
3680
      step_down_to(seq, key_tree->next);
3681
      key_tree= key_tree->next;
3682
      break;
3683
    }
3684
  }
3685
3686
  /*
3687
    Ok, we've stepped down from the path to previous tuple.
3688
    Walk right-up while we can
3689
  */
3690
walk_right_n_up:
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3691
  while (key_tree->next_key_part && key_tree->next_key_part != &optimizer::null_element &&
1 by brian
clean slate
3692
         key_tree->next_key_part->part == key_tree->part + 1 &&
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3693
         key_tree->next_key_part->type == optimizer::SEL_ARG::KEY_RANGE)
1 by brian
clean slate
3694
  {
3695
    {
3696
      RANGE_SEQ_ENTRY *cur= &seq->stack[seq->i];
482 by Brian Aker
Remove uint.
3697
      uint32_t min_key_length= cur->min_key - seq->param->min_key;
3698
      uint32_t max_key_length= cur->max_key - seq->param->max_key;
3699
      uint32_t len= cur->min_key - cur[-1].min_key;
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3700
      if (! (min_key_length == max_key_length &&
3701
          ! memcmp(cur[-1].min_key, cur[-1].max_key, len) &&
3702
          ! key_tree->min_flag && !key_tree->max_flag))
1 by brian
clean slate
3703
      {
55 by brian
Update for using real bool types.
3704
        seq->param->is_ror_scan= false;
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3705
        if (! key_tree->min_flag)
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3706
          cur->min_key_parts +=
1 by brian
clean slate
3707
            key_tree->next_key_part->store_min_key(seq->param->key[seq->keyno],
3708
                                                   &cur->min_key,
3709
                                                   &cur->min_key_flag);
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3710
        if (! key_tree->max_flag)
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3711
          cur->max_key_parts +=
1 by brian
clean slate
3712
            key_tree->next_key_part->store_max_key(seq->param->key[seq->keyno],
3713
                                                   &cur->max_key,
3714
                                                   &cur->max_key_flag);
3715
        break;
3716
      }
3717
    }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3718
1 by brian
clean slate
3719
    /*
3720
      Ok, current atomic interval is in form "t.field=const" and there is
3721
      next_key_part interval. Step right, and walk up from there.
3722
    */
3723
    key_tree= key_tree->next_key_part;
3724
3725
walk_up_n_right:
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3726
    while (key_tree->prev && key_tree->prev != &optimizer::null_element)
1 by brian
clean slate
3727
    {
3728
      /* Step up */
3729
      key_tree= key_tree->prev;
3730
    }
3731
    step_down_to(seq, key_tree);
3732
  }
3733
3734
  /* Ok got a tuple */
3735
  RANGE_SEQ_ENTRY *cur= &seq->stack[seq->i];
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3736
1816.2.4 by Monty Taylor
Cleaned up a bunch more warnings.
3737
  range->ptr= (char*)(size_t)(key_tree->part);
1 by brian
clean slate
3738
  {
3739
    range->range_flag= cur->min_key_flag | cur->max_key_flag;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3740
1 by brian
clean slate
3741
    range->start_key.key=    seq->param->min_key;
3742
    range->start_key.length= cur->min_key - seq->param->min_key;
3743
    range->start_key.keypart_map= make_prev_keypart_map(cur->min_key_parts);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3744
    range->start_key.flag= (cur->min_key_flag & NEAR_MIN ? HA_READ_AFTER_KEY :
1 by brian
clean slate
3745
                                                           HA_READ_KEY_EXACT);
3746
3747
    range->end_key.key=    seq->param->max_key;
3748
    range->end_key.length= cur->max_key - seq->param->max_key;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3749
    range->end_key.flag= (cur->max_key_flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
1 by brian
clean slate
3750
                                                         HA_READ_AFTER_KEY);
3751
    range->end_key.keypart_map= make_prev_keypart_map(cur->max_key_parts);
3752
3753
    if (!(cur->min_key_flag & ~NULL_RANGE) && !cur->max_key_flag &&
895 by Brian Aker
Completion (?) of uint conversion.
3754
        (uint32_t)key_tree->part+1 == seq->param->table->key_info[seq->real_keyno].key_parts &&
53.2.14 by Monty Taylor
Removed HA_END_SPACE_KEY and references to it. It was _supposed_ to be gone anyway, but the ifdef around it was broken (MYSQL_VERSION_ID was actually undefined.)
3755
        (seq->param->table->key_info[seq->real_keyno].flags & (HA_NOSAME)) ==
1 by brian
clean slate
3756
        HA_NOSAME &&
3757
        range->start_key.length == range->end_key.length &&
3758
        !memcmp(seq->param->min_key,seq->param->max_key,range->start_key.length))
3759
      range->range_flag= UNIQUE_RANGE | (cur->min_key_flag & NULL_RANGE);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3760
1 by brian
clean slate
3761
    if (seq->param->is_ror_scan)
3762
    {
3763
      /*
3764
        If we get here, the condition on the key was converted to form
3765
        "(keyXpart1 = c1) AND ... AND (keyXpart{key_tree->part - 1} = cN) AND
3766
          somecond(keyXpart{key_tree->part})"
3767
        Check if
3768
          somecond is "keyXpart{key_tree->part} = const" and
3769
          uncovered "tail" of KeyX parts is either empty or is identical to
3770
          first members of clustered primary key.
3771
      */
3772
      if (!(!(cur->min_key_flag & ~NULL_RANGE) && !cur->max_key_flag &&
3773
            (range->start_key.length == range->end_key.length) &&
3774
            !memcmp(range->start_key.key, range->end_key.key, range->start_key.length) &&
3775
            is_key_scan_ror(seq->param, seq->real_keyno, key_tree->part + 1)))
55 by brian
Update for using real bool types.
3776
        seq->param->is_ror_scan= false;
1 by brian
clean slate
3777
    }
3778
  }
3779
  seq->param->range_count++;
1067.4.7 by Nathan Williams
The remaining files using cmax have been converted to std::max.
3780
  seq->param->max_key_part= max(seq->param->max_key_part,(uint32_t)key_tree->part);
1 by brian
clean slate
3781
  return 0;
3782
}
3783
3784
3785
/*
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3786
  Calculate cost and E(#rows) for a given index and intervals tree
1 by brian
clean slate
3787
3788
  SYNOPSIS
3789
    check_quick_select()
3790
      param             Parameter from test_quick_select
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
3791
      idx               Number of index to use in Parameter::key optimizer::SEL_TREE::key
55 by brian
Update for using real bool types.
3792
      index_only        true  - assume only index tuples will be accessed
3793
                        false - assume full table rows will be read
1 by brian
clean slate
3794
      tree              Transformed selection condition, tree->key[idx] holds
3795
                        the intervals for the given index.
55 by brian
Update for using real bool types.
3796
      update_tbl_stats  true <=> update table->quick_* with information
1 by brian
clean slate
3797
                        about range scan we've evaluated.
3798
      mrr_flags   INOUT MRR access flags
3799
      cost        OUT   Scan cost
3800
3801
  NOTES
3802
    param->is_ror_scan is set to reflect if the key scan is a ROR (see
3803
    is_key_scan_ror function for more info)
3804
    param->table->quick_*, param->range_count (and maybe others) are
3805
    updated with data of given key scan, see quick_range_seq_next for details.
3806
3807
  RETURN
3808
    Estimate # of records to be retrieved.
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
3809
    HA_POS_ERROR if estimate calculation failed due to table Cursor problems.
1 by brian
clean slate
3810
*/
3811
3812
static
1578.4.11 by Brian Aker
PAss through the code removing current_session
3813
ha_rows check_quick_select(Session *session,
3814
                           optimizer::Parameter *param,
1240.3.1 by Brian Aker
Merge Padraig.
3815
                           uint32_t idx,
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3816
                           bool index_only,
1240.3.1 by Brian Aker
Merge Padraig.
3817
                           optimizer::SEL_ARG *tree,
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3818
                           bool update_tbl_stats,
1240.3.1 by Brian Aker
Merge Padraig.
3819
                           uint32_t *mrr_flags,
3820
                           uint32_t *bufsize,
1336.3.2 by Djellel E. Difallah
rename class COST_VECT to CostVector and move it to ./drizzled/optimizer directory
3821
                           optimizer::CostVector *cost)
1 by brian
clean slate
3822
{
3823
  SEL_ARG_RANGE_SEQ seq;
3824
  RANGE_SEQ_IF seq_if = {sel_arg_range_seq_init, sel_arg_range_seq_next};
1208.3.2 by brian
Update for Cursor renaming.
3825
  Cursor *cursor= param->table->cursor;
1 by brian
clean slate
3826
  ha_rows rows;
482 by Brian Aker
Remove uint.
3827
  uint32_t keynr= param->real_keynr[idx];
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3828
1 by brian
clean slate
3829
  /* Handle cases when we don't have a valid non-empty list of range */
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3830
  if (! tree)
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
3831
    return(HA_POS_ERROR);
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3832
  if (tree->type == optimizer::SEL_ARG::IMPOSSIBLE)
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
3833
    return(0L);
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
3834
  if (tree->type != optimizer::SEL_ARG::KEY_RANGE || tree->part != 0)
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
3835
    return(HA_POS_ERROR);
1 by brian
clean slate
3836
3837
  seq.keyno= idx;
3838
  seq.real_keyno= keynr;
3839
  seq.param= param;
3840
  seq.start= tree;
3841
3842
  param->range_count=0;
3843
  param->max_key_part=0;
3844
55 by brian
Update for using real bool types.
3845
  param->is_ror_scan= true;
1235.1.14 by Brian Aker
Final move of index flags up to Engine (new interface still needed).
3846
  if (param->table->index_flags(keynr) & HA_KEY_SCAN_NOT_ROR)
55 by brian
Update for using real bool types.
3847
    param->is_ror_scan= false;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3848
1 by brian
clean slate
3849
  *mrr_flags= param->force_default_mrr? HA_MRR_USE_DEFAULT_IMPL: 0;
3850
  *mrr_flags|= HA_MRR_NO_ASSOCIATION;
3851
1208.3.2 by brian
Update for Cursor renaming.
3852
  bool pk_is_clustered= cursor->primary_key_is_clustered();
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3853
  if (index_only &&
1235.1.14 by Brian Aker
Final move of index flags up to Engine (new interface still needed).
3854
      (param->table->index_flags(keynr) & HA_KEYREAD_ONLY) &&
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
3855
      !(pk_is_clustered && keynr == param->table->getShare()->getPrimaryKey()))
1 by brian
clean slate
3856
     *mrr_flags |= HA_MRR_INDEX_ONLY;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3857
1578.4.11 by Brian Aker
PAss through the code removing current_session
3858
  if (session->lex->sql_command != SQLCOM_SELECT)
1 by brian
clean slate
3859
    *mrr_flags |= HA_MRR_USE_DEFAULT_IMPL;
3860
520.1.22 by Brian Aker
Second pass of thd cleanup
3861
  *bufsize= param->session->variables.read_rnd_buff_size;
1208.3.2 by brian
Update for Cursor renaming.
3862
  rows= cursor->multi_range_read_info_const(keynr, &seq_if, (void*)&seq, 0,
1 by brian
clean slate
3863
                                          bufsize, mrr_flags, cost);
3864
  if (rows != HA_POS_ERROR)
3865
  {
3866
    param->table->quick_rows[keynr]=rows;
3867
    if (update_tbl_stats)
3868
    {
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
3869
      param->table->quick_keys.set(keynr);
1 by brian
clean slate
3870
      param->table->quick_key_parts[keynr]=param->max_key_part+1;
3871
      param->table->quick_n_ranges[keynr]= param->range_count;
3872
      param->table->quick_condition_rows=
1067.4.4 by Nathan Williams
The rest of the files in the drizzled directory were purged of the cmin macro and replace with std::min (except for the definition in globals.h and 1 usage in stacktrace.cc).
3873
        min(param->table->quick_condition_rows, rows);
1 by brian
clean slate
3874
    }
3875
  }
3876
  /* Figure out if the key scan is ROR (returns rows in ROWID order) or not */
3877
  enum ha_key_alg key_alg= param->table->key_info[seq.real_keyno].algorithm;
3878
  if ((key_alg != HA_KEY_ALG_BTREE) && (key_alg!= HA_KEY_ALG_UNDEF))
3879
  {
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3880
    /*
1 by brian
clean slate
3881
      All scans are non-ROR scans for those index types.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3882
      TODO: Don't have this logic here, make table engines return
1 by brian
clean slate
3883
      appropriate flags instead.
3884
    */
55 by brian
Update for using real bool types.
3885
    param->is_ror_scan= false;
1 by brian
clean slate
3886
  }
3887
  else
3888
  {
3889
    /* Clustered PK scan is always a ROR scan (TODO: same as above) */
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
3890
    if (param->table->getShare()->getPrimaryKey() == keynr && pk_is_clustered)
55 by brian
Update for using real bool types.
3891
      param->is_ror_scan= true;
1 by brian
clean slate
3892
  }
3893
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
3894
  return(rows); //psergey-merge:todo: maintain first_null_comp.
1 by brian
clean slate
3895
}
3896
3897
3898
/*
3899
  Check if key scan on given index with equality conditions on first n key
3900
  parts is a ROR scan.
3901
3902
  SYNOPSIS
3903
    is_key_scan_ror()
3904
      param  Parameter from test_quick_select
3905
      keynr  Number of key in the table. The key must not be a clustered
3906
             primary key.
3907
      nparts Number of first key parts for which equality conditions
3908
             are present.
3909
3910
  NOTES
3911
    ROR (Rowid Ordered Retrieval) key scan is a key scan that produces
3912
    ordered sequence of rowids (ha_xxx::cmp_ref is the comparison function)
3913
3914
    This function is needed to handle a practically-important special case:
3915
    an index scan is a ROR scan if it is done using a condition in form
3916
3917
        "key1_1=c_1 AND ... AND key1_n=c_n"
3918
3919
    where the index is defined on (key1_1, ..., key1_N [,a_1, ..., a_n])
3920
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3921
    and the table has a clustered Primary Key defined as
3922
      PRIMARY KEY(a_1, ..., a_n, b1, ..., b_k)
3923
3924
    i.e. the first key parts of it are identical to uncovered parts ot the
1 by brian
clean slate
3925
    key being scanned. This function assumes that the index flags do not
3926
    include HA_KEY_SCAN_NOT_ROR flag (that is checked elsewhere).
3927
3928
    Check (1) is made in quick_range_seq_next()
3929
3930
  RETURN
55 by brian
Update for using real bool types.
3931
    true   The scan is ROR-scan
3932
    false  Otherwise
1 by brian
clean slate
3933
*/
3934
1237.13.7 by Padraig O'Sullivan
Renamed PARAM to Parameter and RANGE_OPT_PARAM to RangeParameter.
3935
static bool is_key_scan_ror(optimizer::Parameter *param, uint32_t keynr, uint8_t nparts)
1 by brian
clean slate
3936
{
1535 by Brian Aker
Rename of KEY to KeyInfo
3937
  KeyInfo *table_key= param->table->key_info + keynr;
1534 by Brian Aker
Remove of KeyPartInfo
3938
  KeyPartInfo *key_part= table_key->key_part + nparts;
3939
  KeyPartInfo *key_part_end= (table_key->key_part +
1 by brian
clean slate
3940
                                table_key->key_parts);
482 by Brian Aker
Remove uint.
3941
  uint32_t pk_number;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3942
1534 by Brian Aker
Remove of KeyPartInfo
3943
  for (KeyPartInfo *kp= table_key->key_part; kp < key_part; kp++)
1 by brian
clean slate
3944
  {
206 by Brian Aker
Removed final uint dead types.
3945
    uint16_t fieldnr= param->table->key_info[keynr].
1 by brian
clean slate
3946
                    key_part[kp - table_key->key_part].fieldnr - 1;
1578.2.16 by Brian Aker
Merge in change to getTable() to private the field objects.
3947
    if (param->table->getField(fieldnr)->key_length() != kp->length)
55 by brian
Update for using real bool types.
3948
      return false;
1 by brian
clean slate
3949
  }
3950
3951
  if (key_part == key_part_end)
55 by brian
Update for using real bool types.
3952
    return true;
1 by brian
clean slate
3953
3954
  key_part= table_key->key_part + nparts;
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
3955
  pk_number= param->table->getShare()->getPrimaryKey();
1208.3.2 by brian
Update for Cursor renaming.
3956
  if (!param->table->cursor->primary_key_is_clustered() || pk_number == MAX_KEY)
55 by brian
Update for using real bool types.
3957
    return false;
1 by brian
clean slate
3958
1534 by Brian Aker
Remove of KeyPartInfo
3959
  KeyPartInfo *pk_part= param->table->key_info[pk_number].key_part;
3960
  KeyPartInfo *pk_part_end= pk_part +
1 by brian
clean slate
3961
                              param->table->key_info[pk_number].key_parts;
3962
  for (;(key_part!=key_part_end) && (pk_part != pk_part_end);
3963
       ++key_part, ++pk_part)
3964
  {
3965
    if ((key_part->field != pk_part->field) ||
3966
        (key_part->length != pk_part->length))
55 by brian
Update for using real bool types.
3967
      return false;
1 by brian
clean slate
3968
  }
3969
  return (key_part == key_part_end);
3970
}
3971
3972
1237.13.2 by Padraig O'Sullivan
Modified the names of 2 classes in the optimizer to adhere to the coding standards.
3973
optimizer::QuickRangeSelect *
1237.13.7 by Padraig O'Sullivan
Renamed PARAM to Parameter and RANGE_OPT_PARAM to RangeParameter.
3974
optimizer::get_quick_select(Parameter *param,
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
3975
                            uint32_t idx,
1240.3.1 by Brian Aker
Merge Padraig.
3976
                            optimizer::SEL_ARG *key_tree,
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
3977
                            uint32_t mrr_flags,
1240.3.1 by Brian Aker
Merge Padraig.
3978
                            uint32_t mrr_buf_size,
1253.1.3 by Monty Taylor
MEM_ROOT == memory::Root
3979
                            memory::Root *parent_alloc)
1 by brian
clean slate
3980
{
1802.16.5 by Padraig O'Sullivan
Adding help method for dynamic bitset functions. Temporary until MyBitmap is removed. Got rid of another MyBitmap usage in the range optimizer.
3981
  optimizer::QuickRangeSelect *quick= new optimizer::QuickRangeSelect(param->session,
3982
                                                                      param->table,
3983
                                                                      param->real_keynr[idx],
3984
                                                                      test(parent_alloc),
3985
                                                                      NULL);
1 by brian
clean slate
3986
3987
  if (quick)
3988
  {
1802.16.5 by Padraig O'Sullivan
Adding help method for dynamic bitset functions. Temporary until MyBitmap is removed. Got rid of another MyBitmap usage in the range optimizer.
3989
	  if (get_quick_keys(param,
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
3990
                       quick,
3991
                       param->key[idx],
3992
                       key_tree,
3993
                       param->min_key,
3994
                       0,
3995
		                   param->max_key,
3996
                       0))
1 by brian
clean slate
3997
    {
3998
      delete quick;
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
3999
      quick= NULL;
1 by brian
clean slate
4000
    }
4001
    else
4002
    {
4003
      quick->mrr_flags= mrr_flags;
4004
      quick->mrr_buf_size= mrr_buf_size;
1487 by Brian Aker
More updates for memory::Root
4005
      if (parent_alloc)
4006
      {
4007
        quick->key_parts=(KEY_PART*)
4008
          parent_alloc->memdup_root( (char*) param->key[idx], sizeof(KEY_PART)* param->table->key_info[param->real_keynr[idx]].key_parts);
4009
      }
4010
      else
4011
      {
4012
        quick->key_parts=(KEY_PART*)
4013
          quick->alloc.memdup_root((char*) param->key[idx], sizeof(KEY_PART)* param->table->key_info[param->real_keynr[idx]].key_parts);
4014
      }
1 by brian
clean slate
4015
    }
4016
  }
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
4017
  return quick;
1 by brian
clean slate
4018
}
4019
4020
4021
/*
4022
** Fix this to get all possible sub_ranges
4023
*/
4024
bool
1237.13.7 by Padraig O'Sullivan
Renamed PARAM to Parameter and RANGE_OPT_PARAM to RangeParameter.
4025
optimizer::get_quick_keys(optimizer::Parameter *param,
1237.13.2 by Padraig O'Sullivan
Modified the names of 2 classes in the optimizer to adhere to the coding standards.
4026
                          optimizer::QuickRangeSelect *quick,
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
4027
                          KEY_PART *key,
1240.3.1 by Brian Aker
Merge Padraig.
4028
	                        optimizer::SEL_ARG *key_tree,
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
4029
                          unsigned char *min_key,
4030
                          uint32_t min_key_flag,
4031
	                        unsigned char *max_key,
4032
                          uint32_t max_key_flag)
1 by brian
clean slate
4033
{
1237.13.2 by Padraig O'Sullivan
Modified the names of 2 classes in the optimizer to adhere to the coding standards.
4034
  optimizer::QuickRange *range= NULL;
482 by Brian Aker
Remove uint.
4035
  uint32_t flag;
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
4036
  int min_part= key_tree->part - 1; // # of keypart values in min_key buffer
4037
  int max_part= key_tree->part - 1; // # of keypart values in max_key buffer
1 by brian
clean slate
4038
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
4039
  if (key_tree->left != &optimizer::null_element)
1 by brian
clean slate
4040
  {
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
4041
    if (get_quick_keys(param,
4042
                       quick,
4043
                       key,
4044
                       key_tree->left,
4045
		                   min_key,
4046
                       min_key_flag,
4047
                       max_key,
4048
                       max_key_flag))
4049
    {
1 by brian
clean slate
4050
      return 1;
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
4051
    }
1 by brian
clean slate
4052
  }
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
4053
  unsigned char *tmp_min_key= min_key,*tmp_max_key= max_key;
1 by brian
clean slate
4054
  min_part+= key_tree->store_min(key[key_tree->part].store_length,
4055
                                 &tmp_min_key,min_key_flag);
4056
  max_part+= key_tree->store_max(key[key_tree->part].store_length,
4057
                                 &tmp_max_key,max_key_flag);
4058
4059
  if (key_tree->next_key_part &&
4060
      key_tree->next_key_part->part == key_tree->part+1 &&
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
4061
      key_tree->next_key_part->type == optimizer::SEL_ARG::KEY_RANGE)
1 by brian
clean slate
4062
  {						  // const key as prefix
4063
    if ((tmp_min_key - min_key) == (tmp_max_key - max_key) &&
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
4064
        memcmp(min_key, max_key, (uint32_t)(tmp_max_key - max_key))==0 &&
4065
        key_tree->min_flag==0 && key_tree->max_flag==0)
1 by brian
clean slate
4066
    {
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
4067
      if (get_quick_keys(param,
4068
                         quick,
4069
                         key,
4070
                         key_tree->next_key_part,
1240.3.1 by Brian Aker
Merge Padraig.
4071
                         tmp_min_key,
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
4072
                         min_key_flag | key_tree->min_flag,
1240.3.1 by Brian Aker
Merge Padraig.
4073
                         tmp_max_key,
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
4074
                         max_key_flag | key_tree->max_flag))
4075
      {
4076
        return 1;
4077
      }
1 by brian
clean slate
4078
      goto end;					// Ugly, but efficient
4079
    }
4080
    {
482 by Brian Aker
Remove uint.
4081
      uint32_t tmp_min_flag=key_tree->min_flag,tmp_max_flag=key_tree->max_flag;
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
4082
      if (! tmp_min_flag)
4083
      {
1240.3.1 by Brian Aker
Merge Padraig.
4084
        min_part+= key_tree->next_key_part->store_min_key(key,
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
4085
                                                          &tmp_min_key,
1 by brian
clean slate
4086
                                                          &tmp_min_flag);
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
4087
      }
4088
      if (! tmp_max_flag)
4089
      {
1240.3.1 by Brian Aker
Merge Padraig.
4090
        max_part+= key_tree->next_key_part->store_max_key(key,
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
4091
                                                          &tmp_max_key,
1 by brian
clean slate
4092
                                                          &tmp_max_flag);
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
4093
      }
1 by brian
clean slate
4094
      flag=tmp_min_flag | tmp_max_flag;
4095
    }
4096
  }
4097
  else
4098
  {
4099
    flag= key_tree->min_flag | key_tree->max_flag;
4100
  }
4101
4102
  /*
4103
    Ensure that some part of min_key and max_key are used.  If not,
4104
    regard this as no lower/upper range
4105
  */
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
4106
  if (tmp_min_key != param->min_key)
4107
  {
4108
    flag&= ~NO_MIN_RANGE;
4109
  }
4110
  else
4111
  {
4112
    flag|= NO_MIN_RANGE;
4113
  }
4114
  if (tmp_max_key != param->max_key)
4115
  {
4116
    flag&= ~NO_MAX_RANGE;
4117
  }
4118
  else
4119
  {
4120
    flag|= NO_MAX_RANGE;
1 by brian
clean slate
4121
  }
4122
  if (flag == 0)
4123
  {
895 by Brian Aker
Completion (?) of uint conversion.
4124
    uint32_t length= (uint32_t) (tmp_min_key - param->min_key);
4125
    if (length == (uint32_t) (tmp_max_key - param->max_key) &&
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
4126
	      ! memcmp(param->min_key,param->max_key,length))
1 by brian
clean slate
4127
    {
1535 by Brian Aker
Rename of KEY to KeyInfo
4128
      KeyInfo *table_key= quick->head->key_info+quick->index;
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
4129
      flag= EQ_RANGE;
53.2.14 by Monty Taylor
Removed HA_END_SPACE_KEY and references to it. It was _supposed_ to be gone anyway, but the ifdef around it was broken (MYSQL_VERSION_ID was actually undefined.)
4130
      if ((table_key->flags & (HA_NOSAME)) == HA_NOSAME &&
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
4131
	        key->part == table_key->key_parts-1)
1 by brian
clean slate
4132
      {
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
4133
        if (! (table_key->flags & HA_NULL_PART_KEY) ||
4134
            ! null_part_in_key(key,
4135
                               param->min_key,
4136
                               (uint32_t) (tmp_min_key - param->min_key)))
4137
        {
4138
          flag|= UNIQUE_RANGE;
4139
        }
4140
        else
4141
        {
4142
          flag|= NULL_RANGE;
4143
        }
1 by brian
clean slate
4144
      }
4145
    }
4146
  }
4147
4148
  /* Get range for retrieving rows in QUICK_SELECT::get_next */
1237.13.2 by Padraig O'Sullivan
Modified the names of 2 classes in the optimizer to adhere to the coding standards.
4149
  if (! (range= new optimizer::QuickRange(param->min_key,
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
4150
			                                     (uint32_t) (tmp_min_key - param->min_key),
4151
                                           min_part >=0 ? make_keypart_map(min_part) : 0,
4152
			                                     param->max_key,
4153
			                                     (uint32_t) (tmp_max_key - param->max_key),
4154
                                           max_part >=0 ? make_keypart_map(max_part) : 0,
4155
			                                     flag)))
4156
  {
1 by brian
clean slate
4157
    return 1;			// out of memory
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
4158
  }
1 by brian
clean slate
4159
937.2.6 by Stewart Smith
make set_if_bigger typesafe for C and C++. Fix up everywhere.
4160
  set_if_bigger(quick->max_used_key_length, (uint32_t)range->min_length);
4161
  set_if_bigger(quick->max_used_key_length, (uint32_t)range->max_length);
895 by Brian Aker
Completion (?) of uint conversion.
4162
  set_if_bigger(quick->used_key_parts, (uint32_t) key_tree->part+1);
481 by Brian Aker
Remove all of uchar.
4163
  if (insert_dynamic(&quick->ranges, (unsigned char*) &range))
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
4164
  {
1 by brian
clean slate
4165
    return 1;
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
4166
  }
1 by brian
clean slate
4167
4168
 end:
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
4169
  if (key_tree->right != &optimizer::null_element)
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
4170
  {
4171
    return get_quick_keys(param,
4172
                          quick,
4173
                          key,
4174
                          key_tree->right,
4175
			                    min_key,
4176
                          min_key_flag,
4177
			                    max_key,
4178
                          max_key_flag);
4179
  }
1 by brian
clean slate
4180
  return 0;
4181
}
4182
4183
/*
55 by brian
Update for using real bool types.
4184
  Return true if any part of the key is NULL
1 by brian
clean slate
4185
4186
  SYNOPSIS
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
4187
    null_part_in_key()
1 by brian
clean slate
4188
      key_part  Array of key parts (index description)
4189
      key       Key values tuple
4190
      length    Length of key values tuple in bytes.
4191
4192
  RETURN
55 by brian
Update for using real bool types.
4193
    true   The tuple has at least one "keypartX is NULL"
4194
    false  Otherwise
1 by brian
clean slate
4195
*/
4196
482 by Brian Aker
Remove uint.
4197
static bool null_part_in_key(KEY_PART *key_part, const unsigned char *key, uint32_t length)
1 by brian
clean slate
4198
{
481 by Brian Aker
Remove all of uchar.
4199
  for (const unsigned char *end=key+length ;
1 by brian
clean slate
4200
       key < end;
4201
       key+= key_part++->store_length)
4202
  {
4203
    if (key_part->null_bit && *key)
4204
      return 1;
4205
  }
4206
  return 0;
4207
}
4208
4209
1802.16.6 by Padraig O'Sullivan
Added temporary conversion of a bitmap to dynamic_bitset in order to remove references to MyBitmap within optimizer code.
4210
bool optimizer::QuickSelectInterface::is_keys_used(const boost::dynamic_bitset<>& fields)
1 by brian
clean slate
4211
{
4212
  return is_key_used(head, index, fields);
4213
}
4214
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
4215
1 by brian
clean slate
4216
/*
4217
  Create quick select from ref/ref_or_null scan.
4218
4219
  SYNOPSIS
4220
    get_quick_select_for_ref()
520.1.22 by Brian Aker
Second pass of thd cleanup
4221
      session      Thread handle
1 by brian
clean slate
4222
      table    Table to access
4223
      ref      ref[_or_null] scan parameters
4224
      records  Estimate of number of records (needed only to construct
4225
               quick select)
4226
  NOTES
4227
    This allocates things in a new memory root, as this may be called many
4228
    times during a query.
4229
4230
  RETURN
4231
    Quick select that retrieves the same rows as passed ref scan
4232
    NULL on error.
4233
*/
4234
1240.3.1 by Brian Aker
Merge Padraig.
4235
optimizer::QuickRangeSelect *optimizer::get_quick_select_for_ref(Session *session,
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4236
                                                                 Table *table,
1240.3.1 by Brian Aker
Merge Padraig.
4237
                                                                 table_reference_st *ref,
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4238
                                                                 ha_rows records)
1 by brian
clean slate
4239
{
1802.16.5 by Padraig O'Sullivan
Adding help method for dynamic bitset functions. Temporary until MyBitmap is removed. Got rid of another MyBitmap usage in the range optimizer.
4240
  memory::Root *old_root= NULL;
4241
  memory::Root *alloc= NULL;
1535 by Brian Aker
Rename of KEY to KeyInfo
4242
  KeyInfo *key_info = &table->key_info[ref->key];
1 by brian
clean slate
4243
  KEY_PART *key_part;
1237.13.2 by Padraig O'Sullivan
Modified the names of 2 classes in the optimizer to adhere to the coding standards.
4244
  optimizer::QuickRange *range= NULL;
482 by Brian Aker
Remove uint.
4245
  uint32_t part;
1336.3.2 by Djellel E. Difallah
rename class COST_VECT to CostVector and move it to ./drizzled/optimizer directory
4246
  optimizer::CostVector cost;
1 by brian
clean slate
4247
520.1.22 by Brian Aker
Second pass of thd cleanup
4248
  old_root= session->mem_root;
4249
  /* The following call may change session->mem_root */
1802.16.5 by Padraig O'Sullivan
Adding help method for dynamic bitset functions. Temporary until MyBitmap is removed. Got rid of another MyBitmap usage in the range optimizer.
4250
  optimizer::QuickRangeSelect *quick= new optimizer::QuickRangeSelect(session, table, ref->key, 0, 0);
1237.13.2 by Padraig O'Sullivan
Modified the names of 2 classes in the optimizer to adhere to the coding standards.
4251
  /* save mem_root set by QuickRangeSelect constructor */
520.1.22 by Brian Aker
Second pass of thd cleanup
4252
  alloc= session->mem_root;
1 by brian
clean slate
4253
  /*
520.1.22 by Brian Aker
Second pass of thd cleanup
4254
    return back default mem_root (session->mem_root) changed by
1237.13.2 by Padraig O'Sullivan
Modified the names of 2 classes in the optimizer to adhere to the coding standards.
4255
    QuickRangeSelect constructor
1 by brian
clean slate
4256
  */
520.1.22 by Brian Aker
Second pass of thd cleanup
4257
  session->mem_root= old_root;
1 by brian
clean slate
4258
1802.16.5 by Padraig O'Sullivan
Adding help method for dynamic bitset functions. Temporary until MyBitmap is removed. Got rid of another MyBitmap usage in the range optimizer.
4259
  if (! quick)
1 by brian
clean slate
4260
    return 0;			/* no ranges found */
4261
  if (quick->init())
4262
    goto err;
4263
  quick->records= records;
4264
520.1.22 by Brian Aker
Second pass of thd cleanup
4265
  if ((cp_buffer_from_ref(session, ref) && session->is_fatal_error) ||
1237.13.2 by Padraig O'Sullivan
Modified the names of 2 classes in the optimizer to adhere to the coding standards.
4266
      !(range= new(alloc) optimizer::QuickRange()))
1 by brian
clean slate
4267
    goto err;                                   // out of memory
4268
4269
  range->min_key= range->max_key= ref->key_buff;
4270
  range->min_length= range->max_length= ref->key_length;
4271
  range->min_keypart_map= range->max_keypart_map=
4272
    make_prev_keypart_map(ref->key_parts);
4273
  range->flag= ((ref->key_length == key_info->key_length &&
1100.1.1 by Brian Aker
Disable MRR
4274
                 (key_info->flags & HA_END_SPACE_KEY) == 0) ? EQ_RANGE : 0);
4275
1 by brian
clean slate
4276
4277
  if (!(quick->key_parts=key_part=(KEY_PART *)
1485 by Brian Aker
Updates to confine memroot
4278
        quick->alloc.alloc_root(sizeof(KEY_PART)*ref->key_parts)))
1 by brian
clean slate
4279
    goto err;
4280
4281
  for (part=0 ; part < ref->key_parts ;part++,key_part++)
4282
  {
4283
    key_part->part=part;
4284
    key_part->field=        key_info->key_part[part].field;
4285
    key_part->length=       key_info->key_part[part].length;
4286
    key_part->store_length= key_info->key_part[part].store_length;
4287
    key_part->null_bit=     key_info->key_part[part].null_bit;
206 by Brian Aker
Removed final uint dead types.
4288
    key_part->flag=         (uint8_t) key_info->key_part[part].key_part_flag;
1 by brian
clean slate
4289
  }
481 by Brian Aker
Remove all of uchar.
4290
  if (insert_dynamic(&quick->ranges,(unsigned char*)&range))
1 by brian
clean slate
4291
    goto err;
4292
4293
  /*
4294
     Add a NULL range if REF_OR_NULL optimization is used.
4295
     For example:
4296
       if we have "WHERE A=2 OR A IS NULL" we created the (A=2) range above
4297
       and have ref->null_ref_key set. Will create a new NULL range here.
4298
  */
4299
  if (ref->null_ref_key)
4300
  {
1237.13.2 by Padraig O'Sullivan
Modified the names of 2 classes in the optimizer to adhere to the coding standards.
4301
    optimizer::QuickRange *null_range= NULL;
1 by brian
clean slate
4302
4303
    *ref->null_ref_key= 1;		// Set null byte then create a range
4304
    if (!(null_range= new (alloc)
1237.13.2 by Padraig O'Sullivan
Modified the names of 2 classes in the optimizer to adhere to the coding standards.
4305
          optimizer::QuickRange(ref->key_buff, ref->key_length,
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
4306
                                 make_prev_keypart_map(ref->key_parts),
4307
                                 ref->key_buff, ref->key_length,
4308
                                 make_prev_keypart_map(ref->key_parts), EQ_RANGE)))
1 by brian
clean slate
4309
      goto err;
4310
    *ref->null_ref_key= 0;		// Clear null byte
481 by Brian Aker
Remove all of uchar.
4311
    if (insert_dynamic(&quick->ranges,(unsigned char*)&null_range))
1 by brian
clean slate
4312
      goto err;
4313
  }
4314
4315
  /* Call multi_range_read_info() to get the MRR flags and buffer size */
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
4316
  quick->mrr_flags= HA_MRR_NO_ASSOCIATION |
1 by brian
clean slate
4317
                    (table->key_read ? HA_MRR_INDEX_ONLY : 0);
520.1.22 by Brian Aker
Second pass of thd cleanup
4318
  if (session->lex->sql_command != SQLCOM_SELECT)
1 by brian
clean slate
4319
    quick->mrr_flags |= HA_MRR_USE_DEFAULT_IMPL;
4320
520.1.22 by Brian Aker
Second pass of thd cleanup
4321
  quick->mrr_buf_size= session->variables.read_rnd_buff_size;
1208.3.2 by brian
Update for Cursor renaming.
4322
  if (table->cursor->multi_range_read_info(quick->index, 1, (uint32_t)records,
1493 by Brian Aker
Remove dead call around "fixing" case where MRR lacked buffer.
4323
                                           &quick->mrr_buf_size,
4324
                                           &quick->mrr_flags, &cost))
1 by brian
clean slate
4325
    goto err;
4326
4327
  return quick;
4328
err:
4329
  delete quick;
4330
  return 0;
4331
}
4332
4333
4334
/*
1237.13.2 by Padraig O'Sullivan
Modified the names of 2 classes in the optimizer to adhere to the coding standards.
4335
  Range sequence interface implementation for array<QuickRange>: initialize
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
4336
1 by brian
clean slate
4337
  SYNOPSIS
4338
    quick_range_seq_init()
1237.13.2 by Padraig O'Sullivan
Modified the names of 2 classes in the optimizer to adhere to the coding standards.
4339
      init_param  Caller-opaque paramenter: QuickRangeSelect* pointer
1 by brian
clean slate
4340
      n_ranges    Number of ranges in the sequence (ignored)
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
4341
      flags       MRR flags (currently not used)
1 by brian
clean slate
4342
4343
  RETURN
4344
    Opaque value to be passed to quick_range_seq_next
4345
*/
4346
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
4347
range_seq_t optimizer::quick_range_seq_init(void *init_param, uint32_t, uint32_t)
1 by brian
clean slate
4348
{
1237.13.2 by Padraig O'Sullivan
Modified the names of 2 classes in the optimizer to adhere to the coding standards.
4349
  optimizer::QuickRangeSelect *quick= (optimizer::QuickRangeSelect*)init_param;
4350
  quick->qr_traversal_ctx.first=  (optimizer::QuickRange**)quick->ranges.buffer;
4351
  quick->qr_traversal_ctx.cur=    (optimizer::QuickRange**)quick->ranges.buffer;
77.1.46 by Monty Taylor
Finished the warnings work!
4352
  quick->qr_traversal_ctx.last=   quick->qr_traversal_ctx.cur +
1 by brian
clean slate
4353
                                  quick->ranges.elements;
4354
  return &quick->qr_traversal_ctx;
4355
}
4356
4357
4358
/*
1237.13.2 by Padraig O'Sullivan
Modified the names of 2 classes in the optimizer to adhere to the coding standards.
4359
  Range sequence interface implementation for array<QuickRange>: get next
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
4360
1 by brian
clean slate
4361
  SYNOPSIS
4362
    quick_range_seq_next()
4363
      rseq        Value returned from quick_range_seq_init
4364
      range  OUT  Store information about the range here
4365
4366
  RETURN
4367
    0  Ok
4368
    1  No more ranges in the sequence
4369
*/
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
4370
uint32_t optimizer::quick_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range)
1 by brian
clean slate
4371
{
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4372
  QuickRangeSequenceContext *ctx= (QuickRangeSequenceContext*) rseq;
1 by brian
clean slate
4373
4374
  if (ctx->cur == ctx->last)
4375
    return 1; /* no more ranges */
4376
1237.13.2 by Padraig O'Sullivan
Modified the names of 2 classes in the optimizer to adhere to the coding standards.
4377
  optimizer::QuickRange *cur= *(ctx->cur);
1 by brian
clean slate
4378
  key_range *start_key= &range->start_key;
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4379
  key_range *end_key= &range->end_key;
1 by brian
clean slate
4380
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4381
  start_key->key= cur->min_key;
1 by brian
clean slate
4382
  start_key->length= cur->min_length;
4383
  start_key->keypart_map= cur->min_keypart_map;
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4384
  start_key->flag= ((cur->flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
4385
                                             (cur->flag & EQ_RANGE) ?
4386
                                             HA_READ_KEY_EXACT : HA_READ_KEY_OR_NEXT);
4387
  end_key->key= cur->max_key;
4388
  end_key->length= cur->max_length;
1 by brian
clean slate
4389
  end_key->keypart_map= cur->max_keypart_map;
4390
  /*
4391
    We use HA_READ_AFTER_KEY here because if we are reading on a key
4392
    prefix. We want to find all keys with this prefix.
4393
  */
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4394
  end_key->flag= (cur->flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
4395
                                         HA_READ_AFTER_KEY);
1 by brian
clean slate
4396
  range->range_flag= cur->flag;
4397
  ctx->cur++;
4398
  return 0;
4399
}
4400
4401
1535 by Brian Aker
Rename of KEY to KeyInfo
4402
static inline uint32_t get_field_keypart(KeyInfo *index, Field *field);
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4403
1240.3.1 by Brian Aker
Merge Padraig.
4404
static inline optimizer::SEL_ARG * get_index_range_tree(uint32_t index,
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
4405
                                                        optimizer::SEL_TREE *range_tree,
1240.3.1 by Brian Aker
Merge Padraig.
4406
                                                        optimizer::Parameter *param,
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
4407
                                                        uint32_t *param_idx);
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4408
1535 by Brian Aker
Rename of KEY to KeyInfo
4409
static bool get_constant_key_infix(KeyInfo *index_info,
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
4410
                                   optimizer::SEL_ARG *index_range_tree,
1534 by Brian Aker
Remove of KeyPartInfo
4411
                                   KeyPartInfo *first_non_group_part,
4412
                                   KeyPartInfo *min_max_arg_part,
4413
                                   KeyPartInfo *last_part,
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4414
                                   Session *session,
1240.3.1 by Brian Aker
Merge Padraig.
4415
                                   unsigned char *key_infix,
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4416
                                   uint32_t *key_infix_len,
1534 by Brian Aker
Remove of KeyPartInfo
4417
                                   KeyPartInfo **first_non_infix_part);
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4418
1055.2.5 by Jay Pipes
Removal of dead Field::image_type and st_key_part::image_type member variables. Legacy from geometry MyISAM types...
4419
static bool check_group_min_max_predicates(COND *cond, Item_field *min_max_arg_item);
1 by brian
clean slate
4420
4421
static void
1240.3.1 by Brian Aker
Merge Padraig.
4422
cost_group_min_max(Table* table,
1535 by Brian Aker
Rename of KEY to KeyInfo
4423
                   KeyInfo *index_info,
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4424
                   uint32_t used_key_parts,
1240.3.1 by Brian Aker
Merge Padraig.
4425
                   uint32_t group_key_parts,
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
4426
                   optimizer::SEL_TREE *range_tree,
1240.3.1 by Brian Aker
Merge Padraig.
4427
                   optimizer::SEL_ARG *index_tree,
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4428
                   ha_rows quick_prefix_records,
1240.3.1 by Brian Aker
Merge Padraig.
4429
                   bool have_min,
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4430
                   bool have_max,
1240.3.1 by Brian Aker
Merge Padraig.
4431
                   double *read_cost,
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4432
                   ha_rows *records);
1 by brian
clean slate
4433
4434
4435
/*
4436
  Test if this access method is applicable to a GROUP query with MIN/MAX
4437
  functions, and if so, construct a new TRP object.
4438
4439
  SYNOPSIS
4440
    get_best_group_min_max()
4441
    param    Parameter from test_quick_select
4442
    sel_tree Range tree generated by get_mm_tree
4443
4444
  DESCRIPTION
1237.13.21 by Padraig O'Sullivan
Corrected some style issues in the QuickGroupMinMaxSelect class.
4445
    Test whether a query can be computed via a QuickGroupMinMaxSelect.
4446
    Queries computable via a QuickGroupMinMaxSelect must satisfy the
1 by brian
clean slate
4447
    following conditions:
4448
    A) Table T has at least one compound index I of the form:
4449
       I = <A_1, ...,A_k, [B_1,..., B_m], C, [D_1,...,D_n]>
4450
    B) Query conditions:
4451
    B0. Q is over a single table T.
4452
    B1. The attributes referenced by Q are a subset of the attributes of I.
4453
    B2. All attributes QA in Q can be divided into 3 overlapping groups:
4454
        - SA = {S_1, ..., S_l, [C]} - from the SELECT clause, where C is
4455
          referenced by any number of MIN and/or MAX functions if present.
4456
        - WA = {W_1, ..., W_p} - from the WHERE clause
4457
        - GA = <G_1, ..., G_k> - from the GROUP BY clause (if any)
4458
             = SA              - if Q is a DISTINCT query (based on the
4459
                                 equivalence of DISTINCT and GROUP queries.
4460
        - NGA = QA - (GA union C) = {NG_1, ..., NG_m} - the ones not in
4461
          GROUP BY and not referenced by MIN/MAX functions.
4462
        with the following properties specified below.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
4463
    B3. If Q has a GROUP BY WITH ROLLUP clause the access method is not
1 by brian
clean slate
4464
        applicable.
4465
4466
    SA1. There is at most one attribute in SA referenced by any number of
4467
         MIN and/or MAX functions which, which if present, is denoted as C.
4468
    SA2. The position of the C attribute in the index is after the last A_k.
4469
    SA3. The attribute C can be referenced in the WHERE clause only in
4470
         predicates of the forms:
4471
         - (C {< | <= | > | >= | =} const)
4472
         - (const {< | <= | > | >= | =} C)
4473
         - (C between const_i and const_j)
4474
         - C IS NULL
4475
         - C IS NOT NULL
4476
         - C != const
4477
    SA4. If Q has a GROUP BY clause, there are no other aggregate functions
4478
         except MIN and MAX. For queries with DISTINCT, aggregate functions
4479
         are allowed.
4480
    SA5. The select list in DISTINCT queries should not contain expressions.
4481
    GA1. If Q has a GROUP BY clause, then GA is a prefix of I. That is, if
4482
         G_i = A_j => i = j.
4483
    GA2. If Q has a DISTINCT clause, then there is a permutation of SA that
4484
         forms a prefix of I. This permutation is used as the GROUP clause
4485
         when the DISTINCT query is converted to a GROUP query.
4486
    GA3. The attributes in GA may participate in arbitrary predicates, divided
4487
         into two groups:
4488
         - RNG(G_1,...,G_q ; where q <= k) is a range condition over the
4489
           attributes of a prefix of GA
4490
         - PA(G_i1,...G_iq) is an arbitrary predicate over an arbitrary subset
4491
           of GA. Since P is applied to only GROUP attributes it filters some
4492
           groups, and thus can be applied after the grouping.
4493
    GA4. There are no expressions among G_i, just direct column references.
4494
    NGA1.If in the index I there is a gap between the last GROUP attribute G_k,
4495
         and the MIN/MAX attribute C, then NGA must consist of exactly the
4496
         index attributes that constitute the gap. As a result there is a
4497
         permutation of NGA that coincides with the gap in the index
4498
         <B_1, ..., B_m>.
4499
    NGA2.If BA <> {}, then the WHERE clause must contain a conjunction EQ of
4500
         equality conditions for all NG_i of the form (NG_i = const) or
4501
         (const = NG_i), such that each NG_i is referenced in exactly one
4502
         conjunct. Informally, the predicates provide constants to fill the
4503
         gap in the index.
4504
    WA1. There are no other attributes in the WHERE clause except the ones
4505
         referenced in predicates RNG, PA, PC, EQ defined above. Therefore
4506
         WA is subset of (GA union NGA union C) for GA,NGA,C that pass the
4507
         above tests. By transitivity then it also follows that each WA_i
4508
         participates in the index I (if this was already tested for GA, NGA
4509
         and C).
4510
4511
    C) Overall query form:
4512
       SELECT EXPR([A_1,...,A_k], [B_1,...,B_m], [MIN(C)], [MAX(C)])
4513
         FROM T
4514
        WHERE [RNG(A_1,...,A_p ; where p <= k)]
4515
         [AND EQ(B_1,...,B_m)]
4516
         [AND PC(C)]
4517
         [AND PA(A_i1,...,A_iq)]
4518
       GROUP BY A_1,...,A_k
4519
       [HAVING PH(A_1, ..., B_1,..., C)]
4520
    where EXPR(...) is an arbitrary expression over some or all SELECT fields,
4521
    or:
4522
       SELECT DISTINCT A_i1,...,A_ik
4523
         FROM T
4524
        WHERE [RNG(A_1,...,A_p ; where p <= k)]
4525
         [AND PA(A_i1,...,A_iq)];
4526
4527
  NOTES
4528
    If the current query satisfies the conditions above, and if
4529
    (mem_root! = NULL), then the function constructs and returns a new TRP
1237.13.21 by Padraig O'Sullivan
Corrected some style issues in the QuickGroupMinMaxSelect class.
4530
    object, that is later used to construct a new QuickGroupMinMaxSelect.
1 by brian
clean slate
4531
    If (mem_root == NULL), then the function only tests whether the current
4532
    query satisfies the conditions above, and, if so, sets
55 by brian
Update for using real bool types.
4533
    is_applicable = true.
1 by brian
clean slate
4534
4535
    Queries with DISTINCT for which index access can be used are transformed
4536
    into equivalent group-by queries of the form:
4537
4538
    SELECT A_1,...,A_k FROM T
4539
     WHERE [RNG(A_1,...,A_p ; where p <= k)]
4540
      [AND PA(A_i1,...,A_iq)]
4541
    GROUP BY A_1,...,A_k;
4542
4543
    The group-by list is a permutation of the select attributes, according
4544
    to their order in the index.
4545
4546
  TODO
4547
  - What happens if the query groups by the MIN/MAX field, and there is no
4548
    other field as in: "select min(a) from t1 group by a" ?
4549
  - We assume that the general correctness of the GROUP-BY query was checked
4550
    before this point. Is this correct, or do we have to check it completely?
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
4551
  - Lift the limitation in condition (B3), that is, make this access method
1 by brian
clean slate
4552
    applicable to ROLLUP queries.
4553
4554
  RETURN
4555
    If mem_root != NULL
1237.13.27 by Padraig O'Sullivan
Correcting the case of a number of classes in the optimizer to adhere to the coding standards. Also
4556
    - valid GroupMinMaxReadPlan object if this QUICK class can be used for
1 by brian
clean slate
4557
      the query
4558
    -  NULL o/w.
4559
    If mem_root == NULL
4560
    - NULL
4561
*/
1237.13.27 by Padraig O'Sullivan
Correcting the case of a number of classes in the optimizer to adhere to the coding standards. Also
4562
static optimizer::GroupMinMaxReadPlan *
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
4563
get_best_group_min_max(optimizer::Parameter *param, optimizer::SEL_TREE *tree)
1 by brian
clean slate
4564
{
520.1.22 by Brian Aker
Second pass of thd cleanup
4565
  Session *session= param->session;
1541.1.1 by Brian Aker
JOIN -> Join rename
4566
  Join *join= session->lex->current_select->join;
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
4567
  Table *table= param->table;
55 by brian
Update for using real bool types.
4568
  bool have_min= false;              /* true if there is a MIN function. */
4569
  bool have_max= false;              /* true if there is a MAX function. */
1 by brian
clean slate
4570
  Item_field *min_max_arg_item= NULL; // The argument of all MIN/MAX functions
1534 by Brian Aker
Remove of KeyPartInfo
4571
  KeyPartInfo *min_max_arg_part= NULL; /* The corresponding keypart. */
482 by Brian Aker
Remove uint.
4572
  uint32_t group_prefix_len= 0; /* Length (in bytes) of the key prefix. */
1535 by Brian Aker
Rename of KEY to KeyInfo
4573
  KeyInfo *index_info= NULL;    /* The index chosen for data access. */
482 by Brian Aker
Remove uint.
4574
  uint32_t index= 0;            /* The id of the chosen index. */
4575
  uint32_t group_key_parts= 0;  // Number of index key parts in the group prefix.
4576
  uint32_t used_key_parts= 0;   /* Number of index key parts used for access. */
481 by Brian Aker
Remove all of uchar.
4577
  unsigned char key_infix[MAX_KEY_LENGTH]; /* Constants from equality predicates.*/
482 by Brian Aker
Remove uint.
4578
  uint32_t key_infix_len= 0;          /* Length of key_infix. */
1237.13.27 by Padraig O'Sullivan
Correcting the case of a number of classes in the optimizer to adhere to the coding standards. Also
4579
  optimizer::GroupMinMaxReadPlan *read_plan= NULL; /* The eventually constructed TRP. */
482 by Brian Aker
Remove uint.
4580
  uint32_t key_part_nr;
1892.3.3 by tdavies
struct order_st changed and renamed to c++ class named:Order
4581
  Order *tmp_group= NULL;
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4582
  Item *item= NULL;
4583
  Item_field *item_field= NULL;
1 by brian
clean slate
4584
4585
  /* Perform few 'cheap' tests whether this access method is applicable. */
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4586
  if (! join)
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
4587
    return NULL;        /* This is not a select statement. */
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4588
1 by brian
clean slate
4589
  if ((join->tables != 1) ||  /* The query must reference one table. */
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4590
      ((! join->group_list) && /* Neither GROUP BY nor a DISTINCT query. */
4591
       (! join->select_distinct)) ||
1 by brian
clean slate
4592
      (join->select_lex->olap == ROLLUP_TYPE)) /* Check (B3) for ROLLUP */
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
4593
    return NULL;
1578.2.10 by Brian Aker
keys and fields partial encapsulation.
4594
  if (table->getShare()->sizeKeys() == 0)        /* There are no indexes to use. */
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
4595
    return NULL;
1 by brian
clean slate
4596
4597
  /* Analyze the query in more detail. */
4598
  List_iterator<Item> select_items_it(join->fields_list);
4599
4600
  /* Check (SA1,SA4) and store the only MIN/MAX argument - the C attribute.*/
4601
  if (join->make_sum_func_list(join->all_fields, join->fields_list, 1))
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
4602
    return NULL;
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4603
1 by brian
clean slate
4604
  if (join->sum_funcs[0])
4605
  {
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4606
    Item_sum *min_max_item= NULL;
1 by brian
clean slate
4607
    Item_sum **func_ptr= join->sum_funcs;
4608
    while ((min_max_item= *(func_ptr++)))
4609
    {
4610
      if (min_max_item->sum_func() == Item_sum::MIN_FUNC)
55 by brian
Update for using real bool types.
4611
        have_min= true;
1 by brian
clean slate
4612
      else if (min_max_item->sum_func() == Item_sum::MAX_FUNC)
55 by brian
Update for using real bool types.
4613
        have_max= true;
1 by brian
clean slate
4614
      else
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
4615
        return NULL;
1 by brian
clean slate
4616
4617
      /* The argument of MIN/MAX. */
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
4618
      Item *expr= min_max_item->args[0]->real_item();
1 by brian
clean slate
4619
      if (expr->type() == Item::FIELD_ITEM) /* Is it an attribute? */
4620
      {
4621
        if (! min_max_arg_item)
4622
          min_max_arg_item= (Item_field*) expr;
4623
        else if (! min_max_arg_item->eq(expr, 1))
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
4624
          return NULL;
1 by brian
clean slate
4625
      }
4626
      else
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
4627
        return NULL;
1 by brian
clean slate
4628
    }
4629
  }
4630
4631
  /* Check (SA5). */
4632
  if (join->select_distinct)
4633
  {
4634
    while ((item= select_items_it++))
4635
    {
4636
      if (item->type() != Item::FIELD_ITEM)
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
4637
        return NULL;
1 by brian
clean slate
4638
    }
4639
  }
4640
4641
  /* Check (GA4) - that there are no expressions among the group attributes. */
4642
  for (tmp_group= join->group_list; tmp_group; tmp_group= tmp_group->next)
4643
  {
4644
    if ((*tmp_group->item)->type() != Item::FIELD_ITEM)
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
4645
      return NULL;
1 by brian
clean slate
4646
  }
4647
4648
  /*
4649
    Check that table has at least one compound index such that the conditions
55 by brian
Update for using real bool types.
4650
    (GA1,GA2) are all true. If there is more than one such index, select the
1 by brian
clean slate
4651
    first one. Here we set the variables: group_prefix_len and index_info.
4652
  */
1535 by Brian Aker
Rename of KEY to KeyInfo
4653
  KeyInfo *cur_index_info= table->key_info;
1578.2.10 by Brian Aker
keys and fields partial encapsulation.
4654
  KeyInfo *cur_index_info_end= cur_index_info + table->getShare()->sizeKeys();
1534 by Brian Aker
Remove of KeyPartInfo
4655
  KeyPartInfo *cur_part= NULL;
4656
  KeyPartInfo *end_part= NULL; /* Last part for loops. */
1 by brian
clean slate
4657
  /* Last index part. */
1534 by Brian Aker
Remove of KeyPartInfo
4658
  KeyPartInfo *last_part= NULL;
4659
  KeyPartInfo *first_non_group_part= NULL;
4660
  KeyPartInfo *first_non_infix_part= NULL;
482 by Brian Aker
Remove uint.
4661
  uint32_t key_infix_parts= 0;
4662
  uint32_t cur_group_key_parts= 0;
4663
  uint32_t cur_group_prefix_len= 0;
1 by brian
clean slate
4664
  /* Cost-related variables for the best index so far. */
4665
  double best_read_cost= DBL_MAX;
4666
  ha_rows best_records= 0;
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
4667
  optimizer::SEL_ARG *best_index_tree= NULL;
1 by brian
clean slate
4668
  ha_rows best_quick_prefix_records= 0;
482 by Brian Aker
Remove uint.
4669
  uint32_t best_param_idx= 0;
1 by brian
clean slate
4670
  double cur_read_cost= DBL_MAX;
4671
  ha_rows cur_records;
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
4672
  optimizer::SEL_ARG *cur_index_tree= NULL;
1 by brian
clean slate
4673
  ha_rows cur_quick_prefix_records= 0;
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4674
  uint32_t cur_param_idx= MAX_KEY;
1052.1.2 by Joe Daly
Bug #309547. Also identified by MySQL #41610. The read plan being
4675
  key_map used_key_parts_map;
4676
  uint32_t cur_key_infix_len= 0;
4677
  unsigned char cur_key_infix[MAX_KEY_LENGTH];
4678
  uint32_t cur_used_key_parts= 0;
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
4679
  uint32_t pk= param->table->getShare()->getPrimaryKey();
1 by brian
clean slate
4680
1240.3.1 by Brian Aker
Merge Padraig.
4681
  for (uint32_t cur_index= 0;
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4682
       cur_index_info != cur_index_info_end;
1 by brian
clean slate
4683
       cur_index_info++, cur_index++)
4684
  {
4685
    /* Check (B1) - if current index is covering. */
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4686
    if (! table->covering_keys.test(cur_index))
1 by brian
clean slate
4687
      goto next_index;
4688
4689
    /*
4690
      If the current storage manager is such that it appends the primary key to
4691
      each index, then the above condition is insufficient to check if the
4692
      index is covering. In such cases it may happen that some fields are
4693
      covered by the PK index, but not by the current index. Since we can't
4694
      use the concatenation of both indexes for index lookup, such an index
4695
      does not qualify as covering in our case. If this is the case, below
4696
      we check that all query fields are indeed covered by 'cur_index'.
4697
    */
4698
    if (pk < MAX_KEY && cur_index != pk &&
1233.1.4 by Brian Aker
Added:
4699
        (table->cursor->getEngine()->check_flag(HTON_BIT_PRIMARY_KEY_IN_READ_INDEX)))
1 by brian
clean slate
4700
    {
4701
      /* For each table field */
1578.2.10 by Brian Aker
keys and fields partial encapsulation.
4702
      for (uint32_t i= 0; i < table->getShare()->sizeFields(); i++)
1 by brian
clean slate
4703
      {
1578.2.16 by Brian Aker
Merge in change to getTable() to private the field objects.
4704
        Field *cur_field= table->getField(i);
1 by brian
clean slate
4705
        /*
4706
          If the field is used in the current query ensure that it's
4707
          part of 'cur_index'
4708
        */
1003.1.12 by Brian Aker
Begin of abstract out the bitmap from direct reference.
4709
        if ((cur_field->isReadSet()) &&
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4710
            ! cur_field->part_of_key_not_clustered.test(cur_index))
1 by brian
clean slate
4711
          goto next_index;                  // Field was not part of key
4712
      }
4713
    }
4714
4715
    /*
4716
      Check (GA1) for GROUP BY queries.
4717
    */
4718
    if (join->group_list)
4719
    {
4720
      cur_part= cur_index_info->key_part;
4721
      end_part= cur_part + cur_index_info->key_parts;
4722
      /* Iterate in parallel over the GROUP list and the index parts. */
1240.3.1 by Brian Aker
Merge Padraig.
4723
      for (tmp_group= join->group_list;
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4724
           tmp_group && (cur_part != end_part);
1 by brian
clean slate
4725
           tmp_group= tmp_group->next, cur_part++)
4726
      {
4727
        /*
4728
          TODO:
4729
          tmp_group::item is an array of Item, is it OK to consider only the
4730
          first Item? If so, then why? What is the array for?
4731
        */
4732
        /* Above we already checked that all group items are fields. */
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
4733
        assert((*tmp_group->item)->type() == Item::FIELD_ITEM);
1 by brian
clean slate
4734
        Item_field *group_field= (Item_field *) (*tmp_group->item);
4735
        if (group_field->field->eq(cur_part->field))
4736
        {
4737
          cur_group_prefix_len+= cur_part->store_length;
4738
          ++cur_group_key_parts;
4739
        }
4740
        else
4741
          goto next_index;
4742
      }
4743
    }
4744
    /*
4745
      Check (GA2) if this is a DISTINCT query.
327.2.3 by Brian Aker
Refactoring of class Table
4746
      If GA2, then Store a new order_st object in group_fields_array at the
4747
      position of the key part of item_field->field. Thus we get the order_st
1 by brian
clean slate
4748
      objects for each field ordered as the corresponding key parts.
327.2.3 by Brian Aker
Refactoring of class Table
4749
      Later group_fields_array of order_st objects is used to convert the query
1 by brian
clean slate
4750
      to a GROUP query.
4751
    */
4752
    else if (join->select_distinct)
4753
    {
4754
      select_items_it.rewind();
1052.1.2 by Joe Daly
Bug #309547. Also identified by MySQL #41610. The read plan being
4755
      used_key_parts_map.reset();
482 by Brian Aker
Remove uint.
4756
      uint32_t max_key_part= 0;
1 by brian
clean slate
4757
      while ((item= select_items_it++))
4758
      {
4759
        item_field= (Item_field*) item; /* (SA5) already checked above. */
4760
        /* Find the order of the key part in the index. */
4761
        key_part_nr= get_field_keypart(cur_index_info, item_field->field);
4762
        /*
4763
          Check if this attribute was already present in the select list.
4764
          If it was present, then its corresponding key part was alredy used.
4765
        */
1052.1.2 by Joe Daly
Bug #309547. Also identified by MySQL #41610. The read plan being
4766
        if (used_key_parts_map.test(key_part_nr))
1 by brian
clean slate
4767
          continue;
4768
        if (key_part_nr < 1 || key_part_nr > join->fields_list.elements)
4769
          goto next_index;
4770
        cur_part= cur_index_info->key_part + key_part_nr - 1;
4771
        cur_group_prefix_len+= cur_part->store_length;
1052.1.2 by Joe Daly
Bug #309547. Also identified by MySQL #41610. The read plan being
4772
        used_key_parts_map.set(key_part_nr);
1 by brian
clean slate
4773
        ++cur_group_key_parts;
1067.4.7 by Nathan Williams
The remaining files using cmax have been converted to std::max.
4774
        max_key_part= max(max_key_part,key_part_nr);
1 by brian
clean slate
4775
      }
4776
      /*
4777
        Check that used key parts forms a prefix of the index.
4778
        To check this we compare bits in all_parts and cur_parts.
4779
        all_parts have all bits set from 0 to (max_key_part-1).
4780
        cur_parts have bits set for only used keyparts.
4781
      */
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4782
      key_map all_parts;
4783
      key_map cur_parts;
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
4784
      for (uint32_t pos= 0; pos < max_key_part; pos++)
4785
        all_parts.set(pos);
1052.1.2 by Joe Daly
Bug #309547. Also identified by MySQL #41610. The read plan being
4786
      cur_parts= used_key_parts_map >> 1;
1 by brian
clean slate
4787
      if (all_parts != cur_parts)
4788
        goto next_index;
4789
    }
4790
    else
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
4791
      assert(false);
1 by brian
clean slate
4792
4793
    /* Check (SA2). */
4794
    if (min_max_arg_item)
4795
    {
4796
      key_part_nr= get_field_keypart(cur_index_info, min_max_arg_item->field);
4797
      if (key_part_nr <= cur_group_key_parts)
4798
        goto next_index;
4799
      min_max_arg_part= cur_index_info->key_part + key_part_nr - 1;
4800
    }
4801
4802
    /*
4803
      Check (NGA1, NGA2) and extract a sequence of constants to be used as part
4804
      of all search keys.
4805
    */
4806
4807
    /*
4808
      If there is MIN/MAX, each keypart between the last group part and the
4809
      MIN/MAX part must participate in one equality with constants, and all
4810
      keyparts after the MIN/MAX part must not be referenced in the query.
4811
4812
      If there is no MIN/MAX, the keyparts after the last group part can be
4813
      referenced only in equalities with constants, and the referenced keyparts
4814
      must form a sequence without any gaps that starts immediately after the
4815
      last group keypart.
4816
    */
4817
    last_part= cur_index_info->key_part + cur_index_info->key_parts;
4818
    first_non_group_part= (cur_group_key_parts < cur_index_info->key_parts) ?
4819
                          cur_index_info->key_part + cur_group_key_parts :
4820
                          NULL;
4821
    first_non_infix_part= min_max_arg_part ?
4822
                          (min_max_arg_part < last_part) ?
4823
                             min_max_arg_part :
4824
                             NULL :
4825
                           NULL;
4826
    if (first_non_group_part &&
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4827
        (! min_max_arg_part || (min_max_arg_part - first_non_group_part > 0)))
1 by brian
clean slate
4828
    {
4829
      if (tree)
4830
      {
482 by Brian Aker
Remove uint.
4831
        uint32_t dummy;
1240.3.1 by Brian Aker
Merge Padraig.
4832
        optimizer::SEL_ARG *index_range_tree= get_index_range_tree(cur_index,
4833
                                                                   tree,
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
4834
                                                                   param,
4835
                                                                   &dummy);
1240.3.1 by Brian Aker
Merge Padraig.
4836
        if (! get_constant_key_infix(cur_index_info,
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4837
                                     index_range_tree,
1240.3.1 by Brian Aker
Merge Padraig.
4838
                                     first_non_group_part,
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4839
                                     min_max_arg_part,
1240.3.1 by Brian Aker
Merge Padraig.
4840
                                     last_part,
4841
                                     session,
4842
                                     cur_key_infix,
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4843
                                     &cur_key_infix_len,
4844
                                     &first_non_infix_part))
4845
        {
1 by brian
clean slate
4846
          goto next_index;
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4847
        }
1 by brian
clean slate
4848
      }
4849
      else if (min_max_arg_part &&
4850
               (min_max_arg_part - first_non_group_part > 0))
4851
      {
4852
        /*
4853
          There is a gap but no range tree, thus no predicates at all for the
4854
          non-group keyparts.
4855
        */
4856
        goto next_index;
4857
      }
4858
      else if (first_non_group_part && join->conds)
4859
      {
4860
        /*
4861
          If there is no MIN/MAX function in the query, but some index
4862
          key part is referenced in the WHERE clause, then this index
4863
          cannot be used because the WHERE condition over the keypart's
4864
          field cannot be 'pushed' to the index (because there is no
4865
          range 'tree'), and the WHERE clause must be evaluated before
4866
          GROUP BY/DISTINCT.
4867
        */
4868
        /*
4869
          Store the first and last keyparts that need to be analyzed
4870
          into one array that can be passed as parameter.
4871
        */
1534 by Brian Aker
Remove of KeyPartInfo
4872
        KeyPartInfo *key_part_range[2];
1 by brian
clean slate
4873
        key_part_range[0]= first_non_group_part;
4874
        key_part_range[1]= last_part;
4875
4876
        /* Check if cur_part is referenced in the WHERE clause. */
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4877
        if (join->conds->walk(&Item::find_item_in_field_list_processor,
4878
                              0,
481 by Brian Aker
Remove all of uchar.
4879
                              (unsigned char*) key_part_range))
1 by brian
clean slate
4880
          goto next_index;
4881
      }
4882
    }
4883
4884
    /*
4885
      Test (WA1) partially - that no other keypart after the last infix part is
4886
      referenced in the query.
4887
    */
4888
    if (first_non_infix_part)
4889
    {
4890
      cur_part= first_non_infix_part +
4891
                (min_max_arg_part && (min_max_arg_part < last_part));
4892
      for (; cur_part != last_part; cur_part++)
4893
      {
1003.1.12 by Brian Aker
Begin of abstract out the bitmap from direct reference.
4894
        if (cur_part->field->isReadSet())
1 by brian
clean slate
4895
          goto next_index;
4896
      }
4897
    }
4898
4899
    /* If we got to this point, cur_index_info passes the test. */
1052.1.2 by Joe Daly
Bug #309547. Also identified by MySQL #41610. The read plan being
4900
    key_infix_parts= cur_key_infix_len ?
1 by brian
clean slate
4901
                     (first_non_infix_part - first_non_group_part) : 0;
1052.1.2 by Joe Daly
Bug #309547. Also identified by MySQL #41610. The read plan being
4902
    cur_used_key_parts= cur_group_key_parts + key_infix_parts;
1 by brian
clean slate
4903
4904
    /* Compute the cost of using this index. */
4905
    if (tree)
4906
    {
4907
      /* Find the SEL_ARG sub-tree that corresponds to the chosen index. */
1240.3.1 by Brian Aker
Merge Padraig.
4908
      cur_index_tree= get_index_range_tree(cur_index,
4909
                                           tree,
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4910
                                           param,
1 by brian
clean slate
4911
                                           &cur_param_idx);
4912
      /* Check if this range tree can be used for prefix retrieval. */
1336.3.2 by Djellel E. Difallah
rename class COST_VECT to CostVector and move it to ./drizzled/optimizer directory
4913
      optimizer::CostVector dummy_cost;
482 by Brian Aker
Remove uint.
4914
      uint32_t mrr_flags= HA_MRR_USE_DEFAULT_IMPL;
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4915
      uint32_t mrr_bufsize= 0;
1578.4.11 by Brian Aker
PAss through the code removing current_session
4916
      cur_quick_prefix_records= check_quick_select(session,
4917
                                                   param,
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4918
                                                   cur_param_idx,
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
4919
                                                   false /*don't care*/,
1240.3.1 by Brian Aker
Merge Padraig.
4920
                                                   cur_index_tree,
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4921
                                                   true,
1240.3.1 by Brian Aker
Merge Padraig.
4922
                                                   &mrr_flags,
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4923
                                                   &mrr_bufsize,
1 by brian
clean slate
4924
                                                   &dummy_cost);
4925
    }
1240.3.1 by Brian Aker
Merge Padraig.
4926
    cost_group_min_max(table,
4927
                       cur_index_info,
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4928
                       cur_used_key_parts,
1240.3.1 by Brian Aker
Merge Padraig.
4929
                       cur_group_key_parts,
4930
                       tree,
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4931
                       cur_index_tree,
1240.3.1 by Brian Aker
Merge Padraig.
4932
                       cur_quick_prefix_records,
4933
                       have_min,
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4934
                       have_max,
1240.3.1 by Brian Aker
Merge Padraig.
4935
                       &cur_read_cost,
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4936
                       &cur_records);
1 by brian
clean slate
4937
    /*
4938
      If cur_read_cost is lower than best_read_cost use cur_index.
4939
      Do not compare doubles directly because they may have different
4940
      representations (64 vs. 80 bits).
4941
    */
4942
    if (cur_read_cost < best_read_cost - (DBL_EPSILON * cur_read_cost))
4943
    {
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
4944
      assert(tree != 0 || cur_param_idx == MAX_KEY);
1 by brian
clean slate
4945
      index_info= cur_index_info;
4946
      index= cur_index;
4947
      best_read_cost= cur_read_cost;
4948
      best_records= cur_records;
4949
      best_index_tree= cur_index_tree;
4950
      best_quick_prefix_records= cur_quick_prefix_records;
4951
      best_param_idx= cur_param_idx;
4952
      group_key_parts= cur_group_key_parts;
4953
      group_prefix_len= cur_group_prefix_len;
1052.1.2 by Joe Daly
Bug #309547. Also identified by MySQL #41610. The read plan being
4954
      key_infix_len= cur_key_infix_len;
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4955
1052.1.2 by Joe Daly
Bug #309547. Also identified by MySQL #41610. The read plan being
4956
      if (key_infix_len)
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4957
      {
4958
        memcpy(key_infix, cur_key_infix, sizeof (key_infix));
4959
      }
4960
1052.1.2 by Joe Daly
Bug #309547. Also identified by MySQL #41610. The read plan being
4961
      used_key_parts= cur_used_key_parts;
1 by brian
clean slate
4962
    }
4963
4964
  next_index:
4965
    cur_group_key_parts= 0;
4966
    cur_group_prefix_len= 0;
1052.1.2 by Joe Daly
Bug #309547. Also identified by MySQL #41610. The read plan being
4967
    cur_key_infix_len= 0;
1 by brian
clean slate
4968
  }
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4969
  if (! index_info) /* No usable index found. */
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
4970
    return NULL;
1 by brian
clean slate
4971
4972
  /* Check (SA3) for the where clause. */
4973
  if (join->conds && min_max_arg_item &&
1055.2.5 by Jay Pipes
Removal of dead Field::image_type and st_key_part::image_type member variables. Legacy from geometry MyISAM types...
4974
      ! check_group_min_max_predicates(join->conds, min_max_arg_item))
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
4975
    return NULL;
1 by brian
clean slate
4976
4977
  /* The query passes all tests, so construct a new TRP object. */
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4978
  read_plan=
1237.13.27 by Padraig O'Sullivan
Correcting the case of a number of classes in the optimizer to adhere to the coding standards. Also
4979
    new(param->mem_root) optimizer::GroupMinMaxReadPlan(have_min,
4980
                                                        have_max,
4981
                                                        min_max_arg_part,
4982
                                                        group_prefix_len,
4983
                                                        used_key_parts,
4984
                                                        group_key_parts,
4985
                                                        index_info,
4986
                                                        index,
4987
                                                        key_infix_len,
4988
                                                        (key_infix_len > 0) ? key_infix : NULL,
4989
                                                        tree,
4990
                                                        best_index_tree,
4991
                                                        best_param_idx,
4992
                                                        best_quick_prefix_records);
1 by brian
clean slate
4993
  if (read_plan)
4994
  {
4995
    if (tree && read_plan->quick_prefix_records == 0)
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
4996
      return NULL;
1 by brian
clean slate
4997
4998
    read_plan->read_cost= best_read_cost;
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
4999
    read_plan->records= best_records;
1 by brian
clean slate
5000
  }
5001
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
5002
  return read_plan;
1 by brian
clean slate
5003
}
5004
5005
5006
/*
5007
  Check that the MIN/MAX attribute participates only in range predicates
5008
  with constants.
5009
5010
  SYNOPSIS
5011
    check_group_min_max_predicates()
5012
    cond              tree (or subtree) describing all or part of the WHERE
5013
                      clause being analyzed
5014
    min_max_arg_item  the field referenced by the MIN/MAX function(s)
5015
    min_max_arg_part  the keypart of the MIN/MAX argument if any
5016
5017
  DESCRIPTION
5018
    The function walks recursively over the cond tree representing a WHERE
5019
    clause, and checks condition (SA3) - if a field is referenced by a MIN/MAX
5020
    aggregate function, it is referenced only by one of the following
5021
    predicates: {=, !=, <, <=, >, >=, between, is null, is not null}.
5022
5023
  RETURN
55 by brian
Update for using real bool types.
5024
    true  if cond passes the test
5025
    false o/w
1 by brian
clean slate
5026
*/
1055.2.5 by Jay Pipes
Removal of dead Field::image_type and st_key_part::image_type member variables. Legacy from geometry MyISAM types...
5027
static bool check_group_min_max_predicates(COND *cond, Item_field *min_max_arg_item)
1 by brian
clean slate
5028
{
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
5029
  assert(cond && min_max_arg_item);
1 by brian
clean slate
5030
5031
  cond= cond->real_item();
5032
  Item::Type cond_type= cond->type();
5033
  if (cond_type == Item::COND_ITEM) /* 'AND' or 'OR' */
5034
  {
5035
    List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
5036
    Item *and_or_arg= NULL;
1 by brian
clean slate
5037
    while ((and_or_arg= li++))
5038
    {
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
5039
      if (! check_group_min_max_predicates(and_or_arg, min_max_arg_item))
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
5040
        return false;
1 by brian
clean slate
5041
    }
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
5042
    return true;
1 by brian
clean slate
5043
  }
5044
5045
  /*
5046
    TODO:
5047
    This is a very crude fix to handle sub-selects in the WHERE clause
5048
    (Item_subselect objects). With the test below we rule out from the
5049
    optimization all queries with subselects in the WHERE clause. What has to
5050
    be done, is that here we should analyze whether the subselect references
5051
    the MIN/MAX argument field, and disallow the optimization only if this is
5052
    so.
5053
  */
5054
  if (cond_type == Item::SUBSELECT_ITEM)
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
5055
    return false;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
5056
1 by brian
clean slate
5057
  /* We presume that at this point there are no other Items than functions. */
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
5058
  assert(cond_type == Item::FUNC_ITEM);
1 by brian
clean slate
5059
5060
  /* Test if cond references only group-by or non-group fields. */
5061
  Item_func *pred= (Item_func*) cond;
5062
  Item **arguments= pred->arguments();
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
5063
  Item *cur_arg= NULL;
482 by Brian Aker
Remove uint.
5064
  for (uint32_t arg_idx= 0; arg_idx < pred->argument_count (); arg_idx++)
1 by brian
clean slate
5065
  {
5066
    cur_arg= arguments[arg_idx]->real_item();
5067
    if (cur_arg->type() == Item::FIELD_ITEM)
5068
    {
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
5069
      if (min_max_arg_item->eq(cur_arg, 1))
1 by brian
clean slate
5070
      {
5071
       /*
5072
         If pred references the MIN/MAX argument, check whether pred is a range
5073
         condition that compares the MIN/MAX argument with a constant.
5074
       */
5075
        Item_func::Functype pred_type= pred->functype();
5076
        if (pred_type != Item_func::EQUAL_FUNC     &&
5077
            pred_type != Item_func::LT_FUNC        &&
5078
            pred_type != Item_func::LE_FUNC        &&
5079
            pred_type != Item_func::GT_FUNC        &&
5080
            pred_type != Item_func::GE_FUNC        &&
5081
            pred_type != Item_func::BETWEEN        &&
5082
            pred_type != Item_func::ISNULL_FUNC    &&
5083
            pred_type != Item_func::ISNOTNULL_FUNC &&
5084
            pred_type != Item_func::EQ_FUNC        &&
5085
            pred_type != Item_func::NE_FUNC)
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
5086
          return false;
1 by brian
clean slate
5087
5088
        /* Check that pred compares min_max_arg_item with a constant. */
5089
        Item *args[3];
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
5090
        memset(args, 0, 3 * sizeof(Item*));
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
5091
        bool inv= false;
1 by brian
clean slate
5092
        /* Test if this is a comparison of a field and a constant. */
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
5093
        if (! optimizer::simple_pred(pred, args, inv))
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
5094
          return false;
1 by brian
clean slate
5095
5096
        /* Check for compatible string comparisons - similar to get_mm_leaf. */
5097
        if (args[0] && args[1] && !args[2] && // this is a binary function
5098
            min_max_arg_item->result_type() == STRING_RESULT &&
5099
            /*
5100
              Don't use an index when comparing strings of different collations.
5101
            */
5102
            ((args[1]->result_type() == STRING_RESULT &&
5103
              ((Field_str*) min_max_arg_item->field)->charset() !=
5104
              pred->compare_collation())
5105
             ||
5106
             /*
5107
               We can't always use indexes when comparing a string index to a
5108
               number.
5109
             */
5110
             (args[1]->result_type() != STRING_RESULT &&
5111
              min_max_arg_item->field->cmp_type() != args[1]->result_type())))
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
5112
        {
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
5113
          return false;
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
5114
        }
1 by brian
clean slate
5115
      }
5116
    }
5117
    else if (cur_arg->type() == Item::FUNC_ITEM)
5118
    {
1055.2.5 by Jay Pipes
Removal of dead Field::image_type and st_key_part::image_type member variables. Legacy from geometry MyISAM types...
5119
      if (! check_group_min_max_predicates(cur_arg, min_max_arg_item))
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
5120
        return false;
1 by brian
clean slate
5121
    }
5122
    else if (cur_arg->const_item())
5123
    {
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
5124
      return true;
1 by brian
clean slate
5125
    }
5126
    else
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
5127
      return false;
1 by brian
clean slate
5128
  }
5129
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
5130
  return true;
1 by brian
clean slate
5131
}
5132
5133
5134
/*
5135
  Extract a sequence of constants from a conjunction of equality predicates.
5136
5137
  SYNOPSIS
5138
    get_constant_key_infix()
5139
    index_info             [in]  Descriptor of the chosen index.
5140
    index_range_tree       [in]  Range tree for the chosen index
5141
    first_non_group_part   [in]  First index part after group attribute parts
5142
    min_max_arg_part       [in]  The keypart of the MIN/MAX argument if any
5143
    last_part              [in]  Last keypart of the index
520.1.22 by Brian Aker
Second pass of thd cleanup
5144
    session                    [in]  Current thread
1 by brian
clean slate
5145
    key_infix              [out] Infix of constants to be used for index lookup
5146
    key_infix_len          [out] Lenghth of the infix
5147
    first_non_infix_part   [out] The first keypart after the infix (if any)
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
5148
1 by brian
clean slate
5149
  DESCRIPTION
5150
    Test conditions (NGA1, NGA2) from get_best_group_min_max(). Namely,
5151
    for each keypart field NGF_i not in GROUP-BY, check that there is a
5152
    constant equality predicate among conds with the form (NGF_i = const_ci) or
5153
    (const_ci = NGF_i).
5154
    Thus all the NGF_i attributes must fill the 'gap' between the last group-by
5155
    attribute and the MIN/MAX attribute in the index (if present). If these
5156
    conditions hold, copy each constant from its corresponding predicate into
5157
    key_infix, in the order its NG_i attribute appears in the index, and update
5158
    key_infix_len with the total length of the key parts in key_infix.
5159
5160
  RETURN
55 by brian
Update for using real bool types.
5161
    true  if the index passes the test
5162
    false o/w
1 by brian
clean slate
5163
*/
5164
static bool
1535 by Brian Aker
Rename of KEY to KeyInfo
5165
get_constant_key_infix(KeyInfo *,
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
5166
                       optimizer::SEL_ARG *index_range_tree,
1534 by Brian Aker
Remove of KeyPartInfo
5167
                       KeyPartInfo *first_non_group_part,
5168
                       KeyPartInfo *min_max_arg_part,
5169
                       KeyPartInfo *last_part,
1240.3.1 by Brian Aker
Merge Padraig.
5170
                       Session *,
5171
                       unsigned char *key_infix,
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
5172
                       uint32_t *key_infix_len,
1534 by Brian Aker
Remove of KeyPartInfo
5173
                       KeyPartInfo **first_non_infix_part)
1 by brian
clean slate
5174
{
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
5175
  optimizer::SEL_ARG *cur_range= NULL;
1534 by Brian Aker
Remove of KeyPartInfo
5176
  KeyPartInfo *cur_part= NULL;
1 by brian
clean slate
5177
  /* End part for the first loop below. */
1534 by Brian Aker
Remove of KeyPartInfo
5178
  KeyPartInfo *end_part= min_max_arg_part ? min_max_arg_part : last_part;
1 by brian
clean slate
5179
5180
  *key_infix_len= 0;
481 by Brian Aker
Remove all of uchar.
5181
  unsigned char *key_ptr= key_infix;
1 by brian
clean slate
5182
  for (cur_part= first_non_group_part; cur_part != end_part; cur_part++)
5183
  {
5184
    /*
5185
      Find the range tree for the current keypart. We assume that
5186
      index_range_tree points to the leftmost keypart in the index.
5187
    */
5188
    for (cur_range= index_range_tree; cur_range;
5189
         cur_range= cur_range->next_key_part)
5190
    {
5191
      if (cur_range->field->eq(cur_part->field))
5192
        break;
5193
    }
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
5194
    if (! cur_range)
1 by brian
clean slate
5195
    {
5196
      if (min_max_arg_part)
55 by brian
Update for using real bool types.
5197
        return false; /* The current keypart has no range predicates at all. */
1 by brian
clean slate
5198
      else
5199
      {
5200
        *first_non_infix_part= cur_part;
55 by brian
Update for using real bool types.
5201
        return true;
1 by brian
clean slate
5202
      }
5203
    }
5204
5205
    /* Check that the current range tree is a single point interval. */
5206
    if (cur_range->prev || cur_range->next)
55 by brian
Update for using real bool types.
5207
      return false; /* This is not the only range predicate for the field. */
1 by brian
clean slate
5208
    if ((cur_range->min_flag & NO_MIN_RANGE) ||
5209
        (cur_range->max_flag & NO_MAX_RANGE) ||
1240.3.1 by Brian Aker
Merge Padraig.
5210
        (cur_range->min_flag & NEAR_MIN) ||
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
5211
        (cur_range->max_flag & NEAR_MAX))
55 by brian
Update for using real bool types.
5212
      return false;
1 by brian
clean slate
5213
482 by Brian Aker
Remove uint.
5214
    uint32_t field_length= cur_part->store_length;
1 by brian
clean slate
5215
    if ((cur_range->maybe_null &&
5216
         cur_range->min_value[0] && cur_range->max_value[0]) ||
5217
        !memcmp(cur_range->min_value, cur_range->max_value, field_length))
5218
    {
5219
      /* cur_range specifies 'IS NULL' or an equality condition. */
5220
      memcpy(key_ptr, cur_range->min_value, field_length);
5221
      key_ptr+= field_length;
5222
      *key_infix_len+= field_length;
5223
    }
5224
    else
55 by brian
Update for using real bool types.
5225
      return false;
1 by brian
clean slate
5226
  }
5227
5228
  if (!min_max_arg_part && (cur_part == last_part))
5229
    *first_non_infix_part= last_part;
5230
55 by brian
Update for using real bool types.
5231
  return true;
1 by brian
clean slate
5232
}
5233
5234
5235
/*
5236
  Find the key part referenced by a field.
5237
5238
  SYNOPSIS
5239
    get_field_keypart()
5240
    index  descriptor of an index
5241
    field  field that possibly references some key part in index
5242
5243
  NOTES
1534 by Brian Aker
Remove of KeyPartInfo
5244
    The return value can be used to get a KeyPartInfo pointer by
1 by brian
clean slate
5245
    part= index->key_part + get_field_keypart(...) - 1;
5246
5247
  RETURN
5248
    Positive number which is the consecutive number of the key part, or
5249
    0 if field does not reference any index field.
5250
*/
5251
static inline uint
1535 by Brian Aker
Rename of KEY to KeyInfo
5252
get_field_keypart(KeyInfo *index, Field *field)
1 by brian
clean slate
5253
{
1534 by Brian Aker
Remove of KeyPartInfo
5254
  KeyPartInfo *part= NULL;
5255
  KeyPartInfo *end= NULL;
1 by brian
clean slate
5256
5257
  for (part= index->key_part, end= part + index->key_parts; part < end; part++)
5258
  {
5259
    if (field->eq(part->field))
5260
      return part - index->key_part + 1;
5261
  }
5262
  return 0;
5263
}
5264
5265
5266
/*
5267
  Find the SEL_ARG sub-tree that corresponds to the chosen index.
5268
5269
  SYNOPSIS
5270
    get_index_range_tree()
5271
    index     [in]  The ID of the index being looked for
5272
    range_tree[in]  Tree of ranges being searched
1237.13.7 by Padraig O'Sullivan
Renamed PARAM to Parameter and RANGE_OPT_PARAM to RangeParameter.
5273
    param     [in]  Parameter from SqlSelect::test_quick_select
5274
    param_idx [out] Index in the array Parameter::key that corresponds to 'index'
1 by brian
clean slate
5275
5276
  DESCRIPTION
5277
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
5278
    A optimizer::SEL_TREE contains range trees for all usable indexes. This procedure
5279
    finds the SEL_ARG sub-tree for 'index'. The members of a optimizer::SEL_TREE are
1237.13.7 by Padraig O'Sullivan
Renamed PARAM to Parameter and RANGE_OPT_PARAM to RangeParameter.
5280
    ordered in the same way as the members of Parameter::key, thus we first find
5281
    the corresponding index in the array Parameter::key. This index is returned
1 by brian
clean slate
5282
    through the variable param_idx, to be used later as argument of
5283
    check_quick_select().
5284
5285
  RETURN
5286
    Pointer to the SEL_ARG subtree that corresponds to index.
5287
*/
1237.13.12 by Padraig O'Sullivan
Corrected the name of the QUICK_ROR_INTERSECT_CLASS class to adhere to the drizzle coding standards.
5288
optimizer::SEL_ARG *get_index_range_tree(uint32_t index,
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
5289
                                         optimizer::SEL_TREE* range_tree,
1237.13.12 by Padraig O'Sullivan
Corrected the name of the QUICK_ROR_INTERSECT_CLASS class to adhere to the drizzle coding standards.
5290
                                         optimizer::Parameter *param,
5291
                                         uint32_t *param_idx)
1 by brian
clean slate
5292
{
482 by Brian Aker
Remove uint.
5293
  uint32_t idx= 0; /* Index nr in param->key_parts */
1 by brian
clean slate
5294
  while (idx < param->keys)
5295
  {
5296
    if (index == param->real_keynr[idx])
5297
      break;
5298
    idx++;
5299
  }
5300
  *param_idx= idx;
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
5301
  return range_tree->keys[idx];
1 by brian
clean slate
5302
}
5303
5304
5305
/*
5306
  Compute the cost of a quick_group_min_max_select for a particular index.
5307
5308
  SYNOPSIS
5309
    cost_group_min_max()
5310
    table                [in] The table being accessed
5311
    index_info           [in] The index used to access the table
5312
    used_key_parts       [in] Number of key parts used to access the index
5313
    group_key_parts      [in] Number of index key parts in the group prefix
5314
    range_tree           [in] Tree of ranges for all indexes
5315
    index_tree           [in] The range tree for the current index
5316
    quick_prefix_records [in] Number of records retrieved by the internally
5317
			      used quick range select if any
5318
    have_min             [in] True if there is a MIN function
5319
    have_max             [in] True if there is a MAX function
5320
    read_cost           [out] The cost to retrieve rows via this quick select
5321
    records             [out] The number of rows retrieved
5322
5323
  DESCRIPTION
1237.13.27 by Padraig O'Sullivan
Correcting the case of a number of classes in the optimizer to adhere to the coding standards. Also
5324
    This method computes the access cost of a GroupMinMaxReadPlan instance and
1 by brian
clean slate
5325
    the number of rows returned. It updates this->read_cost and this->records.
5326
5327
  NOTES
5328
    The cost computation distinguishes several cases:
5329
    1) No equality predicates over non-group attributes (thus no key_infix).
5330
       If groups are bigger than blocks on the average, then we assume that it
5331
       is very unlikely that block ends are aligned with group ends, thus even
5332
       if we look for both MIN and MAX keys, all pairs of neighbor MIN/MAX
5333
       keys, except for the first MIN and the last MAX keys, will be in the
5334
       same block.  If groups are smaller than blocks, then we are going to
5335
       read all blocks.
5336
    2) There are equality predicates over non-group attributes.
5337
       In this case the group prefix is extended by additional constants, and
5338
       as a result the min/max values are inside sub-groups of the original
5339
       groups. The number of blocks that will be read depends on whether the
5340
       ends of these sub-groups will be contained in the same or in different
5341
       blocks. We compute the probability for the two ends of a subgroup to be
5342
       in two different blocks as the ratio of:
5343
       - the number of positions of the left-end of a subgroup inside a group,
5344
         such that the right end of the subgroup is past the end of the buffer
5345
         containing the left-end, and
5346
       - the total number of possible positions for the left-end of the
5347
         subgroup, which is the number of keys in the containing group.
5348
       We assume it is very unlikely that two ends of subsequent subgroups are
5349
       in the same block.
5350
    3) The are range predicates over the group attributes.
5351
       Then some groups may be filtered by the range predicates. We use the
5352
       selectivity of the range predicates to decide how many groups will be
5353
       filtered.
5354
5355
  TODO
5356
     - Take into account the optional range predicates over the MIN/MAX
5357
       argument.
5358
     - Check if we have a PK index and we use all cols - then each key is a
5359
       group, and it will be better to use an index scan.
5360
5361
  RETURN
5362
    None
5363
*/
1240.3.1 by Brian Aker
Merge Padraig.
5364
void cost_group_min_max(Table* table,
1535 by Brian Aker
Rename of KEY to KeyInfo
5365
                        KeyInfo *index_info,
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
5366
                        uint32_t used_key_parts,
1240.3.1 by Brian Aker
Merge Padraig.
5367
                        uint32_t group_key_parts,
1237.13.44 by Padraig O'Sullivan
Moved the SEL_TREE and SEL_IMERGE classes out into their own header and implementation files.
5368
                        optimizer::SEL_TREE *range_tree,
1240.3.1 by Brian Aker
Merge Padraig.
5369
                        optimizer::SEL_ARG *,
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
5370
                        ha_rows quick_prefix_records,
1240.3.1 by Brian Aker
Merge Padraig.
5371
                        bool have_min,
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
5372
                        bool have_max,
1240.3.1 by Brian Aker
Merge Padraig.
5373
                        double *read_cost,
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
5374
                        ha_rows *records)
1 by brian
clean slate
5375
{
5376
  ha_rows table_records;
482 by Brian Aker
Remove uint.
5377
  uint32_t num_groups;
5378
  uint32_t num_blocks;
5379
  uint32_t keys_per_block;
5380
  uint32_t keys_per_group;
5381
  uint32_t keys_per_subgroup; /* Average number of keys in sub-groups */
1 by brian
clean slate
5382
                          /* formed by a key infix. */
5383
  double p_overlap; /* Probability that a sub-group overlaps two blocks. */
5384
  double quick_prefix_selectivity;
5385
  double io_cost;
5386
  double cpu_cost= 0; /* TODO: CPU cost of index_read calls? */
5387
1208.3.2 by brian
Update for Cursor renaming.
5388
  table_records= table->cursor->stats.records;
5389
  keys_per_block= (table->cursor->stats.block_size / 2 /
5390
                   (index_info->key_length + table->cursor->ref_length)
1 by brian
clean slate
5391
                        + 1);
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
5392
  num_blocks= (uint32_t) (table_records / keys_per_block) + 1;
1 by brian
clean slate
5393
5394
  /* Compute the number of keys in a group. */
5395
  keys_per_group= index_info->rec_per_key[group_key_parts - 1];
5396
  if (keys_per_group == 0) /* If there is no statistics try to guess */
5397
    /* each group contains 10% of all records */
895 by Brian Aker
Completion (?) of uint conversion.
5398
    keys_per_group= (uint32_t)(table_records / 10) + 1;
5399
  num_groups= (uint32_t)(table_records / keys_per_group) + 1;
1 by brian
clean slate
5400
5401
  /* Apply the selectivity of the quick select for group prefixes. */
5402
  if (range_tree && (quick_prefix_records != HA_POS_ERROR))
5403
  {
5404
    quick_prefix_selectivity= (double) quick_prefix_records /
5405
                              (double) table_records;
895 by Brian Aker
Completion (?) of uint conversion.
5406
    num_groups= (uint32_t) rint(num_groups * quick_prefix_selectivity);
937.2.6 by Stewart Smith
make set_if_bigger typesafe for C and C++. Fix up everywhere.
5407
    set_if_bigger(num_groups, 1U);
1 by brian
clean slate
5408
  }
5409
5410
  if (used_key_parts > group_key_parts)
5411
  { /*
5412
      Compute the probability that two ends of a subgroup are inside
5413
      different blocks.
5414
    */
5415
    keys_per_subgroup= index_info->rec_per_key[used_key_parts - 1];
5416
    if (keys_per_subgroup >= keys_per_block) /* If a subgroup is bigger than */
5417
      p_overlap= 1.0;       /* a block, it will overlap at least two blocks. */
5418
    else
5419
    {
5420
      double blocks_per_group= (double) num_blocks / (double) num_groups;
5421
      p_overlap= (blocks_per_group * (keys_per_subgroup - 1)) / keys_per_group;
1067.4.4 by Nathan Williams
The rest of the files in the drizzled directory were purged of the cmin macro and replace with std::min (except for the definition in globals.h and 1 usage in stacktrace.cc).
5422
      p_overlap= min(p_overlap, 1.0);
1 by brian
clean slate
5423
    }
1067.4.4 by Nathan Williams
The rest of the files in the drizzled directory were purged of the cmin macro and replace with std::min (except for the definition in globals.h and 1 usage in stacktrace.cc).
5424
    io_cost= (double) min(num_groups * (1 + p_overlap), (double)num_blocks);
1 by brian
clean slate
5425
  }
5426
  else
5427
    io_cost= (keys_per_group > keys_per_block) ?
5428
             (have_min && have_max) ? (double) (num_groups + 1) :
5429
                                      (double) num_groups :
5430
             (double) num_blocks;
5431
5432
  /*
5433
    TODO: If there is no WHERE clause and no other expressions, there should be
5434
    no CPU cost. We leave it here to make this cost comparable to that of index
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
5435
    scan as computed in SqlSelect::test_quick_select().
1 by brian
clean slate
5436
  */
5437
  cpu_cost= (double) num_groups / TIME_FOR_COMPARE;
5438
5439
  *read_cost= io_cost + cpu_cost;
5440
  *records= num_groups;
5441
}
5442
5443
5444
/*
5445
  Construct a new quick select object for queries with group by with min/max.
5446
5447
  SYNOPSIS
1237.13.27 by Padraig O'Sullivan
Correcting the case of a number of classes in the optimizer to adhere to the coding standards. Also
5448
    GroupMinMaxReadPlan::make_quick()
1 by brian
clean slate
5449
    param              Parameter from test_quick_select
5450
    retrieve_full_rows ignored
5451
    parent_alloc       Memory pool to use, if any.
5452
5453
  NOTES
5454
    Make_quick ignores the retrieve_full_rows parameter because
1237.13.21 by Padraig O'Sullivan
Corrected some style issues in the QuickGroupMinMaxSelect class.
5455
    QuickGroupMinMaxSelect always performs 'index only' scans.
1 by brian
clean slate
5456
    The other parameter are ignored as well because all necessary
5457
    data to create the QUICK object is computed at this TRP creation
5458
    time.
5459
5460
  RETURN
1237.13.21 by Padraig O'Sullivan
Corrected some style issues in the QuickGroupMinMaxSelect class.
5461
    New QuickGroupMinMaxSelect object if successfully created,
1 by brian
clean slate
5462
    NULL otherwise.
5463
*/
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
5464
optimizer::QuickSelectInterface *
1237.13.27 by Padraig O'Sullivan
Correcting the case of a number of classes in the optimizer to adhere to the coding standards. Also
5465
optimizer::GroupMinMaxReadPlan::make_quick(optimizer::Parameter *param, bool, memory::Root *parent_alloc)
1 by brian
clean slate
5466
{
1237.13.21 by Padraig O'Sullivan
Corrected some style issues in the QuickGroupMinMaxSelect class.
5467
  optimizer::QuickGroupMinMaxSelect *quick= NULL;
1 by brian
clean slate
5468
1237.13.21 by Padraig O'Sullivan
Corrected some style issues in the QuickGroupMinMaxSelect class.
5469
  quick= new optimizer::QuickGroupMinMaxSelect(param->table,
5470
                                               param->session->lex->current_select->join,
5471
                                               have_min,
5472
                                               have_max,
5473
                                               min_max_arg_part,
5474
                                               group_prefix_len,
5475
                                               group_key_parts,
5476
                                               used_key_parts,
5477
                                               index_info,
5478
                                               index,
5479
                                               read_cost,
5480
                                               records,
5481
                                               key_infix_len,
5482
                                               key_infix,
5483
                                               parent_alloc);
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
5484
  if (! quick)
5485
  {
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
5486
    return NULL;
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
5487
  }
1 by brian
clean slate
5488
5489
  if (quick->init())
5490
  {
5491
    delete quick;
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
5492
    return NULL;
1 by brian
clean slate
5493
  }
5494
5495
  if (range_tree)
5496
  {
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
5497
    assert(quick_prefix_records > 0);
1 by brian
clean slate
5498
    if (quick_prefix_records == HA_POS_ERROR)
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
5499
    {
1 by brian
clean slate
5500
      quick->quick_prefix_select= NULL; /* Can't construct a quick select. */
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
5501
    }
1 by brian
clean slate
5502
    else
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
5503
    {
1237.13.2 by Padraig O'Sullivan
Modified the names of 2 classes in the optimizer to adhere to the coding standards.
5504
      /* Make a QuickRangeSelect to be used for group prefix retrieval. */
1240.3.1 by Brian Aker
Merge Padraig.
5505
      quick->quick_prefix_select= optimizer::get_quick_select(param,
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
5506
                                                              param_idx,
5507
                                                              index_tree,
1240.3.1 by Brian Aker
Merge Padraig.
5508
                                                              HA_MRR_USE_DEFAULT_IMPL,
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
5509
                                                              0,
5510
                                                              &quick->alloc);
5511
    }
1 by brian
clean slate
5512
5513
    /*
5514
      Extract the SEL_ARG subtree that contains only ranges for the MIN/MAX
1237.13.2 by Padraig O'Sullivan
Modified the names of 2 classes in the optimizer to adhere to the coding standards.
5515
      attribute, and create an array of QuickRanges to be used by the
1 by brian
clean slate
5516
      new quick select.
5517
    */
5518
    if (min_max_arg_part)
5519
    {
1237.13.6 by Padraig O'Sullivan
Moved the SEL_ARG class into its own header and implementation files. Cleaned up a bunch of style
5520
      optimizer::SEL_ARG *min_max_range= index_tree;
1 by brian
clean slate
5521
      while (min_max_range) /* Find the tree for the MIN/MAX key part. */
5522
      {
5523
        if (min_max_range->field->eq(min_max_arg_part->field))
5524
          break;
5525
        min_max_range= min_max_range->next_key_part;
5526
      }
5527
      /* Scroll to the leftmost interval for the MIN/MAX argument. */
5528
      while (min_max_range && min_max_range->prev)
5529
        min_max_range= min_max_range->prev;
1237.13.2 by Padraig O'Sullivan
Modified the names of 2 classes in the optimizer to adhere to the coding standards.
5530
      /* Create an array of QuickRanges for the MIN/MAX argument. */
1 by brian
clean slate
5531
      while (min_max_range)
5532
      {
5533
        if (quick->add_range(min_max_range))
5534
        {
5535
          delete quick;
5536
          quick= NULL;
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
5537
          return NULL;
1 by brian
clean slate
5538
        }
5539
        min_max_range= min_max_range->next;
5540
      }
5541
    }
5542
  }
5543
  else
5544
    quick->quick_prefix_select= NULL;
5545
5546
  quick->update_key_stat();
5547
  quick->adjust_prefix_ranges();
5548
723 by Brian Aker
Fix for group_min_max test (aka... use MyISAM... need to further test
5549
  return quick;
1 by brian
clean slate
5550
}
5551
5552
1237.13.28 by Padraig O'Sullivan
Modified classes to have names in camel case instead of all upper case. Added default constructors
5553
optimizer::QuickSelectInterface *optimizer::RangeReadPlan::make_quick(optimizer::Parameter *param, bool, memory::Root *parent_alloc)
1237.13.22 by Padraig O'Sullivan
Extracted a number of small classes into the table_read_plan.h header file.
5554
{
5555
  optimizer::QuickRangeSelect *quick= NULL;
5556
  if ((quick= optimizer::get_quick_select(param,
5557
                                          key_idx,
5558
                                          key,
5559
                                          mrr_flags,
5560
                                          mrr_buf_size,
5561
                                          parent_alloc)))
5562
  {
5563
    quick->records= records;
5564
    quick->read_time= read_cost;
5565
  }
5566
  return quick;
5567
}
5568
5569
1802.16.17 by Padraig O'Sullivan
Hack to fix memory leak. This is horrible but lets us get rid of MyBitmap. This hack is needed for now to prevent a memory leak that occurs because mem_root does not always call desctructors of the objects it allocates memory for. The long term solution to this is to remove the use of mem_root from the optimizer. Once that is done, this hack can be taken back out again which I will very gladly do...
5570
uint32_t optimizer::RorScanInfo::findFirstNotSet() const
5571
{
1802.16.19 by Padraig O'Sullivan
Fix for test case failure.
5572
  boost::dynamic_bitset<> map= bitsToBitset();
1802.16.17 by Padraig O'Sullivan
Hack to fix memory leak. This is horrible but lets us get rid of MyBitmap. This hack is needed for now to prevent a memory leak that occurs because mem_root does not always call desctructors of the objects it allocates memory for. The long term solution to this is to remove the use of mem_root from the optimizer. Once that is done, this hack can be taken back out again which I will very gladly do...
5573
  for (boost::dynamic_bitset<>::size_type i= 0; i < map.size(); i++)
5574
  {
5575
    if (! map.test(i))
5576
    {
5577
      return i;
5578
    }
5579
  }
5580
  return map.size();
5581
}
5582
5583
5584
size_t optimizer::RorScanInfo::getBitCount() const
5585
{
1802.16.19 by Padraig O'Sullivan
Fix for test case failure.
5586
  boost::dynamic_bitset<> tmp_bitset= bitsToBitset();
1802.16.17 by Padraig O'Sullivan
Hack to fix memory leak. This is horrible but lets us get rid of MyBitmap. This hack is needed for now to prevent a memory leak that occurs because mem_root does not always call desctructors of the objects it allocates memory for. The long term solution to this is to remove the use of mem_root from the optimizer. Once that is done, this hack can be taken back out again which I will very gladly do...
5587
  return tmp_bitset.count();
5588
}
5589
5590
5591
void optimizer::RorScanInfo::subtractBitset(const boost::dynamic_bitset<>& in_bitset)
5592
{
1802.16.19 by Padraig O'Sullivan
Fix for test case failure.
5593
  boost::dynamic_bitset<> tmp_bitset= bitsToBitset();
1802.16.17 by Padraig O'Sullivan
Hack to fix memory leak. This is horrible but lets us get rid of MyBitmap. This hack is needed for now to prevent a memory leak that occurs because mem_root does not always call desctructors of the objects it allocates memory for. The long term solution to this is to remove the use of mem_root from the optimizer. Once that is done, this hack can be taken back out again which I will very gladly do...
5594
  tmp_bitset-= in_bitset;
5595
  covered_fields= tmp_bitset.to_ulong();
5596
}
5597
5598
5599
boost::dynamic_bitset<> optimizer::RorScanInfo::bitsToBitset() const
5600
{
5601
  string res;
5602
  uint64_t conv= covered_fields;
5603
  while (conv)
5604
  {
5605
    res.push_back((conv & 1) + '0');
5606
    conv>>= 1;
5607
  }
1802.16.19 by Padraig O'Sullivan
Fix for test case failure.
5608
  if (! res.empty())
1802.16.17 by Padraig O'Sullivan
Hack to fix memory leak. This is horrible but lets us get rid of MyBitmap. This hack is needed for now to prevent a memory leak that occurs because mem_root does not always call desctructors of the objects it allocates memory for. The long term solution to this is to remove the use of mem_root from the optimizer. Once that is done, this hack can be taken back out again which I will very gladly do...
5609
  {
1802.16.19 by Padraig O'Sullivan
Fix for test case failure.
5610
    std::reverse(res.begin(), res.end());
1802.16.17 by Padraig O'Sullivan
Hack to fix memory leak. This is horrible but lets us get rid of MyBitmap. This hack is needed for now to prevent a memory leak that occurs because mem_root does not always call desctructors of the objects it allocates memory for. The long term solution to this is to remove the use of mem_root from the optimizer. Once that is done, this hack can be taken back out again which I will very gladly do...
5611
  }
1802.16.18 by Padraig O'Sullivan
Whoops, had a string constructor parameters in the wrong order.
5612
  string final(covered_fields_size - res.length(), '0');
1802.16.17 by Padraig O'Sullivan
Hack to fix memory leak. This is horrible but lets us get rid of MyBitmap. This hack is needed for now to prevent a memory leak that occurs because mem_root does not always call desctructors of the objects it allocates memory for. The long term solution to this is to remove the use of mem_root from the optimizer. Once that is done, this hack can be taken back out again which I will very gladly do...
5613
  final.append(res);
5614
  return (boost::dynamic_bitset<>(final));
5615
}
5616
5617
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
5618
} /* namespace drizzled */