#include <quick_group_min_max_select.h>
Public Types | |
enum | { QS_TYPE_RANGE = 0, QS_TYPE_INDEX_MERGE = 1, QS_TYPE_RANGE_DESC = 2, QS_TYPE_ROR_INTERSECT = 4, QS_TYPE_ROR_UNION = 5, QS_TYPE_GROUP_MIN_MAX = 6 } |
Public Member Functions | |
QuickGroupMinMaxSelect (Table *table, Join *join, bool have_min, bool have_max, KeyPartInfo *min_max_arg_part, uint32_t group_prefix_len, uint32_t group_key_parts, uint32_t used_key_parts, KeyInfo *index_info, uint use_index, double read_cost, ha_rows records, uint key_infix_len, unsigned char *key_infix, memory::Root *parent_alloc) | |
bool | add_range (SEL_ARG *sel_range) |
void | update_key_stat () |
void | adjust_prefix_ranges () |
bool | alloc_buffers () |
int | init () |
int | reset () |
int | get_next () |
bool | reverse_sorted () const |
bool | unique_key_range () const |
int | get_type () const |
void | add_keys_and_lengths (std::string *key_names, std::string *used_lengths) |
virtual void | range_end () |
virtual int | init_ror_merged_scan (bool) |
virtual void | save_last_pos () |
virtual void | add_info_string (std::string *) |
virtual bool | is_keys_used (const boost::dynamic_bitset<> &fields) |
Public Attributes | |
memory::Root | alloc |
QuickRangeSelect * | quick_prefix_select |
bool | sorted |
ha_rows | records |
double | read_time |
Table * | head |
uint32_t | index |
uint32_t | max_used_key_length |
uint32_t | used_key_parts |
unsigned char * | last_rowid |
Private Member Functions | |
int | next_prefix () |
int | next_min_in_range () |
int | next_max_in_range () |
int | next_min () |
int | next_max () |
void | update_min_result () |
void | update_max_result () |
Private Attributes | |
Cursor * | cursor |
Join * | join |
KeyInfo * | index_info |
unsigned char * | record |
unsigned char * | tmp_record |
unsigned char * | group_prefix |
uint32_t | group_prefix_len |
uint32_t | group_key_parts |
unsigned char * | last_prefix |
bool | have_min |
bool | have_max |
bool | seen_first_key |
KeyPartInfo * | min_max_arg_part |
uint32_t | min_max_arg_len |
unsigned char * | key_infix |
uint32_t | key_infix_len |
std::vector< QuickRange * > | min_max_ranges |
uint32_t | real_prefix_len |
uint32_t | real_key_parts |
List< Item_sum > * | min_functions |
List< Item_sum > * | max_functions |
List< Item_sum >::iterator * | min_functions_it |
List< Item_sum >::iterator * | max_functions_it |
Index scan for GROUP-BY queries with MIN/MAX aggregate functions.
This class provides a specialized index access method for GROUP-BY queries of the forms:
SELECT A_1,...,A_k, [B_1,...,B_m], [MIN(C)], [MAX(C)] FROM T WHERE [RNG(A_1,...,A_p ; where p <= k)] [AND EQ(B_1,...,B_m)] [AND PC(C)] [AND PA(A_i1,...,A_iq)] GROUP BY A_1,...,A_k;
or
SELECT DISTINCT A_i1,...,A_ik FROM T WHERE [RNG(A_1,...,A_p ; where p <= k)] [AND PA(A_i1,...,A_iq)];
where all selected fields are parts of the same index. The class of queries that can be processed by this quick select is fully specified in the description of get_best_trp_group_min_max() in optimizer/range.cc.
The get_next() method directly produces result tuples, thus obviating the need to call end_send_group() because all grouping is already done inside get_next().
Since one of the requirements is that all select fields are part of the same index, this class produces only index keys, and not complete records.
Definition at line 64 of file quick_group_min_max_select.h.
virtual void drizzled::optimizer::QuickSelectInterface::add_info_string | ( | std::string * | ) | [inline, virtual, inherited] |
Append text representation of quick select structure (what and how is merged) to str. The result is added to "Extra" field in EXPLAIN output.
This function is implemented only by quick selects that merge other quick selects output and/or can produce output suitable for merging.
Reimplemented in drizzled::optimizer::QuickRangeSelect, drizzled::optimizer::QuickIndexMergeSelect, drizzled::optimizer::QuickRorIntersectSelect, and drizzled::optimizer::QuickRorUnionSelect.
void drizzled::optimizer::QuickGroupMinMaxSelect::add_keys_and_lengths | ( | std::string * | key_names, |
std::string * | used_lengths | ||
) | [virtual] |
Append comma-separated list of keys this quick select uses to key_names; append comma-separated list of corresponding used lengths to used_lengths.
SYNOPSIS QuickGroupMinMaxSelect::add_keys_and_lengths()
[out] | key_names | Names of used indexes |
[out] | used_lengths | Corresponding lengths of the index names |
DESCRIPTION This method is used by select_describe to extract the names of the indexes used by a quick select.
Implements drizzled::optimizer::QuickSelectInterface.
Definition at line 731 of file quick_group_min_max_select.cc.
bool drizzled::optimizer::QuickGroupMinMaxSelect::add_range | ( | optimizer::SEL_ARG * | sel_range | ) |
Eventually create and add a new quick range object.
SYNOPSIS QuickGroupMinMaxSelect::add_range()
[in] | sel_range | Range object from which a new object is created |
NOTES Construct a new QuickRange object from a SEL_ARG object, and add it to the array min_max_ranges. If sel_arg is an infinite range, e.g. (x < 5 or x > 4), then skip it and do not construct a quick range.
RETURN
false | on success |
true | otherwise |
Definition at line 190 of file quick_group_min_max_select.cc.
Opens the ranges if there are more conditions in quick_prefix_select than the ones used for jumping through the prefixes.
SYNOPSIS QuickGroupMinMaxSelect::adjust_prefix_ranges()
NOTES quick_prefix_select is made over the conditions on the whole key. It defines a number of ranges of length x. However when jumping through the prefixes we use only the the first few most significant keyparts in the range key. However if there are more keyparts to follow the ones we are using we must make the condition on the key inclusive (because x < "ab" means x[0] < 'a' OR (x[0] == 'a' AND x[1] < 'b'). To achive the above we must turn off the NEAR_MIN/NEAR_MAX
Definition at line 223 of file quick_group_min_max_select.cc.
int drizzled::optimizer::QuickGroupMinMaxSelect::get_next | ( | ) | [virtual] |
Get the next key containing the MIN and/or MAX key for the next group.
SYNOPSIS QuickGroupMinMaxSelect::get_next()
DESCRIPTION The method finds the next subsequent group of records that satisfies the query conditions and finds the keys that contain the MIN/MAX values for the key part referenced by the MIN/MAX function(s). Once a group and its MIN/MAX values are found, store these values in the Item_sum objects for the MIN/MAX functions. The rest of the values in the result row are stored in the Item_field::result_field of each select field. If the query does not contain MIN and/or MAX functions, then the function only finds the group prefix, which is a query answer itself.
NOTES If both MIN and MAX are computed, then we use the fact that if there is no MIN key, there can't be a MAX key as well, so we can skip looking for a MAX key in this case.
RETURN
0 | on success |
HA_ERR_END_OF_FILE | if returned all keys |
other | if some error occurred |
Implements drizzled::optimizer::QuickSelectInterface.
Definition at line 298 of file quick_group_min_max_select.cc.
References drizzled::copy_fields(), and drizzled::key_cmp().
int drizzled::optimizer::QuickGroupMinMaxSelect::get_type | ( | ) | const [inline, virtual] |
Returns the type of this quick select - one of the QS_TYPE_* values
Implements drizzled::optimizer::QuickSelectInterface.
Definition at line 434 of file quick_group_min_max_select.h.
int drizzled::optimizer::QuickGroupMinMaxSelect::init | ( | ) | [virtual] |
Do post-constructor initialization.
SYNOPSIS QuickGroupMinMaxSelect::init()
DESCRIPTION The method performs initialization that cannot be done in the constructor such as memory allocations that may fail. It allocates memory for the group prefix and inifix buffers, and for the lists of MIN/MAX item to be updated during execution.
RETURN
0 | OK |
other | Error code |
Implements drizzled::optimizer::QuickSelectInterface.
Definition at line 99 of file quick_group_min_max_select.cc.
virtual int drizzled::optimizer::QuickSelectInterface::init_ror_merged_scan | ( | bool | ) | [inline, virtual, inherited] |
Initialize this quick select as a merged scan inside a ROR-union or a ROR- intersection scan. The caller must not additionally call init() if this function is called.
If | true, the quick select may use table->Cursor, otherwise it must create and use a separate Cursor object. |
0 | Ok |
other | Error |
Reimplemented in drizzled::optimizer::QuickRangeSelect, and drizzled::optimizer::QuickRorIntersectSelect.
bool drizzled::optimizer::QuickSelectInterface::is_keys_used | ( | const boost::dynamic_bitset<> & | fields | ) | [virtual, inherited] |
Returns true if any index used by this quick select uses field which is marked in passed bitmap.
Reimplemented in drizzled::optimizer::QuickIndexMergeSelect, drizzled::optimizer::QuickRorIntersectSelect, and drizzled::optimizer::QuickRorUnionSelect.
Definition at line 4217 of file range.cc.
Referenced by drizzled::update_query().
int drizzled::optimizer::QuickGroupMinMaxSelect::next_max | ( | ) | [private] |
Retrieve the maximal key in the next group.
SYNOPSIS QuickGroupMinMaxSelect::next_max()
DESCRIPTION Lookup the maximal key of the group, and store it into this->record.
RETURN
0 | on success |
HA_ERR_KEY_NOT_FOUND | if no MAX key was found that fulfills all conditions. |
HA_ERR_END_OF_FILE | - "" - |
other | if some error occurred |
Definition at line 443 of file quick_group_min_max_select.cc.
int drizzled::optimizer::QuickGroupMinMaxSelect::next_max_in_range | ( | ) | [private] |
Find the maximal key in a group that satisfies some range conditions for the min/max argument field.
SYNOPSIS QuickGroupMinMaxSelect::next_max_in_range()
DESCRIPTION Given the sequence of ranges min_max_ranges, find the maximal key that is in the right-most possible range. If there is no such key, then the current group does not have a MAX key that satisfies the WHERE clause. If a key is found, its value is stored in this->record.
RETURN
0 | on success |
HA_ERR_KEY_NOT_FOUND | if there is no key with the given prefix in any of the ranges |
HA_ERR_END_OF_FILE | - "" - |
other | if some error |
Definition at line 625 of file quick_group_min_max_select.cc.
References drizzled::key_cmp().
int drizzled::optimizer::QuickGroupMinMaxSelect::next_min | ( | ) | [private] |
Retrieve the minimal key in the next group.
SYNOPSIS QuickGroupMinMaxSelect::next_min()
DESCRIPTION Find the minimal key within this group such that the key satisfies the query conditions and NULL semantics. The found key is loaded into this->record.
IMPLEMENTATION Depending on the values of min_max_ranges.elements, key_infix_len, and whether there is a NULL in the MIN field, this function may directly return without any data access. In this case we use the key loaded into this->record by the call to this->next_prefix() just before this call.
RETURN
0 | on success |
HA_ERR_KEY_NOT_FOUND | if no MIN key was found that fulfills all conditions. |
HA_ERR_END_OF_FILE | - "" - |
other | if some error occurred |
Definition at line 378 of file quick_group_min_max_select.cc.
References drizzled::key_cmp().
int drizzled::optimizer::QuickGroupMinMaxSelect::next_min_in_range | ( | ) | [private] |
Find the minimal key in a group that satisfies some range conditions for the min/max argument field.
SYNOPSIS QuickGroupMinMaxSelect::next_min_in_range()
DESCRIPTION Given the sequence of ranges min_max_ranges, find the minimal key that is in the left-most possible range. If there is no such key, then the current group does not have a MIN key that satisfies the WHERE clause. If a key is found, its value is stored in this->record.
RETURN
0 | on success |
HA_ERR_KEY_NOT_FOUND | if there is no key with the given prefix in any of the ranges |
HA_ERR_END_OF_FILE | - "" - |
other | if some error |
Definition at line 505 of file quick_group_min_max_select.cc.
References drizzled::key_cmp().
int drizzled::optimizer::QuickGroupMinMaxSelect::next_prefix | ( | ) | [private] |
Determine the prefix of the next group.
SYNOPSIS QuickGroupMinMaxSelect::next_prefix()
DESCRIPTION Determine the prefix of the next group that satisfies the query conditions. If there is a range condition referencing the group attributes, use a QuickRangeSelect object to retrieve the *first* key that satisfies the condition. If there is a key infix of constants, append this infix immediately after the group attributes. The possibly extended prefix is stored in this->group_prefix. The first key of the found group is stored in this->record, on which relies this->next_min().
RETURN
0 | on success |
HA_ERR_KEY_NOT_FOUND | if there is no key with the formed prefix |
HA_ERR_END_OF_FILE | if there are no more keys |
other | if some error occurred |
Definition at line 459 of file quick_group_min_max_select.cc.
virtual void drizzled::optimizer::QuickSelectInterface::range_end | ( | ) | [inline, virtual, inherited] |
Range end should be called when we have looped over the whole index
Reimplemented in drizzled::optimizer::QuickRangeSelect.
int drizzled::optimizer::QuickGroupMinMaxSelect::reset | ( | void | ) | [virtual] |
Initialize a quick group min/max select for key retrieval.
SYNOPSIS QuickGroupMinMaxSelect::reset()
DESCRIPTION Initialize the index chosen for access and find and store the prefix of the last group. The method is expensive since it performs disk access.
RETURN
0 | OK |
other | Error code |
Implements drizzled::optimizer::QuickSelectInterface.
Definition at line 279 of file quick_group_min_max_select.cc.
virtual void drizzled::optimizer::QuickSelectInterface::save_last_pos | ( | ) | [inline, virtual, inherited] |
Save ROWID of last retrieved row in file->ref. This used in ROR-merging.
Reimplemented in drizzled::optimizer::QuickRangeSelect.
Definition at line 235 of file range.h.
Referenced by drizzled::optimizer::QuickRorUnionSelect::get_next().
Determine the total number and length of the keys that will be used for index lookup.
SYNOPSIS QuickGroupMinMaxSelect::update_key_stat()
DESCRIPTION The total length of the keys used for index lookup depends on whether there are any predicates referencing the min/max argument, and/or if the min/max argument field can be NULL. This function does an optimistic analysis whether the search key might be extended by a constant for the min/max keypart. It is 'optimistic' because during actual execution it may happen that a particular range is skipped, and then a shorter key will be used. However this is data dependent and can't be easily estimated here.
RETURN None
Definition at line 235 of file quick_group_min_max_select.cc.
void drizzled::optimizer::QuickGroupMinMaxSelect::update_max_result | ( | ) | [private] |
Update all MAX function results with the newly found value.
SYNOPSIS QuickGroupMinMaxSelect::update_max_result()
DESCRIPTION The method iterates through all MAX functions and updates the result value of each function by calling Item_sum::reset(), which in turn picks the new result value from this->head->getInsertRecord(), previously updated by next_max(). The updated value is stored in a member variable of each of the Item_sum objects, depending on the value type.
IMPLEMENTATION The update must be done separately for MIN and MAX, immediately after next_max() was called, because both MIN and MAX take their result value from the same buffer this->head->getInsertRecord() (i.e. this->record).
RETURN None
Definition at line 723 of file quick_group_min_max_select.cc.
void drizzled::optimizer::QuickGroupMinMaxSelect::update_min_result | ( | ) | [private] |
Update all MIN function results with the newly found value.
SYNOPSIS QuickGroupMinMaxSelect::update_min_result()
DESCRIPTION The method iterates through all MIN functions and updates the result value of each function by calling Item_sum::reset(), which in turn picks the new result value from this->head->getInsertRecord(), previously updated by next_min(). The updated value is stored in a member variable of each of the Item_sum objects, depending on the value type.
IMPLEMENTATION The update must be done separately for MIN and MAX, immediately after next_min() was called and before next_max() is called, because both MIN and MAX take their result value from the same buffer this->head->getInsertRecord() (i.e. this->record).
RETURN None
Definition at line 715 of file quick_group_min_max_select.cc.
Memory pool for this and quick_prefix_select data.
Definition at line 99 of file quick_group_min_max_select.h.
The Cursor used to get data.
Definition at line 69 of file quick_group_min_max_select.h.
uint32_t drizzled::optimizer::QuickGroupMinMaxSelect::group_key_parts [private] |
A number of keyparts in the group prefix
Definition at line 76 of file quick_group_min_max_select.h.
unsigned char* drizzled::optimizer::QuickGroupMinMaxSelect::group_prefix [private] |
Key prefix consisting of the GROUP fields.
Definition at line 74 of file quick_group_min_max_select.h.
uint32_t drizzled::optimizer::QuickGroupMinMaxSelect::group_prefix_len [private] |
Length of the group prefix.
Definition at line 75 of file quick_group_min_max_select.h.
bool drizzled::optimizer::QuickGroupMinMaxSelect::have_max [private] |
a MIN, a MAX, or both.
Definition at line 79 of file quick_group_min_max_select.h.
bool drizzled::optimizer::QuickGroupMinMaxSelect::have_min [private] |
Specify whether we are computing
Definition at line 78 of file quick_group_min_max_select.h.
uint32_t drizzled::optimizer::QuickSelectInterface::index [inherited] |
Index this quick select uses, or MAX_KEY for quick selects that use several indexes
Definition at line 120 of file range.h.
Referenced by drizzled::best_access_path(), drizzled::optimizer::Scan::getStats(), drizzled::test_if_skip_sort_order(), and drizzled::update_query().
The index chosen for data access
Definition at line 71 of file quick_group_min_max_select.h.
Descriptor of the current query
Definition at line 70 of file quick_group_min_max_select.h.
unsigned char* drizzled::optimizer::QuickGroupMinMaxSelect::key_infix [private] |
Infix of constants from equality predicates.
Definition at line 83 of file quick_group_min_max_select.h.
unsigned char* drizzled::optimizer::QuickGroupMinMaxSelect::last_prefix [private] |
Prefix of the last group for detecting EOF.
Definition at line 77 of file quick_group_min_max_select.h.
unsigned char* drizzled::optimizer::QuickSelectInterface::last_rowid [inherited] |
The rowid of last row retrieved by this quick select. This is used only when doing ROR-index_merge selects
Definition at line 138 of file range.h.
Referenced by drizzled::optimizer::QuickRorUnionSelect::get_next().
uint32_t drizzled::optimizer::QuickSelectInterface::max_used_key_length [inherited] |
uint32_t drizzled::optimizer::QuickGroupMinMaxSelect::min_max_arg_len [private] |
The keypart of the only argument field of all MIN/MAX functions. The length of the MIN/MAX argument field
Definition at line 82 of file quick_group_min_max_select.h.
std::vector<QuickRange *> drizzled::optimizer::QuickGroupMinMaxSelect::min_max_ranges [private] |
Array of range ptrs for the MIN/MAX field.
Definition at line 85 of file quick_group_min_max_select.h.
For retrieval of group prefixes.
Definition at line 100 of file quick_group_min_max_select.h.
double drizzled::optimizer::QuickSelectInterface::read_time [inherited] |
time to perform this retrieval
Definition at line 114 of file range.h.
Referenced by drizzled::best_access_path(), and drizzled::make_join_statistics().
uint32_t drizzled::optimizer::QuickGroupMinMaxSelect::real_key_parts [private] |
A number of keyparts in the above value.
Definition at line 87 of file quick_group_min_max_select.h.
uint32_t drizzled::optimizer::QuickGroupMinMaxSelect::real_prefix_len [private] |
Length of key prefix extended with key_infix.
Definition at line 86 of file quick_group_min_max_select.h.
unsigned char* drizzled::optimizer::QuickGroupMinMaxSelect::record [private] |
Buffer where the next record is returned.
Reimplemented from drizzled::optimizer::QuickSelectInterface.
Definition at line 72 of file quick_group_min_max_select.h.
ha_rows drizzled::optimizer::QuickSelectInterface::records [inherited] |
estimate of # of records to be retrieved
Definition at line 113 of file range.h.
Referenced by drizzled::FileSort::run().
bool drizzled::optimizer::QuickGroupMinMaxSelect::seen_first_key [private] |
Denotes whether the first key was retrieved.
Definition at line 80 of file quick_group_min_max_select.h.
unsigned char* drizzled::optimizer::QuickGroupMinMaxSelect::tmp_record [private] |
Temporary storage for next_min(), next_max().
Definition at line 73 of file quick_group_min_max_select.h.
uint32_t drizzled::optimizer::QuickSelectInterface::used_key_parts [inherited] |
Maximum number of (first) key parts this quick select uses for retrieval. eg. for "(key1p1=c1 AND key1p2=c2) OR key1p1=c2" used_key_parts == 2. Applicable if index!= MAX_KEY.
For QUICK_GROUP_MIN_MAX_SELECT it includes MIN/MAX argument keyparts.
Definition at line 133 of file range.h.
Referenced by drizzled::test_if_skip_sort_order().