1
0
mirror of synced 2025-01-20 07:21:40 +03:00

Fixed DQL subquery handling

This commit is contained in:
zYne 2007-01-27 10:28:25 +00:00
parent 5cbed200b6
commit 84a7fb7973
3 changed files with 46 additions and 7 deletions

View File

@ -59,6 +59,11 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
* @param boolean $limitSubqueryUsed
*/
private $limitSubqueryUsed = false;
/**
* @param boolean $isSubquery whether or not this query object is a subquery of another
* query object
*/
private $isSubquery;
private $tableStack;
@ -88,7 +93,28 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
{
return new Doctrine_Query();
}
/**
* isSubquery
* if $bool parameter is set this method sets the value of
* Doctrine_Query::$isSubquery. If this value is set to true
* the query object will not load the primary key fields of the selected
* components.
*
* If null is given as the first parameter this method retrieves the current
* value of Doctrine_Query::$isSubquery.
*
* @param boolean $bool whether or not this query acts as a subquery
* @return Doctrine_Query|bool
*/
public function isSubquery($bool = null)
{
if ($bool === null) {
return $this->isSubquery;
}
$this->isSubquery = (bool) $bool;
return $this;
}
public function getTableStack()
{
return $this->tableStack;
@ -119,11 +145,16 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
if (isset($this->pendingFields[$componentAlias])) {
$fields = $this->pendingFields[$componentAlias];
if(in_array('*', $fields))
if(in_array('*', $fields)) {
$fields = $table->getColumnNames();
else
} else {
// only auto-add the primary key fields if this query object is not
// a subquery of another query object
if ( ! $this->isSubquery) {
$fields = array_unique(array_merge($table->getPrimaryKeys(), $fields));
}
}
}
foreach ($fields as $name) {
$name = $table->getColumnName($name);
@ -296,10 +327,13 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
case Doctrine::FETCH_OFFSET:
$this->limit = $table->getAttribute(Doctrine::ATTR_COLL_LIMIT);
case Doctrine::FETCH_IMMEDIATE:
if( ! empty($names))
if( ! empty($names)) {
// only auto-add the primary key fields if this query object is not
// a subquery of another query object
$names = array_unique(array_merge($table->getPrimaryKeys(), $names));
else
} else {
$names = $table->getColumnNames();
}
break;
case Doctrine::FETCH_LAZY_OFFSET:
$this->limit = $table->getAttribute(Doctrine::ATTR_COLL_LIMIT);

View File

@ -132,9 +132,11 @@ class Doctrine_Query_Where extends Doctrine_Query_Condition
$trimmed = Doctrine_Query::bracketTrim($value);
if (substr($trimmed, 0, 4) == 'FROM' || substr($trimmed, 0, 6) == 'SELECT') {
// subquery found
$q = new Doctrine_Query();
$value = '(' . $q->parseQuery($trimmed)->getQuery() . ')';
$value = '(' . $q->isSubquery(true)->parseQuery($trimmed)->getQuery() . ')';
} elseif (substr($trimmed, 0, 4) == 'SQL:') {
$value = '(' . substr($trimmed, 4) . ')';
} else {

View File

@ -48,7 +48,10 @@ class Doctrine_Query_Subquery_TestCase extends Doctrine_UnitTestCase
}
public function testSubqueryAllowsSelectingOfAnyField()
{
$q = new Doctrine_Query();
$q->from('User u')->where('u.id NOT IN (SELECT g.user_id FROM Groupuser g)');
$this->assertEqual($q->getQuery(), "SELECT e.id AS e__id, e.name AS e__name, e.loginname AS e__loginname, e.password AS e__password, e.type AS e__type, e.created AS e__created, e.updated AS e__updated, e.email_id AS e__email_id FROM entity e WHERE e.id NOT IN (SELECT g.user_id AS g__user_id FROM groupuser g) AND (e.type = 0)");
}
}
?>