diff --git a/lib/SQL/Translator/Parser/SQLite.pm b/lib/SQL/Translator/Parser/SQLite.pm index 478730267..f241a097b 100644 --- a/lib/SQL/Translator/Parser/SQLite.pm +++ b/lib/SQL/Translator/Parser/SQLite.pm @@ -425,7 +425,7 @@ table_constraint : PRIMARY_KEY parens_field_list conflict_clause(?) } } | - FOREIGN_KEY parens_field_list REFERENCES ref_def cascade_def(?) + FOREIGN_KEY parens_field_list REFERENCES ref_def cascade_def(?) deferrable(?) { $return = { supertype => 'constraint', @@ -435,6 +435,7 @@ table_constraint : PRIMARY_KEY parens_field_list conflict_clause(?) reference_fields => $item[4]{'reference_fields'}, on_delete => $item[5][0]{'on_delete'}, on_update => $item[5][0]{'on_update'}, + deferrable => $item[6], } } @@ -453,6 +454,14 @@ cascade_delete_def : /on\s+delete\s+(set null|set default|cascade|restrict|no ac cascade_update_def : /on\s+update\s+(set null|set default|cascade|restrict|no action)/i { $return = $1} +not : /not/i + +deferrable_initially : /initially (deferred|immediate)/i +deferrable : not(?) /deferrable/i deferrable_initially(?) + { + $return = $item[1] || !$item[3] || $item[3] ne 'initially deferred' ? 0 : 1 + } + table_name : qualified_name qualified_name : NAME diff --git a/lib/SQL/Translator/Producer/SQLite.pm b/lib/SQL/Translator/Producer/SQLite.pm index 9cc92aff7..1296b1785 100644 --- a/lib/SQL/Translator/Producer/SQLite.pm +++ b/lib/SQL/Translator/Producer/SQLite.pm @@ -282,6 +282,7 @@ sub create_foreignkey { $fk_sql .= " ON DELETE " . $c->{on_delete} if $c->{on_delete}; $fk_sql .= " ON UPDATE " . $c->{on_update} if $c->{on_update}; + $fk_sql .= " DEFERRABLE INITIALLY DEFERRED" if $c->deferrable; return $fk_sql; } diff --git a/t/30sqlt-new-diff-sqlite.t b/t/30sqlt-new-diff-sqlite.t index 34f6fb1c4..8f9a00218 100644 --- a/t/30sqlt-new-diff-sqlite.t +++ b/t/30sqlt-new-diff-sqlite.t @@ -99,7 +99,7 @@ CREATE TEMPORARY TABLE employee_temp_alter ( position varchar(50) NOT NULL, employee_id int(11) NOT NULL, PRIMARY KEY (position, employee_id), - FOREIGN KEY (employee_id) REFERENCES person(person_id) + FOREIGN KEY (employee_id) REFERENCES person(person_id) DEFERRABLE INITIALLY DEFERRED ); INSERT INTO employee_temp_alter( position, employee_id) SELECT position, employee_id FROM employee; @@ -110,7 +110,7 @@ CREATE TABLE employee ( position varchar(50) NOT NULL, employee_id int(11) NOT NULL, PRIMARY KEY (position, employee_id), - FOREIGN KEY (employee_id) REFERENCES person(person_id) + FOREIGN KEY (employee_id) REFERENCES person(person_id) DEFERRABLE INITIALLY DEFERRED ); INSERT INTO employee SELECT position, employee_id FROM employee_temp_alter; diff --git a/t/48xml-to-sqlite.t b/t/48xml-to-sqlite.t index 21e8ad355..dfc84b67a 100644 --- a/t/48xml-to-sqlite.t +++ b/t/48xml-to-sqlite.t @@ -50,7 +50,7 @@ CREATE TABLE "Basic" ( "emptytagdef" varchar DEFAULT '', "another_id" int(10) DEFAULT 2, "timest" timestamp, - FOREIGN KEY ("another_id") REFERENCES "Another"("id") + FOREIGN KEY ("another_id") REFERENCES "Another"("id") DEFERRABLE INITIALLY DEFERRED ); CREATE INDEX "titleindex" ON "Basic" ("title"); @@ -108,7 +108,7 @@ eq_or_diff(\@sql, "emptytagdef" varchar DEFAULT '', "another_id" int(10) DEFAULT 2, "timest" timestamp, - FOREIGN KEY ("another_id") REFERENCES "Another"("id") + FOREIGN KEY ("another_id") REFERENCES "Another"("id") DEFERRABLE INITIALLY DEFERRED )>, q, q, diff --git a/t/56-sqlite-producer.t b/t/56-sqlite-producer.t index d0d2cfeb2..8cebcb394 100644 --- a/t/56-sqlite-producer.t +++ b/t/56-sqlite-producer.t @@ -57,7 +57,7 @@ $SQL::Translator::Producer::SQLite::NO_QUOTES = 0; on_delete => 'RESTRICT', on_update => 'CASCADE', ); - my $expected = [ 'FOREIGN KEY ("foreign_key") REFERENCES "foo"("id") ON DELETE RESTRICT ON UPDATE CASCADE']; + my $expected = [ 'FOREIGN KEY ("foreign_key") REFERENCES "foo"("id") ON DELETE RESTRICT ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED']; my $result = [SQL::Translator::Producer::SQLite::create_foreignkey($constraint,$create_opts)]; is_deeply($result, $expected, 'correct "FOREIGN KEY"'); }