mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
ndb_insert.test, ndb_insert.result, ha_ndbcluster.cc:
Bug#27980 INSERT IGNORE wrongly ignores NULLs in unique index: added check for null values mysql-test/t/ndb_insert.test: Bug#27980 INSERT IGNORE wrongly ignores NULLs in unique index: added check for null values sql/ha_ndbcluster.cc: Bug#27980 INSERT IGNORE wrongly ignores NULLs in unique index: added check for null values mysql-test/r/ndb_insert.result: Bug#27980 INSERT IGNORE wrongly ignores NULLs in unique index: added check for null values
This commit is contained in:
@ -649,3 +649,11 @@ pk a
|
|||||||
6 NULL
|
6 NULL
|
||||||
7 4
|
7 4
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
create table t1(a int primary key, b int, unique key(b)) engine=ndb;
|
||||||
|
insert ignore into t1 values (1,0), (2,0), (2,null), (3,null);
|
||||||
|
select * from t1 order by a;
|
||||||
|
a b
|
||||||
|
1 0
|
||||||
|
2 NULL
|
||||||
|
3 NULL
|
||||||
|
drop table t1;
|
||||||
|
@ -630,4 +630,13 @@ INSERT IGNORE INTO t1 VALUES (4,NULL),(5,NULL),(6,NULL),(7,4);
|
|||||||
SELECT * FROM t1 ORDER BY pk;
|
SELECT * FROM t1 ORDER BY pk;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #27980 INSERT IGNORE wrongly ignores NULLs in unique index
|
||||||
|
#
|
||||||
|
|
||||||
|
create table t1(a int primary key, b int, unique key(b)) engine=ndb;
|
||||||
|
insert ignore into t1 values (1,0), (2,0), (2,null), (3,null);
|
||||||
|
select * from t1 order by a;
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
# End of 4.1 tests
|
# End of 4.1 tests
|
||||||
|
@ -1630,6 +1630,34 @@ bool ha_ndbcluster::check_all_operations_for_error(NdbTransaction *trans,
|
|||||||
DBUG_RETURN(true);
|
DBUG_RETURN(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if record contains any null valued columns that are part of a key
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
int
|
||||||
|
check_null_in_record(const KEY* key_info, const byte *record)
|
||||||
|
{
|
||||||
|
KEY_PART_INFO *curr_part, *end_part;
|
||||||
|
curr_part= key_info->key_part;
|
||||||
|
end_part= curr_part + key_info->key_parts;
|
||||||
|
|
||||||
|
while (curr_part != end_part)
|
||||||
|
{
|
||||||
|
if (curr_part->null_bit &&
|
||||||
|
(record[curr_part->null_offset] & curr_part->null_bit))
|
||||||
|
return 1;
|
||||||
|
curr_part++;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
/*
|
||||||
|
We could instead pre-compute a bitmask in table_share with one bit for
|
||||||
|
every null-bit in the key, and so check this just by OR'ing the bitmask
|
||||||
|
with the null bitmap in the record.
|
||||||
|
But not sure it's worth it.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Peek to check if any rows already exist with conflicting
|
* Peek to check if any rows already exist with conflicting
|
||||||
* primary key or unique index values
|
* primary key or unique index values
|
||||||
@ -1671,7 +1699,17 @@ int ha_ndbcluster::peek_indexed_rows(const byte *record, bool check_pk)
|
|||||||
if (i != table->s->primary_key &&
|
if (i != table->s->primary_key &&
|
||||||
key_info->flags & HA_NOSAME)
|
key_info->flags & HA_NOSAME)
|
||||||
{
|
{
|
||||||
// A unique index is defined on table
|
/*
|
||||||
|
A unique index is defined on table.
|
||||||
|
We cannot look up a NULL field value in a unique index. But since
|
||||||
|
keys with NULLs are not indexed, such rows cannot conflict anyway, so
|
||||||
|
we just skip the index in this case.
|
||||||
|
*/
|
||||||
|
if (check_null_in_record(key_info, record))
|
||||||
|
{
|
||||||
|
DBUG_PRINT("info", ("skipping check for key with NULL"));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
NdbIndexOperation *iop;
|
NdbIndexOperation *iop;
|
||||||
NDBINDEX *unique_index = (NDBINDEX *) m_index[i].unique_index;
|
NDBINDEX *unique_index = (NDBINDEX *) m_index[i].unique_index;
|
||||||
key_part= key_info->key_part;
|
key_part= key_info->key_part;
|
||||||
@ -2816,7 +2854,7 @@ int ha_ndbcluster::index_end()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if key contains null
|
* Check if key contains nullable columns
|
||||||
*/
|
*/
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
|
Reference in New Issue
Block a user