diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Map/DataCategoryHashMap.php b/app/code/Magento/CatalogUrlRewrite/Model/Map/DataCategoryHashMap.php
index 616e120ebafe4a49bebb5bce4c6e4f82b804cf72..d432767e92689527de82f382448722aad0ddd32d 100644
--- a/app/code/Magento/CatalogUrlRewrite/Model/Map/DataCategoryHashMap.php
+++ b/app/code/Magento/CatalogUrlRewrite/Model/Map/DataCategoryHashMap.php
@@ -42,30 +42,13 @@ class DataCategoryHashMap implements HashMapInterface
         $this->categoryResource = $categoryResource;
     }
 
-    /**
-     * {@inheritdoc}
-     */
-    public function getAllData($categoryId)
-    {
-        return $this->generateData($categoryId);
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function getData($categoryId, $key)
-    {
-        $categorySpecificData = $this->generateData($categoryId);
-        return $categorySpecificData[$key];
-    }
-
     /**
      * Returns an array of categories ids that includes category identified by $categoryId and all its subcategories
      *
      * @param int $categoryId
      * @return array
      */
-    private function generateData($categoryId)
+    public function getAllData($categoryId)
     {
         if (!isset($this->hashMap[$categoryId])) {
             $category = $this->categoryRepository->get($categoryId);
@@ -75,6 +58,18 @@ class DataCategoryHashMap implements HashMapInterface
         return $this->hashMap[$categoryId];
     }
 
+    /**
+     * {@inheritdoc}
+     */
+    public function getData($categoryId, $key)
+    {
+        $categorySpecificData = $this->getAllData($categoryId);
+        if (isset($categorySpecificData[$key])) {
+            return $categorySpecificData[$key];
+        }
+        return [];
+    }
+
     /**
      * Queries the database for sub-categories ids from a category
      *
diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Map/DataCategoryUsedInProductsHashMap.php b/app/code/Magento/CatalogUrlRewrite/Model/Map/DataCategoryUsedInProductsHashMap.php
index 8864226d069d290034c540503e1ee882e5147e90..65200ba1f413d63f06f0d9b319fb6a339d55ae43 100644
--- a/app/code/Magento/CatalogUrlRewrite/Model/Map/DataCategoryUsedInProductsHashMap.php
+++ b/app/code/Magento/CatalogUrlRewrite/Model/Map/DataCategoryUsedInProductsHashMap.php
@@ -33,23 +33,6 @@ class DataCategoryUsedInProductsHashMap implements HashMapInterface
         $this->hashMapPool = $hashMapPool;
     }
 
-    /**
-     * {@inheritdoc}
-     */
-    public function getAllData($categoryId)
-    {
-        return $this->generateData($categoryId);
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function getData($categoryId, $key)
-    {
-        $categorySpecificData = $this->generateData($categoryId);
-        return $categorySpecificData[$key];
-    }
-
     /**
      * Returns an array of product ids for all DataProductHashMap list,
      * that occur in other categories not part of DataCategoryHashMap list
@@ -57,7 +40,7 @@ class DataCategoryUsedInProductsHashMap implements HashMapInterface
      * @param int $categoryId
      * @return array
      */
-    private function generateData($categoryId)
+    public function getAllData($categoryId)
     {
         if (!isset($this->hashMap[$categoryId])) {
             $productsLinkConnection = $this->connection->getConnection();
@@ -91,6 +74,18 @@ class DataCategoryUsedInProductsHashMap implements HashMapInterface
         return $this->hashMap[$categoryId];
     }
 
+    /**
+     * {@inheritdoc}
+     */
+    public function getData($categoryId, $key)
+    {
+        $categorySpecificData = $this->getAllData($categoryId);
+        if (isset($categorySpecificData[$key])) {
+            return $categorySpecificData[$key];
+        }
+        return [];
+    }
+
     /**
      * {@inheritdoc}
      */
diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Map/DataProductHashMap.php b/app/code/Magento/CatalogUrlRewrite/Model/Map/DataProductHashMap.php
index a20b837e4096ad3155aca948e393b8b79597a22a..4b107043459a3c041181961f5cb0a9c02eeb1a41 100644
--- a/app/code/Magento/CatalogUrlRewrite/Model/Map/DataProductHashMap.php
+++ b/app/code/Magento/CatalogUrlRewrite/Model/Map/DataProductHashMap.php
@@ -40,30 +40,13 @@ class DataProductHashMap implements HashMapInterface
         $this->connection = $connection;
     }
 
-    /**
-     * {@inheritdoc}
-     */
-    public function getAllData($categoryId)
-    {
-        return $this->generateData($categoryId);
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function getData($categoryId, $key)
-    {
-        $categorySpecificData = $this->generateData($categoryId);
-        return $categorySpecificData[$key];
-    }
-
     /**
      * Returns an array of ids of all visible products and assigned to a category and all its subcategories
      *
      * @param int $categoryId
      * @return array
      */
-    private function generateData($categoryId)
+    public function getAllData($categoryId)
     {
         if (!isset($this->hashMap[$categoryId])) {
             $productsCollection = $this->collectionFactory->create();
@@ -89,6 +72,18 @@ class DataProductHashMap implements HashMapInterface
         return $this->hashMap[$categoryId];
     }
 
+    /**
+     * {@inheritdoc}
+     */
+    public function getData($categoryId, $key)
+    {
+        $categorySpecificData = $this->getAllData($categoryId);
+        if (isset($categorySpecificData[$key])) {
+            return $categorySpecificData[$key];
+        }
+        return [];
+    }
+
     /**
      * {@inheritdoc}
      */
diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Map/DatabaseMapPool.php b/app/code/Magento/CatalogUrlRewrite/Model/Map/DatabaseMapPool.php
index 30732013eace4df7906333bbd43935b2f5761d84..bb94c1972a17c4e4afa1db555fc461cc21625c95 100644
--- a/app/code/Magento/CatalogUrlRewrite/Model/Map/DatabaseMapPool.php
+++ b/app/code/Magento/CatalogUrlRewrite/Model/Map/DatabaseMapPool.php
@@ -44,17 +44,18 @@ class DatabaseMapPool
     {
         $key = $instanceName . '-' . $categoryId;
         if (!isset($this->dataArray[$key])) {
-            $this->dataArray[$key] = $this->objectManager->create(
+            $instance = $this->objectManager->create(
                 $instanceName,
                 [
                     'category' => $categoryId
                 ]
             );
-            if (!$this->dataArray[$key] instanceof DatabaseMapInterface) {
+            if (!$instance instanceof DatabaseMapInterface) {
                 throw new \InvalidArgumentException(
                     $instanceName . ' does not implement interface ' . DatabaseMapInterface::class
                 );
             }
+            $this->dataArray[$key] = $instance;
         }
         return $this->dataArray[$key];
     }
diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Map/HashMapPool.php b/app/code/Magento/CatalogUrlRewrite/Model/Map/HashMapPool.php
index bc6be808d4d9a96e7cd8a42ed106c7266f209c40..6606812a61995fa24a383170e67c6c99eb1caa90 100644
--- a/app/code/Magento/CatalogUrlRewrite/Model/Map/HashMapPool.php
+++ b/app/code/Magento/CatalogUrlRewrite/Model/Map/HashMapPool.php
@@ -45,17 +45,18 @@ class HashMapPool
     {
         $key = $instanceName . '-' . $categoryId;
         if (!isset($this->dataArray[$key])) {
-            $this->dataArray[$key] = $this->objectManager->create(
+            $instance = $this->objectManager->create(
                 $instanceName,
                 [
                     'category' => $categoryId
                 ]
             );
-            if (!$this->dataArray[$key] instanceof HashMapInterface) {
+            if (!$instance instanceof HashMapInterface) {
                 throw new \InvalidArgumentException(
                     $instanceName . ' does not implement interface ' . HashMapInterface::class
                 );
             }
+            $this->dataArray[$key] = $instance;
         }
         return $this->dataArray[$key];
     }
diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Map/HashMapPoolTest.php b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Map/HashMapPoolTest.php
index 78b114f60da858acb0d8bbd2e07edd87dcfb5ad0..eef5e05e4f6429ed90f76d918502b0dff0d20513 100644
--- a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Map/HashMapPoolTest.php
+++ b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Map/HashMapPoolTest.php
@@ -9,6 +9,7 @@ use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
 use Magento\CatalogUrlRewrite\Model\Map\HashMapPool;
 use Magento\CatalogUrlRewrite\Model\Map\DataCategoryHashMap;
 use Magento\CatalogUrlRewrite\Model\Map\DataProductHashMap;
+use Magento\CatalogUrlRewrite\Model\Map\DataCategoryUsedInProductsHashMap;
 use Magento\Framework\ObjectManagerInterface;
 
 /**
@@ -41,15 +42,35 @@ class HashMapPoolTest extends \PHPUnit_Framework_TestCase
     {
         $dataCategoryMapMock = $this->getMock(DataCategoryHashMap::class, [], [], '', false);
         $dataProductMapMock = $this->getMock(DataProductHashMap::class, [], [], '', false);
-        $dataProductMapMockOtherCategory = $this->getMock(DataProductHashMap::class, [], [], '', false);
+        $dataProductMapMockOtherCategory = $this->getMock(DataCategoryUsedInProductsHashMap::class, [], [], '', false);
 
         $this->objectManagerMock->expects($this->any())
             ->method('create')
-            ->willReturnOnConsecutiveCalls($dataCategoryMapMock, $dataProductMapMock, $dataProductMapMockOtherCategory);
-        $this->assertEquals($dataCategoryMapMock, $this->model->getDataMap(DataCategoryHashMap::class, 1));
+            ->willReturnMap(
+                [
+                   [
+                       DataCategoryHashMap::class,
+                       ['category' => 1],
+                       $dataCategoryMapMock
+                   ],
+                    [
+                        DataProductHashMap::class,
+                        ['category' => 1],
+                        $dataProductMapMock
+                    ],
+                   [
+                       DataCategoryUsedInProductsHashMap::class,
+                       ['category' => 2],
+                       $dataProductMapMockOtherCategory
+                   ]
+               ]
+           );
         $this->assertSame($dataCategoryMapMock, $this->model->getDataMap(DataCategoryHashMap::class, 1));
-        $this->assertEquals($dataProductMapMock, $this->model->getDataMap(DataProductHashMap::class, 1));
-        $this->assertEquals($dataProductMapMockOtherCategory, $this->model->getDataMap(DataCategoryHashMap::class, 2));
+        $this->assertSame($dataProductMapMock, $this->model->getDataMap(DataProductHashMap::class, 1));
+        $this->assertSame(
+            $dataProductMapMockOtherCategory,
+            $this->model->getDataMap(DataCategoryUsedInProductsHashMap::class, 2)
+        );
     }
 
     /**
diff --git a/app/etc/di.xml b/app/etc/di.xml
index 3a5533fd825ce677d5df3f6ff2dded69af010693..a7c38ae1246b602a105c5e1a588fc5e7b9561b2e 100755
--- a/app/etc/di.xml
+++ b/app/etc/di.xml
@@ -1221,4 +1221,17 @@
             </argument>
         </arguments>
     </type>
+    <type name="Magento\Framework\DB\TemporaryTableService">
+        <arguments>
+            <argument name="allowedIndexMethods" xsi:type="array">
+                <item name="HASH" xsi:type="string">HASH</item>
+                <item name="BTREE" xsi:type="string">BTREE</item>
+            </argument>
+            <argument name="allowedEngines" xsi:type="array">
+                <item name="INNODB" xsi:type="string">INNODB</item>
+                <item name="MEMORY" xsi:type="string">MEMORY</item>
+                <item name="MYISAM" xsi:type="string">MYISAM</item>
+            </argument>
+        </arguments>
+    </type>
 </config>
diff --git a/lib/internal/Magento/Framework/DB/TemporaryTableService.php b/lib/internal/Magento/Framework/DB/TemporaryTableService.php
index 62d1a0d65cfb5c294e6f9b7771366d10cfcc853f..a2c6f6d46515f4fc0011a65069d5c29af629ac31 100644
--- a/lib/internal/Magento/Framework/DB/TemporaryTableService.php
+++ b/lib/internal/Magento/Framework/DB/TemporaryTableService.php
@@ -16,8 +16,21 @@ use Magento\Framework\DB\Select;
  */
 class TemporaryTableService
 {
+    CONST HASH = 'HASH';
+    CONST INNODB = 'INNODB';
+
+    /**
+     * @var string[]
+     */
+    private $allowedIndexMethods;
+
     /**
-     * @var $random
+     * @var string[]
+     */
+    private $allowedEngines;
+
+    /**
+     * @var \Magento\Framework\Math\Random
      */
     private $random;
 
@@ -28,10 +41,17 @@ class TemporaryTableService
 
     /**
      * @param \Magento\Framework\Math\Random $random
+     * @param string[] $allowedIndexMethods
+     * @param string[] $allowedEngines
      */
-    public function __construct(\Magento\Framework\Math\Random $random)
-    {
+    public function __construct(
+        \Magento\Framework\Math\Random $random,
+        $allowedIndexMethods = [self::HASH],
+        $allowedEngines = [self::INNODB]
+    ) {
         $this->random = $random;
+        $this->allowedIndexMethods = $allowedIndexMethods;
+        $this->allowedEngines = $allowedEngines;
     }
 
     /**
@@ -55,16 +75,29 @@ class TemporaryTableService
      * @param AdapterInterface $adapter
      * @param array $indexes
      * @param string $indexMethod
-     * @param string $engine
+     * @param string $dbEngine
      * @return string
+     * @throws \InvalidArgumentException
      */
     public function createFromSelect(
         Select $select,
         AdapterInterface $adapter,
         array $indexes = [],
-        $indexMethod = 'HASH',
-        $engine = 'INNODB'
+        $indexMethod = self::HASH,
+        $dbEngine = self::INNODB
     ) {
+        if (!in_array($indexMethod, $this->allowedIndexMethods)) {
+            throw new \InvalidArgumentException(
+                sprintf('indexMethod must be of type %s', implode(',', $this->allowedIndexMethods))
+            );
+        }
+
+        if (!in_array($dbEngine, $this->allowedEngines)) {
+            throw new \InvalidArgumentException(
+                sprintf('dbEngine must be of type %s', implode(',', $this->allowedEngines))
+            );
+        }
+
         $name = $this->random->getUniqueHash('tmp_select_');
 
         $indexStatements = [];
@@ -90,7 +123,7 @@ class TemporaryTableService
             'CREATE TEMPORARY TABLE %s %s ENGINE=%s IGNORE (%s)',
             $adapter->quoteIdentifier($name),
             $indexStatements ? '(' . implode(',', $indexStatements) . ')' : '',
-            $adapter->quoteIdentifier($engine),
+            $adapter->quoteIdentifier($dbEngine),
             "{$select}"
         );
 
diff --git a/lib/internal/Magento/Framework/DB/Test/Unit/TemporaryTableServiceTest.php b/lib/internal/Magento/Framework/DB/Test/Unit/TemporaryTableServiceTest.php
index 4105fefb5785b0ccac7c403afcdce630b041dd1c..68ccad5e3855df6d947cf3b365f837aaf72c595e 100644
--- a/lib/internal/Magento/Framework/DB/Test/Unit/TemporaryTableServiceTest.php
+++ b/lib/internal/Magento/Framework/DB/Test/Unit/TemporaryTableServiceTest.php
@@ -51,12 +51,39 @@ class TemporaryTableServiceTest extends \PHPUnit_Framework_TestCase
         );
     }
 
+    /**
+     * Run test createFromSelect method
+     *
+     * @return void
+     */
+    public function testCreateFromSelectWithException()
+    {
+        $this->setExpectedException(\InvalidArgumentException::class);
+        $random = 'random_table';
+        $indexes = [
+            ['PRIMARY' => ['primary_column_name']],
+            'CREATE TEMPORARY TABLE random_table (PRIMARY KEY(primary_column_name)) ENGINE=INNODB IGNORE '
+            . '(select * from sometable)'
+        ];
+
+        $this->assertEquals(
+            $random,
+            $this->temporaryTableService->createFromSelect(
+                $this->selectMock,
+                $this->adapterMock,
+                $indexes,
+                TemporaryTableService::HASH . "Other",
+                TemporaryTableService::INNODB . "Other"
+            )
+        );
+    }
+
     /**
      * Run test createFromSelect method
      *
      * @param array $indexes
      * @param string $expectedSelect
-     * @dataProvider getCreateFromSelectTestParameters
+     * @dataProvider createFromSelectDataProvider
      * @return void
      */
     public function testCreateFromSelect($indexes, $expectedSelect)
@@ -115,7 +142,7 @@ class TemporaryTableServiceTest extends \PHPUnit_Framework_TestCase
      * @param string $tableName
      * @param bool $assertion
      *
-     * @dataProvider getDropTableTestParameters
+     * @dataProvider dropTableWhenCreatedTablesArrayNotEmptyDataProvider
      * @return void
      */
     public function testDropTableWhenCreatedTablesArrayNotEmpty($tableName, $assertion)
@@ -135,7 +162,7 @@ class TemporaryTableServiceTest extends \PHPUnit_Framework_TestCase
     /**
      * @return array
      */
-    public function getCreateFromSelectTestParameters()
+    public function createFromSelectDataProvider()
     {
         return [
             [
@@ -170,7 +197,7 @@ class TemporaryTableServiceTest extends \PHPUnit_Framework_TestCase
     /**
      * @return array
      */
-    public function getDropTableTestParameters()
+    public function dropTableWhenCreatedTablesArrayNotEmptyDataProvider()
     {
         return [
             ['tmp_select_table_1', false],