bug#21507 I can't create a unique hash index in NDB: Added possibillity to...

bug#21507 I can't create a unique hash index in NDB: Added possibillity to create hash only indexes with NULL valued attributes, but any NULL valued access will become full table scan with pushed condition on index attribute values
parent 7acfde91
......@@ -140,7 +140,40 @@ b int unsigned not null,
c int unsigned,
UNIQUE USING HASH (b, c)
) engine=ndbcluster;
ERROR 42000: Column 'c' is used with UNIQUE or INDEX but is not defined as NOT NULL
Warnings:
Warning 1121 Ndb does not support unique index on NULL valued attributes, index access with NULL value will become full table scan
insert t2 values(1,1,NULL),(2,2,2),(3,3,NULL),(4,4,4),(5,5,NULL),(6,6,6),(7,7,NULL),(8,3,NULL),(9,3,NULL);
select * from t2 where c IS NULL order by a;
a b c
1 1 NULL
3 3 NULL
5 5 NULL
7 7 NULL
8 3 NULL
9 3 NULL
select * from t2 where b = 3 AND c IS NULL order by a;
a b c
3 3 NULL
8 3 NULL
9 3 NULL
select * from t2 where (b = 3 OR b = 5) AND c IS NULL order by a;
a b c
3 3 NULL
5 5 NULL
8 3 NULL
9 3 NULL
set @old_ecpd = @@session.engine_condition_pushdown;
set engine_condition_pushdown = true;
explain select * from t2 where (b = 3 OR b = 5) AND c IS NULL AND a < 9 order by a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range PRIMARY,b PRIMARY 4 NULL 1 Using where with pushed condition
select * from t2 where (b = 3 OR b = 5) AND c IS NULL AND a < 9 order by a;
a b c
3 3 NULL
5 5 NULL
8 3 NULL
set engine_condition_pushdown = @old_ecpd;
drop table t2;
CREATE TABLE t3 (
a int unsigned NOT NULL,
b int unsigned not null,
......
......@@ -85,7 +85,6 @@ select * from t2 order by a;
drop table t2;
-- error 1121
CREATE TABLE t2 (
a int unsigned NOT NULL PRIMARY KEY,
b int unsigned not null,
......@@ -93,6 +92,20 @@ CREATE TABLE t2 (
UNIQUE USING HASH (b, c)
) engine=ndbcluster;
insert t2 values(1,1,NULL),(2,2,2),(3,3,NULL),(4,4,4),(5,5,NULL),(6,6,6),(7,7,NULL),(8,3,NULL),(9,3,NULL);
select * from t2 where c IS NULL order by a;
select * from t2 where b = 3 AND c IS NULL order by a;
select * from t2 where (b = 3 OR b = 5) AND c IS NULL order by a;
set @old_ecpd = @@session.engine_condition_pushdown;
set engine_condition_pushdown = true;
explain select * from t2 where (b = 3 OR b = 5) AND c IS NULL AND a < 9 order by a;
select * from t2 where (b = 3 OR b = 5) AND c IS NULL AND a < 9 order by a;
set engine_condition_pushdown = @old_ecpd;
drop table t2;
#
# Show use of PRIMARY KEY USING HASH indexes
#
......
This diff is collapsed.
......@@ -56,6 +56,7 @@ typedef struct ndb_index_data {
void *index;
void *unique_index;
unsigned char *unique_index_attrid_map;
bool null_in_unique_index;
} NDB_INDEX_DATA;
typedef struct st_ndbcluster_share {
......@@ -546,7 +547,9 @@ class ha_ndbcluster: public handler
KEY_MULTI_RANGE*ranges, uint range_count,
bool sorted, HANDLER_BUFFER *buffer);
int read_multi_range_next(KEY_MULTI_RANGE **found_range_p);
bool null_value_index_search(KEY_MULTI_RANGE *ranges,
KEY_MULTI_RANGE *end_range,
HANDLER_BUFFER *buffer);
bool get_error_message(int error, String *buf);
int info(uint);
int extra(enum ha_extra_function operation);
......@@ -649,7 +652,8 @@ private:
void release_metadata();
NDB_INDEX_TYPE get_index_type(uint idx_no) const;
NDB_INDEX_TYPE get_index_type_from_table(uint index_no) const;
int check_index_fields_not_null(uint index_no);
bool has_null_in_unique_index(uint idx_no) const;
bool check_index_fields_not_null(uint index_no);
int pk_read(const byte *key, uint key_len, byte *buf);
int complemented_pk_read(const byte *old_data, byte *new_data);
......@@ -663,6 +667,11 @@ private:
int ordered_index_scan(const key_range *start_key,
const key_range *end_key,
bool sorted, bool descending, byte* buf);
int unique_index_scan(const KEY* key_info,
const byte *key,
uint key_len,
byte *buf);
int full_table_scan(byte * buf);
int fetch_next(NdbScanOperation* op);
int next_result(byte *buf);
......@@ -725,6 +734,13 @@ bool uses_blob_value(bool all_fields);
int build_scan_filter(Ndb_cond* &cond, NdbScanFilter* filter);
int generate_scan_filter(Ndb_cond_stack* cond_stack,
NdbScanOperation* op);
int generate_scan_filter_from_cond(Ndb_cond_stack* cond_stack,
NdbScanFilter& filter);
int generate_scan_filter_from_key(NdbScanOperation* op,
const KEY* key_info,
const byte *key,
uint key_len,
byte *buf);
friend int execute_commit(ha_ndbcluster*, NdbTransaction*);
friend int execute_no_commit(ha_ndbcluster*, NdbTransaction*, bool);
......
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