Commit c5644238 authored by unknown's avatar unknown

Merge bk-internal.mysql.com:/home/bk/mysql-5.1

into serg.mylan:/usr/home/serg/Abk/m51

parents 7c1748a1 7431df60
DROP TABLE IF EXISTS t1;
create table t1(a int) engine=myisam;
select * into outfile 'MYSQLTEST_VARDIR/master-data/ndb_loaddatalocal.select_outfile' from t1;
drop table t1;
create table t1(a int) engine=ndb;
load data local infile 'MYSQLTEST_VARDIR/master-data/ndb_loaddatalocal.select_outfile' into table t1;
select count(*) from t1;
count(*)
10000
drop table t1;
create table t1(a int) engine=myisam;
insert into t1 values (1), (2), (2), (3);
select * into outfile 'MYSQLTEST_VARDIR/master-data/ndb_loaddatalocal.select_outfile' from t1;
drop table t1;
create table t1(a int primary key) engine=ndb;
load data local infile 'MYSQLTEST_VARDIR/master-data/ndb_loaddatalocal.select_outfile' into table t1;
select * from t1 order by a;
a
1
2
3
drop table t1;
create table t1(a int) engine=myisam;
insert into t1 values (1), (1), (2), (3);
select * into outfile 'MYSQLTEST_VARDIR/master-data/ndb_loaddatalocal.select_outfile' from t1;
drop table t1;
create table t1(a int primary key) engine=ndb;
load data local infile 'MYSQLTEST_VARDIR/master-data/ndb_loaddatalocal.select_outfile' into table t1;
select * from t1 order by a;
a
1
2
3
drop table t1;
create table t1(a int) engine=myisam;
insert into t1 values (1), (2), (3), (3);
select * into outfile 'MYSQLTEST_VARDIR/master-data/ndb_loaddatalocal.select_outfile' from t1;
drop table t1;
create table t1(a int primary key) engine=ndb;
load data local infile 'MYSQLTEST_VARDIR/master-data/ndb_loaddatalocal.select_outfile' into table t1;
select * from t1 order by a;
a
1
2
3
drop table t1;
drop table if exists t1; drop table if exists t1;
create table t1 (a bigint)
partition by range (a)
(partition p0 values less than (0xFFFFFFFFFFFFFFFF),
partition p1 values less than (10));
ERROR 42000: VALUES value must be of same type as partition function near '),
partition p1 values less than (10))' at line 3
create table t1 (a bigint)
partition by list (a)
(partition p0 values in (0xFFFFFFFFFFFFFFFF),
partition p1 values in (10));
ERROR 42000: VALUES value must be of same type as partition function near '),
partition p1 values in (10))' at line 3
create table t1 (a bigint unsigned)
partition by range (a)
(partition p0 values less than (100),
partition p1 values less than MAXVALUE);
insert into t1 values (1);
drop table t1;
create table t1 (a bigint unsigned)
partition by hash (a);
insert into t1 values (0xFFFFFFFFFFFFFFFD);
insert into t1 values (0xFFFFFFFFFFFFFFFE);
select * from t1 where (a + 1) < 10;
a
select * from t1 where (a + 1) > 10;
a
18446744073709551613
18446744073709551614
drop table t1;
create table t1 (a int) create table t1 (a int)
engine = csv engine = csv
partition by list (a) partition by list (a)
...@@ -779,6 +808,18 @@ insert into t1 values (null); ...@@ -779,6 +808,18 @@ insert into t1 values (null);
select * from t1 where f1 is null; select * from t1 where f1 is null;
f1 f1
NULL NULL
select * from t1 where f1 < 1;
f1
select * from t1 where f1 <= NULL;
f1
select * from t1 where f1 < NULL;
f1
select * from t1 where f1 >= NULL;
f1
select * from t1 where f1 > NULL;
f1
select * from t1 where f1 > 1;
f1
drop table t1; drop table t1;
create table t1 (f1 smallint) create table t1 (f1 smallint)
partition by range (f1) (partition p0 values less than (0)); partition by range (f1) (partition p0 values less than (0));
...@@ -865,6 +906,16 @@ SHOW TABLE STATUS; ...@@ -865,6 +906,16 @@ SHOW TABLE STATUS;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 MyISAM 10 Dynamic 0 0 0 0 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL partitioned t1 MyISAM 10 Dynamic 0 0 0 0 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL partitioned
DROP TABLE t1; DROP TABLE t1;
create table t1 (a bigint unsigned)
partition by list (a)
(partition p0 values in (0-1));
ERROR HY000: Partition constant is out of partition function domain
create table t1 (a bigint unsigned)
partition by range (a)
(partition p0 values less than (10));
insert into t1 values (0xFFFFFFFFFFFFFFFF);
ERROR HY000: Table has no partition for value 18446744073709551615
drop table t1;
create table t1 (a int) create table t1 (a int)
partition by list (a) partition by list (a)
(partition `s1 s2` values in (0)); (partition `s1 s2` values in (0));
......
...@@ -554,6 +554,10 @@ PARTITION BY RANGE (a) (PARTITION p1 VALUES LESS THAN(5)); ...@@ -554,6 +554,10 @@ PARTITION BY RANGE (a) (PARTITION p1 VALUES LESS THAN(5));
insert into t1 values (10); insert into t1 values (10);
ERROR HY000: Table has no partition for value 10 ERROR HY000: Table has no partition for value 10
drop table t1; drop table t1;
create table t1 (a bigint unsigned)
partition by range (a)
(partition p0 values less than (-1));
ERROR HY000: Partition constant is out of partition function domain
create table t1 (v varchar(12)) create table t1 (v varchar(12))
partition by range (ascii(v)) partition by range (ascii(v))
(partition p0 values less than (10)); (partition p0 values less than (10));
......
...@@ -363,6 +363,33 @@ SELECT COUNT(*) FROM t1 WHERE c3 < '2000-12-31'; ...@@ -363,6 +363,33 @@ SELECT COUNT(*) FROM t1 WHERE c3 < '2000-12-31';
COUNT(*) COUNT(*)
10 10
DROP TABLE t1; DROP TABLE t1;
create table t1 (a bigint unsigned)
partition by range (a)
(partition p0 values less than (10),
partition p1 values less than (0));
ERROR HY000: VALUES LESS THAN value must be strictly increasing for each partition
create table t1 (a bigint unsigned)
partition by range (a)
(partition p0 values less than (0),
partition p1 values less than (10));
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` bigint(20) unsigned DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 PARTITION BY RANGE (a) (PARTITION p0 VALUES LESS THAN (0) ENGINE = MyISAM, PARTITION p1 VALUES LESS THAN (10) ENGINE = MyISAM)
drop table t1;
create table t1 (a bigint unsigned)
partition by range (a)
(partition p0 values less than (2),
partition p1 values less than (10));
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` bigint(20) unsigned DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 PARTITION BY RANGE (a) (PARTITION p0 VALUES LESS THAN (2) ENGINE = MyISAM, PARTITION p1 VALUES LESS THAN (10) ENGINE = MyISAM)
insert into t1 values (0xFFFFFFFFFFFFFFFF);
ERROR HY000: Table has no partition for value 18446744073709551615
drop table t1;
create table t1 (a int) create table t1 (a int)
partition by range (MOD(a,3)) partition by range (MOD(a,3))
subpartition by hash(a) subpartition by hash(a)
......
-- source include/have_ndb.inc
-- source include/not_embedded.inc
--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings
create table t1(a int) engine=myisam;
let $1=10000;
disable_query_log;
set SQL_LOG_BIN=0;
while ($1)
{
insert into t1 values(1);
dec $1;
}
set SQL_LOG_BIN=1;
enable_query_log;
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
eval select * into outfile '$MYSQLTEST_VARDIR/master-data/ndb_loaddatalocal.select_outfile' from t1;
#This will generate a 20KB file, now test LOAD DATA LOCAL
drop table t1;
create table t1(a int) engine=ndb;
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
eval load data local infile '$MYSQLTEST_VARDIR/master-data/ndb_loaddatalocal.select_outfile' into table t1;
select count(*) from t1;
system rm $MYSQLTEST_VARDIR/master-data/ndb_loaddatalocal.select_outfile ;
drop table t1;
create table t1(a int) engine=myisam;
insert into t1 values (1), (2), (2), (3);
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
eval select * into outfile '$MYSQLTEST_VARDIR/master-data/ndb_loaddatalocal.select_outfile' from t1;
drop table t1;
create table t1(a int primary key) engine=ndb;
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
eval load data local infile '$MYSQLTEST_VARDIR/master-data/ndb_loaddatalocal.select_outfile' into table t1;
system rm $MYSQLTEST_VARDIR/master-data/ndb_loaddatalocal.select_outfile;
select * from t1 order by a;
drop table t1;
create table t1(a int) engine=myisam;
insert into t1 values (1), (1), (2), (3);
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
eval select * into outfile '$MYSQLTEST_VARDIR/master-data/ndb_loaddatalocal.select_outfile' from t1;
drop table t1;
create table t1(a int primary key) engine=ndb;
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
eval load data local infile '$MYSQLTEST_VARDIR/master-data/ndb_loaddatalocal.select_outfile' into table t1;
system rm $MYSQLTEST_VARDIR/master-data/ndb_loaddatalocal.select_outfile;
select * from t1 order by a;
drop table t1;
create table t1(a int) engine=myisam;
insert into t1 values (1), (2), (3), (3);
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
eval select * into outfile '$MYSQLTEST_VARDIR/master-data/ndb_loaddatalocal.select_outfile' from t1;
drop table t1;
create table t1(a int primary key) engine=ndb;
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
eval load data local infile '$MYSQLTEST_VARDIR/master-data/ndb_loaddatalocal.select_outfile' into table t1;
system rm $MYSQLTEST_VARDIR/master-data/ndb_loaddatalocal.select_outfile;
select * from t1 order by a;
drop table t1;
# End of 4.1 tests
...@@ -9,6 +9,35 @@ ...@@ -9,6 +9,35 @@
drop table if exists t1; drop table if exists t1;
--enable_warnings --enable_warnings
#
# BUG 16002: Handle unsigned integer functions properly
#
--error 1064
create table t1 (a bigint)
partition by range (a)
(partition p0 values less than (0xFFFFFFFFFFFFFFFF),
partition p1 values less than (10));
--error 1064
create table t1 (a bigint)
partition by list (a)
(partition p0 values in (0xFFFFFFFFFFFFFFFF),
partition p1 values in (10));
create table t1 (a bigint unsigned)
partition by range (a)
(partition p0 values less than (100),
partition p1 values less than MAXVALUE);
insert into t1 values (1);
drop table t1;
create table t1 (a bigint unsigned)
partition by hash (a);
insert into t1 values (0xFFFFFFFFFFFFFFFD);
insert into t1 values (0xFFFFFFFFFFFFFFFE);
select * from t1 where (a + 1) < 10;
select * from t1 where (a + 1) > 10;
drop table t1;
# #
# Bug 19307: CSV engine crashes # Bug 19307: CSV engine crashes
# #
...@@ -19,6 +48,7 @@ partition by list (a) ...@@ -19,6 +48,7 @@ partition by list (a)
(partition p0 values in (null)); (partition p0 values in (null));
# #
# Added test case
# #
create table t1 (a int) create table t1 (a int)
partition by key(a) partition by key(a)
...@@ -919,6 +949,12 @@ create table t1 (f1 smallint) ...@@ -919,6 +949,12 @@ create table t1 (f1 smallint)
partition by list (f1) (partition p0 values in (null)); partition by list (f1) (partition p0 values in (null));
insert into t1 values (null); insert into t1 values (null);
select * from t1 where f1 is null; select * from t1 where f1 is null;
select * from t1 where f1 < 1;
select * from t1 where f1 <= NULL;
select * from t1 where f1 < NULL;
select * from t1 where f1 >= NULL;
select * from t1 where f1 > NULL;
select * from t1 where f1 > 1;
drop table t1; drop table t1;
create table t1 (f1 smallint) create table t1 (f1 smallint)
...@@ -985,6 +1021,23 @@ PARTITION p2 VALUES LESS THAN (30) ENGINE = MyISAM); ...@@ -985,6 +1021,23 @@ PARTITION p2 VALUES LESS THAN (30) ENGINE = MyISAM);
SHOW TABLE STATUS; SHOW TABLE STATUS;
DROP TABLE t1; DROP TABLE t1;
#
#BUG 16002 Erroneus handling of unsigned partition functions
#
--error ER_PARTITION_CONST_DOMAIN_ERROR
create table t1 (a bigint unsigned)
partition by list (a)
(partition p0 values in (0-1));
create table t1 (a bigint unsigned)
partition by range (a)
(partition p0 values less than (10));
--error ER_NO_PARTITION_FOR_GIVEN_VALUE
insert into t1 values (0xFFFFFFFFFFFFFFFF);
drop table t1;
# #
#BUG 18750 Problems with partition names #BUG 18750 Problems with partition names
# #
......
...@@ -748,6 +748,10 @@ CREATE TABLE t1(a int) ...@@ -748,6 +748,10 @@ CREATE TABLE t1(a int)
insert into t1 values (10); insert into t1 values (10);
drop table t1; drop table t1;
--error ER_PARTITION_CONST_DOMAIN_ERROR
create table t1 (a bigint unsigned)
partition by range (a)
(partition p0 values less than (-1));
# #
# Bug 18198 Partitions: Verify that erroneus partition functions doesn't work # Bug 18198 Partitions: Verify that erroneus partition functions doesn't work
# #
......
...@@ -388,6 +388,31 @@ SELECT COUNT(*) FROM t1 WHERE c3 BETWEEN '1996-12-31' AND '2000-12-31'; ...@@ -388,6 +388,31 @@ SELECT COUNT(*) FROM t1 WHERE c3 BETWEEN '1996-12-31' AND '2000-12-31';
SELECT COUNT(*) FROM t1 WHERE c3 < '2000-12-31'; SELECT COUNT(*) FROM t1 WHERE c3 < '2000-12-31';
DROP TABLE t1; DROP TABLE t1;
#
# BUG 16002: Unsigned partition functions not handled correctly
#
--error ER_RANGE_NOT_INCREASING_ERROR
create table t1 (a bigint unsigned)
partition by range (a)
(partition p0 values less than (10),
partition p1 values less than (0));
create table t1 (a bigint unsigned)
partition by range (a)
(partition p0 values less than (0),
partition p1 values less than (10));
show create table t1;
drop table t1;
create table t1 (a bigint unsigned)
partition by range (a)
(partition p0 values less than (2),
partition p1 values less than (10));
show create table t1;
--error ER_NO_PARTITION_FOR_GIVEN_VALUE
insert into t1 values (0xFFFFFFFFFFFFFFFF);
drop table t1;
# #
# BUG 18962 Errors in DROP PARTITION # BUG 18962 Errors in DROP PARTITION
# #
......
...@@ -2452,6 +2452,11 @@ int ha_ndbcluster::write_row(byte *record) ...@@ -2452,6 +2452,11 @@ int ha_ndbcluster::write_row(byte *record)
*/ */
if (!m_use_write && m_ignore_dup_key) if (!m_use_write && m_ignore_dup_key)
{ {
/*
compare if expression with that in start_bulk_insert()
start_bulk_insert will set parameters to ensure that each
write_row is committed individually
*/
int peek_res= peek_indexed_rows(record); int peek_res= peek_indexed_rows(record);
if (!peek_res) if (!peek_res)
...@@ -3693,6 +3698,19 @@ void ha_ndbcluster::start_bulk_insert(ha_rows rows) ...@@ -3693,6 +3698,19 @@ void ha_ndbcluster::start_bulk_insert(ha_rows rows)
DBUG_PRINT("enter", ("rows: %d", (int)rows)); DBUG_PRINT("enter", ("rows: %d", (int)rows));
m_rows_inserted= (ha_rows) 0; m_rows_inserted= (ha_rows) 0;
if (!m_use_write && m_ignore_dup_key)
{
/*
compare if expression with that in write_row
we have a situation where peek_indexed_rows() will be called
so we cannot batch
*/
DBUG_PRINT("info", ("Batching turned off as duplicate key is "
"ignored by using peek_row"));
m_rows_to_insert= 1;
m_bulk_insert_rows= 1;
DBUG_VOID_RETURN;
}
if (rows == (ha_rows) 0) if (rows == (ha_rows) 0)
{ {
/* We don't know how many will be inserted, guess */ /* We don't know how many will be inserted, guess */
...@@ -6455,14 +6473,7 @@ void ha_ndbcluster::print_error(int error, myf errflag) ...@@ -6455,14 +6473,7 @@ void ha_ndbcluster::print_error(int error, myf errflag)
DBUG_PRINT("enter", ("error = %d", error)); DBUG_PRINT("enter", ("error = %d", error));
if (error == HA_ERR_NO_PARTITION_FOUND) if (error == HA_ERR_NO_PARTITION_FOUND)
{ m_part_info->print_no_partition_found(table);
char buf[100];
my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set);
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));
dbug_tmp_restore_column_map(table->read_set, old_map);
}
else else
handler::print_error(error, errflag); handler::print_error(error, errflag);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
...@@ -9668,6 +9679,7 @@ int ha_ndbcluster::set_range_data(void *tab_ref, partition_info *part_info) ...@@ -9668,6 +9679,7 @@ int ha_ndbcluster::set_range_data(void *tab_ref, partition_info *part_info)
MYF(0)); MYF(0));
uint i; uint i;
int error= 0; int error= 0;
bool unsigned_flag= part_info->part_expr->unsigned_flag;
DBUG_ENTER("set_range_data"); DBUG_ENTER("set_range_data");
if (!range_data) if (!range_data)
...@@ -9678,6 +9690,8 @@ int ha_ndbcluster::set_range_data(void *tab_ref, partition_info *part_info) ...@@ -9678,6 +9690,8 @@ int ha_ndbcluster::set_range_data(void *tab_ref, partition_info *part_info)
for (i= 0; i < part_info->no_parts; i++) for (i= 0; i < part_info->no_parts; i++)
{ {
longlong range_val= part_info->range_int_array[i]; longlong range_val= part_info->range_int_array[i];
if (unsigned_flag)
range_val-= 0x8000000000000000ULL;
if (range_val < INT_MIN32 || range_val >= INT_MAX32) if (range_val < INT_MIN32 || range_val >= INT_MAX32)
{ {
if ((i != part_info->no_parts - 1) || if ((i != part_info->no_parts - 1) ||
...@@ -9704,6 +9718,7 @@ int ha_ndbcluster::set_list_data(void *tab_ref, partition_info *part_info) ...@@ -9704,6 +9718,7 @@ int ha_ndbcluster::set_list_data(void *tab_ref, partition_info *part_info)
* sizeof(int32), MYF(0)); * sizeof(int32), MYF(0));
uint32 *part_id, i; uint32 *part_id, i;
int error= 0; int error= 0;
bool unsigned_flag= part_info->part_expr->unsigned_flag;
DBUG_ENTER("set_list_data"); DBUG_ENTER("set_list_data");
if (!list_data) if (!list_data)
...@@ -9715,6 +9730,8 @@ int ha_ndbcluster::set_list_data(void *tab_ref, partition_info *part_info) ...@@ -9715,6 +9730,8 @@ int ha_ndbcluster::set_list_data(void *tab_ref, partition_info *part_info)
{ {
LIST_PART_ENTRY *list_entry= &part_info->list_array[i]; LIST_PART_ENTRY *list_entry= &part_info->list_array[i];
longlong list_val= list_entry->list_value; longlong list_val= list_entry->list_value;
if (unsigned_flag)
list_val-= 0x8000000000000000ULL;
if (list_val < INT_MIN32 || list_val > INT_MAX32) if (list_val < INT_MIN32 || list_val > INT_MAX32)
{ {
my_error(ER_LIMITED_PART_RANGE, MYF(0), "NDB"); my_error(ER_LIMITED_PART_RANGE, MYF(0), "NDB");
......
...@@ -5097,14 +5097,7 @@ void ha_partition::print_error(int error, myf errflag) ...@@ -5097,14 +5097,7 @@ void ha_partition::print_error(int error, myf errflag)
DBUG_PRINT("enter", ("error: %d", error)); DBUG_PRINT("enter", ("error: %d", error));
if (error == HA_ERR_NO_PARTITION_FOUND) if (error == HA_ERR_NO_PARTITION_FOUND)
{ m_part_info->print_no_partition_found(table);
char buf[100];
my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set);
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));
dbug_tmp_restore_column_map(table->read_set, old_map);
}
else else
m_file[0]->print_error(error, errflag); m_file[0]->print_error(error, errflag);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
......
...@@ -36,18 +36,32 @@ enum partition_state { ...@@ -36,18 +36,32 @@ enum partition_state {
PART_IS_ADDED= 8 PART_IS_ADDED= 8
}; };
/*
This struct is used to contain the value of an element
in the VALUES IN struct. It needs to keep knowledge of
whether it is a signed/unsigned value and whether it is
NULL or not.
*/
typedef struct p_elem_val
{
longlong value;
bool null_value;
bool unsigned_flag;
} part_elem_value;
struct st_ddl_log_memory_entry; struct st_ddl_log_memory_entry;
class partition_element :public Sql_alloc { class partition_element :public Sql_alloc {
public: public:
List<partition_element> subpartitions; List<partition_element> subpartitions;
List<longlong> list_val_list; List<part_elem_value> list_val_list;
ulonglong part_max_rows; ulonglong part_max_rows;
ulonglong part_min_rows; ulonglong part_min_rows;
longlong range_value;
char *partition_name; char *partition_name;
char *tablespace_name; char *tablespace_name;
struct st_ddl_log_memory_entry *log_entry; struct st_ddl_log_memory_entry *log_entry;
longlong range_value;
char* part_comment; char* part_comment;
char* data_file_name; char* data_file_name;
char* index_file_name; char* index_file_name;
...@@ -55,14 +69,17 @@ class partition_element :public Sql_alloc { ...@@ -55,14 +69,17 @@ class partition_element :public Sql_alloc {
enum partition_state part_state; enum partition_state part_state;
uint16 nodegroup_id; uint16 nodegroup_id;
bool has_null_value; bool has_null_value;
bool signed_flag;/* Indicate whether this partition uses signed constants */
bool max_value; /* Indicate whether this partition uses MAXVALUE */
partition_element() partition_element()
: part_max_rows(0), part_min_rows(0), partition_name(NULL), : part_max_rows(0), part_min_rows(0), range_value(0),
tablespace_name(NULL), log_entry(NULL), partition_name(NULL), tablespace_name(NULL),
range_value(0), part_comment(NULL), log_entry(NULL), part_comment(NULL),
data_file_name(NULL), index_file_name(NULL), data_file_name(NULL), index_file_name(NULL),
engine_type(NULL),part_state(PART_NORMAL), engine_type(NULL), part_state(PART_NORMAL),
nodegroup_id(UNDEF_NODEGROUP), has_null_value(FALSE) nodegroup_id(UNDEF_NODEGROUP), has_null_value(FALSE),
signed_flag(FALSE), max_value(FALSE)
{ {
} }
partition_element(partition_element *part_elem) partition_element(partition_element *part_elem)
......
...@@ -476,11 +476,13 @@ bool partition_info::check_engine_mix(handlerton **engine_array, uint no_parts) ...@@ -476,11 +476,13 @@ bool partition_info::check_engine_mix(handlerton **engine_array, uint no_parts)
bool partition_info::check_range_constants() bool partition_info::check_range_constants()
{ {
partition_element* part_def; partition_element* part_def;
longlong current_largest_int= LONGLONG_MIN; longlong current_largest;
longlong part_range_value_int; longlong part_range_value;
bool first= TRUE;
uint i; uint i;
List_iterator<partition_element> it(partitions); List_iterator<partition_element> it(partitions);
bool result= TRUE; bool result= TRUE;
bool signed_flag= !part_expr->unsigned_flag;
DBUG_ENTER("partition_info::check_range_constants"); DBUG_ENTER("partition_info::check_range_constants");
DBUG_PRINT("enter", ("INT_RESULT with %d parts", no_parts)); DBUG_PRINT("enter", ("INT_RESULT with %d parts", no_parts));
...@@ -496,18 +498,31 @@ bool partition_info::check_range_constants() ...@@ -496,18 +498,31 @@ bool partition_info::check_range_constants()
{ {
part_def= it++; part_def= it++;
if ((i != (no_parts - 1)) || !defined_max_value) if ((i != (no_parts - 1)) || !defined_max_value)
part_range_value_int= part_def->range_value; {
part_range_value= part_def->range_value;
if (!signed_flag)
part_range_value-= 0x8000000000000000ULL;
}
else else
part_range_value_int= LONGLONG_MAX; part_range_value= LONGLONG_MAX;
if (likely(current_largest_int < part_range_value_int)) if (first)
{ {
current_largest_int= part_range_value_int; current_largest= part_range_value;
range_int_array[i]= part_range_value_int; range_int_array[0]= part_range_value;
first= FALSE;
} }
else else
{ {
my_error(ER_RANGE_NOT_INCREASING_ERROR, MYF(0)); if (likely(current_largest < part_range_value))
goto end; {
current_largest= part_range_value;
range_int_array[i]= part_range_value;
}
else
{
my_error(ER_RANGE_NOT_INCREASING_ERROR, MYF(0));
goto end;
}
} }
} while (++i < no_parts); } while (++i < no_parts);
result= FALSE; result= FALSE;
...@@ -517,8 +532,8 @@ bool partition_info::check_range_constants() ...@@ -517,8 +532,8 @@ bool partition_info::check_range_constants()
/* /*
A support routine for check_list_constants used by qsort to sort the Support routines for check_list_constants used by qsort to sort the
constant list expressions. constant list expressions. One routine for unsigned and one for signed.
SYNOPSIS SYNOPSIS
list_part_cmp() list_part_cmp()
...@@ -568,10 +583,9 @@ bool partition_info::check_list_constants() ...@@ -568,10 +583,9 @@ bool partition_info::check_list_constants()
{ {
uint i; uint i;
uint list_index= 0; uint list_index= 0;
longlong *list_value; part_elem_value *list_value;
bool not_first;
bool result= TRUE; bool result= TRUE;
longlong curr_value, prev_value; longlong curr_value, prev_value, type_add, calc_value;
partition_element* part_def; partition_element* part_def;
bool found_null= FALSE; bool found_null= FALSE;
List_iterator<partition_element> list_func_it(partitions); List_iterator<partition_element> list_func_it(partitions);
...@@ -609,12 +623,13 @@ bool partition_info::check_list_constants() ...@@ -609,12 +623,13 @@ bool partition_info::check_list_constants()
has_null_part_id= i; has_null_part_id= i;
found_null= TRUE; found_null= TRUE;
} }
List_iterator<longlong> list_val_it1(part_def->list_val_list); List_iterator<part_elem_value> list_val_it1(part_def->list_val_list);
while (list_val_it1++) while (list_val_it1++)
no_list_values++; no_list_values++;
} while (++i < no_parts); } while (++i < no_parts);
list_func_it.rewind(); list_func_it.rewind();
list_array= (LIST_PART_ENTRY*)sql_alloc(no_list_values*sizeof(LIST_PART_ENTRY)); list_array= (LIST_PART_ENTRY*)sql_alloc((no_list_values+1) *
sizeof(LIST_PART_ENTRY));
if (unlikely(list_array == NULL)) if (unlikely(list_array == NULL))
{ {
mem_alloc_error(no_list_values * sizeof(LIST_PART_ENTRY)); mem_alloc_error(no_list_values * sizeof(LIST_PART_ENTRY));
...@@ -622,35 +637,48 @@ bool partition_info::check_list_constants() ...@@ -622,35 +637,48 @@ bool partition_info::check_list_constants()
} }
i= 0; i= 0;
/*
Fix to be able to reuse signed sort functions also for unsigned
partition functions.
*/
type_add= (longlong)(part_expr->unsigned_flag ?
0x8000000000000000ULL :
0ULL);
do do
{ {
part_def= list_func_it++; part_def= list_func_it++;
List_iterator<longlong> list_val_it2(part_def->list_val_list); List_iterator<part_elem_value> list_val_it2(part_def->list_val_list);
while ((list_value= list_val_it2++)) while ((list_value= list_val_it2++))
{ {
list_array[list_index].list_value= *list_value; calc_value= list_value->value - type_add;
list_array[list_index].list_value= calc_value;
list_array[list_index++].partition_id= i; list_array[list_index++].partition_id= i;
} }
} while (++i < no_parts); } while (++i < no_parts);
qsort((void*)list_array, no_list_values, sizeof(LIST_PART_ENTRY), if (fixed && no_list_values)
&list_part_cmp);
not_first= FALSE;
prev_value= 0; // prev_value initialised to quiet compiler
for (i= 0; i < no_list_values ; i++)
{ {
curr_value= list_array[i].list_value; bool first= TRUE;
if (likely(!not_first || prev_value != curr_value)) qsort((void*)list_array, no_list_values, sizeof(LIST_PART_ENTRY),
{ &list_part_cmp);
prev_value= curr_value;
not_first= TRUE; i= prev_value= 0; //prev_value initialised to quiet compiler
} do
else
{ {
my_error(ER_MULTIPLE_DEF_CONST_IN_LIST_PART_ERROR, MYF(0)); DBUG_ASSERT(i < no_list_values);
goto end; curr_value= list_array[i].list_value;
} if (likely(first || prev_value != curr_value))
{
prev_value= curr_value;
first= FALSE;
}
else
{
my_error(ER_MULTIPLE_DEF_CONST_IN_LIST_PART_ERROR, MYF(0));
goto end;
}
} while (++i < no_list_values);
} }
result= FALSE; result= FALSE;
end: end:
...@@ -679,7 +707,7 @@ bool partition_info::check_list_constants() ...@@ -679,7 +707,7 @@ bool partition_info::check_list_constants()
*/ */
bool partition_info::check_partition_info(handlerton **eng_type, bool partition_info::check_partition_info(THD *thd, handlerton **eng_type,
handler *file, ulonglong max_rows) handler *file, ulonglong max_rows)
{ {
handlerton **engine_array= NULL; handlerton **engine_array= NULL;
...@@ -786,9 +814,12 @@ bool partition_info::check_partition_info(handlerton **eng_type, ...@@ -786,9 +814,12 @@ bool partition_info::check_partition_info(handlerton **eng_type,
list constants. list constants.
*/ */
if (unlikely((part_type == RANGE_PARTITION && check_range_constants()) || if (fixed)
(part_type == LIST_PARTITION && check_list_constants()))) {
goto end; if (unlikely((part_type == RANGE_PARTITION && check_range_constants()) ||
(part_type == LIST_PARTITION && check_list_constants())))
goto end;
}
result= FALSE; result= FALSE;
end: end:
my_free((char*)engine_array,MYF(MY_ALLOW_ZERO_PTR)); my_free((char*)engine_array,MYF(MY_ALLOW_ZERO_PTR));
...@@ -796,4 +827,28 @@ bool partition_info::check_partition_info(handlerton **eng_type, ...@@ -796,4 +827,28 @@ bool partition_info::check_partition_info(handlerton **eng_type,
} }
/*
Print error for no partition found
SYNOPSIS
print_no_partition_found()
table Table object
RETURN VALUES
NONE
*/
void partition_info::print_no_partition_found(TABLE *table)
{
char buf[100];
char *buf_ptr= (char*)&buf;
my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set);
if (part_expr->null_value)
buf_ptr= (char*)"NULL";
else
longlong2str(part_expr->val_int(), buf,
part_expr->unsigned_flag ? 10 : -10);
my_error(ER_NO_PARTITION_FOR_GIVEN_VALUE, MYF(0), buf_ptr);
dbug_tmp_restore_column_map(table->read_set, old_map);
}
#endif /* WITH_PARTITION_STORAGE_ENGINE */ #endif /* WITH_PARTITION_STORAGE_ENGINE */
...@@ -167,6 +167,7 @@ class partition_info : public Sql_alloc ...@@ -167,6 +167,7 @@ class partition_info : public Sql_alloc
uint no_subpart_fields; uint no_subpart_fields;
uint no_full_part_fields; uint no_full_part_fields;
uint has_null_part_id;
/* /*
This variable is used to calculate the partition id when using This variable is used to calculate the partition id when using
LINEAR KEY/HASH. This functionality is kept in the MySQL Server LINEAR KEY/HASH. This functionality is kept in the MySQL Server
...@@ -187,7 +188,6 @@ class partition_info : public Sql_alloc ...@@ -187,7 +188,6 @@ class partition_info : public Sql_alloc
bool is_auto_partitioned; bool is_auto_partitioned;
bool from_openfrm; bool from_openfrm;
bool has_null_value; bool has_null_value;
uint has_null_part_id;
partition_info() partition_info()
...@@ -210,20 +210,14 @@ class partition_info : public Sql_alloc ...@@ -210,20 +210,14 @@ class partition_info : public Sql_alloc
no_parts(0), no_subparts(0), no_parts(0), no_subparts(0),
count_curr_subparts(0), part_error_code(0), count_curr_subparts(0), part_error_code(0),
no_list_values(0), no_part_fields(0), no_subpart_fields(0), no_list_values(0), no_part_fields(0), no_subpart_fields(0),
no_full_part_fields(0), linear_hash_mask(0), no_full_part_fields(0), has_null_part_id(0), linear_hash_mask(0),
use_default_partitions(TRUE), use_default_partitions(TRUE), use_default_no_partitions(TRUE),
use_default_no_partitions(TRUE), use_default_subpartitions(TRUE), use_default_no_subpartitions(TRUE),
use_default_subpartitions(TRUE), default_partitions_setup(FALSE), defined_max_value(FALSE),
use_default_no_subpartitions(TRUE),
default_partitions_setup(FALSE),
defined_max_value(FALSE),
list_of_part_fields(FALSE), list_of_subpart_fields(FALSE), list_of_part_fields(FALSE), list_of_subpart_fields(FALSE),
linear_hash_ind(FALSE), linear_hash_ind(FALSE), fixed(FALSE),
fixed(FALSE), is_auto_partitioned(FALSE), from_openfrm(FALSE),
is_auto_partitioned(FALSE), has_null_value(FALSE)
from_openfrm(FALSE),
has_null_value(FALSE),
has_null_part_id(0)
{ {
all_fields_in_PF.clear_all(); all_fields_in_PF.clear_all();
all_fields_in_PPF.clear_all(); all_fields_in_PPF.clear_all();
...@@ -255,10 +249,12 @@ class partition_info : public Sql_alloc ...@@ -255,10 +249,12 @@ class partition_info : public Sql_alloc
static bool check_engine_mix(handlerton **engine_array, uint no_parts); static bool check_engine_mix(handlerton **engine_array, uint no_parts);
bool check_range_constants(); bool check_range_constants();
bool check_list_constants(); bool check_list_constants();
bool check_partition_info(handlerton **eng_type, bool check_partition_info(THD *thd, handlerton **eng_type,
handler *file, ulonglong max_rows); handler *file, ulonglong max_rows);
void print_no_partition_found(TABLE *table);
private: private:
static int list_part_cmp(const void* a, const void* b); static int list_part_cmp(const void* a, const void* b);
static int list_part_cmp_unsigned(const void* a, const void* b);
bool set_up_default_partitions(handler *file, ulonglong max_rows, bool set_up_default_partitions(handler *file, ulonglong max_rows,
uint start_no); uint start_no);
bool set_up_default_subpartitions(handler *file, ulonglong max_rows); bool set_up_default_subpartitions(handler *file, ulonglong max_rows);
......
...@@ -5810,6 +5810,9 @@ ER_NDB_CANT_SWITCH_BINLOG_FORMAT ...@@ -5810,6 +5810,9 @@ ER_NDB_CANT_SWITCH_BINLOG_FORMAT
eng "The NDB cluster engine does not support changing the binlog format on the fly yet" eng "The NDB cluster engine does not support changing the binlog format on the fly yet"
ER_PARTITION_NO_TEMPORARY ER_PARTITION_NO_TEMPORARY
eng "Cannot create temporary table with partitions" eng "Cannot create temporary table with partitions"
ER_PARTITION_CONST_DOMAIN_ERROR
eng "Partition constant is out of partition function domain"
swe "Partitionskonstanten r utanfr partitioneringsfunktionens domn"
ER_PARTITION_FUNCTION_IS_NOT_ALLOWED ER_PARTITION_FUNCTION_IS_NOT_ALLOWED
eng "This partition function is not allowed" eng "This partition function is not allowed"
swe "Denna partitioneringsfunktion r inte tillten" swe "Denna partitioneringsfunktion r inte tillten"
......
This diff is collapsed.
...@@ -65,9 +65,8 @@ int get_part_for_delete(const byte *buf, const byte *rec0, ...@@ -65,9 +65,8 @@ int get_part_for_delete(const byte *buf, const byte *rec0,
partition_info *part_info, uint32 *part_id); partition_info *part_info, uint32 *part_id);
void prune_partition_set(const TABLE *table, part_id_range *part_spec); void prune_partition_set(const TABLE *table, part_id_range *part_spec);
bool check_partition_info(partition_info *part_info,handlerton **eng_type, bool check_partition_info(partition_info *part_info,handlerton **eng_type,
handler *file, ulonglong max_rows); TABLE *table, handler *file, ulonglong max_rows);
bool fix_partition_func(THD *thd, const char *name, TABLE *table, bool fix_partition_func(THD *thd, TABLE *table, bool create_table_ind);
bool create_table_ind);
char *generate_partition_syntax(partition_info *part_info, char *generate_partition_syntax(partition_info *part_info,
uint *buf_length, bool use_sql_alloc, uint *buf_length, bool use_sql_alloc,
bool show_partition_options); bool show_partition_options);
...@@ -91,6 +90,8 @@ uint32 get_list_array_idx_for_endpoint(partition_info *part_info, ...@@ -91,6 +90,8 @@ uint32 get_list_array_idx_for_endpoint(partition_info *part_info,
uint32 get_partition_id_range_for_endpoint(partition_info *part_info, uint32 get_partition_id_range_for_endpoint(partition_info *part_info,
bool left_endpoint, bool left_endpoint,
bool include_endpoint); bool include_endpoint);
bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table,
bool is_sub_part, bool is_field_to_be_setup);
/* /*
A "Get next" function for partition iterator. A "Get next" function for partition iterator.
......
...@@ -4000,8 +4000,8 @@ static int get_schema_partitions_record(THD *thd, struct st_table_list *tables, ...@@ -4000,8 +4000,8 @@ static int get_schema_partitions_record(THD *thd, struct st_table_list *tables,
} }
else if (part_info->part_type == LIST_PARTITION) else if (part_info->part_type == LIST_PARTITION)
{ {
List_iterator<longlong> list_val_it(part_elem->list_val_list); List_iterator<part_elem_value> list_val_it(part_elem->list_val_list);
longlong *list_value; part_elem_value *list_value;
uint no_items= part_elem->list_val_list.elements; uint no_items= part_elem->list_val_list.elements;
tmp_str.length(0); tmp_str.length(0);
tmp_res.length(0); tmp_res.length(0);
...@@ -4013,7 +4013,10 @@ static int get_schema_partitions_record(THD *thd, struct st_table_list *tables, ...@@ -4013,7 +4013,10 @@ static int get_schema_partitions_record(THD *thd, struct st_table_list *tables,
} }
while ((list_value= list_val_it++)) while ((list_value= list_val_it++))
{ {
tmp_res.set(*list_value, cs); if (!list_value->unsigned_flag)
tmp_res.set(list_value->value, cs);
else
tmp_res.set((ulonglong)list_value->value, cs);
tmp_str.append(tmp_res); tmp_str.append(tmp_res);
if (--no_items != 0) if (--no_items != 0)
tmp_str.append(","); tmp_str.append(",");
......
...@@ -3144,7 +3144,7 @@ bool mysql_create_table_internal(THD *thd, ...@@ -3144,7 +3144,7 @@ bool mysql_create_table_internal(THD *thd,
} }
DBUG_PRINT("info", ("db_type = %d", DBUG_PRINT("info", ("db_type = %d",
ha_legacy_type(part_info->default_engine_type))); ha_legacy_type(part_info->default_engine_type)));
if (part_info->check_partition_info(&engine_type, file, if (part_info->check_partition_info(thd, &engine_type, file,
create_info->max_rows)) create_info->max_rows))
goto err; goto err;
part_info->default_engine_type= engine_type; part_info->default_engine_type= engine_type;
......
...@@ -42,12 +42,6 @@ ...@@ -42,12 +42,6 @@
#include <myisam.h> #include <myisam.h>
#include <myisammrg.h> #include <myisammrg.h>
typedef struct p_elem_val
{
longlong value;
bool null_value;
} part_elem_value;
int yylex(void *yylval, void *yythd); int yylex(void *yylval, void *yythd);
const LEX_STRING null_lex_str={0,0}; const LEX_STRING null_lex_str={0,0};
...@@ -3553,7 +3547,7 @@ opt_part_values: ...@@ -3553,7 +3547,7 @@ opt_part_values:
; ;
part_func_max: part_func_max:
MAX_VALUE_SYM max_value_sym
{ {
LEX *lex= Lex; LEX *lex= Lex;
if (lex->part_info->defined_max_value) if (lex->part_info->defined_max_value)
...@@ -3562,6 +3556,7 @@ part_func_max: ...@@ -3562,6 +3556,7 @@ part_func_max:
YYABORT; YYABORT;
} }
lex->part_info->defined_max_value= TRUE; lex->part_info->defined_max_value= TRUE;
lex->part_info->curr_part_elem->max_value= TRUE;
lex->part_info->curr_part_elem->range_value= LONGLONG_MAX; lex->part_info->curr_part_elem->range_value= LONGLONG_MAX;
} }
| part_range_func | part_range_func
...@@ -3579,10 +3574,18 @@ part_func_max: ...@@ -3579,10 +3574,18 @@ part_func_max:
} }
; ;
max_value_sym:
MAX_VALUE_SYM
| '(' MAX_VALUE_SYM ')'
;
part_range_func: part_range_func:
'(' part_bit_expr ')' '(' part_bit_expr ')'
{ {
Lex->part_info->curr_part_elem->range_value= $2->value; partition_info *part_info= Lex->part_info;
if (!($2->unsigned_flag))
part_info->curr_part_elem->signed_flag= TRUE;
part_info->curr_part_elem->range_value= $2->value;
} }
; ;
...@@ -3595,9 +3598,12 @@ part_list_item: ...@@ -3595,9 +3598,12 @@ part_list_item:
part_bit_expr part_bit_expr
{ {
part_elem_value *value_ptr= $1; part_elem_value *value_ptr= $1;
partition_info *part_info= Lex->part_info;
if (!value_ptr->unsigned_flag)
part_info->curr_part_elem->signed_flag= TRUE;
if (!value_ptr->null_value && if (!value_ptr->null_value &&
Lex->part_info->curr_part_elem-> part_info->curr_part_elem->
list_val_list.push_back((longlong*) &value_ptr->value)) list_val_list.push_back(value_ptr))
{ {
mem_alloc_error(sizeof(part_elem_value)); mem_alloc_error(sizeof(part_elem_value));
YYABORT; YYABORT;
...@@ -3638,6 +3644,10 @@ part_bit_expr: ...@@ -3638,6 +3644,10 @@ part_bit_expr:
} }
thd->where= save_where; thd->where= save_where;
value_ptr->value= part_expr->val_int(); value_ptr->value= part_expr->val_int();
value_ptr->unsigned_flag= TRUE;
if (!part_expr->unsigned_flag &&
value_ptr->value < 0)
value_ptr->unsigned_flag= FALSE;
if ((value_ptr->null_value= part_expr->null_value)) if ((value_ptr->null_value= part_expr->null_value))
{ {
if (Lex->part_info->curr_part_elem->has_null_value) if (Lex->part_info->curr_part_elem->has_null_value)
......
...@@ -1481,8 +1481,7 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias, ...@@ -1481,8 +1481,7 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
outparam->part_info->is_auto_partitioned= share->auto_partitioned; outparam->part_info->is_auto_partitioned= share->auto_partitioned;
DBUG_PRINT("info", ("autopartitioned: %u", share->auto_partitioned)); DBUG_PRINT("info", ("autopartitioned: %u", share->auto_partitioned));
if (!tmp) if (!tmp)
tmp= fix_partition_func(thd, share->normalized_path.str, outparam, tmp= fix_partition_func(thd, outparam, is_create_table);
is_create_table);
*root_ptr= old_root; *root_ptr= old_root;
if (tmp) if (tmp)
goto err; goto err;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment