Skip to content

Commit

Permalink
Database: Correct MariaDB version check in wpdb::has_cap().
Browse files Browse the repository at this point in the history
MariaDB version is reported differently between PHP versions:
* PHP 8.0.16 or later: `10.6.8-MariaDB`
* PHP 8.0.15 or earlier: `5.5.5-10.6.8-MariaDB`

The latter includes PHP 7.4.x and PHP 5.6.x as well, where the version is also reported with the `5.5.5-` prefix.

This commit makes an adjustment to `wpdb::has_cap()` to check for the correct MariaDB version.

This resolves an issue where the `utf8mb4_unicode_520_ci` collation, which is available in MariaDB since version 10.2, was previously not detected correctly.

References:
* [php/php-src#7972 php-src: #7972: MariaDB version prefix 5.5.5- is not stripped]
* [php/php-src#7963 php-src: PR #7963 Fix GH-7932: MariaDB version prefix not always stripped]
* [https://mariadb.com/docs/reference/mdb/collations/utf8mb4_unicode_520_ci/ MariaDB Documentation: utf8mb4_unicode_520_ci]

Follow-up to [37523], [53919].

Props jamieburchell, SergeyBiryukov.
Fixes #54841.

git-svn-id: https://develop.svn.wordpress.org/trunk@54384 602fd350-edb4-49c9-b593-d223f7449a82
  • Loading branch information
SergeyBiryukov committed Oct 4, 2022
1 parent 306d934 commit fed98bd
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 6 deletions.
20 changes: 15 additions & 5 deletions src/wp-includes/class-wpdb.php
Original file line number Diff line number Diff line change
Expand Up @@ -3960,17 +3960,27 @@ public function get_charset_collate() {
* @return bool True when the database feature is supported, false otherwise.
*/
public function has_cap( $db_cap ) {
$version = $this->db_version();
$db_version = $this->db_version();
$db_server_info = $this->db_server_info();

// Account for MariaDB version being prefixed with '5.5.5-' on older PHP versions.
if ( '5.5.5' === $db_version && str_contains( $db_server_info, 'MariaDB' )
&& PHP_VERSION_ID < 80016 // PHP 8.0.15 or older.
) {
// Strip the '5.5.5-' prefix and set the version to the correct value.
$db_server_info = preg_replace( '/^5\.5\.5-(.*)/', '$1', $db_server_info );
$db_version = preg_replace( '/[^0-9.].*/', '', $db_server_info );
}

switch ( strtolower( $db_cap ) ) {
case 'collation': // @since 2.5.0
case 'group_concat': // @since 2.7.0
case 'subqueries': // @since 2.7.0
return version_compare( $version, '4.1', '>=' );
return version_compare( $db_version, '4.1', '>=' );
case 'set_charset':
return version_compare( $version, '5.0.7', '>=' );
return version_compare( $db_version, '5.0.7', '>=' );
case 'utf8mb4': // @since 4.1.0
if ( version_compare( $version, '5.5.3', '<' ) ) {
if ( version_compare( $db_version, '5.5.3', '<' ) ) {
return false;
}
if ( $this->use_mysqli ) {
Expand All @@ -3990,7 +4000,7 @@ public function has_cap( $db_cap ) {
return version_compare( $client_version, '5.5.3', '>=' );
}
case 'utf8mb4_520': // @since 4.6.0
return version_compare( $version, '5.6', '>=' );
return version_compare( $db_version, '5.6', '>=' );
case 'identifier_placeholders': // @since 6.1.0
/*
* As of WordPress 6.1, wpdb::prepare() supports identifiers via '%i',
Expand Down
18 changes: 17 additions & 1 deletion tests/phpunit/tests/db/charset.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public static function set_up_before_class() {
self::$db_server_info = self::$_wpdb->db_server_info();

// Account for MariaDB version being prefixed with '5.5.5-' on older PHP versions.
if ( str_contains( self::$db_server_info, 'MariaDB' ) && '5.5.5' === self::$db_version
if ( '5.5.5' === self::$db_version && str_contains( self::$db_server_info, 'MariaDB' )
&& PHP_VERSION_ID < 80016 // PHP 8.0.15 or older.
) {
// Strip the '5.5.5-' prefix and set the version to the correct value.
Expand Down Expand Up @@ -1189,4 +1189,20 @@ public function test_set_charset_changes_the_connection_collation() {

self::$_wpdb->set_charset( self::$_wpdb->dbh );
}

/**
* @ticket 54841
*/
public function test_mariadb_supports_utf8mb4_520() {
global $wpdb;

// utf8mb4_520 is available in MariaDB since version 10.2.
if ( ! str_contains( self::$db_server_info, 'MariaDB' )
|| version_compare( self::$db_version, '10.2', '<' )
) {
$this->markTestSkipped( 'This test requires MariaDB 10.2 or later.' );
}

$this->assertTrue( $wpdb->has_cap( 'utf8mb4_520' ) );
}
}

0 comments on commit fed98bd

Please sign in to comment.