Commit 30c98a3876 for wordpress.org

commit 30c98a3876b5d2114395dc9c607b7e1a10431358
Author: SergeyBiryukov <sergeybiryukov@git.wordpress.org>
Date:   Sun Oct 18 21:08:56 2026 +0000

    Database: Ignore default integer display widths in `dbDelta()` on MariaDB.

    `dbDelta()` compares the column type in a `CREATE TABLE` query with the type `DESCRIBE` reports. MariaDB, and MySQL before 8.0.17, add a default display width to an integer column declared without one, so a column declared as `bigint unsigned` reports `bigint(20) unsigned`, and `dbDelta()` sends the same `ALTER TABLE` on every call. Likewise, `INTEGER` never matches the `int` the server reports.

    This commit skips the change when the query has no width and the server reports exactly the default width for that type, and treats `INTEGER` as `int`; any other difference is still compared, and MySQL 8.0.17+ keeps its existing code path, similar to the 6.1 change in #49364.

    Developed in https://github.com/WordPress/wordpress-develop/pull/14353.

    Follow-up to r53897, r60789.

    Props jmdodd, janjakes, SergeyBiryukov.
    Fixes #46145.
    Built from https://develop.svn.wordpress.org/trunk@64487


    git-svn-id: http://core.svn.wordpress.org/trunk@63637 1a063a9b-81f0-0310-95a4-ce76da25c4cd

diff --git a/wp-admin/includes/upgrade.php b/wp-admin/includes/upgrade.php
index 0131f899e3..5c5ebcd312 100644
--- a/wp-admin/includes/upgrade.php
+++ b/wp-admin/includes/upgrade.php
@@ -3030,6 +3030,33 @@ function dbDelta( $queries = '', $execute = true ) { // phpcs:ignore WordPress.N
 	$blob_fields = array( 'tinyblob', 'blob', 'mediumblob', 'longblob' );
 	$int_fields  = array( 'tinyint', 'smallint', 'mediumint', 'int', 'integer', 'bigint' );

+	/*
+	 * Display widths that a server applies by itself when an integer definition omits one.
+	 * MariaDB does this in every version, as did MySQL before 8.0.17.
+	 */
+	$int_display_widths = array(
+		'tinyint'   => array(
+			'signed'   => 4,
+			'unsigned' => 3,
+		),
+		'smallint'  => array(
+			'signed'   => 6,
+			'unsigned' => 5,
+		),
+		'mediumint' => array(
+			'signed'   => 9,
+			'unsigned' => 8,
+		),
+		'int'       => array(
+			'signed'   => 11,
+			'unsigned' => 10,
+		),
+		'bigint'    => array(
+			'signed'   => 20,
+			'unsigned' => 20,
+		),
+	);
+
 	$global_tables  = $wpdb->tables( 'global' );
 	$db_version     = $wpdb->db_version();
 	$db_server_info = $wpdb->db_server_info();
@@ -3208,6 +3235,12 @@ function dbDelta( $queries = '', $execute = true ) { // phpcs:ignore WordPress.N
 				$fieldtype            = $matches[1];
 				$fieldtype_lowercased = strtolower( $fieldtype );

+				/*
+				 * `INTEGER` is an alias for `INT`, and the server reports the column as `int`,
+				 * so the alias never compares equal to the type it created.
+				 */
+				$fieldtype_lowercased = preg_replace( '/^integer\b/', 'int', $fieldtype_lowercased );
+
 				$fieldtype_without_parentheses = preg_replace(
 					'/'
 					. '(.+)'       // Field type, e.g. `int`.
@@ -3239,15 +3272,31 @@ 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' )
 						) {
+							/*
+							 * 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.
+							 */
 							$do_change = false;
+						} elseif ( ! str_contains( $fieldtype_lowercased, '(' )
+							&& isset( $int_display_widths[ $fieldtype_base ] )
+						) {
+							/*
+							 * Every other server stores a default display width when the definition
+							 * omits one, so `DESCRIBE` reports a width the query never asked for.
+							 * The `ALTER TABLE` below cannot remove that width, which would leave the
+							 * same difference in place and repeat the query on every call.
+							 */
+							$signedness    = str_contains( $fieldtype_lowercased, 'unsigned' ) ? 'unsigned' : 'signed';
+							$default_width = $int_display_widths[ $fieldtype_base ][ $signedness ];
+							$padded_type   = $fieldtype_base . '(' . $default_width . ')' . substr( $fieldtype_lowercased, strlen( $fieldtype_base ) );
+
+							if ( $tablefield_type_lowercased === $padded_type ) {
+								$do_change = false;
+							}
 						}
 					}

diff --git a/wp-includes/version.php b/wp-includes/version.php
index 33510ca9d3..62c9236a53 100644
--- a/wp-includes/version.php
+++ b/wp-includes/version.php
@@ -16,7 +16,7 @@
  *
  * @global string $wp_version
  */
-$wp_version = '7.2-alpha-64486';
+$wp_version = '7.2-alpha-64487';

 /**
  * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.