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

Cycle\Orm\Select adds a master table prefix before the name of the table to be joined in MtM case #398

Closed
Shelamkoff opened this issue Feb 22, 2023 · 1 comment · Fixed by #447
Assignees
Labels
Milestone

Comments

@Shelamkoff
Copy link

Hello.
There are two entities product and filters related by many-to-many. Needed to filter the goods through the pivot table.
The following code does everything necessary, but the generated query contains a double join, at a time when to filter it is enough to join with the pivot table.

final class ApplyProductFilters
{
    public function __invoke(Select $select, array $filters): Select
    {
        return $select->where(static function(Select\QueryBuilder $q) use ($filters) {
            foreach ($filters as $filterID => $filterValue) {
                $q->orWhere(static function(Select\QueryBuilder $q) use ($filterID, $filterValue) {
                    $q->where('[email protected]', $filterID);
                    if (is_array($filterValue)) {
                        $q->andWhere(static function(Select\QueryBuilder $q) use ($filterValue) {
                            if (count($filterValue) == 2 && is_numeric($filterValue[0]) && is_numeric($filterValue[1])) {
                                $q->orWhere('[email protected]', 'between', $filterValue[0], $filterValue[1]);
                            } else {
                                foreach ($filterValue as $value) $q->orWhere('[email protected]', $value);
                            }
                        });
                    } else {
                        $q->andWhere('[email protected]', $filterValue);
                    }
                });
            }
        });
    }
}

SELECT `product`.`id` AS `c0`, `product`.`name` AS `c1`, `product`.`price` AS `c2`, `product`.`attributes` AS `c3`, `product`.`description` AS `c4`, `product`.`created_at` AS `c5`, 
`product`.`category_id` AS `c6`, `product`.`brand_id` AS `c7`
FROM `products` AS `product` 
INNER JOIN `filters_products` AS `product_filters_pivot`
    ON `product_filters_pivot`.`product_id` = `product`.`id` 
INNER JOIN `filters` AS `product_filters`
    ON `product_filters`.`id` = `product_filters_pivot`.`filter_id`  
WHERE ((`product_filters_pivot`.`filter_id` = ? AND (`product_filters_pivot`.`filter_value` = ? OR `product_filters_pivot`.`filter_value` = ?  ) )OR (`product_filters_pivot`.`filter_id` = ? AND (`product_filters_pivot`.`filter_value` BETWEEN ? AND ?  ) ) ) 
LIMIT ? OFFSET ?

I tried calling the join directly from the Cycle\ORM\Select instance. But this way adds a master table prefix before the name of the table to be joined.

dd($select->innerJoin('filters_products', 'fp')->on('id', 'fp.product_id')->sqlStatement());
SELECT `product`.`id` AS `c0`, `product`.`name` AS `c1`, `product`.`price` AS `c2`, `product`.`attributes` AS `c3`, `product`.`description` AS `c4`, `product`.`created_at` AS `c5`,
`product`.`category_id` AS `c6`, `product`.`brand_id` AS `c7`
FROM `products` AS `product` 
INNER JOIN `product`.`filters_products` AS `fp`
    ON `product`.`id` = `fp`.`product_id`  
LIMIT ? OFFSET ?

Originally posted by @Shelamkoff in #397

@roxblnfk roxblnfk added this to Cycle Feb 23, 2023
@roxblnfk roxblnfk moved this to Discuss in Cycle Feb 23, 2023
@roxblnfk roxblnfk added the magic Structural changes, new features, performance. label Feb 23, 2023
@roxblnfk roxblnfk added type:bug Bug status:to be verified Needs to be reproduced and validated. and removed magic Structural changes, new features, performance. labels Sep 7, 2023
@roxblnfk roxblnfk changed the title Double join when filtering many-to-many relations. Cycle\Orm\Select adds a master table prefix before the name of the table to be joined in MtM case Sep 7, 2023
@roxblnfk
Copy link
Member

roxblnfk commented Sep 7, 2023

@msmakouz
About multiple joining - it's correct (see #397 (reply in thread)).
The main point is Select adds a master table prefix before the name of the table to be joined

Need to verify and fix it.

@roxblnfk roxblnfk moved this from Discuss to Todo in Cycle Sep 7, 2023
@msmakouz msmakouz moved this from Todo to In Progress in Cycle Dec 4, 2023
@msmakouz msmakouz linked a pull request Dec 7, 2023 that will close this issue
@roxblnfk roxblnfk added this to the 2.6.x milestone Dec 8, 2023
@roxblnfk roxblnfk removed the status:to be verified Needs to be reproduced and validated. label Dec 8, 2023
@github-project-automation github-project-automation bot moved this from In Progress to Done in Cycle Dec 8, 2023
@roxblnfk roxblnfk moved this from Done to Released in Cycle Dec 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: Released
Development

Successfully merging a pull request may close this issue.

3 participants