summaryrefslogtreecommitdiff
path: root/sql/sql_partition.cc
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2010-03-15 12:51:23 +0100
committerSergei Golubchik <sergii@pisem.net>2010-03-15 12:51:23 +0100
commit61522b178f6e94301306bac6a6c5ae71bc1a1673 (patch)
tree1a557d74018ed9cd073b5aa960bd62421962e73d /sql/sql_partition.cc
parent8e45f13937ff529bf66b38a2b86d281f5caf3f54 (diff)
parentd7c0ca654b6d9d9dd1eaa05984119df84282976f (diff)
downloadmariadb-git-61522b178f6e94301306bac6a6c5ae71bc1a1673.tar.gz
merged
Diffstat (limited to 'sql/sql_partition.cc')
-rw-r--r--sql/sql_partition.cc100
1 files changed, 62 insertions, 38 deletions
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index 8fd5f044958..e26197a3096 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -870,6 +870,8 @@ int check_signed_flag(partition_info *part_info)
part_info Reference to partitioning data structure
is_sub_part Is the table subpartitioned as well
is_field_to_be_setup Flag if we are to set-up field arrays
+ is_create_table_ind Indicator of whether openfrm was called as part of
+ CREATE or ALTER TABLE
RETURN VALUE
TRUE An error occurred, something was wrong with the
@@ -892,8 +894,9 @@ int check_signed_flag(partition_info *part_info)
on the field object.
*/
-bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table,
- bool is_sub_part, bool is_field_to_be_setup)
+static bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table,
+ bool is_sub_part, bool is_field_to_be_setup,
+ bool is_create_table_ind)
{
partition_info *part_info= table->part_info;
uint dir_length, home_dir_length;
@@ -1006,10 +1009,31 @@ bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table,
thd->where= save_where;
if (unlikely(func_expr->const_item()))
{
- my_error(ER_CONST_EXPR_IN_PARTITION_FUNC_ERROR, MYF(0));
+ my_error(ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR, MYF(0));
clear_field_flag(table);
goto end;
}
+
+ /*
+ We don't allow creating partitions with timezone-dependent expressions as
+ a (sub)partitioning function, but we want to allow such expressions when
+ opening existing tables for easier maintenance. This exception should be
+ deprecated at some point in future so that we always throw an error.
+ */
+ if (func_expr->walk(&Item::is_timezone_dependent_processor,
+ 0, NULL))
+ {
+ if (is_create_table_ind)
+ {
+ my_error(ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR, MYF(0));
+ goto end;
+ }
+ else
+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR,
+ ER(ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR));
+ }
+
if ((!is_sub_part) && (error= check_signed_flag(part_info)))
goto end;
result= FALSE;
@@ -1617,7 +1641,8 @@ bool fix_partition_func(THD *thd, TABLE *table,
else
{
if (unlikely(fix_fields_part_func(thd, part_info->subpart_expr,
- table, TRUE, TRUE)))
+ table, TRUE, TRUE,
+ is_create_table_ind)))
goto end;
if (unlikely(part_info->subpart_expr->result_type() != INT_RESULT))
{
@@ -1645,7 +1670,8 @@ bool fix_partition_func(THD *thd, TABLE *table,
else
{
if (unlikely(fix_fields_part_func(thd, part_info->part_expr,
- table, FALSE, TRUE)))
+ table, FALSE, TRUE,
+ is_create_table_ind)))
goto end;
if (unlikely(part_info->part_expr->result_type() != INT_RESULT))
{
@@ -1659,7 +1685,8 @@ bool fix_partition_func(THD *thd, TABLE *table,
{
const char *error_str;
if (unlikely(fix_fields_part_func(thd, part_info->part_expr,
- table, FALSE, TRUE)))
+ table, FALSE, TRUE,
+ is_create_table_ind)))
goto end;
if (part_info->part_type == RANGE_PARTITION)
{
@@ -2852,16 +2879,13 @@ int get_partition_id_range(partition_info *part_info,
part_func_value-= 0x8000000000000000ULL;
while (max_part_id > min_part_id)
{
- loc_part_id= (max_part_id + min_part_id + 1) >> 1;
+ loc_part_id= (max_part_id + min_part_id) / 2;
if (range_array[loc_part_id] <= part_func_value)
min_part_id= loc_part_id + 1;
else
- max_part_id= loc_part_id - 1;
+ max_part_id= loc_part_id;
}
loc_part_id= max_part_id;
- if (part_func_value >= range_array[loc_part_id])
- if (loc_part_id != max_partition)
- loc_part_id++;
*part_id= (uint32)loc_part_id;
if (loc_part_id == max_partition &&
part_func_value >= range_array[loc_part_id] &&
@@ -2935,6 +2959,7 @@ uint32 get_partition_id_range_for_endpoint(partition_info *part_info,
bool include_endpoint)
{
longlong *range_array= part_info->range_int_array;
+ longlong part_end_val;
uint max_partition= part_info->no_parts - 1;
uint min_part_id= 0, max_part_id= max_partition, loc_part_id;
/* Get the partitioning function value for the endpoint */
@@ -2968,46 +2993,46 @@ uint32 get_partition_id_range_for_endpoint(partition_info *part_info,
}
}
-
if (unsigned_flag)
part_func_value-= 0x8000000000000000ULL;
if (left_endpoint && !include_endpoint)
part_func_value++;
+
+ /*
+ Search for the partition containing part_func_value
+ (including the right endpoint).
+ */
while (max_part_id > min_part_id)
{
- loc_part_id= (max_part_id + min_part_id + 1) >> 1;
- if (range_array[loc_part_id] <= part_func_value)
+ loc_part_id= (max_part_id + min_part_id) / 2;
+ if (range_array[loc_part_id] < part_func_value)
min_part_id= loc_part_id + 1;
else
- max_part_id= loc_part_id - 1;
+ max_part_id= loc_part_id;
}
loc_part_id= max_part_id;
- if (loc_part_id < max_partition &&
- part_func_value >= range_array[loc_part_id+1])
- {
- loc_part_id++;
- }
+
+ /* Adjust for endpoints */
+ part_end_val= range_array[loc_part_id];
if (left_endpoint)
{
- longlong bound= range_array[loc_part_id];
/*
In case of PARTITION p VALUES LESS THAN MAXVALUE
the maximum value is in the current partition.
*/
- if (part_func_value > bound ||
- (part_func_value == bound &&
- (!part_info->defined_max_value || loc_part_id < max_partition)))
+ if (part_func_value > part_end_val ||
+ (part_func_value == part_end_val &&
+ (loc_part_id < max_partition || !part_info->defined_max_value)))
loc_part_id++;
}
else
{
- if (loc_part_id < max_partition)
- {
- if (part_func_value == range_array[loc_part_id])
- loc_part_id += test(include_endpoint);
- else if (part_func_value > range_array[loc_part_id])
- loc_part_id++;
- }
+ /* if 'WHERE <= X' and partition is LESS THAN (X) include next partition */
+ if (include_endpoint && loc_part_id < max_partition &&
+ part_func_value == part_end_val)
+ loc_part_id++;
+
+ /* Right endpoint, set end after correct partition */
loc_part_id++;
}
DBUG_RETURN(loc_part_id);
@@ -4090,8 +4115,9 @@ static int fast_end_partition(THD *thd, ulonglong copied,
}
if ((!is_empty) && (!written_bin_log) &&
- (!thd->lex->no_write_to_binlog))
- write_bin_log(thd, FALSE, thd->query(), thd->query_length());
+ (!thd->lex->no_write_to_binlog) &&
+ write_bin_log(thd, FALSE, thd->query(), thd->query_length()))
+ DBUG_RETURN(TRUE);
my_snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
(ulong) (copied + deleted),
@@ -5682,8 +5708,7 @@ static bool write_log_drop_partition(ALTER_PARTITION_PARAM_TYPE *lpt)
part_info->first_log_entry= NULL;
build_table_filename(path, sizeof(path) - 1, lpt->db,
lpt->table_name, "", 0);
- build_table_filename(tmp_path, sizeof(tmp_path) - 1, lpt->db,
- lpt->table_name, "#", 0);
+ build_table_shadow_filename(tmp_path, sizeof(tmp_path) - 1, lpt);
pthread_mutex_lock(&LOCK_gdl);
if (write_log_dropped_partitions(lpt, &next_entry, (const char*)path,
FALSE))
@@ -5739,8 +5764,7 @@ static bool write_log_add_change_partition(ALTER_PARTITION_PARAM_TYPE *lpt)
build_table_filename(path, sizeof(path) - 1, lpt->db,
lpt->table_name, "", 0);
- build_table_filename(tmp_path, sizeof(tmp_path) - 1, lpt->db,
- lpt->table_name, "#", 0);
+ build_table_shadow_filename(tmp_path, sizeof(tmp_path) - 1, lpt);
pthread_mutex_lock(&LOCK_gdl);
if (write_log_dropped_partitions(lpt, &next_entry, (const char*)path,
FALSE))
@@ -5965,7 +5989,7 @@ void handle_alter_part_error(ALTER_PARTITION_PARAM_TYPE *lpt,
partition_info *part_info= lpt->part_info;
DBUG_ENTER("handle_alter_part_error");
- if (!part_info->first_log_entry &&
+ if (part_info->first_log_entry &&
execute_ddl_log_entry(current_thd,
part_info->first_log_entry->entry_pos))
{