diff options
author | Sachin <sachinsetia1001@gmail.com> | 2020-09-14 15:27:02 +0100 |
---|---|---|
committer | Sachin <sachinsetia1001@gmail.com> | 2020-09-14 20:08:18 +0100 |
commit | 56f2b3d12b68a34aaa4d4622912d8d838902d917 (patch) | |
tree | 7d6d28cd8209ea16dbbcd4e97a9d64930915223b | |
parent | af834c218a59b0f187edb19aa4f8bd476b9ed6ac (diff) | |
download | mariadb-git-bb-10.4-sachin.tar.gz |
MDEV-23264 Unique blobs allow duplicate values upon UPDATEbb-10.4-sachin
Problem:-
We are able to insert duplicate value in table because cmp_binary_offset
is not able to differentiate between NULL and empty string. So
check_duplicate_long_entry_key is never called and we don't check for
duplicate.
Solution
Added a if condition with is_null() on field which can differentiate
between NULL and empty string.
-rw-r--r-- | mysql-test/main/long_unique_bugs.result | 9 | ||||
-rw-r--r-- | mysql-test/main/long_unique_bugs.test | 11 | ||||
-rw-r--r-- | sql/handler.cc | 9 |
3 files changed, 27 insertions, 2 deletions
diff --git a/mysql-test/main/long_unique_bugs.result b/mysql-test/main/long_unique_bugs.result index 72dab5bb181..a9d96de5073 100644 --- a/mysql-test/main/long_unique_bugs.result +++ b/mysql-test/main/long_unique_bugs.result @@ -288,3 +288,12 @@ Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_par t2 0 a 1 a A NULL NULL NULL YES HASH t2 0 a 2 b A NULL NULL NULL YES HASH DROP TABLE t1,t2; +CREATE TABLE t1 (f TEXT UNIQUE); +INSERT INTO t1 VALUES (NULL),(NULL); +UPDATE t1 SET f = ''; +ERROR 23000: Duplicate entry '' for key 'f' +SELECT * FROM t1; +f + +NULL +DROP TABLE t1; diff --git a/mysql-test/main/long_unique_bugs.test b/mysql-test/main/long_unique_bugs.test index 34d02b1c8f4..4d7a59a066b 100644 --- a/mysql-test/main/long_unique_bugs.test +++ b/mysql-test/main/long_unique_bugs.test @@ -368,3 +368,14 @@ show index from t2; # Cleanup DROP TABLE t1,t2; + +# +# MDEV-23264 Unique blobs allow duplicate values upon UPDATE +# + +CREATE TABLE t1 (f TEXT UNIQUE); +INSERT INTO t1 VALUES (NULL),(NULL); +--error ER_DUP_ENTRY +UPDATE t1 SET f = ''; +SELECT * FROM t1; +DROP TABLE t1; diff --git a/sql/handler.cc b/sql/handler.cc index 40dea349272..71e6a904f23 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -6699,8 +6699,13 @@ static int check_duplicate_long_entries_update(TABLE *table, handler *h, uchar * for (uint j= 0; j < key_parts; j++, keypart++) { field= keypart->field; - /* Compare fields if they are different then check for duplicates*/ - if(field->cmp_binary_offset(reclength)) + /* + Compare fields if they are different then check for duplicates + cmp_binary_offset cannot differentiate between null and empty string + So also check for that too + */ + if((field->is_null(0) != field->is_null(reclength)) || + field->cmp_binary_offset(reclength)) { if((error= check_duplicate_long_entry_key(table, table->update_handler, new_rec, i))) |