diff options
author | Sergey Petrunya <psergey@askmonty.org> | 2014-02-17 18:53:54 +0400 |
---|---|---|
committer | Sergey Petrunya <psergey@askmonty.org> | 2014-02-17 18:53:54 +0400 |
commit | b594e31b6bd12cce22e8cd2b2a1eb097260f9470 (patch) | |
tree | a37bd1994e5e48f4745e06a10a056a4939b5410c /sql/ha_partition.cc | |
parent | c8abf3e6de5b84b1ab028116a040d0dcc1d19262 (diff) | |
parent | df963fd3c7c078ffcdf667e491ffb9688f89e0fd (diff) | |
download | mariadb-git-b594e31b6bd12cce22e8cd2b2a1eb097260f9470.tar.gz |
Merge
Diffstat (limited to 'sql/ha_partition.cc')
-rw-r--r-- | sql/ha_partition.cc | 61 |
1 files changed, 59 insertions, 2 deletions
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 87e80bd49cb..5d5eccc42bb 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -80,6 +80,7 @@ static handler *partition_create_handler(handlerton *hton, static uint partition_flags(); static uint alter_table_flags(uint flags); +extern "C" int cmp_key_then_part_id(void *key_p, uchar *ref1, uchar *ref2); static int partition_initialize(void *p) { @@ -4540,8 +4541,8 @@ bool ha_partition::init_record_priority_queue() } while (++i < m_tot_parts); m_start_key.key= (const uchar*)ptr; /* Initialize priority queue, initialized to reading forward. */ - if (init_queue(&m_queue, used_parts, (uint) PARTITION_BYTES_IN_POS, - 0, key_rec_cmp, (void*)m_curr_key_info, 0, 0)) + if (init_queue(&m_queue, used_parts, 0, + 0, cmp_key_then_part_id, (void*)m_curr_key_info, 0, 0)) { my_free(m_ordered_rec_buffer); m_ordered_rec_buffer= NULL; @@ -4737,6 +4738,52 @@ int ha_partition::index_read_map(uchar *buf, const uchar *key, } +/* + @brief + Provide ordering by (key_value, partition_id). + + @detail + Ordering by partition id is required so that key scans on key=const + return rows in rowid order (this is required for some variants of + index_merge to work). + + In ha_partition, rowid is a (partition_id, underlying_table_rowid). + handle_ordered_index_scan must return rows ordered by (key, rowid). + + If two rows have the same key value and come from different partitions, + it is sufficient to return them in the order of their partition_id. +*/ + +extern "C" int cmp_key_then_part_id(void *key_p, uchar *ref1, uchar *ref2) +{ + my_ptrdiff_t diff1, diff2; + int res; + + if ((res= key_rec_cmp(key_p, ref1 + PARTITION_BYTES_IN_POS, + ref2 + PARTITION_BYTES_IN_POS))) + { + return res; + } + + /* The following was taken from ha_partition::cmp_ref */ + diff1= ref2[1] - ref1[1]; + diff2= ref2[0] - ref1[0]; + if (!diff1 && !diff2) + return 0; + + if (diff1 > 0) + return(-1); + + if (diff1 < 0) + return(+1); + + if (diff2 > 0) + return(-1); + + return(+1); +} + + /** Common routine for a number of index_read variants @@ -7650,6 +7697,16 @@ uint ha_partition::min_record_length(uint options) const If they belong to different partitions we decide that they are not the same record. Otherwise we use the particular handler to decide if they are the same. Sort in partition id order if not equal. + + MariaDB note: + Please don't merge the code from MySQL that does this: + + We get two references and need to check if those records are the same. + If they belong to different partitions we decide that they are not + the same record. Otherwise we use the particular handler to decide if + they are the same. Sort in partition id order if not equal. + + It is incorrect, MariaDB has an alternative fix. */ int ha_partition::cmp_ref(const uchar *ref1, const uchar *ref2) |