Commit 6eda664f authored by Morton Jonuschat's avatar Morton Jonuschat Committed by Christian Kuhn
Browse files

[BUGFIX] Fix functional tests for EXT:core on PostgreSQL

Fix reliance on MySQLs implicit secondary ordering by uid within
DataHandler.

Reset sequenced on non-MySQL database platforms.

Sort expected results retrieved from the database and switch to using
assertEquals() to avoid string/int type differences in result rows
due to different drivers.

Change-Id: I95a8cdb81dbbdb6c4bcf2c6c9ad9f0e5f9ae44fe
Resolves: #79672
Releases: master
Reviewed-on: https://review.typo3.org/51664


Tested-by: default avatarTYPO3com <no-reply@typo3.com>
Reviewed-by: Frank Nägler's avatarFrank Nägler <frank.naegler@typo3.org>
Reviewed-by: Manuel Selbach's avatarManuel Selbach <manuel_selbach@yahoo.de>
Reviewed-by: Christian Kuhn's avatarChristian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn's avatarChristian Kuhn <lolli@schwarzbu.ch>
parent f2283d76
......@@ -3535,6 +3535,7 @@ class DataHandler
if (!empty($GLOBALS['TCA'][$table]['ctrl']['sortby'])) {
$queryBuilder->orderBy($GLOBALS['TCA'][$table]['ctrl']['sortby'], 'DESC');
}
$queryBuilder->addOrderBy('uid');
try {
$result = $queryBuilder->execute();
$rows = [];
......@@ -7005,6 +7006,14 @@ class DataHandler
}
} else {
if ((string)$value !== (string)$row[$key]) {
// The is_numeric check catches cases where we want to store a float/double value
// and database returns the field as a string with the least required amount of
// significant digits, i.e. "0.00" being saved and "0" being read back.
if (is_numeric($value) && is_numeric($row[$key])) {
if ((double)$value === (double)$row[$key]) {
continue;
}
}
$errors[] = $key;
}
}
......@@ -7146,13 +7155,13 @@ class DataHandler
$row = $movePlaceholder;
}
// If the record should be inserted after itself, keep the current sorting information:
if ($row['uid'] == $uid) {
if ((int)$row['uid'] === (int)$uid) {
$sortNumber = $row[$sortRow];
} else {
$queryBuilder = $connectionPool->getQueryBuilderForTable($table);
$this->addDeleteRestriction($queryBuilder->getRestrictions()->removeAll());
$subResult = $queryBuilder
$subResults = $queryBuilder
->select($sortRow, 'pid', 'uid')
->from($table)
->where(
......@@ -7167,14 +7176,13 @@ class DataHandler
)
->orderBy($sortRow, 'ASC')
->setMaxResults(2)
->execute();
->execute()
->fetchAll();
// Fetches the next record in order to calculate the in-between sortNumber
// There was a record afterwards
if ($subResult->rowCount() === 2) {
// Forward to the second result...
$subResult->fetch();
// There was a record afterwards
$subrow = $subResult->fetch();
if (count($subResults) === 2) {
// There was a record afterwards, fetch that
$subrow = array_pop($subResults);
// The sortNumber is found in between these values
$sortNumber = $row[$sortRow] + floor(($subrow[$sortRow] - $row[$sortRow]) / 2);
// The sortNumber happened NOT to be between the two surrounding numbers, so we'll have to resort the list
......@@ -7220,7 +7228,8 @@ class DataHandler
$returnVal = 0;
$intervals = $this->sortIntervals;
$i = $intervals * 2;
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
$connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($table);
$queryBuilder = $connection->createQueryBuilder();
$this->addDeleteRestriction($queryBuilder->getRestrictions()->removeAll());
$result = $queryBuilder
......@@ -7228,13 +7237,12 @@ class DataHandler
->from($table)
->where($queryBuilder->expr()->eq('pid', $queryBuilder->createNamedParameter($pid, \PDO::PARAM_INT)))
->orderBy($sortRow, 'ASC')
->addOrderBy('uid', 'ASC')
->execute();
while ($row = $result->fetch()) {
$uid = (int)$row['uid'];
if ($uid) {
GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionForTable($table)
->update($table, [$sortRow => $i], ['uid' => (int)$uid]);
$connection->update($table, [$sortRow => $i], ['uid' => (int)$uid]);
// This is used to return a sortingValue if the list is resorted because of inserting records inside the list and not in the top
if ($uid == $return_SortNumber_After_This_Uid) {
$i = $i + $intervals;
......
......@@ -685,6 +685,7 @@ class DataMapProcessor
->add(GeneralUtility::makeInstance(BackendWorkspaceRestriction::class, $this->backendUser->workspace, false));
$zeroParameter = $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT);
$ids = array_filter($ids, [MathUtility::class, 'canBeInterpretedAsInteger']);
$idsParameter = $queryBuilder->createNamedParameter($ids, Connection::PARAM_INT_ARRAY);
$predicates = [
......
......@@ -393,9 +393,9 @@ class Typo3DatabaseBackendTest extends \TYPO3\TestingFramework\Core\Functional\F
{
$subject = $this->getSubjectObject();
$this->assertSame(['idA' => 'idA'], $subject->findIdentifiersByTag('tagA'));
$this->assertSame(['idA' => 'idA', 'idB' => 'idB'], $subject->findIdentifiersByTag('tagB'));
$this->assertSame(['idB' => 'idB', 'idC' => 'idC'], $subject->findIdentifiersByTag('tagC'));
$this->assertEquals(['idA' => 'idA'], $subject->findIdentifiersByTag('tagA'));
$this->assertEquals(['idA' => 'idA', 'idB' => 'idB'], $subject->findIdentifiersByTag('tagB'));
$this->assertEquals(['idB' => 'idB', 'idC' => 'idC'], $subject->findIdentifiersByTag('tagC'));
}
/**
......
......@@ -18,6 +18,7 @@ use Doctrine\DBAL\DBALException;
use TYPO3\CMS\Core\Database\Connection;
use TYPO3\CMS\Core\Tests\Functional\DataHandling\Framework\DataSet;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\TestingFramework\Core\Testbase;
/**
* Functional test for the DataHandler
......@@ -114,15 +115,15 @@ abstract class AbstractDataHandlerActionTestCase extends \TYPO3\TestingFramework
$dataSet = DataSet::read($fileName, true);
foreach ($dataSet->getTableNames() as $tableName) {
$connection = $this->getConnectionPool()->getConnectionForTable($tableName);
foreach ($dataSet->getElements($tableName) as $element) {
$connection = $this->getConnectionPool()
->getConnectionForTable($tableName);
try {
$connection->insert($tableName, $element);
} catch (DBALException $e) {
$this->fail('SQL Error for table "' . $tableName . '": ' . LF . $e->getMessage());
}
}
Testbase::resetTableSequences($connection, $tableName);
}
}
......
......@@ -46,7 +46,8 @@ class SpecialLanguagesTest extends AbstractDataHandlerActionTestCase
->getQueryBuilderForTable('be_groups')
->select('allowed_languages')
->from('be_groups')
->where('uid=1')
->orderBy('uid', 'DESC')
->setMaxResults(1)
->execute();
$this->assertEquals($expected, $statement->fetchColumn(0));
}
......
CREATE TABLE a_test_table (
uid BIGINT(11) NOT NULL AUTO_INCREMENT,
title VARCHAR(100) DEFAULT 'Title',
);
......@@ -4,5 +4,5 @@ CREATE TABLE another_test_table (
title VARCHAR(50) DEFAULT '' NOT NULL
);
INSERT INTO a_test_table VALUES (NULL, 0, 0, 0, 0);
INSERT INTO `a_test_table` VALUES (NULL, 1, 1, 1, 1);
INSERT INTO a_test_table VALUES (NULL, 0, 0, 0, 0, 'foo');
INSERT INTO `a_test_table` VALUES (NULL, 1, 1, 1, 1, 'bar');
......@@ -4,6 +4,7 @@ CREATE TABLE a_test_table (
tstamp INT(11) UNSIGNED DEFAULT '0' NOT NULL,
hidden TINYINT(3) UNSIGNED DEFAULT '0' NOT NULL,
deleted TINYINT(3) UNSIGNED DEFAULT '0' NOT NULL,
title VARCHAR(50) DEFAULT '' NOT NULL,
PRIMARY KEY (uid),
KEY parent (pid)
......
......@@ -19,7 +19,6 @@ namespace TYPO3\CMS\Core\Tests\Functional\Database\Schema;
use Doctrine\DBAL\Schema\AbstractSchemaManager;
use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Types\BigIntType;
use Doctrine\DBAL\Types\IntegerType;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Database\Schema\SchemaMigrator;
use TYPO3\CMS\Core\Database\Schema\SqlReader;
......@@ -105,7 +104,7 @@ class SchemaMigratorTest extends \TYPO3\TestingFramework\Core\Functional\Functio
$updateSuggestions[ConnectionPool::DEFAULT_CONNECTION_NAME]['create_table']
);
$this->assertCount(5, $this->getTableDetails()->getColumns());
$this->assertCount(6, $this->getTableDetails()->getColumns());
}
/**
......@@ -144,22 +143,24 @@ class SchemaMigratorTest extends \TYPO3\TestingFramework\Core\Functional\Functio
/**
* @test
* @group mysql
* @TODO: Find PostgreSQL failure
*/
public function changeExistingColumn()
{
$statements = $this->readFixtureFile('changeExistingColumn');
$updateSuggestions = $this->subject->getUpdateSuggestions($statements);
$this->assertInstanceOf(IntegerType::class, $this->getTableDetails()->getColumn('uid')->getType());
$this->assertTrue($this->getTableDetails()->getColumn('uid')->getUnsigned());
$this->assertEquals(50, $this->getTableDetails()->getColumn('title')->getLength());
$this->assertEmpty($this->getTableDetails()->getColumn('title')->getDefault());
$this->subject->migrate(
$statements,
$updateSuggestions[ConnectionPool::DEFAULT_CONNECTION_NAME]['change']
);
$this->assertInstanceOf(BigIntType::class, $this->getTableDetails()->getColumn('uid')->getType());
$this->assertFalse($this->getTableDetails()->getColumn('uid')->getUnsigned());
$this->assertEquals(100, $this->getTableDetails()->getColumn('title')->getLength());
$this->assertEquals('Title', $this->getTableDetails()->getColumn('title')->getDefault());
}
/**
......@@ -201,6 +202,7 @@ class SchemaMigratorTest extends \TYPO3\TestingFramework\Core\Functional\Functio
/**
* @test
* @group mysql
*/
public function renameUnusedField()
{
......@@ -281,6 +283,7 @@ class SchemaMigratorTest extends \TYPO3\TestingFramework\Core\Functional\Functio
/**
* @test
* @group mysql
*/
public function installPerformsOnlyAddAndCreateOperations()
{
......@@ -296,6 +299,7 @@ class SchemaMigratorTest extends \TYPO3\TestingFramework\Core\Functional\Functio
/**
* @test
* @group mysql
*/
public function installCanPerformChangeOperations()
{
......@@ -311,6 +315,7 @@ class SchemaMigratorTest extends \TYPO3\TestingFramework\Core\Functional\Functio
/**
* @test
* @group mysql
*/
public function importStaticDataInsertsRecords()
{
......@@ -336,6 +341,7 @@ class SchemaMigratorTest extends \TYPO3\TestingFramework\Core\Functional\Functio
/**
* @test
* @group mysql
*/
public function changeTableEngine()
{
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment