diff options
Diffstat (limited to 'sql/partition_info.cc')
-rw-r--r-- | sql/partition_info.cc | 156 |
1 files changed, 93 insertions, 63 deletions
diff --git a/sql/partition_info.cc b/sql/partition_info.cc index 4f297c630ad..de415237cf4 100644 --- a/sql/partition_info.cc +++ b/sql/partition_info.cc @@ -1503,21 +1503,15 @@ bool partition_info::check_list_constants(THD *thd) has_null_part_id= i; found_null= TRUE; } - List_iterator<part_elem_value> list_val_it1(part_def->list_val_list); - while (list_val_it1++) - num_list_values++; + num_list_values+= part_def->list_val_list.elements; } while (++i < num_parts); list_func_it.rewind(); num_column_values= part_field_list.elements; size_entries= column_list ? (num_column_values * sizeof(part_column_list_val)) : sizeof(LIST_PART_ENTRY); - ptr= thd->calloc((num_list_values+1) * size_entries); - if (unlikely(ptr == NULL)) - { - mem_alloc_error(num_list_values * size_entries); + if (unlikely(!(ptr= thd->calloc((num_list_values+1) * size_entries)))) goto end; - } if (column_list) { part_column_list_val *loc_list_col_array; @@ -1528,6 +1522,14 @@ bool partition_info::check_list_constants(THD *thd) do { part_def= list_func_it++; + if (part_def->max_value) + { + DBUG_ASSERT(part_type == LIST_PARTITION); + // DEFAULT is not a real value so let's exclude it from sorting. + DBUG_ASSERT(num_list_values); + num_list_values--; + continue; + } List_iterator<part_elem_value> list_val_it2(part_def->list_val_list); while ((list_value= list_val_it2++)) { @@ -1557,6 +1559,13 @@ bool partition_info::check_list_constants(THD *thd) do { part_def= list_func_it++; + if (part_def->max_value && part_type == LIST_PARTITION) + { + // DEFAULT is not a real value so let's exclude it from sorting. + DBUG_ASSERT(num_list_values); + num_list_values--; + continue; + } List_iterator<part_elem_value> list_val_it2(part_def->list_val_list); while ((list_value= list_val_it2++)) { @@ -2287,11 +2296,19 @@ int partition_info::add_max_value(THD *thd) DBUG_ENTER("partition_info::add_max_value"); part_column_list_val *col_val; - if (!(col_val= add_column_value(thd))) + /* + Makes for LIST COLUMNS 'num_columns' DEFAULT tuples, 1 tuple for RANGEs + */ + uint max_val= (num_columns && part_type == LIST_PARTITION) ? + num_columns : 1; + for (uint i= 0; i < max_val; i++) { - DBUG_RETURN(TRUE); + if (!(col_val= add_column_value(thd))) + { + DBUG_RETURN(TRUE); + } + col_val->max_value= TRUE; } - col_val->max_value= TRUE; DBUG_RETURN(FALSE); } @@ -2566,8 +2583,7 @@ int partition_info::reorganize_into_single_field_col_val(THD *thd) */ int partition_info::fix_partition_values(THD *thd, part_elem_value *val, - partition_element *part_elem, - uint part_id) + partition_element *part_elem) { part_column_list_val *col_val= val->col_val_array; DBUG_ENTER("partition_info::fix_partition_values"); @@ -2576,59 +2592,31 @@ int partition_info::fix_partition_values(THD *thd, { DBUG_RETURN(FALSE); } - if (val->added_items != 1) - { - my_error(ER_PARTITION_COLUMN_LIST_ERROR, MYF(0)); - DBUG_RETURN(TRUE); - } - if (col_val->max_value) + + Item *item_expr= col_val->item_expression; + if ((val->null_value= item_expr->null_value)) { - /* The parser ensures we're not LIST partitioned here */ - DBUG_ASSERT(part_type == RANGE_PARTITION); - if (defined_max_value) - { - my_error(ER_PARTITION_MAXVALUE_ERROR, MYF(0)); - DBUG_RETURN(TRUE); - } - if (part_id == (num_parts - 1)) - { - defined_max_value= TRUE; - part_elem->max_value= TRUE; - part_elem->range_value= LONGLONG_MAX; - } - else + if (part_elem->has_null_value) { - my_error(ER_PARTITION_MAXVALUE_ERROR, MYF(0)); + my_error(ER_MULTIPLE_DEF_CONST_IN_LIST_PART_ERROR, MYF(0)); DBUG_RETURN(TRUE); } + part_elem->has_null_value= TRUE; } - else + else if (item_expr->result_type() != INT_RESULT) { - Item *item_expr= col_val->item_expression; - if ((val->null_value= item_expr->null_value)) - { - if (part_elem->has_null_value) - { - my_error(ER_MULTIPLE_DEF_CONST_IN_LIST_PART_ERROR, MYF(0)); - DBUG_RETURN(TRUE); - } - part_elem->has_null_value= TRUE; - } - else if (item_expr->result_type() != INT_RESULT) + my_error(ER_VALUES_IS_NOT_INT_TYPE_ERROR, MYF(0), + part_elem->partition_name); + DBUG_RETURN(TRUE); + } + if (part_type == RANGE_PARTITION) + { + if (part_elem->has_null_value) { - my_error(ER_VALUES_IS_NOT_INT_TYPE_ERROR, MYF(0), - part_elem->partition_name); + my_error(ER_NULL_IN_VALUES_LESS_THAN, MYF(0)); DBUG_RETURN(TRUE); } - if (part_type == RANGE_PARTITION) - { - if (part_elem->has_null_value) - { - my_error(ER_NULL_IN_VALUES_LESS_THAN, MYF(0)); - DBUG_RETURN(TRUE); - } - part_elem->range_value= val->value; - } + part_elem->range_value= val->value; } col_val->fixed= 2; DBUG_RETURN(FALSE); @@ -2835,16 +2823,60 @@ bool partition_info::fix_parser_data(THD *thd) num_elements= part_elem->list_val_list.elements; DBUG_ASSERT(part_type == RANGE_PARTITION ? num_elements == 1U : TRUE); + for (j= 0; j < num_elements; j++) { part_elem_value *val= list_val_it++; - if (column_list) + + if (val->added_items != (column_list ? num_columns : 1)) { - if (val->added_items != num_columns) + my_error(ER_PARTITION_COLUMN_LIST_ERROR, MYF(0)); + DBUG_RETURN(TRUE); + } + + /* + Check the last MAX_VALUE for range partitions and DEFAULT value + for LIST partitions. + Both values are marked with defined_max_value and + default_partition_id. + + This is a max_value/default is max_value is set and this is + a normal RANGE (no column list) or if it's a LIST partition: + + PARTITION p3 VALUES LESS THAN MAXVALUE + or + PARTITION p3 VALUES DEFAULT + */ + if (val->added_items && val->col_val_array[0].max_value && + (!column_list || part_type == LIST_PARTITION)) + { + DBUG_ASSERT(part_type == RANGE_PARTITION || + part_type == LIST_PARTITION); + if (defined_max_value) + { + my_error((part_type == RANGE_PARTITION) ? + ER_PARTITION_MAXVALUE_ERROR : + ER_PARTITION_DEFAULT_ERROR, MYF(0)); + DBUG_RETURN(TRUE); + } + + /* For RANGE PARTITION MAX_VALUE must be last */ + if (i != (num_parts - 1) && + part_type != LIST_PARTITION) { - my_error(ER_PARTITION_COLUMN_LIST_ERROR, MYF(0)); + my_error(ER_PARTITION_MAXVALUE_ERROR, MYF(0)); DBUG_RETURN(TRUE); } + + defined_max_value= TRUE; + default_partition_id= i; + part_elem->max_value= TRUE; + part_elem->range_value= LONGLONG_MAX; + continue; + } + + if (column_list) + { for (k= 0; k < num_columns; k++) { part_column_list_val *col_val= &val->col_val_array[k]; @@ -2857,10 +2889,8 @@ bool partition_info::fix_parser_data(THD *thd) } else { - if (fix_partition_values(thd, val, part_elem, i)) - { + if (fix_partition_values(thd, val, part_elem)) DBUG_RETURN(TRUE); - } if (val->null_value) { /* |