Doctrine 2 - ORM
  1. Doctrine 2 - ORM
  2. DDC-1298

SqlWalker->walkSelectClause imploding empty strings results in invalid query

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Critical Critical
    • Resolution: Fixed
    • Affects Version/s: 2.1
    • Fix Version/s: 2.1.1
    • Component/s: DQL
    • Security Level: All
    • Labels:
      None

      Description

      Given the following MySQL structure

      CREATE TABLE `bar` (
        `barID` int(11) NOT NULL AUTO_INCREMENT,
        `barReference` varchar(45) DEFAULT NULL,
        PRIMARY KEY (`barID`)
      ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COMMENT='module=bug';
      
      CREATE TABLE `foo` (
        `fooID` int(11) NOT NULL AUTO_INCREMENT,
        `fooReference` varchar(45) DEFAULT NULL,
        PRIMARY KEY (`fooID`)
      ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='module=bug';
      
      CREATE TABLE `fooBar` (
        `fooID` int(11) NOT NULL,
        `barID` int(11) NOT NULL,
        PRIMARY KEY (`fooID`,`barID`),
        KEY `fk_foo1` (`fooID`),
        KEY `fk_bar1` (`barID`),
        CONSTRAINT `fk_table1_foo1` FOREIGN KEY (`fooID`) REFERENCES `foo` (`fooID`) ON DELETE CASCADE ON UPDATE NO ACTION,
        CONSTRAINT `fk_table1_bar1` FOREIGN KEY (`barID`) REFERENCES `bar` (`barID`) ON DELETE CASCADE ON UPDATE NO ACTION
      ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='module=bug';
      
      INSERT INTO `bar` (`barID`, `barReference`)
      VALUES
      	(1, 'bar1'),
      	(2, 'bar2');
      
      INSERT INTO `foo` (`fooID`, `fooReference`)
      VALUES
      	(1, 'foo1');
      
      INSERT INTO `fooBar` (`fooID`, `barID`)
      VALUES
      	(1, 1);
      

      the following models:

      use Doctrine\ORM\Mapping as ORM;
      
      /**
       * Model for foo
       *
       * @category Application
       * @package Bug
       * @subpackage Model
       * @ORM\Table(name="foo")
       * @ORM\Entity
       */
      class Bug_Model_Foo
      {
      	/**
      	 * @var integer fooID
      	 * @ORM\Column(name="fooID", type="integer", nullable=false)
      	 * @ORM\GeneratedValue(strategy="IDENTITY")
      	 * @ORM\Id
      	 */
      	protected $_fooID = null;
      
      	/**
      	 * @var string fooReference
      	 * @ORM\Column(name="fooReference", type="string", nullable=true, length=45)
      	 */
      	protected $_fooReference = null;
      
      	/**
      	 * @ORM\OneToMany(targetEntity="Bug_Model_FooBar", mappedBy="_foo",
      	 * cascade={"persist"})
      	 */
      	protected $_fooBarRefFoo = null;
      
      	/**
      	 * Constructor
      	 *
      	 * @param array|Zend_Config|null $options
      	 * @return Bug_Model_Foo
      	 */
      	public function __construct($options = null)
      	{
      		$this->_fooBarRefFoo = new \Doctrine\Common\Collections\ArrayCollection();
      		parent::__construct($options);
      	}
      
      }
      
      use Doctrine\ORM\Mapping as ORM;
      
      /**
       * Model for bar
       *
       * @category Application
       * @package Bug
       * @subpackage Model
       * @ORM\Table(name="bar")
       * @ORM\Entity
       */
      class Bug_Model_Bar
      {
      	/**
      	 * @var integer barID
      	 * @ORM\Column(name="barID", type="integer", nullable=false)
      	 * @ORM\GeneratedValue(strategy="IDENTITY")
      	 * @ORM\Id
      	 */
      	protected $_barID = null;
      
      	/**
      	 * @var string barReference
      	 * @ORM\Column(name="barReference", type="string", nullable=true, length=45)
      	 */
      	protected $_barReference = null;
      
      	/**
      	 * @ORM\OneToMany(targetEntity="Bug_Model_FooBar", mappedBy="_bar",
      	 * cascade={"persist"})
      	 */
      	protected $_fooBarRefBar = null;
      
      	/**
      	 * Constructor
      	 *
      	 * @param array|Zend_Config|null $options
      	 * @return Bug_Model_Bar
      	 */
      	public function __construct($options = null)
      	{
      		$this->_fooBarRefBar = new \Doctrine\Common\Collections\ArrayCollection();
      		parent::__construct($options);
      	}
      }
      
      
      use Doctrine\ORM\Mapping as ORM;
      
      /**
       * Model for fooBar
       *
       * @category Application
       * @package Bug
       * @subpackage Model
       * @ORM\Table(name="fooBar")
       * @ORM\Entity
       */
      class Bug_Model_FooBar
      {
      	/**
      	 * @ORM\ManyToOne(targetEntity="Bug_Model_Foo")
      	 * @ORM\JoinColumn(name="fooID", referencedColumnName="fooID")
      	 * @ORM\Id
      	 */
      	protected $_foo = null;
      
      	/**
      	 * @ORM\ManyToOne(targetEntity="Bug_Model_Bar")
      	 * @ORM\JoinColumn(name="barID", referencedColumnName="barID")
      	 * @ORM\Id
      	 */
      	protected $_bar = null;
      
      }
      

      and using the following DQL:

      SELECT 
      	f, b, fb 
      FROM 
      	Bug_Model_Foo f 
      JOIN 
      	f._fooBarRefFoo fb
      JOIN
      	fb._bar b
      

      will result in the following sql query:

      SELECT f0_.fooID AS fooID0, f0_.fooReference AS fooReference1, , b1_.barID AS barID2, b1_.barReference AS barReference3, f2_.fooID AS fooID4, f2_.barID AS barID5 FROM foo f0_ INNER JOIN fooBar f2_ ON f0_.fooID = f2_.fooID INNER JOIN bar b1_ ON f2_.barID = b1_.barID
      

      there are 2 comma's between "f0_.fooReference AS fooReference1" and "b1_.barID AS barID2" resulting in an invalid query.

      The first line of the walkSelectClause function in Doctrine/ORM/Query/SqlWalker.php will implode the result of the array_map.
      But you receive an empty result from processing the data for the selectExpression "fb" explaining why you got the extra comma.

      This worked in a previous version when 2.1 was still in development.

        Activity

        Hide
        Van Hauwaert Bert added a comment -

        I have fixed it and made a pull request: https://github.com/doctrine/doctrine2/pull/96

        Show
        Van Hauwaert Bert added a comment - I have fixed it and made a pull request: https://github.com/doctrine/doctrine2/pull/96
        Hide
        Benjamin Eberlei added a comment -

        Fixed

        Show
        Benjamin Eberlei added a comment - Fixed

          People

          • Assignee:
            Benjamin Eberlei
            Reporter:
            Van Hauwaert Bert
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: