summaryrefslogtreecommitdiff
path: root/sql/opt_range.h
diff options
context:
space:
mode:
authorMartin Hansson <martin.hansson@sun.com>2010-05-10 09:23:23 +0200
committerMartin Hansson <martin.hansson@sun.com>2010-05-10 09:23:23 +0200
commit1c5200f67d3a5669b987979227d5e314082b00db (patch)
tree0be844b85d1c0561f003ae224114fe675ca35a3b /sql/opt_range.h
parentbea068326fa72be791bac5c2f1658e27e7080cb9 (diff)
downloadmariadb-git-1c5200f67d3a5669b987979227d5e314082b00db.tar.gz
Bug#50939: Loose Index Scan unduly relies on engine to
remember range endpoints The Loose Index Scan optimization keeps track of a sequence of intervals. For the current interval it maintains the current interval's endpoints. But the maximum endpoint was not stored in the SQL layer; rather, it relied on the storage engine to retain this value in-between reads. By coincidence this holds for MyISAM and InnoDB. Not for the partitioning engine, however. Fixed by making the key values iterator (QUICK_RANGE_SELECT) keep track of the current maximum endpoint. This is also more efficient as we save a call through the handler API in case of open-ended intervals. The code to calculate endpoints was extracted into separate methods in QUICK_RANGE_SELECT, and it was possible to get rid of some code duplication as part of fix.
Diffstat (limited to 'sql/opt_range.h')
-rw-r--r--sql/opt_range.h83
1 files changed, 81 insertions, 2 deletions
diff --git a/sql/opt_range.h b/sql/opt_range.h
index 8d2ba1bb0a6..e7d8297faf8 100644
--- a/sql/opt_range.h
+++ b/sql/opt_range.h
@@ -65,6 +65,85 @@ class QUICK_RANGE :public Sql_alloc {
dummy=0;
#endif
}
+
+ /**
+ Initalizes a key_range object for communication with storage engine.
+
+ This function facilitates communication with the Storage Engine API by
+ translating the minimum endpoint of the interval represented by this
+ QUICK_RANGE into an index range endpoint specifier for the engine.
+
+ @param Pointer to an uninitialized key_range C struct.
+
+ @param prefix_length The length of the search key prefix to be used for
+ lookup.
+
+ @param keypart_map A set (bitmap) of keyparts to be used.
+ */
+ void make_min_endpoint(key_range *kr, uint prefix_length,
+ key_part_map keypart_map) {
+ make_min_endpoint(kr);
+ kr->length= min(kr->length, prefix_length);
+ kr->keypart_map&= keypart_map;
+ }
+
+ /**
+ Initalizes a key_range object for communication with storage engine.
+
+ This function facilitates communication with the Storage Engine API by
+ translating the minimum endpoint of the interval represented by this
+ QUICK_RANGE into an index range endpoint specifier for the engine.
+
+ @param Pointer to an uninitialized key_range C struct.
+ */
+ void make_min_endpoint(key_range *kr) {
+ kr->key= (const uchar*)min_key;
+ kr->length= min_length;
+ kr->keypart_map= min_keypart_map;
+ kr->flag= ((flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
+ (flag & EQ_RANGE) ? HA_READ_KEY_EXACT : HA_READ_KEY_OR_NEXT);
+ }
+
+ /**
+ Initalizes a key_range object for communication with storage engine.
+
+ This function facilitates communication with the Storage Engine API by
+ translating the maximum endpoint of the interval represented by this
+ QUICK_RANGE into an index range endpoint specifier for the engine.
+
+ @param Pointer to an uninitialized key_range C struct.
+
+ @param prefix_length The length of the search key prefix to be used for
+ lookup.
+
+ @param keypart_map A set (bitmap) of keyparts to be used.
+ */
+ void make_max_endpoint(key_range *kr, uint prefix_length,
+ key_part_map keypart_map) {
+ make_max_endpoint(kr);
+ kr->length= min(kr->length, prefix_length);
+ kr->keypart_map&= keypart_map;
+ }
+
+ /**
+ Initalizes a key_range object for communication with storage engine.
+
+ This function facilitates communication with the Storage Engine API by
+ translating the maximum endpoint of the interval represented by this
+ QUICK_RANGE into an index range endpoint specifier for the engine.
+
+ @param Pointer to an uninitialized key_range C struct.
+ */
+ void make_max_endpoint(key_range *kr) {
+ kr->key= (const uchar*)max_key;
+ kr->length= max_length;
+ kr->keypart_map= max_keypart_map;
+ /*
+ We use READ_AFTER_KEY here because if we are reading on a key
+ prefix we want to find all keys with this prefix
+ */
+ kr->flag= (flag & NEAR_MAX ? HA_READ_BEFORE_KEY : HA_READ_AFTER_KEY);
+ }
};
@@ -331,7 +410,7 @@ public:
int reset(void);
int get_next();
void range_end();
- int get_next_prefix(uint prefix_length, key_part_map keypart_map,
+ int get_next_prefix(uint prefix_length, uint group_key_parts,
uchar *cur_prefix);
bool reverse_sorted() { return 0; }
bool unique_key_range();
@@ -611,7 +690,7 @@ private:
uchar *record; /* Buffer where the next record is returned. */
uchar *tmp_record; /* Temporary storage for next_min(), next_max(). */
uchar *group_prefix; /* Key prefix consisting of the GROUP fields. */
- uint group_prefix_len; /* Length of the group prefix. */
+ const uint group_prefix_len; /* Length of the group prefix. */
uint group_key_parts; /* A number of keyparts in the group prefix */
uchar *last_prefix; /* Prefix of the last group for detecting EOF. */
bool have_min; /* Specify whether we are computing */