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.