summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <tomas@poseidon.ndb.mysql.com>2006-03-01 15:24:46 +0100
committerunknown <tomas@poseidon.ndb.mysql.com>2006-03-01 15:24:46 +0100
commit22aa6a339748d8dbc5c519c6c5e86e476db755db (patch)
tree25a9483581b700ad2b60a25611c65541ec9b56ad
parentaf47b36d7151ffbc7e1f7c144c93ef0869635a1d (diff)
downloadmariadb-git-22aa6a339748d8dbc5c519c6c5e86e476db755db.tar.gz
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
-rw-r--r--mysql-test/r/ndb_partition_range.result38
-rw-r--r--mysql-test/t/ndb_partition_range.test31
-rw-r--r--sql/ha_ndbcluster.cc37
-rw-r--r--sql/ha_ndbcluster.h4
4 files changed, 96 insertions, 14 deletions
diff --git a/mysql-test/r/ndb_partition_range.result b/mysql-test/r/ndb_partition_range.result
index 546c0b1196c..5297e2a733d 100644
--- a/mysql-test/r/ndb_partition_range.result
+++ b/mysql-test/r/ndb_partition_range.result
@@ -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;
diff --git a/mysql-test/t/ndb_partition_range.test b/mysql-test/t/ndb_partition_range.test
index 5b70b26c97b..e64dc80886a 100644
--- a/mysql-test/t/ndb_partition_range.test
+++ b/mysql-test/t/ndb_partition_range.test
@@ -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;
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index 17b999f8134..dc95ead2e97 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -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
diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h
index 5a65dcc0531..7498d2bb624 100644
--- a/sql/ha_ndbcluster.h
+++ b/sql/ha_ndbcluster.h
@@ -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,