diff --git a/lib/SQL/Translator/Parser/MySQL.pm b/lib/SQL/Translator/Parser/MySQL.pm index 46085e33b..5ea196b23 100644 --- a/lib/SQL/Translator/Parser/MySQL.pm +++ b/lib/SQL/Translator/Parser/MySQL.pm @@ -46,7 +46,7 @@ Here's the word from the MySQL site or INTEGER[(length)] [UNSIGNED] [ZEROFILL] or BIGINT[(length)] [UNSIGNED] [ZEROFILL] or REAL[(length,decimals)] [UNSIGNED] [ZEROFILL] - or DOUBLE[(length,decimals)] [UNSIGNED] [ZEROFILL] + or DOUBLE[ PRECISTION][(length,decimals)] [UNSIGNED] [ZEROFILL] or FLOAT[(length,decimals)] [UNSIGNED] [ZEROFILL] or DECIMAL(length,decimals) [UNSIGNED] [ZEROFILL] or NUMERIC(length,decimals) [UNSIGNED] [ZEROFILL] @@ -626,7 +626,7 @@ field_name : NAME index_name : NAME -data_type : WORD parens_value_list(s?) type_qualifier(s?) +data_type : field_type parens_value_list(s?) type_qualifier(s?) { my $type = $item[1]; my $size; # field size, applicable only to non-set fields @@ -659,7 +659,7 @@ parens_value_list : '(' VALUE(s /,/) ')' type_qualifier : /(BINARY|UNSIGNED|ZEROFILL)/i { lc $item[1] } -field_type : WORD +field_type : /double\s+precision/i | WORD create_index : /create/i /index/i @@ -978,6 +978,8 @@ sub parse { comments => $fdata->{'comments'}, ) or die $table->error; + $field->{'data_type'} = 'double' if $fdata->{'data_type'} =~ /double\s+precision/i; + $table->primary_key( $field->name ) if $fdata->{'is_primary_key'}; for my $qual ( qw[ binary unsigned zerofill list collate ], @@ -1133,13 +1135,18 @@ sub normalize_field { $changed = $size != 20; $size = 20; } - elsif ( lc $type =~ /(float|double|decimal|numeric|real|fixed|dec)/ ) { + elsif ( lc $type =~ /(decimal|numeric|fixed|dec)/ ) { my $old_size = (ref $size || '') eq 'ARRAY' ? $size : []; $changed = @$old_size != 2 || $old_size->[0] != 8 || $old_size->[1] != 2; $size = [8,2]; } + elsif ( lc $type =~ /(float|double|real)/ ) { + my $old_size = (ref $size || '') eq 'ARRAY' ? $size : []; + $changed = @$old_size != 2; + $size = 0; + } } if ( $type =~ /^tiny(text|blob)$/i ) { diff --git a/t/02mysql-parser.t b/t/02mysql-parser.t index d521b9d6e..58ee07b9a 100644 --- a/t/02mysql-parser.t +++ b/t/02mysql-parser.t @@ -959,4 +959,95 @@ ok ($@, 'Exception thrown on invalid version string'); ok (my $schema = $tr->schema, 'got schema'); } +{ + my $tr = SQL::Translator->new; + my $val = parse($tr, + q[ + create table `test` ( + id integer not null primary key, + value1 double precision, + value2 double precision(9,3), + value3 double, + value4 double(6,1), + value5 float, + value6 float(5, 2) + ); + ] + ); + my $schema = $tr->schema; + is( $schema->is_valid, 1, 'Schema is valid' ); + my @tables = $schema->get_tables; + is( scalar @tables, 1, 'Right number of tables (1)' ); + my $table = shift @tables; + is( $table->name, 'test', 'Found "test" table' ); + + my @fields = $table->get_fields; + is( scalar @fields, 7, 'Right number of fields (7)' ); + my $f1 = shift @fields; + is( $f1->name, 'id', 'First field name is "id"' ); + is( $f1->data_type, 'int', 'Type is "int"' ); + is( $f1->size, 11, 'Size is "11"' ); + is( $f1->is_nullable, 0, 'Field cannot be null' ); + is( $f1->default_value, undef, 'Default value is undefined' ); + is( $f1->is_primary_key, 1, 'Field is PK' ); + is( $f1->is_auto_increment, 0, 'Field is not auto inc' ); + + my $f2 = shift @fields; + is( $f2->name, 'value1', 'Second field name is "value1"' ); + is( $f2->data_type, 'double', 'Type is "double"' ); + is( $f2->size, 0, 'Size is "0"' ); + is( $f2->is_nullable, 1, 'Field can be null' ); + is( $f2->default_value, undef, 'Default value is undefined' ); + is( $f2->is_primary_key, 0, 'Field is not PK' ); + + my $f3 = shift @fields; + is( $f3->name, 'value2', 'Third field name is "value2"' ); + is( $f3->data_type, 'double', 'Type is "double"' ); + is( $f3->size, '9,3', 'Size is "9,3"' ); + is( $f3->is_nullable, 1, 'Field can be null' ); + is( $f3->default_value, undef, 'Default value is undefined' ); + is( $f3->is_primary_key, 0, 'Field is not PK' ); + + my $f4 = shift @fields; + is( $f4->name, 'value3', 'Forth field name is "value3"' ); + is( $f4->data_type, 'double', 'Type is "double"' ); + is( $f4->size, 0, 'Size is "0"' ); + is( $f4->is_nullable, 1, 'Field can be null' ); + is( $f4->default_value, undef, 'Default value is undefined' ); + is( $f4->is_primary_key, 0, 'Field is not PK' ); + + my $f5 = shift @fields; + is( $f5->name, 'value4', 'Fifth field name is "value4"' ); + is( $f5->data_type, 'double', 'Type is "double"' ); + is( $f5->size, '6,1', 'Size is "6,1"' ); + is( $f5->is_nullable, 1, 'Field can be null' ); + is( $f5->default_value, undef, 'Default value is undefined' ); + is( $f5->is_primary_key, 0, 'Field is not PK' ); + + my $f6 = shift @fields; + is( $f6->name, 'value5', 'Sixth field name is "value5"' ); + is( $f6->data_type, 'float', 'Type is "float"' ); + is( $f6->size, 0, 'Size is "0"' ); + is( $f6->is_nullable, 1, 'Field can be null' ); + is( $f6->default_value, undef, 'Default value is undefined' ); + is( $f6->is_primary_key, 0, 'Field is not PK' ); + + my $f7 = shift @fields; + is( $f7->name, 'value6', 'Seventh field name is "value6"' ); + is( $f7->data_type, 'float', 'Type is "float"' ); + is( $f7->size, '5,2', 'Size is "5,2"' ); + is( $f7->is_nullable, 1, 'Field can be null' ); + is( $f7->default_value, undef, 'Default value is undefined' ); + is( $f7->is_primary_key, 0, 'Field is not PK' ); + + my @indices = $table->get_indices; + is( scalar @indices, 0, 'Right number of indices (0)' ); + + my @constraints = $table->get_constraints; + is( scalar @constraints, 1, 'Right number of constraints (1)' ); + my $c = shift @constraints; + is( $c->type, PRIMARY_KEY, 'Constraint is a PK' ); + is( join(',', $c->fields), 'id', 'Constraint is on "id"' ); +} + done_testing; diff --git a/t/30sqlt-new-diff-mysql.t b/t/30sqlt-new-diff-mysql.t index 79df23f22..98a7df5cd 100644 --- a/t/30sqlt-new-diff-mysql.t +++ b/t/30sqlt-new-diff-mysql.t @@ -200,7 +200,7 @@ ALTER TABLE employee DROP FOREIGN KEY FK5302D47D93FE702E, ALTER TABLE person DROP CONSTRAINT UC_age_name, DROP INDEX u_name, ADD COLUMN is_rock_star tinyint(4) NULL DEFAULT 1, - ADD COLUMN value double(8, 2) NULL DEFAULT 0.00, + ADD COLUMN value double NULL DEFAULT 0.0, CHANGE COLUMN person_id person_id integer(11) NOT NULL auto_increment, CHANGE COLUMN name name varchar(20) NOT NULL, CHANGE COLUMN age age integer(11) NULL DEFAULT 18, diff --git a/t/30sqlt-new-diff-sqlite.t b/t/30sqlt-new-diff-sqlite.t index 34f6fb1c4..3f10f4c51 100644 --- a/t/30sqlt-new-diff-sqlite.t +++ b/t/30sqlt-new-diff-sqlite.t @@ -128,7 +128,7 @@ CREATE TEMPORARY TABLE person_temp_alter ( weight double(11,2), iq int(11) DEFAULT 0, is_rock_star tinyint(4) DEFAULT 1, - value double(8,2) DEFAULT 0.00, + value double DEFAULT 0.0, physical_description text ); @@ -143,7 +143,7 @@ CREATE TABLE person ( weight double(11,2), iq int(11) DEFAULT 0, is_rock_star tinyint(4) DEFAULT 1, - value double(8,2) DEFAULT 0.00, + value double DEFAULT 0.0, physical_description text ); diff --git a/t/data/diff/create1.yml b/t/data/diff/create1.yml index b0f147763..83c844376 100644 --- a/t/data/diff/create1.yml +++ b/t/data/diff/create1.yml @@ -214,9 +214,7 @@ schema: is_unique: 0 name: value order: 7 - size: - - 8 - - 2 + size: 0 indices: - fields: - name diff --git a/t/data/diff/create2.yml b/t/data/diff/create2.yml index d5912d14d..6d1b920e9 100644 --- a/t/data/diff/create2.yml +++ b/t/data/diff/create2.yml @@ -218,16 +218,14 @@ schema: - 2 value: data_type: double - default_value: 0.00 + default_value: 0.0 extra: {} is_nullable: 1 is_primary_key: 0 is_unique: 0 name: value order: 7 - size: - - 8 - - 2 + size: 0 indices: - fields: - name