Details
-
Type:
Bug
-
Status:
Resolved
-
Priority:
Critical
-
Resolution: Fixed
-
Affects Version/s: 1.2.2
-
Fix Version/s: 1.2.4
-
Component/s: Query
-
Labels:None
-
Environment:Hide
PHP 5.3.1 (cli) (built: Feb 11 2010 02:32:22)
mysql Ver 14.14 Distrib 5.1.41, for apple-darwin9.5.0 (i386) using readline 5.1
Doctrine version 1.2.2 from SVN: http://doctrine.mirror.svn.symfony-project.com/tags/1.2.2/lib/Doctrine.phpShowPHP 5.3.1 (cli) (built: Feb 11 2010 02:32:22) mysql Ver 14.14 Distrib 5.1.41, for apple-darwin9.5.0 (i386) using readline 5.1 Doctrine version 1.2.2 from SVN: http://doctrine.mirror.svn.symfony-project.com/tags/1.2.2/lib/Doctrine.php
Description
I have a simple case with 3 Classes. Contact, Phone and Email. A Contact can many many phones, but only one email.
When doing this simple query:
$query = Doctrine_Query::create()->from('Contact c');
$query->leftJoin('c.Phones p ON c.id = p.contact_id');
$query->where('c.id NOT IN (SELECT Email.contact_id FROM Email)');
$query->execute();
Every thing went fine.
But when adding a limit() condition like:
$query->limit(20);
$query->execute();
The SQL generated query is not valid. There is a problem with the alias used in the NOT IN subquery. This query is generated like this:
WHERE c2.id NOT IN (SELECT e2.contact_id AS e2__contact_id FROM email e)
There is a mix between alias e2 and e
I have been trying to debug, but I didn't understand what was going wrong. The problem seems to happend in the class Doctrine_Query between line 1486 and 1554, but this part is obscur to me.
I attach to this ticket a valid TestCase
Thanks for support
TEXT VERSION OF THE TEST CASE
<?php
require_once('doctrine/lib/Doctrine.php');
spl_autoload_register(array('Doctrine', 'autoload'));
$manager = Doctrine_Manager::getInstance();
$manager->setAttribute(Doctrine::ATTR_EXPORT, Doctrine::EXPORT_ALL);
$conn = Doctrine_Manager::connection('mysql://root:@localhost/test_doctrine');
echo "Connection is set up\n";
class Contact extends Doctrine_Record {
{ $this->setTableName('contact'); $this->hasColumn('name', 'string', 300, array('type' => 'string', 'length' => 300)); }public function setTableDefinition()
public function setUp()
{ $this->hasMany('Phone as Phones', array('local' => 'id', 'foreign' => 'contact_id')); $this->hasOne('Email as Email', array('local' => 'id', 'foreign' => 'contact_id')); }}
{ $this->setTableName('phone'); $this->hasColumn('contact_id', 'integer', null, array('type' => 'integer')); }class Phone extends Doctrine_Record {
public function setTableDefinition()
public function setUp()
{ $this->hasOne('Contact', array('local' => 'contact_id', 'foreign' => 'id', 'onDelete' => 'CASCADE')); }}
{ $this->setTableName('email'); $this->hasColumn('contact_id', 'integer', null, array('type' => 'integer')); }class Email extends Doctrine_Record {
public function setTableDefinition()
public function setUp()
{ $this->hasOne('Contact', array('local' => 'contact_id', 'foreign' => 'id')); }}
echo "Classes Contact, Phone and Email are defines\n";
try
{Doctrine::dropDatabases();}catch(Exception $e){} // Drop if exist
Doctrine::createDatabases();
Doctrine::createTablesFromArray(array('Contact', 'Phone', 'Email'));
echo "Databases tables are create\n";
$query = Doctrine_Query::create()->from('Contact c');
$query->leftJoin('c.Phones p ON c.id = p.contact_id');
$query->where('c.id NOT IN (SELECT Email.contact_id FROM Email)');
$query->limit(20);
try {
$query->execute();
echo "TEST: Doctrine LEFTJOIN + NOT IN + LIMIT is OK\n";
}
catch (Exception $e){
echo "TEST: Doctrine LEFTJOIN + NOTIN + LIMIT is NOT working\n Alias in the NOT IN part are wrong, we get e2 and e\n\nDetail of the error:\n ", $e->getMessage(), "\n";
}