Below is the list of changes that have just been committed into a local
5.1 repository of patg. When patg does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet
1.1961 05/12/16 05:25:19 patg@stripped +3 -0
wl# 2682
Changes to test if a partition specified in a query exists by using a HASH member of the
share, as well as adding the bitmap used_partitions to the handler class
sql/handler.h
1.172 05/12/16 05:25:11 patg@stripped +3 -1
wl# 2682
Added used_partitions bitmap
sql/ha_partition.h
1.7 05/12/16 05:25:11 patg@stripped +9 -0
New struct st_partition_name - a record to store in a hash keyed by partition names.
sql/ha_partition.cc
1.13 05/12/16 05:25:11 patg@stripped +96 -2
wl# 2682 -
Add share->partition_names HASH to share. This is a HASH object to store a parition_name
struct that has partition_name, number, name length and is_sub_partition bool. The reason
for a HASH is for quick lookups to verify a given subpartition in 'SELECT * FROM foo PARTITION (foo)"
exists. Also added is_partition_in table to return bool of whether the partition is
in the table.
Made sure all hash members are deleted in ::close, but still need to figure out how to
free share->partition_names
Using the call to is_partition_in_table in external_lock and throwing an error if not works
just fine!
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: patg
# Host: krsna.patg.net
# Root: /home/patg/mysql-build/mysql-5.1-wl2682
--- 1.171/sql/handler.h 2005-12-13 12:14:45 -08:00
+++ 1.172/sql/handler.h 2005-12-16 05:25:11 -08:00
@@ -555,7 +555,9 @@
longlong *range_int_array;
LIST_PART_ENTRY *list_array;
};
- char* part_info_string;
+
+ MY_BITMAP *used_partitions;
+ char *part_info_string;
char *part_func_string;
char *subpart_func_string;
--- 1.12/sql/ha_partition.cc 2005-11-25 20:17:12 -08:00
+++ 1.13/sql/ha_partition.cc 2005-12-16 05:25:11 -08:00
@@ -62,6 +62,26 @@
static PARTITION_SHARE *get_share(const char *table_name, TABLE * table);
#endif
+static byte *partition_names_get_key(PARTITION_NAME *partition_name, uint *length,
+ my_bool not_used __attribute__ ((unused)))
+{
+ *length= partition_name->partition_name_length;
+ return (byte *) partition_name->partition_name;
+}
+
+bool is_partition_in_table(PARTITION_SHARE *share, char *name)
+{
+ PARTITION_NAME *partition_name;
+ DBUG_ENTER("is_partition_in_table");
+ partition_name= (PARTITION_NAME*)hash_search(&share->partition_names,
+ (byte*) name,
+ strlen(name));
+ if (partition_name && partition_name->partition_name)
+ DBUG_RETURN(1);
+
+ DBUG_RETURN(0);
+}
+
/****************************************************************************
MODULE create/delete handler object
****************************************************************************/
@@ -863,12 +883,15 @@
int ha_partition::open(const char *name, int mode, uint test_if_locked)
{
- int error;
char name_buff[FN_REFLEN];
char *name_buffer_ptr= m_name_buffer_ptr;
+ int error;
+ uint alloc_len,i, j, part_num_counter= 0;
handler **file;
- uint alloc_len;
+ List_iterator_fast <partition_element> part_it(m_part_info->partitions);
DBUG_ENTER("ha_partition::open");
+ (void) hash_init(&share->partition_names, system_charset_info, 32, 0, 0,
+ (hash_get_key) partition_names_get_key, 0, 0);
ref_length= 0;
m_part_field_array= m_part_info->full_part_field_array;
@@ -903,6 +926,39 @@
m_start_key.key= (const byte*)ptr;
}
}
+ for (i= 0; i < m_part_info->no_parts; i++)
+ {
+ PARTITION_NAME *partition_name = (PARTITION_NAME*)my_malloc(sizeof(PARTITION_NAME), MYF(MY_WME));
+ partition_element *part_elem= part_it++;
+ partition_name->partition_name= part_elem->partition_name;
+ partition_name->partition_name_length= strlen(part_elem->partition_name);
+ partition_name->partition_number=part_num_counter++;
+ partition_name->is_sub_partition= FALSE;
+ if (my_hash_insert(&share->partition_names, (byte *)partition_name))
+ goto err_handler;
+ if (is_sub_partitioned(m_part_info))
+ {
+ List_iterator<partition_element> sub_it(part_elem->subpartitions);
+ for (j= 0; j < m_part_info->no_subparts; j++)
+ {
+ partition_element *sub_elem= sub_it++;
+ if (!strcmp(sub_elem->partition_name, part_elem->partition_name))
+ {
+ PARTITION_NAME *sub_partition_name =
+ (PARTITION_NAME*)my_malloc(sizeof(PARTITION_NAME), MYF(MY_WME));
+ sub_partition_name->partition_name= sub_elem->partition_name;
+ sub_partition_name->partition_name_length= strlen(sub_elem->partition_name);
+ sub_partition_name->partition_number=part_num_counter++;
+ sub_partition_name->is_sub_partition= TRUE;
+ }
+ else
+ {
+ continue;
+ }
+ }
+ }
+ DBUG_PRINT("info", ("partition name %s", part_elem->partition_name));
+ }
file= m_file;
do
{
@@ -914,6 +970,7 @@
name_buffer_ptr+= strlen(name_buffer_ptr) + 1;
set_if_bigger(ref_length, ((*file)->ref_length));
} while (*(++file));
+
/*
Add 2 bytes for partition id in position ref length.
ref_length=max_in_all_partitions(ref_length) + PARTITION_BYTES_IN_POS
@@ -931,6 +988,9 @@
if ((error= init_queue(&queue, m_tot_parts, (uint) PARTITION_BYTES_IN_POS,
0, key_rec_cmp, (void*)this)))
goto err_handler;
+
+
+
/*
Some handlers update statistics as part of the open call. This will in
some cases corrupt the statistics of the partition handler and thus
@@ -960,12 +1020,21 @@
int ha_partition::close(void)
{
handler **file;
+ List_iterator_fast <partition_element> part_it(m_part_info->partitions);
DBUG_ENTER("ha_partition::close");
delete_queue(&queue);
file= m_file;
do
{
+ PARTITION_NAME *partition_name;
+ partition_element *part_elem= part_it++;
+ partition_name= (PARTITION_NAME*)hash_search(&share->partition_names,
+ (byte*) part_elem->partition_name,
+ strlen(part_elem->partition_name));
+ VOID(hash_delete(&share->partition_names, (byte*)partition_name));
+ DBUG_PRINT("info", ("partition_name->partition_name %s", partition_name->partition_name));
+ my_free((gptr) partition_name, MYF(0));
(*file)->close();
} while (*(++file));
DBUG_RETURN(0);
@@ -1004,12 +1073,32 @@
{
uint error;
handler **file;
+ uint i;
+ bool is_in_list;
+ List_iterator_fast <partition_element> part_it(m_part_info->partitions);
DBUG_ENTER("ha_partition::external_lock");
+ if (thd->lex->part_info)
+ {
+ uint retval=0;
+ retval= is_partition_in_table(share, thd->lex->part_info->selected_partition);
+ if (retval)
+ {
+ DBUG_PRINT("info", ("selected partition %s is in table",
+ thd->lex->part_info->selected_partition));
+ }
+ else
+ {
+ my_error(ER_NO_SUCH_PARTITION, MYF(0),
+ thd->lex->part_info->selected_partition);
+ }
+ }
+ DBUG_PRINT("info", ("is_in_list %d", is_in_list));
file= m_file;
do
{
if ((error= (*file)->external_lock(thd, lock_type)))
{
+ DBUG_PRINT("info", ("(file)->s->table_name.str", (*file)->table_share->table_name.str));
if (lock_type != F_UNLCK)
goto err_handler;
}
@@ -3261,6 +3350,11 @@
hash_delete(&partition_open_tables, (byte *) share);
thr_lock_delete(&share->lock);
pthread_mutex_destroy(&share->mutex);
+ /*
+ this doesn't seem to free share->partition_names,
+ need to know how to make sure this happens
+ */
+ my_free((gptr) &share->partition_names, MYF(0));
my_free((gptr) share, MYF(0));
}
pthread_mutex_unlock(&partition_mutex);
--- 1.6/sql/ha_partition.h 2005-11-25 00:08:30 -08:00
+++ 1.7/sql/ha_partition.h 2005-12-16 05:25:11 -08:00
@@ -28,8 +28,17 @@
char *table_name;
uint table_name_length, use_count;
pthread_mutex_t mutex;
+ HASH partition_names;
THR_LOCK lock;
} PARTITION_SHARE;
+
+typedef struct st_partition_name
+{
+ char *partition_name;
+ bool is_sub_partition;
+ uint partition_name_length;
+ uint partition_number;
+} PARTITION_NAME;
#define PARTITION_BYTES_IN_POS 2
| Thread |
|---|
| • bk commit into 5.1 tree (patg:1.1961) | Patrick Galbraith | 16 Dec |