Commit bc378d1c by Qiang Xue

properly quote table names for join().

parent 21bc2956
...@@ -524,7 +524,7 @@ class ActiveQuery extends Query implements ActiveQueryInterface ...@@ -524,7 +524,7 @@ class ActiveQuery extends Query implements ActiveQueryInterface
} else { } else {
$on = $child->on; $on = $child->on;
} }
$this->join($joinType, $childTable, $on); $this->join($joinType, empty($child->from) ? $childTable : $child->from, $on);
if (!empty($child->where)) { if (!empty($child->where)) {
$this->andWhere($child->where); $this->andWhere($child->where);
......
...@@ -642,23 +642,7 @@ class QueryBuilder extends \yii\base\Object ...@@ -642,23 +642,7 @@ class QueryBuilder extends \yii\base\Object
return ''; return '';
} }
foreach ($tables as $i => $table) { $tables = $this->quoteTableNames($tables, $params);
if ($table instanceof Query) {
list($sql, $params) = $this->build($table, $params);
$tables[$i] = "($sql) " . $this->db->quoteTableName($i);
} elseif (is_string($i)) {
if (strpos($table, '(') === false) {
$table = $this->db->quoteTableName($table);
}
$tables[$i] = "$table " . $this->db->quoteTableName($i);
} elseif (strpos($table, '(') === false) {
if (preg_match('/^(.*?)(?i:\s+as|)\s+([^ ]+)$/', $table, $matches)) { // with alias
$tables[$i] = $this->db->quoteTableName($matches[1]) . ' ' . $this->db->quoteTableName($matches[2]);
} else {
$tables[$i] = $this->db->quoteTableName($table);
}
}
}
return 'FROM ' . implode(', ', $tables); return 'FROM ' . implode(', ', $tables);
} }
...@@ -681,21 +665,8 @@ class QueryBuilder extends \yii\base\Object ...@@ -681,21 +665,8 @@ class QueryBuilder extends \yii\base\Object
} }
// 0:join type, 1:join table, 2:on-condition (optional) // 0:join type, 1:join table, 2:on-condition (optional)
list ($joinType, $table) = $join; list ($joinType, $table) = $join;
if (is_array($table)) { $tables = $this->quoteTableNames((array)$table, $params);
$query = reset($table); $table = reset($tables);
if (!$query instanceof Query) {
throw new Exception('The sub-query for join must be an instance of yii\db\Query.');
}
$alias = $this->db->quoteTableName(key($table));
list ($sql, $params) = $this->build($query, $params);
$table = "($sql) $alias";
} elseif (strpos($table, '(') === false) {
if (preg_match('/^(.*?)(?i:\s+as|)\s+([^ ]+)$/', $table, $matches)) { // with alias
$table = $this->db->quoteTableName($matches[1]) . ' ' . $this->db->quoteTableName($matches[2]);
} else {
$table = $this->db->quoteTableName($table);
}
}
$joins[$i] = "$joinType $table"; $joins[$i] = "$joinType $table";
if (isset($join[2])) { if (isset($join[2])) {
$condition = $this->buildCondition($join[2], $params); $condition = $this->buildCondition($join[2], $params);
...@@ -708,6 +679,28 @@ class QueryBuilder extends \yii\base\Object ...@@ -708,6 +679,28 @@ class QueryBuilder extends \yii\base\Object
return implode($this->separator, $joins); return implode($this->separator, $joins);
} }
private function quoteTableNames($tables, &$params)
{
foreach ($tables as $i => $table) {
if ($table instanceof Query) {
list($sql, $params) = $this->build($table, $params);
$tables[$i] = "($sql) " . $this->db->quoteTableName($i);
} elseif (is_string($i)) {
if (strpos($table, '(') === false) {
$table = $this->db->quoteTableName($table);
}
$tables[$i] = "$table " . $this->db->quoteTableName($i);
} elseif (strpos($table, '(') === false) {
if (preg_match('/^(.*?)(?i:\s+as|)\s+([^ ]+)$/', $table, $matches)) { // with alias
$tables[$i] = $this->db->quoteTableName($matches[1]) . ' ' . $this->db->quoteTableName($matches[2]);
} else {
$tables[$i] = $this->db->quoteTableName($table);
}
}
}
return $tables;
}
/** /**
* @param string|array $condition * @param string|array $condition
* @param array $params the binding parameters to be populated * @param array $params the binding parameters to be populated
......
...@@ -409,6 +409,11 @@ class ActiveRecordTest extends DatabaseTestCase ...@@ -409,6 +409,11 @@ class ActiveRecordTest extends DatabaseTestCase
'orders' => function ($q) { $q->orderBy([]); } 'orders' => function ($q) { $q->orderBy([]); }
])->one(); ])->one();
$this->assertEquals(1, $customer->id); $this->assertEquals(1, $customer->id);
$order = Order::find()->joinWith([
'items' => function ($q) {
$q->from(['items' => 'tbl_item']);
},
])->one();
} }
public function testJoinWithAndScope() public function testJoinWithAndScope()
......
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