diff --git a/vendor/magento/module-catalog/Setup/Patch/Data/UpdateMultiselectAttributesBackendTypes.php b/vendor/magento/module-catalog/Setup/Patch/Data/UpdateMultiselectAttributesBackendTypes.php index 846784718d02..baa69c473201 100644 --- a/vendor/magento/module-catalog/Setup/Patch/Data/UpdateMultiselectAttributesBackendTypes.php +++ b/vendor/magento/module-catalog/Setup/Patch/Data/UpdateMultiselectAttributesBackendTypes.php @@ -9,11 +9,12 @@ use Magento\Catalog\Model\Product; use Magento\Eav\Setup\EavSetup; use Magento\Eav\Setup\EavSetupFactory; -use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\DB\Adapter\AdapterInterface; use Magento\Framework\Setup\ModuleDataSetupInterface; use Magento\Framework\Setup\Patch\DataPatchInterface; +use Magento\Framework\Setup\Patch\NonTransactionableInterface; -class UpdateMultiselectAttributesBackendTypes implements DataPatchInterface +class UpdateMultiselectAttributesBackendTypes implements DataPatchInterface, NonTransactionableInterface { /** * @var ModuleDataSetupInterface @@ -24,6 +25,11 @@ class UpdateMultiselectAttributesBackendTypes implements DataPatchInterface */ private $eavSetupFactory; + /** + * @var array + */ + private $triggersRestoreQueries = []; + /** * MigrateMultiselectAttributesData constructor. * @param ModuleDataSetupInterface $dataSetup @@ -61,6 +67,7 @@ public function apply() $this->dataSetup->startSetup(); $setup = $this->dataSetup; $connection = $setup->getConnection(); + $this->triggersRestoreQueries = []; $attributeTable = $setup->getTable('eav_attribute'); /** @var EavSetup $eavSetup */ @@ -74,23 +81,31 @@ public function apply() ->where('backend_type = ?', 'varchar') ->where('frontend_input = ?', 'multiselect') ); + $attributesToMigrate = array_map('intval', $attributesToMigrate); $varcharTable = $setup->getTable('catalog_product_entity_varchar'); $textTable = $setup->getTable('catalog_product_entity_text'); - $varcharTableDataSql = $connection - ->select() - ->from($varcharTable) - ->where('attribute_id in (?)', $attributesToMigrate); - $dataToMigrate = array_map(static function ($row) { - $row['value_id'] = null; - return $row; - }, $connection->fetchAll($varcharTableDataSql)); - - foreach (array_chunk($dataToMigrate, 2000) as $dataChunk) { - $connection->insertMultiple($textTable, $dataChunk); - } - $connection->query($connection->deleteFromSelect($varcharTableDataSql, $varcharTable)); + $columns = $connection->describeTable($varcharTable); + unset($columns['value_id']); + $this->dropTriggers($textTable); + $this->dropTriggers($varcharTable); + try { + $connection->query( + $connection->insertFromSelect( + $connection->select() + ->from($varcharTable, array_keys($columns)) + ->where('attribute_id in (?)', $attributesToMigrate, \Zend_Db::INT_TYPE), + $textTable, + array_keys($columns), + AdapterInterface::INSERT_ON_DUPLICATE + ) + ); + $connection->delete($varcharTable, ['attribute_id IN (?)' => $attributesToMigrate]); + } finally { + $this->restoreTriggers($textTable); + $this->restoreTriggers($varcharTable); + } foreach ($attributesToMigrate as $attributeId) { $eavSetup->updateAttribute($entityTypeId, $attributeId, 'backend_type', 'text'); @@ -100,4 +115,48 @@ public function apply() return $this; } + + /** + * Drop table triggers + * + * @param string $tableName + * @return void + * @throws \Zend_Db_Statement_Exception + */ + private function dropTriggers(string $tableName): void + { + $triggers = $this->dataSetup->getConnection() + ->query('SHOW TRIGGERS LIKE \''. $tableName . '\'') + ->fetchAll(); + + if (!$triggers) { + return; + } + + foreach ($triggers as $trigger) { + $triggerData = $this->dataSetup->getConnection() + ->query('SHOW CREATE TRIGGER '. $trigger['Trigger']) + ->fetch(); + $this->triggersRestoreQueries[$tableName][] = + preg_replace('/DEFINER=[^\s]*/', '', $triggerData['SQL Original Statement']); + // phpcs:ignore Magento2.SQL.RawQuery.FoundRawSql + $this->dataSetup->getConnection()->query('DROP TRIGGER IF EXISTS ' . $trigger['Trigger']); + } + } + + /** + * Restore table triggers. + * + * @param string $tableName + * @return void + * @throws \Zend_Db_Statement_Exception + */ + private function restoreTriggers(string $tableName): void + { + if (array_key_exists($tableName, $this->triggersRestoreQueries)) { + foreach ($this->triggersRestoreQueries[$tableName] as $query) { + $this->dataSetup->getConnection()->multiQuery($query); + } + } + } }