From: Rafael Kitover Date: Wed, 5 May 2010 21:34:52 +0000 (-0400) Subject: fix erroneous default_value for MySQL NOT NULL columns (RT#57225) X-Git-Tag: 0.07000~35 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=dbsrgits%2FDBIx-Class-Schema-Loader.git;a=commitdiff_plain;h=33aa346253f9628fea4a9ac427048b544cd91463 fix erroneous default_value for MySQL NOT NULL columns (RT#57225) --- diff --git a/Changes b/Changes index 2404d9a..ae0b91c 100644 --- 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 diff --git a/lib/DBIx/Class/Schema/Loader/DBI/mysql.pm b/lib/DBIx/Class/Schema/Loader/DBI/mysql.pm index e6e10ee..1eb9107 100644 --- a/lib/DBIx/Class/Schema/Loader/DBI/mysql.pm +++ b/lib/DBIx/Class/Schema/Loader/DBI/mysql.pm @@ -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; diff --git a/t/11mysql_common.t b/t/11mysql_common.t index 84339ce..045675d 100644 --- a/t/11mysql_common.t +++ b/t/11mysql_common.t @@ -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 => { diff --git a/t/lib/dbixcsl_common_tests.pm b/t/lib/dbixcsl_common_tests.pm index 5ed2434..1e0593f 100644 --- a/t/lib/dbixcsl_common_tests.pm +++ b/t/lib/dbixcsl_common_tests.pm @@ -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];