mirror of
https://github.com/MariaDB/server.git
synced 2026-01-06 05:22:24 +03:00
WL #2747: Fix such that backup and restore works for user defined
partitioned tables in NDB include/my_sys.h: Move packfrm and unpackfrm to mysys mysql-test/r/ndb_restore.result: New test cases mysql-test/t/ndb_restore.test: New test cases mysys/my_compress.c: Moved packfrm and unpackfrm to mysys sql/ha_ndbcluster.cc: Set value of partition function in hidden field for user defined partitioning in NDB to handle restore and later on-line reorganize of partitions To save space value of those functions are limited to 32 bits sql/ha_partition.cc: Use new get_partition_id interface sql/handler.h: Use new get_partition_id interface sql/mysql_priv.h: Moved to mysys sql/mysqld.cc: Minor sql/opt_range.cc: New get_partition_id interface sql/sql_partition.cc: New get_partition_id interface Fix error checks of specification of engines in ALTER TABLE Moved packfrm and unpackfrm to mysys sql/sql_table.cc: Fixed debug printouts storage/ndb/include/kernel/ndb_limits.h: New constant storage/ndb/include/kernel/signaldata/DictTabInfo.hpp: New table description item storage/ndb/include/ndb_version.h.in: New version specific constant storage/ndb/include/ndbapi/NdbDictionary.hpp: New item in table descriptions storage/ndb/src/common/debugger/signaldata/DictTabInfo.cpp: New item in table descriptions storage/ndb/src/kernel/blocks/backup/Backup.cpp: Write fragment id in backup's log entry storage/ndb/src/kernel/blocks/backup/BackupFormat.hpp: Write fragment id in backup's log entry storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp: New item in table description storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp: New item in table description storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp: Moved constant storage/ndb/src/ndbapi/NdbDictionary.cpp: New item in table description storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp: New item in table description storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp: New item in table description storage/ndb/tools/Makefile.am: Compress library needed for ndb_restore storage/ndb/tools/restore/Restore.cpp: Handle fragment id and also handle backups from older versions storage/ndb/tools/restore/Restore.hpp: Use fragment id storage/ndb/tools/restore/consumer.hpp: Use fragment id storage/ndb/tools/restore/consumer_printer.cpp: Use fragment id storage/ndb/tools/restore/consumer_printer.hpp: Use fragment id storage/ndb/tools/restore/consumer_restore.cpp: Code to map node groups if new cluster has different set of node groups from original cluster Very simple search and replace parser of partition syntax in frm file Fix settings of partition id properly using fragment id and hidden field in tables storage/ndb/tools/restore/consumer_restore.hpp: Changed function headers and new one for mapping node groups storage/ndb/tools/restore/consumer_restorem.cpp: Use fragment id storage/ndb/tools/restore/restore_main.cpp: New parameter to set node group map, parser for this parameter
This commit is contained in:
@@ -63,33 +63,47 @@ static const char *comma_str= ",";
|
||||
static char buff[22];
|
||||
|
||||
int get_partition_id_list(partition_info *part_info,
|
||||
uint32 *part_id);
|
||||
uint32 *part_id,
|
||||
longlong *func_value);
|
||||
int get_partition_id_range(partition_info *part_info,
|
||||
uint32 *part_id);
|
||||
uint32 *part_id,
|
||||
longlong *func_value);
|
||||
int get_partition_id_hash_nosub(partition_info *part_info,
|
||||
uint32 *part_id);
|
||||
uint32 *part_id,
|
||||
longlong *func_value);
|
||||
int get_partition_id_key_nosub(partition_info *part_info,
|
||||
uint32 *part_id);
|
||||
uint32 *part_id,
|
||||
longlong *func_value);
|
||||
int get_partition_id_linear_hash_nosub(partition_info *part_info,
|
||||
uint32 *part_id);
|
||||
uint32 *part_id,
|
||||
longlong *func_value);
|
||||
int get_partition_id_linear_key_nosub(partition_info *part_info,
|
||||
uint32 *part_id);
|
||||
uint32 *part_id,
|
||||
longlong *func_value);
|
||||
int get_partition_id_range_sub_hash(partition_info *part_info,
|
||||
uint32 *part_id);
|
||||
uint32 *part_id,
|
||||
longlong *func_value);
|
||||
int get_partition_id_range_sub_key(partition_info *part_info,
|
||||
uint32 *part_id);
|
||||
uint32 *part_id,
|
||||
longlong *func_value);
|
||||
int get_partition_id_range_sub_linear_hash(partition_info *part_info,
|
||||
uint32 *part_id);
|
||||
uint32 *part_id,
|
||||
longlong *func_value);
|
||||
int get_partition_id_range_sub_linear_key(partition_info *part_info,
|
||||
uint32 *part_id);
|
||||
uint32 *part_id,
|
||||
longlong *func_value);
|
||||
int get_partition_id_list_sub_hash(partition_info *part_info,
|
||||
uint32 *part_id);
|
||||
uint32 *part_id,
|
||||
longlong *func_value);
|
||||
int get_partition_id_list_sub_key(partition_info *part_info,
|
||||
uint32 *part_id);
|
||||
uint32 *part_id,
|
||||
longlong *func_value);
|
||||
int get_partition_id_list_sub_linear_hash(partition_info *part_info,
|
||||
uint32 *part_id);
|
||||
uint32 *part_id,
|
||||
longlong *func_value);
|
||||
int get_partition_id_list_sub_linear_key(partition_info *part_info,
|
||||
uint32 *part_id);
|
||||
uint32 *part_id,
|
||||
longlong *func_value);
|
||||
uint32 get_partition_id_hash_sub(partition_info *part_info);
|
||||
uint32 get_partition_id_key_sub(partition_info *part_info);
|
||||
uint32 get_partition_id_linear_hash_sub(partition_info *part_info);
|
||||
@@ -327,15 +341,18 @@ bool check_reorganise_list(partition_info *new_part_info,
|
||||
|
||||
int get_parts_for_update(const byte *old_data, byte *new_data,
|
||||
const byte *rec0, partition_info *part_info,
|
||||
uint32 *old_part_id, uint32 *new_part_id)
|
||||
uint32 *old_part_id, uint32 *new_part_id,
|
||||
longlong *new_func_value)
|
||||
{
|
||||
Field **part_field_array= part_info->full_part_field_array;
|
||||
int error;
|
||||
longlong old_func_value;
|
||||
DBUG_ENTER("get_parts_for_update");
|
||||
|
||||
DBUG_ASSERT(new_data == rec0);
|
||||
set_field_ptr(part_field_array, old_data, rec0);
|
||||
error= part_info->get_partition_id(part_info, old_part_id);
|
||||
error= part_info->get_partition_id(part_info, old_part_id,
|
||||
&old_func_value);
|
||||
set_field_ptr(part_field_array, rec0, old_data);
|
||||
if (unlikely(error)) // Should never happen
|
||||
{
|
||||
@@ -346,7 +363,9 @@ int get_parts_for_update(const byte *old_data, byte *new_data,
|
||||
if (new_data == rec0)
|
||||
#endif
|
||||
{
|
||||
if (unlikely(error= part_info->get_partition_id(part_info,new_part_id)))
|
||||
if (unlikely(error= part_info->get_partition_id(part_info,
|
||||
new_part_id,
|
||||
new_func_value)))
|
||||
{
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
@@ -360,7 +379,8 @@ int get_parts_for_update(const byte *old_data, byte *new_data,
|
||||
condition is false in one test situation before pushing the code.
|
||||
*/
|
||||
set_field_ptr(part_field_array, new_data, rec0);
|
||||
error= part_info->get_partition_id(part_info, new_part_id);
|
||||
error= part_info->get_partition_id(part_info, new_part_id,
|
||||
new_func_value);
|
||||
set_field_ptr(part_field_array, rec0, new_data);
|
||||
if (unlikely(error))
|
||||
{
|
||||
@@ -397,11 +417,13 @@ int get_part_for_delete(const byte *buf, const byte *rec0,
|
||||
partition_info *part_info, uint32 *part_id)
|
||||
{
|
||||
int error;
|
||||
longlong func_value;
|
||||
DBUG_ENTER("get_part_for_delete");
|
||||
|
||||
if (likely(buf == rec0))
|
||||
{
|
||||
if (unlikely((error= part_info->get_partition_id(part_info, part_id))))
|
||||
if (unlikely((error= part_info->get_partition_id(part_info, part_id,
|
||||
&func_value))))
|
||||
{
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
@@ -411,7 +433,7 @@ int get_part_for_delete(const byte *buf, const byte *rec0,
|
||||
{
|
||||
Field **part_field_array= part_info->full_part_field_array;
|
||||
set_field_ptr(part_field_array, buf, rec0);
|
||||
error= part_info->get_partition_id(part_info, part_id);
|
||||
error= part_info->get_partition_id(part_info, part_id, &func_value);
|
||||
set_field_ptr(part_field_array, rec0, buf);
|
||||
if (unlikely(error))
|
||||
{
|
||||
@@ -1892,7 +1914,7 @@ static uint32 get_part_id_from_linear_hash(longlong hash_value, uint mask,
|
||||
if (part_id >= no_parts)
|
||||
{
|
||||
uint new_mask= ((mask + 1) >> 1) - 1;
|
||||
part_id= hash_value & new_mask;
|
||||
part_id= (uint32)(hash_value & new_mask);
|
||||
}
|
||||
return part_id;
|
||||
}
|
||||
@@ -2658,6 +2680,7 @@ static uint32 get_part_id_for_sub(uint32 loc_part_id, uint32 sub_part_id,
|
||||
get_part_id_hash()
|
||||
no_parts Number of hash partitions
|
||||
part_expr Item tree of hash function
|
||||
out:func_value Value of hash function
|
||||
|
||||
RETURN VALUE
|
||||
Calculated partition id
|
||||
@@ -2665,10 +2688,12 @@ static uint32 get_part_id_for_sub(uint32 loc_part_id, uint32 sub_part_id,
|
||||
|
||||
inline
|
||||
static uint32 get_part_id_hash(uint no_parts,
|
||||
Item *part_expr)
|
||||
Item *part_expr,
|
||||
longlong *func_value)
|
||||
{
|
||||
DBUG_ENTER("get_part_id_hash");
|
||||
longlong int_hash_id= part_expr->val_int() % no_parts;
|
||||
*func_value= part_expr->val_int();
|
||||
longlong int_hash_id= *func_value % no_parts;
|
||||
DBUG_RETURN(int_hash_id < 0 ? -int_hash_id : int_hash_id);
|
||||
}
|
||||
|
||||
@@ -2682,6 +2707,7 @@ static uint32 get_part_id_hash(uint no_parts,
|
||||
desired information is given
|
||||
no_parts Number of hash partitions
|
||||
part_expr Item tree of hash function
|
||||
out:func_value Value of hash function
|
||||
|
||||
RETURN VALUE
|
||||
Calculated partition id
|
||||
@@ -2690,11 +2716,13 @@ static uint32 get_part_id_hash(uint no_parts,
|
||||
inline
|
||||
static uint32 get_part_id_linear_hash(partition_info *part_info,
|
||||
uint no_parts,
|
||||
Item *part_expr)
|
||||
Item *part_expr,
|
||||
longlong *func_value)
|
||||
{
|
||||
DBUG_ENTER("get_part_id_linear_hash");
|
||||
|
||||
DBUG_RETURN(get_part_id_from_linear_hash(part_expr->val_int(),
|
||||
*func_value= part_expr->val_int();
|
||||
DBUG_RETURN(get_part_id_from_linear_hash(*func_value,
|
||||
part_info->linear_hash_mask,
|
||||
no_parts));
|
||||
}
|
||||
@@ -2714,11 +2742,12 @@ static uint32 get_part_id_linear_hash(partition_info *part_info,
|
||||
|
||||
inline
|
||||
static uint32 get_part_id_key(Field **field_array,
|
||||
uint no_parts)
|
||||
uint no_parts,
|
||||
longlong *func_value)
|
||||
{
|
||||
DBUG_ENTER("get_part_id_key");
|
||||
|
||||
DBUG_RETURN(calculate_key_value(field_array) % no_parts);
|
||||
*func_value= calculate_key_value(field_array);
|
||||
DBUG_RETURN(*func_value % no_parts);
|
||||
}
|
||||
|
||||
|
||||
@@ -2739,11 +2768,13 @@ static uint32 get_part_id_key(Field **field_array,
|
||||
inline
|
||||
static uint32 get_part_id_linear_key(partition_info *part_info,
|
||||
Field **field_array,
|
||||
uint no_parts)
|
||||
uint no_parts,
|
||||
longlong *func_value)
|
||||
{
|
||||
DBUG_ENTER("get_partition_id_linear_key");
|
||||
|
||||
DBUG_RETURN(get_part_id_from_linear_hash(calculate_key_value(field_array),
|
||||
*func_value= calculate_key_value(field_array);
|
||||
DBUG_RETURN(get_part_id_from_linear_hash(*func_value,
|
||||
part_info->linear_hash_mask,
|
||||
no_parts));
|
||||
}
|
||||
@@ -2820,7 +2851,8 @@ static uint32 get_part_id_linear_key(partition_info *part_info,
|
||||
|
||||
|
||||
int get_partition_id_list(partition_info *part_info,
|
||||
uint32 *part_id)
|
||||
uint32 *part_id,
|
||||
longlong *func_value)
|
||||
{
|
||||
LIST_PART_ENTRY *list_array= part_info->list_array;
|
||||
int list_index;
|
||||
@@ -2830,6 +2862,7 @@ int get_partition_id_list(partition_info *part_info,
|
||||
longlong part_func_value= part_info->part_expr->val_int();
|
||||
DBUG_ENTER("get_partition_id_list");
|
||||
|
||||
*func_value= part_func_value;
|
||||
while (max_list_index >= min_list_index)
|
||||
{
|
||||
list_index= (max_list_index + min_list_index) >> 1;
|
||||
@@ -2928,7 +2961,8 @@ notfound:
|
||||
|
||||
|
||||
int get_partition_id_range(partition_info *part_info,
|
||||
uint32 *part_id)
|
||||
uint32 *part_id,
|
||||
longlong *func_value)
|
||||
{
|
||||
longlong *range_array= part_info->range_int_array;
|
||||
uint max_partition= part_info->no_parts - 1;
|
||||
@@ -2951,6 +2985,7 @@ int get_partition_id_range(partition_info *part_info,
|
||||
if (loc_part_id != max_partition)
|
||||
loc_part_id++;
|
||||
*part_id= (uint32)loc_part_id;
|
||||
*func_value= part_func_value;
|
||||
if (loc_part_id == max_partition)
|
||||
if (range_array[loc_part_id] != LONGLONG_MAX)
|
||||
if (part_func_value >= range_array[loc_part_id])
|
||||
@@ -3042,192 +3077,229 @@ uint32 get_partition_id_range_for_endpoint(partition_info *part_info,
|
||||
|
||||
|
||||
int get_partition_id_hash_nosub(partition_info *part_info,
|
||||
uint32 *part_id)
|
||||
uint32 *part_id,
|
||||
longlong *func_value)
|
||||
{
|
||||
*part_id= get_part_id_hash(part_info->no_parts, part_info->part_expr);
|
||||
*part_id= get_part_id_hash(part_info->no_parts, part_info->part_expr,
|
||||
func_value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int get_partition_id_linear_hash_nosub(partition_info *part_info,
|
||||
uint32 *part_id)
|
||||
uint32 *part_id,
|
||||
longlong *func_value)
|
||||
{
|
||||
*part_id= get_part_id_linear_hash(part_info, part_info->no_parts,
|
||||
part_info->part_expr);
|
||||
part_info->part_expr, func_value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int get_partition_id_key_nosub(partition_info *part_info,
|
||||
uint32 *part_id)
|
||||
uint32 *part_id,
|
||||
longlong *func_value)
|
||||
{
|
||||
*part_id= get_part_id_key(part_info->part_field_array, part_info->no_parts);
|
||||
*part_id= get_part_id_key(part_info->part_field_array,
|
||||
part_info->no_parts, func_value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int get_partition_id_linear_key_nosub(partition_info *part_info,
|
||||
uint32 *part_id)
|
||||
uint32 *part_id,
|
||||
longlong *func_value)
|
||||
{
|
||||
*part_id= get_part_id_linear_key(part_info,
|
||||
part_info->part_field_array,
|
||||
part_info->no_parts);
|
||||
part_info->no_parts, func_value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int get_partition_id_range_sub_hash(partition_info *part_info,
|
||||
uint32 *part_id)
|
||||
uint32 *part_id,
|
||||
longlong *func_value)
|
||||
{
|
||||
uint32 loc_part_id, sub_part_id;
|
||||
uint no_subparts;
|
||||
longlong local_func_value;
|
||||
int error;
|
||||
DBUG_ENTER("get_partition_id_range_sub_hash");
|
||||
|
||||
if (unlikely((error= get_partition_id_range(part_info, &loc_part_id))))
|
||||
if (unlikely((error= get_partition_id_range(part_info, &loc_part_id,
|
||||
func_value))))
|
||||
{
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
no_subparts= part_info->no_subparts;
|
||||
sub_part_id= get_part_id_hash(no_subparts, part_info->subpart_expr);
|
||||
sub_part_id= get_part_id_hash(no_subparts, part_info->subpart_expr,
|
||||
&local_func_value);
|
||||
*part_id= get_part_id_for_sub(loc_part_id, sub_part_id, no_subparts);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
int get_partition_id_range_sub_linear_hash(partition_info *part_info,
|
||||
uint32 *part_id)
|
||||
uint32 *part_id,
|
||||
longlong *func_value)
|
||||
{
|
||||
uint32 loc_part_id, sub_part_id;
|
||||
uint no_subparts;
|
||||
longlong local_func_value;
|
||||
int error;
|
||||
DBUG_ENTER("get_partition_id_range_sub_linear_hash");
|
||||
|
||||
if (unlikely((error= get_partition_id_range(part_info, &loc_part_id))))
|
||||
if (unlikely((error= get_partition_id_range(part_info, &loc_part_id,
|
||||
func_value))))
|
||||
{
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
no_subparts= part_info->no_subparts;
|
||||
sub_part_id= get_part_id_linear_hash(part_info, no_subparts,
|
||||
part_info->subpart_expr);
|
||||
part_info->subpart_expr,
|
||||
&local_func_value);
|
||||
*part_id= get_part_id_for_sub(loc_part_id, sub_part_id, no_subparts);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
int get_partition_id_range_sub_key(partition_info *part_info,
|
||||
uint32 *part_id)
|
||||
uint32 *part_id,
|
||||
longlong *func_value)
|
||||
{
|
||||
uint32 loc_part_id, sub_part_id;
|
||||
uint no_subparts;
|
||||
longlong local_func_value;
|
||||
int error;
|
||||
DBUG_ENTER("get_partition_id_range_sub_key");
|
||||
|
||||
if (unlikely((error= get_partition_id_range(part_info, &loc_part_id))))
|
||||
if (unlikely((error= get_partition_id_range(part_info, &loc_part_id,
|
||||
func_value))))
|
||||
{
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
no_subparts= part_info->no_subparts;
|
||||
sub_part_id= get_part_id_key(part_info->subpart_field_array, no_subparts);
|
||||
sub_part_id= get_part_id_key(part_info->subpart_field_array,
|
||||
no_subparts, &local_func_value);
|
||||
*part_id= get_part_id_for_sub(loc_part_id, sub_part_id, no_subparts);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
int get_partition_id_range_sub_linear_key(partition_info *part_info,
|
||||
uint32 *part_id)
|
||||
uint32 *part_id,
|
||||
longlong *func_value)
|
||||
{
|
||||
uint32 loc_part_id, sub_part_id;
|
||||
uint no_subparts;
|
||||
longlong local_func_value;
|
||||
int error;
|
||||
DBUG_ENTER("get_partition_id_range_sub_linear_key");
|
||||
|
||||
if (unlikely((error= get_partition_id_range(part_info, &loc_part_id))))
|
||||
if (unlikely((error= get_partition_id_range(part_info, &loc_part_id,
|
||||
func_value))))
|
||||
{
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
no_subparts= part_info->no_subparts;
|
||||
sub_part_id= get_part_id_linear_key(part_info,
|
||||
part_info->subpart_field_array,
|
||||
no_subparts);
|
||||
no_subparts, &local_func_value);
|
||||
*part_id= get_part_id_for_sub(loc_part_id, sub_part_id, no_subparts);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
int get_partition_id_list_sub_hash(partition_info *part_info,
|
||||
uint32 *part_id)
|
||||
uint32 *part_id,
|
||||
longlong *func_value)
|
||||
{
|
||||
uint32 loc_part_id, sub_part_id;
|
||||
uint no_subparts;
|
||||
longlong local_func_value;
|
||||
int error;
|
||||
DBUG_ENTER("get_partition_id_list_sub_hash");
|
||||
|
||||
if (unlikely((error= get_partition_id_list(part_info, &loc_part_id))))
|
||||
if (unlikely((error= get_partition_id_list(part_info, &loc_part_id,
|
||||
func_value))))
|
||||
{
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
no_subparts= part_info->no_subparts;
|
||||
sub_part_id= get_part_id_hash(no_subparts, part_info->subpart_expr);
|
||||
sub_part_id= get_part_id_hash(no_subparts, part_info->subpart_expr,
|
||||
&local_func_value);
|
||||
*part_id= get_part_id_for_sub(loc_part_id, sub_part_id, no_subparts);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
int get_partition_id_list_sub_linear_hash(partition_info *part_info,
|
||||
uint32 *part_id)
|
||||
uint32 *part_id,
|
||||
longlong *func_value)
|
||||
{
|
||||
uint32 loc_part_id, sub_part_id;
|
||||
uint no_subparts;
|
||||
longlong local_func_value;
|
||||
int error;
|
||||
DBUG_ENTER("get_partition_id_list_sub_linear_hash");
|
||||
|
||||
if (unlikely((error= get_partition_id_list(part_info, &loc_part_id))))
|
||||
if (unlikely((error= get_partition_id_list(part_info, &loc_part_id,
|
||||
func_value))))
|
||||
{
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
no_subparts= part_info->no_subparts;
|
||||
sub_part_id= get_part_id_hash(no_subparts, part_info->subpart_expr);
|
||||
sub_part_id= get_part_id_linear_hash(part_info, no_subparts,
|
||||
part_info->subpart_expr,
|
||||
&local_func_value);
|
||||
*part_id= get_part_id_for_sub(loc_part_id, sub_part_id, no_subparts);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
int get_partition_id_list_sub_key(partition_info *part_info,
|
||||
uint32 *part_id)
|
||||
uint32 *part_id,
|
||||
longlong *func_value)
|
||||
{
|
||||
uint32 loc_part_id, sub_part_id;
|
||||
uint no_subparts;
|
||||
longlong local_func_value;
|
||||
int error;
|
||||
DBUG_ENTER("get_partition_id_range_sub_key");
|
||||
|
||||
if (unlikely((error= get_partition_id_list(part_info, &loc_part_id))))
|
||||
if (unlikely((error= get_partition_id_list(part_info, &loc_part_id,
|
||||
func_value))))
|
||||
{
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
no_subparts= part_info->no_subparts;
|
||||
sub_part_id= get_part_id_key(part_info->subpart_field_array, no_subparts);
|
||||
sub_part_id= get_part_id_key(part_info->subpart_field_array,
|
||||
no_subparts, &local_func_value);
|
||||
*part_id= get_part_id_for_sub(loc_part_id, sub_part_id, no_subparts);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
int get_partition_id_list_sub_linear_key(partition_info *part_info,
|
||||
uint32 *part_id)
|
||||
uint32 *part_id,
|
||||
longlong *func_value)
|
||||
{
|
||||
uint32 loc_part_id, sub_part_id;
|
||||
uint no_subparts;
|
||||
longlong local_func_value;
|
||||
int error;
|
||||
DBUG_ENTER("get_partition_id_list_sub_linear_key");
|
||||
|
||||
if (unlikely((error= get_partition_id_list(part_info, &loc_part_id))))
|
||||
if (unlikely((error= get_partition_id_list(part_info, &loc_part_id,
|
||||
func_value))))
|
||||
{
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
no_subparts= part_info->no_subparts;
|
||||
sub_part_id= get_part_id_linear_key(part_info,
|
||||
part_info->subpart_field_array,
|
||||
no_subparts);
|
||||
no_subparts, &local_func_value);
|
||||
*part_id= get_part_id_for_sub(loc_part_id, sub_part_id, no_subparts);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
@@ -3259,29 +3331,34 @@ int get_partition_id_list_sub_linear_key(partition_info *part_info,
|
||||
|
||||
uint32 get_partition_id_hash_sub(partition_info *part_info)
|
||||
{
|
||||
return get_part_id_hash(part_info->no_subparts, part_info->subpart_expr);
|
||||
longlong func_value;
|
||||
return get_part_id_hash(part_info->no_subparts, part_info->subpart_expr,
|
||||
&func_value);
|
||||
}
|
||||
|
||||
|
||||
uint32 get_partition_id_linear_hash_sub(partition_info *part_info)
|
||||
{
|
||||
longlong func_value;
|
||||
return get_part_id_linear_hash(part_info, part_info->no_subparts,
|
||||
part_info->subpart_expr);
|
||||
part_info->subpart_expr, &func_value);
|
||||
}
|
||||
|
||||
|
||||
uint32 get_partition_id_key_sub(partition_info *part_info)
|
||||
{
|
||||
longlong func_value;
|
||||
return get_part_id_key(part_info->subpart_field_array,
|
||||
part_info->no_subparts);
|
||||
part_info->no_subparts, &func_value);
|
||||
}
|
||||
|
||||
|
||||
uint32 get_partition_id_linear_key_sub(partition_info *part_info)
|
||||
{
|
||||
longlong func_value;
|
||||
return get_part_id_linear_key(part_info,
|
||||
part_info->subpart_field_array,
|
||||
part_info->no_subparts);
|
||||
part_info->no_subparts, &func_value);
|
||||
}
|
||||
|
||||
|
||||
@@ -3428,16 +3505,19 @@ bool get_part_id_from_key(const TABLE *table, byte *buf, KEY *key_info,
|
||||
bool result;
|
||||
byte *rec0= table->record[0];
|
||||
partition_info *part_info= table->part_info;
|
||||
longlong func_value;
|
||||
DBUG_ENTER("get_part_id_from_key");
|
||||
|
||||
key_restore(buf, (byte*)key_spec->key, key_info, key_spec->length);
|
||||
if (likely(rec0 == buf))
|
||||
result= part_info->get_part_partition_id(part_info, part_id);
|
||||
result= part_info->get_part_partition_id(part_info, part_id,
|
||||
&func_value);
|
||||
else
|
||||
{
|
||||
Field **part_field_array= part_info->part_field_array;
|
||||
set_field_ptr(part_field_array, buf, rec0);
|
||||
result= part_info->get_part_partition_id(part_info, part_id);
|
||||
result= part_info->get_part_partition_id(part_info, part_id,
|
||||
&func_value);
|
||||
set_field_ptr(part_field_array, rec0, buf);
|
||||
}
|
||||
DBUG_RETURN(result);
|
||||
@@ -3472,16 +3552,19 @@ void get_full_part_id_from_key(const TABLE *table, byte *buf,
|
||||
bool result;
|
||||
partition_info *part_info= table->part_info;
|
||||
byte *rec0= table->record[0];
|
||||
longlong func_value;
|
||||
DBUG_ENTER("get_full_part_id_from_key");
|
||||
|
||||
key_restore(buf, (byte*)key_spec->key, key_info, key_spec->length);
|
||||
if (likely(rec0 == buf))
|
||||
result= part_info->get_partition_id(part_info, &part_spec->start_part);
|
||||
result= part_info->get_partition_id(part_info, &part_spec->start_part,
|
||||
&func_value);
|
||||
else
|
||||
{
|
||||
Field **part_field_array= part_info->full_part_field_array;
|
||||
set_field_ptr(part_field_array, buf, rec0);
|
||||
result= part_info->get_partition_id(part_info, &part_spec->start_part);
|
||||
result= part_info->get_partition_id(part_info, &part_spec->start_part,
|
||||
&func_value);
|
||||
set_field_ptr(part_field_array, rec0, buf);
|
||||
}
|
||||
part_spec->end_part= part_spec->start_part;
|
||||
@@ -3926,6 +4009,47 @@ 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)
|
||||
{
|
||||
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))
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
We need to check if engine used by all partitions can handle
|
||||
partitioning natively.
|
||||
@@ -3954,8 +4078,10 @@ static bool check_native_partitioned(HA_CREATE_INFO *create_info,bool *ret_val,
|
||||
bool first= TRUE;
|
||||
bool default_engine;
|
||||
handlerton *engine_type= create_info->db_type;
|
||||
handlerton *old_engine_type= engine_type;
|
||||
uint i= 0;
|
||||
handler *file;
|
||||
uint no_parts= part_info->partitions.elements;
|
||||
DBUG_ENTER("check_native_partitioned");
|
||||
|
||||
default_engine= (create_info->used_fields | HA_CREATE_USED_ENGINE) ?
|
||||
@@ -3963,27 +4089,48 @@ static bool check_native_partitioned(HA_CREATE_INFO *create_info,bool *ret_val,
|
||||
DBUG_PRINT("info", ("engine_type = %u, default = %u",
|
||||
ha_legacy_type(engine_type),
|
||||
default_engine));
|
||||
do
|
||||
if (no_parts)
|
||||
{
|
||||
partition_element *part_elem= part_it++;
|
||||
if (first && default_engine && part_elem->engine_type)
|
||||
engine_type= part_elem->engine_type;
|
||||
first= FALSE;
|
||||
|
||||
if (part_elem->engine_type != engine_type)
|
||||
do
|
||||
{
|
||||
/*
|
||||
Mixed engines not yet supported but when supported it will need
|
||||
the partition handler
|
||||
*/
|
||||
*ret_val= FALSE;
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
} while (++i < part_info->no_parts);
|
||||
partition_element *part_elem= part_it++;
|
||||
if (is_sub_partitioned(part_info) &&
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
All engines are of the same type. Check if this engine supports
|
||||
native partitioning.
|
||||
*/
|
||||
|
||||
if (!engine_type)
|
||||
engine_type= old_engine_type;
|
||||
DBUG_PRINT("info", ("engine_type = %s",
|
||||
ha_resolve_storage_engine_name(engine_type)));
|
||||
if (engine_type->partition_flags &&
|
||||
(engine_type->partition_flags() & HA_CAN_PARTITION))
|
||||
{
|
||||
@@ -3992,6 +4139,13 @@ static bool check_native_partitioned(HA_CREATE_INFO *create_info,bool *ret_val,
|
||||
*ret_val= TRUE;
|
||||
}
|
||||
DBUG_RETURN(FALSE);
|
||||
error:
|
||||
/*
|
||||
Mixed engines not yet supported but when supported it will need
|
||||
the partition handler
|
||||
*/
|
||||
*ret_val= FALSE;
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
|
||||
|
||||
@@ -4794,7 +4948,7 @@ the generated partition syntax in a correct manner.
|
||||
}
|
||||
else
|
||||
{
|
||||
bool is_native_partitioned;
|
||||
bool is_native_partitioned= FALSE;
|
||||
partition_info *part_info= thd->lex->part_info;
|
||||
part_info->default_engine_type= create_info->db_type;
|
||||
if (check_native_partitioned(create_info, &is_native_partitioned,
|
||||
@@ -4804,11 +4958,7 @@ the generated partition syntax in a correct manner.
|
||||
}
|
||||
if (!is_native_partitioned)
|
||||
{
|
||||
if (create_info->db_type == (handlerton*)&default_hton)
|
||||
{
|
||||
thd->lex->part_info->default_engine_type=
|
||||
ha_checktype(thd, DB_TYPE_DEFAULT, FALSE, FALSE);
|
||||
}
|
||||
DBUG_ASSERT(create_info->db_type != &default_hton);
|
||||
create_info->db_type= &partition_hton;
|
||||
}
|
||||
}
|
||||
@@ -5248,132 +5398,6 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
Internal representation of the frm blob
|
||||
*/
|
||||
|
||||
struct frm_blob_struct
|
||||
{
|
||||
struct frm_blob_header
|
||||
{
|
||||
uint ver; /* Version of header */
|
||||
uint orglen; /* Original length of compressed data */
|
||||
uint complen; /* Compressed length of data, 0=uncompressed */
|
||||
} head;
|
||||
char data[1];
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
packfrm is a method used to compress the frm file for storage in a
|
||||
handler. This method was developed for the NDB handler and has been moved
|
||||
here to serve also other uses.
|
||||
|
||||
SYNOPSIS
|
||||
packfrm()
|
||||
data Data reference to frm file data
|
||||
len Length of frm file data
|
||||
out:pack_data Reference to the pointer to the packed frm data
|
||||
out:pack_len Length of packed frm file data
|
||||
|
||||
RETURN VALUES
|
||||
0 Success
|
||||
>0 Failure
|
||||
*/
|
||||
|
||||
int packfrm(const void *data, uint len,
|
||||
const void **pack_data, uint *pack_len)
|
||||
{
|
||||
int error;
|
||||
ulong org_len, comp_len;
|
||||
uint blob_len;
|
||||
frm_blob_struct *blob;
|
||||
DBUG_ENTER("packfrm");
|
||||
DBUG_PRINT("enter", ("data: %x, len: %d", data, len));
|
||||
|
||||
error= 1;
|
||||
org_len= len;
|
||||
if (my_compress((byte*)data, &org_len, &comp_len))
|
||||
goto err;
|
||||
|
||||
DBUG_PRINT("info", ("org_len: %d, comp_len: %d", org_len, comp_len));
|
||||
DBUG_DUMP("compressed", (char*)data, org_len);
|
||||
|
||||
error= 2;
|
||||
blob_len= sizeof(frm_blob_struct::frm_blob_header)+org_len;
|
||||
if (!(blob= (frm_blob_struct*) my_malloc(blob_len,MYF(MY_WME))))
|
||||
goto err;
|
||||
|
||||
// Store compressed blob in machine independent format
|
||||
int4store((char*)(&blob->head.ver), 1);
|
||||
int4store((char*)(&blob->head.orglen), comp_len);
|
||||
int4store((char*)(&blob->head.complen), org_len);
|
||||
|
||||
// Copy frm data into blob, already in machine independent format
|
||||
memcpy(blob->data, data, org_len);
|
||||
|
||||
*pack_data= blob;
|
||||
*pack_len= blob_len;
|
||||
error= 0;
|
||||
|
||||
DBUG_PRINT("exit", ("pack_data: %x, pack_len: %d", *pack_data, *pack_len));
|
||||
err:
|
||||
DBUG_RETURN(error);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
unpackfrm is a method used to decompress the frm file received from a
|
||||
handler. This method was developed for the NDB handler and has been moved
|
||||
here to serve also other uses for other clustered storage engines.
|
||||
|
||||
SYNOPSIS
|
||||
unpackfrm()
|
||||
pack_data Data reference to packed frm file data
|
||||
out:unpack_data Reference to the pointer to the unpacked frm data
|
||||
out:unpack_len Length of unpacked frm file data
|
||||
|
||||
RETURN VALUES<45>
|
||||
0 Success
|
||||
>0 Failure
|
||||
*/
|
||||
|
||||
int unpackfrm(const void **unpack_data, uint *unpack_len,
|
||||
const void *pack_data)
|
||||
{
|
||||
const frm_blob_struct *blob= (frm_blob_struct*)pack_data;
|
||||
byte *data;
|
||||
ulong complen, orglen, ver;
|
||||
DBUG_ENTER("unpackfrm");
|
||||
DBUG_PRINT("enter", ("pack_data: %x", pack_data));
|
||||
|
||||
complen= uint4korr((char*)&blob->head.complen);
|
||||
orglen= uint4korr((char*)&blob->head.orglen);
|
||||
ver= uint4korr((char*)&blob->head.ver);
|
||||
|
||||
DBUG_PRINT("blob",("ver: %d complen: %d orglen: %d",
|
||||
ver,complen,orglen));
|
||||
DBUG_DUMP("blob->data", (char*) blob->data, complen);
|
||||
|
||||
if (ver != 1)
|
||||
DBUG_RETURN(1);
|
||||
if (!(data= my_malloc(max(orglen, complen), MYF(MY_WME))))
|
||||
DBUG_RETURN(2);
|
||||
memcpy(data, blob->data, complen);
|
||||
|
||||
if (my_uncompress(data, &complen, &orglen))
|
||||
{
|
||||
my_free((char*)data, MYF(0));
|
||||
DBUG_RETURN(3);
|
||||
}
|
||||
|
||||
*unpack_data= data;
|
||||
*unpack_len= complen;
|
||||
|
||||
DBUG_PRINT("exit", ("frmdata: %x, len: %d", *unpack_data, *unpack_len));
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Prepare for calling val_int on partition function by setting fields to
|
||||
|
||||
Reference in New Issue
Block a user