Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

join() comes before contain(), results in "Column not found" #17680

Open
mehov opened this issue May 9, 2024 · 3 comments
Open

join() comes before contain(), results in "Column not found" #17680

mehov opened this issue May 9, 2024 · 3 comments
Labels
Milestone

Comments

@mehov
Copy link
Contributor

mehov commented May 9, 2024

Description

What I have

return $this
    ->find('all')
    ->contain([
        'Categories' => [
            'Stores' => [
            ]
        ],
        'ProductsProducts' => [
            'RefProducts' => [
            ],
        ],
    ])
    ->join([
        [
            'alias' => 'RefCategories',
            'table' => 'Categories',
            'type' => 'LEFT',
            'conditions' => 'RefProducts.category_id = RefCategories.id'
        ],
    ])
;

What happens

In the query that CakePHP generates for that find, my manual join I defined last actually comes before the "contained" tables.

SELECT 
  *
FROM 
  Products Products 
  LEFT JOIN Categories RefCategories ON RefProducts.category_id = RefCategories.id 
  LEFT JOIN Categories Categories ON Categories.id = Products.category_id 
  INNER JOIN Stores Stores ON Stores.id = Categories.store_id 
  LEFT JOIN Products_Products ProductsProducts ON ProductsProducts.id = Products.id 
  INNER JOIN Products RefProducts ON RefProducts.id = ProductsProducts.ref_product_id 

As a result,

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'RefProducts.category_id' in 'on clause'

What I expected to happen

Because I defined the join() after contain(), I expected the contained tables to be available before the join kicks in.

If I copy the SQL from DebugKit and manually edit it to where the contained tables are joined first, the query works when I run it in Workbench

CakePHP Version

4.4.14

PHP Version

8.3.1

@mehov mehov added the defect label May 9, 2024
@markstory markstory added this to the 4.5.6 milestone May 9, 2024
@markstory
Copy link
Member

This is likely caused by join() clauses being separate from contain() clauses. The reason for this separation is that not all contain() operations generate joins. #17184 is somewhat related.

@mehov
Copy link
Contributor Author

mehov commented May 9, 2024

@markstory but shouldn't it generate a bunch of left joins because it's a chain of belongsTo associations?

One can normally get Product to Category to Store all in one query

@markstory
Copy link
Member

but shouldn't it generate a bunch of left joins because it's a chain of belongsTo associations?

Sure, in your situation that is true, but that isn't always the case as contain() can be used for all association types.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants