Skip to content
This repository has been archived by the owner on Dec 21, 2023. It is now read-only.

Wrong results using query builder #138

Open
dop3 opened this issue Jul 29, 2014 · 11 comments
Open

Wrong results using query builder #138

dop3 opened this issue Jul 29, 2014 · 11 comments

Comments

@dop3
Copy link

dop3 commented Jul 29, 2014

Hi,
I'm facing a wrong behaviour while using the query builder.
I have to retrieve the actions made by a given user.
I know I can do:

$actionManager   = $this->get('spy_timeline.action_manager');
$subject         = $actionManager->findOrCreateComponent($user);
$timeline = $actionManager->getSubjectActions($subject, array(
    'page' => $page, 
    'max_per_page' => $limit, 
    'paginate' => true));

But, for several reasons and since my app offer the possibility to filter by verb, i want to do i like this:

$qb = $this->get('spy_timeline.query_builder');
$criterias = $qb->logicalAnd(
            $qb->field('type')->equals('subject'),
            $qb->field('model')->equals('It1000\CoreBundle\Entity\User'),
            $qb->field('identifier')->equals($user->getId()));
$qb->setCriterias($criterias);
$qb->setPage($page);
$qb->setMaxPerPage($limit);
$timeline = $qb->execute(array('paginate' => true, 'filter' => true));

The two options described should return the same results, but it's not true. The second one returns more rows (and theese more rows doesn't belong to the given user).

Using the profiler i've found the query that is produced:

SELECT COUNT(*) AS dctrn_count FROM (
    SELECT DISTINCT id6 FROM (
        SELECT s0_.verb AS verb0, s0_.status_current AS status_current1, s0_.status_wanted AS status_wanted2, s0_.duplicate_key AS duplicate_key3, s0_.duplicate_priority AS duplicate_priority4, s0_.created_at AS created_at5, s0_.id AS id6 
            FROM spy_timeline_action s0_ 
            LEFT JOIN spy_timeline_action_component s1_ ON s0_.id = s1_.action_id AND (s1_.type = 'subject') 
            LEFT JOIN spy_timeline_action_component s2_ ON s0_.id = s2_.action_id LEFT JOIN spy_timeline_component s3_ ON s2_.component_id = s3_.id AND (s3_.model = 'It1000\\CoreBundle\\Entity\\User') 
            LEFT JOIN spy_timeline_action_component s4_ ON s0_.id = s4_.action_id LEFT JOIN spy_timeline_component s5_ ON s4_.component_id = s5_.id AND (s5_.identifier = 's:2:\"39\";') 
           WHERE (s1_.type = 'subject' AND s3_.model = 'It1000\\CoreBundle\\Entity\\User' AND s5_.identifier = 's:2:\"39\";') 
            ORDER BY s0_.created_at DESC
    ) dctrn_result
) dctrn_table

I've found that i have different "components" that have identifier with value: 's:2:"39";' but different model. So since the where clause does the where on the different joins it matches also the rows that have the given identifiers but for another model; and, of course, it returns that rows in the results.

Am i missing something? Maybe the problem is in the "same identifier" been created?
Any kind of help will be appreciated.
Thanks and forgive me for my written english.

@stephpy
Copy link
Owner

stephpy commented Jul 31, 2014

Hi,

Indeed, the sql query built is wrong.
It should not create a new join for assertion of identifier. Results cannot be the same :\

This is a tricky bug. :\

I guess there is many some refactoring to do to fix this bug, i cannot assure you i'll fix it soon :. Sorry.

@stephpy
Copy link
Owner

stephpy commented Jul 31, 2014

Issue come from here

IMO we have to make a better system of repartition of criterias, to be able to optimize joins and make better assertions.

@dop3
Copy link
Author

dop3 commented Jul 31, 2014

Hi stephpy,
thanks for the reply.
Yes, I agree... the repartition of criterias is quite (let me say) ambiguos.
I will try to do some to fix this and, if lucky, i will let you know.
Waiting for yours...
Ciao

@stephpy
Copy link
Owner

stephpy commented Jul 31, 2014

Thanks.

@dop3
Copy link
Author

dop3 commented Aug 28, 2014

Hi all...
Nothing... I ended up bypassing the critirias stuff... doing some dirty query.
Honestly i don't think I can help...

Sorry about that...

@axzx
Copy link
Contributor

axzx commented Feb 17, 2017

@dop3 @stephpy
Tell you how to get around this problem?

@stephpy
Copy link
Owner

stephpy commented Feb 17, 2017

No, sorry.

TimelineBundle->QueryBuilder looks a tricky solution if you want to do a complex query.
IMO, you should create your own queryBuilder via doctrine ORM (or your provider).

@axzx
Copy link
Contributor

axzx commented Feb 17, 2017

I have querybuilder:

$qb = $this->getDoctrine()->getRepository('TimelineBundle:Action')
          ->createQueryBuilder('a');
$qb
      ->leftJoin('a.actionComponents', 'ac')
      ->leftJoin('ac.component', 'c')
      ->where('c.model = :model')
      ->andWhere('c.identifier = :identifier')
      ->setParameter('model', $objectModel)
      ->setParameter('identifier', serialize((string) $objectId))
;

But the problem is with data hydrator. In view, I don't see components. How join all components?

@stephpy
Copy link
Owner

stephpy commented Feb 17, 2017

@axzx
Copy link
Contributor

axzx commented Feb 17, 2017

@stephpy thanks:)

$timeline = $this->get('spy_timeline.result_builder')
          ->fetchResults($qb, $request->query->getInt('page', 1), 5, true, true);

$pagination = $timeline->getIterator();

@stephpy
Copy link
Owner

stephpy commented Feb 17, 2017

You're welcome.

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

No branches or pull requests

3 participants