magento / magento2

Prior to making any Submission(s), you must sign an Adobe Contributor License Agreement, available here at: https://opensource.adobe.com/cla.html. All Submissions you make to Adobe Inc. and its affiliates, assigns and subsidiaries (collectively “Adobe”) are subject to the terms of the Adobe Contributor License Agreement.
http://www.magento.com
Open Software License 3.0
11.53k stars 9.31k forks source link

Magento 245 - Elasticsearch error caused by prefix-table #35970

Open khoailangthang-programing opened 2 years ago

khoailangthang-programing commented 2 years ago

Preconditions and environment

Steps to reproduce

  1. Install Magento version CE-2.4.5
  2. View category page
    Error report
    Exception #1 (Zend_Db_Statement_Exception): SQLSTATE[42S02]: Base table or view not found: 1146 Table 'eav_attribute' doesn't exist

Expected result

View category page, list page, search page without error

Actual result

Error report
Exception #1 (Zend_Db_Statement_Exception): SQLSTATE[42S02]: Base table or view not found: 1146 Table 'eav_attribute' doesn't exist

Additional information

The class that is causing the issue: https://github.com/magento/magento2/blob/2.4.5/app/code/Magento/Elasticsearch/Model/ResourceModel/Fulltext/Collection/SearchResultApplier.php Line 242 (SELECT attribute_id FROM eav_attribute WHERE entity_type_id={$entityTypeId}

The query did not declare the prefix for eav_attribute table

Release note

No response

Triage and priority

m2-assistant[bot] commented 2 years ago

Hi @psydog-1101. Thank you for your report. To speed up processing of this issue, make sure that you provided the following information:

Make sure that the issue is reproducible on the vanilla Magento instance following Steps to reproduce. To deploy vanilla Magento instance on our environment, Add a comment to the issue:

@magento give me 2.4-develop instance - upcoming 2.4.x release

For more details, review the Magento Contributor Assistant documentation.

Add a comment to assign the issue: @magento I am working on this

To learn more about issue processing workflow, refer to the Code Contributions.


:clock10: You can find the schedule on the Magento Community Calendar page.

:telephone_receiver: The triage of issues happens in the queue order. If you want to speed up the delivery of your contribution, join the Community Contributions Triage session to discuss the appropriate ticket.

:pencil2: Feel free to post questions/proposals/feedback related to the Community Contributions Triage process to the corresponding Slack Channel

m2-assistant[bot] commented 2 years ago

Hi @engcom-Lima. Thank you for working on this issue. In order to make sure that issue has enough information and ready for development, please read and check the following instruction: :point_down:

drinkingsouls commented 2 years ago

I was just about to report this issue myself. When upgrading to 2.4.5 my catalog pages all have this error.

Base table or view not found: 1146 Table 'databaseuser.eav_attribute' doesn't exist

We have a prefix on our database too that is is not picking up.

SearchResultApplier.php line 251 also omits table prefix. Causes the same error when sorting by price.

. ' AND price_index.website_id = (Select website_id FROM store WHERE store_id = '

engcom-Lima commented 2 years ago

Hi @psydog-1101 ,

Thanks for your contribution and collaborations. I have tried to reproduce the issue but this issue is not reproducible to me. Followed above given steps but I am successfully able to navigate through Category page both in frontend and backend. Video for your reference attached: TEST-ID-3-Categories-Inventory-Catalog-Magento-Admin.webm

Please add --db-prefix through the installation command and inform us if you are facing any issue. For ex- bin/magento setup:install --base-url=http://********.com --db-host=localhost --db-name=*** --db-user=shubhamdb --db-password=*** --admin-firstname=admin --admin-lastname=admin --admin-email=*** --admin-user=admin --admin-password=*** --language=en_US --currency=USD --timezone=America/Chicago --use-rewrites=1 --backend-frontname=admin --db-prefix=test_ Please follow our official documentation for your reference: https://devdocs.magento.com/guides/v2.4/install-gde/install/cli/install-cli.html

Thanks

drinkingsouls commented 2 years ago

I have this same issue. My table prefix is correctly set in env.php Referring to SearchResultApplier.php (242 & 251) it does not seem that the prefix is called there at all.

engcom-Lima commented 2 years ago

Hi @drinkingsouls ,

Thanks for your contribution and collaboration.

Have you upgraded your instance? Also, can you check above comment and try to install by following the comment? Also, please give more information about step to reproduce ,so , that issue can be reproducible to me as well.

Thanks

drinkingsouls commented 2 years ago

Hi, What are you referring to regarding "upgraded instance"? I updated from 2.4.4 to 2.4.5 via composer and since then I am unable to view catalog pages due to the error mentioned above. If I add my database prefix to line 242 and 251 manually then these pages work correctly. If I downgrade to 2.4.4 then it works correctly again. I have redeployed, cleared caches, restarted server etc. It seems those lines do not pick up the prefix. Thank you.

khoailangthang-programing commented 2 years ago

Hi @engcom-Lima , I created new Instance of Magento 2.4.5 CE and try to replicate this issue. As it turns out, this problem only occurs if the Catalog > Inventory > Display Out of Stock Products configuration is set to Yes. Please take a look

khoailangthang-programing commented 2 years ago

Please refer below replication on my local https://imgur.com/MwfDk5K https://imgur.com/gHa3Ysk

engcom-Lima commented 2 years ago

Hi @psydog-1101 ,

Thanks for your information . I have tried to reproduce the issue but unable to reproduce it. I have create new instance of 2.4.5 CE with prefix table and in configuration I have done Catalog > Inventory > Display Out of Stock Products configuration is set to Yes. But I am able to navigate to category pages and in logs there is no error related to SQL. Below is the screenshot for your reference: image image image

Please follow our official documentation for your reference: https://devdocs.magento.com/guides/v2.4/install-gde/install/cli/install-cli.html

Please add --db-prefix through the installation command : For ex- bin/magento setup:install --base-url=http://********.com --db-host=localhost --db-name=*** --db-user=shubhamdb --db-password=*** --admin-firstname=admin --admin-lastname=admin --admin-email=*** --admin-user=admin --admin-password=*** --language=en_US --currency=USD --timezone=America/Chicago --use-rewrites=1 --backend-frontname=admin --db-prefix=test_

Kindly try to add prefix using above ex inform us if you are facing any issue.

Thanks

khoailangthang-programing commented 2 years ago

Hi @engcom-Lima , I've checked and recognized that the issue occurs if the Category's Default Product Listing Sort By configuration is set to Product Name instead of Position as Default Value Config. Video: https://www.loom.com/share/566e4114c99a4885ac7f8b78831dd40e

If the Category's Default Product Listing Sort By configuration is set to Price, the issue will be as @drinkingsouls mentioned at comment 4

Hope this helpful Thanks

drinkingsouls commented 2 years ago

The issue only occurs if Catalog > Inventory > Display Out of Stock Products configuration is set to Yes If it is, the prefix is not found. Screenshot: https://ibb.co/XLQwxYJ Video of issue: https://www.dropbox.com/s/c8jf58faat2azsd/catagory.mp4?dl=0

Same as @psydog-1101 if the Category's Default Product Listing Sort By is set to anything other than Position then the issue occurs. If I set the Default Product Listing Sort By to Position then it shows correctly. Video: https://www.dropbox.com/s/rqonqlov0esmfck/position-name-.mp4?dl=0

If I then go to the Category and change to sort by Name or Price then the issue occurs again.

engcom-Lima commented 2 years ago

:heavy_check_mark: Issue confirmed

Issue got reproduced in Magento 2.4-develop && 2.4.5 branch.

Description: Getting SQLSTATE[42S02] exception while opening category page in frontend. Pre-requisite: Fresh magento 2.4-develop and 2.4.5should be installed using db prefix .

Steps to reproduce:

  1. Login as admin.
  2. Go to Catalog > Inventory > Display Out of Stock Products configuration is set to Yes.
  3. Go to Catalog >> Categories >> Select your category >> Display setting choose Product name in Default Product Listing Sort By and save it.
  4. Clear cache.
  5. Go to frontend and open category page.
  6. Check the logs for any sql error.

Expected result: Product should be displayed. Actual result: Getting error. Screenshots: Screenshot from 2022-08-24 12-22-40 image

Hence, confirming the issue.

github-jira-sync-bot commented 2 years ago

:white_check_mark: Jira issue https://jira.corp.adobe.com/browse/AC-6503 is successfully created for this GitHub issue.

m2-assistant[bot] commented 2 years ago

:white_check_mark: Confirmed by @engcom-Lima. Thank you for verifying the issue.
Issue Available: @engcom-Lima, You will be automatically unassigned. Contributors/Maintainers can claim this issue to continue. To reclaim and continue work, reassign the ticket to yourself.

iphigenie commented 2 years ago

This bug is in a published live release and it is site breaking - it needs to be added to the release notes!

iphigenie commented 2 years ago

Also this should not have happened all the way to release -

How can we have an automated test that searches for hard coded table names in queries/conditions - there never should be any, they should be gettable() / gettablename() variables?

both times it is subqueries

The class as it is currently does not have any of the requisite context to be able to call getTableName or getTablePrefix - though perhaps in this case the prefix can be fetched from config?

line 241-243 subquery:

                       AND product_var.attribute_id =
                    (SELECT attribute_id FROM eav_attribute WHERE entity_type_id={$entityTypeId}
                    AND attribute_code='name')",

line 251-252 subquery

                     ' AND price_index.website_id = (Select website_id FROM store WHERE store_id = '
                    . $storeId . ')',

(my instincts is that we should know the website ID from the context here and not need a subquery to fetch it?)

drinkingsouls commented 2 years ago

Surprised this hasn't been followed up yet. It's quite a biggie to slip through the net. Release notes Known Issues do not have this listed for 2.4.5.

sanderjongsma commented 1 year ago

try adding: --cleanup-database param to you bin/magento setup:install

mitaldeveloper commented 1 year ago

I have fixed by below changes File: vendor/magento/module-elasticsearch/Model/ResourceModel/Fulltext/Collection/SearchResultApplier.php Line no: 235

From

if ($field === 'name') {
    $entityTypeId = $this->collection->getEntity()->getTypeId();
    $entityMetadata = $this->metadataPool->getMetadata(ProductInterface::class);
    $linkField = $entityMetadata->getLinkField();
    $query->joinLeft(
        ['product_var' => $this->collection->getTable('catalog_product_entity_varchar')],
        "product_var.{$linkField} = e.{$linkField} AND product_var.attribute_id =
        (SELECT attribute_id FROM eav_attribute WHERE entity_type_id={$entityTypeId}
        AND attribute_code='name')",
        ['product_var.value AS name']
    );
} elseif ($field === 'price') {
    $query->joinLeft(
        ['price_index' => $this->collection->getTable('catalog_product_index_price')],
        'price_index.entity_id = e.entity_id'
        . ' AND price_index.customer_group_id = 0'
        . ' AND price_index.website_id = (Select website_id FROM store WHERE store_id = '
        . $storeId . ')',
        ['price_index.max_price AS price']
    );
}

TO

if ($field === 'name') {
    $entityTypeId = $this->collection->getEntity()->getTypeId();
    $entityMetadata = $this->metadataPool->getMetadata(ProductInterface::class);
    $eavTable = $this->collection->getTable('eav_attribute');                
    $linkField = $entityMetadata->getLinkField();
    $query->joinLeft(
        ['product_var' => $this->collection->getTable('catalog_product_entity_varchar')],
        "product_var.{$linkField} = e.{$linkField} AND product_var.attribute_id =
        (SELECT attribute_id FROM ".$eavTable." WHERE entity_type_id={$entityTypeId}
        AND attribute_code='name')",
        ['product_var.value AS name']
    );
} elseif ($field === 'price') {
    $storeTable = $this->collection->getTable('store');
    $query->joinLeft(
        ['price_index' => $this->collection->getTable('catalog_product_index_price')],
        'price_index.entity_id = e.entity_id'
        . ' AND price_index.customer_group_id = 0'
        . ' AND price_index.website_id = (Select website_id FROM '.$storeTable.' WHERE store_id = '
        . $storeId . ')',
        ['price_index.max_price AS price']
    );
}
rjslegall commented 1 year ago

Hi!

We had the same problem. The bug is confirmed. To fix we apply the suggestion: Catalog > Inventory > Display Out of Stock Products configuration is set to No

AndyAcute commented 1 year ago

We have the same issue - Is this bug being worked on? What's the update?

Silarn commented 1 year ago

Just FYI I believe the official patch ACSD-48234 may cover this issue.