summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <holyfoot@vva.(none)>2006-03-18 18:48:21 +0400
committerunknown <holyfoot@vva.(none)>2006-03-18 18:48:21 +0400
commit6a421c56cc425513901d141312bed9c744673b50 (patch)
tree352cfbefcb9f3e256bd081941ca8d1b73ef7e718
parent4ac5afa3b991654a38b39ad44880e74da06a02c3 (diff)
downloadmariadb-git-6a421c56cc425513901d141312bed9c744673b50.tar.gz
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
-rw-r--r--sql/partition_info.cc42
-rw-r--r--sql/partition_info.h1
-rw-r--r--sql/sql_class.h1
-rw-r--r--sql/sql_partition.cc41
-rw-r--r--sql/sql_table.cc7
-rw-r--r--sql/unireg.cc2
6 files changed, 72 insertions, 22 deletions
diff --git a/sql/partition_info.cc b/sql/partition_info.cc
index 66e0d366116..10725878d51 100644
--- a/sql/partition_info.cc
+++ b/sql/partition_info.cc
@@ -25,6 +25,48 @@
#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
diff --git a/sql/partition_info.h b/sql/partition_info.h
index 4a00f5c889f..69aef512a67 100644
--- a/sql/partition_info.h
+++ b/sql/partition_info.h
@@ -229,6 +229,7 @@ public:
}
~partition_info() {}
+ partition_info *get_clone();
/* Answers the question if subpartitioning is used for a certain table */
bool is_sub_partitioned()
{
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 3ad8f49fb76..58447d03c63 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -1206,6 +1206,7 @@ public:
*/
query_id_t first_query_id;
} binlog_evt_union;
+ partition_info *work_part_info;
THD();
~THD();
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index 18793d43016..55b67500c8f 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -4077,6 +4077,9 @@ uint prep_alter_part_table(THD *thd, TABLE *table, ALTER_INFO *alter_info,
if (table->part_info)
table->s->version= 0L;
+ if (!(thd->work_part_info= thd->lex->part_info->get_clone()))
+ DBUG_RETURN(TRUE);
+
if (alter_info->flags &
(ALTER_ADD_PARTITION | ALTER_DROP_PARTITION |
ALTER_COALESCE_PARTITION | ALTER_REORGANIZE_PARTITION |
@@ -4085,7 +4088,7 @@ uint prep_alter_part_table(THD *thd, TABLE *table, ALTER_INFO *alter_info,
ALTER_REPAIR_PARTITION | ALTER_REBUILD_PARTITION))
{
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;
if (!tab_part_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
*/
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
{
@@ -4145,17 +4148,17 @@ uint prep_alter_part_table(THD *thd, TABLE *table, ALTER_INFO *alter_info,
*fast_alter_partition, flags));
if (((alter_info->flags & ALTER_ADD_PARTITION) ||
(alter_info->flags & ALTER_REORGANIZE_PARTITION)) &&
- (thd->lex->part_info->part_type != tab_part_info->part_type) &&
- (thd->lex->part_info->part_type != NOT_A_PARTITION))
+ (thd->work_part_info->part_type != tab_part_info->part_type) &&
+ (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),
"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),
"LIST", "IN");
}
@@ -4623,8 +4626,8 @@ state of p1.
This command can be used on RANGE and LIST partitions.
*/
uint no_parts_reorged= alter_info->partition_names.elements;
- uint no_parts_new= thd->lex->part_info->partitions.elements;
- partition_info *alt_part_info= thd->lex->part_info;
+ uint no_parts_new= thd->work_part_info->partitions.elements;
+ partition_info *alt_part_info= thd->work_part_info;
uint check_total_partitions;
if (no_parts_reorged > tab_part_info->no_parts)
{
@@ -4770,7 +4773,7 @@ the generated partition syntax in a correct manner.
DBUG_ASSERT(FALSE);
}
*partition_changed= TRUE;
- thd->lex->part_info= tab_part_info;
+ thd->work_part_info= tab_part_info;
if (alter_info->flags == ALTER_ADD_PARTITION ||
alter_info->flags == ALTER_REORGANIZE_PARTITION)
{
@@ -4840,35 +4843,35 @@ the generated partition syntax in a correct manner.
*/
if (table->part_info)
{
- if (!thd->lex->part_info &&
+ if (!thd->work_part_info &&
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
using the partition handler.
*/
- if (thd->lex->part_info != table->part_info)
+ if (thd->work_part_info != table->part_info)
*partition_changed= TRUE;
if (create_info->db_type == &partition_hton)
{
if (table->part_info)
{
- thd->lex->part_info->default_engine_type=
+ thd->work_part_info->default_engine_type=
table->part_info->default_engine_type;
}
else
{
- thd->lex->part_info->default_engine_type=
+ thd->work_part_info->default_engine_type=
ha_checktype(thd, DB_TYPE_DEFAULT, FALSE, FALSE);
}
}
else
{
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;
if (check_native_partitioned(create_info, &is_native_partitioned,
part_info, thd))
@@ -4882,7 +4885,7 @@ the generated partition syntax in a correct manner.
}
}
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);
@@ -5065,7 +5068,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
lpt->deleted= 0;
lpt->pack_frm_data= NULL;
lpt->pack_frm_len= 0;
- thd->lex->part_info= part_info;
+ thd->work_part_info= part_info;
if (alter_info->flags & ALTER_OPTIMIZE_PARTITION ||
alter_info->flags & ALTER_ANALYZE_PARTITION ||
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 54fcefa3e6d..53d7441b254 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -2037,7 +2037,10 @@ bool mysql_create_table_internal(THD *thd,
DBUG_RETURN(TRUE);
}
#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 &&
(create_info->db_type->partition_flags() & HA_USE_AUTO_PARTITION))
{
@@ -2046,7 +2049,7 @@ bool mysql_create_table_internal(THD *thd,
all tables as partitioned. The handler will set up the partition info
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)
{
mem_alloc_error(sizeof(partition_info));
diff --git a/sql/unireg.cc b/sql/unireg.cc
index 2c5f4b34091..7cb79e866f9 100644
--- a/sql/unireg.cc
+++ b/sql/unireg.cc
@@ -86,7 +86,7 @@ bool mysql_create_frm(THD *thd, const char *file_name,
uchar *screen_buff;
char buff[32];
#ifdef WITH_PARTITION_STORAGE_ENGINE
- partition_info *part_info= thd->lex->part_info;
+ partition_info *part_info= thd->work_part_info;
#endif
DBUG_ENTER("mysql_create_frm");