Doctrine 1
  1. Doctrine 1
  2. DC-36

Pager brakes joins with "with" keyword

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 1.1.6, 1.2.0-BETA3
    • Component/s: Pager, Query
    • Labels:
      None

      Description

      Extra join condition get applied multiple times so i get error: 'SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens'

      Problem seems to be related to change http://trac.doctrine-project.org/changeset/5550

      What happens now is Doctrine_Query::_buildSqlFromPart() gets executed 3 times.
      First time correctly with $ignorePending == false, second time correctly with $ignorePending == true and third time wrongly with $ignorePending == false.

      1. debug.yml
        0.2 kB
        Ivo Võsa
      2. schema.yml
        0.2 kB
        Ivo Võsa
      3. test.php
        0.4 kB
        Ivo Võsa

        Activity

        Hide
        Jonathan H. Wage added a comment -

        What version of 1.1 are you using?

        Show
        Jonathan H. Wage added a comment - What version of 1.1 are you using?
        Hide
        Ivo Võsa added a comment -

        Sandbox 1.1.3 and I also did 'svn co http://svn.doctrine-project.org/branches/1.1/'

        Show
        Ivo Võsa added a comment - Sandbox 1.1.3 and I also did 'svn co http://svn.doctrine-project.org/branches/1.1/ '
        Hide
        Ivo Võsa added a comment -

        As i did some debuging yesterday i'll post results:

        debug_print_backtace(); done at Doctrine_query::_buildSqlFromPart()

        #0  Doctrine_Query->_buildSqlFromPart() called at [/home/iff/Desktop/Doctrine-1.1.3-Sandbox/lib/Doctrine/Query.php:1233]
        #1  Doctrine_Query->getSqlQuery() called at [/home/iff/Desktop/Doctrine-1.1.3-Sandbox/lib/Doctrine/Query.php:1959]
        #2  Doctrine_Query->getCountQuery() called at [/home/iff/Desktop/Doctrine-1.1.3-Sandbox/lib/Doctrine/Query.php:2055]
        #3  Doctrine_Query->count(Array ()) called at [/home/iff/Desktop/Doctrine-1.1.3-Sandbox/lib/Doctrine/Pager.php:109]
        #4  Doctrine_Pager->_initialize(Array ()) called at [/home/iff/Desktop/Doctrine-1.1.3-Sandbox/lib/Doctrine/Pager.php:571]
        #5  Doctrine_Pager->execute() called at [/home/iff/Desktop/Doctrine-1.1.3-Sandbox/test.php:23]
        
        #0  Doctrine_Query->_buildSqlFromPart(1) called at [/home/iff/Desktop/Doctrine-1.1.3-Sandbox/lib/Doctrine/Query.php:1973]
        #1  Doctrine_Query->getCountQuery() called at [/home/iff/Desktop/Doctrine-1.1.3-Sandbox/lib/Doctrine/Query.php:2055]
        #2  Doctrine_Query->count(Array ()) called at [/home/iff/Desktop/Doctrine-1.1.3-Sandbox/lib/Doctrine/Pager.php:109]
        #3  Doctrine_Pager->_initialize(Array ()) called at [/home/iff/Desktop/Doctrine-1.1.3-Sandbox/lib/Doctrine/Pager.php:571]
        #4  Doctrine_Pager->execute() called at [/home/iff/Desktop/Doctrine-1.1.3-Sandbox/test.php:23]
        
        #0  Doctrine_Query->_buildSqlFromPart() called at [/home/iff/Desktop/Doctrine-1.1.3-Sandbox/lib/Doctrine/Query.php:1233]
        #1  Doctrine_Query->getSqlQuery(Array ()) called at [/home/iff/Desktop/Doctrine-1.1.3-Sandbox/lib/Doctrine/Query/Abstract.php:1076]
        #2  Doctrine_Query_Abstract->_execute(Array ()) called at [/home/iff/Desktop/Doctrine-1.1.3-Sandbox/lib/Doctrine/Query/Abstract.php:1142]
        #3  Doctrine_Query_Abstract->execute(Array (), ) called at [/home/iff/Desktop/Doctrine-1.1.3-Sandbox/lib/Doctrine/Pager.php:574]
        #4  Doctrine_Pager->execute() called at [/home/iff/Desktop/Doctrine-1.1.3-Sandbox/test.php:23]
        

        That lead me to following interesting parts in the code.

        Doctrine_Query.php line 1959

            public function getCountQuery()
            {
                // triggers dql parsing/processing
                $this->getSqlQuery(); // this is ugly
        

        Doctrine_Query.php line 1126

            protected function _processPendingJoinConditions($alias)
            {
                $parts = array();
        
                if ($alias !== null && isset($this->_pendingJoinConditions[$alias])) {
                    $parser = new Doctrine_Query_JoinCondition($this, $this->_tokenizer);
        
                    foreach ($this->_pendingJoinConditions[$alias] as $joinCondition) {
                        $parts[] = $parser->parse($joinCondition);
                    }
        
                    // FIX #1860 and #1876: Cannot unset them, otherwise query cannot be reused later
                    //unset($this->_pendingJoinConditions[$alias]);
                }
        

        Doctrine_Query.php line 1033

            protected function _buildSqlFromPart($ignorePending = false)
        

        So the problem should be obvious now. But what is the solution? Adding bunch of $ignorePending parameters to functions or object properties, so that pager can set it, when it executes does not seem right.

        Show
        Ivo Võsa added a comment - As i did some debuging yesterday i'll post results: debug_print_backtace(); done at Doctrine_query::_buildSqlFromPart() #0 Doctrine_Query->_buildSqlFromPart() called at [/home/iff/Desktop/Doctrine-1.1.3-Sandbox/lib/Doctrine/Query.php:1233] #1 Doctrine_Query->getSqlQuery() called at [/home/iff/Desktop/Doctrine-1.1.3-Sandbox/lib/Doctrine/Query.php:1959] #2 Doctrine_Query->getCountQuery() called at [/home/iff/Desktop/Doctrine-1.1.3-Sandbox/lib/Doctrine/Query.php:2055] #3 Doctrine_Query->count(Array ()) called at [/home/iff/Desktop/Doctrine-1.1.3-Sandbox/lib/Doctrine/Pager.php:109] #4 Doctrine_Pager->_initialize(Array ()) called at [/home/iff/Desktop/Doctrine-1.1.3-Sandbox/lib/Doctrine/Pager.php:571] #5 Doctrine_Pager->execute() called at [/home/iff/Desktop/Doctrine-1.1.3-Sandbox/test.php:23] #0 Doctrine_Query->_buildSqlFromPart(1) called at [/home/iff/Desktop/Doctrine-1.1.3-Sandbox/lib/Doctrine/Query.php:1973] #1 Doctrine_Query->getCountQuery() called at [/home/iff/Desktop/Doctrine-1.1.3-Sandbox/lib/Doctrine/Query.php:2055] #2 Doctrine_Query->count(Array ()) called at [/home/iff/Desktop/Doctrine-1.1.3-Sandbox/lib/Doctrine/Pager.php:109] #3 Doctrine_Pager->_initialize(Array ()) called at [/home/iff/Desktop/Doctrine-1.1.3-Sandbox/lib/Doctrine/Pager.php:571] #4 Doctrine_Pager->execute() called at [/home/iff/Desktop/Doctrine-1.1.3-Sandbox/test.php:23] #0 Doctrine_Query->_buildSqlFromPart() called at [/home/iff/Desktop/Doctrine-1.1.3-Sandbox/lib/Doctrine/Query.php:1233] #1 Doctrine_Query->getSqlQuery(Array ()) called at [/home/iff/Desktop/Doctrine-1.1.3-Sandbox/lib/Doctrine/Query/Abstract.php:1076] #2 Doctrine_Query_Abstract->_execute(Array ()) called at [/home/iff/Desktop/Doctrine-1.1.3-Sandbox/lib/Doctrine/Query/Abstract.php:1142] #3 Doctrine_Query_Abstract->execute(Array (), ) called at [/home/iff/Desktop/Doctrine-1.1.3-Sandbox/lib/Doctrine/Pager.php:574] #4 Doctrine_Pager->execute() called at [/home/iff/Desktop/Doctrine-1.1.3-Sandbox/test.php:23] That lead me to following interesting parts in the code. Doctrine_Query.php line 1959 public function getCountQuery() { // triggers dql parsing/processing $ this ->getSqlQuery(); // this is ugly Doctrine_Query.php line 1126 protected function _processPendingJoinConditions($alias) { $parts = array(); if ($alias !== null && isset($ this ->_pendingJoinConditions[$alias])) { $parser = new Doctrine_Query_JoinCondition($ this , $ this ->_tokenizer); foreach ($ this ->_pendingJoinConditions[$alias] as $joinCondition) { $parts[] = $parser->parse($joinCondition); } // FIX #1860 and #1876: Cannot unset them, otherwise query cannot be reused later //unset($ this ->_pendingJoinConditions[$alias]); } Doctrine_Query.php line 1033 protected function _buildSqlFromPart($ignorePending = false ) So the problem should be obvious now. But what is the solution? Adding bunch of $ignorePending parameters to functions or object properties, so that pager can set it, when it executes does not seem right.
        Hide
        Ivo Võsa added a comment -

        P.S. And in case someone is having same problem. Quick "solution" to get it working is changing

        $q->from('User u')
            ->leftJoin('u.UserGroup g WITH g.status = ?', $status);
        

        to

        $q->from('User u')
            ->leftJoin('u.UserGroup g WITH g.status = ' . (int)$status);
        

        it still produces query like "AND (u2.status = 0) AND (u2.status = 0)" but you won't get exception this way.

        Show
        Ivo Võsa added a comment - P.S. And in case someone is having same problem. Quick "solution" to get it working is changing $q->from('User u') ->leftJoin('u.UserGroup g WITH g.status = ?', $status); to $q->from('User u') ->leftJoin('u.UserGroup g WITH g.status = ' . ( int )$status); it still produces query like "AND (u2.status = 0) AND (u2.status = 0)" but you won't get exception this way.
        Hide
        Nicholas Kasyanov added a comment -
        Show
        Nicholas Kasyanov added a comment - http://www.doctrine-project.org/jira/browse/DC-48 I think it is same problem
        Hide
        Jonathan H. Wage added a comment -
        Show
        Jonathan H. Wage added a comment - This is fixed by http://trac.doctrine-project.org/changeset/6400

          People

          • Assignee:
            Guilherme Blanco
            Reporter:
            Ivo Võsa
          • Votes:
            1 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: