21 #include <drizzled/session.h>
22 #include <drizzled/sql_select.h>
24 #include <drizzled/optimizer/range.h>
25 #include <drizzled/optimizer/quick_group_min_max_select.h>
26 #include <drizzled/optimizer/quick_range.h>
27 #include <drizzled/optimizer/quick_range_select.h>
28 #include <drizzled/optimizer/sel_arg.h>
29 #include <drizzled/internal/m_string.h>
30 #include <drizzled/util/functors.h>
31 #include <drizzled/key.h>
32 #include <drizzled/table.h>
33 #include <drizzled/system_variables.h>
42 QuickGroupMinMaxSelect::QuickGroupMinMaxSelect(Table *table,
46 KeyPartInfo *min_max_arg_part_arg,
47 uint32_t group_prefix_len_arg,
48 uint32_t group_key_parts_arg,
49 uint32_t used_key_parts_arg,
50 KeyInfo *index_info_arg,
54 uint32_t key_infix_len_arg,
55 unsigned char *key_infix_arg,
56 memory::Root *parent_alloc)
59 index_info(index_info_arg),
60 group_prefix_len(group_prefix_len_arg),
61 group_key_parts(group_key_parts_arg),
62 have_min(have_min_arg),
63 have_max(have_max_arg),
64 seen_first_key(false),
65 min_max_arg_part(min_max_arg_part_arg),
66 key_infix(key_infix_arg),
67 key_infix_len(key_infix_len_arg),
68 min_functions_it(NULL),
69 max_functions_it(NULL)
74 record= head->record[0];
75 tmp_record= head->getUpdateRecord();
78 used_key_parts= used_key_parts_arg;
79 real_key_parts= used_key_parts_arg;
80 real_prefix_len= group_prefix_len + key_infix_len;
82 min_max_arg_len= min_max_arg_part ? min_max_arg_part->store_length : 0;
88 assert(! parent_alloc);
91 alloc.init(join->session->variables.range_alloc_block_size);
92 join->session->mem_root= &alloc;
95 memset(&alloc, 0,
sizeof(memory::Root));
111 if (key_infix_len > 0)
117 unsigned char *tmp_key_infix=
alloc.
alloc(key_infix_len);
118 memcpy(tmp_key_infix, this->
key_infix, key_infix_len);
122 if (min_max_arg_part)
127 while (
Item_sum* min_max_item= *(func_ptr++))
129 if (
have_min && (min_max_item->sum_func() == Item_sum::MIN_FUNC))
130 min_functions->push_back(min_max_item);
131 else if (
have_max && (min_max_item->sum_func() == Item_sum::MAX_FUNC))
132 max_functions->push_back(min_max_item);
143 QuickGroupMinMaxSelect::~QuickGroupMinMaxSelect()
145 if (
cursor->inited != Cursor::NONE)
149 if (min_max_arg_part)
157 delete min_functions_it;
158 delete max_functions_it;
166 uint32_t range_flag= sel_range->min_flag | sel_range->max_flag;
169 if ((range_flag & NO_MIN_RANGE) && (range_flag & NO_MAX_RANGE))
172 if (! (sel_range->min_flag & NO_MIN_RANGE) &&
173 ! (sel_range->max_flag & NO_MAX_RANGE))
175 if (sel_range->maybe_null &&
176 sel_range->min_value[0] && sel_range->max_value[0])
177 range_flag|= NULL_RANGE;
178 else if (memcmp(sel_range->min_value, sel_range->max_value,
180 range_flag|= EQ_RANGE;
184 make_keypart_map(sel_range->part),
185 sel_range->max_value,
187 make_keypart_map(sel_range->part),
202 for (
size_t inx= 0; inx < arr.size(); inx++)
203 reinterpret_cast<QuickRange**>(arr.buffer)[inx]->flag &= ~(NEAR_MIN | NEAR_MAX);
217 if (! (cur_range->flag & NO_MIN_RANGE))
227 if (! (cur_range->flag & NO_MAX_RANGE))
235 else if (
have_min && min_max_arg_part &&
236 min_max_arg_part->field->real_maybe_null())
256 cursor->extra(HA_EXTRA_KEYREAD);
262 if (result == HA_ERR_END_OF_FILE)
276 int is_last_prefix= 0;
293 assert(is_last_prefix <= 0);
297 if (result == HA_ERR_KEY_NOT_FOUND)
331 }
while ((result == HA_ERR_KEY_NOT_FOUND || result == HA_ERR_END_OF_FILE) &&
332 is_last_prefix != 0);
344 else if (result == HA_ERR_KEY_NOT_FOUND)
345 result= HA_ERR_END_OF_FILE;
364 if (key_infix_len > 0)
380 if (min_max_arg_part && min_max_arg_part->field->is_null())
403 else if (result == HA_ERR_KEY_NOT_FOUND || result == HA_ERR_END_OF_FILE)
462 if (key_infix_len > 0)
473 ha_rkey_function find_flag;
474 key_part_map keypart_map;
476 bool found_null=
false;
477 int result= HA_ERR_KEY_NOT_FOUND;
478 basic_string<unsigned char> max_key;
493 ! (cur_range->flag & NO_MAX_RANGE) &&
495 (
const unsigned char*) cur_range->max_key,
499 if (cur_range->flag & NO_MIN_RANGE)
502 find_flag= HA_READ_KEY_EXACT;
509 cur_range->min_length);
511 find_flag= (cur_range->flag & (EQ_RANGE | NULL_RANGE)) ?
512 HA_READ_KEY_EXACT : (cur_range->flag & NEAR_MIN) ?
513 HA_READ_AFTER_KEY : HA_READ_KEY_OR_NEXT;
519 if ((result == HA_ERR_KEY_NOT_FOUND || result == HA_ERR_END_OF_FILE) &&
520 (cur_range->flag & (EQ_RANGE | NULL_RANGE)))
532 if (cur_range->flag & EQ_RANGE)
535 if (cur_range->flag & NULL_RANGE)
549 result= HA_ERR_KEY_NOT_FOUND;
554 if (! (cur_range->flag & NO_MAX_RANGE) )
559 max_key.append(cur_range->max_key, cur_range->max_length);
564 if (! (((cur_range->flag & NEAR_MAX) && (cmp_res == -1)) ||
567 result= HA_ERR_KEY_NOT_FOUND;
580 if (found_null && result)
591 ha_rkey_function find_flag;
592 key_part_map keypart_map;
595 basic_string<unsigned char> min_key;
600 for (vector<QuickRange *>::reverse_iterator rit=
min_max_ranges.rbegin();
611 ! (cur_range->flag & NO_MIN_RANGE) &&
613 (
const unsigned char*) cur_range->min_key,
617 if (cur_range->flag & NO_MAX_RANGE)
620 find_flag= HA_READ_PREFIX_LAST;
627 cur_range->max_length);
629 find_flag= (cur_range->flag & EQ_RANGE) ?
630 HA_READ_KEY_EXACT : (cur_range->flag & NEAR_MAX) ?
631 HA_READ_BEFORE_KEY : HA_READ_PREFIX_LAST_OR_PREV;
638 if ((result == HA_ERR_KEY_NOT_FOUND || result == HA_ERR_END_OF_FILE) &&
639 (cur_range->flag & EQ_RANGE))
649 if (cur_range->flag & EQ_RANGE)
657 if (! (cur_range->flag & NO_MIN_RANGE) )
662 min_key.append(cur_range->min_key, cur_range->min_length);
668 if (! (((cur_range->flag & NEAR_MIN) && (cmp_res == 1)) ||
675 return HA_ERR_KEY_NOT_FOUND;
681 *min_functions_it= min_functions->begin();
682 for (
Item_sum *min_func; (min_func= (*min_functions_it)++); )
689 *max_functions_it= max_functions->begin();
690 for (
Item_sum *max_func; (max_func= (*max_functions_it)++); )
696 string *used_lengths)
701 used_lengths->append(buf, length);
bool add_range(SEL_ARG *sel_range)
int get_next_prefix(uint32_t prefix_length, key_part_map keypart_map, unsigned char *cur_prefix)
unsigned char * alloc(size_t Size)
Allocate a chunk of memory from the Root structure provided, obtaining more memory from the heap if n...
void copy_fields(Tmp_Table_Param *param)
TODO: Rename this file - func.h is stupid.
uint32_t max_used_key_length
unsigned char * key_infix
QuickRangeSelect * quick_prefix_select
void add_keys_and_lengths(std::string *key_names, std::string *used_lengths)
int key_cmp(KeyPartInfo *key_part, const unsigned char *key, uint32_t key_length)
unsigned char * tmp_record
unsigned char * group_prefix
void adjust_prefix_ranges()
uint32_t group_prefix_len
virtual int index_read_map(unsigned char *buf, const unsigned char *key, key_part_map keypart_map, enum ha_rkey_function find_flag)
Positions an index cursor to the index specified in the handle. Fetches the row if available...
unsigned char * last_prefix
void free_root(myf MyFLAGS)
Deallocate everything used by alloc_root or just move used blocks to free list if called with MY_USED...
std::vector< QuickRange * > min_max_ranges