diff --git a/src/wp-admin/includes/upgrade.php b/src/wp-admin/includes/upgrade.php index dfe38d29e3..5030483769 100644 --- a/src/wp-admin/includes/upgrade.php +++ b/src/wp-admin/includes/upgrade.php @@ -2713,6 +2713,8 @@ function deslash( $content ) { * Useful for creating new tables and updating existing tables to a new structure. * * @since 1.5.0 + * @since 6.1.0 Ignores display width for integer data types on MySQL 8.0.17 or later, + * to match MySQL behavior. Note: This does not affect MariaDB. * * @global wpdb $wpdb WordPress database abstraction object. * @@ -2789,8 +2791,12 @@ function dbDelta( $queries = '', $execute = true ) { // phpcs:ignore WordPress.N $text_fields = array( 'tinytext', 'text', 'mediumtext', 'longtext' ); $blob_fields = array( 'tinyblob', 'blob', 'mediumblob', 'longblob' ); + $int_fields = array( 'tinyint', 'smallint', 'mediumint', 'int', 'integer', 'bigint' ); + + $global_tables = $wpdb->tables( 'global' ); + $db_version = $wpdb->db_version(); + $db_server_info = $wpdb->db_server_info(); - $global_tables = $wpdb->tables( 'global' ); foreach ( $cqueries as $table => $qry ) { // Upgrade global tables only for the main site. Don't upgrade at all if conditions are not optimal. if ( in_array( $table, $global_tables, true ) && ! wp_should_upgrade_global_tables() ) { @@ -2948,6 +2954,19 @@ function dbDelta( $queries = '', $execute = true ) { // phpcs:ignore WordPress.N $tablefield_field_lowercased = strtolower( $tablefield->Field ); $tablefield_type_lowercased = strtolower( $tablefield->Type ); + $tablefield_type_without_parentheses = preg_replace( + '/' + . '(.+)' // Field type, e.g. `int`. + . '\(\d*\)' // Display width. + . '(.*)' // Optional attributes, e.g. `unsigned`. + . '/', + '$1$2', + $tablefield_type_lowercased + ); + + // Get the type without attributes, e.g. `int`. + $tablefield_type_base = strtok( $tablefield_type_without_parentheses, ' ' ); + // If the table field exists in the field array... if ( array_key_exists( $tablefield_field_lowercased, $cfields ) ) { @@ -2956,6 +2975,19 @@ function dbDelta( $queries = '', $execute = true ) { // phpcs:ignore WordPress.N $fieldtype = $matches[1]; $fieldtype_lowercased = strtolower( $fieldtype ); + $fieldtype_without_parentheses = preg_replace( + '/' + . '(.+)' // Field type, e.g. `int`. + . '\(\d*\)' // Display width. + . '(.*)' // Optional attributes, e.g. `unsigned`. + . '/', + '$1$2', + $fieldtype_lowercased + ); + + // Get the type without attributes, e.g. `int`. + $fieldtype_base = strtok( $fieldtype_without_parentheses, ' ' ); + // Is actual field type different from the field type in query? if ( $tablefield->Type != $fieldtype ) { $do_change = true; @@ -2971,6 +3003,21 @@ function dbDelta( $queries = '', $execute = true ) { // phpcs:ignore WordPress.N } } + if ( in_array( $fieldtype_base, $int_fields, true ) && in_array( $tablefield_type_base, $int_fields, true ) + && $fieldtype_without_parentheses === $tablefield_type_without_parentheses + ) { + /* + * MySQL 8.0.17 or later does not support display width for integer data types, + * so if display width is the only difference, it can be safely ignored. + * Note: This is specific to MySQL and does not affect MariaDB. + */ + if ( version_compare( $db_version, '8.0.17', '>=' ) + && ! str_contains( $db_server_info, 'MariaDB' ) + ) { + $do_change = false; + } + } + if ( $do_change ) { // Add a query to change the column type. $cqueries[] = "ALTER TABLE {$table} CHANGE COLUMN `{$tablefield->Field}` " . $cfields[ $tablefield_field_lowercased ]; diff --git a/tests/phpunit/tests/dbdelta.php b/tests/phpunit/tests/dbdelta.php index f717eb436d..c9e20d966b 100644 --- a/tests/phpunit/tests/dbdelta.php +++ b/tests/phpunit/tests/dbdelta.php @@ -22,21 +22,32 @@ class Tests_dbDelta extends WP_UnitTestCase { protected $db_engine = ''; /** - * Display width for BIGINT data type. + * The database server version. * - * Prior to MySQL 8.0.17, default width of 20 digits was used: BIGINT(20). - * Since MySQL 8.0.17, display width for integer data types is no longer supported. + * @var string */ - protected $bigint_display_width = ''; + private static $db_version; + + /** + * Full database server information. + * + * @var string + */ + private static $db_server_info; /** * Make sure the upgrade code is loaded before the tests are run. */ public static function set_up_before_class() { + global $wpdb; + parent::set_up_before_class(); require_once ABSPATH . 'wp-admin/includes/upgrade.php'; + + self::$db_version = $wpdb->db_version(); + self::$db_server_info = $wpdb->db_server_info(); } /** @@ -46,31 +57,24 @@ class Tests_dbDelta extends WP_UnitTestCase { global $wpdb; - $db_version = $wpdb->db_version(); - - if ( version_compare( $db_version, '5.7', '<' ) ) { + if ( version_compare( self::$db_version, '5.7', '<' ) ) { // Prior to MySQL 5.7, InnoDB did not support FULLTEXT indexes, so MyISAM is used instead. $this->db_engine = 'ENGINE=MyISAM'; } - if ( version_compare( $db_version, '8.0.17', '<' ) ) { - // Prior to MySQL 8.0.17, default width of 20 digits was used: BIGINT(20). - $this->bigint_display_width = '(20)'; - } - $wpdb->query( $wpdb->prepare( " CREATE TABLE {$wpdb->prefix}dbdelta_test (" . // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared - "id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT, + 'id bigint(20) NOT NULL AUTO_INCREMENT, column_1 varchar(255) NOT NULL, column_2 text, column_3 blob, PRIMARY KEY (id), KEY key_1 (column_1(%d)), KEY compound_key (id,column_1(%d)), - FULLTEXT KEY fulltext_key (column_1)" . + FULLTEXT KEY fulltext_key (column_1)' . // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared ") {$this->db_engine} ", @@ -109,7 +113,7 @@ class Tests_dbDelta extends WP_UnitTestCase { $updates = dbDelta( "CREATE TABLE {$wpdb->prefix}dbdelta_create_test ( - id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT, + id bigint(20) NOT NULL AUTO_INCREMENT, column_1 varchar(255) NOT NULL, PRIMARY KEY (id) );" @@ -144,7 +148,7 @@ class Tests_dbDelta extends WP_UnitTestCase { $updates = dbDelta( " CREATE TABLE {$wpdb->prefix}dbdelta_test ( - id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT, + id bigint(20) NOT NULL AUTO_INCREMENT, column_1 varchar(255) NOT NULL, PRIMARY KEY (id), KEY key_1 (column_1($this->max_index_length)), @@ -163,7 +167,7 @@ class Tests_dbDelta extends WP_UnitTestCase { global $wpdb; - // id: bigint => int(11) + // id: bigint(20) => int(11) $updates = dbDelta( " CREATE TABLE {$wpdb->prefix}dbdelta_test ( @@ -176,10 +180,23 @@ class Tests_dbDelta extends WP_UnitTestCase { " ); + $bigint_display_width = '(20)'; + + /* + * MySQL 8.0.17 or later does not support display width for integer data types, + * so if display width is the only difference, it can be safely ignored. + * Note: This is specific to MySQL and does not affect MariaDB. + */ + if ( version_compare( self::$db_version, '8.0.17', '>=' ) + && ! str_contains( self::$db_server_info, 'MariaDB' ) + ) { + $bigint_display_width = ''; + } + $this->assertSame( array( "{$wpdb->prefix}dbdelta_test.id" - => "Changed type of {$wpdb->prefix}dbdelta_test.id from bigint{$this->bigint_display_width} to int(11)", + => "Changed type of {$wpdb->prefix}dbdelta_test.id from bigint{$bigint_display_width} to int(11)", ), $updates ); @@ -195,7 +212,7 @@ class Tests_dbDelta extends WP_UnitTestCase { $updates = dbDelta( " CREATE TABLE {$wpdb->prefix}dbdelta_test ( - id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT, + id bigint(20) NOT NULL AUTO_INCREMENT, column_1 varchar(255) NOT NULL, extra_col longtext, PRIMARY KEY (id), @@ -230,7 +247,7 @@ class Tests_dbDelta extends WP_UnitTestCase { $updates = dbDelta( " CREATE TABLE {$wpdb->prefix}dbdelta_test ( - id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT, + id bigint(20) NOT NULL AUTO_INCREMENT, PRIMARY KEY (id), KEY key_1 (column_1($this->max_index_length)), KEY compound_key (id,column_1($this->max_index_length)) @@ -254,7 +271,7 @@ class Tests_dbDelta extends WP_UnitTestCase { $updates = dbDelta( " CREATE TABLE {$wpdb->prefix}dbdelta_test ( - id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT, + id bigint(20) NOT NULL AUTO_INCREMENT, column_1 varchar(255) NOT NULL, extra_col longtext, PRIMARY KEY (id), @@ -306,7 +323,7 @@ class Tests_dbDelta extends WP_UnitTestCase { $updates = dbDelta( " CREATE TABLE {$wpdb->prefix}dbdelta_test ( - id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT, + id bigint(20) NOT NULL AUTO_INCREMENT, column_1 varchar(255) NOT NULL, PRIMARY KEY (id), KEY key_1 (column_1($this->max_index_length)), @@ -451,7 +468,7 @@ class Tests_dbDelta extends WP_UnitTestCase { $result = dbDelta( " CREATE TABLE {$wpdb->prefix}dbdelta_test ( - id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT, + id bigint(20) NOT NULL AUTO_INCREMENT, column_1 varchar(255) NOT NULL, column_2 tinytext, column_3 blob, @@ -476,7 +493,7 @@ class Tests_dbDelta extends WP_UnitTestCase { $result = dbDelta( " CREATE TABLE {$wpdb->prefix}dbdelta_test ( - id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT, + id bigint(20) NOT NULL AUTO_INCREMENT, column_1 varchar(255) NOT NULL, column_2 text, column_3 tinyblob, @@ -501,7 +518,7 @@ class Tests_dbDelta extends WP_UnitTestCase { $result = dbDelta( " CREATE TABLE {$wpdb->prefix}dbdelta_test ( - id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT, + id bigint(20) NOT NULL AUTO_INCREMENT, column_1 varchar(255) NOT NULL, column_2 bigtext, column_3 blob, @@ -532,7 +549,7 @@ class Tests_dbDelta extends WP_UnitTestCase { $result = dbDelta( " CREATE TABLE {$wpdb->prefix}dbdelta_test ( - id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT, + id bigint(20) NOT NULL AUTO_INCREMENT, column_1 varchar(255) NOT NULL, column_2 text, column_3 mediumblob, @@ -562,7 +579,7 @@ class Tests_dbDelta extends WP_UnitTestCase { $schema = " CREATE TABLE {$wpdb->prefix}dbdelta_test2 ( - `id` bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT, + `id` bigint(20) NOT NULL AUTO_INCREMENT, `column_1` varchar(255) NOT NULL, PRIMARY KEY (id), KEY compound_key (id,column_1($this->max_index_length)) @@ -585,24 +602,28 @@ class Tests_dbDelta extends WP_UnitTestCase { public function test_spatial_indices() { global $wpdb; - $db_version = $wpdb->db_version(); - - if ( version_compare( $db_version, '5.4', '<' ) ) { + if ( version_compare( self::$db_version, '5.4', '<' ) ) { $this->markTestSkipped( 'Spatial indices require MySQL 5.4 and above.' ); } - $geomcollection_name = 'geomcollection'; + $geometrycollection_name = 'geometrycollection'; - if ( version_compare( $db_version, '8.0.11', '<' ) ) { - // Prior to MySQL 8.0.11, GeometryCollection data type name was used. - $geomcollection_name = 'geometrycollection'; + if ( version_compare( self::$db_version, '8.0.11', '>=' ) + && ! str_contains( self::$db_server_info, 'MariaDB' ) + ) { + /* + * MySQL 8.0.11 or later uses GeomCollection data type name + * as the preferred synonym for GeometryCollection. + * Note: This is specific to MySQL and does not affect MariaDB. + */ + $geometrycollection_name = 'geomcollection'; } $schema = " CREATE TABLE {$wpdb->prefix}spatial_index_test ( - non_spatial bigint{$this->bigint_display_width} unsigned NOT NULL, - spatial_value {$geomcollection_name} NOT NULL, + non_spatial bigint(20) unsigned NOT NULL, + spatial_value {$geometrycollection_name} NOT NULL, KEY non_spatial (non_spatial), SPATIAL KEY spatial_key (spatial_value) ) {$this->db_engine}; @@ -618,9 +639,9 @@ class Tests_dbDelta extends WP_UnitTestCase { $schema = " CREATE TABLE {$wpdb->prefix}spatial_index_test ( - non_spatial bigint{$this->bigint_display_width} unsigned NOT NULL, - spatial_value {$geomcollection_name} NOT NULL, - spatial_value2 {$geomcollection_name} NOT NULL, + non_spatial bigint(20) unsigned NOT NULL, + spatial_value {$geometrycollection_name} NOT NULL, + spatial_value2 {$geometrycollection_name} NOT NULL, KEY non_spatial (non_spatial), SPATIAL KEY spatial_key (spatial_value) SPATIAL KEY spatial_key2 (spatial_value2) @@ -648,7 +669,7 @@ class Tests_dbDelta extends WP_UnitTestCase { $schema = " CREATE TABLE {$wpdb->prefix}dbdelta_test2 ( - `id` bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT, + `id` bigint(20) NOT NULL AUTO_INCREMENT, `references` varchar(255) NOT NULL, PRIMARY KEY (`id`), KEY `compound_key` (`id`,`references`($this->max_index_length)) @@ -678,7 +699,7 @@ class Tests_dbDelta extends WP_UnitTestCase { $updates = dbDelta( " CREATE TABLE {$wpdb->prefix}dbdelta_test ( - id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT, + id bigint(20) NOT NULL AUTO_INCREMENT, column_1 varchar(255) NOT NULL, column_2 text, column_3 blob, @@ -708,7 +729,7 @@ class Tests_dbDelta extends WP_UnitTestCase { /** * @ticket 20263 */ - public function test_wp_get_db_schema_does_no_alter_queries_on_existing_install() { + public function test_wp_get_db_schema_does_not_alter_queries_on_existing_install() { $updates = dbDelta( wp_get_db_schema() ); $this->assertEmpty( $updates ); @@ -722,7 +743,7 @@ class Tests_dbDelta extends WP_UnitTestCase { $schema = " CREATE TABLE {$wpdb->prefix}dbdelta_test ( - id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT, + id bigint(20) NOT NULL AUTO_INCREMENT, column_1 varchar(255) NOT NULL, column_2 text, column_3 blob, @@ -761,7 +782,7 @@ class Tests_dbDelta extends WP_UnitTestCase { $updates = dbDelta( " CREATE TABLE {$wpdb->prefix}dbdelta_test ( - id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT, + id bigint(20) NOT NULL AUTO_INCREMENT, column_1 varchar(255) NOT NULL, column_2 text, column_3 blob, @@ -784,7 +805,7 @@ class Tests_dbDelta extends WP_UnitTestCase { $schema = " CREATE TABLE {$wpdb->prefix}dbdelta_test ( - id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT, + id bigint(20) NOT NULL AUTO_INCREMENT, column_1 varchar(255) NOT NULL, column_2 text, column_3 blob, @@ -819,7 +840,7 @@ class Tests_dbDelta extends WP_UnitTestCase { $updates = dbDelta( " CREATE TABLE {$wpdb->prefix}dbdelta_test ( - id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT, + id bigint(20) NOT NULL AUTO_INCREMENT, column_1 varchar(255) NOT NULL, column_2 text, column_3 blob, @@ -843,7 +864,7 @@ class Tests_dbDelta extends WP_UnitTestCase { $updates = dbDelta( " CREATE TABLE {$wpdb->prefix}dbdelta_test ( - id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT, + id bigint(20) NOT NULL AUTO_INCREMENT, column_1 varchar(255) NOT NULL, column_2 text, column_3 blob, @@ -867,7 +888,7 @@ class Tests_dbDelta extends WP_UnitTestCase { $updates = dbDelta( " CREATE TABLE {$wpdb->prefix}dbdelta_test ( - id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT, + id bigint(20) NOT NULL AUTO_INCREMENT, column_1 varchar(255) NOT NULL, column_2 text, column_3 blob, @@ -891,7 +912,7 @@ class Tests_dbDelta extends WP_UnitTestCase { $updates = dbDelta( " CREATE TABLE {$wpdb->prefix}dbdelta_test ( - id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT, + id bigint(20) NOT NULL AUTO_INCREMENT, column_1 varchar(255) NOT NULL, column_2 text, column_3 blob, @@ -915,7 +936,7 @@ class Tests_dbDelta extends WP_UnitTestCase { $updates = dbDelta( " CREATE TABLE {$wpdb->prefix}dbdelta_test ( - id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT, + id bigint(20) NOT NULL AUTO_INCREMENT, column_1 varchar(255) NOT NULL, column_2 text, column_3 blob, @@ -940,7 +961,7 @@ class Tests_dbDelta extends WP_UnitTestCase { $updates = dbDelta( " CREATE TABLE {$wpdb->prefix}dbdelta_test ( - id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT, + id bigint(20) NOT NULL AUTO_INCREMENT, column_1 varchar(255) NOT NULL, column_2 text, column_3 blob, @@ -965,7 +986,7 @@ class Tests_dbDelta extends WP_UnitTestCase { $updates = dbDelta( " CREATE TABLE {$wpdb->prefix}dbdelta_test ( - id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT, + id bigint(20) NOT NULL AUTO_INCREMENT, column_1 varchar(255) NOT NULL, column_2 text, column_3 blob, @@ -988,7 +1009,7 @@ class Tests_dbDelta extends WP_UnitTestCase { $updates = dbDelta( " CREATE TABLE {$wpdb->prefix}dbdelta_test ( - id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT, + id bigint(20) NOT NULL AUTO_INCREMENT, column_1 varchar(255) NOT NULL, column_2 text, column_3 blob, @@ -1006,7 +1027,7 @@ class Tests_dbDelta extends WP_UnitTestCase { $updates = dbDelta( " CREATE TABLE {$wpdb->prefix}dbdelta_test ( - id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT, + id bigint(20) NOT NULL AUTO_INCREMENT, column_1 varchar(255) NOT NULL, column_2 text, column_3 blob, @@ -1024,7 +1045,7 @@ class Tests_dbDelta extends WP_UnitTestCase { $updates = dbDelta( " CREATE TABLE {$wpdb->prefix}dbdelta_test ( - id bigint{$this->bigint_display_width} NOT NULL AUTO_INCREMENT, + id bigint(20) NOT NULL AUTO_INCREMENT, column_1 varchar(255) NOT NULL, column_2 text, column_3 blob,