summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorMattias Jonsson <mattias.jonsson@oracle.com>2010-07-09 15:02:27 +0200
committerMattias Jonsson <mattias.jonsson@oracle.com>2010-07-09 15:02:27 +0200
commita0752a9eaff88a7204e0871dd2c52abbd0c9c1a9 (patch)
treeaae086366c0b02897d04b3ca6ed86afc23ef0203 /sql
parent07e1cdc179ba1e24794e3785fb837de705158581 (diff)
parent6433a5535662753aedd95759000cd354dd8e3fba (diff)
downloadmariadb-git-a0752a9eaff88a7204e0871dd2c52abbd0c9c1a9.tar.gz
merge
Diffstat (limited to 'sql')
-rw-r--r--sql/ha_partition.cc52
-rw-r--r--sql/ha_partition.h15
-rw-r--r--sql/handler.h18
3 files changed, 75 insertions, 10 deletions
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index 3fb5a30b560..60f2d4d9dc5 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -4371,6 +4371,58 @@ int ha_partition::index_read_last_map(uchar *buf, const uchar *key,
/*
+ Optimization of the default implementation to take advantage of dynamic
+ partition pruning.
+*/
+int ha_partition::index_read_idx_map(uchar *buf, uint index,
+ const uchar *key,
+ key_part_map keypart_map,
+ enum ha_rkey_function find_flag)
+{
+ int error= HA_ERR_KEY_NOT_FOUND;
+ DBUG_ENTER("ha_partition::index_read_idx_map");
+
+ if (find_flag == HA_READ_KEY_EXACT)
+ {
+ uint part;
+ m_start_key.key= key;
+ m_start_key.keypart_map= keypart_map;
+ m_start_key.flag= find_flag;
+ m_start_key.length= calculate_key_len(table, index, m_start_key.key,
+ m_start_key.keypart_map);
+
+ get_partition_set(table, buf, index, &m_start_key, &m_part_spec);
+
+ /* How can it be more than one partition with the current use? */
+ DBUG_ASSERT(m_part_spec.start_part == m_part_spec.end_part);
+
+ for (part= m_part_spec.start_part; part <= m_part_spec.end_part; part++)
+ {
+ if (bitmap_is_set(&(m_part_info->used_partitions), part))
+ {
+ error= m_file[part]->index_read_idx_map(buf, index, key,
+ keypart_map, find_flag);
+ if (error != HA_ERR_KEY_NOT_FOUND &&
+ error != HA_ERR_END_OF_FILE)
+ break;
+ }
+ }
+ }
+ else
+ {
+ /*
+ If not only used with READ_EXACT, we should investigate if possible
+ to optimize for other find_flag's as well.
+ */
+ DBUG_ASSERT(0);
+ /* fall back on the default implementation */
+ error= handler::index_read_idx_map(buf, index, key, keypart_map, find_flag);
+ }
+ DBUG_RETURN(error);
+}
+
+
+/*
Read next record in a forward index scan
SYNOPSIS
diff --git a/sql/ha_partition.h b/sql/ha_partition.h
index eec3cb71537..cdbfb2163c7 100644
--- a/sql/ha_partition.h
+++ b/sql/ha_partition.h
@@ -36,8 +36,7 @@ enum partition_keywords
HA_CAN_FULLTEXT | \
HA_DUPLICATE_POS | \
HA_CAN_SQL_HANDLER | \
- HA_CAN_INSERT_DELAYED | \
- HA_PRIMARY_KEY_REQUIRED_FOR_POSITION)
+ HA_CAN_INSERT_DELAYED)
class ha_partition :public handler
{
private:
@@ -431,6 +430,15 @@ public:
virtual int index_init(uint idx, bool sorted);
virtual int index_end();
+ /**
+ @breif
+ Positions an index cursor to the index specified in the hanlde. Fetches the
+ row if available. If the key value is null, begin at first key of the
+ index.
+ */
+ virtual int index_read_idx_map(uchar *buf, uint index, const uchar *key,
+ key_part_map keypart_map,
+ enum ha_rkey_function find_flag);
/*
These methods are used to jump to next or previous entry in the index
scan. There are also methods to jump to first and last entry.
@@ -749,9 +757,6 @@ public:
HA_PRIMARY_KEY_REQUIRED_FOR_POSITION:
Does the storage engine need a PK for position?
- Used with hidden primary key in InnoDB.
- Hidden primary keys cannot be supported by partitioning, since the
- partitioning expressions columns must be a part of the primary key.
(InnoDB)
HA_FILE_BASED is always set for partition handler since we use a
diff --git a/sql/handler.h b/sql/handler.h
index fc49d9e647d..d73bd949a02 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -100,7 +100,10 @@
#define HA_PRIMARY_KEY_IN_READ_INDEX (1 << 15)
/*
If HA_PRIMARY_KEY_REQUIRED_FOR_POSITION is set, it means that to position()
- uses a primary key. Without primary key, we can't call position().
+ uses a primary key given by the record argument.
+ Without primary key, we can't call position().
+ If not set, the position is returned as the current rows position
+ regardless of what argument is given.
*/
#define HA_PRIMARY_KEY_REQUIRED_FOR_POSITION (1 << 16)
#define HA_CAN_RTREEKEYS (1 << 17)
@@ -1537,10 +1540,9 @@ public:
virtual int rnd_next(uchar *buf)=0;
virtual int rnd_pos(uchar * buf, uchar *pos)=0;
/**
- One has to use this method when to find
- random position by record as the plain
- position() call doesn't work for some
- handlers for random position.
+ This function only works for handlers having
+ HA_PRIMARY_KEY_REQUIRED_FOR_POSITION set.
+ It will return the row with the PK given in the record argument.
*/
virtual int rnd_pos_by_record(uchar *record)
{
@@ -1558,6 +1560,12 @@ public:
{ return HA_ERR_WRONG_COMMAND; }
virtual ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key)
{ return (ha_rows) 10; }
+ /*
+ If HA_PRIMARY_KEY_REQUIRED_FOR_POSITION is set, then it sets ref
+ (reference to the row, aka position, with the primary key given in
+ the record).
+ Otherwise it set ref to the current row.
+ */
virtual void position(const uchar *record)=0;
virtual int info(uint)=0; // see my_base.h for full description
virtual void get_dynamic_partition_info(PARTITION_STATS *stat_info,