improve Pg default handling
Rafael Kitover [Tue, 6 Sep 2011 07:18:58 +0000 (03:18 -0400)]
Correctly handles these cases:
 - <type> DEFAULT NULL
 - boolean DEFAULT 0::boolean

lib/DBIx/Class/Schema/Loader/DBI/Component/QuotedDefault.pm
lib/DBIx/Class/Schema/Loader/DBI/Pg.pm
t/10_03pg_common.t

index e690522..223b044 100644 (file)
@@ -34,9 +34,18 @@ sub _columns_info_for {
             if ($def =~ /^["'](.*?)['"](?:::[\w\s]+)?\z/) {
                 $info->{default_value} = $1;
             }
+# Some DBs (eg. Pg) put parenthesis around negative number defaults
+            elsif ($def =~ /^\((-?\d.*?)\)(?:::[\w\s]+)?\z/) {
+                $info->{default_value} = $1;
+            }
+            elsif ($def =~ /^(\d.*?)(?:::[\w\s]+)?\z/) {
+                $info->{default_value} = $1;
+            }
+            elsif ($def =~ /^NULL:?/i) {
+                $info->{default_value} = \'null';
+            }
             else {
-                # Some DBs (eg. Pg) put brackets around negative number defaults
-                $info->{default_value} = $def =~ /^\(?(-?\d.*?)\)?$/ ? $1 : \$def;
+                $info->{default_value} = \$def;
             }
         }
     }
index c16231a..8fe2f6b 100644 (file)
@@ -151,7 +151,7 @@ sub _columns_info_for {
         # these types are fixed size
         # XXX should this be a negative match?
         if ($data_type =~
-/^(?:bigint|int8|bigserial|serial8|boolean|bool|box|bytea|cidr|circle|date|double precision|float8|inet|integer|int|int4|line|lseg|macaddr|money|path|point|polygon|real|float4|smallint|int2|serial|serial4|text)\z/i) {
+/^(?:bigint|int8|bigserial|serial8|bool(?:ean)?|box|bytea|cidr|circle|date|double precision|float8|inet|integer|int|int4|line|lseg|macaddr|money|path|point|polygon|real|float4|smallint|int2|serial|serial4|text)\z/i) {
             delete $info->{size};
         }
 # for datetime types, check if it has a precision or not
@@ -272,6 +272,18 @@ EOF
             my $now = 'now()';
             $info->{original}{default_value} = \$now;
         }
+
+# detect 0/1 for booleans and rewrite
+        if ($data_type =~ /^bool/i && exists $info->{default_value}) {
+            if ($info->{default_value} eq '0') {
+                my $false = 'false';
+                $info->{default_value} = \$false;
+            }
+            elsif ($info->{default_value} eq '1') {
+                my $true = 'true';
+                $info->{default_value} = \$true;
+            }
+        }
     }
 
     return $result;
index 668d4da..b93c092 100644 (file)
@@ -39,6 +39,12 @@ my $tester = dbixcsl_common_tests->new(
        bool        => { data_type => 'boolean' },
         'bool default false'
                     => { data_type => 'boolean', default_value => \'false' },
+        'bool default true'
+                    => { data_type => 'boolean', default_value => \'true' },
+        'bool default 0::bool'
+                    => { data_type => 'boolean', default_value => \'false' },
+        'bool default 1::bool'
+                    => { data_type => 'boolean', default_value => \'true' },
 
        bigint      => { data_type => 'bigint' },
        int8        => { data_type => 'bigint' },
@@ -100,6 +106,9 @@ my $tester = dbixcsl_common_tests->new(
         # varchar with no size has unlimited size, we rewrite to 'text'
        varchar                          => { data_type => 'text',
                                               original => { data_type => 'varchar' } },
+        # check that default NULL is correctly rewritten
+        'varchar(3) default NULL'        => { data_type => 'varchar', size => 3,
+                                              default_value => \'null' },
 
         # Datetime Types
        date                             => { data_type => 'date' },