summaryrefslogtreecommitdiff
path: root/sql/opt_range.cc
diff options
context:
space:
mode:
authormonty@donna.mysql.fi <>2001-04-10 11:32:28 +0300
committermonty@donna.mysql.fi <>2001-04-10 11:32:28 +0300
commit3c82d4a2e1d678d2b14023577b64c1fc90d35757 (patch)
tree95bbcccc6e046548f22eead9222fdd1cce980d1e /sql/opt_range.cc
parent7f21a7a6daff97675749db987b12a080bb4c3799 (diff)
downloadmariadb-git-3c82d4a2e1d678d2b14023577b64c1fc90d35757.tar.gz
Fixed bug with UPDATE/DELETE on UNIQUE key which could be NULL
Diffstat (limited to 'sql/opt_range.cc')
-rw-r--r--sql/opt_range.cc32
1 files changed, 29 insertions, 3 deletions
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
****************************************************************************/