From: Arthur Axel 'fREW' Schmidt Date: Wed, 22 Feb 2012 02:15:42 +0000 (-0600) Subject: Default SQLite quoting to off until we are capable of disabling it everywhere X-Git-Tag: v0.11011~23 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=2d23c1e1b5e4e66212eef0bba029664b60fd8cb7;p=dbsrgits%2FSQL-Translator.git Default SQLite quoting to off until we are capable of disabling it everywhere Currently the diffing routines are either "always on" or "always off" with no ability to pass around a setting (they are all class methods, never looking at the $translator object). Until we can allow a user to say quote_identifiers => 0, and not have to change any of the old tests, it makes little sense to change the default. --- diff --git a/Changes b/Changes index d0ce623..27cca39 100644 --- a/Changes +++ b/Changes @@ -1,3 +1,4 @@ +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! *** INCOMPATIBLE CHANGES: * SQLT no longer supports setting separate conflicting values for the now deprecated 'quote_table_names' and 'quote_field_names'. Instead their values @@ -6,12 +7,16 @@ specified the default is TRUE as before. If only one is specified - default to its value for everything, and if both are specified with a conflicting value an exception is thrown. - +* Partial quoting support has been added in SQLite. It is currently disabled by + default, you need to request is explicitly with quote_identifiers => 1. In a + future version of SQL::Translator *THIS DEFAULT BEHAVIOR WILL CHANGE*. + If you do NOT WANT quoting, set quote_identifiers to a false value to + protect yourself from changes in a future release. +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! * Fixes to SQLite foreign keys production (patch from Johan Viklund) closes RT#16412, RT#44769 * ON DELETE/UPDATE actions for SQLite (patch from Lukas Thiemeier) closes RT#70734, RT#71283, RT#70378 -* Proper quoting support in SQLite * Fix data preservation on SQLite diffs involving adding/dropping columns * Support for triggers in PostgreSQL producer and parser * Correct Data Type in SQLT::Parser::DBI::PostgreSQL (patch from Andrew Pam) diff --git a/lib/SQL/Translator/Diff.pm b/lib/SQL/Translator/Diff.pm index 9d9e493..cc1ff17 100644 --- a/lib/SQL/Translator/Diff.pm +++ b/lib/SQL/Translator/Diff.pm @@ -269,7 +269,7 @@ sub produce_diff_sql { } if (my @tables = @{ $self->tables_to_create } ) { - my $translator = new SQL::Translator( + my $translator = SQL::Translator->new( producer_type => $self->output_db, add_drop_table => 0, no_comments => 1, diff --git a/lib/SQL/Translator/Generator/DDL/SQLite.pm b/lib/SQL/Translator/Generator/DDL/SQLite.pm index 9dda649..7a173a2 100644 --- a/lib/SQL/Translator/Generator/DDL/SQLite.pm +++ b/lib/SQL/Translator/Generator/DDL/SQLite.pm @@ -3,10 +3,11 @@ package SQL::Translator::Generator::DDL::SQLite; use Moo; use SQL::Translator::Generator::Utils; +has quote_chars => (is=>'ro', default=>sub { +[qw(" ")] } ); + with 'SQL::Translator::Generator::Role::Quote'; with 'SQL::Translator::Generator::Role::DDL'; -sub quote_chars { [qw(" ")] } sub name_sep { q(.) } sub _build_type_map { diff --git a/lib/SQL/Translator/Producer/SQLite.pm b/lib/SQL/Translator/Producer/SQLite.pm index 5d80337..2cccce2 100644 --- a/lib/SQL/Translator/Producer/SQLite.pm +++ b/lib/SQL/Translator/Producer/SQLite.pm @@ -22,8 +22,6 @@ use warnings; use Data::Dumper; use SQL::Translator::Schema::Constants; use SQL::Translator::Utils qw(debug header_comment parse_dbms_version); -use SQL::Translator::Generator::Utils; -my $util = SQL::Translator::Generator::Utils->new( quote_chars => q(") ); use SQL::Translator::Generator::DDL::SQLite; our ( $DEBUG, $WARN ); @@ -33,7 +31,18 @@ $WARN = 0 unless defined $WARN; our $max_id_length = 30; my %global_names; -my $future = SQL::Translator::Generator::DDL::SQLite->new(); + +# HIDEOUS TEMPORARY DEFAULT WITHOUT QUOTING! +our $NO_QUOTES = 1; +{ + + my ($quoting_generator, $nonquoting_generator); + sub _generator { + $NO_QUOTES + ? $nonquoting_generator ||= SQL::Translator::Generator::DDL::SQLite->new(quote_chars => []) + : $quoting_generator ||= SQL::Translator::Generator::DDL::SQLite->new + } +} sub produce { my $translator = shift; @@ -52,6 +61,10 @@ sub produce { %global_names = (); #reset + # only quote if quotes were requested for real + # 0E0 indicates "the default of true" was assumed + local $NO_QUOTES = 0 + if $translator->quote_identifiers and $translator->quote_identifiers ne '0E0'; my $head = (header_comment() . "\n") unless $no_comments; @@ -109,14 +122,14 @@ sub mk_name { } $scope->{ $name }++; - return $util->quote($name); + return _generator()->quote($name); } sub create_view { my ($view, $options) = @_; my $add_drop_view = $options->{add_drop_view}; - my $view_name = $util->quote($view->name); + my $view_name = _generator()->quote($view->name); $global_names{$view->name} = 1; debug("PKG: Looking at view '${view_name}'\n"); @@ -150,7 +163,7 @@ sub create_table { my ($table, $options) = @_; - my $table_name = $util->quote($table->name); + my $table_name = _generator()->quote($table->name); $global_names{$table->name} = 1; my $no_comments = $options->{no_comments}; @@ -206,7 +219,7 @@ sub create_table || ( @pk_fields && !grep /INTEGER PRIMARY KEY/, @field_defs ) ) { - push @field_defs, 'PRIMARY KEY (' . join(', ', map $util->quote($_), @pk_fields ) . ')'; + push @field_defs, 'PRIMARY KEY (' . join(', ', map _generator()->quote($_), @pk_fields ) . ')'; } # @@ -253,9 +266,9 @@ sub create_foreignkey { } my $fk_sql = sprintf 'FOREIGN KEY (%s) REFERENCES %s(%s)', - join (', ', map { $util->quote($_) } @fields ), - $util->quote($c->reference_table), - join (', ', map { $util->quote($_) } @rfields ) + join (', ', map { _generator()->quote($_) } @fields ), + _generator()->quote($c->reference_table), + join (', ', map { _generator()->quote($_) } @rfields ) ; $fk_sql .= " ON DELETE " . $c->{on_delete} if $c->{on_delete}; @@ -264,7 +277,7 @@ sub create_foreignkey { return $fk_sql; } -sub create_field { return $future->field($_[0]) } +sub create_field { return _generator()->field($_[0]) } sub create_index { @@ -276,9 +289,9 @@ sub create_index my $type = $index->type eq 'UNIQUE' ? "UNIQUE " : ''; # strip any field size qualifiers as SQLite doesn't like these - my @fields = map { s/\(\d+\)$//; $util->quote($_) } $index->fields; + my @fields = map { s/\(\d+\)$//; _generator()->quote($_) } $index->fields; (my $index_table_name = $index->table->name) =~ s/^.+?\.//; # table name may not specify schema - $index_table_name = $util->quote($index_table_name); + $index_table_name = _generator()->quote($index_table_name); warn "removing schema name from '" . $index->table->name . "' to make '$index_table_name'\n" if $WARN; my $index_def = "CREATE ${type}INDEX $name ON " . $index_table_name . @@ -293,9 +306,9 @@ sub create_constraint my $name = $c->name; $name = mk_name($name); - my @fields = map $util->quote($_), $c->fields; + my @fields = map _generator()->quote($_), $c->fields; (my $index_table_name = $c->table->name) =~ s/^.+?\.//; # table name may not specify schema - $index_table_name = $util->quote($index_table_name); + $index_table_name = _generator()->quote($index_table_name); warn "removing schema name from '" . $c->table->name . "' to make '$index_table_name'\n" if $WARN; my $c_def = @@ -325,7 +338,7 @@ sub create_trigger { "creating trigger '$trig_name' for the '$evt' event.\n" if $WARN; } - $trig_name = $util->quote($trig_name); + $trig_name = _generator()->quote($trig_name); push @statements, "DROP TRIGGER IF EXISTS $trig_name" if $add_drop; @@ -353,7 +366,7 @@ sub create_trigger { $trig_name, $trigger->perform_action_when, $evt, - $util->quote($trigger->on_table), + _generator()->quote($trigger->on_table), $action ); } @@ -367,7 +380,7 @@ sub add_field { my ($field) = @_; return sprintf("ALTER TABLE %s ADD COLUMN %s", - $util->quote($field->table->name), create_field($field)) + _generator()->quote($field->table->name), create_field($field)) } sub alter_create_index { @@ -389,7 +402,7 @@ sub alter_drop_index { my ($constraint) = @_; return sprintf("DROP INDEX %s", - $util->quote($constraint->name)); + _generator()->quote($constraint->name)); } sub batch_alter_table { @@ -458,26 +471,26 @@ sub batch_alter_table { %temp_table_fields = map { $_ => 1} $table->get_fields; }; - push @sql, "INSERT INTO @{[$util->quote($table_name.'_temp_alter')]}( @{[ join(', ', map $util->quote($_), grep { $temp_table_fields{$_} } $old_table->get_fields)]}) SELECT @{[ join(', ', map $util->quote($_), grep { $temp_table_fields{$_} } $old_table->get_fields)]} FROM @{[$util->quote($old_table)]}", - "DROP TABLE @{[$util->quote($old_table)]}", + push @sql, "INSERT INTO @{[_generator()->quote($table_name.'_temp_alter')]}( @{[ join(', ', map _generator()->quote($_), grep { $temp_table_fields{$_} } $old_table->get_fields)]}) SELECT @{[ join(', ', map _generator()->quote($_), grep { $temp_table_fields{$_} } $old_table->get_fields)]} FROM @{[_generator()->quote($old_table)]}", + "DROP TABLE @{[_generator()->quote($old_table)]}", create_table($table, { no_comments => 1 }), - "INSERT INTO @{[$util->quote($table_name)]} SELECT @{[ join(', ', map $util->quote($_), $table->get_fields)]} FROM @{[$util->quote($table_name.'_temp_alter')]}", - "DROP TABLE @{[$util->quote($table_name.'_temp_alter')]}"; + "INSERT INTO @{[_generator()->quote($table_name)]} SELECT @{[ join(', ', map _generator()->quote($_), $table->get_fields)]} FROM @{[_generator()->quote($table_name.'_temp_alter')]}", + "DROP TABLE @{[_generator()->quote($table_name.'_temp_alter')]}"; return @sql; # return join("", @sql, ""); } sub drop_table { my ($table) = @_; - $table = $util->quote($table); + $table = _generator()->quote($table); return "DROP TABLE $table"; } sub rename_table { my ($old_table, $new_table, $options) = @_; - $old_table = $util->quote($old_table); - $new_table = $util->quote($new_table); + $old_table = _generator()->quote($old_table); + $new_table = _generator()->quote($new_table); return "ALTER TABLE $old_table RENAME TO $new_table"; diff --git a/t/30sqlt-new-diff-sqlite.t b/t/30sqlt-new-diff-sqlite.t index 926162a..ef7fee7 100644 --- a/t/30sqlt-new-diff-sqlite.t +++ b/t/30sqlt-new-diff-sqlite.t @@ -44,35 +44,35 @@ eq_or_diff($out, <<'## END OF DIFF', "Diff as expected"); BEGIN; -CREATE TABLE "added" ( - "id" int(11) +CREATE TABLE added ( + id int(11) ); -ALTER TABLE "old_name" RENAME TO "new_name"; +ALTER TABLE old_name RENAME TO new_name; -DROP INDEX "FK5302D47D93FE702E"; +DROP INDEX FK5302D47D93FE702E; -DROP INDEX "UC_age_name"; +DROP INDEX UC_age_name; -DROP INDEX "u_name"; +DROP INDEX u_name; -- SQL::Translator::Producer::SQLite cant drop_field; -ALTER TABLE "new_name" ADD COLUMN "new_field" int; +ALTER TABLE new_name ADD COLUMN new_field int; -ALTER TABLE "person" ADD COLUMN "is_rock_star" tinyint(4) DEFAULT 1; +ALTER TABLE person ADD COLUMN is_rock_star tinyint(4) DEFAULT 1; -- SQL::Translator::Producer::SQLite cant alter_field; -- SQL::Translator::Producer::SQLite cant rename_field; -CREATE UNIQUE INDEX "unique_name" ON "person" ("name"); +CREATE UNIQUE INDEX unique_name ON person (name); -CREATE UNIQUE INDEX "UC_person_id" ON "person" ("person_id"); +CREATE UNIQUE INDEX UC_person_id ON person (person_id); -CREATE UNIQUE INDEX "UC_age_name" ON "person" ("age", "name"); +CREATE UNIQUE INDEX UC_age_name ON person (age, name); -DROP TABLE "deleted"; +DROP TABLE deleted; COMMIT; @@ -91,71 +91,71 @@ eq_or_diff($out, <<'## END OF DIFF', "Diff as expected"); BEGIN; -CREATE TABLE "added" ( - "id" int(11) +CREATE TABLE added ( + id int(11) ); -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") +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) ); -INSERT INTO "employee_temp_alter"( "position", "employee_id") SELECT "position", "employee_id" FROM "employee"; +INSERT INTO employee_temp_alter( position, employee_id) SELECT position, employee_id FROM employee; -DROP TABLE "employee"; +DROP TABLE employee; -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") +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) ); -INSERT INTO "employee" SELECT "position", "employee_id" FROM "employee_temp_alter"; +INSERT INTO employee SELECT position, employee_id FROM employee_temp_alter; -DROP TABLE "employee_temp_alter"; +DROP TABLE employee_temp_alter; -ALTER TABLE "old_name" RENAME TO "new_name"; +ALTER TABLE old_name RENAME TO new_name; -ALTER TABLE "new_name" ADD COLUMN "new_field" int; +ALTER TABLE new_name ADD COLUMN new_field int; -CREATE TEMPORARY TABLE "person_temp_alter" ( - "person_id" INTEGER PRIMARY KEY NOT NULL, - "name" varchar(20) NOT NULL, - "age" int(11) DEFAULT 18, - "weight" double(11,2), - "iq" int(11) DEFAULT 0, - "is_rock_star" tinyint(4) DEFAULT 1, - "physical_description" text +CREATE TEMPORARY TABLE person_temp_alter ( + person_id INTEGER PRIMARY KEY NOT NULL, + name varchar(20) NOT NULL, + age int(11) DEFAULT 18, + weight double(11,2), + iq int(11) DEFAULT 0, + is_rock_star tinyint(4) DEFAULT 1, + physical_description text ); -INSERT INTO "person_temp_alter"( "person_id", "name", "age", "weight", "iq", "is_rock_star", "physical_description") SELECT "person_id", "name", "age", "weight", "iq", "is_rock_star", "physical_description" FROM "person"; +INSERT INTO person_temp_alter( person_id, name, age, weight, iq, is_rock_star, physical_description) SELECT person_id, name, age, weight, iq, is_rock_star, physical_description FROM person; -DROP TABLE "person"; +DROP TABLE person; -CREATE TABLE "person" ( - "person_id" INTEGER PRIMARY KEY NOT NULL, - "name" varchar(20) NOT NULL, - "age" int(11) DEFAULT 18, - "weight" double(11,2), - "iq" int(11) DEFAULT 0, - "is_rock_star" tinyint(4) DEFAULT 1, - "physical_description" text +CREATE TABLE person ( + person_id INTEGER PRIMARY KEY NOT NULL, + name varchar(20) NOT NULL, + age int(11) DEFAULT 18, + weight double(11,2), + iq int(11) DEFAULT 0, + is_rock_star tinyint(4) DEFAULT 1, + physical_description text ); -CREATE UNIQUE INDEX "unique_name02" ON "person" ("name"); +CREATE UNIQUE INDEX unique_name02 ON person (name); -CREATE UNIQUE INDEX "UC_person_id02" ON "person" ("person_id"); +CREATE UNIQUE INDEX UC_person_id02 ON person (person_id); -CREATE UNIQUE INDEX "UC_age_name02" ON "person" ("age", "name"); +CREATE UNIQUE INDEX UC_age_name02 ON person (age, name); -INSERT INTO "person" SELECT "person_id", "name", "age", "weight", "iq", "is_rock_star", "physical_description" FROM "person_temp_alter"; +INSERT INTO person SELECT person_id, name, age, weight, iq, is_rock_star, physical_description FROM person_temp_alter; -DROP TABLE "person_temp_alter"; +DROP TABLE person_temp_alter; -DROP TABLE "deleted"; +DROP TABLE deleted; COMMIT; diff --git a/t/48xml-to-sqlite.t b/t/48xml-to-sqlite.t index 8bccd28..21e8ad3 100644 --- a/t/48xml-to-sqlite.t +++ b/t/48xml-to-sqlite.t @@ -20,6 +20,7 @@ my $xmlfile = "$Bin/data/xml/schema.xml"; my $sqlt; $sqlt = SQL::Translator->new( + quote_identifiers => 1, no_comments => 1, show_warnings => 0, add_drop_table => 1, diff --git a/t/56-sqlite-producer.t b/t/56-sqlite-producer.t index 7124a75..a83cbe6 100644 --- a/t/56-sqlite-producer.t +++ b/t/56-sqlite-producer.t @@ -9,6 +9,7 @@ use FindBin qw/$Bin/; use SQL::Translator::Schema::View; use SQL::Translator::Schema::Table; use SQL::Translator::Producer::SQLite; +$SQL::Translator::Producer::SQLite::NO_QUOTES = 0; { my $view1 = SQL::Translator::Schema::View->new( name => 'view_foo', diff --git a/t/57-class-dbi.t b/t/57-class-dbi.t index 81daf2b..26534a4 100644 --- a/t/57-class-dbi.t +++ b/t/57-class-dbi.t @@ -23,7 +23,7 @@ use SQL::Translator::Producer::SQLite; my $view1_sql1 = [ SQL::Translator::Producer::SQLite::create_view( $view1, $create_opts ) ]; - my $view_sql_replace = [ 'CREATE TEMPORARY VIEW IF NOT EXISTS "view_foo" AS + my $view_sql_replace = [ 'CREATE TEMPORARY VIEW IF NOT EXISTS view_foo AS SELECT id, name FROM thing' ]; is_deeply( $view1_sql1, $view_sql_replace, 'correct "CREATE TEMPORARY VIEW" SQL' ); @@ -35,7 +35,7 @@ use SQL::Translator::Producer::SQLite; my $view1_sql2 = [ SQL::Translator::Producer::SQLite::create_view( $view2, $create_opts ) ]; - my $view_sql_noreplace = [ 'CREATE VIEW "view_foo" AS + my $view_sql_noreplace = [ 'CREATE VIEW view_foo AS SELECT id, name FROM thing' ]; is_deeply( $view1_sql2, $view_sql_noreplace, 'correct "CREATE VIEW" SQL' ); } diff --git a/t/72-sqlite-add-drop-fields.t b/t/72-sqlite-add-drop-fields.t index bdc3f93..1fb0ab3 100644 --- a/t/72-sqlite-add-drop-fields.t +++ b/t/72-sqlite-add-drop-fields.t @@ -40,27 +40,27 @@ eq_or_diff($upgrade_sql, <<'## END OF DIFF', "Diff as expected"); BEGIN; -CREATE TEMPORARY TABLE "Foo_temp_alter" ( - "foo" INTEGER PRIMARY KEY NOT NULL, - "bar" VARCHAR(10) NOT NULL, - "baz" VARCHAR(10), - "doomed" VARCHAR(10) +CREATE TEMPORARY TABLE Foo_temp_alter ( + foo INTEGER PRIMARY KEY NOT NULL, + bar VARCHAR(10) NOT NULL, + baz VARCHAR(10), + doomed VARCHAR(10) ); -INSERT INTO "Foo_temp_alter"( "foo", "bar") SELECT "foo", "bar" FROM "Foo"; +INSERT INTO Foo_temp_alter( foo, bar) SELECT foo, bar FROM Foo; -DROP TABLE "Foo"; +DROP TABLE Foo; -CREATE TABLE "Foo" ( - "foo" INTEGER PRIMARY KEY NOT NULL, - "bar" VARCHAR(10) NOT NULL, - "baz" VARCHAR(10), - "doomed" VARCHAR(10) +CREATE TABLE Foo ( + foo INTEGER PRIMARY KEY NOT NULL, + bar VARCHAR(10) NOT NULL, + baz VARCHAR(10), + doomed VARCHAR(10) ); -INSERT INTO "Foo" SELECT "foo", "bar", "baz", "doomed" FROM "Foo_temp_alter"; +INSERT INTO Foo SELECT foo, bar, baz, doomed FROM Foo_temp_alter; -DROP TABLE "Foo_temp_alter"; +DROP TABLE Foo_temp_alter; COMMIT; diff --git a/t/73-sqlite-respects-quote.t b/t/73-sqlite-respects-quote.t new file mode 100644 index 0000000..be1d48a --- /dev/null +++ b/t/73-sqlite-respects-quote.t @@ -0,0 +1,101 @@ +#!/usr/bin/env perl + +use strict; +use warnings; + +use Test::More tests => 3; +use Test::Exception; +use Test::Differences; +use SQL::Translator; +use SQL::Translator::Parser::SQLite; +use SQL::Translator::Diff; + +my $ddl = < 1, + from => 'SQLite', + to => 'SQLite'); + +my $unquoted = SQL::Translator + ->new(%common_args) + ->translate(\$ddl); + +eq_or_diff($unquoted, <<'DDL', 'DDL with default quoting'); +BEGIN TRANSACTION; + +CREATE TABLE Foo ( + foo INTEGER PRIMARY KEY NOT NULL, + bar VARCHAR(10) NOT NULL, + biff VARCHAR(10) +); + +COMMIT; +DDL + +dies_ok { SQL::Translator + ->new(%common_args, quote_table_names=>0, quote_field_names => 1) + ->translate(\$ddl) } 'mix and match quotes is asinine'; + +my $quoteall = SQL::Translator + ->new(%common_args, quote_identifiers=>1) + ->translate(\$ddl); + +eq_or_diff($quoteall, <<'DDL', 'DDL with quoting'); +BEGIN TRANSACTION; + +CREATE TABLE "Foo" ( + "foo" INTEGER PRIMARY KEY NOT NULL, + "bar" VARCHAR(10) NOT NULL, + "biff" VARCHAR(10) +); + +COMMIT; +DDL + +=begin FOR TODO + +# FIGURE OUT HOW TO DO QUOTED DIFFS EVEN WHEN QUOTING IS DEFAULT OFF +# + +eq_or_diff($upgrade_sql, <<'## END OF DIFF', "Diff as expected"); +-- Convert schema '' to '':; + +BEGIN; + +CREATE TEMPORARY TABLE "Foo_temp_alter" ( + "foo" INTEGER PRIMARY KEY NOT NULL, + "bar" VARCHAR(10) NOT NULL, + "baz" VARCHAR(10), + "doomed" VARCHAR(10) +); + +INSERT INTO "Foo_temp_alter"( "foo", "bar") SELECT "foo", "bar" FROM "Foo"; + +DROP TABLE "Foo"; + +CREATE TABLE "Foo" ( + "foo" INTEGER PRIMARY KEY NOT NULL, + "bar" VARCHAR(10) NOT NULL, + "baz" VARCHAR(10), + "doomed" VARCHAR(10) +); + +INSERT INTO "Foo" SELECT "foo", "bar", "baz", "doomed" FROM "Foo_temp_alter"; + +DROP TABLE "Foo_temp_alter"; + + +COMMIT; + +## END OF DIFF + +=cut + +