From: Jess Robinson Date: Wed, 22 Oct 2008 21:19:45 +0000 (+0000) Subject: Patch from jgoulah for mysqls UNION (merge engine) option X-Git-Tag: v0.11008~289 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=9a96648f006e57816543756a548303d55397010e;p=dbsrgits%2FSQL-Translator.git Patch from jgoulah for mysqls UNION (merge engine) option --- diff --git a/Changes b/Changes index ecade0b..e514881 100644 --- a/Changes +++ b/Changes @@ -1,6 +1,7 @@ # ---------------------------------------------------------- # # ---------------------------------------------------------- +* Applied patch from jgoulah to support mysql's MERGE option * Applied patch from rbo to add support of multiple database events on a trigger * Applied patch from lukes to allow drop if exists in sqlite producer, with version >= 3.3 * Applied patch from rjbs with minor changes, now we support scalar refs in default values! diff --git a/lib/SQL/Translator/Parser/MySQL.pm b/lib/SQL/Translator/Parser/MySQL.pm index a8793f6..e132ee4 100644 --- a/lib/SQL/Translator/Parser/MySQL.pm +++ b/lib/SQL/Translator/Parser/MySQL.pm @@ -713,6 +713,10 @@ table_option : /comment/i /=/ /'.*?'/ { $return = { 'COLLATE' => $item[2] } } + | /union/i /\s*=\s*/ '(' table_name(s /,/) ')' + { + $return = { $item[1] => $item[4] }; + } | WORD /\s*=\s*/ WORD { $return = { $item[1] => $item[3] }; @@ -765,7 +769,6 @@ END_OF_GRAMMAR sub parse { my ( $translator, $data ) = @_; my $parser = Parse::RecDescent->new($GRAMMAR); - local $::RD_TRACE = $translator->trace ? 1 : undef; local $DEBUG = $translator->debug; diff --git a/lib/SQL/Translator/Producer/MySQL.pm b/lib/SQL/Translator/Producer/MySQL.pm index 9121160..86b32bf 100644 --- a/lib/SQL/Translator/Producer/MySQL.pm +++ b/lib/SQL/Translator/Producer/MySQL.pm @@ -419,7 +419,7 @@ sub create_table # Footer # $create .= "\n)"; - $create .= generate_table_options($table) || ''; + $create .= generate_table_options($table, $options) || ''; # $create .= ";\n\n"; return $drop ? ($drop,$create) : $create; @@ -427,12 +427,14 @@ sub create_table sub generate_table_options { - my ($table) = @_; + my ($table, $options) = @_; my $create; my $table_type_defined = 0; + my $qf = $options->{quote_field_names} ||= ''; my $charset = $table->extra('mysql_charset'); my $collate = $table->extra('mysql_collate'); + my $union = undef; for my $t1_option_ref ( $table->options ) { my($key, $value) = %{$t1_option_ref}; $table_type_defined = 1 @@ -443,6 +445,9 @@ sub generate_table_options } elsif (uc $key eq 'COLLATE') { $collate = $value; next; + } elsif (uc $key eq 'UNION') { + $union = "($qf". join("$qf, $qf", @$value) ."$qf)"; + next; } $create .= " $key=$value"; } @@ -454,6 +459,7 @@ sub generate_table_options $create .= " DEFAULT CHARACTER SET $charset" if $charset; $create .= " COLLATE $collate" if $collate; + $create .= " UNION=$union" if $union; $create .= qq[ comment='$comments'] if $comments; return $create; } @@ -730,7 +736,7 @@ sub alter_table my $qt = $options->{quote_table_names} || ''; - my $table_options = generate_table_options($to_table) || ''; + my $table_options = generate_table_options($to_table, $options) || ''; my $out = sprintf('ALTER TABLE %s%s', $qt . $to_table->name . $qt, $table_options); diff --git a/t/02mysql-parser.t b/t/02mysql-parser.t index 585bd05..1ed7001 100644 --- a/t/02mysql-parser.t +++ b/t/02mysql-parser.t @@ -11,7 +11,7 @@ use SQL::Translator::Utils qw//; use Test::SQL::Translator qw(maybe_plan); BEGIN { - maybe_plan(244, "SQL::Translator::Parser::MySQL"); + maybe_plan(265, "SQL::Translator::Parser::MySQL"); SQL::Translator::Parser::MySQL->import('parse'); } @@ -660,3 +660,65 @@ for my $target (keys %$parse_as) { eval { SQL::Translator::Utils::parse_mysql_version ('bogus5.1') }; ok ($@, 'Exception thrown on invalid version string'); + +{ + my $tr = SQL::Translator->new; + my $data = q|create table merge_example ( + id int(11) NOT NULL auto_increment, + shape_field geometry NOT NULL, + PRIMARY KEY (id), + SPATIAL KEY shape_field (shape_field) + ) ENGINE=MRG_MyISAM UNION=(`sometable_0`,`sometable_1`,`sometable_2`);|; + + my $val = parse($tr, $data); + 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, 'merge_example', 'Found "merge_example" table' ); + + my $tableTypeFound = 0; + my $unionFound = 0; + for my $t_option_ref ( $table->options ) { + my($key, $value) = %{$t_option_ref}; + if ( $key eq 'ENGINE' ) { + is($value, 'MRG_MyISAM', 'Table has right table engine option' ); + $tableTypeFound = 1; + } elsif ( $key eq 'UNION' ) { + is_deeply($value, [ 'sometable_0','sometable_1','sometable_2' ], + "UNION option has correct set"); + $unionFound = 1; + } + } + + fail('Table did not have a type option') unless $tableTypeFound; + fail('Table did not have a union option') unless $unionFound; + + my @fields = $table->get_fields; + is( scalar @fields, 2, 'Right number of fields (2)' ); + my $f1 = shift @fields; + my $f2 = 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->is_primary_key, 1, 'Field is PK' ); + + is( $f2->name, 'shape_field', 'Second field name is "shape_field"' ); + is( $f2->data_type, 'geometry', 'Type is "geometry"' ); + is( $f2->is_nullable, 0, 'Field cannot be null' ); + is( $f2->is_primary_key, 0, 'Field is not PK' ); + + my @indices = $table->get_indices; + is( scalar @indices, 1, 'Right number of indices (1)' ); + my $i1 = shift @indices; + is( $i1->name, 'shape_field', 'No name on index' ); + is( $i1->type, SPATIAL, 'Spatial index' ); + + 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"' ); +}