Search code examples
sqliteforeign-keys

What is causing this sqlite foreign key mismatch?


I already checked out this question, and thought I had the answer - but then it didn't look right to me.

I have the following pared down example:

CREATE TABLE pipelines (                                                        
        name VARCHAR NOT NULL,                                                  
        owner VARCHAR NOT NULL,                                                 
        description VARCHAR,                                                    
        PRIMARY KEY (name, owner),                                              
        FOREIGN KEY(owner) REFERENCES user (id)                                 
);                                                                              
CREATE TABLE tasks (                                                            
        id INTEGER NOT NULL,                                                    
        title VARCHAR,                                                          
        pipeline VARCHAR,                                                       
        owner VARCHAR,                                                          
        PRIMARY KEY (id),                                                       
        FOREIGN KEY(pipeline) REFERENCES pipelines (name),                      
        FOREIGN KEY(owner) REFERENCES pipelines (owner)                         
);                                                                              
CREATE TABLE user (                                                           
        id VARCHAR NOT NULL,                                                    
        name VARCHAR,                                                           
        password VARCHAR,                                                       
        PRIMARY KEY (id)                                                        
);                                                                              
pragma foreign_keys=on;                                                         

insert into user values ('wayne', '', '');                                    
insert into pipelines values ('pipey', 'wayne', '');                            
insert into tasks values (1, 'hello', 'pipey', 'wayne'); 

When executing this code, it bails out:

$ sqlite3 foo.sq3 '.read mismatch.sql'    
Error: near line 27: foreign key mismatch

Through the list in the question I cited:

  • the parent table (user) exists.
  • the parent columns (name, owner) exist
  • the parent columns are, in fact, the primary key (I thought that may have been it originally)
  • the child table references all of the primary key columns in the parent table

So what in the world could be causing this error?


Solution

  • The documentation says:

    Usually, the parent key of a foreign key constraint is the primary key of the parent table. If they are not the primary key, then the parent key columns must be collectively subject to a UNIQUE constraint or have a UNIQUE index.

    In the pipelines table, neither the name nor the owner columns are, by themselves, unique.

    I guess you actually want to have a two-column foreign key in the tasks table:

    FOREIGN KEY(pipeline, owner) REFERENCES pipelines(name, owner)