Fixed DQL subquery handling
This commit is contained in:
parent
5cbed200b6
commit
84a7fb7973
@ -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,10 +145,15 @@ 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 {
|
||||||
$fields = array_unique(array_merge($table->getPrimaryKeys(), $fields));
|
// 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) {
|
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);
|
||||||
|
@ -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 {
|
||||||
|
@ -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)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user