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