Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generated SQL for SQLite creates invalid FKs from temporary tables referencing main tables #76

Closed
dboehmer opened this issue Dec 31, 2020 · 2 comments

Comments

@dboehmer
Copy link

I use App::DH and DBIC-DeploymentHandler to create migration files, currently for SQLite and PostgreSQL. After I've made my application enforce PRAGMA foreign_keys = on for SQLite I found that the generated SQL is invalid. For complex table changes a temporary table is created like this:

CREATE TEMPORARY TABLE mytable_temp_alter (
  -- copy columns
  FOREIGN KEY ( mycolumn_id ) REFERENCES othertable(id)
);

Example: https://github.com/dboehmer/coocook/blob/6535a11e3525ba776d05e3e087331e2a2a15656e/share/ddl/SQLite/upgrade/21-22/001-auto.sql

This is invalid SQL.

I could not find that detail in the SQLite docs. The only page that explicitly discusses this that I found is http://sqlite.1065341.n5.nabble.com/Foreign-keys-amp-TEMPORARY-tables-td92306.html

You can see here that this is just ignored by default and throws an error if PRAGMA foreign_keys is on:

  1. is ignored
  2. implicitly references temp. schema
  3. invalid syntax
$ sqlite3 -init /dev/null
-- Loading resources from /dev/null
SQLite version 3.27.2 2019-02-25 16:06:06
Enter ".help" for usage hints.
sqlite> CREATE TABLE first (id);
sqlite> CREATE TEMPORARY TABLE second (first_id REFERENCES first(id) );
sqlite> INSERT INTO second VALUES(42);
sqlite> 

$ sqlite3 -init /dev/null
-- Loading resources from /dev/null
SQLite version 3.27.2 2019-02-25 16:06:06
Enter ".help" for usage hints.
sqlite> PRAGMA foreign_keys = on;
sqlite> CREATE TABLE first (id);
sqlite> CREATE TEMPORARY TABLE second (first_id REFERENCES first(id) );
sqlite> INSERT INTO second VALUES(42);
Error: no such table: temp.first
sqlite> 

$ sqlite3 -init /dev/null
-- Loading resources from /dev/null
SQLite version 3.27.2 2019-02-25 16:06:06
Enter ".help" for usage hints.
sqlite> CREATE TABLE first (id);
sqlite> CREATE TEMPORARY TABLE second (first_id REFERENCES main.first(id) );
Error: near ".": syntax error

For SQLite I see no other solution that to just skip the FKs for the temporary table. The new main table will have FKs again and if PRAGMA foreign_keys is on they will be checked during insertion.

@frioux
Copy link
Owner

frioux commented Dec 31, 2020 via email

@mohawk2
Copy link
Collaborator

mohawk2 commented Dec 31, 2020

Might be worth closing this issue since it can't be solved by this project?

@dboehmer dboehmer closed this as completed Jan 1, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants