diff --git a/typo3/sysext/dbal/Classes/Database/DatabaseConnection.php b/typo3/sysext/dbal/Classes/Database/DatabaseConnection.php
index c75de074e836d72f0872982caa675ff60d53e64a..683803b67f0005345d9a2491b84e213dea76cf85 100644
--- a/typo3/sysext/dbal/Classes/Database/DatabaseConnection.php
+++ b/typo3/sysext/dbal/Classes/Database/DatabaseConnection.php
@@ -202,6 +202,11 @@ class DatabaseConnection extends \TYPO3\CMS\Core\Database\DatabaseConnection {
 		MYSQLI_TYPE_GEOMETRY => 'geometry'
 	);
 
+	/**
+	 * @var Specifics\AbstractSpecifics
+	 */
+	protected $dbmsSpecifics;
+
 	/**
 	 * Constructor.
 	 * Creates SQL parser object and imports configuration from $TYPO3_CONF_VARS['EXTCONF']['dbal']
@@ -230,6 +235,18 @@ class DatabaseConnection extends \TYPO3\CMS\Core\Database\DatabaseConnection {
 		}
 		if (isset($this->conf['handlerCfg'])) {
 			$this->handlerCfg = $this->conf['handlerCfg'];
+
+			if (isset($this->handlerCfg['_DEFAULT']['config']['driver'])) {
+				// load DBMS specifics
+				$driver = $this->handlerCfg['_DEFAULT']['config']['driver'];
+				$className = 'TYPO3\\CMS\\Dbal\\Database\\Specifics\\' . ucfirst(strtolower($driver));
+				if (class_exists($className)) {
+					if (!is_subclass_of($className, Specifics\AbstractSpecifics::class)) {
+						throw new \InvalidArgumentException($className . ' must inherit from ' . Specifics\AbstractSpecifics::class, 1416919866);
+					}
+					$this->dbmsSpecifics = GeneralUtility::makeInstance($className);
+				}
+			}
 		}
 		$this->cacheFieldInfo();
 		// Debugging settings:
@@ -237,6 +254,15 @@ class DatabaseConnection extends \TYPO3\CMS\Core\Database\DatabaseConnection {
 		$this->debug = !empty($this->conf['debugOptions']['enabled']);
 	}
 
+	/**
+	 * Gets the DBMS specifics object
+	 *
+	 * @return Specifics\AbstractSpecifics
+	 */
+	public function getSpecifics() {
+		return $this->dbmsSpecifics;
+	}
+
 	/**
 	 * @return \TYPO3\CMS\Core\Cache\Frontend\PhpFrontend
 	 */
diff --git a/typo3/sysext/dbal/Classes/Database/Specifics/AbstractSpecifics.php b/typo3/sysext/dbal/Classes/Database/Specifics/AbstractSpecifics.php
new file mode 100644
index 0000000000000000000000000000000000000000..7fb7e3a76668162fb45fdb2f6aa7eb396b8bc220
--- /dev/null
+++ b/typo3/sysext/dbal/Classes/Database/Specifics/AbstractSpecifics.php
@@ -0,0 +1,71 @@
+<?php
+namespace TYPO3\CMS\Dbal\Database\Specifics;
+
+/**
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+/**
+ * This class handles the specifics of the active DBMS. Inheriting classes
+ * are intended to define their own specifics.
+ */
+abstract class AbstractSpecifics {
+	/**
+	 * Constants used as identifiers in $specificProperties.
+	 */
+	const TABLE_MAXLENGTH = 'table_maxlength';
+	const FIELD_MAXLENGTH = 'field_maxlength';
+	const LIST_MAXEXPRESSIONS = 'list_maxexpressions';
+
+	/**
+	 * Contains the specifics of a DBMS.
+	 * This is intended to be overridden by inheriting classes.
+	 *
+	 * @var array
+	 */
+	protected $specificProperties = array();
+
+	/**
+	 * Checks if a specific is defined for the used DBMS.
+	 *
+	 * @param string $specific
+	 * @return bool
+	 */
+	public function specificExists($specific) {
+		return isset($this->specificProperties[$specific]);
+	}
+
+	/**
+	 * Gets the specific value.
+	 *
+	 * @param string $specific
+	 * @return mixed
+	 */
+	public function getSpecific($specific) {
+		return $this->specificProperties[$specific];
+	}
+
+	/**
+	 * Splits $expressionList into multiple chunks.
+	 *
+	 * @param array $expressionList
+	 * @param bool $preserveArrayKeys If TRUE, array keys are preserved in array_chunk()
+	 * @return array
+	 */
+	public function splitMaxExpressions($expressionList, $preserveArrayKeys = FALSE) {
+		if (!$this->specificExists(self::LIST_MAXEXPRESSIONS)) {
+			return array($expressionList);
+		}
+
+		return array_chunk($expressionList, $this->getSpecific(self::LIST_MAXEXPRESSIONS), $preserveArrayKeys);
+	}
+}
\ No newline at end of file
diff --git a/typo3/sysext/dbal/Classes/Database/Specifics/Oci8.php b/typo3/sysext/dbal/Classes/Database/Specifics/Oci8.php
new file mode 100644
index 0000000000000000000000000000000000000000..2d4ab19c708e8e79a7eb308f35a92c1e9441fa14
--- /dev/null
+++ b/typo3/sysext/dbal/Classes/Database/Specifics/Oci8.php
@@ -0,0 +1,32 @@
+<?php
+namespace TYPO3\CMS\Dbal\Database\Specifics;
+
+/**
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+/**
+ * This class contains the specifics for Oracle DBMS.
+ * Any logic is in AbstractSpecifics.
+ */
+class Oci8 extends AbstractSpecifics {
+	/**
+	 * Contains the specifics that need to be taken care of for Oracle DBMS.
+	 *
+	 * @var array
+	 */
+	protected $specificProperties = array(
+		self::TABLE_MAXLENGTH => 30,
+		self::FIELD_MAXLENGTH => 30,
+		self::LIST_MAXEXPRESSIONS => 1000
+	);
+}
\ No newline at end of file
diff --git a/typo3/sysext/dbal/Classes/Database/SqlParser.php b/typo3/sysext/dbal/Classes/Database/SqlParser.php
index b9dbcfbd1596ff30f002f5db402189376492b523..3100541c86bc51a1cf44a0fa4313d1ab9c49fcc4 100644
--- a/typo3/sysext/dbal/Classes/Database/SqlParser.php
+++ b/typo3/sysext/dbal/Classes/Database/SqlParser.php
@@ -654,7 +654,8 @@ class SqlParser extends \TYPO3\CMS\Core\Database\SqlParser {
 										}
 										$output .= ' ' . $v['comparator'];
 										// Detecting value type; list or plain:
-										if (GeneralUtility::inList('NOTIN,IN', strtoupper(str_replace(array(' ', TAB, CR, LF), '', $v['comparator'])))) {
+										$comparator = strtoupper(str_replace(array(' ', TAB, CR, LF), '', $v['comparator']));
+										if (GeneralUtility::inList('NOTIN,IN', $comparator)) {
 											if (isset($v['subquery'])) {
 												$output .= ' (' . $this->compileSELECT($v['subquery']) . ')';
 											} else {
@@ -662,7 +663,42 @@ class SqlParser extends \TYPO3\CMS\Core\Database\SqlParser {
 												foreach ($v['value'] as $realValue) {
 													$valueBuffer[] = $realValue[1] . $this->compileAddslashes($realValue[0]) . $realValue[1];
 												}
-												$output .= ' (' . trim(implode(',', $valueBuffer)) . ')';
+
+												$dbmsSpecifics = $this->databaseConnection->getSpecifics();
+												if ($dbmsSpecifics === NULL) {
+													$output .= ' (' . trim(implode(',', $valueBuffer)) . ')';
+												} else {
+													$chunkedList = $dbmsSpecifics->splitMaxExpressions($valueBuffer);
+													$chunkCount = count($chunkedList);
+
+													if ($chunkCount === 1) {
+														$output .= ' (' . trim(implode(',', $valueBuffer)) . ')';
+													} else {
+														$listExpressions = array();
+														$field = trim(($v['table'] ? $v['table'] . '.' : '') . $v['field']);
+
+														switch ($comparator) {
+															case 'IN':
+																$operator = 'OR';
+																break;
+															case 'NOTIN':
+																$operator = 'AND';
+																break;
+														}
+
+														for ($i = 0; $i < $chunkCount; ++$i) {
+															$listPart = trim(implode(',', $chunkedList[$i]));
+															$listExpressions[] = ' (' . $listPart . ')';
+														}
+
+														$implodeString = ' ' . $operator . ' ' . $field . ' ' . $v['comparator'];
+
+														// add opening brace before field
+														$lastFieldPos = strpos($output, $field);
+														$output = substr_replace($output, '(', $lastFieldPos, 0);
+														$output .= implode($implodeString, $listExpressions) . ')';
+													}
+												}
 											}
 										} elseif (GeneralUtility::inList('BETWEEN,NOT BETWEEN', $v['comparator'])) {
 											$lbound = $v['values'][0];
diff --git a/typo3/sysext/dbal/Tests/Unit/Database/DatabaseConnectionOracleTest.php b/typo3/sysext/dbal/Tests/Unit/Database/DatabaseConnectionOracleTest.php
index 2bd5bd216f53c9bae428d343905ec58a9eaf37c5..3b7a241a61bef2dc1689a0aa1b32fb0520195384 100644
--- a/typo3/sysext/dbal/Tests/Unit/Database/DatabaseConnectionOracleTest.php
+++ b/typo3/sysext/dbal/Tests/Unit/Database/DatabaseConnectionOracleTest.php
@@ -909,4 +909,67 @@ class DatabaseConnectionOracleTest extends AbstractTestCase {
 		$expected = 'SELECT * FROM "tt_content" WHERE (dbms_lob.instr("bodytext", \'test\',1,1) > 0)';
 		$this->assertEquals($expected, $this->cleanSql($result));
 	}
+
+	/**
+	 * @test
+	 */
+	public function expressionListWithNotInIsConcatenatedWithAnd() {
+		$listMaxExpressions = 1000;
+
+		$mockSpecificsOci8 = $this->getAccessibleMock('TYPO3\\CMS\\Dbal\\Database\\Specifics\\Oci8', array(), array(), '', FALSE);
+		$mockSpecificsOci8->expects($this->any())->method('getSpecific')->will($this->returnValue($listMaxExpressions));
+
+		$items = range(0, 1250);
+		$where = 'uid NOT IN(' . implode(',', $items) . ')';
+		$result = $this->subject->SELECTquery('*', 'tt_content', $where);
+
+		$chunks = array_chunk($items, $listMaxExpressions);
+		$whereExpr = array();
+		foreach ($chunks as $chunk) {
+			$whereExpr[] = '"uid" NOT IN (' . implode(',', $chunk) . ')';
+		}
+
+		$expectedWhere = '(' . implode(' AND ', $whereExpr) . ')';
+		$expectedQuery = 'SELECT * FROM "tt_content" WHERE ' . $expectedWhere;
+		$this->assertEquals($expectedQuery, $this->cleanSql($result));
+	}
+
+	/**
+	 * @test
+	 */
+	public function expressionListWithInIsConcatenatedWithOr() {
+		$listMaxExpressions = 1000;
+
+		$mockSpecificsOci8 = $this->getAccessibleMock('TYPO3\\CMS\\Dbal\\Database\\Specifics\\Oci8', array(), array(), '', FALSE);
+		$mockSpecificsOci8->expects($this->any())->method('getSpecific')->will($this->returnValue($listMaxExpressions));
+
+		$items = range(0, 1250);
+		$where = 'uid IN(' . implode(',', $items) . ')';
+		$result = $this->subject->SELECTquery('*', 'tt_content', $where);
+
+		$chunks = array_chunk($items, $listMaxExpressions);
+		$whereExpr = array();
+		foreach ($chunks as $chunk) {
+			$whereExpr[] = '"uid" IN (' . implode(',', $chunk) . ')';
+		}
+
+		$expectedWhere = '(' . implode(' OR ', $whereExpr) . ')';
+		$expectedQuery = 'SELECT * FROM "tt_content" WHERE ' . $expectedWhere;
+		$this->assertEquals($expectedQuery, $this->cleanSql($result));
+	}
+
+	/**
+	 * @test
+	 */
+	public function expressionListIsUnchanged() {
+		$listMaxExpressions = 1000;
+
+		$mockSpecificsOci8 = $this->getAccessibleMock('TYPO3\\CMS\\Dbal\\Database\\Specifics\\Oci8', array(), array(), '', FALSE);
+		$mockSpecificsOci8->expects($this->any())->method('getSpecific')->will($this->returnValue($listMaxExpressions));
+
+		$result = $this->subject->SELECTquery('*', 'tt_content', 'uid IN (0,1,2,3,4,5,6,7,8,9,10)');
+
+		$expectedQuery = 'SELECT * FROM "tt_content" WHERE "uid" IN (0,1,2,3,4,5,6,7,8,9,10)';
+		$this->assertEquals($expectedQuery, $this->cleanSql($result));
+	}
 }
\ No newline at end of file
diff --git a/typo3/sysext/extensionmanager/Classes/Domain/Repository/ExtensionRepository.php b/typo3/sysext/extensionmanager/Classes/Domain/Repository/ExtensionRepository.php
index 6f37bef2c719306d4cfcaf502766d60afb6ed0b9..9ddbdf9fa838bb1a0f6c3d6ed9d87ee7b1627ef6 100644
--- a/typo3/sysext/extensionmanager/Classes/Domain/Repository/ExtensionRepository.php
+++ b/typo3/sysext/extensionmanager/Classes/Domain/Repository/ExtensionRepository.php
@@ -25,15 +25,6 @@ class ExtensionRepository extends \TYPO3\CMS\Extbase\Persistence\Repository {
 	 */
 	const TABLE_NAME = 'tx_extensionmanager_domain_model_extension';
 
-	/**
-	 * Oracle has a limit of 1000 values in an IN clause. Set the size of a chunk
-	 * being updated to 500 to make sure it does not collide with a limit in any
-	 * other DBMS.
-	 *
-	 * @var int
-	 */
-	const CHUNK_SIZE = 500;
-
 	/**
 	 * @var \TYPO3\CMS\Core\Database\DatabaseConnection
 	 */
@@ -293,18 +284,13 @@ class ExtensionRepository extends \TYPO3\CMS\Extbase\Persistence\Repository {
 	protected function markExtensionWithMaximumVersionAsCurrent($repositoryUid) {
 		$uidsOfCurrentVersion = $this->fetchMaximalVersionsForAllExtensions($repositoryUid);
 
-		// some DBMS limit the amount of expressions, apply the update in chunks
-		$chunks = array_chunk($uidsOfCurrentVersion, self::CHUNK_SIZE);
-		$chunkCount = count($chunks);
-		for ($i = 0; $i < $chunkCount; ++$i) {
-			$this->databaseConnection->exec_UPDATEquery(
-				self::TABLE_NAME,
-				'uid IN (' . implode(',', $chunks[$i]) . ')',
-				array(
-					'current_version' => 1,
-				)
-			);
-		}
+		$this->databaseConnection->exec_UPDATEquery(
+			self::TABLE_NAME,
+			'uid IN (' . implode(',', $uidsOfCurrentVersion) . ')',
+			array(
+				'current_version' => 1,
+			)
+		);
 	}
 
 	/**