diff options
author | unknown <monty@donna.mysql.fi> | 2001-04-10 11:32:28 +0300 |
---|---|---|
committer | unknown <monty@donna.mysql.fi> | 2001-04-10 11:32:28 +0300 |
commit | 92de72694b78d41980c48b8a6fedf10f153bb56e (patch) | |
tree | 95bbcccc6e046548f22eead9222fdd1cce980d1e /sql | |
parent | c7105d8008aa42e90e830ede25e7cbf0c22893c0 (diff) | |
download | mariadb-git-92de72694b78d41980c48b8a6fedf10f153bb56e.tar.gz |
Fixed bug with UPDATE/DELETE on UNIQUE key which could be NULL
Docs/manual.texi:
Updated replication section
mysql-test/r/null_key.result:
Added test UPDATE/DELETE with IS NULL on unique key
mysql-test/t/null_key.test:
Added test UPDATE/DELETE with IS NULL on unique key
mysys/Makefile.am:
Removed -f from $CP as this is not portable
Fixed rule for testhash
sql/field.cc:
Safety fix
sql/opt_range.cc:
Fixed bug with UPDATE/DELETE on UNIQUE key which could be NULL
sql/opt_range.h:
Fixed bug with UPDATE/DELETE on UNIQUE key which could be NULL
Diffstat (limited to 'sql')
-rw-r--r-- | sql/field.cc | 2 | ||||
-rw-r--r-- | sql/opt_range.cc | 32 | ||||
-rw-r--r-- | sql/opt_range.h | 1 |
3 files changed, 31 insertions, 4 deletions
diff --git a/sql/field.cc b/sql/field.cc index f2310dd0229..f7dbd3c72f0 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -3891,7 +3891,7 @@ String *Field_blob::val_str(String *val_buffer __attribute__((unused)), char *blob; memcpy_fixed(&blob,ptr+packlength,sizeof(char*)); if (!blob) - val_ptr->length(0); + val_ptr->set("",0); // A bit safer than ->length(0) else val_ptr->set((const char*) blob,get_length(ptr)); return val_ptr; diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 4c1a0db72b7..eedae87719d 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -321,7 +321,7 @@ static bool get_quick_keys(PARAM *param,QUICK_SELECT *quick,KEY_PART *key, static bool eq_tree(SEL_ARG* a,SEL_ARG *b); static SEL_ARG null_element(SEL_ARG::IMPOSSIBLE); - +static bool null_part_in_key(KEY_PART *key_part, const char *key, uint length); /*************************************************************************** ** Basic functions for SQL_SELECT and QUICK_SELECT @@ -2306,7 +2306,15 @@ get_quick_keys(PARAM *param,QUICK_SELECT *quick,KEY_PART *key, KEY *table_key=quick->head->key_info+quick->index; flag=EQ_RANGE; if (table_key->flags & HA_NOSAME && key->part == table_key->key_parts-1) - flag|= UNIQUE_RANGE; + { + if (!(table_key->flags & HA_NULL_PART_KEY) || + !null_part_in_key(key, + param->min_key, + (uint) (tmp_min_key - param->min_key))) + flag|= UNIQUE_RANGE; + else + flag|= NULL_RANGE; + } } } @@ -2339,7 +2347,7 @@ bool QUICK_SELECT::unique_key_range() if (ranges.elements == 1) { QUICK_RANGE *tmp; - if ((tmp=ranges.head())->flag & EQ_RANGE) + if (((tmp=ranges.head())->flag & (EQ_RANGE | NULL_RANGE)) == EQ_RANGE) { KEY *key=head->key_info+index; return ((key->flags & HA_NOSAME) && @@ -2349,6 +2357,24 @@ bool QUICK_SELECT::unique_key_range() return 0; } + +/* Returns true if any part of the key is NULL */ + +static bool null_part_in_key(KEY_PART *key_part, const char *key, uint length) +{ + for (const char *end=key+length ; + key < end; + key+= key_part++->part_length) + { + if (key_part->null_bit) + { + if (*key++) + return 1; + } + } + return 0; +} + /**************************************************************************** ** Create a QUICK RANGE based on a key ****************************************************************************/ diff --git a/sql/opt_range.h b/sql/opt_range.h index 2005773eca7..247dd260817 100644 --- a/sql/opt_range.h +++ b/sql/opt_range.h @@ -30,6 +30,7 @@ #define NEAR_MAX 8 #define UNIQUE_RANGE 16 #define EQ_RANGE 32 +#define NULL_RANGE 64 typedef struct st_key_part { uint16 key,part,part_length; |