Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix tests addCheck(), dropCheck() MariaDB. #20174

Merged
merged 1 commit into from
May 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 3 additions & 9 deletions framework/db/mysql/Schema.php
Original file line number Diff line number Diff line change
Expand Up @@ -205,8 +205,10 @@ protected function loadTableUniques($tableName)
*/
protected function loadTableChecks($tableName)
{
$version = $this->db->getServerVersion();

// check version MySQL >= 8.0.16
if (version_compare($this->db->getSlavePdo()->getAttribute(\PDO::ATTR_SERVER_VERSION), '8.0.16', '<')) {
if (\stripos($version, 'MariaDb') === false && \version_compare($version, '8.0.16', '<')) {
throw new NotSupportedException('MySQL < 8.0.16 does not support check constraints.');
}

Expand All @@ -230,17 +232,9 @@ protected function loadTableChecks($tableName)
$tableRows = $this->normalizePdoRowKeyCase($tableRows, true);

foreach ($tableRows as $tableRow) {
$matches = [];
$columnName = null;

if (preg_match('/\(`?([a-zA-Z0-9_]+)`?\s*[><=]/', $tableRow['check_clause'], $matches)) {
$columnName = $matches[1];
}

$check = new CheckConstraint(
[
'name' => $tableRow['constraint_name'],
'columnNames' => [$columnName],
'expression' => $tableRow['check_clause'],
]
);
Expand Down
32 changes: 4 additions & 28 deletions tests/framework/db/SchemaTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -773,14 +773,6 @@ public function testTableSchemaConstraints($tableName, $type, $expected)
$this->expectException('yii\base\NotSupportedException');
}

if (
$this->driverName === 'mysql' &&
version_compare($this->getConnection(false)->getServerVersion(), '8.0.16', '<') &&
$type === 'checks'
) {
$this->expectException('yii\base\NotSupportedException');
}

$constraints = $this->getConnection(false)->getSchema()->{'getTable' . ucfirst($type)}($tableName);
$this->assertMetadataEquals($expected, $constraints);
}
Expand All @@ -797,14 +789,6 @@ public function testTableSchemaConstraintsWithPdoUppercase($tableName, $type, $e
$this->expectException('yii\base\NotSupportedException');
}

if (
$this->driverName === 'mysql' &&
version_compare($this->getConnection(false)->getServerVersion(), '8.0.16', '<') &&
$type === 'checks'
) {
$this->expectException('yii\base\NotSupportedException');
}

$connection = $this->getConnection(false);
$connection->getSlavePdo(true)->setAttribute(PDO::ATTR_CASE, PDO::CASE_UPPER);
$constraints = $connection->getSchema()->{'getTable' . ucfirst($type)}($tableName, true);
Expand All @@ -823,21 +807,13 @@ public function testTableSchemaConstraintsWithPdoLowercase($tableName, $type, $e
$this->expectException('yii\base\NotSupportedException');
}

if (
$this->driverName === 'mysql' &&
version_compare($this->getConnection(false)->getServerVersion(), '8.0.16', '<') &&
$type === 'checks'
) {
$this->expectException('yii\base\NotSupportedException');
}

$connection = $this->getConnection(false);
$connection->getSlavePdo(true)->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER);
$constraints = $connection->getSchema()->{'getTable' . ucfirst($type)}($tableName, true);
$this->assertMetadataEquals($expected, $constraints);
}

private function assertMetadataEquals($expected, $actual)
protected function assertMetadataEquals($expected, $actual)
{
switch (\strtolower(\gettype($expected))) {
case 'object':
Expand Down Expand Up @@ -865,7 +841,7 @@ private function assertMetadataEquals($expected, $actual)
$this->assertEquals($expected, $actual);
}

private function normalizeArrayKeys(array &$array, $caseSensitive)
protected function normalizeArrayKeys(array &$array, $caseSensitive)
{
$newArray = [];
foreach ($array as $value) {
Expand All @@ -889,7 +865,7 @@ private function normalizeArrayKeys(array &$array, $caseSensitive)
$array = $newArray;
}

private function normalizeConstraints(&$expected, &$actual)
protected function normalizeConstraints(&$expected, &$actual)
{
if (\is_array($expected)) {
foreach ($expected as $key => $value) {
Expand All @@ -904,7 +880,7 @@ private function normalizeConstraints(&$expected, &$actual)
}
}

private function normalizeConstraintPair(Constraint $expectedConstraint, Constraint $actualConstraint)
protected function normalizeConstraintPair(Constraint $expectedConstraint, Constraint $actualConstraint)
{
if ($expectedConstraint::className() !== $actualConstraint::className()) {
return;
Expand Down
11 changes: 10 additions & 1 deletion tests/framework/db/mysql/CommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public function testAddDropCheckSeveral()
'int1' => 'integer',
'int2' => 'integer',
'int3' => 'integer',
'int4' => 'integer',
])->execute();

$this->assertEmpty($schema->getTableChecks($tableName, true));
Expand All @@ -43,14 +44,22 @@ public function testAddDropCheckSeveral()
['name' => 'check_int1_positive', 'expression' => '[[int1]] > 0', 'expected' => '(`int1` > 0)'],
['name' => 'check_int2_nonzero', 'expression' => '[[int2]] <> 0', 'expected' => '(`int2` <> 0)'],
['name' => 'check_int3_less_than_100', 'expression' => '[[int3]] < 100', 'expected' => '(`int3` < 100)'],
['name' => 'check_int1_less_than_int2', 'expression' => '[[int1]] < [[int2]]', 'expected' => '(`int1` < `int2`)'],
];

if (\stripos($db->getServerVersion(), 'MariaDb') !== false) {
$constraints[0]['expected'] = '`int1` > 0';
$constraints[1]['expected'] = '`int2` <> 0';
$constraints[2]['expected'] = '`int3` < 100';
$constraints[3]['expected'] = '`int1` < `int2`';
}

foreach ($constraints as $constraint) {
$db->createCommand()->addCheck($constraint['name'], $tableName, $constraint['expression'])->execute();
}

$tableChecks = $schema->getTableChecks($tableName, true);
$this->assertCount(3, $tableChecks);
$this->assertCount(4, $tableChecks);

foreach ($constraints as $index => $constraint) {
$this->assertSame(
Expand Down
113 changes: 111 additions & 2 deletions tests/framework/db/mysql/SchemaTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ public function constraintsProvider()
{
$result = parent::constraintsProvider();

$result['1: check'][2][0]->expression = "(`C_check` <> _utf8mb4\\'\\')";

$result['1: check'][2][0]->columnNames = null;
$result['1: check'][2][0]->expression = "`C_check` <> ''";
$result['2: primary key'][2]->name = null;

// Work aroung bug in MySQL 5.1 - it creates only this table in lowercase. O_o
Expand All @@ -88,6 +88,115 @@ public function constraintsProvider()
return $result;
}

/**
* @dataProvider constraintsProvider
* @param string $tableName
* @param string $type
* @param mixed $expected
*/
public function testTableSchemaConstraints($tableName, $type, $expected)
{
$version = $this->getConnection(false)->getServerVersion();

if ($expected === false) {
$this->expectException('yii\base\NotSupportedException');
}

if (
$this->driverName === 'mysql' &&
\stripos($version, 'MariaDb') === false &&
version_compare($version, '8.0.16', '<') &&
$type === 'checks'
) {
$this->expectException('yii\base\NotSupportedException');
} elseif (
$this->driverName === 'mysql' &&
\stripos($version, 'MariaDb') === false &&
version_compare($version, '8.0.16', '>=') &&
$tableName === 'T_constraints_1' &&
$type === 'checks'
) {
$expected[0]->expression = "(`C_check` <> _utf8mb4\\'\\')";
}

$constraints = $this->getConnection(false)->getSchema()->{'getTable' . ucfirst($type)}($tableName);
$this->assertMetadataEquals($expected, $constraints);
}

/**
* @dataProvider uppercaseConstraintsProvider
* @param string $tableName
* @param string $type
* @param mixed $expected
*/
public function testTableSchemaConstraintsWithPdoUppercase($tableName, $type, $expected)
{
$version = $this->getConnection(false)->getServerVersion();

if ($expected === false) {
$this->expectException('yii\base\NotSupportedException');
}

if (
$this->driverName === 'mysql' &&
\stripos($version, 'MariaDb') === false &&
version_compare($version, '8.0.16', '<') &&
$type === 'checks'
) {
$this->expectException('yii\base\NotSupportedException');
} elseif (
$this->driverName === 'mysql' &&
\stripos($version, 'MariaDb') === false &&
version_compare($version, '8.0.16', '>=') &&
$tableName === 'T_constraints_1' &&
$type === 'checks'
) {
$expected[0]->expression = "(`C_check` <> _utf8mb4\\'\\')";
}

$connection = $this->getConnection(false);
$connection->getSlavePdo(true)->setAttribute(\PDO::ATTR_CASE, \PDO::CASE_UPPER);
$constraints = $connection->getSchema()->{'getTable' . ucfirst($type)}($tableName, true);
$this->assertMetadataEquals($expected, $constraints);
}

/**
* @dataProvider lowercaseConstraintsProvider
* @param string $tableName
* @param string $type
* @param mixed $expected
*/
public function testTableSchemaConstraintsWithPdoLowercase($tableName, $type, $expected)
{
$version = $this->getConnection(false)->getServerVersion();

if ($expected === false) {
$this->expectException('yii\base\NotSupportedException');
}

if (
$this->driverName === 'mysql' &&
\stripos($version, 'MariaDb') === false &&
version_compare($version, '8.0.16', '<') &&
$type === 'checks'
) {
$this->expectException('yii\base\NotSupportedException');
} elseif (
$this->driverName === 'mysql' &&
\stripos($version, 'MariaDb') === false &&
version_compare($version, '8.0.16', '>=') &&
$tableName === 'T_constraints_1' &&
$type === 'checks'
) {
$expected[0]->expression = "(`C_check` <> _utf8mb4\\'\\')";
}

$connection = $this->getConnection(false);
$connection->getSlavePdo(true)->setAttribute(\PDO::ATTR_CASE, \PDO::CASE_LOWER);
$constraints = $connection->getSchema()->{'getTable' . ucfirst($type)}($tableName, true);
$this->assertMetadataEquals($expected, $constraints);
}

/**
* When displayed in the INFORMATION_SCHEMA.COLUMNS table, a default CURRENT TIMESTAMP is displayed
* as CURRENT_TIMESTAMP up until MariaDB 10.2.2, and as current_timestamp() from MariaDB 10.2.3.
Expand Down
3 changes: 3 additions & 0 deletions tests/framework/db/mysql/connection/DeadLockTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ class DeadLockTest extends \yiiunit\framework\db\mysql\ConnectionTest
*/
public function testDeadlockException()
{
if (\stripos($this->getConnection(false)->getServerVersion(), 'MariaDB') !== false) {
$this->markTestSkipped('MariaDB does not support this test');
}
if (PHP_VERSION_ID >= 70400 && PHP_VERSION_ID < 70500) {
$this->markTestSkipped('Stable failed in PHP 7.4');
}
Expand Down
Loading