diff --git a/oslo_db/sqlalchemy/exc_filters.py b/oslo_db/sqlalchemy/exc_filters.py index 7f186a35..2b3ce2cb 100644 --- a/oslo_db/sqlalchemy/exc_filters.py +++ b/oslo_db/sqlalchemy/exc_filters.py @@ -120,6 +120,12 @@ def _default_dupe_key_error(integrity_error, match, engine_name, N columns - (IntegrityError) duplicate key value violates unique constraint "name_of_our_constraint" + mysql since 8.0.19: + 1 column - (IntegrityError) (1062, "Duplicate entry 'value_of_c1' for key + 'table_name.c1'") + N columns - (IntegrityError) (1062, "Duplicate entry 'values joined + with -' for key 'table_name.name_of_our_constraint'") + mysql+mysqldb: 1 column - (IntegrityError) (1062, "Duplicate entry 'value_of_c1' for key 'c1'") @@ -145,6 +151,9 @@ def _default_dupe_key_error(integrity_error, match, engine_name, if not columns.startswith(uniqbase): if engine_name == "postgresql": columns = [columns[columns.index("_") + 1:columns.rindex("_")]] + elif (engine_name == "mysql") and \ + (uniqbase in str(columns.split("0")[:1])): + columns = columns.split("0")[1:] else: columns = [columns] else: diff --git a/oslo_db/tests/sqlalchemy/test_exc_filters.py b/oslo_db/tests/sqlalchemy/test_exc_filters.py index 49826e0b..677516d1 100644 --- a/oslo_db/tests/sqlalchemy/test_exc_filters.py +++ b/oslo_db/tests/sqlalchemy/test_exc_filters.py @@ -821,6 +821,14 @@ class TestDuplicate(TestsExceptionFilter): expected_value='2' ) + def test_mysql_duplicate_entry_key_start_with_tablename(self): + self._run_dupe_constraint_test( + "mysql", + "1062 (23000): Duplicate entry '2' for key 'tbl.uniq_tbl0b'", + expected_columns=['b'], + expected_value='2' + ) + def test_mysql_binary(self): self._run_dupe_constraint_test( "mysql", @@ -839,6 +847,24 @@ class TestDuplicate(TestsExceptionFilter): expected_value="'\\\\x8A$\\\\x8D\\\\xA6\"s\\\\x8E!," ) + def test_mysql_duplicate_entry_key_start_with_tablename_binary(self): + self._run_dupe_constraint_test( + "mysql", + "(1062, \'Duplicate entry " + "\\\'\\\\x8A$\\\\x8D\\\\xA6\"s\\\\x8E\\\' " + "for key \\\'tbl.uniq_tbl0c1\\\'\')", + expected_columns=['c1'], + expected_value="\\\\x8A$\\\\x8D\\\\xA6\"s\\\\x8E" + ) + self._run_dupe_constraint_test( + "mysql", + "(1062, \'Duplicate entry " + "''\\\\x8A$\\\\x8D\\\\xA6\"s\\\\x8E!,' " + "for key 'tbl.uniq_tbl0c1'\')", + expected_columns=['c1'], + expected_value="'\\\\x8A$\\\\x8D\\\\xA6\"s\\\\x8E!," + ) + def test_postgresql_single(self): self._run_dupe_constraint_test( 'postgresql',