~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/optimizer/quick_range_select.h

  • Committer: Padraig O'Sullivan
  • Date: 2009-08-08 04:22:33 UTC
  • mto: (1115.3.4 captain)
  • mto: This revision was merged to the branch mainline in revision 1117.
  • Revision ID: osullivan.padraig@gmail.com-20090808042233-q0z88zc490z3f3r7
Renamed the Command class to be Statement. Renamed the command directory to
statement and also the command header file to statement. Updated various
source files to reflect this renaming.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 
 *
4
 
 *  Copyright (C) 2008-2009 Sun Microsystems
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
 
 */
19
 
 
20
 
#ifndef DRIZZLED_OPTIMIZER_QUICK_RANGE_SELECT_H
21
 
#define DRIZZLED_OPTIMIZER_QUICK_RANGE_SELECT_H
22
 
 
23
 
#include "drizzled/optimizer/range.h"
24
 
 
25
 
#include <vector>
26
 
 
27
 
namespace drizzled
28
 
{
29
 
 
30
 
class Cursor;
31
 
 
32
 
namespace optimizer
33
 
{
34
 
 
35
 
/**
36
 
 * Quick select that does a range scan on a single key. 
37
 
 *
38
 
 * The records are returned in key order.
39
 
 * 
40
 
 */
41
 
class QuickRangeSelect : public QuickSelectInterface
42
 
{
43
 
 
44
 
public:
45
 
 
46
 
  uint32_t mrr_flags; /**< Flags to be used with MRR interface */
47
 
 
48
 
  memory::Root alloc;
49
 
 
50
 
  QuickRangeSelect(Session *session,
51
 
                     Table *table,
52
 
                     uint32_t index_arg,
53
 
                     bool no_alloc,
54
 
                     memory::Root *parent_alloc,
55
 
                     bool *create_err);
56
 
 
57
 
  ~QuickRangeSelect();
58
 
 
59
 
  int init();
60
 
 
61
 
  int reset(void);
62
 
 
63
 
  /**
64
 
   * Get next possible record using quick-struct.
65
 
   *
66
 
   * SYNOPSIS
67
 
   * QuickRangeSelect::get_next()
68
 
   *
69
 
   * NOTES
70
 
   * Record is read into table->record[0]
71
 
   *
72
 
   * RETURN
73
 
   * @retval 0                  Found row
74
 
   * @retval HA_ERR_END_OF_FILE No (more) rows in range
75
 
   * @retaval # Error code
76
 
   */
77
 
  int get_next();
78
 
 
79
 
  void range_end();
80
 
 
81
 
  /**
82
 
   * Get the next record with a different prefix.
83
 
   *
84
 
   * SYNOPSIS
85
 
   * QuickRangeSelect::get_next_prefix()
86
 
   * @param[in] prefix_length  length of cur_prefix
87
 
   * @param[in] cur_prefix     prefix of a key to be searched for
88
 
   *
89
 
   * DESCRIPTION
90
 
   * Each subsequent call to the method retrieves the first record that has a
91
 
   * prefix with length prefix_length different from cur_prefix, such that the
92
 
   * record with the new prefix is within the ranges described by
93
 
   * this->ranges. The record found is stored into the buffer pointed by
94
 
   * this->record.
95
 
   * The method is useful for GROUP-BY queries with range conditions to
96
 
   * discover the prefix of the next group that satisfies the range conditions.
97
 
   *
98
 
   * @todo
99
 
   * This method is a modified copy of QuickRangeSelect::get_next(), so both
100
 
   * methods should be unified into a more general one to reduce code
101
 
   * duplication.
102
 
   *
103
 
   * RETURN
104
 
   * @retval 0                  on success
105
 
   * @retval HA_ERR_END_OF_FILE if returned all keys
106
 
   * @retval other              if some error occurred
107
 
   */
108
 
  int get_next_prefix(uint32_t prefix_length,
109
 
                      key_part_map keypart_map,
110
 
                      unsigned char *cur_prefix);
111
 
 
112
 
  bool reverse_sorted() const
113
 
  {
114
 
    return false;
115
 
  }
116
 
 
117
 
  /**
118
 
   * @return true if there is only one range and this uses the whole primary key
119
 
   */
120
 
  bool unique_key_range() const;
121
 
 
122
 
  /**
123
 
   * Initialize this quick select to be a ROR-merged scan.
124
 
   *
125
 
   * SYNOPSIS
126
 
   * QuickRangeSelect::init_ror_merged_scan()
127
 
   * @param[in] reuse_handler If true, use head->cursor, otherwise create a separate Cursor object
128
 
   *
129
 
   * NOTES
130
 
   * This function creates and prepares for subsequent use a separate Cursor
131
 
   * object if it can't reuse head->cursor. The reason for this is that during
132
 
   * ROR-merge several key scans are performed simultaneously, and a single
133
 
   * Cursor is only capable of preserving context of a single key scan.
134
 
   *
135
 
   * In ROR-merge the quick select doing merge does full records retrieval,
136
 
   * merged quick selects read only keys.
137
 
   *
138
 
   * RETURN
139
 
   * @reval 0  ROR child scan initialized, ok to use.
140
 
   * @retval 1  error
141
 
   */
142
 
  int init_ror_merged_scan(bool reuse_handler);
143
 
 
144
 
  void save_last_pos();
145
 
 
146
 
  int get_type() const
147
 
  {
148
 
    return QS_TYPE_RANGE;
149
 
  }
150
 
 
151
 
  void add_keys_and_lengths(String *key_names, String *used_lengths);
152
 
 
153
 
  void add_info_string(String *str);
154
 
 
155
 
  void resetCursor()
156
 
  {
157
 
    cursor= NULL;
158
 
  }
159
 
 
160
 
protected:
161
 
 
162
 
  Cursor *cursor;
163
 
  DYNAMIC_ARRAY ranges; /**< ordered array of range ptrs */
164
 
 
165
 
  /** Members to deal with case when this quick select is a ROR-merged scan */
166
 
  bool in_ror_merged_scan;
167
 
  MyBitmap column_bitmap;
168
 
  MyBitmap *save_read_set;
169
 
  MyBitmap *save_write_set;
170
 
  bool free_file; /**< True when this->file is "owned" by this quick select */
171
 
 
172
 
  /* Range pointers to be used when not using MRR interface */
173
 
  QuickRange **cur_range; /**< current element in ranges  */
174
 
  QuickRange *last_range;
175
 
 
176
 
  /** Members needed to use the MRR interface */
177
 
  QuickRangeSequenceContext qr_traversal_ctx;
178
 
  uint32_t mrr_buf_size; /**< copy from session->variables.read_rnd_buff_size */
179
 
  HANDLER_BUFFER *mrr_buf_desc; /**< the Cursor buffer */
180
 
 
181
 
  /** Info about index we're scanning */
182
 
  KEY_PART *key_parts;
183
 
  KEY_PART_INFO *key_part_info;
184
 
 
185
 
  bool dont_free; /**< Used by QuickSelectDescending */
186
 
 
187
 
  /**
188
 
   * Compare if found key is over max-value
189
 
   * @return 0 if key <= range->max_key
190
 
   * @todo: Figure out why can't this function be as simple as cmp_prev().
191
 
   */
192
 
  int cmp_next(QuickRange *range);
193
 
 
194
 
  /**
195
 
   * @return 0 if found key is inside range (found key >= range->min_key).
196
 
   */
197
 
  int cmp_prev(QuickRange *range);
198
 
 
199
 
  /**
200
 
   * Check if current row will be retrieved by this QuickRangeSelect
201
 
   *
202
 
   * NOTES
203
 
   * It is assumed that currently a scan is being done on another index
204
 
   * which reads all necessary parts of the index that is scanned by this
205
 
   * quick select.
206
 
   * The implementation does a binary search on sorted array of disjoint
207
 
   * ranges, without taking size of range into account.
208
 
   *
209
 
   * This function is used to filter out clustered PK scan rows in
210
 
   * index_merge quick select.
211
 
   *
212
 
   * RETURN
213
 
   * @retval true  if current row will be retrieved by this quick select
214
 
   * false if not
215
 
   */
216
 
  bool row_in_ranges();
217
 
 
218
 
private:
219
 
 
220
 
  /* Used only by QuickSelectDescending */
221
 
  QuickRangeSelect(const QuickRangeSelect& org) : QuickSelectInterface()
222
 
  {
223
 
    memmove(this, &org, sizeof(*this));
224
 
    /*
225
 
      Use default MRR implementation for reverse scans. No table engine
226
 
      currently can do an MRR scan with output in reverse index order.
227
 
    */
228
 
    mrr_buf_desc= NULL;
229
 
    mrr_flags|= HA_MRR_USE_DEFAULT_IMPL;
230
 
    mrr_buf_size= 0;
231
 
  }
232
 
 
233
 
  friend class ::drizzled::RorIntersectReadPlan; 
234
 
 
235
 
  friend
236
 
  QuickRangeSelect *get_quick_select_for_ref(Session *session, Table *table,
237
 
                                             struct table_reference_st *ref,
238
 
                                             ha_rows records);
239
 
 
240
 
  friend bool get_quick_keys(Parameter *param, 
241
 
                             QuickRangeSelect *quick,
242
 
                             KEY_PART *key, 
243
 
                             SEL_ARG *key_tree,
244
 
                             unsigned char *min_key, 
245
 
                             uint32_t min_key_flag,
246
 
                             unsigned char *max_key, 
247
 
                             uint32_t max_key_flag);
248
 
 
249
 
  friend QuickRangeSelect *get_quick_select(Parameter *,
250
 
                                            uint32_t idx,
251
 
                                            SEL_ARG *key_tree,
252
 
                                            uint32_t mrr_flags,
253
 
                                            uint32_t mrr_buf_size,
254
 
                                            memory::Root *alloc);
255
 
  friend class QuickSelectDescending;
256
 
 
257
 
  friend class QuickIndexMergeSelect;
258
 
 
259
 
  friend class QuickRorIntersectSelect;
260
 
 
261
 
  friend class QuickGroupMinMaxSelect;
262
 
 
263
 
  friend uint32_t quick_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range);
264
 
 
265
 
  friend range_seq_t quick_range_seq_init(void *init_param,
266
 
                                          uint32_t n_ranges, 
267
 
                                          uint32_t flags);
268
 
 
269
 
  friend void select_describe(JOIN *join, 
270
 
                              bool need_tmp_table, 
271
 
                              bool need_order,
272
 
                              bool distinct,
273
 
                              const char *message);
274
 
};
275
 
 
276
 
class QuickSelectDescending : public QuickRangeSelect
277
 
{
278
 
public:
279
 
 
280
 
  QuickSelectDescending(QuickRangeSelect *q, 
281
 
                        uint32_t used_key_parts,
282
 
                        bool *create_err);
283
 
 
284
 
  int get_next();
285
 
 
286
 
  bool reverse_sorted() const
287
 
  { 
288
 
    return true; 
289
 
  }
290
 
 
291
 
  int get_type() const
292
 
  { 
293
 
    return QS_TYPE_RANGE_DESC;
294
 
  }
295
 
 
296
 
private:
297
 
 
298
 
  bool range_reads_after_key(QuickRange *range);
299
 
 
300
 
  int reset(void) 
301
 
  { 
302
 
    rev_it= rev_ranges.begin();
303
 
    return QuickRangeSelect::reset();
304
 
  }
305
 
 
306
 
  std::vector<QuickRange *> rev_ranges;
307
 
 
308
 
  std::vector<QuickRange *>::iterator rev_it;
309
 
 
310
 
};
311
 
 
312
 
} /* namespace optimizer */
313
 
 
314
 
} /* namespace drizzled */
315
 
 
316
 
#endif /* DRIZZLED_OPTIMIZER_QUICK_RANGE_SELECT_H */