DDC-1298: SqlWalker->walkSelectClause imploding empty strings results in invalid query #1910

Closed
doctrinebot opened this Issue Jul 27, 2011 · 3 comments

2 participants

@doctrinebot

Jira issue originally created by user tbo:

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.

@doctrinebot

Comment created by tbo:

I have fixed it and made a pull request: #96

@doctrinebot

Comment created by @beberlei:

Fixed

@doctrinebot

Issue was closed with resolution "Fixed"

@beberlei beberlei was assigned by doctrinebot Dec 6, 2015
@doctrinebot doctrinebot added this to the 2.1.1 milestone Dec 6, 2015
@doctrinebot doctrinebot closed this Dec 6, 2015
@doctrinebot doctrinebot added the Bug label Dec 7, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment