summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <gluh@eagle.intranet.mysql.r18.ru>2006-03-07 15:25:08 +0400
committerunknown <gluh@eagle.intranet.mysql.r18.ru>2006-03-07 15:25:08 +0400
commit807c7a6a49e6a78d87edb835185d3e69acaeea98 (patch)
tree8df887a5a4ec972aa7cf8c293da8463b078eb293 /sql
parent8cf8e4ed37ab4d5ce22db7359544a3db14e5fb41 (diff)
downloadmariadb-git-807c7a6a49e6a78d87edb835185d3e69acaeea98.tar.gz
Fix for bug#15447 Partitions: NULL is treated as zero
NULL value handling mysql-test/r/ndb_partition_error.result: Fix for bug#15447 Partitions: NULL is treated as zero test case mysql-test/r/partition.result: Fix for bug#15447 Partitions: NULL is treated as zero test case mysql-test/t/ndb_partition_error.test: Fix for bug#15447 Partitions: NULL is treated as zero test case mysql-test/t/partition.test: Fix for bug#15447 Partitions: NULL is treated as zero test case sql/partition_element.h: Fix for bug#15447 Partitions: NULL is treated as zero added null value flag to partition_element object sql/partition_info.h: Fix for bug#15447 Partitions: NULL is treated as zero added null value flag to partition_info object added has_null partition id variable
Diffstat (limited to 'sql')
-rw-r--r--sql/ha_ndbcluster.cc1
-rw-r--r--sql/ha_partition.cc1
-rw-r--r--sql/partition_element.h3
-rw-r--r--sql/partition_info.h7
-rw-r--r--sql/sql_partition.cc41
-rw-r--r--sql/sql_show.cc6
-rw-r--r--sql/sql_yacc.yy46
7 files changed, 93 insertions, 12 deletions
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index ff8a1221052..7f1eb343139 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -6012,6 +6012,7 @@ void ha_ndbcluster::print_error(int error, myf errflag)
{
char buf[100];
my_error(ER_NO_PARTITION_FOR_GIVEN_VALUE, MYF(0),
+ m_part_info->part_expr->null_value ? "NULL" :
llstr(m_part_info->part_expr->val_int(), buf));
}
else
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index e7a324481db..927b5a4a065 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -5092,6 +5092,7 @@ void ha_partition::print_error(int error, myf errflag)
{
char buf[100];
my_error(ER_NO_PARTITION_FOR_GIVEN_VALUE, MYF(0),
+ m_part_info->part_expr->null_value ? "NULL" :
llstr(m_part_info->part_expr->val_int(), buf));
}
else
diff --git a/sql/partition_element.h b/sql/partition_element.h
index 8a11c332897..d20715d2408 100644
--- a/sql/partition_element.h
+++ b/sql/partition_element.h
@@ -51,13 +51,14 @@ public:
handlerton *engine_type;
enum partition_state part_state;
uint16 nodegroup_id;
+ bool has_null_value;
partition_element()
: part_max_rows(0), part_min_rows(0), partition_name(NULL),
tablespace_name(NULL), range_value(0), part_comment(NULL),
data_file_name(NULL), index_file_name(NULL),
engine_type(NULL),part_state(PART_NORMAL),
- nodegroup_id(UNDEF_NODEGROUP)
+ nodegroup_id(UNDEF_NODEGROUP), has_null_value(FALSE)
{
subpartitions.empty();
list_val_list.empty();
diff --git a/sql/partition_info.h b/sql/partition_info.h
index c8cb4ae407a..4a00f5c889f 100644
--- a/sql/partition_info.h
+++ b/sql/partition_info.h
@@ -181,6 +181,9 @@ public:
bool linear_hash_ind;
bool fixed;
bool from_openfrm;
+ bool has_null_value;
+ uint has_null_part_id;
+
partition_info()
: get_partition_id(NULL), get_part_partition_id(NULL),
@@ -211,7 +214,9 @@ public:
list_of_part_fields(FALSE), list_of_subpart_fields(FALSE),
linear_hash_ind(FALSE),
fixed(FALSE),
- from_openfrm(FALSE)
+ from_openfrm(FALSE),
+ has_null_value(FALSE),
+ has_null_part_id(0)
{
all_fields_in_PF.clear_all();
all_fields_in_PPF.clear_all();
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index c98f8f915b9..257c1988cbd 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -531,6 +531,7 @@ static bool check_list_constants(partition_info *part_info)
bool result= TRUE;
longlong curr_value, prev_value;
partition_element* part_def;
+ bool found_null= FALSE;
List_iterator<partition_element> list_func_it(part_info->partitions);
DBUG_ENTER("check_list_constants");
@@ -556,6 +557,17 @@ static bool check_list_constants(partition_info *part_info)
do
{
part_def= list_func_it++;
+ if (part_def->has_null_value)
+ {
+ if (found_null)
+ {
+ my_error(ER_MULTIPLE_DEF_CONST_IN_LIST_PART_ERROR, MYF(0));
+ goto end;
+ }
+ part_info->has_null_value= TRUE;
+ part_info->has_null_part_id= i;
+ found_null= TRUE;
+ }
List_iterator<longlong> list_val_it1(part_def->list_val_list);
while (list_val_it1++)
no_list_values++;
@@ -2041,6 +2053,16 @@ static int add_partition_values(File fptr, partition_info *part_info,
err+= add_string(fptr, "VALUES IN ");
uint no_items= p_elem->list_val_list.elements;
err+= add_begin_parenthesis(fptr);
+ if (p_elem->has_null_value)
+ {
+ err+= add_string(fptr, "NULL");
+ if (no_items == 0)
+ {
+ err+= add_end_parenthesis(fptr);
+ goto end;
+ }
+ err+= add_comma(fptr);
+ }
i= 0;
do
{
@@ -2051,6 +2073,7 @@ static int add_partition_values(File fptr, partition_info *part_info,
} while (++i < no_items);
err+= add_end_parenthesis(fptr);
}
+end:
return err + add_space(fptr);
}
@@ -2631,6 +2654,15 @@ int get_partition_id_list(partition_info *part_info,
longlong part_func_value= part_val_int(part_info->part_expr);
DBUG_ENTER("get_partition_id_list");
+ if (part_info->part_expr->null_value)
+ {
+ if (part_info->has_null_value)
+ {
+ *part_id= part_info->has_null_part_id;
+ DBUG_RETURN(0);
+ }
+ goto notfound;
+ }
*func_value= part_func_value;
while (max_list_index >= min_list_index)
{
@@ -2741,6 +2773,11 @@ int get_partition_id_range(partition_info *part_info,
longlong part_func_value= part_val_int(part_info->part_expr);
DBUG_ENTER("get_partition_id_int_range");
+ if (part_info->part_expr->null_value)
+ {
+ *part_id= 0;
+ DBUG_RETURN(0);
+ }
while (max_part_id > min_part_id)
{
loc_part_id= (max_part_id + min_part_id + 1) >> 1;
@@ -2814,6 +2851,10 @@ uint32 get_partition_id_range_for_endpoint(partition_info *part_info,
uint min_part_id= 0, max_part_id= max_partition, loc_part_id;
/* Get the partitioning function value for the endpoint */
longlong part_func_value= part_val_int(part_info->part_expr);
+
+ if (part_info->part_expr->null_value)
+ DBUG_RETURN(0);
+
while (max_part_id > min_part_id)
{
loc_part_id= (max_part_id + min_part_id + 1) >> 1;
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 13f880ef228..51c92977a27 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -3832,6 +3832,12 @@ static int get_schema_partitions_record(THD *thd, struct st_table_list *tables,
uint no_items= part_elem->list_val_list.elements;
tmp_str.length(0);
tmp_res.length(0);
+ if (part_elem->has_null_value)
+ {
+ tmp_str.append("NULL");
+ if (no_items > 0)
+ tmp_str.append(",");
+ }
while ((list_value= list_val_it++))
{
tmp_res.set(*list_value, cs);
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 6c8b52d243c..235e78c6657 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -42,6 +42,12 @@
#include <myisam.h>
#include <myisammrg.h>
+typedef struct p_elem_val
+{
+ longlong value;
+ bool null_value;
+} part_elem_value;
+
int yylex(void *yylval, void *yythd);
const LEX_STRING null_lex_str={0,0};
@@ -105,6 +111,7 @@ inline Item *is_truth_value(Item *A, bool v1, bool v2)
sp_name *spname;
struct st_lex *lex;
sp_head *sphead;
+ struct p_elem_val *p_elem_value;
}
%{
@@ -752,7 +759,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%type <ulonglong_number>
ulonglong_num size_number
-%type <longlong_number>
+%type <p_elem_value>
part_bit_expr
%type <lock_type>
@@ -3781,7 +3788,7 @@ part_func_max:
part_range_func:
'(' part_bit_expr ')'
{
- Lex->part_info->curr_part_elem->range_value= $2;
+ Lex->part_info->curr_part_elem->range_value= $2->value;
}
;
@@ -3793,12 +3800,12 @@ part_list_func:
part_list_item:
part_bit_expr
{
- longlong *value_ptr;
- if (!(value_ptr= (longlong*)sql_alloc(sizeof(longlong))) ||
- ((*value_ptr= $1, FALSE) ||
- Lex->part_info->curr_part_elem->list_val_list.push_back(value_ptr)))
+ part_elem_value *value_ptr= $1;
+ if (!value_ptr->null_value &&
+ Lex->part_info->curr_part_elem->
+ list_val_list.push_back((longlong*) &value_ptr->value))
{
- mem_alloc_error(sizeof(longlong));
+ mem_alloc_error(sizeof(part_elem_value));
YYABORT;
}
}
@@ -3818,6 +3825,15 @@ part_bit_expr:
context->table_list= 0;
thd->where= "partition function";
+
+ part_elem_value *value_ptr=
+ (part_elem_value*)sql_alloc(sizeof(part_elem_value));
+ if (!value_ptr)
+ {
+ mem_alloc_error(sizeof(part_elem_value));
+ YYABORT;
+ }
+
if (part_expr->fix_fields(YYTHD, (Item**)0) ||
((context->table_list= save_list), FALSE) ||
(!part_expr->const_item()) ||
@@ -3827,13 +3843,23 @@ part_bit_expr:
YYABORT;
}
thd->where= save_where;
- if (part_expr->result_type() != INT_RESULT)
+ value_ptr->value= part_expr->val_int();
+ if ((value_ptr->null_value= part_expr->null_value))
+ {
+ if (Lex->part_info->curr_part_elem->has_null_value)
+ {
+ my_error(ER_MULTIPLE_DEF_CONST_IN_LIST_PART_ERROR, MYF(0));
+ YYABORT;
+ }
+ Lex->part_info->curr_part_elem->has_null_value= TRUE;
+ }
+ else if (part_expr->result_type() != INT_RESULT &&
+ !part_expr->null_value)
{
yyerror(ER(ER_INCONSISTENT_TYPE_OF_FUNCTIONS_ERROR));
YYABORT;
}
- item_value= part_expr->val_int();
- $$= item_value;
+ $$= value_ptr;
}
;