diff options
-rw-r--r-- | includes/database/select.inc | 23 | ||||
-rw-r--r-- | modules/simpletest/tests/database_test.test | 66 |
2 files changed, 88 insertions, 1 deletions
diff --git a/includes/database/select.inc b/includes/database/select.inc index d46abefdf..b4f14c983 100644 --- a/includes/database/select.inc +++ b/includes/database/select.inc @@ -1125,7 +1125,21 @@ class SelectQuery extends Query implements SelectQueryInterface { } drupal_alter($hooks, $query); } - return $this->prepared = TRUE; + + $this->prepared = TRUE; + + // Now also prepare any sub-queries. + foreach ($this->tables as $table) { + if ($table['table'] instanceof SelectQueryInterface) { + $table['table']->preExecute(); + } + } + + foreach ($this->union as $union) { + $union['query']->preExecute(); + } + + return $this->prepared; } public function execute() { @@ -1411,6 +1425,13 @@ class SelectQuery extends Query implements SelectQueryInterface { // WHERE if (count($this->where)) { + // The following line will not generate placeholders correctly if there + // is a subquery. Fortunately, it is also called from getArguments() first + // so it's not a problem in practice... unless you try to call __toString() + // before calling getArguments(). That is a problem that we will have to + // fix in Drupal 8, because it requires more refactoring than we are + // able to do in Drupal 7. + // @todo Move away from __toString() For SelectQuery compilation at least. $this->where->compile($this->connection, $this); // There is an implicit string cast on $this->condition. $query .= "\nWHERE " . $this->where; diff --git a/modules/simpletest/tests/database_test.test b/modules/simpletest/tests/database_test.test index 89b28537a..16199c345 100644 --- a/modules/simpletest/tests/database_test.test +++ b/modules/simpletest/tests/database_test.test @@ -2030,6 +2030,72 @@ class DatabaseSelectComplexTestCase extends DatabaseTestCase { $this->assertEqual($crowded_job->job, $crowded_job->otherjob, t('Correctly joined same table twice.')); $this->assertNotEqual($crowded_job->name, $crowded_job->othername, t('Correctly joined same table twice.')); } + +} + +/** + * Test more complex select statements, part 2. + */ +class DatabaseSelectComplexTestCase2 extends DatabaseTestCase { + + public static function getInfo() { + return array( + 'name' => 'Select tests, complex 2', + 'description' => 'Test the Select query builder with even more complex queries.', + 'group' => 'Database', + ); + } + + function setUp() { + DrupalWebTestCase::setUp('database_test', 'node_access_test'); + + $schema['test'] = drupal_get_schema('test'); + $schema['test_people'] = drupal_get_schema('test_people'); + $schema['test_one_blob'] = drupal_get_schema('test_one_blob'); + $schema['test_two_blobs'] = drupal_get_schema('test_two_blobs'); + $schema['test_task'] = drupal_get_schema('test_task'); + + $this->installTables($schema); + + $this->addSampleData(); + } + + /** + * Test that we can join on a query. + */ + function testJoinSubquery() { + $acct = $this->drupalCreateUser(array('access content')); + $this->drupalLogin($acct); + + $query = db_select('test_task', 'tt', array('target' => 'slave')); + $query->addExpression('tt.pid + 1', 'abc'); + $query->condition('priority', 1, '>'); + $query->condition('priority', 100, '<'); + + $subquery = db_select('test', 'tp'); + $subquery->join('test_one_blob', 'tpb', 'tp.id = tpb.id'); + $subquery->join('node', 'n', 'tp.id = n.nid'); + $subquery->addTag('node_access'); + $subquery->addMetaData('account', $acct); + $subquery->addField('tp', 'id'); + $subquery->condition('age', 5, '>'); + $subquery->condition('age', 500, '<'); + + $query->leftJoin($subquery, 'sq', 'tt.pid = sq.id'); + $query->join('test_one_blob', 'tb3', 'tt.pid = tb3.id'); + + // Construct the query string. + // This is the same sequence that SelectQuery::execute() goes through. + $query->preExecute(); + $query->getArguments(); + $str = (string) $query; + + // Verify that the string only has one copy of condition placeholder 0. + debug($str); + $pos = strpos($str, 'db_condition_placeholder_0', 0); + $pos2 = strpos($str, 'db_condition_placeholder_0', $pos + 1); + $this->assertFalse($pos2, "Condition placeholder is not repeated"); + } } class DatabaseSelectPagerDefaultTestCase extends DatabaseTestCase { |