summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSachin <sachinsetia1001@gmail.com>2020-09-14 15:27:02 +0100
committerSachin <sachinsetia1001@gmail.com>2020-09-14 20:08:18 +0100
commit56f2b3d12b68a34aaa4d4622912d8d838902d917 (patch)
tree7d6d28cd8209ea16dbbcd4e97a9d64930915223b
parentaf834c218a59b0f187edb19aa4f8bd476b9ed6ac (diff)
downloadmariadb-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.result9
-rw-r--r--mysql-test/main/long_unique_bugs.test11
-rw-r--r--sql/handler.cc9
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)))