Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for alter table with unique constraint syntax in MySQL. #132

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 20 additions & 6 deletions lib/SQL/Translator/Parser/MySQL.pm
Original file line number Diff line number Diff line change
Expand Up @@ -101,14 +101,15 @@ Here's the word from the MySQL site
or INDEX DIRECTORY="absolute path to directory"


A subset of the ALTER TABLE syntax that allows addition of foreign keys:
A subset of the ALTER TABLE syntax that allows addition of foreign keys and unique keys:

ALTER [IGNORE] TABLE tbl_name alter_specification [, alter_specification] ...

alter_specification:
ADD [CONSTRAINT [symbol]]
FOREIGN KEY [index_name] (index_col_name,...)
[reference_definition]
or UNIQUE [INDEX|KEY] [index_name] (index_col_name,...)

A subset of INSERT that we ignore:

Expand Down Expand Up @@ -231,7 +232,8 @@ alter : ALTER TABLE table_name alter_specification(s /,/) "$delimiter"
}
}

alter_specification : ADD foreign_key_def
alter_specification : ADD foreign_key_def |
ADD unique_key_def
{ $return = $item[2] }

create : CREATE /database/i NAME "$delimiter"
Expand Down Expand Up @@ -777,17 +779,29 @@ primary_key_def : primary_key index_type(?) '(' name_with_opt_paren(s /,/) ')' i
};
}

unique_key_def : UNIQUE KEY(?) index_name_not_using(?) index_type(?) '(' name_with_opt_paren(s /,/) ')' index_type(?)
unique_key_def : unique_key_def_begin index_type(?) '(' name_with_opt_paren(s /,/) ')' index_type(?)
{
$return = {
supertype => 'constraint',
name => $item[3][0],
name => $item[1],
type => 'unique',
fields => $item[6],
options => $item[4][0] || $item[8][0],
fields => $item[4],
options => $item[2][0] || $item[6][0],
}
}

unique_key_def_begin : UNIQUE KEY(?) index_name_not_using
{ $return = $item[3] }
|
UNIQUE KEY(?)
{ $return = '' }
|
/constraint/i NAME UNIQUE KEY(?)
{ $return = $item[2] }
|
/constraint/i UNIQUE KEY(?)
{ $return = '' }

normal_index : KEY index_name_not_using(?) index_type(?) '(' name_with_opt_paren(s /,/) ')' index_type(?)
{
$return = {
Expand Down
100 changes: 100 additions & 0 deletions t/02mysql-parser.t
Original file line number Diff line number Diff line change
Expand Up @@ -959,4 +959,104 @@ ok ($@, 'Exception thrown on invalid version string');
ok (my $schema = $tr->schema, 'got schema');
}

{
my $tr = SQL::Translator->new;
my $data = parse($tr,
q[
create table `example` (
id integer not null,
`subid` varchar(255),
`subid2` varchar(255),
primary key (`id`)
);

alter table `example`
add constraint subid_uniq unique key (`subid`, `subid2`);
]
);

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, 'example', 'Found "example" table' );

my @fields = $table->get_fields;
is( scalar @fields, 3, 'Right number of fields (3)' );
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, 'subid', 'Second field name is "subid"' );
is( $f2->data_type, 'varchar', 'Type is "varchar"' );
is( $f2->size, 255, 'Size is "255"' );
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, 'subid2', 'Third field name is "subid2"' );
is( $f3->data_type, 'varchar', 'Type is "varchar"' );
is( $f3->size, 255, 'Size is "255"' );
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 @indices = $table->get_indices;
is( scalar @indices, 0, 'Right number of indices (0)' );

my @constraints = $table->get_constraints;
is( scalar @constraints, 2, 'Right number of constraints (2)' );

my $c1 = shift @constraints;
is( $c1->type, PRIMARY_KEY, 'Constraint is a PK' );
is( join(',', $c1->fields), 'id', 'Constraint is on "id"' );

my $c2 = shift @constraints;
is( $c2->type, UNIQUE, 'Constraint is UNIQUE' );
is( $c2->name, 'subid_uniq', 'Constraint name is "subid_uniq"' );
is( join(',', $c2->fields), 'subid,subid2', 'Constraint is on "subid, subid2"' );
}


{
my $tr = SQL::Translator->new;
my $data = parse($tr,
q[
create table `example` (
id integer not null,
`subid` varchar(255),
`subid2` varchar(255),
primary key (`id`)
);

alter table `example`
add unique index (`subid`, `subid2`);
]
);

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, 'example', 'Found "example" table' );

my @constraints = $table->get_constraints;
is( scalar @constraints, 2, 'Right number of constraints (2)' );

my $c1 = shift @constraints;
my $c2 = shift @constraints;
is( $c2->type, UNIQUE, 'Constraint is UNIQUE' );
is( $c2->name, '', 'No name on unique constraint' );
is( join(',', $c2->fields), 'subid,subid2', 'Constraint is on "subid, subid2"' );
}

done_testing;