summaryrefslogtreecommitdiff
path: root/sql/ha_partition.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/ha_partition.cc')
-rw-r--r--sql/ha_partition.cc191
1 files changed, 96 insertions, 95 deletions
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index b1a5a447b6f..1d12d1967d3 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -69,7 +69,8 @@ static PARTITION_SHARE *get_share(const char *table_name, TABLE * table);
MODULE create/delete handler object
****************************************************************************/
-static handler *partition_create_handler(TABLE_SHARE *share);
+static handler *partition_create_handler(TABLE_SHARE *share,
+ MEM_ROOT *mem_root);
static uint partition_flags();
static uint alter_table_flags(uint flags);
@@ -125,9 +126,16 @@ handlerton partition_hton = {
New partition object
*/
-static handler *partition_create_handler(TABLE_SHARE *share)
+static handler *partition_create_handler(TABLE_SHARE *share,
+ MEM_ROOT *mem_root)
{
- return new ha_partition(share);
+ ha_partition *file= new (mem_root) ha_partition(share);
+ if (file && file->initialise_partition(mem_root))
+ {
+ delete file;
+ file= 0;
+ }
+ return file;
}
/*
@@ -229,7 +237,6 @@ void ha_partition::init_handler_variables()
m_reorged_parts= 0;
m_added_file= NULL;
m_tot_parts= 0;
- m_has_transactions= 0;
m_pkey_is_clustered= 0;
m_lock_type= F_UNLCK;
m_part_spec.start_part= NO_CURRENT_PART_ID;
@@ -301,7 +308,8 @@ ha_partition::~ha_partition()
Initialise partition handler object
SYNOPSIS
- ha_initialise()
+ initialise_partition()
+ mem_root Allocate memory through this
RETURN VALUE
1 Error
@@ -341,16 +349,16 @@ ha_partition::~ha_partition()
*/
-int ha_partition::ha_initialise()
+bool ha_partition::initialise_partition(MEM_ROOT *mem_root)
{
handler **file_array, *file;
- DBUG_ENTER("ha_partition::ha_initialise");
+ DBUG_ENTER("ha_partition::initialise_partition");
if (m_create_handler)
{
m_tot_parts= m_part_info->get_tot_partitions();
DBUG_ASSERT(m_tot_parts > 0);
- if (new_handlers_from_part_info())
+ if (new_handlers_from_part_info(mem_root))
DBUG_RETURN(1);
}
else if (!table_share || !table_share->normalized_path.str)
@@ -363,7 +371,7 @@ int ha_partition::ha_initialise()
m_table_flags|= HA_FILE_BASED | HA_REC_NOT_IN_SEQ;
DBUG_RETURN(0);
}
- else if (get_from_handler_file(table_share->normalized_path.str))
+ else if (get_from_handler_file(table_share->normalized_path.str, mem_root))
{
mem_alloc_error(2);
DBUG_RETURN(1);
@@ -377,12 +385,11 @@ int ha_partition::ha_initialise()
other parameters are calculated on demand.
HA_FILE_BASED is always set for partition handler since we use a
special file for handling names of partitions, engine types.
- HA_CAN_GEOMETRY, HA_CAN_FULLTEXT, HA_CAN_SQL_HANDLER, HA_DUPP_POS,
+ HA_CAN_GEOMETRY, HA_CAN_FULLTEXT, HA_CAN_SQL_HANDLER, HA_DUPLICATE_POS,
HA_CAN_INSERT_DELAYED is disabled until further investigated.
*/
m_table_flags= m_file[0]->table_flags();
m_low_byte_first= m_file[0]->low_byte_first();
- m_has_transactions= TRUE;
m_pkey_is_clustered= TRUE;
file_array= m_file;
do
@@ -394,13 +401,11 @@ int ha_partition::ha_initialise()
my_error(ER_MIX_HANDLER_ERROR, MYF(0));
DBUG_RETURN(1);
}
- if (!file->has_transactions())
- m_has_transactions= FALSE;
if (!file->primary_key_is_clustered())
m_pkey_is_clustered= FALSE;
m_table_flags&= file->table_flags();
} while (*(++file_array));
- m_table_flags&= ~(HA_CAN_GEOMETRY | HA_CAN_FULLTEXT | HA_DUPP_POS |
+ m_table_flags&= ~(HA_CAN_GEOMETRY | HA_CAN_FULLTEXT | HA_DUPLICATE_POS |
HA_CAN_SQL_HANDLER | HA_CAN_INSERT_DELAYED);
m_table_flags|= HA_FILE_BASED | HA_REC_NOT_IN_SEQ;
DBUG_RETURN(0);
@@ -1388,9 +1393,10 @@ int ha_partition::change_partitions(HA_CREATE_INFO *create_info,
uint j= 0;
do
{
- if (!(new_file_array[part_count++]= get_new_handler(table->s,
- thd->mem_root,
- part_elem->engine_type)))
+ if (!(new_file_array[part_count++]=
+ get_new_handler(table->s,
+ thd->mem_root,
+ part_elem->engine_type)))
{
mem_alloc_error(sizeof(handler));
DBUG_RETURN(ER_OUTOFMEMORY);
@@ -1644,7 +1650,7 @@ uint ha_partition::del_ren_cre_table(const char *from,
handler **file;
DBUG_ENTER("del_ren_cre_table()");
- if (get_from_handler_file(from))
+ if (get_from_handler_file(from, current_thd->mem_root))
DBUG_RETURN(TRUE);
DBUG_ASSERT(m_file_buffer);
name_buffer_ptr= m_name_buffer_ptr;
@@ -1953,7 +1959,6 @@ void ha_partition::clear_handler_file()
my_free((char*) m_file_buffer, MYF(MY_ALLOW_ZERO_PTR));
my_free((char*) m_engine_array, MYF(MY_ALLOW_ZERO_PTR));
m_file_buffer= NULL;
- m_name_buffer_ptr= NULL;
m_engine_array= NULL;
}
@@ -1962,29 +1967,29 @@ void ha_partition::clear_handler_file()
SYNOPSIS
create_handlers()
+ mem_root Allocate memory through this
RETURN VALUE
TRUE Error
FALSE Success
*/
-bool ha_partition::create_handlers()
+bool ha_partition::create_handlers(MEM_ROOT *mem_root)
{
uint i;
uint alloc_len= (m_tot_parts + 1) * sizeof(handler*);
DBUG_ENTER("create_handlers");
- if (!(m_file= (handler **) sql_alloc(alloc_len)))
+ if (!(m_file= (handler **) alloc_root(mem_root, alloc_len)))
DBUG_RETURN(TRUE);
- bzero(m_file, alloc_len);
+ bzero((char*) m_file, alloc_len);
for (i= 0; i < m_tot_parts; i++)
{
- if (!(m_file[i]= get_new_handler(table_share, current_thd->mem_root,
+ if (!(m_file[i]= get_new_handler(table_share, mem_root,
m_engine_array[i])))
DBUG_RETURN(TRUE);
DBUG_PRINT("info", ("engine_type: %u", m_engine_array[i]));
}
- m_file[m_tot_parts]= 0;
/* For the moment we only support partition over the same table engine */
if (m_engine_array[0] == &myisam_hton)
{
@@ -2005,13 +2010,14 @@ bool ha_partition::create_handlers()
SYNOPSIS
new_handlers_from_part_info()
+ mem_root Allocate memory through this
RETURN VALUE
TRUE Error
FALSE Success
*/
-bool ha_partition::new_handlers_from_part_info()
+bool ha_partition::new_handlers_from_part_info(MEM_ROOT *mem_root)
{
uint i, j, part_count;
partition_element *part_elem;
@@ -2020,12 +2026,12 @@ bool ha_partition::new_handlers_from_part_info()
THD *thd= current_thd;
DBUG_ENTER("ha_partition::new_handlers_from_part_info");
- if (!(m_file= (handler **) sql_alloc(alloc_len)))
+ if (!(m_file= (handler **) alloc_root(mem_root, alloc_len)))
{
mem_alloc_error(alloc_len);
goto error_end;
}
- bzero(m_file, alloc_len);
+ bzero((char*) m_file, alloc_len);
DBUG_ASSERT(m_part_info->no_parts > 0);
i= 0;
@@ -2041,8 +2047,8 @@ bool ha_partition::new_handlers_from_part_info()
{
for (j= 0; j < m_part_info->no_subparts; j++)
{
- if (!(m_file[i]= get_new_handler(table_share, thd->mem_root,
- part_elem->engine_type)))
+ if (!(m_file[part_count++]= get_new_handler(table_share, mem_root,
+ part_elem->engine_type)))
goto error;
DBUG_PRINT("info", ("engine_type: %u",
(uint) ha_legacy_type(part_elem->engine_type)));
@@ -2050,7 +2056,7 @@ bool ha_partition::new_handlers_from_part_info()
}
else
{
- if (!(m_file[part_count++]= get_new_handler(table_share, thd->mem_root,
+ if (!(m_file[part_count++]= get_new_handler(table_share, mem_root,
part_elem->engine_type)))
goto error;
DBUG_PRINT("info", ("engine_type: %u",
@@ -2076,6 +2082,7 @@ error_end:
SYNOPSIS
get_from_handler_file()
name Full path of table name
+ mem_root Allocate memory through this
RETURN VALUE
TRUE Error
@@ -2086,7 +2093,7 @@ error_end:
partitions.
*/
-bool ha_partition::get_from_handler_file(const char *name)
+bool ha_partition::get_from_handler_file(const char *name, MEM_ROOT *mem_root)
{
char buff[FN_REFLEN], *address_tot_name_len;
File file;
@@ -2125,7 +2132,8 @@ bool ha_partition::get_from_handler_file(const char *name)
goto err2;
for (i= 0; i < m_tot_parts; i++)
engine_array[i]= ha_resolve_by_legacy_type(current_thd,
- (enum legacy_db_type) *(uchar *) ((file_buffer) + 12 + i));
+ (enum legacy_db_type)
+ *(uchar *) ((file_buffer) + 12 + i));
address_tot_name_len= file_buffer + 12 + 4 * tot_partition_words;
tot_name_words= (uint4korr(address_tot_name_len) + 3) / 4;
if (len_words != (tot_partition_words + tot_name_words + 4))
@@ -2135,7 +2143,7 @@ bool ha_partition::get_from_handler_file(const char *name)
m_file_buffer= file_buffer; // Will be freed in clear_handler_file()
m_name_buffer_ptr= name_buffer_ptr;
m_engine_array= engine_array;
- if (!m_file && create_handlers())
+ if (!m_file && create_handlers(mem_root))
{
clear_handler_file();
DBUG_RETURN(TRUE);
@@ -2189,7 +2197,7 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
m_mode= mode;
m_open_test_lock= test_if_locked;
m_part_field_array= m_part_info->full_part_field_array;
- if (get_from_handler_file(name))
+ if (get_from_handler_file(name, &table->mem_root))
DBUG_RETURN(1);
m_start_key.length= 0;
m_rec0= table->record[0];
@@ -2226,6 +2234,8 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
DBUG_RETURN(1);
bitmap_set_all(&(m_part_info->used_partitions));
+ /* Recalculate table flags as they may change after open */
+ m_table_flags= m_file[0]->table_flags();
file= m_file;
do
{
@@ -2237,7 +2247,11 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
m_no_locks+= (*file)->lock_count();
name_buffer_ptr+= strlen(name_buffer_ptr) + 1;
set_if_bigger(ref_length, ((*file)->ref_length));
+ m_table_flags&= (*file)->table_flags();
} while (*(++file));
+ m_table_flags&= ~(HA_CAN_GEOMETRY | HA_CAN_FULLTEXT | HA_DUPLICATE_POS |
+ HA_CAN_SQL_HANDLER | HA_CAN_INSERT_DELAYED);
+ m_table_flags|= HA_FILE_BASED | HA_REC_NOT_IN_SEQ;
/*
Add 2 bytes for partition id in position ref length.
@@ -2600,6 +2614,7 @@ int ha_partition::write_row(byte * buf)
if (table->next_number_field && buf == table->record[0])
update_auto_increment();
+ my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set);
#ifdef NOT_NEEDED
if (likely(buf == rec0))
#endif
@@ -2614,6 +2629,7 @@ int ha_partition::write_row(byte * buf)
set_field_ptr(m_part_field_array, rec0, buf);
}
#endif
+ dbug_tmp_restore_column_map(table->read_set, old_map);
if (unlikely(error))
DBUG_RETURN(error);
m_last_part= part_id;
@@ -4070,7 +4086,7 @@ void ha_partition::include_partition_fields_in_used_fields()
do
{
- ha_set_bit_in_read_set((*ptr)->fieldnr);
+ bitmap_set_bit(table->read_set, (*ptr)->field_index);
} while (*(++ptr));
DBUG_VOID_RETURN;
}
@@ -4158,7 +4174,7 @@ void ha_partition::info(uint flag)
if (flag & HA_STATUS_AUTO)
{
DBUG_PRINT("info", ("HA_STATUS_AUTO"));
- auto_increment_value= get_auto_increment();
+ stats.auto_increment_value= get_auto_increment();
}
if (flag & HA_STATUS_VARIABLE)
{
@@ -4180,11 +4196,11 @@ void ha_partition::info(uint flag)
check_time: Time of last check (only applicable to MyISAM)
We report last time of all underlying handlers
*/
- records= 0;
- deleted= 0;
- data_file_length= 0;
- index_file_length= 0;
- check_time= 0;
+ stats.records= 0;
+ stats.deleted= 0;
+ stats.data_file_length= 0;
+ stats.index_file_length= 0;
+ stats.check_time= 0;
file_array= m_file;
do
{
@@ -4192,21 +4208,21 @@ void ha_partition::info(uint flag)
{
file= *file_array;
file->info(HA_STATUS_VARIABLE);
- records+= file->records;
- deleted+= file->deleted;
- data_file_length+= file->data_file_length;
- index_file_length+= file->index_file_length;
- if (file->check_time > check_time)
- check_time= file->check_time;
+ stats.records+= file->stats.records;
+ stats.deleted+= file->stats.deleted;
+ stats.data_file_length+= file->stats.data_file_length;
+ stats.index_file_length+= file->stats.index_file_length;
+ if (file->stats.check_time > stats.check_time)
+ stats.check_time= file->stats.check_time;
}
} while (*(++file_array));
- if (records < 2 &&
- m_table_flags & HA_NOT_EXACT_COUNT)
- records= 2;
- if (records > 0)
- mean_rec_length= (ulong) (data_file_length / records);
+ if (stats.records < 2 &&
+ !(m_table_flags & HA_STATS_RECORDS_IS_EXACT))
+ stats.records= 2;
+ if (stats.records > 0)
+ stats.mean_rec_length= (ulong) (stats.data_file_length / stats.records);
else
- mean_rec_length= 1; //? What should we set here
+ stats.mean_rec_length= 1; //? What should we set here
}
if (flag & HA_STATUS_CONST)
{
@@ -4251,7 +4267,6 @@ void ha_partition::info(uint flag)
We ignore it since it is never used
block_size: Block size used
We set it to the value of the first handler
- sortkey: Never used at any place so ignored
ref_length: We set this to the value calculated
and stored in local object
create_time: Creation time of table
@@ -4263,7 +4278,7 @@ void ha_partition::info(uint flag)
file= m_file[0];
file->info(HA_STATUS_CONST);
- create_time= file->create_time;
+ stats.create_time= file->stats.create_time;
ref_length= m_ref_length;
}
if (flag & HA_STATUS_ERRKEY)
@@ -4287,14 +4302,14 @@ void ha_partition::info(uint flag)
Used by SHOW commands
We will report the maximum of these times
*/
- update_time= 0;
+ stats.update_time= 0;
file_array= m_file;
do
{
file= *file_array;
file->info(HA_STATUS_TIME);
- if (file->update_time > update_time)
- update_time= file->update_time;
+ if (file->stats.update_time > stats.update_time)
+ stats.update_time= file->stats.update_time;
} while (*(++file_array));
}
DBUG_VOID_RETURN;
@@ -4308,17 +4323,17 @@ void ha_partition::get_dynamic_partition_info(PARTITION_INFO *stat_info,
file->info(HA_STATUS_CONST | HA_STATUS_TIME | HA_STATUS_VARIABLE |
HA_STATUS_NO_LOCK);
- stat_info->records= file->records;
- stat_info->mean_rec_length= file->mean_rec_length;
- stat_info->data_file_length= file->data_file_length;
- stat_info->max_data_file_length= file->max_data_file_length;
- stat_info->index_file_length= file->index_file_length;
- stat_info->delete_length= file->delete_length;
- stat_info->create_time= file->create_time;
- stat_info->update_time= file->update_time;
- stat_info->check_time= file->check_time;
+ stat_info->records= file->stats.records;
+ stat_info->mean_rec_length= file->stats.mean_rec_length;
+ stat_info->data_file_length= file->stats.data_file_length;
+ stat_info->max_data_file_length= file->stats.max_data_file_length;
+ stat_info->index_file_length= file->stats.index_file_length;
+ stat_info->delete_length= file->stats.delete_length;
+ stat_info->create_time= file->stats.create_time;
+ stat_info->update_time= file->stats.update_time;
+ stat_info->check_time= file->stats.check_time;
stat_info->check_sum= 0;
- if (file->table_flags() & (ulong) HA_HAS_CHECKSUM)
+ if (file->ha_table_flags() & HA_HAS_CHECKSUM)
stat_info->check_sum= file->checksum();
return;
}
@@ -4389,22 +4404,6 @@ void ha_partition::get_dynamic_partition_info(PARTITION_INFO *stat_info,
2) Parameters used by some non-MyISAM handlers
----------------------------------------------
- HA_EXTRA_RETRIEVE_ALL_COLS:
- Many handlers have implemented optimisations to avoid fetching all
- fields when retrieving data. In certain situations all fields need
- to be retrieved even though the query_id is not set on all field
- objects.
-
- It is called from copy_data_between_tables where all fields are
- copied without setting query_id before calling the handlers.
- It is called from UPDATE statements when the fields of the index
- used is updated or ORDER BY is used with UPDATE.
- And finally when calculating checksum of a table using the CHECKSUM
- command.
- HA_EXTRA_RETRIEVE_PRIMARY_KEY:
- In some situations it is mandatory to retrieve primary key fields
- independent of the query id's. This extra flag specifies that fetch
- of primary key fields is mandatory.
HA_EXTRA_KEYREAD_PRESERVE_FIELDS:
This is a strictly InnoDB feature that is more or less undocumented.
When it is activated InnoDB copies field by field from its fetch
@@ -4553,7 +4552,7 @@ void ha_partition::get_dynamic_partition_info(PARTITION_INFO *stat_info,
4) Parameters only used by temporary tables for query processing
----------------------------------------------------------------
HA_EXTRA_RESET_STATE:
- Same as HA_EXTRA_RESET except that buffers are not released. If there is
+ Same as reset() except that buffers are not released. If there is
a READ CACHE it is reinit'ed. A cache is reinit'ed to restart reading
or to change type of cache between READ CACHE and WRITE CACHE.
@@ -4592,8 +4591,9 @@ void ha_partition::get_dynamic_partition_info(PARTITION_INFO *stat_info,
HA_EXTRA_FLUSH_CACHE:
Flush WRITE CACHE in MyISAM. It is only from one place in the code.
This is in sql_insert.cc where it is called if the table_flags doesn't
- contain HA_DUPP_POS. The only handler having the HA_DUPP_POS set is the
- MyISAM handler and so the only handler not receiving this call is MyISAM.
+ contain HA_DUPLICATE_POS. The only handler having the HA_DUPLICATE_POS
+ set is the MyISAM handler and so the only handler not receiving this
+ call is MyISAM.
Thus in effect this call is called but never used. Could be removed
from sql_insert.cc
HA_EXTRA_NO_USER_CHANGE:
@@ -4637,8 +4637,6 @@ int ha_partition::extra(enum ha_extra_function operation)
/* Category 2), used by non-MyISAM handlers */
case HA_EXTRA_IGNORE_DUP_KEY:
case HA_EXTRA_NO_IGNORE_DUP_KEY:
- case HA_EXTRA_RETRIEVE_ALL_COLS:
- case HA_EXTRA_RETRIEVE_PRIMARY_KEY:
case HA_EXTRA_KEYREAD_PRESERVE_FIELDS:
{
if (!m_myisam)
@@ -4704,8 +4702,7 @@ int ha_partition::extra(enum ha_extra_function operation)
0 Success
DESCRIPTION
- This will in the future be called instead of extra(HA_EXTRA_RESET) as this
- is such a common call
+ Called at end of each statement to reste buffers
*/
int ha_partition::reset(void)
@@ -5113,14 +5110,16 @@ void ha_partition::print_error(int error, myf errflag)
/* Should probably look for my own errors first */
/* monty: needs to be called for the last used partition ! */
- DBUG_PRINT("enter", ("error = %d", error));
+ DBUG_PRINT("enter", ("error: %d", error));
if (error == HA_ERR_NO_PARTITION_FOUND)
{
char buf[100];
+ my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set);
my_error(ER_NO_PARTITION_FOR_GIVEN_VALUE, MYF(0),
m_part_info->part_expr->null_value ? "NULL" :
llstr(m_part_info->part_expr->val_int(), buf));
+ dbug_tmp_restore_column_map(table->read_set, old_map);
}
else
m_file[0]->print_error(error, errflag);
@@ -5302,12 +5301,14 @@ void ha_partition::restore_auto_increment()
ulonglong ha_partition::get_auto_increment()
{
- ulonglong auto_inc, max_auto_inc= 0;
+ ulonglong max_auto_inc= 0;
+ handler **pos, **end;
DBUG_ENTER("ha_partition::get_auto_increment");
- for (uint i= 0; i < m_tot_parts; i++)
+ for (pos=m_file, end= m_file+ m_tot_parts; pos != end ; pos++)
{
- auto_inc= m_file[i]->get_auto_increment();
+ ulonglong auto_inc;
+ auto_inc= (*pos)->get_auto_increment();
set_if_bigger(max_auto_inc, auto_inc);
}
DBUG_RETURN(max_auto_inc);