From 5a794f82be65ca59fd9b4de085f5e99f70651f39 Mon Sep 17 00:00:00 2001 From: Alex Hermann Date: Fri, 29 Mar 2024 19:01:40 +0100 Subject: [PATCH] mysql-parser: Set missing field's collate to table's collate Newer MariaDB exports don;t set the field's collate if it is the same a the table's collate. To prevent huge diffs between exports of the old and new version, set missing field's collate to the table's collate. --- lib/SQL/Translator/Parser/MySQL.pm | 56 +++++++++++++++++++----------- 1 file changed, 35 insertions(+), 21 deletions(-) diff --git a/lib/SQL/Translator/Parser/MySQL.pm b/lib/SQL/Translator/Parser/MySQL.pm index 0a51c4ee..a7f05368 100644 --- a/lib/SQL/Translator/Parser/MySQL.pm +++ b/lib/SQL/Translator/Parser/MySQL.pm @@ -952,9 +952,38 @@ sub parse { my $tdata = $result->{tables}{$table_name}; my $table = $schema->add_table(name => $tdata->{'table_name'},) or die $schema->error; + my $table_collate = undef; $table->comments($tdata->{'comments'}); + if (my @options = @{ $tdata->{'table_options'} || [] }) { + my @cleaned_options; + my @ignore_opts + = $translator->parser_args->{'ignore_opts'} + ? split(/,/, $translator->parser_args->{'ignore_opts'}) + : (); + if (@ignore_opts) { + my $ignores = { map { $_ => 1 } @ignore_opts }; + foreach my $option (@options) { + + # make sure the option isn't in ignore list + my ($option_key) = keys %$option; + if (!exists $ignores->{$option_key}) { + push @cleaned_options, $option; + } + } + } else { + @cleaned_options = @options; + } + foreach my $option (@cleaned_options) { + my ($option_key) = keys %$option; + if ($option_key eq 'COLLATE') { + $table_collate = $option->{$option_key} + } + } + $table->options(\@cleaned_options) or die $table->error; + } + my @fields = sort { $tdata->{'fields'}->{$a}->{'order'} <=> $tdata->{'fields'}->{$b}->{'order'} } keys %{ $tdata->{'fields'} }; @@ -979,6 +1008,12 @@ sub parse { } } + # Set missing column's collate to the table's collate + if (!defined($field->extra('collate')) && + defined($table_collate)) { + $field->extra('collate', $table_collate); + } + if ($fdata->{'has_index'}) { $table->add_index( name => '', @@ -1011,27 +1046,6 @@ sub parse { ) or die $table->error; } - if (my @options = @{ $tdata->{'table_options'} || [] }) { - my @cleaned_options; - my @ignore_opts - = $translator->parser_args->{'ignore_opts'} - ? split(/,/, $translator->parser_args->{'ignore_opts'}) - : (); - if (@ignore_opts) { - my $ignores = { map { $_ => 1 } @ignore_opts }; - foreach my $option (@options) { - - # make sure the option isn't in ignore list - my ($option_key) = keys %$option; - if (!exists $ignores->{$option_key}) { - push @cleaned_options, $option; - } - } - } else { - @cleaned_options = @options; - } - $table->options(\@cleaned_options) or die $table->error; - } for my $cdata (@{ $tdata->{'constraints'} || [] }) { my $constraint = $table->add_constraint(