Added page_range to records_in_range() to improve range statistics

Prototype change:
-  virtual ha_rows records_in_range(uint inx, key_range *min_key,
-                                   key_range *max_key)
+  virtual ha_rows records_in_range(uint inx, const key_range *min_key,
+                                   const key_range *max_key,
+                                   page_range *res)

The handler can ignore the page_range parameter. In the case the handler
updates the parameter, the optimizer can deduce the following:
- If previous range's last key is on the same block as next range's first
  key
- If the current key range is in one block
- We can also assume that the first and last block read are cached!
  This can be used for a better calculation of IO seeks when we
  estimate the cost of a range index scan.

The parameter is fully implemented for MyISAM, Aria and InnoDB.
A separate patch will update handler::multi_range_read_info_const() to
take the benefits of this change and also remove the double
records_in_range() calls that are not anymore needed.
This commit is contained in:
Monty 2020-02-27 19:12:27 +02:00
parent 9b06199080
commit f36ca142f7
63 changed files with 333 additions and 188 deletions

View File

@ -239,8 +239,9 @@ extern int heap_disable_indexes(HP_INFO *info);
extern int heap_enable_indexes(HP_INFO *info);
extern int heap_indexes_are_disabled(HP_INFO *info);
extern void heap_update_auto_increment(HP_INFO *info, const uchar *record);
ha_rows hp_rb_records_in_range(HP_INFO *info, int inx, key_range *min_key,
key_range *max_key);
ha_rows hp_rb_records_in_range(HP_INFO *info, int inx,
const key_range *min_key,
const key_range *max_key);
int hp_panic(enum ha_panic_function flag);
int heap_rkey(HP_INFO *info, uchar *record, int inx, const uchar *key,
key_part_map keypart_map, enum ha_rkey_function find_flag);

View File

@ -324,7 +324,9 @@ extern int maria_extra(MARIA_HA *file,
enum ha_extra_function function, void *extra_arg);
extern int maria_reset(MARIA_HA *file);
extern ha_rows maria_records_in_range(MARIA_HA *info, int inx,
key_range *min_key, key_range *max_key);
const key_range *min_key,
const key_range *max_key,
page_range *page);
extern int maria_is_changed(MARIA_HA *info);
extern int maria_delete_all_rows(MARIA_HA *info);
extern uint maria_get_pointer_length(ulonglong file_length, uint def);

View File

@ -636,6 +636,17 @@ typedef struct st_key_multi_range
} KEY_MULTI_RANGE;
/* Store first and last leaf page accessed by records_in_range */
typedef struct st_page_range
{
ulonglong first_page;
ulonglong last_page;
} page_range;
#define UNUSED_PAGE_NO ULONGLONG_MAX
#define unused_page_range { UNUSED_PAGE_NO, UNUSED_PAGE_NO }
/* For number of records */
#ifdef BIG_TABLES
#define rows2double(A) ulonglong2double(A)

View File

@ -291,7 +291,9 @@ extern int mi_extra(struct st_myisam_info *file,
void *extra_arg);
extern int mi_reset(struct st_myisam_info *file);
extern ha_rows mi_records_in_range(MI_INFO *info,int inx,
key_range *min_key, key_range *max_key);
const key_range *min_key,
const key_range *max_key,
page_range *pages);
extern int mi_log(int activate_log);
extern int mi_is_changed(struct st_myisam_info *info);
extern int mi_delete_all_rows(struct st_myisam_info *info);

View File

@ -116,7 +116,9 @@ extern int myrg_extra(MYRG_INFO *file,enum ha_extra_function function,
extern int myrg_reset(MYRG_INFO *info);
extern void myrg_extrafunc(MYRG_INFO *info,invalidator_by_filename inv);
extern ha_rows myrg_records_in_range(MYRG_INFO *info, int inx,
key_range *min_key, key_range *max_key);
const key_range *min_key,
const key_range *max_key,
page_range *pages);
extern ha_rows myrg_records(MYRG_INFO *info);
extern ulonglong myrg_position(MYRG_INFO *info);

View File

@ -9492,19 +9492,25 @@ double ha_partition::keyread_time(uint inx, uint ranges, ha_rows rows)
if start_key matches any rows.
*/
ha_rows ha_partition::records_in_range(uint inx, key_range *min_key,
key_range *max_key)
ha_rows ha_partition::records_in_range(uint inx, const key_range *min_key,
const key_range *max_key,
page_range *pages)
{
ha_rows min_rows_to_check, rows, estimated_rows=0, checked_rows= 0;
uint partition_index= 0, part_id;
page_range ignore_pages;
DBUG_ENTER("ha_partition::records_in_range");
/* Don't calculate pages of more than one active partition */
if (bitmap_bits_set(&m_part_info->read_partitions) != 1)
pages= &ignore_pages;
min_rows_to_check= min_rows_for_estimate();
while ((part_id= get_biggest_used_partition(&partition_index))
!= NO_CURRENT_PART_ID)
{
rows= m_file[part_id]->records_in_range(inx, min_key, max_key);
rows= m_file[part_id]->records_in_range(inx, min_key, max_key, pages);
DBUG_PRINT("info", ("part %u match %lu rows of %lu", part_id, (ulong) rows,
(ulong) m_file[part_id]->stats.records));

View File

@ -1048,8 +1048,10 @@ public:
For the given range how many records are estimated to be in this range.
Used by optimiser to calculate cost of using a particular index.
*/
ha_rows records_in_range(uint inx, key_range * min_key, key_range * max_key)
override;
ha_rows records_in_range(uint inx,
const key_range * min_key,
const key_range * max_key,
page_range *pages) override;
/*
Upper bound of number records returned in scan is sum of all

View File

@ -3864,8 +3864,9 @@ public:
virtual int rnd_same(uchar *buf, uint inx)
{ return HA_ERR_WRONG_COMMAND; }
virtual ha_rows records_in_range(uint inx, key_range *min_key,
key_range *max_key)
virtual ha_rows records_in_range(uint inx, const key_range *min_key,
const key_range *max_key,
page_range *res)
{ return (ha_rows) 10; }
/*
If HA_PRIMARY_KEY_REQUIRED_FOR_POSITION is set, then it sets ref

View File

@ -121,10 +121,11 @@ handler::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
}
else
{
page_range pages= unused_page_range;
if ((range.range_flag & UNIQUE_RANGE) && !(range.range_flag & NULL_RANGE))
rows= 1; /* there can be at most one row */
else if (HA_POS_ERROR == (rows= this->records_in_range(keyno, min_endp,
max_endp)))
max_endp, &pages)))
{
/* Can't scan one range => can't do MRR scan at all */
total_rows= HA_POS_ERROR;

View File

@ -6724,6 +6724,7 @@ static double ror_scan_selectivity(const ROR_INTERSECT_INFO *info,
{
/* create (part1val, ..., part{n-1}val) tuple. */
ha_rows records;
page_range pages;
if (!tuple_arg)
{
tuple_arg= scan->sel_arg;
@ -6741,7 +6742,7 @@ static double ror_scan_selectivity(const ROR_INTERSECT_INFO *info,
min_range.length= max_range.length= (uint) (key_ptr - key_val);
min_range.keypart_map= max_range.keypart_map= keypart_map;
records= (info->param->table->file->
records_in_range(scan->keynr, &min_range, &max_range));
records_in_range(scan->keynr, &min_range, &max_range, &pages));
if (cur_covered)
{
/* uncovered -> covered */

View File

@ -5232,8 +5232,11 @@ int ha_connect::rename_table(const char *from, const char *to)
@see
check_quick_keys() in opt_range.cc
*/
ha_rows ha_connect::records_in_range(uint inx, key_range *min_key,
key_range *max_key)
ha_rows ha_connect::records_in_range(uint inx,
const key_range *min_key,
const key_range *max_key,
page_range *pages)
{
ha_rows rows;
DBUG_ENTER("ha_connect::records_in_range");

View File

@ -461,8 +461,8 @@ int index_prev(uchar *buf);
int start_stmt(THD *thd, thr_lock_type lock_type);
int external_lock(THD *thd, int lock_type); ///< required
int delete_all_rows(void);
ha_rows records_in_range(uint inx, key_range *min_key,
key_range *max_key);
ha_rows records_in_range(uint inx, const key_range *start_key,
const key_range *end_key, page_range *pages);
/**
These methods can be overridden, but their default implementation
provide useful functionality.

View File

@ -839,6 +839,10 @@ int ha_example::delete_table(const char *name)
@brief
Given a starting key and an ending key, estimate the number of rows that
will exist between the two keys.
The handler can also optionally update the 'pages' parameter with the page
number that contains the min and max keys. This will help the optimizer
to know if two ranges are partly on the same pages and if the min and
max key are on the same page.
@details
end_key may be empty, in which case determine if start_key matches any rows.
@ -848,8 +852,10 @@ int ha_example::delete_table(const char *name)
@see
check_quick_keys() in opt_range.cc
*/
ha_rows ha_example::records_in_range(uint inx, key_range *min_key,
key_range *max_key)
ha_rows ha_example::records_in_range(uint inx,
const key_range *min_key,
const key_range *max_key,
page_range *pages)
{
DBUG_ENTER("ha_example::records_in_range");
DBUG_RETURN(10); // low number to force index usage

View File

@ -242,8 +242,8 @@ public:
int extra(enum ha_extra_function operation);
int external_lock(THD *thd, int lock_type); ///< required
int delete_all_rows(void);
ha_rows records_in_range(uint inx, key_range *min_key,
key_range *max_key);
ha_rows records_in_range(uint inx, const key_range *min_key,
const key_range *max_key, page_range *pages);
int delete_table(const char *from);
int create(const char *name, TABLE *form,
HA_CREATE_INFO *create_info); ///< required

View File

@ -1603,8 +1603,10 @@ static int free_share(FEDERATED_SHARE *share)
}
ha_rows ha_federated::records_in_range(uint inx, key_range *start_key,
key_range *end_key)
ha_rows ha_federated::records_in_range(uint inx,
const key_range *start_key,
const key_range *end_key,
page_range *pages)
{
/*

View File

@ -249,8 +249,10 @@ public:
int truncate();
int create(const char *name, TABLE *form,
HA_CREATE_INFO *create_info); //required
ha_rows records_in_range(uint inx, key_range *start_key,
key_range *end_key);
ha_rows records_in_range(uint inx,
const key_range *start_key,
const key_range *end_key,
page_range *pages);
uint8 table_cache_type() { return HA_CACHE_TBL_NOCACHE; }
THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,

View File

@ -1731,8 +1731,10 @@ static void free_share(federatedx_txn *txn, FEDERATEDX_SHARE *share)
}
ha_rows ha_federatedx::records_in_range(uint inx, key_range *start_key,
key_range *end_key)
ha_rows ha_federatedx::records_in_range(uint inx,
const key_range *start_key,
const key_range *end_key,
page_range *pages)
{
/*

View File

@ -435,8 +435,8 @@ public:
int delete_all_rows(void);
int create(const char *name, TABLE *form,
HA_CREATE_INFO *create_info); //required
ha_rows records_in_range(uint inx, key_range *start_key,
key_range *end_key);
ha_rows records_in_range(uint inx, const key_range *start_key,
const key_range *end_key, page_range *pages);
uint8 table_cache_type() { return HA_CACHE_TBL_NOCACHE; }
THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,

View File

@ -579,8 +579,8 @@ int ha_heap::rename_table(const char * from, const char * to)
}
ha_rows ha_heap::records_in_range(uint inx, key_range *min_key,
key_range *max_key)
ha_rows ha_heap::records_in_range(uint inx, const key_range *min_key,
const key_range *max_key, page_range *pages)
{
KEY *key=table->key_info+inx;
if (key->algorithm == HA_KEY_ALG_BTREE)

View File

@ -102,7 +102,8 @@ public:
int disable_indexes(uint mode);
int enable_indexes(uint mode);
int indexes_are_disabled(void);
ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key);
ha_rows records_in_range(uint inx, const key_range *start_key,
const key_range *end_key, page_range *pages);
int delete_table(const char *from);
void drop_table(const char *name);
int rename_table(const char * from, const char * to);

View File

@ -55,8 +55,9 @@ static ulong hp_hashnr(HP_KEYDEF *keydef, const uchar *key);
the range.
*/
ha_rows hp_rb_records_in_range(HP_INFO *info, int inx, key_range *min_key,
key_range *max_key)
ha_rows hp_rb_records_in_range(HP_INFO *info, int inx,
const key_range *min_key,
const key_range *max_key)
{
ha_rows start_pos, end_pos;
HP_KEYDEF *keyinfo= info->s->keydef + inx;

View File

@ -6135,10 +6135,8 @@ static const ha_rows rows_in_range_arbitrary_ret_val = 10;
/** Estimates the number of rows in a given index range.
@param[in] index index
@param[in] tuple1 range start, may also be empty tuple
@param[in] mode1 search mode for range start
@param[in] tuple2 range end, may also be empty tuple
@param[in] mode2 search mode for range end
@param[in] tuple1 range start
@param[in] tuple2 range end
@param[in] nth_attempt if the tree gets modified too much while
we are trying to analyze it, then we will retry (this function will call
itself, incrementing this parameter)
@ -6151,10 +6149,8 @@ static
ha_rows
btr_estimate_n_rows_in_range_low(
dict_index_t* index,
const dtuple_t* tuple1,
page_cur_mode_t mode1,
const dtuple_t* tuple2,
page_cur_mode_t mode2,
btr_pos_t* tuple1,
btr_pos_t* tuple2,
unsigned nth_attempt)
{
btr_path_t path1[BTR_PATH_ARRAY_N_SLOTS];
@ -6170,6 +6166,7 @@ btr_estimate_n_rows_in_range_low(
ulint i;
mtr_t mtr;
ha_rows table_n_rows;
page_cur_mode_t mode2= tuple2->mode;
table_n_rows = dict_table_get_n_rows(index->table);
@ -6188,9 +6185,10 @@ btr_estimate_n_rows_in_range_low(
bool should_count_the_left_border;
if (dtuple_get_n_fields(tuple1) > 0) {
if (dtuple_get_n_fields(tuple1->tuple) > 0) {
btr_cur_search_to_nth_level(index, 0, tuple1, mode1,
btr_cur_search_to_nth_level(index, 0, tuple1->tuple,
tuple1->mode,
BTR_SEARCH_LEAF | BTR_ESTIMATE,
&cursor, 0,
__FILE__, __LINE__, &mtr);
@ -6230,6 +6228,8 @@ btr_estimate_n_rows_in_range_low(
should_count_the_left_border = false;
}
tuple1->page_id= cursor.page_cur.block->page.id;
mtr_commit(&mtr);
if (!index->is_readable()) {
@ -6242,9 +6242,10 @@ btr_estimate_n_rows_in_range_low(
bool should_count_the_right_border;
if (dtuple_get_n_fields(tuple2) > 0) {
if (dtuple_get_n_fields(tuple2->tuple) > 0) {
btr_cur_search_to_nth_level(index, 0, tuple2, mode2,
btr_cur_search_to_nth_level(index, 0, tuple2->tuple,
mode2,
BTR_SEARCH_LEAF | BTR_ESTIMATE,
&cursor, 0,
__FILE__, __LINE__, &mtr);
@ -6256,7 +6257,7 @@ btr_estimate_n_rows_in_range_low(
should_count_the_right_border
= (mode2 == PAGE_CUR_LE /* if the range is '<=' */
/* and the record was found */
&& cursor.low_match >= dtuple_get_n_fields(tuple2))
&& cursor.low_match >= dtuple_get_n_fields(tuple2->tuple))
|| (mode2 == PAGE_CUR_L /* or if the range is '<' */
/* and there are any records to match the criteria,
i.e. if the minimum record on the tree is 5 and
@ -6300,6 +6301,8 @@ btr_estimate_n_rows_in_range_low(
should_count_the_right_border = false;
}
tuple2->page_id= cursor.page_cur.block->page.id;
mtr_commit(&mtr);
/* We have the path information for the range in path1 and path2 */
@ -6438,8 +6441,8 @@ btr_estimate_n_rows_in_range_low(
}
return btr_estimate_n_rows_in_range_low(
index, tuple1, mode1,
tuple2, mode2, nth_attempt + 1);
index, tuple1, tuple2,
nth_attempt + 1);
}
diverged = true;
@ -6510,13 +6513,11 @@ btr_estimate_n_rows_in_range_low(
ha_rows
btr_estimate_n_rows_in_range(
dict_index_t* index,
const dtuple_t* tuple1,
page_cur_mode_t mode1,
const dtuple_t* tuple2,
page_cur_mode_t mode2)
btr_pos_t *tuple1,
btr_pos_t *tuple2)
{
return btr_estimate_n_rows_in_range_low(
index, tuple1, mode1, tuple2, mode2, 1);
index, tuple1, tuple2, 1);
}
/*******************************************************************//**

View File

@ -13936,10 +13936,11 @@ ha_rows
ha_innobase::records_in_range(
/*==========================*/
uint keynr, /*!< in: index number */
key_range *min_key, /*!< in: start key value of the
const key_range *min_key, /*!< in: start key value of the
range, may also be 0 */
key_range *max_key) /*!< in: range end key val, may
const key_range *max_key, /*!< in: range end key val, may
also be 0 */
page_range *pages)
{
KEY* key;
dict_index_t* index;
@ -14028,8 +14029,12 @@ ha_innobase::records_in_range(
n_rows = rtr_estimate_n_rows_in_range(
index, range_start, mode1);
} else {
btr_pos_t tuple1(range_start, mode1, pages->first_page);
btr_pos_t tuple2(range_end, mode2, pages->last_page);
n_rows = btr_estimate_n_rows_in_range(
index, range_start, mode1, range_end, mode2);
index, &tuple1, &tuple2);
pages->first_page= tuple1.page_id.raw();
pages->last_page= tuple2.page_id.raw();
}
} else {

View File

@ -184,9 +184,10 @@ public:
int start_stmt(THD *thd, thr_lock_type lock_type) override;
ha_rows records_in_range(
uint inx,
key_range* min_key,
key_range* max_key) override;
uint inx,
const key_range* min_key,
const key_range* max_key,
page_range* pages) override;
ha_rows estimate_rows_upper_bound() override;

View File

@ -555,20 +555,41 @@ btr_cur_pessimistic_delete(
@param[in,out] mtr mini-transaction */
void btr_cur_node_ptr_delete(btr_cur_t* parent, mtr_t* mtr)
MY_ATTRIBUTE((nonnull));
/***********************************************************//**
Parses a redo log record of updating a record in-place.
@return end of log record or NULL */
byte*
btr_cur_parse_update_in_place(
/*==========================*/
byte* ptr, /*!< in: buffer */
byte* end_ptr,/*!< in: buffer end */
page_t* page, /*!< in/out: page or NULL */
page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
dict_index_t* index); /*!< in: index corresponding to page */
/** Arguments to btr_estimate_n_rows_in_range */
struct btr_pos_t
{
btr_pos_t(dtuple_t *arg_tuple,
page_cur_mode_t arg_mode,
page_id_t arg_page_id)
:tuple(arg_tuple), mode(arg_mode), page_id(arg_page_id)
{}
dtuple_t* tuple; /* Range start or end. May be NULL */
page_cur_mode_t mode; /* search mode for range */
page_id_t page_id; /* Out: Page where we found the tuple */
};
/** Estimates the number of rows in a given index range.
@param[in] index index
@param[in] tuple1 range start, may also be empty tuple
@param[in] mode1 search mode for range start
@param[in] tuple2 range end, may also be empty tuple
@param[in] mode2 search mode for range end
@param[in/out] range_start
@param[in/out] range_ end
@return estimated number of rows */
ha_rows
btr_estimate_n_rows_in_range(
dict_index_t* index,
const dtuple_t* tuple1,
page_cur_mode_t mode1,
const dtuple_t* tuple2,
page_cur_mode_t mode2);
btr_pos_t* range_start,
btr_pos_t* range_end);
/*******************************************************************//**
Estimates the number of different key values in a given index, for

View File

@ -141,6 +141,7 @@ public:
ut_ad(page_no <= 0xFFFFFFFFU);
}
page_id_t(ulonglong id) : m_id(id) {}
bool operator==(const page_id_t& rhs) const { return m_id == rhs.m_id; }
bool operator!=(const page_id_t& rhs) const { return m_id != rhs.m_id; }
@ -169,6 +170,7 @@ public:
/** Set the FIL_NULL for the space and page_no */
void set_corrupt_id() { m_id= ~uint64_t{0}; }
ulonglong raw() { return m_id; }
private:
/** The page identifier */
uint64_t m_id;

View File

@ -3296,6 +3296,8 @@ void ha_maria::get_auto_increment(ulonglong offset, ulonglong increment,
inx Index to use
min_key Start of range. Null pointer if from first key
max_key End of range. Null pointer if to last key
pages Store first and last page for the range in case of
b-trees. In other cases it's not touched.
NOTES
min_key.flag can have one of the following values:
@ -3313,11 +3315,12 @@ void ha_maria::get_auto_increment(ulonglong offset, ulonglong increment,
the range.
*/
ha_rows ha_maria::records_in_range(uint inx, key_range *min_key,
key_range *max_key)
ha_rows ha_maria::records_in_range(uint inx, const key_range *min_key,
const key_range *max_key, page_range *pages)
{
register_handler(file);
return (ha_rows) maria_records_in_range(file, (int) inx, min_key, max_key);
return (ha_rows) maria_records_in_range(file, (int) inx, min_key, max_key,
pages);
}

View File

@ -124,7 +124,9 @@ public:
int indexes_are_disabled(void);
void start_bulk_insert(ha_rows rows, uint flags);
int end_bulk_insert();
ha_rows records_in_range(uint inx, key_range * min_key, key_range * max_key);
ha_rows records_in_range(uint inx, const key_range *min_key,
const key_range *max_key,
page_range *pages);
void update_create_info(HA_CREATE_INFO * create_info);
int create(const char *name, TABLE * form, HA_CREATE_INFO * create_info);
THR_LOCK_DATA **store_lock(THD * thd, THR_LOCK_DATA ** to,

View File

@ -22,8 +22,9 @@
#include "ma_rt_index.h"
static ha_rows _ma_record_pos(MARIA_HA *,const uchar *, key_part_map,
enum ha_rkey_function);
static double _ma_search_pos(MARIA_HA *, MARIA_KEY *, uint32, my_off_t);
enum ha_rkey_function, ulonglong *);
static double _ma_search_pos(MARIA_HA *, MARIA_KEY *, uint32, my_off_t,
ulonglong *page);
static uint _ma_keynr(MARIA_PAGE *page, uchar *keypos, uint *ret_max_key);
@ -43,8 +44,9 @@ static uint _ma_keynr(MARIA_PAGE *page, uchar *keypos, uint *ret_max_key);
@retval number Estimated number of rows
*/
ha_rows maria_records_in_range(MARIA_HA *info, int inx, key_range *min_key,
key_range *max_key)
ha_rows maria_records_in_range(MARIA_HA *info, int inx,
const key_range *min_key,
const key_range *max_key, page_range *pages)
{
ha_rows start_pos,end_pos,res;
MARIA_SHARE *share= info->s;
@ -96,11 +98,11 @@ ha_rows maria_records_in_range(MARIA_HA *info, int inx, key_range *min_key,
default:
start_pos= (min_key ?
_ma_record_pos(info, min_key->key, min_key->keypart_map,
min_key->flag) :
min_key->flag, &pages->first_page) :
(ha_rows) 0);
end_pos= (max_key ?
_ma_record_pos(info, max_key->key, max_key->keypart_map,
max_key->flag) :
max_key->flag, &pages->last_page) :
info->state->records + (ha_rows) 1);
res= (end_pos < start_pos ? (ha_rows) 0 :
(end_pos == start_pos ? (ha_rows) 1 : end_pos-start_pos));
@ -128,7 +130,8 @@ ha_rows maria_records_in_range(MARIA_HA *info, int inx, key_range *min_key,
static ha_rows _ma_record_pos(MARIA_HA *info, const uchar *key_data,
key_part_map keypart_map,
enum ha_rkey_function search_flag)
enum ha_rkey_function search_flag,
ulonglong *final_page)
{
uint inx= (uint) info->lastinx;
uint32 nextflag;
@ -185,7 +188,7 @@ static ha_rows _ma_record_pos(MARIA_HA *info, const uchar *key_data,
*/
pos= _ma_search_pos(info, &key,
nextflag | SEARCH_SAVE_BUFF | SEARCH_UPDATE,
info->s->state.key_root[inx]);
info->s->state.key_root[inx], final_page);
if (pos >= 0.0)
{
DBUG_PRINT("exit",("pos: %ld",(ulong) (pos*info->state->records)));
@ -206,7 +209,8 @@ static ha_rows _ma_record_pos(MARIA_HA *info, const uchar *key_data,
*/
static double _ma_search_pos(MARIA_HA *info, MARIA_KEY *key,
uint32 nextflag, my_off_t pos)
uint32 nextflag, my_off_t pos,
ulonglong *final_page)
{
int flag;
uint keynr, UNINIT_VAR(max_keynr);
@ -224,6 +228,7 @@ static double _ma_search_pos(MARIA_HA *info, MARIA_KEY *key,
PAGECACHE_LOCK_LEFT_UNLOCKED, DFLT_INIT_HITS,
info->buff, 1))
goto err;
*final_page= pos;
flag= (*keyinfo->bin_search)(key, &page, nextflag, &keypos,
info->lastkey_buff, &after_key);
keynr= _ma_keynr(&page, keypos, &max_keynr);
@ -240,7 +245,8 @@ static double _ma_search_pos(MARIA_HA *info, MARIA_KEY *key,
if (! page.node)
offset= 0.0;
else if ((offset= _ma_search_pos(info, key, nextflag,
_ma_kpos(page.node,keypos))) < 0)
_ma_kpos(page.node,keypos),
final_page)) < 0)
DBUG_RETURN(offset);
}
else
@ -269,7 +275,8 @@ static double _ma_search_pos(MARIA_HA *info, MARIA_KEY *key,
Matches keynr + [0-1]
*/
if ((offset= _ma_search_pos(info, key, SEARCH_FIND,
_ma_kpos(page.node,keypos))) < 0)
_ma_kpos(page.node,keypos),
final_page)) < 0)
DBUG_RETURN(offset); /* Read error */
}
}

View File

@ -142,6 +142,7 @@ static int run_test(const char *filename)
uchar read_record[MAX_REC_LENGTH];
int upd= 10;
ha_rows hrows;
page_range pages;
bzero(&uniquedef, sizeof(uniquedef));
bzero(&create_info, sizeof(create_info));
@ -427,7 +428,7 @@ static int run_test(const char *filename)
range.key= record+1;
range.length= 1000; /* Big enough */
range.flag= HA_READ_MBR_INTERSECT;
hrows= maria_records_in_range(file,0, &range, (key_range*) 0);
hrows= maria_records_in_range(file,0, &range, (key_range*) 0, &pages);
if (!silent)
printf(" %ld rows\n", (long) hrows);

View File

@ -71,6 +71,7 @@ int run_test(const char *filename)
uchar read_record[MAX_REC_LENGTH];
int upd=10;
ha_rows hrows;
page_range pages;
/* Define a column for NULLs and DEL markers*/
@ -258,7 +259,7 @@ int run_test(const char *filename)
max_range.key= record+1;
max_range.length= 1000; /* Big enough */
max_range.flag= HA_READ_KEY_EXACT;
hrows= maria_records_in_range(file,0, &min_range, &max_range);
hrows= maria_records_in_range(file,0, &min_range, &max_range, &pages);
printf(" %ld rows\n", (long) hrows);
if (maria_close(file)) goto err;

View File

@ -69,6 +69,7 @@ int main(int argc, char *argv[])
char *blob_buffer;
MARIA_CREATE_INFO create_info;
char filename[FN_REFLEN];
page_range pages;
#ifdef SAFE_MUTEX
safe_mutex_deadlock_detector= 1;
@ -722,7 +723,8 @@ int main(int argc, char *argv[])
max_key.keypart_map= HA_WHOLE_KEY;
max_key.flag= HA_READ_AFTER_KEY;
range_records= maria_records_in_range(file,(int) i, &min_key, &max_key);
range_records= maria_records_in_range(file,(int) i, &min_key, &max_key,
&pages);
if (range_records < info.records*8/10 ||
range_records > info.records*12/10)
{
@ -756,7 +758,8 @@ int main(int argc, char *argv[])
max_key.key= key2;
max_key.keypart_map= HA_WHOLE_KEY;
max_key.flag= HA_READ_BEFORE_KEY;
range_records= maria_records_in_range(file, 0, &min_key, &max_key);
range_records= maria_records_in_range(file, 0, &min_key, &max_key,
&pages);
records=0;
for (j++ ; j < k ; j++)
records+=key1[j];

View File

@ -7437,8 +7437,10 @@ uint ha_mroonga::max_supported_key_parts() const
DBUG_RETURN(parts);
}
ha_rows ha_mroonga::wrapper_records_in_range(uint key_nr, key_range *range_min,
key_range *range_max)
ha_rows ha_mroonga::wrapper_records_in_range(uint key_nr,
const key_range *range_min,
const key_range *range_max,
page_range *pages)
{
ha_rows row_count;
MRN_DBUG_ENTER_METHOD();
@ -7448,15 +7450,18 @@ ha_rows ha_mroonga::wrapper_records_in_range(uint key_nr, key_range *range_min,
} else {
MRN_SET_WRAP_SHARE_KEY(share, table->s);
MRN_SET_WRAP_TABLE_KEY(this, table);
row_count = wrap_handler->records_in_range(key_nr, range_min, range_max);
row_count = wrap_handler->records_in_range(key_nr, range_min, range_max,
pages);
MRN_SET_BASE_SHARE_KEY(share, table->s);
MRN_SET_BASE_TABLE_KEY(this, table);
}
DBUG_RETURN(row_count);
}
ha_rows ha_mroonga::storage_records_in_range(uint key_nr, key_range *range_min,
key_range *range_max)
ha_rows ha_mroonga::storage_records_in_range(uint key_nr,
const key_range *range_min,
const key_range *range_max,
page_range *pages)
{
MRN_DBUG_ENTER_METHOD();
int flags = 0;
@ -7569,8 +7574,8 @@ ha_rows ha_mroonga::storage_records_in_range(uint key_nr, key_range *range_min,
}
ha_rows ha_mroonga::generic_records_in_range_geo(uint key_nr,
key_range *range_min,
key_range *range_max)
const key_range *range_min,
const key_range *range_max)
{
MRN_DBUG_ENTER_METHOD();
ha_rows row_count;
@ -7604,15 +7609,17 @@ ha_rows ha_mroonga::generic_records_in_range_geo(uint key_nr,
DBUG_RETURN(row_count);
}
ha_rows ha_mroonga::records_in_range(uint key_nr, key_range *range_min, key_range *range_max)
ha_rows ha_mroonga::records_in_range(uint key_nr, const key_range *range_min,
const key_range *range_max,
page_range *pages)
{
MRN_DBUG_ENTER_METHOD();
ha_rows row_count = 0;
if (share->wrapper_mode)
{
row_count = wrapper_records_in_range(key_nr, range_min, range_max);
row_count = wrapper_records_in_range(key_nr, range_min, range_max, pages);
} else {
row_count = storage_records_in_range(key_nr, range_min, range_max);
row_count = storage_records_in_range(key_nr, range_min, range_max, pages);
}
DBUG_PRINT("info", ("mroonga: row_count=%" MRN_HA_ROWS_FORMAT, row_count));
DBUG_RETURN(row_count);

View File

@ -461,7 +461,8 @@ public:
uint max_supported_key_length() const mrn_override;
uint max_supported_key_part_length() const mrn_override;
ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key) mrn_override;
ha_rows records_in_range(uint inx, const key_range *min_key,
const key_range *max_key, page_range *pages) mrn_override;
int index_init(uint idx, bool sorted) mrn_override;
int index_end() mrn_override;
#ifndef MRN_HANDLER_HAVE_HA_INDEX_READ_MAP
@ -984,12 +985,14 @@ private:
int storage_rnd_pos(uchar *buf, uchar *pos);
void wrapper_position(const uchar *record);
void storage_position(const uchar *record);
ha_rows wrapper_records_in_range(uint key_nr, key_range *range_min,
key_range *range_max);
ha_rows storage_records_in_range(uint key_nr, key_range *range_min,
key_range *range_max);
ha_rows generic_records_in_range_geo(uint key_nr, key_range *range_min,
key_range *range_max);
ha_rows wrapper_records_in_range(uint key_nr, const key_range *range_min,
const key_range *range_max,
page_range *pages);
ha_rows storage_records_in_range(uint key_nr, const key_range *range_min,
const key_range *range_max,
page_range *pages);
ha_rows generic_records_in_range_geo(uint key_nr, const key_range *range_min,
const key_range *range_max);
int wrapper_index_init(uint idx, bool sorted);
int storage_index_init(uint idx, bool sorted);
int wrapper_index_end();

View File

@ -2337,6 +2337,8 @@ void ha_myisam::get_auto_increment(ulonglong offset, ulonglong increment,
inx Index to use
min_key Start of range. Null pointer if from first key
max_key End of range. Null pointer if to last key
pages Store first and last page for the range in case of
b-trees. In other cases it's not touched.
NOTES
min_key.flag can have one of the following values:
@ -2354,10 +2356,12 @@ void ha_myisam::get_auto_increment(ulonglong offset, ulonglong increment,
the range.
*/
ha_rows ha_myisam::records_in_range(uint inx, key_range *min_key,
key_range *max_key)
ha_rows ha_myisam::records_in_range(uint inx, const key_range *min_key,
const key_range *max_key,
page_range *pages)
{
return (ha_rows) mi_records_in_range(file, (int) inx, min_key, max_key);
return (ha_rows) mi_records_in_range(file, (int) inx, min_key, max_key,
pages);
}

View File

@ -114,7 +114,8 @@ class ha_myisam: public handler
int indexes_are_disabled(void);
void start_bulk_insert(ha_rows rows, uint flags);
int end_bulk_insert();
ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key);
ha_rows records_in_range(uint inx, const key_range *min_key,
const key_range *max_key, page_range *pages);
void update_create_info(HA_CREATE_INFO *create_info);
int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info);
THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,

View File

@ -24,9 +24,9 @@
#include "rt_index.h"
static double _mi_record_pos(MI_INFO *, const uchar *, key_part_map,
enum ha_rkey_function);
enum ha_rkey_function, ulonglong *);
static double _mi_search_pos(MI_INFO *,MI_KEYDEF *,uchar *, uint,uint,
my_off_t,my_bool);
my_off_t,my_bool, ulonglong *);
static uint _mi_keynr(MI_INFO *info,MI_KEYDEF *,uchar *, uchar *,uint *);
/*
@ -48,7 +48,8 @@ static uint _mi_keynr(MI_INFO *info,MI_KEYDEF *,uchar *, uchar *,uint *);
*/
ha_rows mi_records_in_range(MI_INFO *info, int inx,
key_range *min_key, key_range *max_key)
const key_range *min_key, const key_range *max_key,
page_range *pages)
{
ha_rows res;
double start_pos,end_pos,diff;
@ -98,10 +99,12 @@ ha_rows mi_records_in_range(MI_INFO *info, int inx,
case HA_KEY_ALG_BTREE:
default:
start_pos= (min_key ?_mi_record_pos(info, min_key->key,
min_key->keypart_map, min_key->flag)
min_key->keypart_map, min_key->flag,
&pages->first_page)
: (double) 0);
end_pos= (max_key ? _mi_record_pos(info, max_key->key,
max_key->keypart_map, max_key->flag)
max_key->keypart_map, max_key->flag,
&pages->last_page)
: (double) info->state->records);
res= (end_pos < start_pos ? (ha_rows) 0 :
(end_pos == start_pos ? (ha_rows) 1 : (ha_rows) (end_pos-start_pos)));
@ -147,7 +150,8 @@ ha_rows mi_records_in_range(MI_INFO *info, int inx,
static double _mi_record_pos(MI_INFO *info, const uchar *key,
key_part_map keypart_map,
enum ha_rkey_function search_flag)
enum ha_rkey_function search_flag,
ulonglong *final_page)
{
uint inx=(uint) info->lastinx, nextflag, key_len;
MI_KEYDEF *keyinfo=info->s->keyinfo+inx;
@ -203,7 +207,8 @@ static double _mi_record_pos(MI_INFO *info, const uchar *key,
*/
pos=_mi_search_pos(info,keyinfo,key_buff,key_len,
nextflag | SEARCH_SAVE_BUFF | SEARCH_UPDATE,
info->s->state.key_root[inx], TRUE);
info->s->state.key_root[inx], TRUE,
final_page);
if (pos >= 0.0)
{
DBUG_PRINT("exit",("pos: %g",(pos*info->state->records)));
@ -219,7 +224,8 @@ static double _mi_record_pos(MI_INFO *info, const uchar *key,
static double _mi_search_pos(register MI_INFO *info,
register MI_KEYDEF *keyinfo,
uchar *key, uint key_len, uint nextflag,
register my_off_t pos, my_bool last_in_level)
register my_off_t pos, my_bool last_in_level,
ulonglong *final_page)
{
int flag;
uint nod_flag,keynr,UNINIT_VAR(max_keynr);
@ -233,6 +239,7 @@ static double _mi_search_pos(register MI_INFO *info,
if (!(buff=_mi_fetch_keypage(info,keyinfo,pos,DFLT_INIT_HITS,info->buff,1)))
goto err;
*final_page= pos;
flag=(*keyinfo->bin_search)(info,keyinfo,buff,key,key_len,nextflag,
&keypos,info->lastkey, &after_key);
nod_flag=mi_test_if_nod(buff);
@ -251,7 +258,8 @@ static double _mi_search_pos(register MI_INFO *info,
offset= 1.0;
else if ((offset=_mi_search_pos(info,keyinfo,key,key_len,nextflag,
_mi_kpos(nod_flag,keypos),
last_in_level && after_key)) < 0)
last_in_level && after_key,
final_page)) < 0)
DBUG_RETURN(offset);
}
else
@ -271,7 +279,8 @@ static double _mi_search_pos(register MI_INFO *info,
*/
if ((offset=_mi_search_pos(info,keyinfo,key,key_len,SEARCH_FIND,
_mi_kpos(nod_flag,keypos),
last_in_level && after_key)) < 0)
last_in_level && after_key,
final_page)) < 0)
DBUG_RETURN(offset); /* Read error */
}
}

View File

@ -67,6 +67,7 @@ int main(int argc, char *argv[])
const char *filename;
char *blob_buffer;
MI_CREATE_INFO create_info;
page_range pages;
MY_INIT(argv[0]);
filename= "test2";
@ -622,7 +623,8 @@ int main(int argc, char *argv[])
max_key.keypart_map= HA_WHOLE_KEY;
max_key.flag= HA_READ_AFTER_KEY;
range_records= mi_records_in_range(file,(int) i, &min_key, &max_key);
range_records= mi_records_in_range(file,(int) i, &min_key, &max_key,
&pages);
if (range_records < info.records*8/10 ||
range_records > info.records*12/10)
{
@ -645,6 +647,7 @@ int main(int argc, char *argv[])
if (j != 0 && k != 0)
{
key_range min_key, max_key;
page_range pages;
if (j > k)
swap_variables(int, j, k);
sprintf((char*) key,"%6d",j);
@ -656,7 +659,7 @@ int main(int argc, char *argv[])
max_key.key= key2;
max_key.keypart_map= HA_WHOLE_KEY;
max_key.flag= HA_READ_BEFORE_KEY;
range_records= mi_records_in_range(file, 0, &min_key, &max_key);
range_records= mi_records_in_range(file, 0, &min_key, &max_key, &pages);
records=0;
for (j++ ; j < k ; j++)
records+=key1[j];

View File

@ -113,6 +113,7 @@ static int run_test(const char *filename)
uchar read_record[MAX_REC_LENGTH];
int upd= 10;
ha_rows hrows;
page_range pages;
bzero(&uniquedef, sizeof(uniquedef));
bzero(&create_info, sizeof(create_info));
@ -335,7 +336,7 @@ static int run_test(const char *filename)
range.key= record+1;
range.length= 1000; /* Big enough */
range.flag= HA_READ_MBR_INTERSECT;
hrows= mi_records_in_range(file, 0, &range, (key_range*) 0);
hrows= mi_records_in_range(file, 0, &range, (key_range*) 0, &pages);
printf(" %ld rows\n", (long) hrows);
if (mi_close(file)) goto err;

View File

@ -70,6 +70,7 @@ int run_test(const char *filename)
uchar read_record[MAX_REC_LENGTH];
int upd=10;
ha_rows hrows;
page_range pages;
/* Define a column for NULLs and DEL markers*/
@ -256,7 +257,7 @@ int run_test(const char *filename)
max_range.key= record+1;
max_range.length= 1000; /* Big enough */
max_range.flag= HA_READ_KEY_EXACT;
hrows= mi_records_in_range(file, 0, &min_range, &max_range);
hrows= mi_records_in_range(file, 0, &min_range, &max_range, &pages);
printf(" %ld rows\n", (long) hrows);
if (mi_close(file)) goto err;

View File

@ -1216,11 +1216,14 @@ void ha_myisammrg::position(const uchar *record)
}
ha_rows ha_myisammrg::records_in_range(uint inx, key_range *min_key,
key_range *max_key)
ha_rows ha_myisammrg::records_in_range(uint inx,
const key_range *min_key,
const key_range *max_key,
page_range *pages)
{
DBUG_ASSERT(this->file->children_attached);
return (ha_rows) myrg_records_in_range(file, (int) inx, min_key, max_key);
return (ha_rows) myrg_records_in_range(file, (int) inx, min_key, max_key,
pages);
}

View File

@ -129,7 +129,8 @@ public:
int rnd_next(uchar *buf);
int rnd_pos(uchar * buf, uchar *pos);
void position(const uchar *record);
ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key);
ha_rows records_in_range(uint inx, const key_range *start_key,
const key_range *end_key, page_range *pages);
int delete_all_rows();
int info(uint);
int reset(void);

View File

@ -17,14 +17,21 @@
#include "myrg_def.h"
ha_rows myrg_records_in_range(MYRG_INFO *info, int inx,
key_range *min_key, key_range *max_key)
const key_range *min_key,
const key_range *max_key,
page_range *pages)
{
ha_rows records=0, res;
MYRG_TABLE *table;
page_range ignore_pages;
/* Don't calculate pages of more than one active partition */
if (info->open_tables +1 != info->end_table)
pages= &ignore_pages;
for (table=info->open_tables ; table != info->end_table ; table++)
{
res= mi_records_in_range(table->table, inx, min_key, max_key);
res= mi_records_in_range(table->table, inx, min_key, max_key, pages);
if (res == HA_POS_ERROR)
return HA_POS_ERROR;
if (records > HA_POS_ERROR - res)

View File

@ -1185,8 +1185,10 @@ int ha_oqgraph::rename_table(const char *, const char *)
}
ha_rows ha_oqgraph::records_in_range(uint inx, key_range *min_key,
key_range *max_key)
ha_rows ha_oqgraph::records_in_range(uint inx,
const key_range *min_key,
const key_range *max_key,
page_range *pages)
{
if (graph->get_thd() != current_thd) {
DBUG_PRINT( "oq-debug", ("g->table->in_use: 0x%lx <-- current_thd 0x%lx", (long) graph->get_thd(), (long) current_thd));

View File

@ -99,7 +99,8 @@ public:
int extra(enum ha_extra_function operation);
int external_lock(THD *thd, int lock_type);
int delete_all_rows(void);
ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key);
ha_rows records_in_range(uint inx, const key_range *min_key,
const key_range *max_key, page_range *pages);
int delete_table(const char *from);
int rename_table(const char * from, const char * to);
int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info);

View File

@ -11910,8 +11910,9 @@ int ha_rocksdb::extra(enum ha_extra_function operation) {
Given a starting key and an ending key, estimate the number of rows that
will exist between the two keys.
*/
ha_rows ha_rocksdb::records_in_range(uint inx, key_range *const min_key,
key_range *const max_key) {
ha_rows ha_rocksdb::records_in_range(uint inx, const key_range *const min_key,
const key_range *const max_key,
page_range *pages) {
DBUG_ENTER_FUNC();
ha_rows ret = THDVAR(ha_thd(), records_in_range);

View File

@ -902,8 +902,10 @@ public:
int check(THD *const thd, HA_CHECK_OPT *const check_opt) override
MY_ATTRIBUTE((__warn_unused_result__));
int remove_rows(Rdb_tbl_def *const tbl);
ha_rows records_in_range(uint inx, key_range *const min_key,
key_range *const max_key) override
ha_rows records_in_range(uint inx,
const key_range *const min_key,
const key_range *const max_key,
page_range *pages) override
MY_ATTRIBUTE((__warn_unused_result__));
int delete_table(Rdb_tbl_def *const tbl);

View File

@ -93,9 +93,8 @@ public:
int index_prev(uchar *buf);
int index_first(uchar *buf);
int index_last(uchar *buf);
ha_rows records_in_range(uint inx, key_range *min_key,
key_range *max_key);
ha_rows records_in_range(uint inx, const key_range *start_key,
const key_range *end_key, page_range *pages);
double scan_time() { return (double)nvalues(); }
double read_time(uint index, uint ranges, ha_rows rows) { return (double)rows; }
double keyread_time(uint index, uint ranges, ha_rows rows) { return (double)rows; }
@ -234,8 +233,9 @@ int ha_seq::index_last(uchar *buf)
return index_prev(buf);
}
ha_rows ha_seq::records_in_range(uint inx, key_range *min_key,
key_range *max_key)
ha_rows ha_seq::records_in_range(uint inx, const key_range *min_key,
const key_range *max_key,
page_range *pages)
{
ulonglong kmin= min_key ? uint8korr(min_key->key) : seqs->from;
ulonglong kmax= max_key ? uint8korr(max_key->key) : seqs->to - 1;

View File

@ -3360,7 +3360,7 @@ int ha_sphinx::rename_table ( const char *, const char * )
// if start_key matches any rows.
//
// Called from opt_range.cc by check_quick_keys().
ha_rows ha_sphinx::records_in_range ( uint, key_range *, key_range * )
ha_rows ha_sphinx::records_in_range ( uint, const key_range *, const key_range *, page_range *)
{
SPH_ENTER_METHOD();
SPH_RET(3); // low number to force index usage

View File

@ -119,7 +119,7 @@ public:
int reset();
int external_lock ( THD * thd, int lock_type );
int delete_all_rows ();
ha_rows records_in_range ( uint inx, key_range * min_key, key_range * max_key );
ha_rows records_in_range ( uint inx, const key_range * min_key, const key_range * max_key, page_range *pages);
int delete_table ( const char * from );
int rename_table ( const char * from, const char * to );

View File

@ -8847,9 +8847,10 @@ int ha_spider::info(
ha_rows ha_spider::records_in_range(
uint inx,
key_range *start_key,
key_range *end_key
) {
const key_range *start_key,
const key_range *end_key,
page_range *pages)
{
int error_num;
THD *thd = ha_thd();
double crd_interval = spider_param_crd_interval(thd, share->crd_interval);

View File

@ -512,8 +512,9 @@ public:
);
ha_rows records_in_range(
uint inx,
key_range *start_key,
key_range *end_key
const key_range *start_key,
const key_range *end_key,
page_range *pages
);
int check_crd();
int pre_records();

View File

@ -5987,8 +5987,8 @@ int spider_db_show_index(
}
ha_rows spider_db_explain_select(
key_range *start_key,
key_range *end_key,
const key_range *start_key,
const key_range *end_key,
ha_spider *spider,
int link_idx
) {

View File

@ -732,8 +732,8 @@ int spider_db_show_index(
);
ha_rows spider_db_explain_select(
key_range *start_key,
key_range *end_key,
const key_range *start_key,
const key_range *end_key,
ha_spider *spider,
int link_idx
);

View File

@ -5421,8 +5421,8 @@ int spider_handlersocket_handler::append_delete_all_rows_part(
}
int spider_handlersocket_handler::append_explain_select_part(
key_range *start_key,
key_range *end_key,
const key_range *start_key,
const key_range *end_key,
ulong sql_type,
int link_idx
) {

View File

@ -843,8 +843,8 @@ public:
ulong sql_type
);
int append_explain_select_part(
key_range *start_key,
key_range *end_key,
const key_range *start_key,
const key_range *end_key,
ulong sql_type,
int link_idx
);
@ -966,8 +966,8 @@ public:
ulonglong &last_insert_id
);
ha_rows explain_select(
key_range *start_key,
key_range *end_key,
const key_range *start_key,
const key_range *end_key,
int link_idx
);
int lock_tables(

View File

@ -1570,8 +1570,8 @@ public:
ulong sql_type
) = 0;
virtual int append_explain_select_part(
key_range *start_key,
key_range *end_key,
const key_range *start_key,
const key_range *end_key,
ulong sql_type,
int link_idx
) = 0;
@ -1688,8 +1688,8 @@ public:
ulonglong &last_insert_id
) = 0;
virtual ha_rows explain_select(
key_range *start_key,
key_range *end_key,
const key_range *start_key,
const key_range *end_key,
int link_idx
) = 0;
virtual int lock_tables(

View File

@ -12690,8 +12690,8 @@ int spider_mbase_handler::append_truncate(
}
int spider_mbase_handler::append_explain_select_part(
key_range *start_key,
key_range *end_key,
const key_range *start_key,
const key_range *end_key,
ulong sql_type,
int link_idx
) {
@ -12714,8 +12714,8 @@ int spider_mbase_handler::append_explain_select_part(
int spider_mbase_handler::append_explain_select(
spider_string *str,
key_range *start_key,
key_range *end_key,
const key_range *start_key,
const key_range *end_key,
ulong sql_type,
int link_idx
) {
@ -14354,8 +14354,8 @@ int spider_mbase_handler::show_last_insert_id(
}
ha_rows spider_mbase_handler::explain_select(
key_range *start_key,
key_range *end_key,
const key_range *start_key,
const key_range *end_key,
int link_idx
) {
int error_num;

View File

@ -1381,15 +1381,15 @@ public:
int link_idx
);
int append_explain_select_part(
key_range *start_key,
key_range *end_key,
const key_range *start_key,
const key_range *end_key,
ulong sql_type,
int link_idx
);
int append_explain_select(
spider_string *str,
key_range *start_key,
key_range *end_key,
const key_range *start_key,
const key_range *end_key,
ulong sql_type,
int link_idx
);
@ -1518,8 +1518,8 @@ public:
ulonglong &last_insert_id
);
ha_rows explain_select(
key_range *start_key,
key_range *end_key,
const key_range *start_key,
const key_range *end_key,
int link_idx
);
int lock_tables(

View File

@ -10150,8 +10150,8 @@ int spider_oracle_handler::append_truncate(
}
int spider_oracle_handler::append_explain_select_part(
key_range *start_key,
key_range *end_key,
const key_range *start_key,
const key_range *end_key,
ulong sql_type,
int link_idx
) {
@ -10174,8 +10174,8 @@ int spider_oracle_handler::append_explain_select_part(
int spider_oracle_handler::append_explain_select(
spider_string *str,
key_range *start_key,
key_range *end_key,
const key_range *start_key,
const key_range *end_key,
ulong sql_type,
int link_idx
) {
@ -11899,8 +11899,8 @@ int spider_oracle_handler::show_last_insert_id(
}
ha_rows spider_oracle_handler::explain_select(
key_range *start_key,
key_range *end_key,
const key_range *start_key,
const key_range *end_key,
int link_idx
) {
int error_num;

View File

@ -1266,15 +1266,15 @@ public:
int link_idx
);
int append_explain_select_part(
key_range *start_key,
key_range *end_key,
const key_range *start_key,
const key_range *end_key,
ulong sql_type,
int link_idx
);
int append_explain_select(
spider_string *str,
key_range *start_key,
key_range *end_key,
const key_range *start_key,
const key_range *end_key,
ulong sql_type,
int link_idx
);
@ -1397,8 +1397,8 @@ public:
ulonglong &last_insert_id
);
ha_rows explain_select(
key_range *start_key,
key_range *end_key,
const key_range *start_key,
const key_range *end_key,
int link_idx
);
int lock_tables(

View File

@ -7889,7 +7889,9 @@ double ha_tokudb::index_only_read_time(uint keynr, double records) {
// number > 0 - There are approximately number matching rows in the range
// HA_POS_ERROR - Something is wrong with the index tree
//
ha_rows ha_tokudb::records_in_range(uint keynr, key_range* start_key, key_range* end_key) {
ha_rows ha_tokudb::records_in_range(uint keynr, const key_range* start_key,
const key_range* end_key,
page_range *pages) {
TOKUDB_HANDLER_DBUG_ENTER("%d %p %p", keynr, start_key, end_key);
DBT *pleft_key, *pright_key;
DBT left_key, right_key;

View File

@ -844,7 +844,9 @@ public:
int external_lock(THD * thd, int lock_type);
int start_stmt(THD * thd, thr_lock_type lock_type);
ha_rows records_in_range(uint inx, key_range * min_key, key_range * max_key);
ha_rows records_in_range(uint inx, const key_range * min_key,
const key_range * max_key,
page_range *pages);
uint32_t get_cursor_isolation_flags(enum thr_lock_type lock_type, THD* thd);
THR_LOCK_DATA **store_lock(THD * thd, THR_LOCK_DATA ** to, enum thr_lock_type lock_type);