1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008-2009 Sun Microsystems, Inc.
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.
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.
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
20
#ifndef DRIZZLED_OPTIMIZER_QUICK_RANGE_SELECT_H
21
#define DRIZZLED_OPTIMIZER_QUICK_RANGE_SELECT_H
23
#include "drizzled/optimizer/range.h"
25
#include <boost/dynamic_bitset.hpp>
37
* Quick select that does a range scan on a single key.
39
* The records are returned in key order.
42
class QuickRangeSelect : public QuickSelectInterface
46
DYNAMIC_ARRAY ranges; /**< ordered array of range ptrs */
48
/** Members to deal with case when this quick select is a ROR-merged scan */
49
bool in_ror_merged_scan;
50
boost::dynamic_bitset<> *column_bitmap;
51
boost::dynamic_bitset<> *save_read_set;
52
boost::dynamic_bitset<> *save_write_set;
53
bool free_file; /**< True when this->file is "owned" by this quick select */
55
/* Range pointers to be used when not using MRR interface */
56
QuickRange **cur_range; /**< current element in ranges */
57
QuickRange *last_range;
59
/** Members needed to use the MRR interface */
60
QuickRangeSequenceContext qr_traversal_ctx;
61
uint32_t mrr_buf_size; /**< copy from session->variables.read_rnd_buff_size */
63
/** Info about index we're scanning */
65
KeyPartInfo *key_part_info;
67
bool dont_free; /**< Used by QuickSelectDescending */
70
* Compare if found key is over max-value
71
* @return 0 if key <= range->max_key
72
* @todo: Figure out why can't this function be as simple as cmp_prev().
74
int cmp_next(QuickRange *range);
77
* @return 0 if found key is inside range (found key >= range->min_key).
79
int cmp_prev(QuickRange *range);
82
* Check if current row will be retrieved by this QuickRangeSelect
85
* It is assumed that currently a scan is being done on another index
86
* which reads all necessary parts of the index that is scanned by this
88
* The implementation does a binary search on sorted array of disjoint
89
* ranges, without taking size of range into account.
91
* This function is used to filter out clustered PK scan rows in
92
* index_merge quick select.
95
* @retval true if current row will be retrieved by this quick select
102
uint32_t mrr_flags; /**< Flags to be used with MRR interface */
106
QuickRangeSelect(Session *session,
110
memory::Root *parent_alloc);
119
* Get next possible record using quick-struct.
122
* QuickRangeSelect::get_next()
125
* Record is read into table->getInsertRecord()
128
* @retval 0 Found row
129
* @retval HA_ERR_END_OF_FILE No (more) rows in range
130
* @retaval # Error code
137
* Get the next record with a different prefix.
140
* QuickRangeSelect::get_next_prefix()
141
* @param[in] prefix_length length of cur_prefix
142
* @param[in] cur_prefix prefix of a key to be searched for
145
* Each subsequent call to the method retrieves the first record that has a
146
* prefix with length prefix_length different from cur_prefix, such that the
147
* record with the new prefix is within the ranges described by
148
* this->ranges. The record found is stored into the buffer pointed by
150
* The method is useful for GROUP-BY queries with range conditions to
151
* discover the prefix of the next group that satisfies the range conditions.
154
* This method is a modified copy of QuickRangeSelect::get_next(), so both
155
* methods should be unified into a more general one to reduce code
159
* @retval 0 on success
160
* @retval HA_ERR_END_OF_FILE if returned all keys
161
* @retval other if some error occurred
163
int get_next_prefix(uint32_t prefix_length,
164
key_part_map keypart_map,
165
unsigned char *cur_prefix);
167
bool reverse_sorted() const
173
* @return true if there is only one range and this uses the whole primary key
175
bool unique_key_range() const;
178
* Initialize this quick select to be a ROR-merged scan.
181
* QuickRangeSelect::init_ror_merged_scan()
182
* @param[in] reuse_handler If true, use head->cursor, otherwise create a separate Cursor object
185
* This function creates and prepares for subsequent use a separate Cursor
186
* object if it can't reuse head->cursor. The reason for this is that during
187
* ROR-merge several key scans are performed simultaneously, and a single
188
* Cursor is only capable of preserving context of a single key scan.
190
* In ROR-merge the quick select doing merge does full records retrieval,
191
* merged quick selects read only keys.
194
* @reval 0 ROR child scan initialized, ok to use.
197
int init_ror_merged_scan(bool reuse_handler);
199
void save_last_pos();
203
return QS_TYPE_RANGE;
206
void add_keys_and_lengths(String *key_names, String *used_lengths);
208
void add_info_string(String *str);
217
/* Used only by QuickSelectDescending */
218
QuickRangeSelect(const QuickRangeSelect& org) : QuickSelectInterface()
220
memmove(this, &org, sizeof(*this));
222
Use default MRR implementation for reverse scans. No table engine
223
currently can do an MRR scan with output in reverse index order.
225
mrr_flags|= HA_MRR_USE_DEFAULT_IMPL;
229
friend class ::drizzled::RorIntersectReadPlan;
232
QuickRangeSelect *get_quick_select_for_ref(Session *session, Table *table,
233
struct table_reference_st *ref,
236
friend bool get_quick_keys(Parameter *param,
237
QuickRangeSelect *quick,
240
unsigned char *min_key,
241
uint32_t min_key_flag,
242
unsigned char *max_key,
243
uint32_t max_key_flag);
245
friend QuickRangeSelect *get_quick_select(Parameter *,
249
uint32_t mrr_buf_size,
250
memory::Root *alloc);
251
friend class QuickSelectDescending;
253
friend class QuickIndexMergeSelect;
255
friend class QuickRorIntersectSelect;
257
friend class QuickGroupMinMaxSelect;
259
friend uint32_t quick_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range);
261
friend range_seq_t quick_range_seq_init(void *init_param,
265
friend void select_describe(Join *join,
269
const char *message);
272
class QuickSelectDescending : public QuickRangeSelect
276
QuickSelectDescending(QuickRangeSelect *q,
277
uint32_t used_key_parts,
282
bool reverse_sorted() const
289
return QS_TYPE_RANGE_DESC;
294
bool range_reads_after_key(QuickRange *range);
298
rev_it= rev_ranges.begin();
299
return QuickRangeSelect::reset();
302
std::vector<QuickRange *> rev_ranges;
304
std::vector<QuickRange *>::iterator rev_it;
308
} /* namespace optimizer */
310
} /* namespace drizzled */
312
#endif /* DRIZZLED_OPTIMIZER_QUICK_RANGE_SELECT_H */