8 use Magento\Catalog\Model\Indexer\Product\Flat\Table\BuilderInterfaceFactory;
35 private $tableBuilderFactory;
47 BuilderInterfaceFactory $tableBuilderFactory =
null 49 $this->_productIndexerHelper = $productIndexerHelper;
51 $this->_connection =
$resource->getConnection();
53 ->get(BuilderInterfaceFactory::class);
66 $entityTableName = $this->_productIndexerHelper->getTable(
'catalog_product_entity');
67 $attributes = $this->_productIndexerHelper->getAttributes();
68 $eavAttributes = $this->_productIndexerHelper->getTablesStructure(
$attributes);
69 $entityTableColumns = $eavAttributes[$entityTableName];
70 $linkField = $this->getMetadataPool()
71 ->getMetadata(\
Magento\Catalog\Api\Data\ProductInterface::class)
74 $temporaryEavAttributes = $eavAttributes;
78 $status = $this->_productIndexerHelper->getAttribute(
'status');
79 $temporaryEavAttributes[
$status->getBackendTable()][
'status'] =
$status;
83 $valueTables = array_merge(
94 unset($temporaryEavAttributes[$entityTableName]);
103 if (isset($valueTables[$temporaryTableName . $valueFieldSuffix])) {
121 protected function _createTemporaryTable(
$tableName, array
$columns, $valueFieldSuffix)
125 $valueTableName =
$tableName . $valueFieldSuffix;
126 $temporaryTableBuilder = $this->tableBuilderFactory->create(
128 'connection' => $this->_connection,
132 $valueTemporaryTableBuilder = $this->tableBuilderFactory->create(
134 'connection' => $this->_connection,
135 'tableName' => $valueTableName
138 $flatColumns = $this->_productIndexerHelper->getFlatColumns();
140 $temporaryTableBuilder->addColumn(
'entity_id', \
Magento\Framework\DB\Ddl\Table::TYPE_INTEGER);
142 $temporaryTableBuilder->addColumn(
'type_id', \
Magento\Framework\DB\Ddl\Table::TYPE_TEXT);
144 $temporaryTableBuilder->addColumn(
'attribute_set_id', \
Magento\Framework\DB\Ddl\Table::TYPE_INTEGER);
146 $valueTemporaryTableBuilder->addColumn(
'entity_id', \
Magento\Framework\DB\Ddl\Table::TYPE_INTEGER);
154 $column =
$attribute->_getFlatColumnsDdlDefinition();
158 $temporaryTableBuilder->addColumn(
161 isset($column[
'length']) ? $column[
'length'] :
null 165 if (isset($flatColumns[$columnValueName])) {
166 $columnValue = $flatColumns[$columnValueName];
167 $valueTemporaryTableBuilder->addColumn(
169 $columnValue[
'type'],
170 isset($columnValue[
'length']) ? $columnValue[
'length'] :
null 174 $this->_connection->dropTemporaryTable(
$tableName);
175 $this->_connection->createTemporaryTable($temporaryTableBuilder->getTable());
177 if (count($valueTemporaryTableBuilder->getTable()->getColumns()) > 1) {
178 $this->_connection->dropTemporaryTable($valueTableName);
179 $this->_connection->createTemporaryTable($valueTemporaryTableBuilder->getTable());
180 $valueTables[$valueTableName] = $valueTableName;
208 $select = $this->_connection->select();
210 $metadata = $this->getMetadataPool()->getMetadata(\
Magento\Catalog\Api\Data\ProductInterface::class);
211 $idsColumns = array_unique([$metadata->getLinkField(),
'entity_id',
'type_id',
'attribute_set_id']);
216 $onDuplicate =
false;
217 if (!empty($changedIds)) {
218 $select->where($this->_connection->quoteInto(
'e.entity_id IN (?)', $changedIds));
221 $sql =
$select->insertFromSelect($temporaryEntityTable,
$columns, $onDuplicate);
222 $this->_connection->query($sql);
235 $this->_connection->addIndex(
239 \
Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_PRIMARY
253 protected function _fillTemporaryTable(
260 $metadata = $this->getMetadataPool()->getMetadata(\
Magento\Catalog\Api\Data\ProductInterface::class);
261 if (!empty($tableColumns)) {
262 $columnsChunks = array_chunk(
264 Action\Indexer::ATTRIBUTES_CHUNK_SIZE,
267 foreach ($columnsChunks as $columnsList) {
268 $select = $this->_connection->select();
269 $selectValue = $this->_connection->select();
271 $this->_productIndexerHelper->getTable(
'catalog_product_entity')
274 $temporaryValueTableName = $temporaryTableName . $valueFieldSuffix;
275 $keyColumn = array_unique([$metadata->getLinkField(),
'entity_id']);
276 $columns = array_merge($keyColumn, array_keys($columnsList));
277 $valueColumns = $keyColumn;
278 $flatColumns = $this->_productIndexerHelper->getFlatColumns();
281 $select->from([
'et' => $entityTableName], $keyColumn)
283 [
'e' => $this->resource->getTableName(
'catalog_product_entity')],
284 'e.entity_id = et.entity_id',
288 $selectValue->from([
'e' => $temporaryTableName], $keyColumn);
291 foreach ($columnsList as $columnName =>
$attribute) {
292 $countTableName =
't' . $iterationNum++;
293 $joinCondition = sprintf(
294 'e.%3$s = %1$s.%3$s AND %1$s.attribute_id = %2$d AND %1$s.store_id = 0',
297 $metadata->getLinkField()
303 [$columnName =>
'value']
306 if (
$attribute->getFlatUpdateSelect(
$storeId) instanceof \Magento\Framework\DB\Select) {
309 if (isset($flatColumns[$columnValueName])) {
310 $valueJoinCondition = sprintf(
311 'e.%1$s = %2$s.option_id AND %2$s.store_id = 0',
315 $selectValue->joinLeft(
317 $countTableName => $this->_productIndexerHelper->getTable(
318 'eav_attribute_option_value' 322 [$columnValueName => $countTableName .
'.value']
324 $valueColumns[] = $columnValueName;
329 if (!empty($changedIds)) {
330 $select->where($this->_connection->quoteInto(
'e.entity_id IN (?)', $changedIds));
334 $this->_connection->query($sql);
336 if (count($valueColumns) > 1) {
337 if (!empty($changedIds)) {
338 $selectValue->where($this->_connection->quoteInto(
'e.entity_id IN (?)', $changedIds));
340 $sql = $selectValue->insertFromSelect($temporaryValueTableName, $valueColumns,
true);
341 $this->_connection->query($sql);
351 private function getMetadataPool()
353 if (
null === $this->metadataPool) {
355 ->get(\
Magento\Framework\EntityManager\MetadataPool::class);
_addPrimaryKeyToTable($tableName, $columnName='entity_id')
build($storeId, $changedIds, $valueFieldSuffix)
_getTemporaryTableName($tableName)
_fillTemporaryEntityTable($tableName, array $columns, array $changedIds=[])
__construct(\Magento\Catalog\Helper\Product\Flat\Indexer $productIndexerHelper, \Magento\Framework\App\ResourceConnection $resource, BuilderInterfaceFactory $tableBuilderFactory=null)