Commit b6c18664 authored by alexpott's avatar alexpott

Issue #2275519 by Nephele, daffie: Unable to use Condition objects with joins

parent 241a653f
......@@ -39,7 +39,7 @@ class Select extends Query implements SelectInterface {
* 'type' => $join_type (one of INNER, LEFT OUTER, RIGHT OUTER),
* 'table' => $table,
* 'alias' => $alias_of_the_table,
* 'condition' => $condition_clause_on_which_to_join,
* 'condition' => $join_condition (string or Condition object),
* 'arguments' => $array_of_arguments_for_placeholders_in_the condition.
* 'all_fields' => TRUE to SELECT $alias.*, FALSE or NULL otherwise.
* )
......@@ -47,6 +47,10 @@ class Select extends Query implements SelectInterface {
* If $table is a string, it is taken as the name of a table. If it is
* a Select query object, it is taken as a subquery.
*
* If $join_condition is a Condition object, any arguments should be
* incorporated into the object; a separate array of arguments does not
* need to be provided.
*
* @var array
*/
protected $tables = array();
......@@ -196,6 +200,10 @@ public function arguments() {
if ($table['table'] instanceof SelectInterface) {
$args += $table['table']->arguments();
}
// If the join condition is an object, grab its arguments recursively.
if (!empty($table['condition']) && $table['condition'] instanceof ConditionInterface) {
$args += $table['condition']->arguments();
}
}
foreach ($this->expressions as $expression) {
......@@ -225,6 +233,10 @@ public function compile(Connection $connection, PlaceholderInterface $queryPlace
if ($table['table'] instanceof SelectInterface) {
$table['table']->compile($connection, $queryPlaceholder);
}
// Make sure join conditions are also compiled.
if (!empty($table['condition']) && $table['condition'] instanceof ConditionInterface) {
$table['condition']->compile($connection, $queryPlaceholder);
}
}
// If there are any dependent queries to UNION, compile it recursively.
......@@ -248,6 +260,11 @@ public function compiled() {
return FALSE;
}
}
if (!empty($table['condition']) && $table['condition'] instanceof ConditionInterface) {
if (!$table['condition']->compiled()) {
return FALSE;
}
}
}
foreach ($this->union as $union) {
......@@ -822,7 +839,7 @@ public function __toString() {
$query .= $table_string . ' ' . $this->connection->escapeTable($table['alias']);
if (!empty($table['condition'])) {
$query .= ' ON ' . $table['condition'];
$query .= ' ON ' . (string) $table['condition'];
}
}
......
......@@ -375,4 +375,50 @@ function testSelectWithRowCount() {
$this->assertTrue($exception, 'Exception was thrown');
}
/**
* Test that join conditions can use Condition objects.
*/
public function testJoinConditionObject() {
// Same test as testDefaultJoin, but with a Condition object.
$query = db_select('test_task', 't');
$join_cond = db_and()->where('t.pid = p.id');
$people_alias = $query->join('test', 'p', $join_cond);
$name_field = $query->addField($people_alias, 'name', 'name');
$query->addField('t', 'task', 'task');
$priority_field = $query->addField('t', 'priority', 'priority');
$query->orderBy($priority_field);
$result = $query->execute();
$num_records = 0;
$last_priority = 0;
foreach ($result as $record) {
$num_records++;
$this->assertTrue($record->$priority_field >= $last_priority, 'Results returned in correct order.');
$this->assertNotEqual($record->$name_field, 'Ringo', 'Taskless person not selected.');
$last_priority = $record->$priority_field;
}
$this->assertEqual($num_records, 7, 'Returned the correct number of rows.');
// Test a condition object that creates placeholders.
$t1_name = 'John';
$t2_name = 'George';
$join_cond = db_and()
->condition('t1.name', $t1_name)
->condition('t2.name', $t2_name);
$query = db_select('test', 't1');
$query->innerJoin('test', 't2', $join_cond);
$query->addField('t1', 'name', 't1_name');
$query->addField('t2', 'name', 't2_name');
$num_records = $query->countQuery()->execute()->fetchField();
$this->assertEqual($num_records, 1, 'Query expected to return 1 row. Actual: ' . $num_records);
if ($num_records == 1) {
$record = $query->execute()->fetchObject();
$this->assertEqual($record->t1_name, $t1_name, 'Query expected to retrieve name ' . $t1_name . ' from table t1. Actual: ' . $record->t1_name);
$this->assertEqual($record->t2_name, $t2_name, 'Query expected to retrieve name ' . $t2_name . ' from table t2. Actual: ' . $record->t2_name);
}
}
}
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