Skip to content

Commit

Permalink
Bug 1592129: [MYSQL8] The groups table in Bugzilla conflicts with res…
Browse files Browse the repository at this point in the history
…erved keyword in MySQL 8.x (#153)

* [MYSQL8] The groups table in Bugzilla conflicts with reserved keyword in MySQL 8.x
  • Loading branch information
bovine committed Mar 13, 2024
1 parent 1fcfb29 commit 0867901
Show file tree
Hide file tree
Showing 19 changed files with 264 additions and 140 deletions.
2 changes: 1 addition & 1 deletion Bugzilla/Bug.pm
Original file line number Diff line number Diff line change
Expand Up @@ -3984,7 +3984,7 @@ sub groups {
. " THEN 1 ELSE 0 END,"
. " CASE WHEN groups.id IN($grouplist) THEN 1 ELSE 0 END,"
. " isactive, membercontrol, othercontrol"
. " FROM groups"
. " FROM " . $dbh->quote_identifier('groups')
. " LEFT JOIN bug_group_map"
. " ON bug_group_map.group_id = groups.id"
. " AND bug_id = ?"
Expand Down
15 changes: 12 additions & 3 deletions Bugzilla/DB.pm
Original file line number Diff line number Diff line change
Expand Up @@ -1559,7 +1559,11 @@ sub _check_references {
# reserved words.
my $bad_values = $self->selectcol_arrayref(
"SELECT DISTINCT tabl.$column
FROM $table AS tabl LEFT JOIN $foreign_table AS forn
FROM "
. $self->quote_identifier($table)
. " AS tabl LEFT JOIN "
. $self->quote_identifier($foreign_table)
. " AS forn
ON tabl.$column = forn.$foreign_column
WHERE forn.$foreign_column IS NULL
AND tabl.$column IS NOT NULL"
Expand All @@ -1569,7 +1573,10 @@ sub _check_references {
my $delete_action = $fk->{DELETE} || '';
if ($delete_action eq 'CASCADE') {
$self->do(
"DELETE FROM $table WHERE $column IN (" . join(',', ('?') x @$bad_values) . ")",
"DELETE FROM "
. $self->quote_identifier($table)
. " WHERE $column IN ("
. join(',', ('?') x @$bad_values) . ")",
undef, @$bad_values
);
if (Bugzilla->usage_mode == USAGE_MODE_CMDLINE) {
Expand All @@ -1590,7 +1597,9 @@ sub _check_references {
}
elsif ($delete_action eq 'SET NULL') {
$self->do(
"UPDATE $table SET $column = NULL
"UPDATE "
. $self->quote_identifier($table)
. " SET $column = NULL
WHERE $column IN ("
. join(',', ('?') x @$bad_values) . ")", undef, @$bad_values
);
Expand Down
37 changes: 28 additions & 9 deletions Bugzilla/DB/Mysql.pm
Original file line number Diff line number Diff line change
Expand Up @@ -338,10 +338,17 @@ sub bz_setup_database {
if ($self->utf8_charset eq 'utf8mb4') {
my %global = map {@$_}
@{$self->selectall_arrayref(q(SHOW GLOBAL VARIABLES LIKE 'innodb_%'))};

# In versions of MySQL > 8, the default value for innodb_file_format is Barracuda
# and the setting was deprecated. Also innodb_file_per_table also now defaults
# to ON. innodb_large_prefix has also been removed in newer MySQL versions.
my $utf8mb4_supported
= $global{innodb_file_format} eq 'Barracuda'
&& $global{innodb_file_per_table} eq 'ON'
&& $global{innodb_large_prefix} eq 'ON';
= (!exists $global{innodb_file_format}
|| $global{innodb_file_format} eq 'Barracuda')
&& (!exists $global{innodb_file_per_table}
|| $global{innodb_file_per_table} eq 'ON')
&& (!exists $global{innodb_large_prefix}
|| $global{innodb_large_prefix} eq 'ON');

die install_string('mysql_innodb_settings') unless $utf8mb4_supported;

Expand All @@ -359,7 +366,11 @@ sub bz_setup_database {
'mysql_row_format_conversion', {table => $table, format => $new_row_format}
),
"\n";
$self->do(sprintf 'ALTER TABLE %s ROW_FORMAT=%s', $table, $new_row_format);
$self->do(
sprintf 'ALTER TABLE %s ROW_FORMAT=%s',
$self->quote_identifier($table),
$new_row_format
);
}
}
}
Expand Down Expand Up @@ -402,7 +413,7 @@ sub bz_setup_database {
" most tables.\nConverting tables to InnoDB:\n";
foreach my $table (@$myisam_tables) {
print "Converting table $table... ";
$self->do("ALTER TABLE $table ENGINE = InnoDB");
$self->do('ALTER TABLE ' . $self->quote_identifier($table) . ' ENGINE = InnoDB');
print "done.\n";
}
}
Expand Down Expand Up @@ -770,8 +781,13 @@ sub bz_setup_database {
}

print "Converting the $table table to UTF-8...\n";
my $bin = "ALTER TABLE $table " . join(', ', @binary_sql);
my $utf = "ALTER TABLE $table "
my $bin
= 'ALTER TABLE '
. $self->quote_identifier($table) . ' '
. join(', ', @binary_sql);
my $utf
= 'ALTER TABLE '
. $self->quote_identifier($table) . ' '
. join(', ', @utf8_sql, "DEFAULT CHARACTER SET $charset COLLATE $collate");
$self->do($bin);
$self->do($utf);
Expand All @@ -782,7 +798,9 @@ sub bz_setup_database {
}
}
else {
$self->do("ALTER TABLE $table DEFAULT CHARACTER SET $charset COLLATE $collate");
$self->do('ALTER TABLE '
. $self->quote_identifier($table)
. " DEFAULT CHARACTER SET $charset COLLATE $collate");
}

} # foreach my $table (@tables)
Expand Down Expand Up @@ -870,7 +888,8 @@ sub _fix_defaults {
print "Fixing defaults...\n";
foreach my $table (reverse sort keys %fix_columns) {
my @alters = map("ALTER COLUMN $_ DROP DEFAULT", @{$fix_columns{$table}});
my $sql = "ALTER TABLE $table " . join(',', @alters);
my $sql
= 'ALTER TABLE ' . $self->quote_identifier($table) . ' ' . join(',', @alters);
$self->do($sql);
}
}
Expand Down
79 changes: 60 additions & 19 deletions Bugzilla/DB/Schema.pm
Original file line number Diff line number Diff line change
Expand Up @@ -2014,7 +2014,9 @@ is undefined.

return
"\n CONSTRAINT $fk_name FOREIGN KEY ($column)\n"
. " REFERENCES $to_table($to_column)\n"
. " REFERENCES "
. Bugzilla->dbh->quote_identifier($to_table)
. "($to_column)\n"
. " ON UPDATE $update ON DELETE $delete";
}

Expand Down Expand Up @@ -2049,13 +2051,18 @@ sub get_add_fks_sql {
my @add = $self->_column_fks_to_ddl($table, $column_fks);

my @sql;
my $dbh = Bugzilla->dbh;
if ($self->MULTIPLE_FKS_IN_ALTER) {
my $alter = "ALTER TABLE $table ADD " . join(', ADD ', @add);
my $alter
= "ALTER TABLE "
. $dbh->quote_identifier($table) . " ADD "
. join(', ADD ', @add);
push(@sql, $alter);
}
else {
foreach my $fk_string (@add) {
push(@sql, "ALTER TABLE $table ADD $fk_string");
push(@sql,
"ALTER TABLE " . $dbh->quote_identifier($table) . " ADD $fk_string");
}
}
return @sql;
Expand All @@ -2076,7 +2083,8 @@ sub get_drop_fk_sql {
my ($self, $table, $column, $references) = @_;
my $fk_name = $self->_get_fk_name($table, $column, $references);

return ("ALTER TABLE $table DROP CONSTRAINT $fk_name");
return (
"ALTER TABLE " . Bugzilla->dbh->quote_identifier($table) . " DROP CONSTRAINT $fk_name");
}

sub convert_type {
Expand Down Expand Up @@ -2241,7 +2249,9 @@ sub _get_create_table_ddl {
}

my $sql
= "CREATE TABLE $table (\n" . join(",\n", @col_lines, @fk_lines) . "\n)";
= "CREATE TABLE "
. Bugzilla->dbh->quote_identifier($table) . " (\n"
. join(",\n", @col_lines, @fk_lines) . "\n)";
return $sql;

}
Expand All @@ -2265,7 +2275,9 @@ sub _get_create_index_ddl {
my $sql = "CREATE ";
$sql .= "$index_type " if ($index_type && $index_type eq 'UNIQUE');
$sql
.= "INDEX $index_name ON $table_name \(" . join(", ", @$index_fields) . "\)";
.= "INDEX $index_name ON "
. Bugzilla->dbh->quote_identifier($table_name) . ' ('
. join(', ', @$index_fields) . ')';

return ($sql);

Expand All @@ -2291,16 +2303,20 @@ sub get_add_column_ddl {

my ($self, $table, $column, $definition, $init_value) = @_;
my @statements;
my $dbh = Bugzilla->dbh;
push(@statements,
"ALTER TABLE $table "
'ALTER TABLE '
. $dbh->quote_identifier($table) . ' '
. $self->ADD_COLUMN
. " $column "
. $self->get_type_ddl($definition));

# XXX - Note that although this works for MySQL, most databases will fail
# before this point, if we haven't set a default.
(push(@statements, "UPDATE $table SET $column = $init_value"))
if defined $init_value;
(
push(@statements,
'UPDATE ' . $dbh->quote_identifier($table) . " SET $column = $init_value")
) if defined $init_value;

if (defined $definition->{REFERENCES}) {
push(@statements,
Expand Down Expand Up @@ -2367,6 +2383,7 @@ sub get_alter_column_ddl {

my $self = shift;
my ($table, $column, $new_def, $set_nulls_to) = @_;
my $dbh = Bugzilla->dbh;

my @statements;
my $old_def = $self->get_column_abstract($table, $column);
Expand All @@ -2393,36 +2410,51 @@ sub get_alter_column_ddl {

# If we went from having a default to not having one
elsif (!defined $default && defined $default_old) {
push(@statements, "ALTER TABLE $table ALTER COLUMN $column" . " DROP DEFAULT");
push(@statements,
"ALTER TABLE "
. $dbh->quote_identifier($table)
. " ALTER COLUMN $column DROP DEFAULT");
}

# If we went from no default to a default, or we changed the default.
elsif ((defined $default && !defined $default_old)
|| ($default ne $default_old))
{
push(@statements,
"ALTER TABLE $table ALTER COLUMN $column " . " SET DEFAULT $default");
"ALTER TABLE "
. $dbh->quote_identifier($table)
. " ALTER COLUMN $column SET DEFAULT $default");
}

# If we went from NULL to NOT NULL.
if (!$old_def->{NOTNULL} && $new_def->{NOTNULL}) {
push(@statements, $self->_set_nulls_sql(@_));
push(@statements, "ALTER TABLE $table ALTER COLUMN $column" . " SET NOT NULL");
push(@statements,
"ALTER TABLE "
. $dbh->quote_identifier($table)
. " ALTER COLUMN $column SET NOT NULL");
}

# If we went from NOT NULL to NULL
elsif ($old_def->{NOTNULL} && !$new_def->{NOTNULL}) {
push(@statements, "ALTER TABLE $table ALTER COLUMN $column" . " DROP NOT NULL");
push(@statements,
"ALTER TABLE "
. $dbh->quote_identifier($table)
. " ALTER COLUMN $column DROP NOT NULL");
}

# If we went from not being a PRIMARY KEY to being a PRIMARY KEY.
if (!$old_def->{PRIMARYKEY} && $new_def->{PRIMARYKEY}) {
push(@statements, "ALTER TABLE $table ADD PRIMARY KEY ($column)");
push(@statements,
"ALTER TABLE "
. $dbh->quote_identifier($table)
. " ADD PRIMARY KEY ($column)");
}

# If we went from being a PK to not being a PK
elsif ($old_def->{PRIMARYKEY} && !$new_def->{PRIMARYKEY}) {
push(@statements, "ALTER TABLE $table DROP PRIMARY KEY");
push(@statements,
"ALTER TABLE " . $dbh->quote_identifier($table) . " DROP PRIMARY KEY");
}

return @statements;
Expand All @@ -2444,7 +2476,10 @@ sub _set_nulls_sql {
}
my @sql;
if (defined $default) {
push(@sql, "UPDATE $table SET $column = $default" . " WHERE $column IS NULL");
push(@sql,
"UPDATE "
. Bugzilla->dbh->quote_identifier($table)
. " SET $column = $default WHERE $column IS NULL");
}
return @sql;
}
Expand Down Expand Up @@ -2479,7 +2514,9 @@ sub get_drop_column_ddl {
=cut

my ($self, $table, $column) = @_;
return ("ALTER TABLE $table DROP COLUMN $column");
return ("ALTER TABLE "
. Bugzilla->dbh->quote_identifier($table)
. " DROP COLUMN $column");
}

=item C<get_drop_table_ddl($table)>
Expand All @@ -2492,7 +2529,7 @@ sub get_drop_column_ddl {

sub get_drop_table_ddl {
my ($self, $table) = @_;
return ("DROP TABLE $table");
return ('DROP TABLE ' . Bugzilla->dbh->quote_identifier($table));
}

sub get_rename_column_ddl {
Expand Down Expand Up @@ -2542,7 +2579,11 @@ Gets SQL to rename a table in the database.
=cut

my ($self, $old_name, $new_name) = @_;
return ("ALTER TABLE $old_name RENAME TO $new_name");
my $dbh = Bugzilla->dbh;
return ('ALTER TABLE '
. $dbh->quote_identifier($old_name)
. ' RENAME TO '
. $dbh->quote_identifier($new_name));
}

=item C<delete_table($name)>
Expand Down

0 comments on commit 0867901

Please sign in to comment.