commit e9aa4e18cfb76b37ce00f6f45d507d22e1e89550
Author: Viktor Paladiichuk <vpaladiychuk@magento.com>
Date:   Tue Nov 28 15:29:54 2017 +0200

    MAGETWO-84444: Mview does not work with Staging

diff -Nuar a/vendor/magento/module-catalog-inventory/etc/mview.xml b/vendor/magento/module-catalog-inventory/etc/mview.xml
--- a/vendor/magento/module-catalog-inventory/etc/mview.xml
+++ b/vendor/magento/module-catalog-inventory/etc/mview.xml
@@ -5,10 +5,13 @@
  * See COPYING.txt for license details.
  */
 -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Mview/etc/mview.xsd">
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:noNamespaceSchemaLocation="urn:magento:framework:Mview/etc/mview.xsd">
     <view id="cataloginventory_stock" class="Magento\CatalogInventory\Model\Indexer\Stock" group="indexer">
         <subscriptions>
             <table name="cataloginventory_stock_item" entity_column="product_id" />
+            <table name="catalog_product_entity" entity_column="entity_id" />
+            <table name="catalog_product_entity_int" entity_column="entity_id" />
         </subscriptions>
     </view>
 </config>
diff -Nuar a/vendor/magento/module-indexer/Setup/RecurringData.php b/vendor/magento/module-indexer/Setup/RecurringData.php
new file mode 100644
--- /dev/null
+++ b/vendor/magento/module-indexer/Setup/RecurringData.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Copyright © 2013-2017 Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Indexer\Setup;
+
+use Magento\Framework\Setup\InstallDataInterface;
+use Magento\Framework\Setup\ModuleContextInterface;
+use Magento\Framework\Setup\ModuleDataSetupInterface;
+use Magento\Indexer\Model\IndexerFactory;
+use Magento\Framework\Indexer\ConfigInterface;
+
+/**
+ * Recurring data upgrade for indexer module
+ */
+class RecurringData implements InstallDataInterface
+{
+    /**
+     * @var IndexerFactory
+     */
+    private $indexerFactory;
+
+    /**
+     * @var ConfigInterface
+     */
+    private $configInterface;
+
+    /**
+     * RecurringData constructor.
+     *
+     * @param IndexerFactory $indexerFactory
+     * @param ConfigInterface $configInterface
+     */
+    public function __construct(
+        IndexerFactory $indexerFactory,
+        ConfigInterface $configInterface
+    ) {
+        $this->indexerFactory = $indexerFactory;
+        $this->configInterface = $configInterface;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
+    {
+        foreach (array_keys($this->configInterface->getIndexers()) as $indexerId) {
+            $indexer = $this->indexerFactory->create()->load($indexerId);
+            if ($indexer->isScheduled()) {
+                $indexer->getView()->unsubscribe()->subscribe();
+            }
+        }
+    }
+}
diff -Nuar a/vendor/magento/framework/Mview/Test/Unit/View/SubscriptionTest.php b/vendor/magento/framework/Mview/Test/Unit/View/SubscriptionTest.php
--- a/vendor/magento/framework/Mview/Test/Unit/View/SubscriptionTest.php
+++ b/vendor/magento/framework/Mview/Test/Unit/View/SubscriptionTest.php
@@ -62,7 +62,7 @@ class SubscriptionTest extends \PHPUnit_Framework_TestCase
 
         $this->resourceMock->expects($this->any())
             ->method('getTableName')
-            ->willReturn($this->tableName);
+            ->will($this->returnArgument(0));
 
         $this->model = new Subscription(
             $this->resourceMock,
@@ -89,11 +89,15 @@ class SubscriptionTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals('columnName', $this->model->getColumnName());
     }
 
+    /**
+     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+     */
     public function testCreate()
     {
         $triggerName = 'trigger_name';
         $this->resourceMock->expects($this->atLeastOnce())->method('getTriggerName')->willReturn($triggerName);
         $triggerMock = $this->getMockBuilder('Magento\Framework\DB\Ddl\Trigger')
+            ->setMethods(['setName', 'getName', 'setTime', 'setEvent', 'setTable', 'addStatement'])
             ->disableOriginalConstructor()
             ->getMock();
         $triggerMock->expects($this->exactly(3))
@@ -114,8 +118,35 @@ class SubscriptionTest extends \PHPUnit_Framework_TestCase
             ->method('setTable')
             ->with($this->tableName)
             ->will($this->returnSelf());
-        $triggerMock->expects($this->exactly(6))
+
+        $triggerMock->expects($this->at(4))
+            ->method('addStatement')
+            ->with("INSERT IGNORE INTO test_view_cl (entity_id) VALUES (NEW.columnName);")
+            ->will($this->returnSelf());
+
+        $triggerMock->expects($this->at(5))
+            ->method('addStatement')
+            ->with("INSERT IGNORE INTO other_test_view_cl (entity_id) VALUES (NEW.columnName);")
+            ->will($this->returnSelf());
+
+        $triggerMock->expects($this->at(11))
+            ->method('addStatement')
+            ->with("INSERT IGNORE INTO test_view_cl (entity_id) VALUES (NEW.columnName);")
+            ->will($this->returnSelf());
+
+        $triggerMock->expects($this->at(12))
+            ->method('addStatement')
+            ->with("INSERT IGNORE INTO other_test_view_cl (entity_id) VALUES (NEW.columnName);")
+            ->will($this->returnSelf());
+
+        $triggerMock->expects($this->at(18))
+            ->method('addStatement')
+            ->with("INSERT IGNORE INTO test_view_cl (entity_id) VALUES (OLD.columnName);")
+            ->will($this->returnSelf());
+
+        $triggerMock->expects($this->at(19))
             ->method('addStatement')
+            ->with("INSERT IGNORE INTO other_test_view_cl (entity_id) VALUES (OLD.columnName);")
             ->will($this->returnSelf());
 
         $changelogMock = $this->getMockForAbstractClass(
diff -Nuar a/vendor/magento/framework/Mview/View/Subscription.php b/vendor/magento/framework/Mview/View/Subscription.php
--- a/vendor/magento/framework/Mview/View/Subscription.php
+++ b/vendor/magento/framework/Mview/View/Subscription.php
@@ -10,6 +10,8 @@ namespace Magento\Framework\Mview\View;
 
 use Magento\Framework\App\ResourceConnection;
 use Magento\Framework\DB\Ddl\Trigger;
+use Magento\Framework\DB\Ddl\TriggerFactory;
+use Magento\Framework\Mview\ViewInterface;
 
 class Subscription implements SubscriptionInterface
 {
@@ -21,12 +23,12 @@ class Subscription implements SubscriptionInterface
     protected $connection;
 
     /**
-     * @var \Magento\Framework\DB\Ddl\TriggerFactory
+     * @var TriggerFactory
      */
     protected $triggerFactory;
 
     /**
-     * @var \Magento\Framework\Mview\View\CollectionInterface
+     * @var CollectionInterface
      */
     protected $viewCollection;
 
@@ -58,20 +60,31 @@ class Subscription implements SubscriptionInterface
     protected $resource;
 
     /**
+     * List of columns that can be updated in a subscribed table
+     * without creating a new change log entry
+     *
+     * @var array
+     */
+    private $ignoredUpdateColumns = [];
+
+    /**
      * @param ResourceConnection $resource
-     * @param \Magento\Framework\DB\Ddl\TriggerFactory $triggerFactory
-     * @param \Magento\Framework\Mview\View\CollectionInterface $viewCollection
-     * @param \Magento\Framework\Mview\ViewInterface $view
+     * @param TriggerFactory $triggerFactory
+     * @param CollectionInterface $viewCollection
+     * @param ViewInterface $view
      * @param string $tableName
      * @param string $columnName
+     * @param array $ignoredUpdateColumns
+     * @throws \DomainException
      */
     public function __construct(
         ResourceConnection $resource,
-        \Magento\Framework\DB\Ddl\TriggerFactory $triggerFactory,
-        \Magento\Framework\Mview\View\CollectionInterface $viewCollection,
-        \Magento\Framework\Mview\ViewInterface $view,
+        TriggerFactory $triggerFactory,
+        CollectionInterface $viewCollection,
+        ViewInterface $view,
         $tableName,
-        $columnName
+        $columnName,
+        array $ignoredUpdateColumns = []
     ) {
         $this->connection = $resource->getConnection();
         $this->triggerFactory = $triggerFactory;
@@ -80,12 +93,14 @@ class Subscription implements SubscriptionInterface
         $this->tableName = $tableName;
         $this->columnName = $columnName;
         $this->resource = $resource;
+        $this->ignoredUpdateColumns = $ignoredUpdateColumns;
     }
 
     /**
-     * Create subsciption
+     * Create subscription
      *
-     * @return \Magento\Framework\Mview\View\SubscriptionInterface
+     * @return SubscriptionInterface
+     * @throws \InvalidArgumentException
      */
     public function create()
     {
@@ -102,7 +117,7 @@ class Subscription implements SubscriptionInterface
 
             // Add statements for linked views
             foreach ($this->getLinkedViews() as $view) {
-                /** @var \Magento\Framework\Mview\ViewInterface $view */
+                /** @var ViewInterface $view */
                 $trigger->addStatement($this->buildStatement($event, $view->getChangelog()));
             }
 
@@ -116,7 +131,8 @@ class Subscription implements SubscriptionInterface
     /**
      * Remove subscription
      *
-     * @return \Magento\Framework\Mview\View\SubscriptionInterface
+     * @return SubscriptionInterface
+     * @throws \InvalidArgumentException
      */
     public function remove()
     {
@@ -131,7 +147,7 @@ class Subscription implements SubscriptionInterface
 
             // Add statements for linked views
             foreach ($this->getLinkedViews() as $view) {
-                /** @var \Magento\Framework\Mview\ViewInterface $view */
+                /** @var ViewInterface $view */
                 $trigger->addStatement($this->buildStatement($event, $view->getChangelog()));
             }
 
@@ -154,10 +170,10 @@ class Subscription implements SubscriptionInterface
     protected function getLinkedViews()
     {
         if (!$this->linkedViews) {
-            $viewList = $this->viewCollection->getViewsByStateMode(\Magento\Framework\Mview\View\StateInterface::MODE_ENABLED);
+            $viewList = $this->viewCollection->getViewsByStateMode(StateInterface::MODE_ENABLED);
 
             foreach ($viewList as $view) {
-                /** @var \Magento\Framework\Mview\ViewInterface $view */
+                /** @var ViewInterface $view */
                 // Skip the current view
                 if ($view->getId() == $this->getView()->getId()) {
                     continue;
@@ -175,35 +191,58 @@ class Subscription implements SubscriptionInterface
     }
 
     /**
-     * Build trigger statement for INSER, UPDATE, DELETE events
+     * Build trigger statement for INSERT, UPDATE, DELETE events
      *
      * @param string $event
-     * @param \Magento\Framework\Mview\View\ChangelogInterface $changelog
+     * @param ChangelogInterface $changelog
      * @return string
      */
     protected function buildStatement($event, $changelog)
     {
         switch ($event) {
             case Trigger::EVENT_INSERT:
+                $trigger = 'INSERT IGNORE INTO %s (%s) VALUES (NEW.%s);';
+                break;
+
             case Trigger::EVENT_UPDATE:
-                return sprintf(
-                    "INSERT IGNORE INTO %s (%s) VALUES (NEW.%s);",
-                    $this->connection->quoteIdentifier($this->resource->getTableName($changelog->getName())),
-                    $this->connection->quoteIdentifier($changelog->getColumnName()),
-                    $this->connection->quoteIdentifier($this->getColumnName())
-                );
+                $trigger = 'INSERT IGNORE INTO %s (%s) VALUES (NEW.%s);';
+
+                if ($this->connection->isTableExists($this->getTableName())
+                    && $describe = $this->connection->describeTable($this->getTableName())
+                ) {
+                    $columnNames = array_column($describe, 'COLUMN_NAME');
+                    $columnNames = array_diff($columnNames, $this->ignoredUpdateColumns);
+                    if ($columnNames) {
+                        $columns = [];
+                        foreach ($columnNames as $columnName) {
+                            $columns[] = sprintf(
+                                'NEW.%1$s != OLD.%1$s',
+                                $this->connection->quoteIdentifier($columnName)
+                            );
+                        }
+                        $trigger = sprintf(
+                            "IF (%s) THEN %s END IF;",
+                            implode(' OR ', $columns),
+                            $trigger
+                        );
+                    }
+                }
+                break;
 
             case Trigger::EVENT_DELETE:
-                return sprintf(
-                    "INSERT IGNORE INTO %s (%s) VALUES (OLD.%s);",
-                    $this->connection->quoteIdentifier($this->resource->getTableName($changelog->getName())),
-                    $this->connection->quoteIdentifier($changelog->getColumnName()),
-                    $this->connection->quoteIdentifier($this->getColumnName())
-                );
+                $trigger = 'INSERT IGNORE INTO %s (%s) VALUES (OLD.%s);';
+                break;
 
             default:
                 return '';
         }
+
+        return sprintf(
+            $trigger,
+            $this->connection->quoteIdentifier($this->resource->getTableName($changelog->getName())),
+            $this->connection->quoteIdentifier($changelog->getColumnName()),
+            $this->connection->quoteIdentifier($this->getColumnName())
+        );
     }
 
     /**
@@ -225,7 +264,7 @@ class Subscription implements SubscriptionInterface
     /**
      * Retrieve View related to subscription
      *
-     * @return \Magento\Framework\Mview\ViewInterface
+     * @return ViewInterface
      * @codeCoverageIgnore
      */
     public function getView()
diff -Nuar a/vendor/magento/framework/Mview/etc/mview.xsd b/vendor/magento/framework/Mview/etc/mview.xsd
--- a/vendor/magento/framework/Mview/etc/mview.xsd
+++ b/vendor/magento/framework/Mview/etc/mview.xsd
@@ -106,7 +106,7 @@
     <xs:simpleType name="subscriptionModelType">
         <xs:annotation>
             <xs:documentation>
-                Subscription model must be a valid PHP class or interface name.
+                DEPRECATED. Subscription model must be a valid PHP class or interface name.
             </xs:documentation>
         </xs:annotation>
         <xs:restriction base="xs:string">
commit a85bf456be38fa943e4144309cd330e199d1e4b6
Author: Viktor Paladiichuk <vpaladiychuk@magento.com>
Date:   Tue Nov 28 15:30:48 2017 +0200

    MAGETWO-84444: Mview does not work with Staging

diff -Nuar a/vendor/magento/module-catalog-staging/Model/Mview/View/Category/Attribute/Subscription.php b/vendor/magento/module-catalog-staging/Model/Mview/View/Category/Attribute/Subscription.php
--- a/vendor/magento/module-catalog-staging/Model/Mview/View/Category/Attribute/Subscription.php
+++ b/vendor/magento/module-catalog-staging/Model/Mview/View/Category/Attribute/Subscription.php
@@ -6,22 +6,16 @@
 namespace Magento\CatalogStaging\Model\Mview\View\Category\Attribute;
 
 use Magento\Catalog\Api\Data\CategoryInterface;
-use Magento\Framework\DB\Ddl\Trigger;
 use Magento\Framework\App\ResourceConnection;
 use Magento\Framework\EntityManager\MetadataPool;
 
 /**
- * Class Subscription
+ * Class Subscription implements statement building for staged category entity attribute subscription
  * @package Magento\CatalogStaging\Model\Mview\View\Category\Attribute
  */
-class Subscription extends \Magento\Framework\Mview\View\Subscription
+class Subscription extends \Magento\CatalogStaging\Model\Mview\View\Attribute\Subscription
 {
     /**
-     * @var \Magento\Framework\EntityManager\EntityMetadata
-     */
-    protected $entityMetadata;
-
-    /**
      * @param ResourceConnection $resource
      * @param \Magento\Framework\DB\Ddl\TriggerFactory $triggerFactory
      * @param \Magento\Framework\Mview\View\CollectionInterface $viewCollection
@@ -29,7 +23,8 @@ class Subscription extends \Magento\Framework\Mview\View\Subscription
      * @param string $tableName
      * @param string $columnName
      * @param MetadataPool $metadataPool
-     * @throws \Exception
+     * @param string|null $entityInterface
+     * @param array $ignoredUpdateColumns
      */
     public function __construct(
         ResourceConnection $resource,
@@ -38,50 +33,20 @@ class Subscription extends \Magento\Framework\Mview\View\Subscription
         \Magento\Framework\Mview\ViewInterface $view,
         $tableName,
         $columnName,
-        MetadataPool $metadataPool
+        MetadataPool $metadataPool,
+        $entityInterface = CategoryInterface::class,
+        $ignoredUpdateColumns = []
     ) {
-        parent::__construct($resource, $triggerFactory, $viewCollection, $view, $tableName, $columnName);
-        $this->entityMetadata = $metadataPool->getMetadata(CategoryInterface::class);
-    }
-
-    /**
-     * Build trigger statement for INSERT, UPDATE, DELETE events
-     *
-     * @param string $event
-     * @param \Magento\Framework\Mview\View\ChangelogInterface $changelog
-     * @return string
-     */
-    protected function buildStatement($event, $changelog)
-    {
-        $triggerBody = null;
-        switch ($event) {
-            case Trigger::EVENT_INSERT:
-            case Trigger::EVENT_UPDATE:
-                $triggerBody = "INSERT IGNORE INTO %1\$s (%2\$s) SELECT %3\$s FROM %4\$s WHERE %5\$s = NEW.%5\$s;";
-                break;
-            case Trigger::EVENT_DELETE:
-                $triggerBody = "INSERT IGNORE INTO %1\$s (%2\$s) SELECT %3\$s FROM %4\$s WHERE %5\$s = OLD.%5\$s;";
-                break;
-            default:
-                break;
-        }
-        $params = [
-            $this->connection->quoteIdentifier(
-                $this->resource->getTableName($changelog->getName())
-            ),
-            $this->connection->quoteIdentifier(
-                $changelog->getColumnName()
-            ),
-            $this->connection->quoteIdentifier(
-                $this->entityMetadata->getIdentifierField()
-            ),
-            $this->connection->quoteIdentifier(
-                $this->resource->getTableName($this->entityMetadata->getEntityTable())
-            ),
-            $this->connection->quoteIdentifier(
-                $this->entityMetadata->getLinkField()
-            )
-        ];
-        return vsprintf($triggerBody, $params);
+        parent::__construct(
+            $resource,
+            $triggerFactory,
+            $viewCollection,
+            $view,
+            $tableName,
+            $columnName,
+            $metadataPool,
+            $entityInterface,
+            $ignoredUpdateColumns
+        );
     }
 }
diff -Nuar a/vendor/magento/module-catalog-staging/Model/Mview/View/SubscriptionFactory.php b/vendor/magento/module-catalog-staging/Model/Mview/View/SubscriptionFactory.php
--- a/vendor/magento/module-catalog-staging/Model/Mview/View/SubscriptionFactory.php
+++ b/vendor/magento/module-catalog-staging/Model/Mview/View/SubscriptionFactory.php
@@ -11,34 +11,43 @@ class SubscriptionFactory extends FrameworkSubscriptionFactory
 {
     /**
      * @var array
+     * @deprecated 2.2.0
      */
     private $stagingEntityTables = ['catalog_product_entity', 'catalog_category_entity'];
 
     /**
      * @var array
+     * @deprecated 2.2.0
      */
     private $versionTables;
 
     /**
+     * @var string[]
+     */
+    private $subscriptionModels = [];
+
+    /**
      * @param \Magento\Framework\ObjectManagerInterface $objectManager
      * @param \Magento\CatalogStaging\Model\VersionTables $versionTables
+     * @param array $subscriptionModels
      */
     public function __construct(
         \Magento\Framework\ObjectManagerInterface $objectManager,
-        \Magento\CatalogStaging\Model\VersionTables $versionTables
+        \Magento\CatalogStaging\Model\VersionTables $versionTables,
+        $subscriptionModels = []
     ) {
         parent::__construct($objectManager);
         $this->versionTables = $versionTables;
+        $this->subscriptionModels = $subscriptionModels;
     }
 
     /**
-     * @param array $data
-     * @return \Magento\Framework\Mview\View\CollectionInterface
+     * {@inheritdoc}
      */
     public function create(array $data = [])
     {
-        if ($this->isStagingTable($data)) {
-            $data['columnName'] = 'row_id';
+        if (isset($data['tableName']) && isset($this->subscriptionModels[$data['tableName']])) {
+            $data['subscriptionModel'] = $this->subscriptionModels[$data['tableName']];
         }
         return parent::create($data);
     }
@@ -46,6 +55,7 @@ class SubscriptionFactory extends FrameworkSubscriptionFactory
     /**
      * @param array $data
      * @return bool
+     * @deprecated
      */
     protected function isStagingTable(array $data = [])
     {
diff -Nuar a/vendor/magento/module-catalog-staging/Model/VersionTables.php b/vendor/magento/module-catalog-staging/Model/VersionTables.php
--- a/vendor/magento/module-catalog-staging/Model/VersionTables.php
+++ b/vendor/magento/module-catalog-staging/Model/VersionTables.php
@@ -5,6 +5,11 @@
  */
 namespace Magento\CatalogStaging\Model;
 
+/**
+ * Class VersionTables stores information about staged tables.
+ *
+ * @package Magento\CatalogStaging\Model
+ */
 class VersionTables extends \Magento\Framework\DataObject
 {
     /**
diff -Nuar a/vendor/magento/module-catalog-staging/Test/Unit/Model/Mview/View/SubscriptionFactoryTest.php b/vendor/magento/module-catalog-staging/Test/Unit/Model/Mview/View/SubscriptionFactoryTest.php
--- a/vendor/magento/module-catalog-staging/Test/Unit/Model/Mview/View/SubscriptionFactoryTest.php
+++ b/vendor/magento/module-catalog-staging/Test/Unit/Model/Mview/View/SubscriptionFactoryTest.php
@@ -17,11 +17,6 @@ class SubscriptionFactoryTest extends \PHPUnit_Framework_TestCase
     protected $objectManagerMock;
 
     /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $versionTablesrMock;
-
-    /**
      * @var \Magento\CatalogStaging\Model\Mview\View\SubscriptionFactory
      */
     protected $model;
@@ -29,110 +24,45 @@ class SubscriptionFactoryTest extends \PHPUnit_Framework_TestCase
     protected function setUp()
     {
         $objectManager = new ObjectManager($this);
-
-        $this->objectManagerMock = $this->getMockBuilder('Magento\Framework\ObjectManagerInterface')
-            ->disableOriginalConstructor()
-            ->getMock();
-        $this->versionTablesrMock = $this->getMockBuilder('Magento\CatalogStaging\Model\VersionTables')
+        $this->objectManagerMock = $this->getMockBuilder(\Magento\Framework\ObjectManagerInterface::class)
             ->disableOriginalConstructor()
             ->getMock();
         $this->model = $objectManager->getObject(
             SubscriptionFactory::class,
             [
                 'objectManager' => $this->objectManagerMock,
-                'versionTables' => $this->versionTablesrMock
+                'subscriptionModels' => [
+                    'catalog_product_entity_int' => 'ProductEntityIntSubscription'
+                ]
             ]
         );
     }
-
     public function testCreate()
     {
         $data = ['tableName' => 'catalog_product_entity_int', 'columnName' => 'entity_id'];
-        $versionTables = ['catalog_product_entity_int'];
-
         $expectedData = $data;
-        $expectedData['columnName'] = 'row_id';
-
-        $this->versionTablesrMock->expects($this->once())
-            ->method('getVersionTables')
-            ->willReturn($versionTables);
-        $subscriptionMock = $this->getMockBuilder('Magento\Framework\Mview\View\SubscriptionInterface')
+        $expectedData['columnName'] = 'entity_id';
+        $subscriptionMock = $this->getMockBuilder(\Magento\Framework\Mview\View\SubscriptionInterface::class)
             ->disableOriginalConstructor()
             ->getMock();
         $this->objectManagerMock->expects($this->once())
             ->method('create')
-            ->with(FrameworkSubstrictionFactory::INSTANCE_NAME, $expectedData)
+            ->with('ProductEntityIntSubscription', $expectedData)
             ->willReturn($subscriptionMock);
-
         $result = $this->model->create($data);
         $this->assertEquals($subscriptionMock, $result);
     }
-
     public function testCreateNoTableName()
     {
         $data = ['columnName' => 'entity_id'];
-
-        $expectedData = $data;
-
-        $subscriptionMock = $this->getMockBuilder('Magento\Framework\Mview\View\SubscriptionInterface')
-            ->disableOriginalConstructor()
-            ->getMock();
-        $this->objectManagerMock->expects($this->once())
-            ->method('create')
-            ->with(FrameworkSubstrictionFactory::INSTANCE_NAME, $expectedData)
-            ->willReturn($subscriptionMock);
-
-        $result = $this->model->create($data);
-        $this->assertEquals($subscriptionMock, $result);
-    }
-
-    /**
-     * @param $stagingEntityTable
-     * @dataProvider tablesDataProvider
-     */
-    public function testCreateStagingEntityTables($stagingEntityTable)
-    {
-        $data = ['tableName' => $stagingEntityTable, 'columnName' => 'entity_id'];
-
         $expectedData = $data;
-        $subscriptionMock = $this->getMockBuilder('Magento\Framework\Mview\View\SubscriptionInterface')
+        $subscriptionMock = $this->getMockBuilder(\Magento\Framework\Mview\View\SubscriptionInterface::class)
             ->disableOriginalConstructor()
             ->getMock();
         $this->objectManagerMock->expects($this->once())
             ->method('create')
             ->with(FrameworkSubstrictionFactory::INSTANCE_NAME, $expectedData)
             ->willReturn($subscriptionMock);
-
-        $result = $this->model->create($data);
-        $this->assertEquals($subscriptionMock, $result);
-    }
-
-    public static function tablesDataProvider()
-    {
-        return [
-            ['catalog_product_entity'],
-            ['catalog_category_entity']
-        ];
-    }
-
-    public function testCreateNoVersionTable()
-    {
-        $data = ['tableName' => 'not_existed_table', 'columnName' => 'entity_id'];
-        $versionTables = ['catalog_product_entity_int'];
-
-        $expectedData = $data;
-
-        $this->versionTablesrMock->expects($this->once())
-            ->method('getVersionTables')
-            ->willReturn($versionTables);
-        $subscriptionMock = $this->getMockBuilder('Magento\Framework\Mview\View\SubscriptionInterface')
-            ->disableOriginalConstructor()
-            ->getMock();
-        $this->objectManagerMock->expects($this->once())
-            ->method('create')
-            ->with(FrameworkSubstrictionFactory::INSTANCE_NAME, $expectedData)
-            ->willReturn($subscriptionMock);
-
         $result = $this->model->create($data);
         $this->assertEquals($subscriptionMock, $result);
     }
diff -Nuar a/vendor/magento/module-catalog-staging/etc/di.xml b/vendor/magento/module-catalog-staging/etc/di.xml
--- a/vendor/magento/module-catalog-staging/etc/di.xml
+++ b/vendor/magento/module-catalog-staging/etc/di.xml
@@ -56,6 +56,35 @@
             </argument>
         </arguments>
     </type>
+    <virtualType name="stagedCategoryAttributeSubscription" type="Magento\CatalogStaging\Model\Mview\View\Attribute\Subscription">
+        <arguments>
+            <argument name="entityInterface" xsi:type="string">Magento\Catalog\Api\Data\CategoryInterface</argument>
+        </arguments>
+    </virtualType>
+    <virtualType name="stagedProductAttributeSubscription" type="Magento\CatalogStaging\Model\Mview\View\Attribute\Subscription">
+        <arguments>
+            <argument name="entityInterface" xsi:type="string">Magento\Catalog\Api\Data\ProductInterface</argument>
+        </arguments>
+    </virtualType>
+    <type name="Magento\CatalogStaging\Model\Mview\View\SubscriptionFactory">
+        <arguments>
+            <argument name="subscriptionModels" xsi:type="array">
+                <item name="catalog_category_entity_decimal" xsi:type="string">stagedCategoryAttributeSubscription</item>
+                <item name="catalog_category_entity_int" xsi:type="string">stagedCategoryAttributeSubscription</item>
+                <item name="catalog_category_entity_text" xsi:type="string">stagedCategoryAttributeSubscription</item>
+                <item name="catalog_category_entity_varchar" xsi:type="string">stagedCategoryAttributeSubscription</item>
+                <item name="catalog_category_entity_datetime" xsi:type="string">stagedCategoryAttributeSubscription</item>
+                <item name="catalog_product_entity_datetime" xsi:type="string">stagedProductAttributeSubscription</item>
+                <item name="catalog_product_entity_decimal" xsi:type="string">stagedProductAttributeSubscription</item>
+                <item name="catalog_product_entity_int" xsi:type="string">stagedProductAttributeSubscription</item>
+                <item name="catalog_product_entity_gallery" xsi:type="string">stagedProductAttributeSubscription</item>
+                <item name="catalog_product_entity_media_gallery_value" xsi:type="string">stagedProductAttributeSubscription</item>
+                <item name="catalog_product_entity_text" xsi:type="string">stagedProductAttributeSubscription</item>
+                <item name="catalog_product_entity_tier_price" xsi:type="string">stagedProductAttributeSubscription</item>
+                <item name="catalog_product_entity_varchar" xsi:type="string">stagedProductAttributeSubscription</item>
+            </argument>
+        </arguments>
+    </type>
     <type name="Magento\CatalogStaging\Helper\ReindexPool">
         <arguments>
             <argument name="reindexPool" xsi:type="array">
diff -Nuar a/vendor/magento/module-catalog-staging/etc/mview.xml b/vendor/magento/module-catalog-staging/etc/mview.xml
deleted file mode 100644
--- a/vendor/magento/module-catalog-staging/etc/mview.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/**
- * Copyright © 2013-2017 Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Mview/etc/mview.xsd">
-    <view id="catalog_category_flat" class="Magento\Catalog\Model\Indexer\Category\Flat" group="indexer">
-        <subscriptions>
-            <table name="catalog_category_entity_decimal" entity_column="entity_id" subscription_model="Magento\CatalogStaging\Model\Mview\View\Category\Attribute\Subscription" />
-            <table name="catalog_category_entity_int" entity_column="entity_id" subscription_model="Magento\CatalogStaging\Model\Mview\View\Category\Attribute\Subscription" />
-            <table name="catalog_category_entity_text" entity_column="entity_id" subscription_model="Magento\CatalogStaging\Model\Mview\View\Category\Attribute\Subscription" />
-            <table name="catalog_category_entity_varchar" entity_column="entity_id" subscription_model="Magento\CatalogStaging\Model\Mview\View\Category\Attribute\Subscription" />
-            <table name="catalog_category_entity_datetime" entity_column="entity_id" subscription_model="Magento\CatalogStaging\Model\Mview\View\Category\Attribute\Subscription" />
-        </subscriptions>
-    </view>
-    <view id="catalog_category_product" class="Magento\Catalog\Model\Indexer\Category\Product" group="indexer">
-        <subscriptions>
-            <table name="catalog_category_entity_int" entity_column="entity_id" subscription_model="Magento\CatalogStaging\Model\Mview\View\Category\Attribute\Subscription" />
-        </subscriptions>
-    </view>
-</config>
commit 0193f89517fc864c9ab5acd4b518f03b2c796a2f
Author: Viktor Paladiichuk <vpaladiychuk@magento.com>
Date:   Tue Nov 28 15:45:17 2017 +0200

    MAGETWO-84444: Mview does not work with Staging

diff -Nuar a/vendor/magento/module-catalog-staging/Model/Mview/View/Attribute/Subscription.php b/vendor/magento/module-catalog-staging/Model/Mview/View/Attribute/Subscription.php
new file mode 100644
--- /dev/null
+++ b/vendor/magento/module-catalog-staging/Model/Mview/View/Attribute/Subscription.php
@@ -0,0 +1,100 @@
+<?php
+/**
+ * Copyright © 2013-2017 Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\CatalogStaging\Model\Mview\View\Attribute;
+
+use Magento\Framework\DB\Ddl\Trigger;
+use Magento\Framework\App\ResourceConnection;
+use Magento\Framework\EntityManager\MetadataPool;
+
+/**
+ * Class Subscription implements statement building for staged entity attribute subscription
+ *
+ * @package Magento\CatalogStaging\Model\Mview\View\Attribute
+ */
+class Subscription extends \Magento\Framework\Mview\View\Subscription
+{
+    /**
+     * @var \Magento\Framework\EntityManager\EntityMetadata
+     */
+    protected $entityMetadata;
+
+    /**
+     * @param ResourceConnection $resource
+     * @param \Magento\Framework\DB\Ddl\TriggerFactory $triggerFactory
+     * @param \Magento\Framework\Mview\View\CollectionInterface $viewCollection
+     * @param \Magento\Framework\Mview\ViewInterface $view
+     * @param string $tableName
+     * @param string $columnName
+     * @param MetadataPool $metadataPool
+     * @param string|null $entityInterface
+     * @param array $ignoredUpdateColumns
+     * @throws \Exception
+     * @throws \DomainException
+     */
+    public function __construct(
+        ResourceConnection $resource,
+        \Magento\Framework\DB\Ddl\TriggerFactory $triggerFactory,
+        \Magento\Framework\Mview\View\CollectionInterface $viewCollection,
+        \Magento\Framework\Mview\ViewInterface $view,
+        $tableName,
+        $columnName,
+        MetadataPool $metadataPool,
+        $entityInterface = null,
+        $ignoredUpdateColumns = []
+    ) {
+        parent::__construct(
+            $resource,
+            $triggerFactory,
+            $viewCollection,
+            $view,
+            $tableName,
+            $columnName,
+            $ignoredUpdateColumns
+        );
+        $this->entityMetadata = $metadataPool->getMetadata($entityInterface);
+    }
+
+    /**
+     * Build trigger statement for INSERT, UPDATE, DELETE events
+     *
+     * @param string $event
+     * @param \Magento\Framework\Mview\View\ChangelogInterface $changelog
+     * @return string
+     */
+    protected function buildStatement($event, $changelog)
+    {
+        $triggerBody = null;
+        switch ($event) {
+            case Trigger::EVENT_INSERT:
+            case Trigger::EVENT_UPDATE:
+                $triggerBody = "INSERT IGNORE INTO %1\$s (%2\$s) SELECT %3\$s FROM %4\$s WHERE %5\$s = NEW.%5\$s;";
+                break;
+            case Trigger::EVENT_DELETE:
+                $triggerBody = "INSERT IGNORE INTO %1\$s (%2\$s) SELECT %3\$s FROM %4\$s WHERE %5\$s = OLD.%5\$s;";
+                break;
+            default:
+                break;
+        }
+        $params = [
+            $this->connection->quoteIdentifier(
+                $this->resource->getTableName($changelog->getName())
+            ),
+            $this->connection->quoteIdentifier(
+                $changelog->getColumnName()
+            ),
+            $this->connection->quoteIdentifier(
+                $this->entityMetadata->getIdentifierField()
+            ),
+            $this->connection->quoteIdentifier(
+                $this->resource->getTableName($this->entityMetadata->getEntityTable())
+            ),
+            $this->connection->quoteIdentifier(
+                $this->entityMetadata->getLinkField()
+            )
+        ];
+        return vsprintf($triggerBody, $params);
+    }
+}
commit a0dc6a745002eacaaf2ef57e37a25f79f65de650
Author: Viktor Paladiichuk <vpaladiychuk@magento.com>
Date:   Tue Nov 28 15:54:17 2017 +0200

    MAGETWO-84444: Mview does not work with Staging

diff -Nuar a/vendor/magento/module-catalog-staging/Test/Unit/Model/Mview/View/Attribute/SubscriptionTest.php b/vendor/magento/module-catalog-staging/Test/Unit/Model/Mview/View/Attribute/SubscriptionTest.php
new file mode 100644
--- /dev/null
+++ b/vendor/magento/module-catalog-staging/Test/Unit/Model/Mview/View/Attribute/SubscriptionTest.php
@@ -0,0 +1,302 @@
+<?php
+/**
+ * Copyright © 2013-2017 Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\CatalogStaging\Test\Unit\Model\Mview\View\Attribute;
+
+use Magento\CatalogStaging\Model\Mview\View\Attribute\Subscription as SubscriptionModel;
+use Magento\Framework\App\ResourceConnection;
+use Magento\Framework\DB\Adapter\Pdo\Mysql;
+use Magento\Framework\DB\Ddl\TriggerFactory;
+use Magento\Framework\EntityManager\EntityMetadataInterface;
+use Magento\Framework\EntityManager\MetadataPool;
+use Magento\Framework\Mview\View\CollectionInterface;
+use Magento\Framework\Mview\View\StateInterface;
+use Magento\Framework\Mview\ViewInterface;
+
+/**
+ * Class SubscriptionTest - unit test for attribute subscription model
+ * @package Magento\CatalogStaging\Test\Unit\Model\Mview\View\Attribute
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
+class SubscriptionTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * Mysql PDO DB adapter mock
+     *
+     * @var \PHPUnit_Framework_MockObject_MockObject|Mysql
+     */
+    protected $connectionMock;
+
+    /**
+     * @var SubscriptionModel
+     */
+    protected $model;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|ResourceConnection
+     */
+    protected $resourceMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|TriggerFactory
+     */
+    protected $triggerFactoryMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|CollectionInterface
+     */
+    protected $viewCollectionMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|ViewInterface
+     */
+    protected $viewMock;
+
+    /**
+     * @var string
+     */
+    private $tableName;
+
+    /**
+     * @var EntityMetadataInterface
+     */
+    private $entityMetadataMock;
+
+    /**
+     * @var MetadataPool
+     */
+    private $entityMetadataPoolMock;
+
+    protected function setUp()
+    {
+        $this->connectionMock = $this->getMock(Mysql::class, [], [], '', false);
+        $this->resourceMock = $this->getMock(ResourceConnection::class, [], [], '', false, false);
+        $this->connectionMock->expects($this->any())
+            ->method('quoteIdentifier')
+            ->will($this->returnArgument(0));
+        $this->resourceMock->expects($this->atLeastOnce())
+            ->method('getConnection')
+            ->willReturn($this->connectionMock);
+        $this->triggerFactoryMock = $this->getMock(TriggerFactory::class, [], [], '', false, false);
+        $this->viewCollectionMock = $this->getMockForAbstractClass(
+            CollectionInterface::class,
+            [],
+            '',
+            false,
+            false,
+            true,
+            []
+        );
+        $this->viewMock = $this->getMockForAbstractClass(ViewInterface::class, [], '', false, false, true, []);
+        $this->resourceMock->expects($this->any())
+            ->method('getTableName')
+            ->will($this->returnArgument(0));
+
+        $entityInterface = 'EntityInterface';
+        $this->entityMetadataPoolMock = $this->getMock(MetadataPool::class, [], [], '', false);
+
+        $this->entityMetadataMock = $this->getMock(EntityMetadataInterface::class, [], [], '', false);
+        $this->entityMetadataMock->expects($this->any())
+            ->method('getEntityTable')
+            ->will($this->returnValue('entity_table'));
+
+        $this->entityMetadataMock->expects($this->any())
+            ->method('getIdentifierField')
+            ->will($this->returnValue('entity_identifier'));
+
+        $this->entityMetadataMock->expects($this->any())
+            ->method('getLinkField')
+            ->will($this->returnValue('entity_link_field'));
+
+        $this->entityMetadataPoolMock->expects($this->any())
+            ->method('getMetadata')
+            ->with($entityInterface)
+            ->will($this->returnValue($this->entityMetadataMock));
+
+        $this->model = new SubscriptionModel(
+            $this->resourceMock,
+            $this->triggerFactoryMock,
+            $this->viewCollectionMock,
+            $this->viewMock,
+            $this->tableName,
+            'columnName',
+            $this->entityMetadataPoolMock,
+            $entityInterface
+        );
+    }
+
+    /**
+     * Prepare trigger mock
+     *
+     * @param string $triggerName
+     * @return \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected function prepareTriggerMock($triggerName)
+    {
+        $triggerMock = $this->getMockBuilder(\Magento\Framework\DB\Ddl\Trigger::class)
+            ->setMethods(['setName', 'getName', 'setTime', 'setEvent', 'setTable', 'addStatement'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $triggerMock->expects($this->exactly(3))
+            ->method('setName')
+            ->with($triggerName)
+            ->will($this->returnSelf());
+        $triggerMock->expects($this->exactly(3))
+            ->method('getName')
+            ->will($this->returnValue('triggerName'));
+        $triggerMock->expects($this->exactly(3))
+            ->method('setTime')
+            ->with(\Magento\Framework\DB\Ddl\Trigger::TIME_AFTER)
+            ->will($this->returnSelf());
+        $triggerMock->expects($this->exactly(3))
+            ->method('setEvent')
+            ->will($this->returnSelf());
+        $triggerMock->expects($this->exactly(3))
+            ->method('setTable')
+            ->with($this->tableName)
+            ->will($this->returnSelf());
+        return $triggerMock;
+    }
+
+    /**
+     * Prepare expected trigger call map
+     *
+     * @param \PHPUnit_Framework_MockObject_MockObject $triggerMock
+     * @return \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected function prepareTriggerTestCallMap(\PHPUnit_Framework_MockObject_MockObject $triggerMock)
+    {
+        $triggerMock->expects($this->at(4))
+            ->method('addStatement')
+            ->with(
+                "INSERT IGNORE INTO test_view_cl (entity_id) "
+                . "SELECT entity_identifier FROM entity_table WHERE entity_link_field = NEW.entity_link_field;"
+            )
+            ->will($this->returnSelf());
+
+        $triggerMock->expects($this->at(5))
+            ->method('addStatement')
+            ->with(
+                "INSERT IGNORE INTO other_test_view_cl (entity_id) "
+                . "SELECT entity_identifier FROM entity_table WHERE entity_link_field = NEW.entity_link_field;"
+            )->will($this->returnSelf());
+
+        $triggerMock->expects($this->at(11))
+            ->method('addStatement')
+            ->with(
+                "INSERT IGNORE INTO test_view_cl (entity_id) "
+                . "SELECT entity_identifier FROM entity_table WHERE entity_link_field = NEW.entity_link_field;"
+            )->will($this->returnSelf());
+
+        $triggerMock->expects($this->at(12))
+            ->method('addStatement')
+            ->with(
+                "INSERT IGNORE INTO other_test_view_cl (entity_id) "
+                . "SELECT entity_identifier FROM entity_table WHERE entity_link_field = NEW.entity_link_field;"
+            )->will($this->returnSelf());
+
+        $triggerMock->expects($this->at(18))
+            ->method('addStatement')
+            ->with(
+                "INSERT IGNORE INTO test_view_cl (entity_id) "
+                . "SELECT entity_identifier FROM entity_table WHERE entity_link_field = OLD.entity_link_field;"
+            )->will($this->returnSelf());
+
+        $triggerMock->expects($this->at(19))
+            ->method('addStatement')
+            ->with(
+                "INSERT IGNORE INTO other_test_view_cl (entity_id) "
+                . "SELECT entity_identifier FROM entity_table WHERE entity_link_field = OLD.entity_link_field;"
+            )->will($this->returnSelf());
+
+        return $triggerMock;
+    }
+
+    /**
+     * Prepare changelog mock
+     *
+     * @param string $changelogName
+     * @return \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected function prepareChangelogMock($changelogName)
+    {
+        $changelogMock = $this->getMockForAbstractClass(
+            \Magento\Framework\Mview\View\ChangelogInterface::class,
+            [],
+            '',
+            false,
+            false,
+            true,
+            []
+        );
+        $changelogMock->expects($this->exactly(3))
+            ->method('getName')
+            ->will($this->returnValue($changelogName));
+        $changelogMock->expects($this->exactly(3))
+            ->method('getColumnName')
+            ->will($this->returnValue('entity_id'));
+        return $changelogMock;
+    }
+
+    public function testCreate()
+    {
+        $triggerName = 'trigger_name';
+        $this->resourceMock->expects($this->atLeastOnce())->method('getTriggerName')->willReturn($triggerName);
+        $triggerMock = $this->prepareTriggerMock($triggerName);
+        $this->prepareTriggerTestCallMap($triggerMock);
+        $changelogMock = $this->prepareChangelogMock('test_view_cl');
+
+        $this->viewMock->expects($this->exactly(3))
+            ->method('getChangelog')
+            ->will($this->returnValue($changelogMock));
+
+        $this->triggerFactoryMock->expects($this->exactly(3))
+            ->method('create')
+            ->will($this->returnValue($triggerMock));
+
+        $otherChangelogMock = $this->prepareChangelogMock('other_test_view_cl');
+
+        $otherViewMock = $this->getMockForAbstractClass(
+            ViewInterface::class,
+            [],
+            '',
+            false,
+            false,
+            true,
+            []
+        );
+        $otherViewMock->expects($this->exactly(1))
+            ->method('getId')
+            ->will($this->returnValue('other_id'));
+        $otherViewMock->expects($this->exactly(1))
+            ->method('getSubscriptions')
+            ->will($this->returnValue([['name' => $this->tableName], ['name' => 'otherTableName']]));
+        $otherViewMock->expects($this->any())
+            ->method('getChangelog')
+            ->will($this->returnValue($otherChangelogMock));
+
+        $this->viewMock->expects($this->exactly(3))
+            ->method('getId')
+            ->will($this->returnValue('this_id'));
+        $this->viewMock->expects($this->never())
+            ->method('getSubscriptions');
+
+        $this->viewCollectionMock->expects($this->exactly(1))
+            ->method('getViewsByStateMode')
+            ->with(StateInterface::MODE_ENABLED)
+            ->will($this->returnValue([$this->viewMock, $otherViewMock]));
+
+        $this->connectionMock->expects($this->exactly(3))
+            ->method('dropTrigger')
+            ->with('triggerName')
+            ->will($this->returnValue(true));
+        $this->connectionMock->expects($this->exactly(3))
+            ->method('createTrigger')
+            ->with($triggerMock);
+
+        $this->model->create();
+    }
+}
