MSSQL fixes and improvements
Peter Rabbitson [Wed, 24 Jun 2009 23:59:50 +0000 (23:59 +0000)]
No additional tests as things are a mess. Besides t/60roundtrip.t does exactly what it is supposed to do

Changes
lib/SQL/Translator/Parser/SQLServer.pm
lib/SQL/Translator/Producer/SQLServer.pm

diff --git a/Changes b/Changes
index 454e0c8..df82e83 100644 (file)
--- 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
index 45bea7c..98c7fe1 100644 (file)
@@ -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 = ();
index 5e91cc8..11cee5f 100644 (file)
@@ -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