Commit 81c5ce1d authored by mkanat%bugzilla.org's avatar mkanat%bugzilla.org

Bug 458390: Foreign Key names can be too long as currently designed

Patch By Max Kanat-Alexander <mkanat@bugzilla.org> r=ghendricks
parent 6708131d
...@@ -41,6 +41,7 @@ use Bugzilla::Util; ...@@ -41,6 +41,7 @@ use Bugzilla::Util;
use Bugzilla::Constants; use Bugzilla::Constants;
use Carp qw(confess); use Carp qw(confess);
use Digest::MD5 qw(md5_hex);
use Hash::Util qw(lock_value unlock_hash lock_keys unlock_keys); use Hash::Util qw(lock_value unlock_hash lock_keys unlock_keys);
use Safe; use Safe;
# Historical, needed for SCHEMA_VERSION = '1.00' # Historical, needed for SCHEMA_VERSION = '1.00'
...@@ -207,6 +208,8 @@ update this column in this table." ...@@ -207,6 +208,8 @@ update this column in this table."
use constant SCHEMA_VERSION => '2.00'; use constant SCHEMA_VERSION => '2.00';
use constant ADD_COLUMN => 'ADD COLUMN'; use constant ADD_COLUMN => 'ADD COLUMN';
# This is a reasonable default that's true for both PostgreSQL and MySQL.
use constant MAX_IDENTIFIER_LEN => 63;
use constant ABSTRACT_SCHEMA => { use constant ABSTRACT_SCHEMA => {
# BUG-RELATED TABLES # BUG-RELATED TABLES
...@@ -1689,9 +1692,23 @@ sub _get_fk_name { ...@@ -1689,9 +1692,23 @@ sub _get_fk_name {
my ($self, $table, $column, $references) = @_; my ($self, $table, $column, $references) = @_;
my $to_table = $references->{TABLE}; my $to_table = $references->{TABLE};
my $to_column = $references->{COLUMN}; my $to_column = $references->{COLUMN};
return "fk_${table}_${column}_${to_table}_${to_column}"; my $name = "fk_${table}_${column}_${to_table}_${to_column}";
if (length($name) > $self->MAX_IDENTIFIER_LEN) {
$name = 'fk_' . $self->_hash_identifier($name);
}
return $name;
} }
sub _hash_identifier {
my ($invocant, $value) = @_;
# We do -7 to allow prefixes like "idx_" or "fk_", or perhaps something
# longer in the future.
return substr(md5_hex($value), 0, $invocant->MAX_IDENTIFIER_LEN - 7);
}
sub get_add_fk_sql { sub get_add_fk_sql {
my ($self, $table, $column, $def) = @_; my ($self, $table, $column, $def) = @_;
......
...@@ -32,10 +32,13 @@ use strict; ...@@ -32,10 +32,13 @@ use strict;
use base qw(Bugzilla::DB::Schema); use base qw(Bugzilla::DB::Schema);
use Carp qw(confess); use Carp qw(confess);
use Digest::MD5 qw(md5_hex);
use Bugzilla::Util; use Bugzilla::Util;
use constant ADD_COLUMN => 'ADD'; use constant ADD_COLUMN => 'ADD';
# Whether this is true or not, this is what it needs to be in order for
# hash_identifier to maintain backwards compatibility with versions before
# 3.2rc2.
use constant MAX_IDENTIFIER_LEN => 27;
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
sub _initialize { sub _initialize {
...@@ -105,7 +108,7 @@ sub get_table_ddl { ...@@ -105,7 +108,7 @@ sub get_table_ddl {
sub _get_create_index_ddl { sub _get_create_index_ddl {
my ($self, $table_name, $index_name, $index_fields, $index_type) = @_; my ($self, $table_name, $index_name, $index_fields, $index_type) = @_;
$index_name = "idx_" . $self->_hash_index_name($index_name); $index_name = "idx_" . $self->_hash_identifier($index_name);
if ($index_type eq 'FULLTEXT') { if ($index_type eq 'FULLTEXT') {
my $sql = "CREATE INDEX $index_name ON $table_name (" my $sql = "CREATE INDEX $index_name ON $table_name ("
. join(',',@$index_fields) . join(',',@$index_fields)
...@@ -123,14 +126,10 @@ sub get_drop_index_ddl { ...@@ -123,14 +126,10 @@ sub get_drop_index_ddl {
my $self = shift; my $self = shift;
my ($table, $name) = @_; my ($table, $name) = @_;
$name = 'idx_' . $self->_hash_index_name($name); $name = 'idx_' . $self->_hash_identifier($name);
return $self->SUPER::get_drop_index_ddl($table, $name); return $self->SUPER::get_drop_index_ddl($table, $name);
} }
sub _hash_index_name {
return substr(md5_hex($_[1]),0,20);
}
# Oracle supports the use of FOREIGN KEY integrity constraints # Oracle supports the use of FOREIGN KEY integrity constraints
# to define the referential integrity actions, including: # to define the referential integrity actions, including:
# - Update and delete No Action (default) # - Update and delete No Action (default)
...@@ -187,7 +186,7 @@ sub _get_fk_name { ...@@ -187,7 +186,7 @@ sub _get_fk_name {
my $to_table = $references->{TABLE}; my $to_table = $references->{TABLE};
my $to_column = $references->{COLUMN}; my $to_column = $references->{COLUMN};
my $fk_name = "${table}_${column}_${to_table}_${to_column}"; my $fk_name = "${table}_${column}_${to_table}_${to_column}";
$fk_name = "fk_" . $self->_hash_index_name($fk_name); $fk_name = "fk_" . $self->_hash_identifier($fk_name);
return $fk_name; return $fk_name;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment