Bug #16385 Partitions: crash when updating a range partitioned NDB table

Bug #17806 Update on NDB table with list partition causes mysqld to core
- modified complemented_pk_read to be complemented_read, and handle also hidden key
parent 7c14d9ea
......@@ -223,3 +223,41 @@ SELECT * FROM t1;
id b1 vc bc d f total y t
2 NULL NULL NULL NULL NULL NULL NULL NULL
DROP TABLE t1;
CREATE TABLE t1 (
a int not null,
b int not null,
c int not null)
partition by list(a)
partitions 2
(partition x123 values in (1,5,6),
partition x234 values in (4,7,8));
INSERT into t1 VALUES (5,1,1);
select * from t1;
a b c
5 1 1
UPDATE t1 SET a=8 WHERE a=5 AND b=1;
select * from t1;
a b c
8 1 1
drop table t1;
CREATE TABLE t1 ( f1 INTEGER, f2 char(20)) engine=ndb
PARTITION BY RANGE(f1)
( PARTITION part1 VALUES LESS THAN (2),
PARTITION part2 VALUES LESS THAN (1000));
INSERT INTO t1 VALUES(1, '---1---');
INSERT INTO t1 VALUES(2, '---2---');
select * from t1;
f1 f2
1 ---1---
2 ---2---
UPDATE t1 SET f1 = f1 + 4 WHERE f1 = 2;
select * from t1;
f1 f2
1 ---1---
6 ---2---
UPDATE t1 SET f1 = f1 + 4 WHERE f1 = 1;
select * from t1;
f1 f2
5 ---1---
6 ---2---
drop table t1;
......@@ -227,3 +227,34 @@ ALTER TABLE t1 ADD PARTITION
(PARTITION p2 VALUES IN (412));
SELECT * FROM t1;
DROP TABLE t1;
#
# Bug #17806 Update on NDB table with list partition causes mysqld to core
# Bug #16385 Partitions: crash when updating a range partitioned NDB table
#
CREATE TABLE t1 (
a int not null,
b int not null,
c int not null)
partition by list(a)
partitions 2
(partition x123 values in (1,5,6),
partition x234 values in (4,7,8));
INSERT into t1 VALUES (5,1,1);
select * from t1;
UPDATE t1 SET a=8 WHERE a=5 AND b=1;
select * from t1;
drop table t1;
CREATE TABLE t1 ( f1 INTEGER, f2 char(20)) engine=ndb
PARTITION BY RANGE(f1)
( PARTITION part1 VALUES LESS THAN (2),
PARTITION part2 VALUES LESS THAN (1000));
INSERT INTO t1 VALUES(1, '---1---');
INSERT INTO t1 VALUES(2, '---2---');
select * from t1;
UPDATE t1 SET f1 = f1 + 4 WHERE f1 = 2;
select * from t1;
UPDATE t1 SET f1 = f1 + 4 WHERE f1 = 1;
select * from t1;
drop table t1;
......@@ -1684,15 +1684,16 @@ int ha_ndbcluster::pk_read(const byte *key, uint key_len, byte *buf,
/*
Read one complementing record from NDB using primary key from old_data
or hidden key
*/
int ha_ndbcluster::complemented_pk_read(const byte *old_data, byte *new_data,
uint32 old_part_id)
int ha_ndbcluster::complemented_read(const byte *old_data, byte *new_data,
uint32 old_part_id)
{
uint no_fields= table_share->fields, i;
NdbTransaction *trans= m_active_trans;
NdbOperation *op;
DBUG_ENTER("complemented_pk_read");
DBUG_ENTER("complemented_read");
m_write_op= FALSE;
if (ha_get_all_bit_in_read_set())
......@@ -1706,9 +1707,17 @@ int ha_ndbcluster::complemented_pk_read(const byte *old_data, byte *new_data,
if (!(op= trans->getNdbOperation((const NDBTAB *) m_table)) ||
op->readTuple(lm) != 0)
ERR_RETURN(trans->getNdbError());
int res;
if ((res= set_primary_key_from_record(op, old_data)))
ERR_RETURN(trans->getNdbError());
if (table_share->primary_key != MAX_KEY)
{
if (set_primary_key_from_record(op, old_data))
ERR_RETURN(trans->getNdbError());
}
else
{
// This table has no primary key, use "hidden" primary key
if (set_hidden_key(op, table->s->fields, m_ref))
ERR_RETURN(op->getNdbError());
}
if (m_use_partition_function)
op->setPartitionId(old_part_id);
......@@ -2501,19 +2510,23 @@ int ha_ndbcluster::update_row(const byte *old_data, byte *new_data)
DBUG_RETURN(error);
}
/* Check for update of primary key for special handling */
if ((table_share->primary_key != MAX_KEY) &&
(key_cmp(table_share->primary_key, old_data, new_data)) ||
/*
* Check for update of primary key or partition change
* for special handling
*/
if (((table_share->primary_key != MAX_KEY) &&
key_cmp(table_share->primary_key, old_data, new_data)) ||
(old_part_id != new_part_id))
{
int read_res, insert_res, delete_res, undo_res;
DBUG_PRINT("info", ("primary key update, doing pk read+delete+insert"));
DBUG_PRINT("info", ("primary key update or partition change, "
"doing read+delete+insert"));
// Get all old fields, since we optimize away fields not in query
read_res= complemented_pk_read(old_data, new_data, old_part_id);
read_res= complemented_read(old_data, new_data, old_part_id);
if (read_res)
{
DBUG_PRINT("info", ("pk read failed"));
DBUG_PRINT("info", ("read failed"));
DBUG_RETURN(read_res);
}
// Delete old row
......
......@@ -731,8 +731,8 @@ private:
char* get_tablespace_name(THD *thd);
int set_range_data(void *tab, partition_info* part_info);
int set_list_data(void *tab, partition_info* part_info);
int complemented_pk_read(const byte *old_data, byte *new_data,
uint32 old_part_id);
int complemented_read(const byte *old_data, byte *new_data,
uint32 old_part_id);
int pk_read(const byte *key, uint key_len, byte *buf, uint32 part_id);
int ordered_index_scan(const key_range *start_key,
const key_range *end_key,
......
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