MT#66199 helper/compare_dbs.pl: normalize options under quotes

On Debian/forky we have mariadb version 11.8.9+ds-2, and our
check-ngcp-db-compare-schemes there fails due to:

| Element: tables/provisioning/voip_contract_preferences_blob/create_options are not equal:
|   ---
|   local db:  `PAGE_COMPRESSED`='1'
|   json file: `PAGE_COMPRESSED`=1
| Element: tables/provisioning/voip_dom_preferences_blob/create_options are not equal:
|   ---
|   local db:  `PAGE_COMPRESSED`='1'
|   json file: `PAGE_COMPRESSED`=1
| Element: tables/provisioning/voip_peer_preferences_blob/create_options are not equal:
|   ---
|   local db:  `PAGE_COMPRESSED`='1'
|   json file: `PAGE_COMPRESSED`=1
| Element: tables/provisioning/voip_usr_preferences_blob/create_options are not equal:
|   ---
|   local db:  `PAGE_COMPRESSED`='1'
|   json file: `PAGE_COMPRESSED`=1

This is caused by a behavior change in mariadb v11.8.9, quoting from
https://mariadb.com/docs/release-notes/community-server/11.8/11.8.9:

| SHOW CREATE TABLE corrupts `-quoted table options (MDEV-39776)

See https://jira.mariadb.org/browse/MDEV-39776 for further details.

NOTE: someone else also stumbled upon this, see
https://jira.mariadb.org/browse/MDEV-41307

So up and until including Debian/trixie we had:

  MariaDB [provisioning]> SELECT TABLE_NAME, ENGINE, TABLE_COLLATION, CREATE_OPTIONS, TABLE_NAME AS key_col FROM information_schema.TABLES where TABLE_NAME = 'voip_usr_preferences_blob';
  +---------------------------+--------+--------------------+---------------------+---------------------------+
  | TABLE_NAME                | ENGINE | TABLE_COLLATION    | CREATE_OPTIONS      | key_col                   |
  +---------------------------+--------+--------------------+---------------------+---------------------------+
  | voip_usr_preferences_blob | InnoDB | utf8mb3_general_ci | `PAGE_COMPRESSED`=1 | voip_usr_preferences_blob |
  +---------------------------+--------+--------------------+---------------------+---------------------------+
  1 row in set (0.004 sec)

Whereas starting with Debian/forky, we get:

  MariaDB [provisioning]> SELECT TABLE_NAME, ENGINE, TABLE_COLLATION, CREATE_OPTIONS, TABLE_NAME AS key_col FROM information_schema.TABLES where TABLE_NAME = 'voip_usr_preferences_blob';
  +---------------------------+--------+--------------------+-----------------------+---------------------------+
  | TABLE_NAME                | ENGINE | TABLE_COLLATION    | CREATE_OPTIONS        | key_col                   |
  +---------------------------+--------+--------------------+-----------------------+---------------------------+
  | voip_usr_preferences_blob | InnoDB | utf8mb3_general_ci | `PAGE_COMPRESSED`='1' | voip_usr_preferences_blob |
  +---------------------------+--------+--------------------+-----------------------+---------------------------+
  1 row in set (0.001 sec)

Handle this by normalizing the options. We only match backtick-quoted
names followed by ='...'.  MariaDB prints engine-defined options that
way, for example `PAGE_COMPRESSED`='1' or `ENCRYPTED`='yes'.
Built-in options (like COMMENT='none', ROW_FORMAT=DYNAMIC and
KEY_BLOCK_SIZE=8) have no backticks around the name, so they are never
touched.  By using \w+, we only unquote simple tokens such as 1, yes or
ON. A value with spaces or special characters stays quoted, since that
is exactly the case the MariaDB fix was about. This ensures that our
helper/compare_dbs.pl is both compatible with older mariadb as well as
more recent ones as present on Debian/forky.

Change-Id: Ief5dac49e27df420051c84196bcb952a2fabcd53
master
Michael Prokop 4 weeks ago
parent 002a444990
commit ce11f63996

@ -272,6 +272,17 @@ sub is_exception {
return 0;
}
# MariaDB 11.8.9+ reports values in in SHOW CREATE TABLE and
# CREATE_OPTIONS under quotes, see MDEV-39776.
# So e.g. `PAGE_COMPRESSED`=1 became `PAGE_COMPRESSED`='1'.
# Strip the quotes around simple values so old and new output compare equal.
sub normalize_options {
my ($value) = @_;
return $value unless defined $value;
$value =~ s/(`\w+`)='(\w+)'/$1=$2/g;
return $value;
}
sub print_diff {
my ($obj1, $obj2, $object_name, $result, $schema) = @_;
@ -294,7 +305,8 @@ sub print_diff {
$obj1->{$key}->{$c_name} = 'NULL' if ( ! defined($obj1->{$key}->{$c_name}) );
$obj2->{$key}->{$c_name} = 'NULL' if ( ! defined($obj2->{$key}->{$c_name}) );
if ( $obj1->{$key}->{$c_name} ne $obj2->{$key}->{$c_name} ) {
if ( normalize_options($obj1->{$key}->{$c_name})
ne normalize_options($obj2->{$key}->{$c_name}) ) {
next if ( is_exception(\@diff_exceptions, $object_name, $schema, $key, $c_name) );
push( @{$result}, "Element: " . lc("$object_name/$schema/$key/$c_name") . " are not equal:\n ---\n"
. " local db: $obj1->{$key}->{$c_name}\n"

Loading…
Cancel
Save