diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index d1f7c8c052..99e36ec4dc 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -13143,7 +13143,7 @@ parameters: Use dependency injection instead\.$# ''' identifier: staticMethod.deprecated - count: 4 + count: 3 path: src/Util.php - diff --git a/psalm-baseline.xml b/psalm-baseline.xml index d295fc1991..a7274ac31b 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -8529,7 +8529,6 @@ - diff --git a/src/Controllers/HomeController.php b/src/Controllers/HomeController.php index f3284bbe51..f133597909 100644 --- a/src/Controllers/HomeController.php +++ b/src/Controllers/HomeController.php @@ -162,7 +162,7 @@ final class HomeController implements InvocableController $databaseServer = [ 'host' => $hostInfo, 'hostname' => $this->dbi->fetchValue('SELECT @@hostname;'), - 'type' => Util::getServerType(), + 'type' => Util::getServerType($this->dbi), 'connection' => Generator::getServerSSL(), 'version' => $this->dbi->getVersionString() . ' - ' . $this->dbi->getVersionComment(), 'user' => $this->dbi->fetchValue('SELECT USER();'), diff --git a/src/Normalization.php b/src/Normalization.php index 66617f77ca..5dd7fab759 100644 --- a/src/Normalization.php +++ b/src/Normalization.php @@ -170,9 +170,13 @@ class Normalization 'relation_parameters' => $relationParameters, 'content_cells' => $contentCells, 'change_column' => $_POST['change_column'] ?? $_GET['change_column'] ?? null, - 'is_virtual_columns_supported' => Compatibility::isVirtualColumnsSupported($this->dbi->getVersion()), + 'is_virtual_columns_supported' => Compatibility::isVirtualColumnsSupported( + $this->dbi, + $this->dbi->getVersion(), + ), 'browse_mime' => $this->config->config->BrowseMIME, 'supports_stored_keyword' => Compatibility::supportsStoredKeywordForVirtualColumns( + $this->dbi, $this->dbi->getVersion(), ), 'server_version' => $this->dbi->getVersion(), diff --git a/src/Query/Compatibility.php b/src/Query/Compatibility.php index 669467e3f4..0b7d1463e7 100644 --- a/src/Query/Compatibility.php +++ b/src/Query/Compatibility.php @@ -72,28 +72,26 @@ class Compatibility return $eachTables; } - public static function isMySqlOrPerconaDb(): bool + public static function isMySqlOrPerconaDb(DatabaseInterface $dbi): bool { - $serverType = Util::getServerType(); + $serverType = Util::getServerType($dbi); return $serverType === 'MySQL' || $serverType === 'Percona Server'; } - public static function isMariaDb(): bool + public static function isMariaDb(DatabaseInterface $dbi): bool { - $serverType = Util::getServerType(); - - return $serverType === 'MariaDB'; + return Util::getServerType($dbi) === 'MariaDB'; } - public static function isCompatibleRenameIndex(int $serverVersion): bool + public static function isCompatibleRenameIndex(DatabaseInterface $dbi, int $serverVersion): bool { - if (self::isMySqlOrPerconaDb()) { + if (self::isMySqlOrPerconaDb($dbi)) { return $serverVersion >= 50700; } // @see https://mariadb.com/kb/en/alter-table/#rename-indexkey - if (self::isMariaDb()) { + if (self::isMariaDb($dbi)) { return $serverVersion >= 100502; } @@ -104,7 +102,7 @@ class Compatibility { // MySQL made restrictions on the integer types' length from versions >= 8.0.18 // See: https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-19.html - $serverType = Util::getServerType(); + $serverType = Util::getServerType($dbi); $serverVersion = $dbi->getVersion(); return $serverType === 'MySQL' && $serverVersion >= 80018; @@ -140,15 +138,15 @@ class Compatibility /** * Returns whether the database server supports virtual columns */ - public static function isVirtualColumnsSupported(int $serverVersion): bool + public static function isVirtualColumnsSupported(DatabaseInterface $dbi, int $serverVersion): bool { // @see: https://dev.mysql.com/doc/relnotes/mysql/5.7/en/news-5-7-6.html - if (self::isMySqlOrPerconaDb()) { + if (self::isMySqlOrPerconaDb($dbi)) { return $serverVersion >= 50706; } // @see https://mariadb.com/kb/en/changes-improvements-in-mariadb-52/#new-features - if (self::isMariaDb()) { + if (self::isMariaDb($dbi)) { return $serverVersion >= 50200; } @@ -195,15 +193,15 @@ class Compatibility /** * Returns whether the database server supports virtual columns */ - public static function supportsStoredKeywordForVirtualColumns(int $serverVersion): bool + public static function supportsStoredKeywordForVirtualColumns(DatabaseInterface $dbi, int $serverVersion): bool { // @see: https://dev.mysql.com/doc/relnotes/mysql/5.7/en/news-5-7-6.html - if (self::isMySqlOrPerconaDb()) { + if (self::isMySqlOrPerconaDb($dbi)) { return $serverVersion >= 50706; } // @see https://mariadb.com/kb/en/generated-columns/#mysql-compatibility-support - if (self::isMariaDb()) { + if (self::isMariaDb($dbi)) { return $serverVersion >= 100201; } @@ -213,11 +211,11 @@ class Compatibility /** * Returns whether the database server supports compressed columns */ - public static function supportsCompressedColumns(int $serverVersion): bool + public static function supportsCompressedColumns(DatabaseInterface $dbi, int $serverVersion): bool { // @see https://mariadb.com/kb/en/innodb-page-compression/#comment_1992 // Comment: Page compression is only available in MariaDB >= 10.1. [...] - if (self::isMariaDb()) { + if (self::isMariaDb($dbi)) { return $serverVersion >= 100100; } diff --git a/src/Server/Privileges.php b/src/Server/Privileges.php index 2a8c67aff1..4f31b17799 100644 --- a/src/Server/Privileges.php +++ b/src/Server/Privileges.php @@ -628,8 +628,8 @@ class Privileges $authPlugin = $this->getDefaultAuthenticationPlugin(); } - $isNew = (Compatibility::isMySqlOrPerconaDb() && $serverVersion >= 50507) - || (Compatibility::isMariaDb() && $serverVersion >= 50200); + $isNew = (Compatibility::isMySqlOrPerconaDb($this->dbi) && $serverVersion >= 50507) + || (Compatibility::isMariaDb($this->dbi) && $serverVersion >= 50200); $activeAuthPlugins = ['mysql_native_password' => __('Native MySQL authentication')]; if ($isNew) { @@ -777,7 +777,7 @@ class Privileges ); // Use 'ALTER USER ...' syntax for MySQL 5.7.6+ - if (Compatibility::isMySqlOrPerconaDb() && $serverVersion >= 50706) { + if (Compatibility::isMySqlOrPerconaDb($this->dbi) && $serverVersion >= 50706) { if ($authenticationPlugin !== 'mysql_old_password') { $queryPrefix = 'ALTER USER ' . $this->dbi->quoteString($username) @@ -796,7 +796,7 @@ class Privileges $sqlQuery = $queryPrefix . "'*'"; $localQuery = $queryPrefix . $this->dbi->quoteString($_POST['pma_pw']); - } elseif (Compatibility::isMariaDb() && $serverVersion >= 10000) { + } elseif (Compatibility::isMariaDb($this->dbi) && $serverVersion >= 10000) { // MariaDB uses "SET PASSWORD" syntax to change user password. // On Galera cluster only DDL queries are replicated, since // users are stored in MyISAM storage engine. @@ -804,7 +804,7 @@ class Privileges . $this->dbi->quoteString($username) . '@' . $this->dbi->quoteString($hostname) . ' = PASSWORD (' . $this->dbi->quoteString($_POST['pma_pw']) . ')'; - } elseif (Compatibility::isMariaDb() && $serverVersion >= 50200 && $this->dbi->isSuperUser()) { + } elseif (Compatibility::isMariaDb($this->dbi) && $serverVersion >= 50200 && $this->dbi->isSuperUser()) { // Use 'UPDATE `mysql`.`user` ...' Syntax for MariaDB 5.2+ if ($authenticationPlugin === 'mysql_native_password') { // Set the hashing method used by PASSWORD() @@ -999,7 +999,7 @@ class Privileges $sqlQuery = ''; if ( isset($_POST['Grant_priv']) && $_POST['Grant_priv'] === 'Y' - && ! (Compatibility::isMySqlOrPerconaDb() && $this->dbi->getVersion() >= 80011) + && ! (Compatibility::isMySqlOrPerconaDb($this->dbi) && $this->dbi->getVersion() >= 80011) ) { $sqlQuery .= ' GRANT OPTION'; } @@ -2007,7 +2007,7 @@ class Privileges . ' TO ' . $this->dbi->quoteString($username) . '@' . $this->dbi->quoteString($hostname); - $isMySqlOrPercona = Compatibility::isMySqlOrPerconaDb(); + $isMySqlOrPercona = Compatibility::isMySqlOrPerconaDb($this->dbi); $needsToUseAlter = $isMySqlOrPercona && $this->dbi->getVersion() >= 80011; if ($needsToUseAlter) { @@ -2076,7 +2076,7 @@ class Privileges } if ( - Compatibility::isMySqlOrPerconaDb() + Compatibility::isMySqlOrPerconaDb($this->dbi) && $serverVersion >= 50606 && $serverVersion < 50706 && ((isset($row['authentication_string']) @@ -2088,7 +2088,7 @@ class Privileges } if ( - Compatibility::isMariaDb() + Compatibility::isMariaDb($this->dbi) && $serverVersion >= 50500 && isset($row['authentication_string']) && empty($row['password']) @@ -2100,7 +2100,7 @@ class Privileges // for MySQL 5.7.6+ since it does not have // the 'password' column at all if ( - Compatibility::isMySqlOrPerconaDb() + Compatibility::isMySqlOrPerconaDb($this->dbi) && $serverVersion >= 50706 && isset($row['authentication_string']) ) { @@ -2447,7 +2447,7 @@ class Privileges public function getHtmlForUserOverview(UserPrivileges $userPrivileges, string|null $initial): string { $serverVersion = $this->dbi->getVersion(); - $passwordColumn = Compatibility::isMySqlOrPerconaDb() && $serverVersion >= 50706 + $passwordColumn = Compatibility::isMySqlOrPerconaDb($this->dbi) && $serverVersion >= 50706 ? 'authentication_string' : 'Password'; @@ -2850,7 +2850,7 @@ class Privileges private function checkIfMariaDBPwdCheckPluginActive(): bool { $serverVersion = $this->dbi->getVersion(); - if (! (Compatibility::isMariaDb() && $serverVersion >= 100002)) { + if (! (Compatibility::isMariaDb($this->dbi) && $serverVersion >= 100002)) { return false; } @@ -2894,7 +2894,11 @@ class Privileges // 'IDENTIFIED WITH auth_plugin' // is supported by MySQL 5.5.7+ - if (Compatibility::isMySqlOrPerconaDb() && $serverVersion >= 50507 && isset($_POST['authentication_plugin'])) { + if ( + Compatibility::isMySqlOrPerconaDb($this->dbi) + && $serverVersion >= 50507 + && isset($_POST['authentication_plugin']) + ) { $createUserStmt .= ' IDENTIFIED WITH ' . $_POST['authentication_plugin']; } @@ -2902,7 +2906,7 @@ class Privileges // 'IDENTIFIED VIA auth_plugin' // is supported by MariaDB 5.2+ if ( - Compatibility::isMariaDb() + Compatibility::isMariaDb($this->dbi) && $serverVersion >= 50200 && isset($_POST['authentication_plugin']) && ! $isMariaDBPwdPluginActive @@ -2935,8 +2939,8 @@ class Privileges // and 'CREATE USER ... VIA .. USING ..' syntax for // newer MariaDB versions if ( - (Compatibility::isMySqlOrPerconaDb() && $serverVersion >= 50706) - || (Compatibility::isMariaDb() && $serverVersion >= 50200) + (Compatibility::isMySqlOrPerconaDb($this->dbi) && $serverVersion >= 50706) + || (Compatibility::isMariaDb($this->dbi) && $serverVersion >= 50200) ) { $passwordSetReal = ''; @@ -2945,11 +2949,15 @@ class Privileges // MariaDB uses 'USING' whereas MySQL uses 'AS' // but MariaDB with validation plugin needs cleartext password - if (Compatibility::isMariaDb() && ! $isMariaDBPwdPluginActive && isset($_POST['authentication_plugin'])) { + if ( + Compatibility::isMariaDb($this->dbi) + && ! $isMariaDBPwdPluginActive + && isset($_POST['authentication_plugin']) + ) { $createUserStmt .= ' USING %s'; - } elseif (Compatibility::isMariaDb()) { + } elseif (Compatibility::isMariaDb($this->dbi)) { $createUserStmt .= ' IDENTIFIED BY %s'; - } elseif (Compatibility::isMySqlOrPerconaDb() && $serverVersion >= 80011) { + } elseif (Compatibility::isMySqlOrPerconaDb($this->dbi) && $serverVersion >= 80011) { if (! str_contains($createUserStmt, 'IDENTIFIED')) { // Maybe the authentication_plugin was not posted and then a part is missing $createUserStmt .= ' IDENTIFIED BY %s'; @@ -2966,8 +2974,8 @@ class Privileges $createUserReal = sprintf($createUserStmt, "''"); } else { if ( - ! ((Compatibility::isMariaDb() && $isMariaDBPwdPluginActive) - || Compatibility::isMySqlOrPerconaDb() && $serverVersion >= 80011) + ! ((Compatibility::isMariaDb($this->dbi) && $isMariaDBPwdPluginActive) + || Compatibility::isMySqlOrPerconaDb($this->dbi) && $serverVersion >= 80011) ) { $hashedPassword = $this->getHashedPassword($_POST['pma_pw']); } else { @@ -2997,7 +3005,7 @@ class Privileges $alterRealSqlQuery = ''; $alterSqlQuery = ''; - if (Compatibility::isMySqlOrPerconaDb() && $serverVersion >= 80011) { + if (Compatibility::isMySqlOrPerconaDb($this->dbi) && $serverVersion >= 80011) { $sqlQueryStmt = ''; if (isset($_POST['Grant_priv']) && $_POST['Grant_priv'] === 'Y') { $sqlQueryStmt = ' WITH GRANT OPTION'; @@ -3015,7 +3023,7 @@ class Privileges $requireClause = $this->getRequireClause(); $withClause = $this->getWithClauseForAddUserAndUpdatePrivs(); - if (Compatibility::isMySqlOrPerconaDb() && $serverVersion >= 80011) { + if (Compatibility::isMySqlOrPerconaDb($this->dbi) && $serverVersion >= 80011) { $alterRealSqlQuery .= $requireClause; $alterSqlQuery .= $requireClause; $alterRealSqlQuery .= $withClause; @@ -3045,9 +3053,9 @@ class Privileges // Use 'SET PASSWORD' for pre-5.7.6 MySQL versions // and pre-5.2.0 MariaDB if ( - (Compatibility::isMySqlOrPerconaDb() + (Compatibility::isMySqlOrPerconaDb($this->dbi) && $serverVersion >= 50706) - || (Compatibility::isMariaDb() + || (Compatibility::isMariaDb($this->dbi) && $serverVersion >= 50200) ) { $passwordSetReal = ''; @@ -3127,9 +3135,9 @@ class Privileges $serverVersion = $this->dbi->getVersion(); $origAuthPlugin = $this->getCurrentAuthenticationPlugin($username, $hostname); - $isNew = (Compatibility::isMySqlOrPerconaDb() && $serverVersion >= 50507) - || (Compatibility::isMariaDb() && $serverVersion >= 50200); - $hasMoreAuthPlugins = (Compatibility::isMySqlOrPerconaDb() && $serverVersion >= 50706) + $isNew = (Compatibility::isMySqlOrPerconaDb($this->dbi) && $serverVersion >= 50507) + || (Compatibility::isMariaDb($this->dbi) && $serverVersion >= 50200); + $hasMoreAuthPlugins = (Compatibility::isMySqlOrPerconaDb($this->dbi) && $serverVersion >= 50706) || ($this->dbi->isSuperUser() && $editOthers); $activeAuthPlugins = ['mysql_native_password' => __('Native MySQL authentication')]; diff --git a/src/Table/ColumnsDefinition.php b/src/Table/ColumnsDefinition.php index fd334a557a..6538f34800 100644 --- a/src/Table/ColumnsDefinition.php +++ b/src/Table/ColumnsDefinition.php @@ -341,10 +341,14 @@ final class ColumnsDefinition 'storage_engines' => $storageEngines, 'connection' => $_POST['connection'] ?? null, 'change_column' => $_POST['change_column'] ?? $_GET['change_column'] ?? null, - 'is_virtual_columns_supported' => Compatibility::isVirtualColumnsSupported($this->dbi->getVersion()), + 'is_virtual_columns_supported' => Compatibility::isVirtualColumnsSupported( + $this->dbi, + $this->dbi->getVersion(), + ), 'is_integers_length_restricted' => $isIntegersLengthRestricted, 'browse_mime' => $config->config->BrowseMIME , 'supports_stored_keyword' => Compatibility::supportsStoredKeywordForVirtualColumns( + $this->dbi, $this->dbi->getVersion(), ), 'server_version' => $this->dbi->getVersion(), diff --git a/src/Table/Indexes.php b/src/Table/Indexes.php index 06a7c0172d..2bcbc78738 100644 --- a/src/Table/Indexes.php +++ b/src/Table/Indexes.php @@ -149,7 +149,7 @@ final class Indexes public function getSqlQueryForRename(string $oldIndexName, Index $index, string $db, string $table): string { - if (! Compatibility::isCompatibleRenameIndex($this->dbi->getVersion())) { + if (! Compatibility::isCompatibleRenameIndex($this->dbi, $this->dbi->getVersion())) { return $this->getSqlQueryForIndexCreateOrEdit($oldIndexName, $index, $db, $table); } diff --git a/src/Table/Table.php b/src/Table/Table.php index 5956ee38ee..2cd3af4d40 100644 --- a/src/Table/Table.php +++ b/src/Table/Table.php @@ -465,10 +465,10 @@ class Table implements Stringable // if column is virtual, check if server type is Mysql as only Mysql server // supports extra column properties - $isVirtualColMysql = $virtuality && Compatibility::isMySqlOrPerconaDb(); + $isVirtualColMysql = $virtuality && Compatibility::isMySqlOrPerconaDb($dbi); // if column is virtual, check if server type is MariaDB as MariaDB server // supports no extra virtual column properties except CHARACTER SET for text column types - $isVirtualColMariaDB = $virtuality && Compatibility::isMariaDb(); + $isVirtualColMariaDB = $virtuality && Compatibility::isMariaDb($dbi); $matches = preg_match('@^(TINYTEXT|TEXT|MEDIUMTEXT|LONGTEXT|VARCHAR|CHAR|ENUM|SET)$@i', $type) === 1; if ($collation !== '' && $collation !== 'NULL' && $matches) { @@ -1693,7 +1693,7 @@ class Table implements Stringable public function getColumnGenerationExpression(string|null $column = null): array|bool { if ( - Compatibility::isMySqlOrPerconaDb() + Compatibility::isMySqlOrPerconaDb($this->dbi) && $this->dbi->getVersion() > 50705 && ! Config::getInstance()->selectedServer['DisableIS'] ) { diff --git a/src/Types.php b/src/Types.php index 5a4e73e2ff..fba40e9a3d 100644 --- a/src/Types.php +++ b/src/Types.php @@ -568,7 +568,7 @@ class Types $attributes = ['', 'BINARY', 'UNSIGNED', 'UNSIGNED ZEROFILL', 'on update CURRENT_TIMESTAMP']; - if (Compatibility::supportsCompressedColumns($serverVersion)) { + if (Compatibility::supportsCompressedColumns($this->dbi, $serverVersion)) { $attributes[] = 'COMPRESSED=zlib'; } diff --git a/src/UserPassword.php b/src/UserPassword.php index 8a3fb8cde3..7205f41673 100644 --- a/src/UserPassword.php +++ b/src/UserPassword.php @@ -80,7 +80,7 @@ class UserPassword $sqlQuery = 'SET password = ' . ($password === '' ? '\'\'' : $hashingFunction . '(\'***\')'); - $isPerconaOrMySql = Compatibility::isMySqlOrPerconaDb(); + $isPerconaOrMySql = Compatibility::isMySqlOrPerconaDb($this->dbi); if ($isPerconaOrMySql && $serverVersion >= 50706) { $sqlQuery = $this->getChangePasswordQueryAlterUserMySQL( $serverVersion, @@ -92,7 +92,7 @@ class UserPassword ); } elseif ( ($isPerconaOrMySql && $serverVersion >= 50507) - || (Compatibility::isMariaDb() && $serverVersion >= 50200) + || (Compatibility::isMariaDb($this->dbi) && $serverVersion >= 50200) ) { // For MySQL and Percona versions 5.5.7+ and MariaDB versions 5.2+, // explicitly set value of `old_passwords` so that @@ -185,7 +185,7 @@ class UserPassword $errUrl = Url::getFromRoute('/user-password'); $serverVersion = $this->dbi->getVersion(); - $isPerconaOrMySql = Compatibility::isMySqlOrPerconaDb(); + $isPerconaOrMySql = Compatibility::isMySqlOrPerconaDb($this->dbi); if ($isPerconaOrMySql && $serverVersion >= 50706) { $localQuery = $this->getChangePasswordQueryAlterUserMySQL( @@ -197,7 +197,7 @@ class UserPassword $authPluginChanged, ); } elseif ( - Compatibility::isMariaDb() + Compatibility::isMariaDb($this->dbi) && $serverVersion >= 50200 && $serverVersion < 100100 && $origAuthPlugin !== '' diff --git a/src/Util.php b/src/Util.php index bb0ccb0120..ff4774f827 100644 --- a/src/Util.php +++ b/src/Util.php @@ -1303,9 +1303,8 @@ class Util * * @phpstan-return 'MariaDB'|'Percona Server'|'MySQL' */ - public static function getServerType(): string + public static function getServerType(DatabaseInterface $dbi): string { - $dbi = DatabaseInterface::getInstance(); if ($dbi->isMariaDB()) { return 'MariaDB'; } diff --git a/tests/unit/Server/PrivilegesTest.php b/tests/unit/Server/PrivilegesTest.php index 39ef121cba..78e4c9be5a 100644 --- a/tests/unit/Server/PrivilegesTest.php +++ b/tests/unit/Server/PrivilegesTest.php @@ -767,7 +767,10 @@ class PrivilegesTest extends AbstractTestCase public function testGetSqlQueriesForDisplayAndAddUserWithUserDefinedPassword(): void { - $dbi = $this->createDatabaseInterface(); + $dbiDummy = $this->createDbiDummy(); + $dbiDummy->addResult("SHOW PLUGINS SONAME LIKE '%_password_check%'", []); + $dbiDummy->addResult("SELECT PASSWORD('pma_password');", [['*pma_password*']]); + $dbi = $this->createDatabaseInterface($dbiDummy); $dbi->setVersion(['@@version' => '10.4.3-MariaDB']); $serverPrivileges = $this->getPrivileges($dbi); @@ -784,8 +787,9 @@ class PrivilegesTest extends AbstractTestCase $password, ); + $dbiDummy->assertAllQueriesConsumed(); self::assertSame( - 'CREATE USER \'PMA_username\'@\'PMA_hostname\' IDENTIFIED BY \'pma_password\';', + 'CREATE USER \'PMA_username\'@\'PMA_hostname\' IDENTIFIED BY \'*pma_password*\';', $createUserReal, ); self::assertSame('CREATE USER \'PMA_username\'@\'PMA_hostname\' IDENTIFIED BY \'***\';', $createUserShow); diff --git a/tests/unit/UtilTest.php b/tests/unit/UtilTest.php index fc8385fb0b..bebe79a393 100644 --- a/tests/unit/UtilTest.php +++ b/tests/unit/UtilTest.php @@ -1470,4 +1470,20 @@ SQL; self::assertSame('s\\s', Util::unquoteDefaultValue('\'s\\\\s\'')); self::assertSame('sq\'sq', Util::unquoteDefaultValue('\'sq\\\'sq\'')); } + + #[DataProvider('providerForTestGetServerType')] + public function testGetServerType(string $expected, string $version, string $versionComment): void + { + $dbi = $this->createDatabaseInterface(); + $dbi->setVersion(['@@version' => $version, '@@version_comment' => $versionComment]); + self::assertSame($expected, Util::getServerType($dbi)); + } + + /** @return iterable */ + public static function providerForTestGetServerType(): iterable + { + yield 'MySQL' => ['MySQL', '7.10.3', 'MySQL Community Server (GPL)']; + yield 'MariaDB' => ['MariaDB', '10.01.40-MariaDB-1:10.01.40+maria~ubu2204', 'mariadb.org binary distribution']; + yield 'Percona' => ['Percona Server', '6.1.0', "Percona Server (GPL), Release '11', Revision 'c1y2gr1df4a'"]; + } }