summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorMikael Ronstrom <mikael@mysql.com>2009-10-21 12:40:21 +0200
committerMikael Ronstrom <mikael@mysql.com>2009-10-21 12:40:21 +0200
commitbbd922b09c94bafb18e583a00865750164358736 (patch)
treef8665cdbc5f804477667c1ef89f27f0de619b382 /sql
parentaaa79d9530e64bb092bb994312b7e490d16b9eef (diff)
downloadmariadb-git-bbd922b09c94bafb18e583a00865750164358736.tar.gz
Removed column_list and fixed all issues relating to this change
Diffstat (limited to 'sql')
-rw-r--r--sql/partition_info.cc213
-rw-r--r--sql/partition_info.h6
-rw-r--r--sql/sql_partition.cc85
-rw-r--r--sql/sql_yacc.yy36
4 files changed, 206 insertions, 134 deletions
diff --git a/sql/partition_info.cc b/sql/partition_info.cc
index 857ae765135..bdcac00dae9 100644
--- a/sql/partition_info.cc
+++ b/sql/partition_info.cc
@@ -1577,27 +1577,78 @@ part_column_list_val *partition_info::add_column_value()
}
DBUG_RETURN(NULL);
}
- my_error(ER_PARTITION_COLUMN_LIST_ERROR, MYF(0));
+ if (column_list)
+ {
+ my_error(ER_PARTITION_COLUMN_LIST_ERROR, MYF(0));
+ }
+ else
+ {
+ if (part_type == RANGE_PARTITION)
+ my_error(ER_TOO_MANY_VALUES_ERROR, MYF(0), "RANGE");
+ else
+ my_error(ER_TOO_MANY_VALUES_ERROR, MYF(0), "LIST");
+ }
DBUG_RETURN(NULL);
}
/*
+ Initialise part_elem_value object at setting of a new object
+ (Helper functions to functions called by parser)
+
+ SYNOPSIS
+ init_col_val
+ col_val Column value object to be initialised
+ item Item object representing column value
+
+ RETURN VALUES
+ TRUE Failure
+ FALSE Success
+*/
+void partition_info::init_col_val(part_column_list_val *col_val, Item *item)
+{
+ DBUG_ENTER("partition_info::init_col_val");
+
+ col_val->item_expression= item;
+ col_val->null_value= item->null_value;
+ if (item->result_type() == INT_RESULT)
+ {
+ /*
+ This could be both column_list partitioning and function
+ partitioning, but it doesn't hurt to set the function
+ partitioning flags about unsignedness.
+ */
+ curr_list_val->value= item->val_int();
+ curr_list_val->unsigned_flag= TRUE;
+ if (!item->unsigned_flag &&
+ curr_list_val->value < 0)
+ curr_list_val->unsigned_flag= FALSE;
+ if (!curr_list_val->unsigned_flag)
+ curr_part_elem->signed_flag= TRUE;
+ }
+ col_val->part_info= NULL;
+ DBUG_VOID_RETURN;
+}
+/*
Add a column value in VALUES LESS THAN or VALUES IN
(Called from parser)
SYNOPSIS
add_column_list_value()
lex Parser's lex object
+ thd Thread object
item Item object representing column value
RETURN VALUES
TRUE Failure
FALSE Success
*/
-bool partition_info::add_column_list_value(Item *item)
+bool partition_info::add_column_list_value(THD *thd, Item *item)
{
part_column_list_val *col_val;
+ Name_resolution_context *context= &thd->lex->current_select->context;
+ TABLE_LIST *save_list= context->table_list;
+ const char *save_where= thd->where;
DBUG_ENTER("partition_info::add_column_list_value");
if (part_type == LIST_PARTITION &&
@@ -1608,12 +1659,35 @@ bool partition_info::add_column_list_value(Item *item)
DBUG_RETURN(TRUE);
}
}
+
+ context->table_list= 0;
+ if (column_list)
+ thd->where= "field list";
+ else
+ thd->where= "partition function";
+
+ if (item->walk(&Item::check_partition_func_processor, 0,
+ NULL))
+ {
+ my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0));
+ DBUG_RETURN(TRUE);
+ }
+ if (item->fix_fields(thd, (Item**)0) ||
+ ((context->table_list= save_list), FALSE) ||
+ (!item->const_item()))
+ {
+ context->table_list= save_list;
+ thd->where= save_where;
+ my_error(ER_NO_CONST_EXPR_IN_RANGE_OR_LIST_ERROR, MYF(0));
+ DBUG_RETURN(TRUE);
+ }
+ thd->where= save_where;
+
if (!(col_val= add_column_value()))
{
DBUG_RETURN(TRUE);
}
- col_val->item_expression= item;
- col_val->part_info= NULL;
+ init_col_val(col_val, item);
DBUG_RETURN(FALSE);
}
@@ -1686,25 +1760,32 @@ bool partition_info::init_column_part()
*/
int partition_info::reorganize_into_single_field_col_val()
{
- part_column_list_val *col_val;
- Item *part_expr;
+ part_column_list_val *col_val, *new_col_val;
+ part_elem_value *val= curr_list_val;
uint loc_num_columns= num_columns;
uint i;
DBUG_ENTER("partition_info::reorganize_into_single_field_col_val");
num_columns= 1;
- curr_list_val->added_items= 1U;
+ val->added_items= 1U;
+ col_val= &val->col_val_array[0];
+ init_col_val(col_val, col_val->item_expression);
for (i= 1; i < loc_num_columns; i++)
{
- col_val= &curr_list_val->col_val_array[i];
- part_expr= col_val->item_expression;
- if ((part_type != LIST_PARTITION &&
- init_column_part()) ||
- add_column_list_value(part_expr))
+ col_val= &val->col_val_array[i];
+ DBUG_ASSERT(part_type == LIST_PARTITION);
+ if (init_column_part())
+ {
+ DBUG_RETURN(TRUE);
+ }
+ if (!(new_col_val= add_column_value()))
{
DBUG_RETURN(TRUE);
}
+ memcpy(new_col_val, col_val, sizeof(*col_val));
+ init_col_val(new_col_val, col_val->item_expression);
}
+ curr_list_val= val;
DBUG_RETURN(FALSE);
}
@@ -1719,6 +1800,7 @@ int partition_info::reorganize_into_single_field_col_val()
thd Thread object
col_val Array of one value
part_elem The partition instance
+ part_id Id of partition instance
RETURN VALUES
TRUE Failure
@@ -1726,9 +1808,9 @@ int partition_info::reorganize_into_single_field_col_val()
*/
int partition_info::fix_func_partition(THD *thd,
part_elem_value *val,
- partition_element *part_elem)
+ partition_element *part_elem,
+ uint part_id)
{
- uint i;
part_column_list_val *col_val= val->col_val_array;
DBUG_ENTER("partition_info::fix_func_partition");
@@ -1750,7 +1832,7 @@ int partition_info::fix_func_partition(THD *thd,
my_error(ER_PARTITION_MAXVALUE_ERROR, MYF(0));
DBUG_RETURN(TRUE);
}
- if (i == (num_parts - 1))
+ if (part_id == (num_parts - 1))
{
defined_max_value= TRUE;
part_elem->max_value= TRUE;
@@ -1764,43 +1846,8 @@ int partition_info::fix_func_partition(THD *thd,
}
else
{
- part_elem_value *value_ptr;
- Name_resolution_context *context= &thd->lex->current_select->context;
- TABLE_LIST *save_list= context->table_list;
- const char *save_where= thd->where;
Item *item_expr= col_val->item_expression;
-
- context->table_list= 0;
- thd->where= "partition function";
-
- value_ptr= (part_elem_value*)sql_alloc(sizeof(part_elem_value));
- if (!value_ptr)
- {
- mem_alloc_error(sizeof(part_elem_value));
- DBUG_RETURN(TRUE);
- }
- if (item_expr->walk(&Item::check_partition_func_processor, 0,
- NULL))
- {
- my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0));
- DBUG_RETURN(TRUE);
- }
- if (item_expr->fix_fields(thd, (Item**)0) ||
- ((context->table_list= save_list), FALSE) ||
- (!item_expr->const_item()))
- {
- context->table_list= save_list;
- thd->where= save_where;
- my_error(ER_NO_CONST_EXPR_IN_RANGE_OR_LIST_ERROR, MYF(0));
- DBUG_RETURN(TRUE);
- }
- thd->where= save_where;
- value_ptr->value= part_expr->val_int();
- value_ptr->unsigned_flag= TRUE;
- if (!item_expr->unsigned_flag &&
- value_ptr->value < 0)
- value_ptr->unsigned_flag= FALSE;
- if ((value_ptr->null_value= item_expr->null_value))
+ if ((val->null_value= item_expr->null_value))
{
if (part_elem->has_null_value)
{
@@ -1814,8 +1861,6 @@ int partition_info::fix_func_partition(THD *thd,
my_error(ER_INCONSISTENT_TYPE_OF_FUNCTIONS_ERROR, MYF(0));
DBUG_RETURN(TRUE);
}
- if (!value_ptr->unsigned_flag)
- part_elem->signed_flag= TRUE;
if (part_type == RANGE_PARTITION)
{
if (part_elem->has_null_value)
@@ -1823,16 +1868,7 @@ int partition_info::fix_func_partition(THD *thd,
my_error(ER_NULL_IN_VALUES_LESS_THAN, MYF(0));
DBUG_RETURN(TRUE);
}
- part_elem->range_value= value_ptr->value;
- }
- else if (part_type == LIST_PARTITION)
- {
- if (!value_ptr->null_value &&
- part_elem->list_val_list.push_back(value_ptr))
- {
- mem_alloc_error(sizeof(part_elem_value));
- DBUG_RETURN(TRUE);
- }
+ part_elem->range_value= val->value;
}
}
col_val->fixed= 2;
@@ -1860,11 +1896,8 @@ bool partition_info::fix_column_value_functions(THD *thd,
uint part_id)
{
uint num_columns= part_field_list.elements;
- Name_resolution_context *context= &thd->lex->current_select->context;
- TABLE_LIST *save_list= context->table_list;
bool result= FALSE;
uint i;
- const char *save_where= thd->where;
part_column_list_val *col_val= val->col_val_array;
DBUG_ENTER("partition_info::fix_column_value_functions");
@@ -1872,13 +1905,6 @@ bool partition_info::fix_column_value_functions(THD *thd,
{
DBUG_RETURN(FALSE);
}
- if (val->added_items != num_columns)
- {
- my_error(ER_PARTITION_COLUMN_LIST_ERROR, MYF(0));
- DBUG_RETURN(TRUE);
- }
- context->table_list= 0;
- thd->where= "partition function";
for (i= 0; i < num_columns; col_val++, i++)
{
Item *column_item= col_val->item_expression;
@@ -1889,15 +1915,6 @@ bool partition_info::fix_column_value_functions(THD *thd,
col_val->column_value= NULL;
else
{
- if (!col_val->fixed &&
- (column_item->fix_fields(thd, (Item**)0) ||
- (!column_item->const_item())))
- {
- my_error(ER_NO_CONST_EXPR_IN_RANGE_OR_LIST_ERROR, MYF(0));
- result= TRUE;
- goto end;
- }
- col_val->null_value= column_item->null_value;
col_val->column_value= NULL;
if (!col_val->null_value)
{
@@ -1922,8 +1939,6 @@ bool partition_info::fix_column_value_functions(THD *thd,
col_val->fixed= 2;
}
end:
- thd->where= save_where;
- context->table_list= save_list;
DBUG_RETURN(result);
}
@@ -1989,22 +2004,40 @@ int partition_info::fix_parser_data(THD *thd)
do
{
part_elem= it++;
+ List_iterator<part_elem_value> list_val_it(part_elem->list_val_list);
j= 0;
num_elements= part_elem->list_val_list.elements;
DBUG_ASSERT(part_type == RANGE_PARTITION ?
num_elements == 1U : TRUE);
+ do
{
- List_iterator<part_elem_value> list_val_it(part_elem->list_val_list);
part_elem_value *val= list_val_it++;
- result= column_list ?
- fix_column_value_functions(thd, val, i) :
- fix_func_partition(thd, val, part_elem);
- if (result)
+ if (column_list)
{
- DBUG_RETURN(TRUE);
+ if (val->added_items != num_columns)
+ {
+ my_error(ER_PARTITION_COLUMN_LIST_ERROR, MYF(0));
+ DBUG_RETURN(TRUE);
+ }
+ }
+ else
+ {
+ if (fix_func_partition(thd, val, part_elem, i))
+ {
+ DBUG_RETURN(TRUE);
+ }
+ if (val->null_value)
+ {
+ /*
+ Null values aren't required in the value part, they are kept per
+ partition instance, only LIST partitions have NULL values.
+ */
+ list_val_it.remove();
+ }
}
} while (++j < num_elements);
} while (++i < num_parts);
+ DBUG_RETURN(FALSE);
}
void partition_info::print_debug(const char *str, uint *value)
diff --git a/sql/partition_info.h b/sql/partition_info.h
index 16f3bff8016..2ed0289f656 100644
--- a/sql/partition_info.h
+++ b/sql/partition_info.h
@@ -283,12 +283,14 @@ public:
void print_debug(const char *str, uint*);
int fix_func_partition(THD *thd,
part_elem_value *val,
- partition_element *part_elem);
+ partition_element *part_elem,
+ uint part_id);
bool fix_column_value_functions(THD *thd,
part_elem_value *val,
uint part_id);
int fix_parser_data(THD *thd);
int add_max_value();
+ void init_col_val(part_column_list_val *col_val, Item *item);
int reorganize_into_single_field_col_val();
part_column_list_val *add_column_value();
bool set_part_expr(char *start_token, Item *item_ptr,
@@ -296,7 +298,7 @@ public:
static int compare_column_values(const void *a, const void *b);
bool set_up_charset_field_preps();
bool init_column_part();
- bool add_column_list_value(Item *item);
+ bool add_column_list_value(THD *thd, Item *item);
private:
static int list_part_cmp(const void* a, const void* b);
bool set_up_default_partitions(handler *file, HA_CREATE_INFO *info,
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index 0bd658f7861..690e690a833 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -2007,14 +2007,6 @@ static int add_column_list_values(File fptr, partition_info *part_info,
char buffer[MAX_STR_SIZE_PF];
String str(buffer, sizeof(buffer), &my_charset_bin);
Item *item_expr= col_val->item_expression;
- if (!col_val->fixed &&
- (item_expr->fix_fields(current_thd, (Item**)0) ||
- (!item_expr->const_item())))
- {
- my_error(ER_NO_CONST_EXPR_IN_RANGE_OR_LIST_ERROR, MYF(0));
- return 1;
- }
- col_val->fixed= 1;
if (item_expr->null_value)
err+= add_string(fptr, "NULL");
else
@@ -4340,38 +4332,63 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info,
if ((alter_info->flags & ALTER_ADD_PARTITION) ||
(alter_info->flags & ALTER_REORGANIZE_PARTITION))
{
- if ((tab_part_info->column_list &&
- alt_part_info->num_columns != tab_part_info->num_columns) ||
- (!tab_part_info->column_list && alt_part_info->num_columns))
+ if (thd->work_part_info->part_type != tab_part_info->part_type)
{
- my_error(ER_PARTITION_COLUMN_LIST_ERROR, MYF(0));
- DBUG_RETURN(TRUE);
- }
- if ((thd->work_part_info->part_type != tab_part_info->part_type) &&
- (thd->work_part_info->part_type != NOT_A_PARTITION))
- {
- if (thd->work_part_info->part_type == RANGE_PARTITION)
- {
- my_error(ER_PARTITION_WRONG_VALUES_ERROR, MYF(0),
- "RANGE", "LESS THAN");
- }
- else if (thd->work_part_info->part_type == LIST_PARTITION)
- {
- DBUG_ASSERT(thd->work_part_info->part_type == LIST_PARTITION);
- my_error(ER_PARTITION_WRONG_VALUES_ERROR, MYF(0),
- "LIST", "IN");
- }
- else if (tab_part_info->part_type == RANGE_PARTITION)
+ if (thd->work_part_info->part_type == NOT_A_PARTITION)
{
- my_error(ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0),
- "RANGE", "LESS THAN");
+ if (tab_part_info->part_type == RANGE_PARTITION)
+ {
+ my_error(ER_PARTITIONS_MUST_BE_DEFINED_ERROR, MYF(0), "RANGE");
+ DBUG_RETURN(TRUE);
+ }
+ else if (tab_part_info->part_type == LIST_PARTITION)
+ {
+ my_error(ER_PARTITIONS_MUST_BE_DEFINED_ERROR, MYF(0), "LIST");
+ DBUG_RETURN(TRUE);
+ }
+ /*
+ Hash partitions can be altered without parser finds out about
+ that it is HASH partitioned. So no error here.
+ */
}
else
{
- DBUG_ASSERT(tab_part_info->part_type == LIST_PARTITION);
- my_error(ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0),
- "LIST", "IN");
+ if (thd->work_part_info->part_type == RANGE_PARTITION)
+ {
+ my_error(ER_PARTITION_WRONG_VALUES_ERROR, MYF(0),
+ "RANGE", "LESS THAN");
+ }
+ else if (thd->work_part_info->part_type == LIST_PARTITION)
+ {
+ DBUG_ASSERT(thd->work_part_info->part_type == LIST_PARTITION);
+ my_error(ER_PARTITION_WRONG_VALUES_ERROR, MYF(0),
+ "LIST", "IN");
+ }
+ else if (tab_part_info->part_type == RANGE_PARTITION)
+ {
+ my_error(ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0),
+ "RANGE", "LESS THAN");
+ }
+ else
+ {
+ DBUG_ASSERT(tab_part_info->part_type == LIST_PARTITION);
+ my_error(ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0),
+ "LIST", "IN");
+ }
+ DBUG_RETURN(TRUE);
}
+ }
+ if ((tab_part_info->column_list &&
+ alt_part_info->num_columns != tab_part_info->num_columns) ||
+ (!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) ||
+ (!tab_part_info->column_list &&
+ tab_part_info->part_type == HASH_PARTITION &&
+ alt_part_info->num_columns != 0))
+ {
+ my_error(ER_PARTITION_COLUMN_LIST_ERROR, MYF(0));
DBUG_RETURN(TRUE);
}
alt_part_info->column_list= tab_part_info->column_list;
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 8ebc754eb03..6da77d14b0d 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1,4 +1,4 @@
-/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
+/* Copyright 2000-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -3870,6 +3870,7 @@ part_func:
partition_info *part_info= Lex->part_info;
if (part_info->set_part_expr($2+1, $3, $4, FALSE))
{ MYSQL_YYABORT; }
+ part_info->num_columns= 1;
part_info->column_list= FALSE;
}
;
@@ -3972,7 +3973,21 @@ opt_num_subparts:
part_defs:
/* empty */
- {}
+ {
+ partition_info *part_info= Lex->part_info;
+ if (part_info->part_type == RANGE_PARTITION)
+ {
+ my_error(ER_PARTITIONS_MUST_BE_DEFINED_ERROR, MYF(0),
+ "RANGE");
+ MYSQL_YYABORT;
+ }
+ else if (part_info->part_type == LIST_PARTITION)
+ {
+ my_error(ER_PARTITIONS_MUST_BE_DEFINED_ERROR, MYF(0),
+ "LIST");
+ MYSQL_YYABORT;
+ }
+ }
| '(' part_def_list ')'
{
partition_info *part_info= Lex->part_info;
@@ -4081,7 +4096,7 @@ opt_part_values:
if (part_info->part_type != LIST_PARTITION)
{
my_error(ER_PARTITION_WRONG_VALUES_ERROR, MYF(0),
- "LIST", "IN");
+ "LIST", "IN");
MYSQL_YYABORT;
}
}
@@ -4099,6 +4114,7 @@ part_func_max:
if (part_info->num_columns &&
part_info->num_columns != 1U)
{
+ part_info->print_debug("Kilroy II", NULL);
my_parse_error(ER(ER_PARTITION_COLUMN_LIST_ERROR));
MYSQL_YYABORT;
}
@@ -4121,6 +4137,7 @@ part_values_in:
{
LEX *lex= Lex;
partition_info *part_info= lex->part_info;
+ part_info->print_debug("part_values_in: part_value_item", NULL);
if (part_info->num_columns != 1U)
{
@@ -4128,6 +4145,7 @@ part_values_in:
part_info->num_columns == 0 ||
part_info->num_columns > MAX_REF_PARTS)
{
+ part_info->print_debug("Kilroy III", NULL);
my_parse_error(ER(ER_PARTITION_COLUMN_LIST_ERROR));
MYSQL_YYABORT;
}
@@ -4135,7 +4153,8 @@ part_values_in:
Reorganize the current large array into a list of small
arrays with one entry in each array. This can happen
in the first partition of an ALTER TABLE statement where
- we ADD or REORGANIZE partitions.
+ we ADD or REORGANIZE partitions. Also can only happen
+ for LIST partitions.
*/
if (part_info->reorganize_into_single_field_col_val())
{
@@ -4163,9 +4182,9 @@ part_value_item:
'('
{
partition_info *part_info= Lex->part_info;
+ part_info->print_debug("( part_value_item", NULL);
/* Initialisation code needed for each list of value expressions */
- if (!(part_info->column_list &&
- part_info->part_type == LIST_PARTITION &&
+ if (!(part_info->part_type == LIST_PARTITION &&
part_info->num_columns == 1U) &&
part_info->init_column_part())
{
@@ -4177,7 +4196,7 @@ part_value_item:
{
LEX *lex= Lex;
partition_info *part_info= Lex->part_info;
-
+ part_info->print_debug(") part_value_item", NULL);
if (part_info->num_columns == 0)
part_info->num_columns= part_info->curr_list_object;
if (part_info->num_columns != part_info->curr_list_object)
@@ -4189,6 +4208,7 @@ part_value_item:
ensures that we only report errors when we know we have an
error.
*/
+ part_info->print_debug("Kilroy I", NULL);
my_parse_error(ER(ER_PARTITION_COLUMN_LIST_ERROR));
MYSQL_YYABORT;
}
@@ -4227,7 +4247,7 @@ part_value_expr_item:
my_error(ER_NO_CONST_EXPR_IN_RANGE_OR_LIST_ERROR, MYF(0));
MYSQL_YYABORT;
}
- if (part_info->add_column_list_value(part_expr))
+ if (part_info->add_column_list_value(YYTHD, part_expr))
{
MYSQL_YYABORT;
}