From: Peter Rabbitson Date: Wed, 24 Jun 2009 23:59:50 +0000 (+0000) Subject: MSSQL fixes and improvements X-Git-Tag: v0.11008~144 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=f9a5ee799e92d2cfe5a8906a794420628c5c2e73;p=dbsrgits%2FSQL-Translator.git MSSQL fixes and improvements No additional tests as things are a mess. Besides t/60roundtrip.t does exactly what it is supposed to do --- diff --git a/Changes b/Changes index 454e0c8..df82e83 100644 --- a/Changes +++ b/Changes @@ -4,6 +4,10 @@ * Fixed Pg parser - caching the compiled P::RD schema is a *very* bad idea +* Fix MSSQL handling of ON UPDATE/DELETE RESTRICT +* Delay MSSQL FK constraint deployment until after all CREATE TABLE + statements +* Coerce other engine's bytea/blob/clob datatypes to VarBinary # ---------------------------------------------------------- # 0.09006 2009-06-10 diff --git a/lib/SQL/Translator/Parser/SQLServer.pm b/lib/SQL/Translator/Parser/SQLServer.pm index 45bea7c..98c7fe1 100644 --- a/lib/SQL/Translator/Parser/SQLServer.pm +++ b/lib/SQL/Translator/Parser/SQLServer.pm @@ -181,12 +181,17 @@ create_table : /create/i /table/i ident '(' create_def(s /,/) ')' lock(?) on_sys } } -create_constraint : /create/i constraint +create_constraint : /create/i constraint { @table_comments = (); push @{ $tables{ $item[2]{'table'} }{'constraints'} }, $item[2]; } +create_constraint : /alter/i /table/i ident /add/i foreign_key_constraint END_STATEMENT + { + push @{ $tables{ $item[3]{name} }{constraints} }, $item[5]; + } + create_index : /create/i index { @table_comments = (); diff --git a/lib/SQL/Translator/Producer/SQLServer.pm b/lib/SQL/Translator/Producer/SQLServer.pm index 5e91cc8..11cee5f 100644 --- a/lib/SQL/Translator/Producer/SQLServer.pm +++ b/lib/SQL/Translator/Producer/SQLServer.pm @@ -152,6 +152,9 @@ sub produce { } # Generate the CREATE sql + + my @foreign_constraints = (); # these need to be added separately, as tables may not exist yet + for my $table ( $schema->get_tables ) { my $table_name = $table->name or next; my $table_name_ur = unreserve($table_name) || ''; @@ -195,6 +198,9 @@ sub produce { elsif ( $data_type eq 'set' ) { $data_type .= 'character varying'; } + elsif ( grep { $data_type eq $_ } qw/bytea blob clob/ ) { + $data_type = 'varbinary'; + } else { if ( defined $translate{ $data_type } ) { $data_type = $translate{ $data_type }; @@ -276,13 +282,7 @@ sub produce { next unless @fields; my $c_def; - if ( $type eq PRIMARY_KEY ) { - $name ||= mk_name( $table_name . '_pk' ); - $c_def = - "CONSTRAINT $name PRIMARY KEY ". - '(' . join( ', ', @fields ) . ')'; - } - elsif ( $type eq FOREIGN_KEY ) { + if ( $type eq FOREIGN_KEY ) { $name ||= mk_name( $table_name . '_fk' ); my $on_delete = uc ($constraint->on_delete || ''); my $on_update = uc ($constraint->on_update || ''); @@ -294,16 +294,31 @@ sub produce { } $c_def = - "CONSTRAINT $name FOREIGN KEY". + "ALTER TABLE $table_name ADD CONSTRAINT $name FOREIGN KEY". ' (' . join( ', ', @fields ) . ') REFERENCES '. $constraint->reference_table. - ' (' . join( ', ', @rfields ) . ')'; + ' (' . join( ', ', @rfields ) . ')' + ; + if ( $on_delete && $on_delete ne "NO ACTION") { $c_def .= " ON DELETE $on_delete"; } if ( $on_update && $on_update ne "NO ACTION") { $c_def .= " ON UPDATE $on_update"; } + + $c_def .= ";"; + + push @foreign_constraints, $c_def; + next; + } + + + if ( $type eq PRIMARY_KEY ) { + $name ||= mk_name( $table_name . '_pk' ); + $c_def = + "CONSTRAINT $name PRIMARY KEY ". + '(' . join( ', ', @fields ) . ')'; } elsif ( $type eq UNIQUE ) { $name ||= mk_name( $table_name . '_uc' ); @@ -339,6 +354,9 @@ sub produce { ); } +# Add FK constraints + $output .= join ("\n", '', @foreign_constraints) if @foreign_constraints; + # create view/procedure are NOT prepended to the input $sql, needs # to be filled in with the proper syntax