[MDEV-32839] LONG UNIQUE gives error when used with REPLACE Created: 2023-11-19  Updated: 2023-12-12  Resolved: 2023-12-12

Status: Closed
Project: MariaDB Server
Component/s: Data Manipulation - Insert
Affects Version/s: 10.5, 10.6, 10.11, 11.0, 11.1, 11.2
Fix Version/s: 10.5.24, 10.6.17, 10.11.7, 11.0.5, 11.1.4, 11.2.3

Type: Bug Priority: Blocker
Reporter: Michael Widenius Assignee: Sergei Golubchik
Resolution: Fixed Votes: 1
Labels: None

Issue Links:
Relates
relates to MDEV-33003 long uniques don't work with spider Open
relates to MDEV-32837 long unique does not work like unique... Closed

 Description   

REPLACE with unique key works in some cases, not in other cases:

CREATE OR REPLACE TABLE t1 (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `M_Number` varchar(30) DEFAULT NULL,
  `A_Number` varchar(30) DEFAULT NULL,
  `Type` varchar(255) DEFAULT NULL,
  `S_Id` varchar(30) DEFAULT NULL,
  `U_Id` varchar(255) DEFAULT NULL,
  `IND` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE `problem_key` (`A_Number`,`S_Id`,`U_Id`,`M_Number`,`Type`,`IND`) USING HASH
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci;
INSERT INTO  t1 (`M_Number`, `A_Number`, `Type`, `S_Id`, `U_Id`, `IND`) VALUES ('00004', '0001009089999', '', 'NETSTES', 'PSIT', 'D');
REPLACE INTO  t1 (`M_Number`, `A_Number`, `Type`, `S_Id`, `U_Id`, `IND`) VALUES ('00004', '0001009089999', '', 'NETSTES', 'PSIT', 'D');
INSERT INTO  t1 (`M_Number`, `A_Number`, `Type`, `S_Id`, `U_Id`, `IND`) VALUES ('00004', '0001009089999', '', 'NETSTES', 'PSIT', 'E');
# This should not generate a duplicate key error
REPLACE INTO  t1 (`M_Number`, `A_Number`, `Type`, `S_Id`, `U_Id`, `IND`) VALUES ('00004', '0001009089999', '', 'NETSTES', 'PSIT', 'E');
ERROR: Duplicate entry '0001009089999-NETSTES-PSIT-00004--E' for key 'problem_key'
 
select * from t1;
 
+----+----------+---------------+------+---------+------+------+
| id | M_Number | A_Number      | Type | S_Id    | U_Id | IND  |
+----+----------+---------------+------+---------+------+------+
|  0 | 00004    | 0001009089999 |      | NETSTES | PSIT | D    |
|  2 | 00004    | 0001009089999 |      | NETSTES | PSIT | E    |
+----+----------+---------------+------+---------+------+------+

There are two bugs here:
The last REPLACE should replace the third inserted row and not give an error
The first replace should not change the ID to 0

One can get the correct result by removing 'USING HASH' above:

+----+----------+---------------+------+---------+------+------+
| id | M_Number | A_Number      | Type | S_Id    | U_Id | IND  |
+----+----------+---------------+------+---------+------+------+
|  2 | 00004    | 0001009089999 |      | NETSTES | PSIT | D    |
|  4 | 00004    | 0001009089999 |      | NETSTES | PSIT | E    |
+----+----------+---------------+------+---------+------+------+



 Comments   
Comment by Sergei Golubchik [ 2023-11-29 ]

The problem here is — auto-increment values are calculated very late, inside the engine, in ha_myisam::write_row() for example. But long uniques are checked by the server in handler::ha_write_row(), so if there's a long duplicate, ha_myisam::write_row() isn't called, auto-increment value isn't calculated and the following update fails.

A proper fix would be, of course, to fill in auto-inc values earlier, but we cannot do it in an old GA version

Comment by Sergei Golubchik [ 2023-12-05 ]

bar, please review commits

c8d0f3370b7 MDEV-32839 LONG UNIQUE gives error when used with REPLACE
4f2d0541b50 cleanup: remove innodb-specific code around update_auto_increment()
94f26086663 cleanup: remove partition-specific code around update_auto_increment()

Comment by Alexander Barkov [ 2023-12-06 ]

serg, review comments sent by email:

https://lists.mariadb.org/hyperkitty/list/developers@lists.mariadb.org/thread/VY25CVKLKCIWLWFFUXCLWLGOTO3MYTWX/

Generated at Thu Feb 08 10:34:25 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.