mirror of
https://github.com/MariaDB/server.git
synced 2026-05-02 13:15:32 +02:00
Merge witty.:/Users/mattiasj/clones/mysql-5.1-bug31931.2
into witty.:/Users/mattiasj/clones/topush-51 mysql-test/r/partition.result: Auto merged mysql-test/suite/ndb/r/ndb_partition_key.result: Auto merged mysql-test/suite/ndb/t/ndb_partition_key.test: Auto merged mysql-test/t/partition.test: Auto merged sql/sql_partition.cc: Auto merged sql/partition_info.cc: SCCS merged
This commit is contained in:
commit
1864caeafc
14 changed files with 551 additions and 5694 deletions
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue