mirror of
https://github.com/yiisoft/yii2.git
synced 2025-08-26 14:26:54 +08:00
Fixes #2880
This commit is contained in:
@ -62,7 +62,7 @@ namespace yii\db;
|
||||
* If a relation involves a pivot table, it may be specified by [[via()]] or [[viaTable()]] method.
|
||||
* These methods may only be called in a relational context. Same is true for [[inverseOf()]], which
|
||||
* marks a relation as inverse of another relation and [[onCondition()]] which adds a condition that
|
||||
* is to be added to relational querys join condition.
|
||||
* is to be added to relational query join condition.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @author Carsten Brandt <mail@cebe.cc>
|
||||
@ -103,6 +103,40 @@ class ActiveQuery extends Query implements ActiveQueryInterface
|
||||
return parent::all($db);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function prepareBuild($builder)
|
||||
{
|
||||
if (!empty($this->joinWith)) {
|
||||
$this->buildJoinWith();
|
||||
$this->joinWith = null; // clean it up to avoid issue https://github.com/yiisoft/yii2/issues/2687
|
||||
}
|
||||
|
||||
if (empty($this->from)) {
|
||||
/** @var ActiveRecord $modelClass */
|
||||
$modelClass = $this->modelClass;
|
||||
$tableName = $modelClass::tableName();
|
||||
$this->from = [$tableName];
|
||||
}
|
||||
|
||||
if (empty($this->select) && !empty($this->join)) {
|
||||
foreach ((array)$this->from as $alias => $table) {
|
||||
if (is_string($alias)) {
|
||||
$this->select = ["$alias.*"];
|
||||
} elseif (is_string($table)) {
|
||||
if (preg_match('/^(.*?)\s+({{\w+}}|\w+)$/', $table, $matches)) {
|
||||
$alias = $matches[2];
|
||||
} else {
|
||||
$alias = $table;
|
||||
}
|
||||
$this->select = ["$alias.*"];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
@ -246,10 +280,6 @@ class ActiveQuery extends Query implements ActiveQueryInterface
|
||||
}
|
||||
|
||||
if ($this->sql === null) {
|
||||
if (!empty($this->joinWith)) {
|
||||
$this->buildJoinWith();
|
||||
$this->joinWith = null; // clean it up to avoid issue https://github.com/yiisoft/yii2/issues/2687
|
||||
}
|
||||
list ($sql, $params) = $db->getQueryBuilder()->build($this);
|
||||
} else {
|
||||
$sql = $this->sql;
|
||||
|
@ -123,6 +123,16 @@ class Query extends Component implements QueryInterface
|
||||
return $db->createCommand($sql, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares for building SQL.
|
||||
* This method is called by [[QueryBuilder]] when it starts to build SQL from a query object.
|
||||
* You may override this method to do some final preparation work when converting a query into a SQL statement.
|
||||
* @param QueryBuilder $builder
|
||||
*/
|
||||
public function prepareBuild($builder)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a batch query.
|
||||
*
|
||||
|
@ -64,12 +64,13 @@ class QueryBuilder extends \yii\base\Object
|
||||
*/
|
||||
public function build($query, $params = [])
|
||||
{
|
||||
$query->prepareBuild($this);
|
||||
|
||||
$params = empty($params) ? $query->params : array_merge($params, $query->params);
|
||||
list ($select, $from) = $this->adjustSelectFrom($query);
|
||||
|
||||
$clauses = [
|
||||
$this->buildSelect($select, $params, $query->distinct, $query->selectOption),
|
||||
$this->buildFrom($from, $params),
|
||||
$this->buildSelect($query->select, $params, $query->distinct, $query->selectOption),
|
||||
$this->buildFrom($query->from, $params),
|
||||
$this->buildJoin($query->join, $params),
|
||||
$this->buildWhere($query->where, $params),
|
||||
$this->buildGroupBy($query->groupBy),
|
||||
@ -88,44 +89,6 @@ class QueryBuilder extends \yii\base\Object
|
||||
return [$sql, $params];
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjusts the select and from parts of the query when it is an ActiveQuery.
|
||||
* When ActiveQuery does not specify "from", or if it is a join query without explicit "select",
|
||||
* certain adjustments need to be made. This method is put here so that QueryBuilder can
|
||||
* support sub-queries.
|
||||
* @param Query $query
|
||||
* @return array the select and from parts.
|
||||
*/
|
||||
protected function adjustSelectFrom($query)
|
||||
{
|
||||
$select = $query->select;
|
||||
$from = $query->from;
|
||||
if ($query instanceof ActiveQuery && (empty($select) || empty($from))) {
|
||||
/** @var ActiveRecord $modelClass */
|
||||
$modelClass = $query->modelClass;
|
||||
$tableName = $modelClass::tableName();
|
||||
if (empty($from)) {
|
||||
$from = [$tableName];
|
||||
}
|
||||
if (empty($select) && !empty($query->join)) {
|
||||
foreach ((array)$from as $alias => $table) {
|
||||
if (is_string($alias)) {
|
||||
$select = ["$alias.*"];
|
||||
} elseif (is_string($table)) {
|
||||
if (preg_match('/^(.*?)\s+({{\w+}}|\w+)$/', $table, $matches)) {
|
||||
$alias = $matches[2];
|
||||
} else {
|
||||
$alias = $tableName;
|
||||
}
|
||||
$select = ["$alias.*"];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return [$select, $from];
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an INSERT SQL statement.
|
||||
* For example,
|
||||
|
@ -19,7 +19,6 @@ use yii\db\ActiveRecord;
|
||||
*/
|
||||
class QueryBuilder extends \yii\db\QueryBuilder
|
||||
{
|
||||
|
||||
private $sql;
|
||||
|
||||
/**
|
||||
@ -28,11 +27,10 @@ class QueryBuilder extends \yii\db\QueryBuilder
|
||||
public function build($query, $params = [])
|
||||
{
|
||||
$params = empty($params) ? $query->params : array_merge($params, $query->params);
|
||||
list ($select, $from) = $this->adjustSelectFrom($query);
|
||||
|
||||
$clauses = [
|
||||
$this->buildSelect($select, $params, $query->distinct, $query->selectOption),
|
||||
$this->buildFrom($from, $params),
|
||||
$this->buildSelect($query->select, $params, $query->distinct, $query->selectOption),
|
||||
$this->buildFrom($query->from, $params),
|
||||
$this->buildJoin($query->join, $params),
|
||||
$this->buildWhere($query->where, $params),
|
||||
$this->buildGroupBy($query->groupBy),
|
||||
|
Reference in New Issue
Block a user