1
0
mirror of synced 2025-01-20 15:31: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 * @param boolean $limitSubqueryUsed
*/ */
private $limitSubqueryUsed = false; private $limitSubqueryUsed = false;
/**
* @param boolean $isSubquery whether or not this query object is a subquery of another
* query object
*/
private $isSubquery;
private $tableStack; private $tableStack;
@ -88,7 +93,28 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
{ {
return new Doctrine_Query(); 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() public function getTableStack()
{ {
return $this->tableStack; return $this->tableStack;
@ -119,11 +145,16 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
if (isset($this->pendingFields[$componentAlias])) { if (isset($this->pendingFields[$componentAlias])) {
$fields = $this->pendingFields[$componentAlias]; $fields = $this->pendingFields[$componentAlias];
if(in_array('*', $fields)) if(in_array('*', $fields)) {
$fields = $table->getColumnNames(); $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)); $fields = array_unique(array_merge($table->getPrimaryKeys(), $fields));
} }
}
}
foreach ($fields as $name) { foreach ($fields as $name) {
$name = $table->getColumnName($name); $name = $table->getColumnName($name);
@ -296,10 +327,13 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
case Doctrine::FETCH_OFFSET: case Doctrine::FETCH_OFFSET:
$this->limit = $table->getAttribute(Doctrine::ATTR_COLL_LIMIT); $this->limit = $table->getAttribute(Doctrine::ATTR_COLL_LIMIT);
case Doctrine::FETCH_IMMEDIATE: 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)); $names = array_unique(array_merge($table->getPrimaryKeys(), $names));
else } else {
$names = $table->getColumnNames(); $names = $table->getColumnNames();
}
break; break;
case Doctrine::FETCH_LAZY_OFFSET: case Doctrine::FETCH_LAZY_OFFSET:
$this->limit = $table->getAttribute(Doctrine::ATTR_COLL_LIMIT); $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); $trimmed = Doctrine_Query::bracketTrim($value);
if (substr($trimmed, 0, 4) == 'FROM' || substr($trimmed, 0, 6) == 'SELECT') { if (substr($trimmed, 0, 4) == 'FROM' || substr($trimmed, 0, 6) == 'SELECT') {
// subquery found // subquery found
$q = new Doctrine_Query(); $q = new Doctrine_Query();
$value = '(' . $q->parseQuery($trimmed)->getQuery() . ')'; $value = '(' . $q->isSubquery(true)->parseQuery($trimmed)->getQuery() . ')';
} elseif (substr($trimmed, 0, 4) == 'SQL:') { } elseif (substr($trimmed, 0, 4) == 'SQL:') {
$value = '(' . substr($trimmed, 4) . ')'; $value = '(' . substr($trimmed, 4) . ')';
} else { } else {

View File

@ -48,7 +48,10 @@ class Doctrine_Query_Subquery_TestCase extends Doctrine_UnitTestCase
} }
public function testSubqueryAllowsSelectingOfAnyField() 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)");
} }
} }
?> ?>