[MDEV-29717] Foreign key constraint is incorrectly formed Created: 2022-10-05  Updated: 2022-10-08  Resolved: 2022-10-07

Status: Closed
Project: MariaDB Server
Component/s: Data Definition - Alter Table
Affects Version/s: 10.9.3
Fix Version/s: N/A

Type: Bug Priority: Major
Reporter: Farid Assignee: Unassigned
Resolution: Not a Bug Votes: 0
Labels: None
Environment:

Windows 10 x64



 Description   

Can not create the FK between these two tables.
Works fine in MySQL and other DBMSs but fails on MariaDB.

create table in_sync_data_source
(
   ds_oid               integer not null auto_increment,
   dbms_name            varchar(256) character set utf8mb4 not null,
   server_name          varchar(256) character set utf8mb4,
   cluster_id           varchar(256) character set utf8mb4,
   database_name        varchar(520) character set utf8mb4,
   logid                varchar(256) character set utf8mb4,
   owner_oid            int,
   root_rs_oid          int,
   readonly_ind         tinyint not null,
   ctrl_ins_dtm         timestamp(6) not null default current_timestamp(6),
   ctrl_upd_dtm         timestamp(6) not null default current_timestamp(6) on update current_timestamp(6),
   ctrl_usr_id          varchar(256) character set utf8mb4 not null,
   primary key (ds_oid)
);
 
create table in_sync_object
(
   rs_oid               int not null,
   ds_oid               integer not null,
   object_cat           varchar(520) character set utf8mb4 collate utf8mb4_bin,
   object_schem         varchar(256) character set utf8mb4 collate utf8mb4_bin,
   object_name          varchar(256) character set utf8mb4 collate utf8mb4_bin not null,
   object_sig           varchar(512) character set utf8mb4,
   object_subtype       varchar(60),
   object_ignore_ind    tinyint not null default 0,
   ctrl_ins_dtm         timestamp(6) not null default current_timestamp(6),
   ctrl_upd_dtm         timestamp(6) not null default current_timestamp(6) on update current_timestamp(6),
   ctrl_usr_id          varchar(256) character set utf8mb4 not null,
   primary key (rs_oid)
);
 
create unique index IX1IN_SYNC_OBJECT on in_sync_object
(
   ds_oid,
   object_cat,
   object_schem,
   object_name,
   object_sig
);

-- [10.9.3-MariaDB]Can't create table `in_sync_object` (errno: 150 "Foreign key constraint is incorrectly formed")
alter table in_sync_object add constraint FK_IST_ISDS_DS_OID foreign key (ds_oid)
      references in_sync_data_source (ds_oid) on delete restrict on update restrict;



 Comments   
Comment by Sergei Golubchik [ 2022-10-07 ]

The documentation says

The columns in the child table must be a BTREE (not HASH, RTREE, or FULLTEXT — see SHOW INDEX) index, or the leftmost part of a BTREE index

Your IX1IN_SYNC_OBJECT is likely a HASH index, use SHOW INDEX to double-check.
And it's a HASH index, because the maximal length of a BTREE key value in MariaDB is 3072, and your index is longer. HASH indexes can have any length.

MySQL also has 3072 limitation, but doesn't support arbitrary long UNIQUE constraints, so your example above fails in MySQL with "Error ER_TOO_LONG_KEY: Specified key was too long; max key length is 3072 bytes" — https://www.db-fiddle.com/f/pwEBEe3SW3YK8fYfxTSZ6z/0

Comment by Farid [ 2022-10-08 ]

The foreign key definition is valid, so the error message can be clearer and say something like:
Can not create foreign key due to existing index on the child table.

This is an implementation issue with MariaDB and MySQL auto-indexing foreign keys.
On MySQL, the unique index creation fails and the foreign key gets created.
On MariaDB, the unique index creation succeeds and the foreign key creation fails with misleading error message.

On other DBMSs this is not an issue and both the unique index and the foreign keys are successfully created.

Db2 -> works
Informix IDS -> works
Oracle -> works
PostgreSQL -> works
Microsoft SQL Server -> works
SAP Adaptive Server Enterprise -> works

So, at a minimum, the error message can be more informative on why the foreign key can not be created.

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