Commit 6a421c56 authored by unknown's avatar unknown

bug 17290 and bug 14350

added THD::work_part_info member where we now store modified
partition_info structure.
It allows no solve problem when different parts of the part_info get
into different mem_roots


sql/partition_info.cc:
  get_clone implementation
sql/partition_info.h:
  get_clone() declared
sql/sql_class.h:
  THD::work_part_info added
sql/sql_partition.cc:
  thd->work_part_info instead of lex->part_info
sql/sql_table.cc:
  thd->work_part_info instad of lex->part_info
sql/unireg.cc:
  thd->work_part_info instad of lex->part_info
parent 4ac5afa3
...@@ -25,6 +25,48 @@ ...@@ -25,6 +25,48 @@
#ifdef WITH_PARTITION_STORAGE_ENGINE #ifdef WITH_PARTITION_STORAGE_ENGINE
partition_info *partition_info::get_clone()
{
if (!this)
return 0;
List_iterator<partition_element> part_it(partitions);
partition_element *part;
partition_info *clone= new partition_info();
if (!clone)
{
mem_alloc_error(sizeof(partition_info));
return NULL;
}
memcpy(clone, this, sizeof(partition_info));
clone->partitions.empty();
while ((part= (part_it++)))
{
List_iterator<partition_element> subpart_it(part->subpartitions);
partition_element *subpart;
partition_element *part_clone= new partition_element();
if (!part_clone)
{
mem_alloc_error(sizeof(partition_element));
return NULL;
}
memcpy(part_clone, part, sizeof(partition_element));
part_clone->subpartitions.empty();
while ((subpart= (subpart_it++)))
{
partition_element *subpart_clone= new partition_element();
if (!subpart_clone)
{
mem_alloc_error(sizeof(partition_element));
return NULL;
}
memcpy(subpart_clone, subpart, sizeof(partition_element));
part_clone->subpartitions.push_back(subpart_clone);
}
clone->partitions.push_back(part_clone);
}
return clone;
}
/* /*
Create a memory area where default partition names are stored and fill it Create a memory area where default partition names are stored and fill it
......
...@@ -229,6 +229,7 @@ class partition_info : public Sql_alloc ...@@ -229,6 +229,7 @@ class partition_info : public Sql_alloc
} }
~partition_info() {} ~partition_info() {}
partition_info *get_clone();
/* Answers the question if subpartitioning is used for a certain table */ /* Answers the question if subpartitioning is used for a certain table */
bool is_sub_partitioned() bool is_sub_partitioned()
{ {
......
...@@ -1206,6 +1206,7 @@ class THD :public Statement, ...@@ -1206,6 +1206,7 @@ class THD :public Statement,
*/ */
query_id_t first_query_id; query_id_t first_query_id;
} binlog_evt_union; } binlog_evt_union;
partition_info *work_part_info;
THD(); THD();
~THD(); ~THD();
......
...@@ -4077,6 +4077,9 @@ uint prep_alter_part_table(THD *thd, TABLE *table, ALTER_INFO *alter_info, ...@@ -4077,6 +4077,9 @@ uint prep_alter_part_table(THD *thd, TABLE *table, ALTER_INFO *alter_info,
if (table->part_info) if (table->part_info)
table->s->version= 0L; table->s->version= 0L;
if (!(thd->work_part_info= thd->lex->part_info->get_clone()))
DBUG_RETURN(TRUE);
if (alter_info->flags & if (alter_info->flags &
(ALTER_ADD_PARTITION | ALTER_DROP_PARTITION | (ALTER_ADD_PARTITION | ALTER_DROP_PARTITION |
ALTER_COALESCE_PARTITION | ALTER_REORGANIZE_PARTITION | ALTER_COALESCE_PARTITION | ALTER_REORGANIZE_PARTITION |
...@@ -4085,7 +4088,7 @@ uint prep_alter_part_table(THD *thd, TABLE *table, ALTER_INFO *alter_info, ...@@ -4085,7 +4088,7 @@ uint prep_alter_part_table(THD *thd, TABLE *table, ALTER_INFO *alter_info,
ALTER_REPAIR_PARTITION | ALTER_REBUILD_PARTITION)) ALTER_REPAIR_PARTITION | ALTER_REBUILD_PARTITION))
{ {
partition_info *tab_part_info= table->part_info; partition_info *tab_part_info= table->part_info;
partition_info *alt_part_info= thd->lex->part_info; partition_info *alt_part_info= thd->work_part_info;
uint flags= 0; uint flags= 0;
if (!tab_part_info) if (!tab_part_info)
{ {
...@@ -4121,7 +4124,7 @@ uint prep_alter_part_table(THD *thd, TABLE *table, ALTER_INFO *alter_info, ...@@ -4121,7 +4124,7 @@ uint prep_alter_part_table(THD *thd, TABLE *table, ALTER_INFO *alter_info,
setting the flag for no default number of partitions setting the flag for no default number of partitions
*/ */
alter_info->flags|= ALTER_ADD_PARTITION; alter_info->flags|= ALTER_ADD_PARTITION;
thd->lex->part_info->no_parts= new_part_no - curr_part_no; thd->work_part_info->no_parts= new_part_no - curr_part_no;
} }
else else
{ {
...@@ -4145,17 +4148,17 @@ uint prep_alter_part_table(THD *thd, TABLE *table, ALTER_INFO *alter_info, ...@@ -4145,17 +4148,17 @@ uint prep_alter_part_table(THD *thd, TABLE *table, ALTER_INFO *alter_info,
*fast_alter_partition, flags)); *fast_alter_partition, flags));
if (((alter_info->flags & ALTER_ADD_PARTITION) || if (((alter_info->flags & ALTER_ADD_PARTITION) ||
(alter_info->flags & ALTER_REORGANIZE_PARTITION)) && (alter_info->flags & ALTER_REORGANIZE_PARTITION)) &&
(thd->lex->part_info->part_type != tab_part_info->part_type) && (thd->work_part_info->part_type != tab_part_info->part_type) &&
(thd->lex->part_info->part_type != NOT_A_PARTITION)) (thd->work_part_info->part_type != NOT_A_PARTITION))
{ {
if (thd->lex->part_info->part_type == RANGE_PARTITION) if (thd->work_part_info->part_type == RANGE_PARTITION)
{ {
my_error(ER_PARTITION_WRONG_VALUES_ERROR, MYF(0), my_error(ER_PARTITION_WRONG_VALUES_ERROR, MYF(0),
"RANGE", "LESS THAN"); "RANGE", "LESS THAN");
} }
else if (thd->lex->part_info->part_type == LIST_PARTITION) else if (thd->work_part_info->part_type == LIST_PARTITION)
{ {
DBUG_ASSERT(thd->lex->part_info->part_type == LIST_PARTITION); DBUG_ASSERT(thd->work_part_info->part_type == LIST_PARTITION);
my_error(ER_PARTITION_WRONG_VALUES_ERROR, MYF(0), my_error(ER_PARTITION_WRONG_VALUES_ERROR, MYF(0),
"LIST", "IN"); "LIST", "IN");
} }
...@@ -4623,8 +4626,8 @@ state of p1. ...@@ -4623,8 +4626,8 @@ state of p1.
This command can be used on RANGE and LIST partitions. This command can be used on RANGE and LIST partitions.
*/ */
uint no_parts_reorged= alter_info->partition_names.elements; uint no_parts_reorged= alter_info->partition_names.elements;
uint no_parts_new= thd->lex->part_info->partitions.elements; uint no_parts_new= thd->work_part_info->partitions.elements;
partition_info *alt_part_info= thd->lex->part_info; partition_info *alt_part_info= thd->work_part_info;
uint check_total_partitions; uint check_total_partitions;
if (no_parts_reorged > tab_part_info->no_parts) if (no_parts_reorged > tab_part_info->no_parts)
{ {
...@@ -4770,7 +4773,7 @@ the generated partition syntax in a correct manner. ...@@ -4770,7 +4773,7 @@ the generated partition syntax in a correct manner.
DBUG_ASSERT(FALSE); DBUG_ASSERT(FALSE);
} }
*partition_changed= TRUE; *partition_changed= TRUE;
thd->lex->part_info= tab_part_info; thd->work_part_info= tab_part_info;
if (alter_info->flags == ALTER_ADD_PARTITION || if (alter_info->flags == ALTER_ADD_PARTITION ||
alter_info->flags == ALTER_REORGANIZE_PARTITION) alter_info->flags == ALTER_REORGANIZE_PARTITION)
{ {
...@@ -4840,35 +4843,35 @@ the generated partition syntax in a correct manner. ...@@ -4840,35 +4843,35 @@ the generated partition syntax in a correct manner.
*/ */
if (table->part_info) if (table->part_info)
{ {
if (!thd->lex->part_info && if (!thd->work_part_info &&
create_info->db_type == old_db_type) create_info->db_type == old_db_type)
thd->lex->part_info= table->part_info; thd->work_part_info= table->part_info;
} }
if (thd->lex->part_info) if (thd->work_part_info)
{ {
/* /*
Need to cater for engine types that can handle partition without Need to cater for engine types that can handle partition without
using the partition handler. using the partition handler.
*/ */
if (thd->lex->part_info != table->part_info) if (thd->work_part_info != table->part_info)
*partition_changed= TRUE; *partition_changed= TRUE;
if (create_info->db_type == &partition_hton) if (create_info->db_type == &partition_hton)
{ {
if (table->part_info) if (table->part_info)
{ {
thd->lex->part_info->default_engine_type= thd->work_part_info->default_engine_type=
table->part_info->default_engine_type; table->part_info->default_engine_type;
} }
else else
{ {
thd->lex->part_info->default_engine_type= thd->work_part_info->default_engine_type=
ha_checktype(thd, DB_TYPE_DEFAULT, FALSE, FALSE); ha_checktype(thd, DB_TYPE_DEFAULT, FALSE, FALSE);
} }
} }
else else
{ {
bool is_native_partitioned= FALSE; bool is_native_partitioned= FALSE;
partition_info *part_info= thd->lex->part_info; partition_info *part_info= thd->work_part_info;
part_info->default_engine_type= create_info->db_type; part_info->default_engine_type= create_info->db_type;
if (check_native_partitioned(create_info, &is_native_partitioned, if (check_native_partitioned(create_info, &is_native_partitioned,
part_info, thd)) part_info, thd))
...@@ -4882,7 +4885,7 @@ the generated partition syntax in a correct manner. ...@@ -4882,7 +4885,7 @@ the generated partition syntax in a correct manner.
} }
} }
DBUG_PRINT("info", ("default_db_type = %s", DBUG_PRINT("info", ("default_db_type = %s",
thd->lex->part_info->default_engine_type->name)); thd->work_part_info->default_engine_type->name));
} }
} }
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
...@@ -5065,7 +5068,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table, ...@@ -5065,7 +5068,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
lpt->deleted= 0; lpt->deleted= 0;
lpt->pack_frm_data= NULL; lpt->pack_frm_data= NULL;
lpt->pack_frm_len= 0; lpt->pack_frm_len= 0;
thd->lex->part_info= part_info; thd->work_part_info= part_info;
if (alter_info->flags & ALTER_OPTIMIZE_PARTITION || if (alter_info->flags & ALTER_OPTIMIZE_PARTITION ||
alter_info->flags & ALTER_ANALYZE_PARTITION || alter_info->flags & ALTER_ANALYZE_PARTITION ||
......
...@@ -2037,7 +2037,10 @@ bool mysql_create_table_internal(THD *thd, ...@@ -2037,7 +2037,10 @@ bool mysql_create_table_internal(THD *thd,
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
#ifdef WITH_PARTITION_STORAGE_ENGINE #ifdef WITH_PARTITION_STORAGE_ENGINE
partition_info *part_info= thd->lex->part_info; partition_info *part_info;
if (!(part_info= thd->lex->part_info->get_clone()))
DBUG_RETURN(TRUE);
thd->work_part_info= part_info;
if (!part_info && create_info->db_type->partition_flags && if (!part_info && create_info->db_type->partition_flags &&
(create_info->db_type->partition_flags() & HA_USE_AUTO_PARTITION)) (create_info->db_type->partition_flags() & HA_USE_AUTO_PARTITION))
{ {
...@@ -2046,7 +2049,7 @@ bool mysql_create_table_internal(THD *thd, ...@@ -2046,7 +2049,7 @@ bool mysql_create_table_internal(THD *thd,
all tables as partitioned. The handler will set up the partition info all tables as partitioned. The handler will set up the partition info
object with the default settings. object with the default settings.
*/ */
thd->lex->part_info= part_info= new partition_info(); thd->work_part_info= part_info= new partition_info();
if (!part_info) if (!part_info)
{ {
mem_alloc_error(sizeof(partition_info)); mem_alloc_error(sizeof(partition_info));
......
...@@ -86,7 +86,7 @@ bool mysql_create_frm(THD *thd, const char *file_name, ...@@ -86,7 +86,7 @@ bool mysql_create_frm(THD *thd, const char *file_name,
uchar *screen_buff; uchar *screen_buff;
char buff[32]; char buff[32];
#ifdef WITH_PARTITION_STORAGE_ENGINE #ifdef WITH_PARTITION_STORAGE_ENGINE
partition_info *part_info= thd->lex->part_info; partition_info *part_info= thd->work_part_info;
#endif #endif
DBUG_ENTER("mysql_create_frm"); DBUG_ENTER("mysql_create_frm");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment