Commit 1f42b72b by Qiang Xue

Fixes #2346: ActiveQuery used in building sub-query should not need to set FROM clause explicitly.

parent fa353294
...@@ -95,7 +95,10 @@ class Query extends Component implements QueryInterface ...@@ -95,7 +95,10 @@ class Query extends Component implements QueryInterface
public $having; public $having;
/** /**
* @var array this is used to construct the UNION clause(s) in a SQL statement. * @var array this is used to construct the UNION clause(s) in a SQL statement.
* Each array element can be either a string or a [[Query]] object representing a sub-query. * Each array element is an array of the following structure:
*
* - `query`: either a string or a [[Query]] object representing a query
* - `all`: boolean, whether it should be `UNION ALL` or `UNION`
*/ */
public $union; public $union;
/** /**
......
...@@ -767,8 +767,11 @@ class QueryBuilder extends \yii\base\Object ...@@ -767,8 +767,11 @@ class QueryBuilder extends \yii\base\Object
if ($query instanceof Query) { if ($query instanceof Query) {
// save the original parameters so that we can restore them later to prevent from modifying the query object // save the original parameters so that we can restore them later to prevent from modifying the query object
$originalParams = $query->params; $originalParams = $query->params;
$query->addParams($params); $command = $query->createCommand($this->db);
list ($unions[$i]['query'], $params) = $this->build($query); $unions[$i]['query'] = $command->sql;
foreach ($command->params as $name => $value) {
$params[$name] = $value;
}
$query->params = $originalParams; $query->params = $originalParams;
} }
...@@ -1107,11 +1110,18 @@ class QueryBuilder extends \yii\base\Object ...@@ -1107,11 +1110,18 @@ class QueryBuilder extends \yii\base\Object
* @param array $operands contains only one element which is a [[Query]] object representing the sub-query. * @param array $operands contains only one element which is a [[Query]] object representing the sub-query.
* @param array $params the binding parameters to be populated * @param array $params the binding parameters to be populated
* @return string the generated SQL expression * @return string the generated SQL expression
* @throws InvalidParamException if the operand is not a [[Query]] object.
*/ */
public function buildExistsCondition($operator, $operands, &$params) public function buildExistsCondition($operator, $operands, &$params)
{ {
$subQuery = $operands[0]; $subQuery = $operands[0];
list($subQuerySql, $subQueryParams) = $this->build($subQuery); if (!$subQuery instanceof Query) {
throw new InvalidParamException('Subquery for EXISTS operator must be a Query object.');
}
$command = $subQuery->createCommand($this->db);
$subQuerySql = $command->sql;
$subQueryParams = $command->params;
if (!empty($subQueryParams)) { if (!empty($subQueryParams)) {
foreach ($subQueryParams as $name => $value) { foreach ($subQueryParams as $name => $value) {
$params[$name] = $value; $params[$name] = $value;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment