fix erroneous default_value for MySQL NOT NULL columns (RT#57225)
Rafael Kitover [Wed, 5 May 2010 21:34:52 +0000 (17:34 -0400)]
Changes
lib/DBIx/Class/Schema/Loader/DBI/mysql.pm
t/11mysql_common.t
t/lib/dbixcsl_common_tests.pm

diff --git a/Changes b/Changes
index 2404d9a..ae0b91c 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1,5 +1,6 @@
 Revision history for Perl extension DBIx::Class::Schema::Loader
 
+        - fix erroneous default_value for MySQL NOT NULL columns (RT#57225)
         - remove is_deferrable => 1 from default for belongs_to rels
         - better type info for Oracle
         - preliminary Informix support
index e6e10ee..1eb9107 100644 (file)
@@ -136,8 +136,7 @@ sub _columns_info_for {
     my $dbh = $self->schema->storage->dbh;
 
     while (my ($col, $info) = each %$result) {
-        delete $info->{size}
-            unless $info->{data_type} =~ /^(?: (?:var)?(?:char(?:acter)?|binary) | bit | year)\z/ix;
+        delete $info->{size} if $info->{data_type} !~ /^(?: (?:var)?(?:char(?:acter)?|binary) | bit | year)\z/ix;
 
         if ($info->{data_type} eq 'int') {
             $info->{data_type} = 'integer';
@@ -146,17 +145,19 @@ sub _columns_info_for {
             $info->{data_type} = 'double precision';
         }
 
-        my ($precision, $scale, $column_type) = eval { $dbh->selectrow_array(<<'EOF', {}, lc $table, lc $col) };
-SELECT numeric_precision, numeric_scale, column_type
+        my ($precision, $scale, $column_type, $default) = eval { $dbh->selectrow_array(<<'EOF', {}, $table, $col) };
+SELECT numeric_precision, numeric_scale, column_type, column_default
 FROM information_schema.columns
-WHERE lower(table_name) = ? AND lower(column_name) = ?
+WHERE table_name = ? AND column_name = ?
 EOF
+        my $has_information_schema = not defined $@;
+
         $column_type = '' if not defined $column_type;
 
         if ($info->{data_type} eq 'bit' && (not exists $info->{size})) {
             $info->{size} = $precision if defined $precision;
         }
-        elsif ($info->{data_type} =~ /^(?:float|double precision|decimal)\z/) {
+        elsif ($info->{data_type} =~ /^(?:float|double precision|decimal)\z/i) {
             if (defined $precision && defined $scale) {
                 if ($precision == 10 && $scale == 0) {
                     delete $info->{size};
@@ -174,6 +175,19 @@ EOF
                 delete $info->{size};
             }
         }
+
+        # Sometimes apparently there's a bug where default_value gets set to ''
+        # for things that don't actually have or support that default (like ints.)
+        if (exists $info->{default_value} && $info->{default_value} eq '') {
+            if ($has_information_schema) {
+                if (not defined $default) {
+                    delete $info->{default_value};
+                }
+            }
+            else { # just check if it's a char/text type, otherwise remove
+                delete $info->{default_value} unless $info->{data_type} =~ /char|text/i;
+            }
+        }
     }
 
     return $result;
index 84339ce..045675d 100644 (file)
@@ -45,6 +45,8 @@ my $tester = dbixcsl_common_tests->new(
         'integer'     => { data_type => 'integer' },
         'integer unsigned'
                       => { data_type => 'integer',   extra => { unsigned => 1 } },
+        'integer not null'
+                      => { data_type => 'integer' },
         'bigint'      => { data_type => 'bigint' },
         'bigint unsigned'
                       => { data_type => 'bigint',    extra => { unsigned => 1 } },
@@ -117,9 +119,9 @@ my $tester = dbixcsl_common_tests->new(
         'longblob'    => { data_type => 'longblob' },
         'longtext'    => { data_type => 'longtext' },
 
-        "enum('foo', 'bar', 'baz')"
+        "enum('foo','bar','baz')"
                       => { data_type => 'enum', extra => { list => [qw/foo bar baz/] } },
-        "set('foo', 'bar', 'baz')"
+        "set('foo','bar','baz')"
                       => { data_type => 'set',  extra => { list => [qw/foo bar baz/] } },
     },
     extra => {
index 5ed2434..1e0593f 100644 (file)
@@ -110,6 +110,8 @@ sub run_only_extra_tests {
 
     plan tests => @$connect_info * (4 + ($self->{extra}{count} || 0) + ($self->{data_type_tests}{test_count} || 0));
 
+    rmtree $DUMP_DIR;
+
     foreach my $info_idx (0..$#$connect_info) {
         my $info = $connect_info->[$info_idx];