summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authormattiasj@witty. <>2008-02-24 16:46:35 +0100
committermattiasj@witty. <>2008-02-24 16:46:35 +0100
commitd3937fd63cc599264247d2a9f21997965fa377fd (patch)
tree34aff5fa227a60756b3b78c0c2e6a322e280b686 /sql
parent28aaef3ccf122b160ab26863769e54a974a8aece (diff)
parenta6a9774849acafd54b4e625da444697ac76af2f0 (diff)
downloadmariadb-git-d3937fd63cc599264247d2a9f21997965fa377fd.tar.gz
Merge witty.:/Users/mattiasj/clones/mysql-5.1-bug31931.2
into witty.:/Users/mattiasj/clones/topush-51
Diffstat (limited to 'sql')
-rw-r--r--sql/partition_info.cc247
-rw-r--r--sql/partition_info.h2
-rw-r--r--sql/sql_partition.cc138
3 files changed, 253 insertions, 134 deletions
diff --git a/sql/partition_info.cc b/sql/partition_info.cc
index 16433497efd..6816fce7818 100644
--- a/sql/partition_info.cc
+++ b/sql/partition_info.cc
@@ -419,41 +419,167 @@ char *partition_info::has_unique_names()
/*
- Check that all partitions use the same storage engine.
- This is currently a limitation in this version.
+ Check that the partition/subpartition is setup to use the correct
+ storage engine
+ SYNOPSIS
+ check_engine_condition()
+ p_elem Partition element
+ table_engine_set Have user specified engine on table level
+ inout::engine_type Current engine used
+ inout::first Is it first partition
+ RETURN VALUE
+ TRUE Failed check
+ FALSE Ok
+ DESCRIPTION
+ Specified engine for table and partitions p0 and pn
+ Must be correct both on CREATE and ALTER commands
+ table p0 pn res (0 - OK, 1 - FAIL)
+ - - - 0
+ - - x 1
+ - x - 1
+ - x x 0
+ x - - 0
+ x - x 0
+ x x - 0
+ x x x 0
+ i.e:
+ - All subpartitions must use the same engine
+ AND it must be the same as the partition.
+ - All partitions must use the same engine
+ AND it must be the same as the table.
+ - if one does NOT specify an engine on the table level
+ then one must either NOT specify any engine on any
+ partition/subpartition OR for ALL partitions/subpartitions
+ Note:
+ When ALTER a table, the engines are already set for all levels
+ (table, all partitions and subpartitions). So if one want to
+ change the storage engine, one must specify it on the table level
+
+*/
+
+static bool check_engine_condition(partition_element *p_elem,
+ bool table_engine_set,
+ handlerton **engine_type,
+ bool *first)
+{
+ DBUG_ENTER("check_engine_condition");
+
+ DBUG_PRINT("enter", ("p_eng %u t_eng %u t_eng_set %u first %u state %u",
+ ha_legacy_type(p_elem->engine_type),
+ ha_legacy_type(*engine_type),
+ table_engine_set, *first, p_elem->part_state));
+ if (*first && !table_engine_set)
+ {
+ *engine_type= p_elem->engine_type;
+ DBUG_PRINT("info", ("setting table_engine = %u",
+ ha_legacy_type(*engine_type)));
+ }
+ *first= FALSE;
+ if ((table_engine_set &&
+ (p_elem->engine_type != (*engine_type) &&
+ p_elem->engine_type)) ||
+ (!table_engine_set &&
+ p_elem->engine_type != (*engine_type)))
+ {
+ DBUG_RETURN(TRUE);
+ }
+ else
+ {
+ DBUG_RETURN(FALSE);
+ }
+}
+
+/*
+ Check engine mix that it is correct
+ Current limitation is that all partitions and subpartitions
+ must use the same storage engine.
SYNOPSIS
check_engine_mix()
- engine_array An array of engine identifiers
- no_parts Total number of partitions
-
+ inout::engine_type Current engine used
+ table_engine_set Have user specified engine on table level
RETURN VALUE
- TRUE Error, mixed engines
- FALSE Ok, no mixed engines
+ TRUE Error, mixed engines
+ FALSE Ok, no mixed engines
DESCRIPTION
Current check verifies only that all handlers are the same.
Later this check will be more sophisticated.
+ (specified partition handler ) specified table handler
+ (NDB, NDB) NDB OK
+ (MYISAM, MYISAM) - OK
+ (MYISAM, -) - NOT OK
+ (MYISAM, -) MYISAM OK
+ (- , MYISAM) - NOT OK
+ (- , -) MYISAM OK
+ (-,-) - OK
+ (NDB, MYISAM) * NOT OK
*/
-bool partition_info::check_engine_mix(handlerton **engine_array, uint no_parts)
+bool partition_info::check_engine_mix(handlerton *engine_type,
+ bool table_engine_set)
{
- uint i= 0;
+ handlerton *old_engine_type= engine_type;
+ bool first= TRUE;
+ uint no_parts= partitions.elements;
DBUG_ENTER("partition_info::check_engine_mix");
-
- do
+ DBUG_PRINT("info", ("in: engine_type = %u, table_engine_set = %u",
+ ha_legacy_type(engine_type),
+ table_engine_set));
+ if (no_parts)
{
- if (engine_array[i] != engine_array[0])
+ List_iterator<partition_element> part_it(partitions);
+ uint i= 0;
+ do
{
- my_error(ER_MIX_HANDLER_ERROR, MYF(0));
- DBUG_RETURN(TRUE);
- }
- } while (++i < no_parts);
- if (engine_array[0]->flags & HTON_NO_PARTITION)
+ partition_element *part_elem= part_it++;
+ DBUG_PRINT("info", ("part = %d engine = %d table_engine_set %u",
+ i, ha_legacy_type(part_elem->engine_type),
+ table_engine_set));
+ if (is_sub_partitioned() &&
+ part_elem->subpartitions.elements)
+ {
+ uint no_subparts= part_elem->subpartitions.elements;
+ uint j= 0;
+ List_iterator<partition_element> sub_it(part_elem->subpartitions);
+ do
+ {
+ partition_element *sub_elem= sub_it++;
+ DBUG_PRINT("info", ("sub = %d engine = %u table_engie_set %u",
+ j, ha_legacy_type(sub_elem->engine_type),
+ table_engine_set));
+ if (check_engine_condition(sub_elem, table_engine_set,
+ &engine_type, &first))
+ goto error;
+ } while (++j < no_subparts);
+ /* ensure that the partition also has correct engine */
+ if (check_engine_condition(part_elem, table_engine_set,
+ &engine_type, &first))
+ goto error;
+ }
+ else if (check_engine_condition(part_elem, table_engine_set,
+ &engine_type, &first))
+ goto error;
+ } while (++i < no_parts);
+ }
+ DBUG_PRINT("info", ("engine_type = %u",
+ ha_legacy_type(engine_type)));
+ if (!engine_type)
+ engine_type= old_engine_type;
+ if (engine_type->flags & HTON_NO_PARTITION)
{
my_error(ER_PARTITION_MERGE_ERROR, MYF(0));
DBUG_RETURN(TRUE);
}
+ DBUG_PRINT("info", ("out: engine_type = %u",
+ ha_legacy_type(engine_type)));
+ DBUG_ASSERT(engine_type != partition_hton);
DBUG_RETURN(FALSE);
+error:
+ /*
+ Mixed engines not yet supported but when supported it will need
+ the partition handler
+ */
+ DBUG_RETURN(TRUE);
}
@@ -726,12 +852,12 @@ bool partition_info::check_partition_info(THD *thd, handlerton **eng_type,
handler *file, HA_CREATE_INFO *info,
bool check_partition_function)
{
- handlerton **engine_array= NULL;
- uint part_count= 0;
+ handlerton *table_engine= default_engine_type;
uint i, tot_partitions;
- bool result= TRUE;
+ bool result= TRUE, table_engine_set;
char *same_name;
DBUG_ENTER("partition_info::check_partition_info");
+ DBUG_ASSERT(default_engine_type != partition_hton);
if (check_partition_function)
{
@@ -777,23 +903,49 @@ bool partition_info::check_partition_info(THD *thd, handlerton **eng_type,
my_error(ER_TOO_MANY_PARTITIONS_ERROR, MYF(0));
goto end;
}
+ /*
+ if NOT specified ENGINE = <engine>:
+ If Create, always use create_info->db_type
+ else, use previous tables db_type
+ either ALL or NONE partition should be set to
+ default_engine_type when not table_engine_set
+ Note: after a table is created its storage engines for
+ the table and all partitions/subpartitions are set.
+ So when ALTER it is already set on table level
+ */
+ if (thd->lex->create_info.used_fields & HA_CREATE_USED_ENGINE)
+ {
+ table_engine_set= TRUE;
+ table_engine= thd->lex->create_info.db_type;
+ }
+ else
+ {
+ table_engine_set= FALSE;
+ if (thd->lex->sql_command != SQLCOM_CREATE_TABLE)
+ {
+ table_engine_set= TRUE;
+ DBUG_ASSERT(table_engine && table_engine != partition_hton);
+ }
+ }
+
if ((same_name= has_unique_names()))
{
my_error(ER_SAME_NAME_PARTITION, MYF(0), same_name);
goto end;
}
- engine_array= (handlerton**)my_malloc(tot_partitions * sizeof(handlerton *),
- MYF(MY_WME));
- if (unlikely(!engine_array))
- goto end;
i= 0;
{
List_iterator<partition_element> part_it(partitions);
+ uint no_parts_not_set= 0;
+ uint prev_no_subparts_not_set= no_subparts + 1;
do
{
partition_element *part_elem= part_it++;
if (part_elem->engine_type == NULL)
+ {
+ no_parts_not_set++;
part_elem->engine_type= default_engine_type;
+ }
#ifdef HAVE_READLINK
if (!my_use_symdir || (thd->variables.sql_mode & MODE_NO_DIR_IN_CREATE))
#endif
@@ -814,13 +966,13 @@ bool partition_info::check_partition_info(THD *thd, handlerton **eng_type,
my_error(ER_WRONG_PARTITION_NAME, MYF(0));
goto end;
}
- DBUG_PRINT("info", ("engine = %d",
- ha_legacy_type(part_elem->engine_type)));
- engine_array[part_count++]= part_elem->engine_type;
+ DBUG_PRINT("info", ("part = %d engine = %d",
+ i, ha_legacy_type(part_elem->engine_type)));
}
else
{
uint j= 0;
+ uint no_subparts_not_set= 0;
List_iterator<partition_element> sub_it(part_elem->subpartitions);
do
{
@@ -832,19 +984,49 @@ bool partition_info::check_partition_info(THD *thd, handlerton **eng_type,
goto end;
}
if (sub_elem->engine_type == NULL)
+ {
sub_elem->engine_type= default_engine_type;
- DBUG_PRINT("info", ("engine = %u",
- ha_legacy_type(sub_elem->engine_type)));
- engine_array[part_count++]= sub_elem->engine_type;
+ no_subparts_not_set++;
+ }
+ DBUG_PRINT("info", ("part = %d sub = %d engine = %u",
+ i, j, ha_legacy_type(sub_elem->engine_type)));
} while (++j < no_subparts);
+ if (prev_no_subparts_not_set == (no_subparts + 1))
+ prev_no_subparts_not_set= no_subparts_not_set;
+ if (!table_engine_set &&
+ prev_no_subparts_not_set == no_subparts_not_set &&
+ no_subparts_not_set != 0 &&
+ no_subparts_not_set != no_subparts)
+ {
+ DBUG_PRINT("info", ("no_subparts_not_set = %u no_subparts = %u",
+ no_subparts_not_set, no_subparts));
+ my_error(ER_MIX_HANDLER_ERROR, MYF(0));
+ goto end;
+ }
}
} while (++i < no_parts);
+ if (!table_engine_set &&
+ no_parts_not_set != 0 &&
+ no_parts_not_set != no_parts)
+ {
+ DBUG_PRINT("info", ("no_parts_not_set = %u no_parts = %u",
+ no_parts_not_set, no_subparts));
+ my_error(ER_MIX_HANDLER_ERROR, MYF(0));
+ goto end;
+ }
}
- if (unlikely(partition_info::check_engine_mix(engine_array, part_count)))
+ if (unlikely(check_engine_mix(table_engine, table_engine_set)))
+ {
+ my_error(ER_MIX_HANDLER_ERROR, MYF(0));
goto end;
+ }
+ if (table_engine == partition_hton)
+ DBUG_PRINT("info", ("Table engine set to partition_hton"));
+ DBUG_ASSERT(default_engine_type == table_engine);
if (eng_type)
- *eng_type= (handlerton*)engine_array[0];
+ *eng_type= table_engine;
+
/*
We need to check all constant expressions that they are of the correct
@@ -860,7 +1042,6 @@ bool partition_info::check_partition_info(THD *thd, handlerton **eng_type,
}
result= FALSE;
end:
- my_free((char*)engine_array,MYF(MY_ALLOW_ZERO_PTR));
DBUG_RETURN(result);
}
diff --git a/sql/partition_info.h b/sql/partition_info.h
index b7d13e188f3..b38e572d3aa 100644
--- a/sql/partition_info.h
+++ b/sql/partition_info.h
@@ -269,7 +269,7 @@ public:
bool set_up_defaults_for_partitioning(handler *file, HA_CREATE_INFO *info,
uint start_no);
char *has_unique_names();
- static bool check_engine_mix(handlerton **engine_array, uint no_parts);
+ bool check_engine_mix(handlerton *engine_type, bool default_engine);
bool check_range_constants();
bool check_list_constants();
bool check_partition_info(THD *thd, handlerton **eng_type,
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index 8a22193863f..7929cae65da 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -3863,6 +3863,8 @@ bool mysql_unpack_partition(THD *thd,
if (!part_info->default_engine_type)
part_info->default_engine_type= default_db_type;
DBUG_ASSERT(part_info->default_engine_type == default_db_type);
+ DBUG_ASSERT(part_info->default_engine_type->db_type != DB_TYPE_UNKNOWN);
+ DBUG_ASSERT(part_info->default_engine_type != partition_hton);
{
/*
@@ -3997,56 +3999,6 @@ static int fast_end_partition(THD *thd, ulonglong copied,
/*
- Check engine mix that it is correct
- SYNOPSIS
- check_engine_condition()
- p_elem Partition element
- default_engine Have user specified engine on table level
- inout::engine_type Current engine used
- inout::first Is it first partition
- RETURN VALUE
- TRUE Failed check
- FALSE Ok
- DESCRIPTION
- (specified partition handler ) specified table handler
- (NDB, NDB) NDB OK
- (MYISAM, MYISAM) - OK
- (MYISAM, -) - NOT OK
- (MYISAM, -) MYISAM OK
- (- , MYISAM) - NOT OK
- (- , -) MYISAM OK
- (-,-) - OK
- (NDB, MYISAM) * NOT OK
-*/
-
-static bool check_engine_condition(partition_element *p_elem,
- bool default_engine,
- handlerton **engine_type,
- bool *first)
-{
- DBUG_ENTER("check_engine_condition");
-
- DBUG_PRINT("enter", ("def_eng = %u, first = %u", default_engine, *first));
- if (*first && default_engine)
- {
- *engine_type= p_elem->engine_type;
- }
- *first= FALSE;
- if ((!default_engine &&
- (p_elem->engine_type != (*engine_type) &&
- p_elem->engine_type)) ||
- (default_engine &&
- p_elem->engine_type != (*engine_type)))
- {
- DBUG_RETURN(TRUE);
- }
- else
- {
- DBUG_RETURN(FALSE);
- }
-}
-
-/*
We need to check if engine used by all partitions can handle
partitioning natively.
@@ -4070,52 +4022,30 @@ static bool check_engine_condition(partition_element *p_elem,
static bool check_native_partitioned(HA_CREATE_INFO *create_info,bool *ret_val,
partition_info *part_info, THD *thd)
{
- List_iterator<partition_element> part_it(part_info->partitions);
- bool first= TRUE;
- bool default_engine;
- handlerton *engine_type= create_info->db_type;
+ bool table_engine_set;
+ handlerton *engine_type= part_info->default_engine_type;
handlerton *old_engine_type= engine_type;
- uint i= 0;
- uint no_parts= part_info->partitions.elements;
DBUG_ENTER("check_native_partitioned");
- default_engine= (create_info->used_fields & HA_CREATE_USED_ENGINE) ?
- FALSE : TRUE;
- DBUG_PRINT("info", ("engine_type = %u, default = %u",
- ha_legacy_type(engine_type),
- default_engine));
- if (no_parts)
+ if (create_info->used_fields & HA_CREATE_USED_ENGINE)
{
- do
+ table_engine_set= TRUE;
+ engine_type= create_info->db_type;
+ }
+ else
+ {
+ table_engine_set= FALSE;
+ if (thd->lex->sql_command != SQLCOM_CREATE_TABLE)
{
- partition_element *part_elem= part_it++;
- if (part_info->is_sub_partitioned() &&
- part_elem->subpartitions.elements)
- {
- uint no_subparts= part_elem->subpartitions.elements;
- uint j= 0;
- List_iterator<partition_element> sub_it(part_elem->subpartitions);
- do
- {
- partition_element *sub_elem= sub_it++;
- if (check_engine_condition(sub_elem, default_engine,
- &engine_type, &first))
- goto error;
- } while (++j < no_subparts);
- /*
- In case of subpartitioning and defaults we allow that only
- subparts have specified engines, as long as the parts haven't
- specified the wrong engine it's ok.
- */
- if (check_engine_condition(part_elem, FALSE,
- &engine_type, &first))
- goto error;
- }
- else if (check_engine_condition(part_elem, default_engine,
- &engine_type, &first))
- goto error;
- } while (++i < no_parts);
+ table_engine_set= TRUE;
+ DBUG_ASSERT(engine_type && engine_type != partition_hton);
+ }
}
+ DBUG_PRINT("info", ("engine_type = %u, table_engine_set = %u",
+ ha_legacy_type(engine_type),
+ table_engine_set));
+ if (part_info->check_engine_mix(engine_type, table_engine_set))
+ goto error;
/*
All engines are of the same type. Check if this engine supports
@@ -4212,7 +4142,7 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info,
my_error(ER_PARTITION_MGMT_ON_NONPARTITIONED, MYF(0));
DBUG_RETURN(TRUE);
}
- if (alter_info->flags == ALTER_TABLE_REORG)
+ if (alter_info->flags & ALTER_TABLE_REORG)
{
uint new_part_no, curr_part_no;
if (tab_part_info->part_type != HASH_PARTITION ||
@@ -4543,7 +4473,7 @@ that are reorganised.
tab_part_info->is_auto_partitioned= FALSE;
}
}
- else if (alter_info->flags == ALTER_DROP_PARTITION)
+ else if (alter_info->flags & ALTER_DROP_PARTITION)
{
/*
Drop a partition from a range partition and list partitioning is
@@ -4747,7 +4677,7 @@ state of p1.
tab_part_info->is_auto_partitioned= FALSE;
}
}
- else if (alter_info->flags == ALTER_REORGANIZE_PARTITION)
+ else if (alter_info->flags & ALTER_REORGANIZE_PARTITION)
{
/*
Reorganise partitions takes a number of partitions that are next
@@ -4928,8 +4858,8 @@ the generated partition syntax in a correct manner.
}
*partition_changed= TRUE;
thd->work_part_info= tab_part_info;
- if (alter_info->flags == ALTER_ADD_PARTITION ||
- alter_info->flags == ALTER_REORGANIZE_PARTITION)
+ if (alter_info->flags & ALTER_ADD_PARTITION ||
+ alter_info->flags & ALTER_REORGANIZE_PARTITION)
{
if (tab_part_info->use_default_subpartitions &&
!alt_part_info->use_default_subpartitions)
@@ -5056,13 +4986,21 @@ the generated partition syntax in a correct manner.
DBUG_PRINT("info", ("partition changed"));
*partition_changed= TRUE;
}
- if (create_info->db_type == partition_hton)
+ /*
+ Set up partition default_engine_type either from the create_info
+ or from the previus table
+ */
+ if (create_info->used_fields & HA_CREATE_USED_ENGINE)
+ part_info->default_engine_type= create_info->db_type;
+ else
{
- if (!part_info->default_engine_type)
+ if (table->part_info)
part_info->default_engine_type= table->part_info->default_engine_type;
+ else
+ part_info->default_engine_type= create_info->db_type;
}
- else
- part_info->default_engine_type= create_info->db_type;
+ DBUG_ASSERT(part_info->default_engine_type &&
+ part_info->default_engine_type != partition_hton);
if (check_native_partitioned(create_info, &is_native_partitioned,
part_info, thd))
{
@@ -6160,7 +6098,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
goto err;
}
}
- else if (alter_info->flags == ALTER_DROP_PARTITION)
+ else if (alter_info->flags & ALTER_DROP_PARTITION)
{
/*
Now after all checks and setting state on dropped partitions we can