Skip to content

Loading…

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

Closed
doctrinebot opened this Issue · 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
@doctrinebot doctrinebot added this to the 2.1.1 milestone
@doctrinebot doctrinebot closed this
@doctrinebot doctrinebot added the Bug label
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.