diff options
author | Aditya A <aditya.a@oracle.com> | 2013-11-05 19:25:26 +0530 |
---|---|---|
committer | Aditya A <aditya.a@oracle.com> | 2013-11-05 19:25:26 +0530 |
commit | 097a5b59ed7ece015d3d90a04fb5cd27160a605b (patch) | |
tree | be79209485ccab9f689de65813cf4ab60139e0f3 /sql/ha_partition.cc | |
parent | 175085e7d20ae3b6e593167ab10a6078772d1730 (diff) | |
download | mariadb-git-097a5b59ed7ece015d3d90a04fb5cd27160a605b.tar.gz |
Bug#17588348: INDEX MERGE USED ON PARTITIONED TABLE
CAN RETURN WRONG RESULT SET
PROBLEM
-------
In ha_partition::cmp_ref() we were only calling the
underlying cmp_ref() of storage engine if the records
are in the same partiton,else we sort by partition and
returns the result.But the index merge intersect
algorithm expects first to sort by row-id first and
then by partition id.
FIX
---
Compare the refernces first using storage engine cmp_ref
and then if references are equal(only happens if
non clustered index is used) then sort it by partition id.
[Approved by Mattiasj #rb3755]
-
Diffstat (limited to 'sql/ha_partition.cc')
-rw-r--r-- | sql/ha_partition.cc | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 507f202e349..bf4ba5ed765 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -7485,19 +7485,29 @@ uint ha_partition::min_record_length(uint options) const int ha_partition::cmp_ref(const uchar *ref1, const uchar *ref2) { - uint part_id; + int cmp; my_ptrdiff_t diff1, diff2; - handler *file; DBUG_ENTER("ha_partition::cmp_ref"); + cmp = m_file[0]->cmp_ref((ref1 + PARTITION_BYTES_IN_POS), + (ref2 + PARTITION_BYTES_IN_POS)); + if (cmp) + DBUG_RETURN(cmp); + if ((ref1[0] == ref2[0]) && (ref1[1] == ref2[1])) { - part_id= uint2korr(ref1); - file= m_file[part_id]; - DBUG_ASSERT(part_id < m_tot_parts); - DBUG_RETURN(file->cmp_ref((ref1 + PARTITION_BYTES_IN_POS), - (ref2 + PARTITION_BYTES_IN_POS))); + /* This means that the references are same and are in same partition.*/ + DBUG_RETURN(0); } + + /* + In Innodb we compare with either primary key value or global DB_ROW_ID so + it is not possible that the two references are equal and are in different + partitions, but in myisam it is possible since we are comparing offsets. + Remove this assert if DB_ROW_ID is changed to be per partition. + */ + DBUG_ASSERT(!m_innodb); + diff1= ref2[1] - ref1[1]; diff2= ref2[0] - ref1[0]; if (diff1 > 0) |