Make WordPress Core


Ignore:
Timestamp:
08/15/2022 01:16:22 PM (4 years ago)
Author:
SergeyBiryukov
Message:

Database: Ignore display width for integer data types in dbDelta() on MySQL 8.0.17 or later.

MySQL 8.0.17 deprecated the display width attribute for integer data types:

As of MySQL 8.0.17, the ZEROFILL attribute is deprecated for numeric data types, as is the display width attribute for integer data types. You should expect support for ZEROFILL and display widths for integer data types to be removed in a future version of MySQL. Consider using an alternative means of producing the effect of these attributes. For example, applications can use the LPAD() function to zero-pad numbers up to the desired width, or they can store the formatted numbers in CHAR columns.

In practice, this means that display width is removed for integer types when creating a table:

  • BIGINT(20)BIGINT
  • INT(11)INT
  • MEDIUMINT(9)MEDIUMINT
  • SMALLINT(6)SMALLINT
  • TINYINT(4)TINYINT

Note: This only applies specifically to MySQL 8.0.17 or later. In MariaDB, display width for integer types is still available and expected.

This commit ensures that dbDelta(), which relies on the DESCRIBE SQL command to get the existing table structure and field types, when running on MySQL 8.0.17 or later, does not unnecessarily attempt to convert BIGINT fields back to BIGINT(20), INT back to INT(11), etc. When comparing the field type in the query with the existing field type, if display width is the only difference, it can be safely ignored to match MySQL behavior.

The change is covered by existing dbDelta() unit tests:

  • A test for not altering wp_get_db_schema() queries on an existing install using MySQL 8.0.17+ now passes.
  • More than twenty tests which previously failed on PHP 8.0.x + MariaDB due to incorrect expectations, caused by MariaDB version reporting not being consistent between PHP versions, now pass.

References:

Follow-up to [1575], [18899], [37525], [47183], [47184].

Props SergeyBiryukov, pbearne, leewillis77, JavierCasares, desrosj, costdev, johnbillion.
Fixes #49364. See #51740.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tests/phpunit/tests/dbdelta.php

    r52010 r53897  
    2323
    2424        /**
    25          * Display width for BIGINT data type.
     25         * The database server version.
    2626         *
    27          * Prior to MySQL 8.0.17, default width of 20 digits was used: BIGINT(20).
    28          * Since MySQL 8.0.17, display width for integer data types is no longer supported.
    29          */
    30         protected $bigint_display_width = '';
     27         * @var string
     28         */
     29        private static $db_version;
     30
     31        /**
     32         * Full database server information.
     33         *
     34         * @var string
     35         */
     36        private static $db_server_info;
    3137
    3238        /**
     
    3541        public static function set_up_before_class() {
    3642
     43                global $wpdb;
     44
    3745                parent::set_up_before_class();
    3846
    3947                require_once ABSPATH . 'wp-admin/includes/upgrade.php';
     48
     49                self::$db_version     = $wpdb->db_version();
     50                self::$db_server_info = $wpdb->db_server_info();
    4051        }
    4152
     
    4758                global $wpdb;
    4859
    49                 $db_version = $wpdb->db_version();
    50 
    51                 if ( version_compare( $db_version, '5.7', '<' ) ) {
     60                if ( version_compare( self::$db_version, '5.7', '<' ) ) {
    5261                        // Prior to MySQL 5.7, InnoDB did not support FULLTEXT indexes, so MyISAM is used instead.
    5362                        $this->db_engine = 'ENGINE=MyISAM';
    54                 }
    55 
    56                 if ( version_compare( $db_version, '8.0.17', '<' ) ) {
    57                         // Prior to MySQL 8.0.17, default width of 20 digits was used: BIGINT(20).
    58                         $this->bigint_display_width = '(20)';
    5963                }
    6064
     
    6468                                CREATE TABLE {$wpdb->prefix}dbdelta_test (" .
    6569                                        // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
    66                                         "id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT,
     70                                        'id bigint(20) NOT NULL AUTO_INCREMENT,
    6771                                        column_1 varchar(255) NOT NULL,
    6872                                        column_2 text,
     
    7175                                        KEY key_1 (column_1(%d)),
    7276                                        KEY compound_key (id,column_1(%d)),
    73                                         FULLTEXT KEY fulltext_key (column_1)" .
     77                                        FULLTEXT KEY fulltext_key (column_1)' .
    7478                                        // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
    7579                                ") {$this->db_engine}
     
    110114                $updates = dbDelta(
    111115                        "CREATE TABLE {$wpdb->prefix}dbdelta_create_test (
    112                                 id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT,
     116                                id bigint(20) NOT NULL AUTO_INCREMENT,
    113117                                column_1 varchar(255) NOT NULL,
    114118                                PRIMARY KEY  (id)
     
    145149                        "
    146150                        CREATE TABLE {$wpdb->prefix}dbdelta_test (
    147                                 id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT,
     151                                id bigint(20) NOT NULL AUTO_INCREMENT,
    148152                                column_1 varchar(255) NOT NULL,
    149153                                PRIMARY KEY  (id),
     
    164168                global $wpdb;
    165169
    166                 // id: bigint => int(11)
     170                // id: bigint(20) => int(11)
    167171                $updates = dbDelta(
    168172                        "
     
    176180                        "
    177181                );
     182
     183                $bigint_display_width = '(20)';
     184
     185                /*
     186                 * MySQL 8.0.17 or later does not support display width for integer data types,
     187                 * so if display width is the only difference, it can be safely ignored.
     188                 * Note: This is specific to MySQL and does not affect MariaDB.
     189                 */
     190                if ( version_compare( self::$db_version, '8.0.17', '>=' )
     191                        && ! str_contains( self::$db_server_info, 'MariaDB' )
     192                ) {
     193                        $bigint_display_width = '';
     194                }
    178195
    179196                $this->assertSame(
    180197                        array(
    181198                                "{$wpdb->prefix}dbdelta_test.id"
    182                                         => "Changed type of {$wpdb->prefix}dbdelta_test.id from bigint{$this->bigint_display_width} to int(11)",
     199                                        => "Changed type of {$wpdb->prefix}dbdelta_test.id from bigint{$bigint_display_width} to int(11)",
    183200                        ),
    184201                        $updates
     
    196213                        "
    197214                        CREATE TABLE {$wpdb->prefix}dbdelta_test (
    198                                 id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT,
     215                                id bigint(20) NOT NULL AUTO_INCREMENT,
    199216                                column_1 varchar(255) NOT NULL,
    200217                                extra_col longtext,
     
    231248                        "
    232249                        CREATE TABLE {$wpdb->prefix}dbdelta_test (
    233                                 id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT,
     250                                id bigint(20) NOT NULL AUTO_INCREMENT,
    234251                                PRIMARY KEY  (id),
    235252                                KEY key_1 (column_1($this->max_index_length)),
     
    255272                        "
    256273                        CREATE TABLE {$wpdb->prefix}dbdelta_test (
    257                                 id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT,
     274                                id bigint(20) NOT NULL AUTO_INCREMENT,
    258275                                column_1 varchar(255) NOT NULL,
    259276                                extra_col longtext,
     
    307324                        "
    308325                        CREATE TABLE {$wpdb->prefix}dbdelta_test (
    309                                 id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT,
     326                                id bigint(20) NOT NULL AUTO_INCREMENT,
    310327                                column_1 varchar(255) NOT NULL,
    311328                                PRIMARY KEY  (id),
     
    452469                        "
    453470                        CREATE TABLE {$wpdb->prefix}dbdelta_test (
    454                                 id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT,
     471                                id bigint(20) NOT NULL AUTO_INCREMENT,
    455472                                column_1 varchar(255) NOT NULL,
    456473                                column_2 tinytext,
     
    477494                        "
    478495                        CREATE TABLE {$wpdb->prefix}dbdelta_test (
    479                                 id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT,
     496                                id bigint(20) NOT NULL AUTO_INCREMENT,
    480497                                column_1 varchar(255) NOT NULL,
    481498                                column_2 text,
     
    502519                        "
    503520                        CREATE TABLE {$wpdb->prefix}dbdelta_test (
    504                                 id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT,
     521                                id bigint(20) NOT NULL AUTO_INCREMENT,
    505522                                column_1 varchar(255) NOT NULL,
    506523                                column_2 bigtext,
     
    533550                        "
    534551                        CREATE TABLE {$wpdb->prefix}dbdelta_test (
    535                                 id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT,
     552                                id bigint(20) NOT NULL AUTO_INCREMENT,
    536553                                column_1 varchar(255) NOT NULL,
    537554                                column_2 text,
     
    563580                $schema = "
    564581                        CREATE TABLE {$wpdb->prefix}dbdelta_test2 (
    565                                 `id` bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT,
     582                                `id` bigint(20) NOT NULL AUTO_INCREMENT,
    566583                                `column_1` varchar(255) NOT NULL,
    567584                                PRIMARY KEY  (id),
     
    586603                global $wpdb;
    587604
    588                 $db_version = $wpdb->db_version();
    589 
    590                 if ( version_compare( $db_version, '5.4', '<' ) ) {
     605                if ( version_compare( self::$db_version, '5.4', '<' ) ) {
    591606                        $this->markTestSkipped( 'Spatial indices require MySQL 5.4 and above.' );
    592607                }
    593608
    594                 $geomcollection_name = 'geomcollection';
    595 
    596                 if ( version_compare( $db_version, '8.0.11', '<' ) ) {
    597                         // Prior to MySQL 8.0.11, GeometryCollection data type name was used.
    598                         $geomcollection_name = 'geometrycollection';
     609                $geometrycollection_name = 'geometrycollection';
     610
     611                if ( version_compare( self::$db_version, '8.0.11', '>=' )
     612                        && ! str_contains( self::$db_server_info, 'MariaDB' )
     613                ) {
     614                        /*
     615                         * MySQL 8.0.11 or later uses GeomCollection data type name
     616                         * as the preferred synonym for GeometryCollection.
     617                         * Note: This is specific to MySQL and does not affect MariaDB.
     618                         */
     619                        $geometrycollection_name = 'geomcollection';
    599620                }
    600621
     
    602623                        "
    603624                        CREATE TABLE {$wpdb->prefix}spatial_index_test (
    604                                 non_spatial bigint{$this->bigint_display_width} unsigned NOT NULL,
    605                                 spatial_value {$geomcollection_name} NOT NULL,
     625                                non_spatial bigint(20) unsigned NOT NULL,
     626                                spatial_value {$geometrycollection_name} NOT NULL,
    606627                                KEY non_spatial (non_spatial),
    607628                                SPATIAL KEY spatial_key (spatial_value)
     
    619640                        "
    620641                        CREATE TABLE {$wpdb->prefix}spatial_index_test (
    621                                 non_spatial bigint{$this->bigint_display_width} unsigned NOT NULL,
    622                                 spatial_value {$geomcollection_name} NOT NULL,
    623                                 spatial_value2 {$geomcollection_name} NOT NULL,
     642                                non_spatial bigint(20) unsigned NOT NULL,
     643                                spatial_value {$geometrycollection_name} NOT NULL,
     644                                spatial_value2 {$geometrycollection_name} NOT NULL,
    624645                                KEY non_spatial (non_spatial),
    625646                                SPATIAL KEY spatial_key (spatial_value)
     
    649670                $schema = "
    650671                        CREATE TABLE {$wpdb->prefix}dbdelta_test2 (
    651                                 `id` bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT,
     672                                `id` bigint(20) NOT NULL AUTO_INCREMENT,
    652673                                `references` varchar(255) NOT NULL,
    653674                                PRIMARY KEY  (`id`),
     
    679700                        "
    680701                        CREATE TABLE {$wpdb->prefix}dbdelta_test (
    681                                 id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT,
     702                                id bigint(20) NOT NULL AUTO_INCREMENT,
    682703                                column_1 varchar(255) NOT NULL,
    683704                                column_2 text,
     
    709730         * @ticket 20263
    710731         */
    711         public function test_wp_get_db_schema_does_no_alter_queries_on_existing_install() {
     732        public function test_wp_get_db_schema_does_not_alter_queries_on_existing_install() {
    712733                $updates = dbDelta( wp_get_db_schema() );
    713734
     
    723744                $schema = "
    724745                        CREATE TABLE {$wpdb->prefix}dbdelta_test (
    725                                 id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT,
     746                                id bigint(20) NOT NULL AUTO_INCREMENT,
    726747                                column_1 varchar(255) NOT NULL,
    727748                                column_2 text,
     
    762783                        "
    763784                        CREATE TABLE {$wpdb->prefix}dbdelta_test (
    764                                 id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT,
     785                                id bigint(20) NOT NULL AUTO_INCREMENT,
    765786                                column_1 varchar(255) NOT NULL,
    766787                                column_2 text,
     
    785806                $schema = "
    786807                        CREATE TABLE {$wpdb->prefix}dbdelta_test (
    787                                 id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT,
     808                                id bigint(20) NOT NULL AUTO_INCREMENT,
    788809                                column_1 varchar(255) NOT NULL,
    789810                                column_2 text,
     
    820841                        "
    821842                        CREATE TABLE {$wpdb->prefix}dbdelta_test (
    822                                 id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT,
     843                                id bigint(20) NOT NULL AUTO_INCREMENT,
    823844                                column_1 varchar(255) NOT NULL,
    824845                                column_2 text,
     
    844865                        "
    845866                        CREATE TABLE {$wpdb->prefix}dbdelta_test (
    846                                 id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT,
     867                                id bigint(20) NOT NULL AUTO_INCREMENT,
    847868                                column_1 varchar(255) NOT NULL,
    848869                                column_2 text,
     
    868889                        "
    869890                        CREATE TABLE {$wpdb->prefix}dbdelta_test (
    870                                 id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT,
     891                                id bigint(20) NOT NULL AUTO_INCREMENT,
    871892                                column_1 varchar(255) NOT NULL,
    872893                                column_2 text,
     
    892913                        "
    893914                        CREATE TABLE {$wpdb->prefix}dbdelta_test (
    894                                 id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT,
     915                                id bigint(20) NOT NULL AUTO_INCREMENT,
    895916                                column_1 varchar(255) NOT NULL,
    896917                                column_2 text,
     
    916937                        "
    917938                        CREATE TABLE {$wpdb->prefix}dbdelta_test (
    918                                 id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT,
     939                                id bigint(20) NOT NULL AUTO_INCREMENT,
    919940                                column_1 varchar(255) NOT NULL,
    920941                                column_2 text,
     
    941962                        "
    942963                        CREATE TABLE {$wpdb->prefix}dbdelta_test (
    943                                 id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT,
     964                                id bigint(20) NOT NULL AUTO_INCREMENT,
    944965                                column_1 varchar(255) NOT NULL,
    945966                                column_2 text,
     
    966987                        "
    967988                        CREATE TABLE {$wpdb->prefix}dbdelta_test (
    968                                 id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT,
     989                                id bigint(20) NOT NULL AUTO_INCREMENT,
    969990                                column_1 varchar(255) NOT NULL,
    970991                                column_2 text,
     
    9891010                        "
    9901011                        CREATE TABLE {$wpdb->prefix}dbdelta_test (
    991                                 id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT,
     1012                                id bigint(20) NOT NULL AUTO_INCREMENT,
    9921013                                column_1 varchar(255) NOT NULL,
    9931014                                column_2 text,
     
    10071028                        "
    10081029                        CREATE TABLE {$wpdb->prefix}dbdelta_test (
    1009                                 id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT,
     1030                                id bigint(20) NOT NULL AUTO_INCREMENT,
    10101031                                column_1 varchar(255) NOT NULL,
    10111032                                column_2 text,
     
    10251046                        "
    10261047                        CREATE TABLE {$wpdb->prefix}dbdelta_test (
    1027                                 id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT,
     1048                                id bigint(20) NOT NULL AUTO_INCREMENT,
    10281049                                column_1 varchar(255) NOT NULL,
    10291050                                column_2 text,
Note: See TracChangeset for help on using the changeset viewer.