Commit 39c03f0d authored by unknown's avatar unknown
Browse files

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


mysql-test/r/ndb_partition_range.result:
  Bug #16385 Partitions: crash when updating a range partitioned NDB table
  Bug #17806 Update on NDB table with list partition causes mysqld to core
mysql-test/t/ndb_partition_range.test:
  Bug #16385 Partitions: crash when updating a range partitioned NDB table
  Bug #17806 Update on NDB table with list partition causes mysqld to core
sql/ha_ndbcluster.h:
  Bug #16385 Partitions: crash when updating a range partitioned NDB table
  Bug #17806 Update on NDB table with list partition causes mysqld to core
parent eab8bb65
Loading
Loading
Loading
Loading
+38 −0
Original line number Diff line number Diff line
@@ -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;
+31 −0
Original line number Diff line number Diff line
@@ -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;
+25 −12
Original line number Diff line number Diff line
@@ -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,
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)))
  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
+2 −2
Original line number Diff line number Diff line
@@ -731,7 +731,7 @@ static void set_tabname(const char *pathname, char *tabname);
  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,
  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,