summaryrefslogtreecommitdiff
path: root/sql/sql_partition.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_partition.cc')
-rw-r--r--sql/sql_partition.cc891
1 files changed, 335 insertions, 556 deletions
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index c214c2a13ee..4a200dd670b 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -83,67 +83,21 @@ using std::min;
/*
Partition related functions declarations and some static constants;
*/
-const LEX_STRING partition_keywords[]=
-{
- { C_STRING_WITH_LEN("HASH") },
- { C_STRING_WITH_LEN("RANGE") },
- { C_STRING_WITH_LEN("LIST") },
- { C_STRING_WITH_LEN("KEY") },
- { C_STRING_WITH_LEN("MAXVALUE") },
- { C_STRING_WITH_LEN("LINEAR ") },
- { C_STRING_WITH_LEN(" COLUMNS") },
- { C_STRING_WITH_LEN("ALGORITHM") }
-
-};
-static const char *part_str= "PARTITION";
-static const char *sub_str= "SUB";
-static const char *by_str= "BY";
-static const char *space_str= " ";
-static const char *equal_str= "=";
-static const char *end_paren_str= ")";
-static const char *begin_paren_str= "(";
-static const char *comma_str= ",";
-
-int get_partition_id_list_col(partition_info *part_info,
- uint32 *part_id,
- longlong *func_value);
-int get_partition_id_list(partition_info *part_info,
- uint32 *part_id,
- longlong *func_value);
-int get_partition_id_range_col(partition_info *part_info,
- uint32 *part_id,
- longlong *func_value);
-int get_partition_id_range(partition_info *part_info,
- uint32 *part_id,
- longlong *func_value);
-static int get_part_id_charset_func_part(partition_info *part_info,
- uint32 *part_id,
- longlong *func_value);
-static int get_part_id_charset_func_subpart(partition_info *part_info,
- uint32 *part_id);
-int get_partition_id_hash_nosub(partition_info *part_info,
- uint32 *part_id,
- longlong *func_value);
-int get_partition_id_key_nosub(partition_info *part_info,
- uint32 *part_id,
- longlong *func_value);
-int get_partition_id_linear_hash_nosub(partition_info *part_info,
- uint32 *part_id,
- longlong *func_value);
-int get_partition_id_linear_key_nosub(partition_info *part_info,
- uint32 *part_id,
- longlong *func_value);
-int get_partition_id_with_sub(partition_info *part_info,
- uint32 *part_id,
- longlong *func_value);
-int get_partition_id_hash_sub(partition_info *part_info,
- uint32 *part_id);
-int get_partition_id_key_sub(partition_info *part_info,
- uint32 *part_id);
-int get_partition_id_linear_hash_sub(partition_info *part_info,
- uint32 *part_id);
-int get_partition_id_linear_key_sub(partition_info *part_info,
- uint32 *part_id);
+static int get_partition_id_list_col(partition_info *, uint32 *, longlong *);
+static int get_partition_id_list(partition_info *, uint32 *, longlong *);
+static int get_partition_id_range_col(partition_info *, uint32 *, longlong *);
+static int get_partition_id_range(partition_info *, uint32 *, longlong *);
+static int get_part_id_charset_func_part(partition_info *, uint32 *, longlong *);
+static int get_part_id_charset_func_subpart(partition_info *, uint32 *);
+static int get_partition_id_hash_nosub(partition_info *, uint32 *, longlong *);
+static int get_partition_id_key_nosub(partition_info *, uint32 *, longlong *);
+static int get_partition_id_linear_hash_nosub(partition_info *, uint32 *, longlong *);
+static int get_partition_id_linear_key_nosub(partition_info *, uint32 *, longlong *);
+static int get_partition_id_with_sub(partition_info *, uint32 *, longlong *);
+static int get_partition_id_hash_sub(partition_info *part_info, uint32 *part_id);
+static int get_partition_id_key_sub(partition_info *part_info, uint32 *part_id);
+static int get_partition_id_linear_hash_sub(partition_info *part_info, uint32 *part_id);
+static int get_partition_id_linear_key_sub(partition_info *part_info, uint32 *part_id);
static uint32 get_next_partition_via_walking(PARTITION_ITERATOR*);
static void set_up_range_analysis_info(partition_info *part_info);
static uint32 get_next_subpartition_via_walking(PARTITION_ITERATOR*);
@@ -255,7 +209,7 @@ static bool is_name_in_list(char *name, List<char> list_names)
FALSE Success
*/
-bool partition_default_handling(TABLE *table, partition_info *part_info,
+bool partition_default_handling(THD *thd, TABLE *table, partition_info *part_info,
bool is_create_table_ind,
const char *normalized_path)
{
@@ -283,7 +237,7 @@ bool partition_default_handling(TABLE *table, partition_info *part_info,
part_info->num_subparts= num_parts / part_info->num_parts;
}
}
- part_info->set_up_defaults_for_partitioning(table->file,
+ part_info->set_up_defaults_for_partitioning(thd, table->file,
NULL, 0U);
DBUG_RETURN(FALSE);
}
@@ -318,10 +272,10 @@ int get_parts_for_update(const uchar *old_data, uchar *new_data,
DBUG_ENTER("get_parts_for_update");
DBUG_ASSERT(new_data == rec0); // table->record[0]
- set_field_ptr(part_field_array, old_data, rec0);
+ part_info->table->move_fields(part_field_array, old_data, rec0);
error= part_info->get_partition_id(part_info, old_part_id,
&old_func_value);
- set_field_ptr(part_field_array, rec0, old_data);
+ part_info->table->move_fields(part_field_array, rec0, old_data);
if (unlikely(error)) // Should never happen
{
DBUG_ASSERT(0);
@@ -346,10 +300,10 @@ int get_parts_for_update(const uchar *old_data, uchar *new_data,
future use. It will be tested by ensuring that the above
condition is false in one test situation before pushing the code.
*/
- set_field_ptr(part_field_array, new_data, rec0);
+ part_info->table->move_fields(part_field_array, new_data, rec0);
error= part_info->get_partition_id(part_info, new_part_id,
new_func_value);
- set_field_ptr(part_field_array, rec0, new_data);
+ part_info->table->move_fields(part_field_array, rec0, new_data);
if (unlikely(error))
{
DBUG_RETURN(error);
@@ -400,9 +354,9 @@ int get_part_for_delete(const uchar *buf, const uchar *rec0,
else
{
Field **part_field_array= part_info->full_part_field_array;
- set_field_ptr(part_field_array, buf, rec0);
+ part_info->table->move_fields(part_field_array, buf, rec0);
error= part_info->get_partition_id(part_info, part_id, &func_value);
- set_field_ptr(part_field_array, rec0, buf);
+ part_info->table->move_fields(part_field_array, rec0, buf);
if (unlikely(error))
{
DBUG_RETURN(error);
@@ -455,7 +409,7 @@ int get_part_for_delete(const uchar *buf, const uchar *rec0,
function.
*/
-static bool set_up_field_array(TABLE *table,
+static bool set_up_field_array(THD *thd, TABLE *table,
bool is_sub_part)
{
Field **ptr, *field, **field_array;
@@ -492,7 +446,7 @@ static bool set_up_field_array(TABLE *table,
DBUG_RETURN(result);
}
size_field_array= (num_fields+1)*sizeof(Field*);
- field_array= (Field**)sql_calloc(size_field_array);
+ field_array= (Field**) thd->calloc(size_field_array);
if (unlikely(!field_array))
{
mem_alloc_error(size_field_array);
@@ -617,7 +571,7 @@ static bool create_full_part_field_array(THD *thd, TABLE *table,
num_part_fields++;
}
size_field_array= (num_part_fields+1)*sizeof(Field*);
- field_array= (Field**)sql_calloc(size_field_array);
+ field_array= (Field**) thd->calloc(size_field_array);
if (unlikely(!field_array))
{
mem_alloc_error(size_field_array);
@@ -660,9 +614,16 @@ static bool create_full_part_field_array(THD *thd, TABLE *table,
full_part_field_array may be NULL if storage engine supports native
partitioning.
*/
+ table->vcol_set= table->read_set= &part_info->full_part_field_set;
if ((ptr= part_info->full_part_field_array))
for (; *ptr; ptr++)
- bitmap_set_bit(&part_info->full_part_field_set, (*ptr)->field_index);
+ {
+ if ((*ptr)->vcol_info)
+ table->mark_virtual_col(*ptr);
+ else
+ bitmap_fast_test_and_set(table->read_set, (*ptr)->field_index);
+ }
+ table->default_column_bitmaps();
end:
DBUG_RETURN(result);
@@ -804,7 +765,7 @@ static void clear_field_flag(TABLE *table)
*/
-static bool handle_list_of_fields(List_iterator<char> it,
+static bool handle_list_of_fields(THD *thd, List_iterator<char> it,
TABLE *table,
partition_info *part_info,
bool is_sub_part)
@@ -865,7 +826,7 @@ static bool handle_list_of_fields(List_iterator<char> it,
}
}
}
- result= set_up_field_array(table, is_sub_part);
+ result= set_up_field_array(thd, table, is_sub_part);
end:
DBUG_RETURN(result);
}
@@ -961,9 +922,9 @@ static bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table,
if (init_lex_with_single_table(thd, table, &lex))
goto end;
+ table->get_fields_in_item_tree= true;
- func_expr->walk(&Item::change_context_processor, 0,
- (uchar*) &lex.select_lex.context);
+ func_expr->walk(&Item::change_context_processor, 0, &lex.select_lex.context);
thd->where= "partition function";
/*
In execution we must avoid the use of thd->change_item_tree since
@@ -988,7 +949,7 @@ static bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table,
thd->lex->allow_sum_func= 0;
if (!(error= func_expr->fix_fields(thd, (Item**)&func_expr)))
- func_expr->walk(&Item::vcol_in_partition_func_processor, 0, NULL);
+ func_expr->walk(&Item::post_fix_fields_part_expr_processor, 0, NULL);
/*
Restore agg_field/agg_func and allow_sum_func,
@@ -1018,8 +979,7 @@ static bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table,
easier maintenance. This exception should be deprecated at some point
in future so that we always throw an error.
*/
- if (func_expr->walk(&Item::check_valid_arguments_processor,
- 0, NULL))
+ if (func_expr->walk(&Item::check_valid_arguments_processor, 0, NULL))
{
if (is_create_table_ind)
{
@@ -1034,13 +994,10 @@ static bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table,
if ((!is_sub_part) && (error= check_signed_flag(part_info)))
goto end;
- result= set_up_field_array(table, is_sub_part);
+ result= set_up_field_array(thd, table, is_sub_part);
end:
end_lex_with_single_table(thd, table, old_lex);
-#if !defined(DBUG_OFF)
- func_expr->walk(&Item::change_context_processor, 0,
- (uchar*) 0);
-#endif
+ func_expr->walk(&Item::change_context_processor, 0, 0);
DBUG_RETURN(result);
}
@@ -1622,7 +1579,7 @@ bool fix_partition_func(THD *thd, TABLE *table,
if (!is_create_table_ind ||
thd->lex->sql_command != SQLCOM_CREATE_TABLE)
{
- if (partition_default_handling(table, part_info,
+ if (partition_default_handling(thd, table, part_info,
is_create_table_ind,
table->s->normalized_path.str))
{
@@ -1641,7 +1598,7 @@ bool fix_partition_func(THD *thd, TABLE *table,
if (part_info->list_of_subpart_fields)
{
List_iterator<char> it(part_info->subpart_field_list);
- if (unlikely(handle_list_of_fields(it, table, part_info, TRUE)))
+ if (unlikely(handle_list_of_fields(thd, it, table, part_info, TRUE)))
goto end;
}
else
@@ -1668,7 +1625,7 @@ bool fix_partition_func(THD *thd, TABLE *table,
if (part_info->list_of_part_fields)
{
List_iterator<char> it(part_info->part_field_list);
- if (unlikely(handle_list_of_fields(it, table, part_info, FALSE)))
+ if (unlikely(handle_list_of_fields(thd, it, table, part_info, FALSE)))
goto end;
}
else
@@ -1690,7 +1647,7 @@ bool fix_partition_func(THD *thd, TABLE *table,
if (part_info->column_list)
{
List_iterator<char> it(part_info->part_field_list);
- if (unlikely(handle_list_of_fields(it, table, part_info, FALSE)))
+ if (unlikely(handle_list_of_fields(thd, it, table, part_info, FALSE)))
goto end;
}
else
@@ -1702,13 +1659,13 @@ bool fix_partition_func(THD *thd, TABLE *table,
part_info->fixed= TRUE;
if (part_info->part_type == RANGE_PARTITION)
{
- error_str= partition_keywords[PKW_RANGE].str;
+ error_str= "HASH";
if (unlikely(part_info->check_range_constants(thd)))
goto end;
}
else if (part_info->part_type == LIST_PARTITION)
{
- error_str= partition_keywords[PKW_LIST].str;
+ error_str= "LIST";
if (unlikely(part_info->check_list_constants(thd)))
goto end;
}
@@ -1786,154 +1743,48 @@ end:
ALTER TABLE commands. Finally it is used for SHOW CREATE TABLES.
*/
-static int add_write(File fptr, const char *buf, uint len)
-{
- uint ret_code= mysql_file_write(fptr, (const uchar*)buf, len, MYF(MY_FNABP));
-
- if (likely(ret_code == 0))
- return 0;
- else
- return 1;
-}
-
-static int add_string_object(File fptr, String *string)
-{
- return add_write(fptr, string->ptr(), string->length());
-}
-
-static int add_string(File fptr, const char *string)
-{
- return add_write(fptr, string, strlen(string));
-}
-
-static int add_string_len(File fptr, const char *string, uint len)
+static int add_part_field_list(THD *thd, String *str, List<char> field_list)
{
- return add_write(fptr, string, len);
-}
-
-static int add_space(File fptr)
-{
- return add_string(fptr, space_str);
-}
-
-static int add_comma(File fptr)
-{
- return add_string(fptr, comma_str);
-}
-
-static int add_equal(File fptr)
-{
- return add_string(fptr, equal_str);
-}
-
-static int add_end_parenthesis(File fptr)
-{
- return add_string(fptr, end_paren_str);
-}
-
-static int add_begin_parenthesis(File fptr)
-{
- return add_string(fptr, begin_paren_str);
-}
-
-static int add_part_key_word(File fptr, const char *key_string)
-{
- int err= add_string(fptr, key_string);
- err+= add_space(fptr);
- return err;
-}
-
-static int add_partition(File fptr)
-{
- char buff[22];
- strxmov(buff, part_str, space_str, NullS);
- return add_string(fptr, buff);
-}
-
-static int add_subpartition(File fptr)
-{
- int err= add_string(fptr, sub_str);
-
- return err + add_partition(fptr);
-}
-
-static int add_partition_by(File fptr)
-{
- char buff[22];
- strxmov(buff, part_str, space_str, by_str, space_str, NullS);
- return add_string(fptr, buff);
-}
-
-static int add_subpartition_by(File fptr)
-{
- int err= add_string(fptr, sub_str);
-
- return err + add_partition_by(fptr);
-}
-
-static int add_name_string(File fptr, const char *name)
-{
- int err;
- String name_string("", 0, system_charset_info);
- THD *thd= current_thd;
- ulonglong save_sql_mode= thd->variables.sql_mode;
- thd->variables.sql_mode&= ~MODE_ANSI_QUOTES;
- ulonglong save_options= thd->variables.option_bits;
- thd->variables.option_bits&= ~OPTION_QUOTE_SHOW_CREATE;
- append_identifier(thd, &name_string, name, strlen(name));
- thd->variables.sql_mode= save_sql_mode;
- thd->variables.option_bits= save_options;
- err= add_string_object(fptr, &name_string);
- return err;
-}
-
-static int add_part_field_list(File fptr, List<char> field_list)
-{
- uint i, num_fields;
int err= 0;
-
+ const char *field_name;
List_iterator<char> part_it(field_list);
- num_fields= field_list.elements;
- i= 0;
- err+= add_begin_parenthesis(fptr);
- while (i < num_fields)
+
+ err+= str->append('(');
+ while ((field_name= part_it++))
{
- err+= add_name_string(fptr, part_it++);
- if (i != (num_fields-1))
- err+= add_comma(fptr);
- i++;
+ err+= append_identifier(thd, str, field_name, strlen(field_name));
+ err+= str->append(',');
}
- err+= add_end_parenthesis(fptr);
+ if (field_list.elements)
+ str->length(str->length()-1);
+ err+= str->append(')');
return err;
}
-static int add_int(File fptr, longlong number)
-{
- char buff[32];
- llstr(number, buff);
- return add_string(fptr, buff);
-}
-
-static int add_uint(File fptr, ulonglong number)
-{
- char buff[32];
- longlong2str(number, buff, 10);
- return add_string(fptr, buff);
-}
-
/*
Must escape strings in partitioned tables frm-files,
parsing it later with mysql_unpack_partition will fail otherwise.
*/
-static int add_quoted_string(File fptr, const char *quotestr)
+
+static int add_keyword_string(String *str, const char *keyword,
+ bool quoted, const char *keystr)
{
- String escapedstr;
- int err= add_string(fptr, "'");
- err+= escapedstr.append_for_single_quote(quotestr);
- err+= add_string(fptr, escapedstr.c_ptr_safe());
- return err + add_string(fptr, "'");
+ int err= str->append(' ');
+ err+= str->append(keyword);
+
+ str->append(STRING_WITH_LEN(" = "));
+ if (quoted)
+ {
+ err+= str->append('\'');
+ err+= str->append_for_single_quote(keystr);
+ err+= str->append('\'');
+ }
+ else
+ err+= str->append(keystr);
+ return err;
}
+
/**
@brief Truncate the partition file name from a path it it exists.
@@ -1966,7 +1817,6 @@ void truncate_partition_filename(char *path)
}
}
-
/**
@brief Output a filepath. Similar to add_keyword_string except it
also converts \ to / on Windows and skips the partition file name at
@@ -1978,15 +1828,9 @@ table. So when the storage engine is asked for the DATA DIRECTORY string
after a restart through Handler::update_create_options(), the storage
engine may include the filename.
*/
-static int add_keyword_path(File fptr, const char *keyword,
+static int add_keyword_path(String *str, const char *keyword,
const char *path)
{
- int err= add_string(fptr, keyword);
-
- err+= add_space(fptr);
- err+= add_equal(fptr);
- err+= add_space(fptr);
-
char temp_path[FN_REFLEN];
strcpy(temp_path, path);
#ifdef __WIN__
@@ -2006,73 +1850,44 @@ static int add_keyword_path(File fptr, const char *keyword,
*/
truncate_partition_filename(temp_path);
- err+= add_quoted_string(fptr, temp_path);
-
- return err + add_space(fptr);
+ return add_keyword_string(str, keyword, true, temp_path);
}
-static int add_keyword_string(File fptr, const char *keyword,
- bool should_use_quotes,
- const char *keystr)
+static int add_keyword_int(String *str, const char *keyword, longlong num)
{
- int err= add_string(fptr, keyword);
-
- err+= add_space(fptr);
- err+= add_equal(fptr);
- err+= add_space(fptr);
- if (should_use_quotes)
- err+= add_quoted_string(fptr, keystr);
- else
- err+= add_string(fptr, keystr);
- return err + add_space(fptr);
-}
-
-static int add_keyword_int(File fptr, const char *keyword, longlong num)
-{
- int err= add_string(fptr, keyword);
-
- err+= add_space(fptr);
- err+= add_equal(fptr);
- err+= add_space(fptr);
- err+= add_int(fptr, num);
- return err + add_space(fptr);
+ int err= str->append(' ');
+ err+= str->append(keyword);
+ str->append(STRING_WITH_LEN(" = "));
+ return err + str->append_longlong(num);
}
-static int add_engine(File fptr, handlerton *engine_type)
-{
- const char *engine_str= ha_resolve_storage_engine_name(engine_type);
- DBUG_PRINT("info", ("ENGINE: %s", engine_str));
- int err= add_string(fptr, "ENGINE = ");
- return err + add_string(fptr, engine_str);
-}
-
-static int add_partition_options(File fptr, partition_element *p_elem)
+static int add_partition_options(String *str, partition_element *p_elem)
{
int err= 0;
- err+= add_space(fptr);
if (p_elem->tablespace_name)
- err+= add_keyword_string(fptr,"TABLESPACE", FALSE,
- p_elem->tablespace_name);
+ err+= add_keyword_string(str,"TABLESPACE", false, p_elem->tablespace_name);
if (p_elem->nodegroup_id != UNDEF_NODEGROUP)
- err+= add_keyword_int(fptr,"NODEGROUP",(longlong)p_elem->nodegroup_id);
+ err+= add_keyword_int(str,"NODEGROUP",(longlong)p_elem->nodegroup_id);
if (p_elem->part_max_rows)
- err+= add_keyword_int(fptr,"MAX_ROWS",(longlong)p_elem->part_max_rows);
+ err+= add_keyword_int(str,"MAX_ROWS",(longlong)p_elem->part_max_rows);
if (p_elem->part_min_rows)
- err+= add_keyword_int(fptr,"MIN_ROWS",(longlong)p_elem->part_min_rows);
+ err+= add_keyword_int(str,"MIN_ROWS",(longlong)p_elem->part_min_rows);
if (!(current_thd->variables.sql_mode & MODE_NO_DIR_IN_CREATE))
{
if (p_elem->data_file_name)
- err+= add_keyword_path(fptr, "DATA DIRECTORY", p_elem->data_file_name);
+ err+= add_keyword_path(str, "DATA DIRECTORY", p_elem->data_file_name);
if (p_elem->index_file_name)
- err+= add_keyword_path(fptr, "INDEX DIRECTORY", p_elem->index_file_name);
+ err+= add_keyword_path(str, "INDEX DIRECTORY", p_elem->index_file_name);
}
if (p_elem->part_comment)
- err+= add_keyword_string(fptr, "COMMENT", TRUE, p_elem->part_comment);
+ err+= add_keyword_string(str, "COMMENT", true, p_elem->part_comment);
if (p_elem->connect_string.length)
- err+= add_keyword_string(fptr, "CONNECTION", TRUE,
+ err+= add_keyword_string(str, "CONNECTION", true,
p_elem->connect_string.str);
- return err + add_engine(fptr,p_elem->engine_type);
+ err += add_keyword_string(str, "ENGINE", false,
+ ha_resolve_storage_engine_name(p_elem->engine_type));
+ return err;
}
@@ -2183,7 +1998,7 @@ static Create_field* get_sql_field(char *field_name,
}
-static int add_column_list_values(File fptr, partition_info *part_info,
+static int add_column_list_values(String *str, partition_info *part_info,
part_elem_value *list_value,
HA_CREATE_INFO *create_info,
Alter_info *alter_info)
@@ -2196,25 +2011,22 @@ static int add_column_list_values(File fptr, partition_info *part_info,
part_info->num_columns > 1U);
if (use_parenthesis)
- err+= add_begin_parenthesis(fptr);
+ err+= str->append('(');
for (i= 0; i < num_elements; i++)
{
part_column_list_val *col_val= &list_value->col_val_array[i];
char *field_name= it++;
if (col_val->max_value)
- err+= add_string(fptr, partition_keywords[PKW_MAXVALUE].str);
+ err+= str->append(STRING_WITH_LEN("MAXVALUE"));
else if (col_val->null_value)
- err+= add_string(fptr, "NULL");
+ err+= str->append(STRING_WITH_LEN("NULL"));
else
{
- char buffer[MAX_KEY_LENGTH];
- String str(buffer, sizeof(buffer), &my_charset_bin);
Item *item_expr= col_val->item_expression;
if (item_expr->null_value)
- err+= add_string(fptr, "NULL");
+ err+= str->append(STRING_WITH_LEN("NULL"));
else
{
- String *res;
CHARSET_INFO *field_cs;
bool need_cs_check= FALSE;
Item_result result_type= STRING_RESULT;
@@ -2275,27 +2087,28 @@ static int add_column_list_values(File fptr, partition_info *part_info,
}
}
{
- String val_conv;
+ StringBuffer<MAX_KEY_LENGTH> buf;
+ String val_conv, *res;
val_conv.set_charset(system_charset_info);
- res= item_expr->val_str(&str);
+ res= item_expr->val_str(&buf);
if (get_cs_converted_part_value_from_string(current_thd,
item_expr, res,
&val_conv, field_cs,
(bool)(alter_info != NULL)))
return 1;
- err+= add_string_object(fptr, &val_conv);
+ err+= str->append(val_conv);
}
}
}
if (i != (num_elements - 1))
- err+= add_string(fptr, comma_str);
+ err+= str->append(',');
}
if (use_parenthesis)
- err+= add_end_parenthesis(fptr);
+ err+= str->append(')');
return err;
}
-static int add_partition_values(File fptr, partition_info *part_info,
+static int add_partition_values(String *str, partition_info *part_info,
partition_element *p_elem,
HA_CREATE_INFO *create_info,
Alter_info *alter_info)
@@ -2304,48 +2117,57 @@ static int add_partition_values(File fptr, partition_info *part_info,
if (part_info->part_type == RANGE_PARTITION)
{
- err+= add_string(fptr, " VALUES LESS THAN ");
+ err+= str->append(STRING_WITH_LEN(" VALUES LESS THAN "));
if (part_info->column_list)
{
List_iterator<part_elem_value> list_val_it(p_elem->list_val_list);
part_elem_value *list_value= list_val_it++;
- err+= add_begin_parenthesis(fptr);
- err+= add_column_list_values(fptr, part_info, list_value,
+ err+= str->append('(');
+ err+= add_column_list_values(str, part_info, list_value,
create_info, alter_info);
- err+= add_end_parenthesis(fptr);
+ err+= str->append(')');
}
else
{
if (!p_elem->max_value)
{
- err+= add_begin_parenthesis(fptr);
+ err+= str->append('(');
if (p_elem->signed_flag)
- err+= add_int(fptr, p_elem->range_value);
+ err+= str->append_longlong(p_elem->range_value);
else
- err+= add_uint(fptr, p_elem->range_value);
- err+= add_end_parenthesis(fptr);
+ err+= str->append_ulonglong(p_elem->range_value);
+ err+= str->append(')');
}
else
- err+= add_string(fptr, partition_keywords[PKW_MAXVALUE].str);
+ err+= str->append(STRING_WITH_LEN("MAXVALUE"));
}
}
else if (part_info->part_type == LIST_PARTITION)
{
uint i;
List_iterator<part_elem_value> list_val_it(p_elem->list_val_list);
- err+= add_string(fptr, " VALUES IN ");
+
+ if (p_elem->max_value)
+ {
+ DBUG_ASSERT(part_info->defined_max_value ||
+ current_thd->lex->sql_command == SQLCOM_ALTER_TABLE);
+ err+= str->append(STRING_WITH_LEN(" DEFAULT"));
+ return err;
+ }
+
+ err+= str->append(STRING_WITH_LEN(" VALUES IN "));
uint num_items= p_elem->list_val_list.elements;
- err+= add_begin_parenthesis(fptr);
+ err+= str->append('(');
if (p_elem->has_null_value)
{
- err+= add_string(fptr, "NULL");
+ err+= str->append(STRING_WITH_LEN("NULL"));
if (num_items == 0)
{
- err+= add_end_parenthesis(fptr);
+ err+= str->append(')');
goto end;
}
- err+= add_comma(fptr);
+ err+= str->append(',');
}
i= 0;
do
@@ -2353,19 +2175,19 @@ static int add_partition_values(File fptr, partition_info *part_info,
part_elem_value *list_value= list_val_it++;
if (part_info->column_list)
- err+= add_column_list_values(fptr, part_info, list_value,
+ err+= add_column_list_values(str, part_info, list_value,
create_info, alter_info);
else
{
if (!list_value->unsigned_flag)
- err+= add_int(fptr, list_value->value);
+ err+= str->append_longlong(list_value->value);
else
- err+= add_uint(fptr, list_value->value);
+ err+= str->append_ulonglong(list_value->value);
}
if (i != (num_items-1))
- err+= add_comma(fptr);
+ err+= str->append(',');
} while (++i < num_items);
- err+= add_end_parenthesis(fptr);
+ err+= str->append(')');
}
end:
return err;
@@ -2375,53 +2197,40 @@ end:
/**
Add 'KEY' word, with optional 'ALGORTIHM = N'.
- @param fptr File to write to.
+ @param str String to write to.
@param part_info partition_info holding the used key_algorithm
- @param current_comment_start NULL, or comment string encapsulating the
- PARTITION BY clause.
@return Operation status.
@retval 0 Success
@retval != 0 Failure
*/
-static int add_key_with_algorithm(File fptr, partition_info *part_info,
- const char *current_comment_start)
+static int add_key_with_algorithm(String *str, partition_info *part_info)
{
int err= 0;
- err+= add_part_key_word(fptr, partition_keywords[PKW_KEY].str);
+ err+= str->append(STRING_WITH_LEN("KEY "));
- /*
- current_comment_start is given when called from SHOW CREATE TABLE,
- Then only add ALGORITHM = 1, not the default 2 or non-set 0!
- For .frm current_comment_start is NULL, then add ALGORITHM if != 0.
- */
- if (part_info->key_algorithm == partition_info::KEY_ALGORITHM_51 || // SHOW
- (!current_comment_start && // .frm
- (part_info->key_algorithm != partition_info::KEY_ALGORITHM_NONE)))
- {
- /* If we already are within a comment, end that comment first. */
- if (current_comment_start)
- err+= add_string(fptr, "*/ ");
- err+= add_string(fptr, "/*!50611 ");
- err+= add_part_key_word(fptr, partition_keywords[PKW_ALGORITHM].str);
- err+= add_equal(fptr);
- err+= add_space(fptr);
- err+= add_int(fptr, part_info->key_algorithm);
- err+= add_space(fptr);
- err+= add_string(fptr, "*/ ");
- if (current_comment_start)
- {
- /* Skip new line. */
- if (current_comment_start[0] == '\n')
- current_comment_start++;
- err+= add_string(fptr, current_comment_start);
- err+= add_space(fptr);
- }
+ if (part_info->key_algorithm == partition_info::KEY_ALGORITHM_51)
+ {
+ err+= str->append(STRING_WITH_LEN("ALGORITHM = "));
+ err+= str->append_longlong(part_info->key_algorithm);
+ err+= str->append(' ');
}
return err;
}
+char *generate_partition_syntax_for_frm(THD *thd, partition_info *part_info,
+ uint *buf_length,
+ HA_CREATE_INFO *create_info,
+ Alter_info *alter_info)
+{
+ sql_mode_t old_mode= thd->variables.sql_mode;
+ thd->variables.sql_mode &= ~MODE_ANSI_QUOTES;
+ char *res= generate_partition_syntax(thd, part_info, buf_length,
+ true, create_info, alter_info);
+ thd->variables.sql_mode= old_mode;
+ return res;
+}
/*
Generate the partition syntax from the partition data structure.
@@ -2432,8 +2241,6 @@ static int add_key_with_algorithm(File fptr, partition_info *part_info,
generate_partition_syntax()
part_info The partitioning data structure
buf_length A pointer to the returned buffer length
- use_sql_alloc Allocate buffer from sql_alloc if true
- otherwise use my_malloc
show_partition_options Should we display partition options
create_info Info generated by parser
alter_info Info generated by parser
@@ -2450,64 +2257,42 @@ static int add_key_with_algorithm(File fptr, partition_info *part_info,
type ALTER TABLE commands focusing on changing the PARTITION structure
in any fashion.
- The implementation writes the syntax to a temporary file (essentially
- an abstraction of a dynamic array) and if all writes goes well it
- allocates a buffer and writes the syntax into this one and returns it.
-
- As a security precaution the file is deleted before writing into it. This
- means that no other processes on the machine can open and read the file
- while this processing is ongoing.
-
The code is optimised for minimal code size since it is not used in any
common queries.
*/
-char *generate_partition_syntax(partition_info *part_info,
+char *generate_partition_syntax(THD *thd, partition_info *part_info,
uint *buf_length,
- bool use_sql_alloc,
bool show_partition_options,
HA_CREATE_INFO *create_info,
- Alter_info *alter_info,
- const char *current_comment_start)
+ Alter_info *alter_info)
{
uint i,j, tot_num_parts, num_subparts;
partition_element *part_elem;
- ulonglong buffer_length;
- char path[FN_REFLEN];
int err= 0;
List_iterator<partition_element> part_it(part_info->partitions);
- File fptr;
- char *buf= NULL; //Return buffer
+ StringBuffer<1024> str;
DBUG_ENTER("generate_partition_syntax");
- if (unlikely(((fptr= create_temp_file(path,mysql_tmpdir,"psy",
- O_RDWR | O_BINARY | O_TRUNC |
- O_TEMPORARY, MYF(MY_WME)))) < 0))
- DBUG_RETURN(NULL);
-#ifndef __WIN__
- unlink(path);
-#endif
- err+= add_space(fptr);
- err+= add_partition_by(fptr);
+ err+= str.append(STRING_WITH_LEN(" PARTITION BY "));
switch (part_info->part_type)
{
case RANGE_PARTITION:
- err+= add_part_key_word(fptr, partition_keywords[PKW_RANGE].str);
+ err+= str.append(STRING_WITH_LEN("RANGE "));
break;
case LIST_PARTITION:
- err+= add_part_key_word(fptr, partition_keywords[PKW_LIST].str);
+ err+= str.append(STRING_WITH_LEN("LIST "));
break;
case HASH_PARTITION:
if (part_info->linear_hash_ind)
- err+= add_string(fptr, partition_keywords[PKW_LINEAR].str);
+ err+= str.append(STRING_WITH_LEN("LINEAR "));
if (part_info->list_of_part_fields)
{
- err+= add_key_with_algorithm(fptr, part_info,
- current_comment_start);
- err+= add_part_field_list(fptr, part_info->part_field_list);
+ err+= add_key_with_algorithm(&str, part_info);
+ err+= add_part_field_list(thd, &str, part_info->part_field_list);
}
else
- err+= add_part_key_word(fptr, partition_keywords[PKW_HASH].str);
+ err+= str.append(STRING_WITH_LEN("HASH "));
break;
default:
DBUG_ASSERT(0);
@@ -2517,51 +2302,45 @@ char *generate_partition_syntax(partition_info *part_info,
}
if (part_info->part_expr)
{
- err+= add_begin_parenthesis(fptr);
- err+= add_string_len(fptr, part_info->part_func_string,
- part_info->part_func_len);
- err+= add_end_parenthesis(fptr);
+ err+= str.append('(');
+ part_info->part_expr->print_for_table_def(&str);
+ err+= str.append(')');
}
else if (part_info->column_list)
{
- err+= add_string(fptr, partition_keywords[PKW_COLUMNS].str);
- err+= add_part_field_list(fptr, part_info->part_field_list);
+ err+= str.append(STRING_WITH_LEN(" COLUMNS"));
+ err+= add_part_field_list(thd, &str, part_info->part_field_list);
}
if ((!part_info->use_default_num_partitions) &&
part_info->use_default_partitions)
{
- err+= add_string(fptr, "\n");
- err+= add_string(fptr, "PARTITIONS ");
- err+= add_int(fptr, part_info->num_parts);
+ err+= str.append(STRING_WITH_LEN("\nPARTITIONS "));
+ err+= str.append_ulonglong(part_info->num_parts);
}
if (part_info->is_sub_partitioned())
{
- err+= add_string(fptr, "\n");
- err+= add_subpartition_by(fptr);
+ err+= str.append(STRING_WITH_LEN("\nSUBPARTITION BY "));
/* Must be hash partitioning for subpartitioning */
if (part_info->linear_hash_ind)
- err+= add_string(fptr, partition_keywords[PKW_LINEAR].str);
+ err+= str.append(STRING_WITH_LEN("LINEAR "));
if (part_info->list_of_subpart_fields)
{
- err+= add_key_with_algorithm(fptr, part_info,
- current_comment_start);
- err+= add_part_field_list(fptr, part_info->subpart_field_list);
+ err+= add_key_with_algorithm(&str, part_info);
+ err+= add_part_field_list(thd, &str, part_info->subpart_field_list);
}
else
- err+= add_part_key_word(fptr, partition_keywords[PKW_HASH].str);
+ err+= str.append(STRING_WITH_LEN("HASH "));
if (part_info->subpart_expr)
{
- err+= add_begin_parenthesis(fptr);
- err+= add_string_len(fptr, part_info->subpart_func_string,
- part_info->subpart_func_len);
- err+= add_end_parenthesis(fptr);
+ err+= str.append('(');
+ part_info->subpart_expr->print_for_table_def(&str);
+ err+= str.append(')');
}
if ((!part_info->use_default_num_subpartitions) &&
part_info->use_default_subpartitions)
{
- err+= add_string(fptr, "\n");
- err+= add_string(fptr, "SUBPARTITIONS ");
- err+= add_int(fptr, part_info->num_subparts);
+ err+= str.append(STRING_WITH_LEN("\nSUBPARTITIONS "));
+ err+= str.append_ulonglong(part_info->num_subparts);
}
}
tot_num_parts= part_info->partitions.elements;
@@ -2570,8 +2349,7 @@ char *generate_partition_syntax(partition_info *part_info,
if (!part_info->use_default_partitions)
{
bool first= TRUE;
- err+= add_string(fptr, "\n");
- err+= add_begin_parenthesis(fptr);
+ err+= str.append(STRING_WITH_LEN("\n("));
i= 0;
do
{
@@ -2580,80 +2358,47 @@ char *generate_partition_syntax(partition_info *part_info,
part_elem->part_state != PART_REORGED_DROPPED)
{
if (!first)
- {
- err+= add_comma(fptr);
- err+= add_string(fptr, "\n");
- err+= add_space(fptr);
- }
+ err+= str.append(STRING_WITH_LEN(",\n "));
first= FALSE;
- err+= add_partition(fptr);
- err+= add_name_string(fptr, part_elem->partition_name);
- err+= add_partition_values(fptr, part_info, part_elem,
+ err+= str.append(STRING_WITH_LEN("PARTITION "));
+ err+= append_identifier(thd, &str, part_elem->partition_name,
+ strlen(part_elem->partition_name));
+ err+= add_partition_values(&str, part_info, part_elem,
create_info, alter_info);
if (!part_info->is_sub_partitioned() ||
part_info->use_default_subpartitions)
{
if (show_partition_options)
- err+= add_partition_options(fptr, part_elem);
+ err+= add_partition_options(&str, part_elem);
}
else
{
- err+= add_string(fptr, "\n");
- err+= add_space(fptr);
- err+= add_begin_parenthesis(fptr);
+ err+= str.append(STRING_WITH_LEN("\n ("));
List_iterator<partition_element> sub_it(part_elem->subpartitions);
j= 0;
do
{
part_elem= sub_it++;
- err+= add_subpartition(fptr);
- err+= add_name_string(fptr, part_elem->partition_name);
+ err+= str.append(STRING_WITH_LEN("SUBPARTITION "));
+ err+= append_identifier(thd, &str, part_elem->partition_name,
+ strlen(part_elem->partition_name));
if (show_partition_options)
- err+= add_partition_options(fptr, part_elem);
+ err+= add_partition_options(&str, part_elem);
if (j != (num_subparts-1))
- {
- err+= add_comma(fptr);
- err+= add_string(fptr, "\n");
- err+= add_space(fptr);
- err+= add_space(fptr);
- }
+ err+= str.append(STRING_WITH_LEN(",\n "));
else
- err+= add_end_parenthesis(fptr);
+ err+= str.append(')');
} while (++j < num_subparts);
}
}
if (i == (tot_num_parts-1))
- err+= add_end_parenthesis(fptr);
+ err+= str.append(')');
} while (++i < tot_num_parts);
}
if (err)
- goto close_file;
- buffer_length= mysql_file_seek(fptr, 0L, MY_SEEK_END, MYF(0));
- if (unlikely(buffer_length == MY_FILEPOS_ERROR))
- goto close_file;
- if (unlikely(mysql_file_seek(fptr, 0L, MY_SEEK_SET, MYF(0))
- == MY_FILEPOS_ERROR))
- goto close_file;
- *buf_length= (uint)buffer_length;
- if (use_sql_alloc)
- buf= (char*) sql_alloc(*buf_length+1);
- else
- buf= (char*) my_malloc(*buf_length+1, MYF(MY_WME));
- if (!buf)
- goto close_file;
-
- if (unlikely(mysql_file_read(fptr, (uchar*)buf, *buf_length, MYF(MY_FNABP))))
- {
- if (!use_sql_alloc)
- my_free(buf);
- buf= NULL;
- }
- else
- buf[*buf_length]= 0;
-
-close_file:
- mysql_file_close(fptr, MYF(0));
- DBUG_RETURN(buf);
+ DBUG_RETURN(NULL);
+ *buf_length= str.length();
+ DBUG_RETURN(thd->strmake(str.ptr(), str.length()));
}
@@ -3092,6 +2837,11 @@ int get_partition_id_list_col(partition_info *part_info,
}
}
notfound:
+ if (part_info->defined_max_value)
+ {
+ *part_id= part_info->default_partition_id;
+ DBUG_RETURN(0);
+ }
*part_id= 0;
DBUG_RETURN(HA_ERR_NO_PARTITION_FOUND);
}
@@ -3145,6 +2895,11 @@ int get_partition_id_list(partition_info *part_info,
}
}
notfound:
+ if (part_info->defined_max_value)
+ {
+ *part_id= part_info->default_partition_id;
+ DBUG_RETURN(0);
+ }
*part_id= 0;
DBUG_RETURN(HA_ERR_NO_PARTITION_FOUND);
}
@@ -3790,9 +3545,9 @@ static int get_sub_part_id_from_key(const TABLE *table,uchar *buf,
else
{
Field **part_field_array= part_info->subpart_field_array;
- set_field_ptr(part_field_array, buf, rec0);
+ part_info->table->move_fields(part_field_array, buf, rec0);
res= part_info->get_subpartition_id(part_info, part_id);
- set_field_ptr(part_field_array, rec0, buf);
+ part_info->table->move_fields(part_field_array, rec0, buf);
}
DBUG_RETURN(res);
}
@@ -3836,10 +3591,10 @@ bool get_part_id_from_key(const TABLE *table, uchar *buf, KEY *key_info,
else
{
Field **part_field_array= part_info->part_field_array;
- set_field_ptr(part_field_array, buf, rec0);
+ part_info->table->move_fields(part_field_array, buf, rec0);
result= part_info->get_part_partition_id(part_info, part_id,
&func_value);
- set_field_ptr(part_field_array, rec0, buf);
+ part_info->table->move_fields(part_field_array, rec0, buf);
}
DBUG_RETURN(result);
}
@@ -3885,10 +3640,10 @@ void get_full_part_id_from_key(const TABLE *table, uchar *buf,
else
{
Field **part_field_array= part_info->full_part_field_array;
- set_field_ptr(part_field_array, buf, rec0);
+ part_info->table->move_fields(part_field_array, buf, rec0);
result= part_info->get_partition_id(part_info, &part_spec->start_part,
&func_value);
- set_field_ptr(part_field_array, rec0, buf);
+ part_info->table->move_fields(part_field_array, rec0, buf);
}
part_spec->end_part= part_spec->start_part;
if (unlikely(result))
@@ -3938,7 +3693,7 @@ bool verify_data_with_partition(TABLE *table, TABLE *part_table,
bitmap_union(table->read_set, &part_info->full_part_field_set);
old_rec= part_table->record[0];
part_table->record[0]= table->record[0];
- set_field_ptr(part_info->full_part_field_array, table->record[0], old_rec);
+ part_info->table->move_fields(part_info->full_part_field_array, table->record[0], old_rec);
if ((error= file->ha_rnd_init(TRUE)))
{
file->print_error(error, MYF(0));
@@ -3973,7 +3728,7 @@ bool verify_data_with_partition(TABLE *table, TABLE *part_table,
} while (TRUE);
(void) file->ha_rnd_end();
err:
- set_field_ptr(part_info->full_part_field_array, old_rec,
+ part_info->table->move_fields(part_info->full_part_field_array, old_rec,
table->record[0]);
part_table->record[0]= old_rec;
if (error)
@@ -4374,39 +4129,6 @@ bool mysql_unpack_partition(THD *thd,
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);
-
- {
- /*
- This code part allocates memory for the serialised item information for
- the partition functions. In most cases this is not needed but if the
- table is used for SHOW CREATE TABLES or ALTER TABLE that modifies
- partition information it is needed and the info is lost if we don't
- save it here so unfortunately we have to do it here even if in most
- cases it is not needed. This is a consequence of that item trees are
- not serialisable.
- */
- uint part_func_len= part_info->part_func_len;
- uint subpart_func_len= part_info->subpart_func_len;
- char *part_func_string= NULL;
- char *subpart_func_string= NULL;
- if ((part_func_len &&
- !((part_func_string= (char*) thd->alloc(part_func_len)))) ||
- (subpart_func_len &&
- !((subpart_func_string= (char*) thd->alloc(subpart_func_len)))))
- {
- mem_alloc_error(part_func_len);
- thd->free_items();
- goto end;
- }
- if (part_func_len)
- memcpy(part_func_string, part_info->part_func_string, part_func_len);
- if (subpart_func_len)
- memcpy(subpart_func_string, part_info->subpart_func_string,
- subpart_func_len);
- part_info->part_func_string= part_func_string;
- part_info->subpart_func_string= subpart_func_string;
- }
-
result= FALSE;
end:
end_lex_with_single_table(thd, table, old_lex);
@@ -4772,13 +4494,31 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info,
DBUG_RETURN(TRUE);
}
+ partition_info *alt_part_info= thd->lex->part_info;
+ /*
+ This variable is TRUE in very special case when we add only DEFAULT
+ partition to the existing table
+ */
+ bool only_default_value_added=
+ (alt_part_info &&
+ alt_part_info->current_partition &&
+ alt_part_info->current_partition->list_val_list.elements == 1 &&
+ alt_part_info->current_partition->list_val_list.head()->
+ added_items >= 1 &&
+ alt_part_info->current_partition->list_val_list.head()->
+ col_val_array[0].max_value) &&
+ alt_part_info->part_type == LIST_PARTITION &&
+ (alter_info->flags & Alter_info::ALTER_ADD_PARTITION);
+ if (only_default_value_added &&
+ !thd->lex->part_info->num_columns)
+ thd->lex->part_info->num_columns= 1; // to make correct clone
+
/*
One of these is done in handle_if_exists_option():
thd->work_part_info= thd->lex->part_info;
or
thd->work_part_info= NULL;
*/
-
if (thd->work_part_info &&
!(thd->work_part_info= thd->work_part_info->get_clone(thd)))
DBUG_RETURN(TRUE);
@@ -4795,12 +4535,12 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info,
Alter_info::ALTER_REBUILD_PARTITION))
{
partition_info *tab_part_info;
- partition_info *alt_part_info= thd->work_part_info;
uint flags= 0;
bool is_last_partition_reorged= FALSE;
part_elem_value *tab_max_elem_val= NULL;
part_elem_value *alt_max_elem_val= NULL;
longlong tab_max_range= 0, alt_max_range= 0;
+ alt_part_info= thd->work_part_info;
if (!table->part_info)
{
@@ -4960,14 +4700,16 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info,
}
}
if ((tab_part_info->column_list &&
- alt_part_info->num_columns != tab_part_info->num_columns) ||
+ alt_part_info->num_columns != tab_part_info->num_columns &&
+ !only_default_value_added) ||
(!tab_part_info->column_list &&
(tab_part_info->part_type == RANGE_PARTITION ||
tab_part_info->part_type == LIST_PARTITION) &&
- alt_part_info->num_columns != 1U) ||
+ alt_part_info->num_columns != 1U &&
+ !only_default_value_added) ||
(!tab_part_info->column_list &&
tab_part_info->part_type == HASH_PARTITION &&
- alt_part_info->num_columns != 0))
+ (alt_part_info->num_columns != 0)))
{
my_error(ER_PARTITION_COLUMN_LIST_ERROR, MYF(0));
goto err;
@@ -5000,9 +4742,13 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info,
my_error(ER_NO_BINLOG_ERROR, MYF(0));
goto err;
}
- if (tab_part_info->defined_max_value)
+ if (tab_part_info->defined_max_value &&
+ (tab_part_info->part_type == RANGE_PARTITION ||
+ alt_part_info->defined_max_value))
{
- my_error(ER_PARTITION_MAXVALUE_ERROR, MYF(0));
+ my_error((tab_part_info->part_type == RANGE_PARTITION ?
+ ER_PARTITION_MAXVALUE_ERROR :
+ ER_PARTITION_DEFAULT_ERROR), MYF(0));
goto err;
}
if (num_new_partitions == 0)
@@ -5029,7 +4775,7 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info,
}
alt_part_info->part_type= tab_part_info->part_type;
alt_part_info->subpart_type= tab_part_info->subpart_type;
- if (alt_part_info->set_up_defaults_for_partitioning(table->file, 0,
+ if (alt_part_info->set_up_defaults_for_partitioning(thd, table->file, 0,
tab_part_info->num_parts))
{
goto err;
@@ -5221,7 +4967,7 @@ that are reorganised.
{
if (!alt_part_info->use_default_partitions)
{
- DBUG_PRINT("info", ("part_info: 0x%lx", (long) tab_part_info));
+ DBUG_PRINT("info", ("part_info: %p", tab_part_info));
tab_part_info->use_default_partitions= FALSE;
}
tab_part_info->use_default_num_partitions= FALSE;
@@ -5448,7 +5194,8 @@ state of p1.
DBUG_ASSERT(!alt_part_info->use_default_partitions);
/* We specified partitions explicitly so don't use defaults anymore. */
tab_part_info->use_default_partitions= FALSE;
- if (alt_part_info->set_up_defaults_for_partitioning(table->file, 0, 0))
+ if (alt_part_info->set_up_defaults_for_partitioning(thd, table->file, 0,
+ 0))
{
goto err;
}
@@ -6691,7 +6438,8 @@ void handle_alter_part_error(ALTER_PARTITION_PARAM_TYPE *lpt,
}
}
/* Ensure the share is destroyed and reopened. */
- part_info= lpt->part_info->get_clone(thd);
+ if (part_info)
+ part_info= part_info->get_clone(thd);
close_all_tables_for_name(thd, table->s, HA_EXTRA_NOT_USED, NULL);
}
else
@@ -6709,7 +6457,8 @@ err_exclusive_lock:
the table cache.
*/
mysql_lock_remove(thd, thd->lock, table);
- part_info= lpt->part_info->get_clone(thd);
+ if (part_info)
+ part_info= part_info->get_clone(thd);
close_thread_table(thd, &thd->open_tables);
lpt->table_list->table= NULL;
}
@@ -7249,39 +6998,6 @@ err:
}
#endif
-
-/*
- Prepare for calling val_int on partition function by setting fields to
- point to the record where the values of the PF-fields are stored.
-
- SYNOPSIS
- set_field_ptr()
- ptr Array of fields to change ptr
- new_buf New record pointer
- old_buf Old record pointer
-
- DESCRIPTION
- Set ptr in field objects of field array to refer to new_buf record
- instead of previously old_buf. Used before calling val_int and after
- it is used to restore pointers to table->record[0].
- This routine is placed outside of partition code since it can be useful
- also for other programs.
-*/
-
-void set_field_ptr(Field **ptr, const uchar *new_buf,
- const uchar *old_buf)
-{
- my_ptrdiff_t diff= (new_buf - old_buf);
- DBUG_ENTER("set_field_ptr");
-
- do
- {
- (*ptr)->move_field_offset(diff);
- } while (*(++ptr));
- DBUG_VOID_RETURN;
-}
-
-
/*
Prepare for calling val_int on partition function by setting fields to
point to the record where the values of the PF-fields are stored.
@@ -7760,8 +7476,10 @@ int get_part_iter_for_interval_cols_via_map(partition_info *part_info,
uint flags,
PARTITION_ITERATOR *part_iter)
{
+ bool can_match_multiple_values;
uint32 nparts;
get_col_endpoint_func UNINIT_VAR(get_col_endpoint);
+ uint full_length= 0;
DBUG_ENTER("get_part_iter_for_interval_cols_via_map");
if (part_info->part_type == RANGE_PARTITION)
@@ -7771,6 +7489,9 @@ int get_part_iter_for_interval_cols_via_map(partition_info *part_info,
}
else if (part_info->part_type == LIST_PARTITION)
{
+ if (part_info->has_default_partititon() &&
+ part_info->num_parts == 1)
+ DBUG_RETURN(-1); //only DEFAULT partition
get_col_endpoint= get_partition_id_cols_list_for_endpoint;
part_iter->get_next= get_next_partition_id_list;
part_iter->part_info= part_info;
@@ -7779,6 +7500,19 @@ int get_part_iter_for_interval_cols_via_map(partition_info *part_info,
else
assert(0);
+ for (uint32 i= 0; i < part_info->num_columns; i++)
+ full_length+= store_length_array[i];
+
+ can_match_multiple_values= ((flags &
+ (NO_MIN_RANGE | NO_MAX_RANGE | NEAR_MIN |
+ NEAR_MAX)) ||
+ (min_len != max_len) ||
+ (min_len != full_length) ||
+ memcmp(min_value, max_value, min_len));
+ DBUG_ASSERT(can_match_multiple_values || (flags & EQ_RANGE) || flags == 0);
+ if (can_match_multiple_values && part_info->has_default_partititon())
+ part_iter->ret_default_part= part_iter->ret_default_part_orig= TRUE;
+
if (flags & NO_MIN_RANGE)
part_iter->part_nums.start= part_iter->part_nums.cur= 0;
else
@@ -7814,7 +7548,15 @@ int get_part_iter_for_interval_cols_via_map(partition_info *part_info,
nparts);
}
if (part_iter->part_nums.start == part_iter->part_nums.end)
+ {
+ // No matching partition found.
+ if (part_info->has_default_partititon())
+ {
+ part_iter->ret_default_part= part_iter->ret_default_part_orig= TRUE;
+ DBUG_RETURN(1);
+ }
DBUG_RETURN(0);
+ }
DBUG_RETURN(1);
}
@@ -7875,6 +7617,7 @@ int get_part_iter_for_interval_via_mapping(partition_info *part_info,
(void)min_len;
(void)max_len;
part_iter->ret_null_part= part_iter->ret_null_part_orig= FALSE;
+ part_iter->ret_default_part= part_iter->ret_default_part_orig= FALSE;
if (part_info->part_type == RANGE_PARTITION)
{
@@ -7911,8 +7654,13 @@ int get_part_iter_for_interval_via_mapping(partition_info *part_info,
else
MY_ASSERT_UNREACHABLE();
- can_match_multiple_values= (flags || !min_value || !max_value ||
+ can_match_multiple_values= ((flags &
+ (NO_MIN_RANGE | NO_MAX_RANGE | NEAR_MIN |
+ NEAR_MAX)) ||
memcmp(min_value, max_value, field_len));
+ DBUG_ASSERT(can_match_multiple_values || (flags & EQ_RANGE) || flags == 0);
+ if (can_match_multiple_values && part_info->has_default_partititon())
+ part_iter->ret_default_part= part_iter->ret_default_part_orig= TRUE;
if (can_match_multiple_values &&
(part_info->part_type == RANGE_PARTITION ||
part_info->has_null_value))
@@ -7942,6 +7690,12 @@ int get_part_iter_for_interval_via_mapping(partition_info *part_info,
{
/* The right bound is X <= NULL, i.e. it is a "X IS NULL" interval */
part_iter->part_nums.end= 0;
+ /*
+ It is something like select * from tbl where col IS NULL
+ and we have partition with NULL to catch it, so we do not need
+ DEFAULT partition
+ */
+ part_iter->ret_default_part= part_iter->ret_default_part_orig= FALSE;
DBUG_RETURN(1);
}
}
@@ -7965,8 +7719,19 @@ int get_part_iter_for_interval_via_mapping(partition_info *part_info,
/* col = x and F(x) = NULL -> only search NULL partition */
part_iter->part_nums.cur= part_iter->part_nums.start= 0;
part_iter->part_nums.end= 0;
- part_iter->ret_null_part= part_iter->ret_null_part_orig= TRUE;
- DBUG_RETURN(1);
+ /*
+ if NULL partition exists:
+ for RANGE it is the first partition (always exists);
+ for LIST should be indicator that it is present
+ */
+ if (part_info->part_type == RANGE_PARTITION ||
+ part_info->has_null_value)
+ {
+ part_iter->ret_null_part= part_iter->ret_null_part_orig= TRUE;
+ DBUG_RETURN(1);
+ }
+ // If no NULL partition look up in DEFAULT or there is no such value
+ goto not_found;
}
part_iter->part_nums.cur= part_iter->part_nums.start;
if (check_zero_dates && !part_info->part_expr->null_value)
@@ -7983,7 +7748,7 @@ int get_part_iter_for_interval_via_mapping(partition_info *part_info,
}
}
if (part_iter->part_nums.start == max_endpoint_val)
- DBUG_RETURN(0); /* No partitions */
+ goto not_found;
}
}
@@ -8020,9 +7785,17 @@ int get_part_iter_for_interval_via_mapping(partition_info *part_info,
}
if (part_iter->part_nums.start >= part_iter->part_nums.end &&
!part_iter->ret_null_part)
- DBUG_RETURN(0); /* No partitions */
+ goto not_found;
}
DBUG_RETURN(1); /* Ok, iterator initialized */
+
+not_found:
+ if (part_info->has_default_partititon())
+ {
+ part_iter->ret_default_part= part_iter->ret_default_part_orig= TRUE;
+ DBUG_RETURN(1);
+ }
+ DBUG_RETURN(0); /* No partitions */
}
@@ -8086,6 +7859,8 @@ int get_part_iter_for_interval_via_walking(partition_info *part_info,
(void)max_len;
part_iter->ret_null_part= part_iter->ret_null_part_orig= FALSE;
+ part_iter->ret_default_part= part_iter->ret_default_part_orig= FALSE;
+
if (is_subpart)
{
field= part_info->subpart_field_array[0];
@@ -8217,6 +7992,9 @@ uint32 get_next_partition_id_range(PARTITION_ITERATOR* part_iter)
part_iter->ret_null_part= FALSE;
return 0; /* NULL always in first range partition */
}
+ // we do not have default partition in RANGE partitioning
+ DBUG_ASSERT(!part_iter->ret_default_part);
+
part_iter->part_nums.cur= part_iter->part_nums.start;
part_iter->ret_null_part= part_iter->ret_null_part_orig;
return NOT_A_PARTITION_ID;
@@ -8254,8 +8032,15 @@ uint32 get_next_partition_id_list(PARTITION_ITERATOR *part_iter)
part_iter->ret_null_part= FALSE;
return part_iter->part_info->has_null_part_id;
}
+ if (part_iter->ret_default_part)
+ {
+ part_iter->ret_default_part= FALSE;
+ return part_iter->part_info->default_partition_id;
+ }
+ /* Reset partition for next read */
part_iter->part_nums.cur= part_iter->part_nums.start;
part_iter->ret_null_part= part_iter->ret_null_part_orig;
+ part_iter->ret_default_part= part_iter->ret_default_part_orig;
return NOT_A_PARTITION_ID;
}
else
@@ -8376,13 +8161,10 @@ int create_partition_name(char *out, size_t outlen, const char *in1,
end= strxnmov(out, outlen-1, in1, "#P#", transl_part, NullS);
else if (name_variant == TEMP_PART_NAME)
end= strxnmov(out, outlen-1, in1, "#P#", transl_part, "#TMP#", NullS);
- else if (name_variant == RENAMED_PART_NAME)
- end= strxnmov(out, outlen-1, in1, "#P#", transl_part, "#REN#", NullS);
else
{
- DBUG_ASSERT(0);
- out[0]= 0;
- end= out + (outlen-1);
+ DBUG_ASSERT(name_variant == RENAMED_PART_NAME);
+ end= strxnmov(out, outlen-1, in1, "#P#", transl_part, "#REN#", NullS);
}
if (end - out == static_cast<ptrdiff_t>(outlen-1))
{
@@ -8423,14 +8205,11 @@ int create_subpartition_name(char *out, size_t outlen,
else if (name_variant == TEMP_PART_NAME)
end= strxnmov(out, outlen-1, in1, "#P#", transl_part_name,
"#SP#", transl_subpart_name, "#TMP#", NullS);
- else if (name_variant == RENAMED_PART_NAME)
- end= strxnmov(out, outlen-1, in1, "#P#", transl_part_name,
- "#SP#", transl_subpart_name, "#REN#", NullS);
else
{
- DBUG_ASSERT(0);
- out[0]= 0;
- end= out + (outlen-1);
+ DBUG_ASSERT(name_variant == RENAMED_PART_NAME);
+ end= strxnmov(out, outlen-1, in1, "#P#", transl_part_name,
+ "#SP#", transl_subpart_name, "#REN#", NullS);
}
if (end - out == static_cast<ptrdiff_t>(outlen-1))
{