Verified Commit 11082e25 authored by Juraj Nemec's avatar Juraj Nemec
Browse files

Issue #2582069 by plach, poker10, Nephele: [D7] Unable to use Condition objects with joins

parent e354dcb5
Loading
Loading
Loading
Loading
+19 −2
Changes for includes/database/select.inc: 19 added lines, 2 removed lines.
Original line number Diff line number Diff line
@@ -883,7 +883,7 @@ class SelectQuery extends Query implements SelectQueryInterface {
   *   '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.
   * )
@@ -891,6 +891,10 @@ class SelectQuery extends Query implements SelectQueryInterface {
   * If $table is a string, it is taken as the name of a table. If it is
   * a SelectQuery 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();
@@ -1028,6 +1032,10 @@ public function arguments() {
      if ($table['table'] instanceof SelectQueryInterface) {
        $args += $table['table']->arguments();
      }
      // If the join condition is an object, grab its arguments recursively.
      if (!empty($table['condition']) && $table['condition'] instanceof QueryConditionInterface) {
        $args += $table['condition']->arguments();
      }
    }

    foreach ($this->expressions as $expression) {
@@ -1079,6 +1087,10 @@ public function compile(DatabaseConnection $connection, QueryPlaceholderInterfac
      if ($table['table'] instanceof SelectQueryInterface) {
        $table['table']->compile($connection, $queryPlaceholder);
      }
      // Make sure join conditions are also compiled.
      if (!empty($table['condition']) && $table['condition'] instanceof QueryConditionInterface) {
        $table['condition']->compile($connection, $queryPlaceholder);
      }
    }

    // If there are any dependent queries to UNION, compile it recursively.
@@ -1099,6 +1111,11 @@ public function compiled() {
          return FALSE;
        }
      }
      if (!empty($table['condition']) && $table['condition'] instanceof QueryConditionInterface) {
        if (!$table['condition']->compiled()) {
          return FALSE;
        }
      }
    }

    foreach ($this->union as $union) {
@@ -1568,7 +1585,7 @@ public function __toString() {
      $query .=  $table_string . ' ' . $this->connection->escapeAlias($table['alias']);

      if (!empty($table['condition'])) {
        $query .= ' ON ' . $table['condition'];
        $query .= ' ON ' . (string) $table['condition'];
      }
    }

+45 −0
Changes for modules/simpletest/tests/database_test.test: 45 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -2440,6 +2440,51 @@ class DatabaseSelectComplexTestCase extends DatabaseTestCase {
    $this->assertNotEqual($crowded_job->name, $crowded_job->othername, 'Correctly joined same table twice.');
  }

  /**
   * Test that join conditions can use Condition objects.
   */
  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);
    }
  }
}

/**