Issue #2142107 by drunken monkey, gilsbert, David_Rothstein, mondrake, Kristi Wachter: Complex cloned query dependent on __toString() call

8.7.x
Nathaniel Catchpole 2018-09-17 11:37:28 +01:00
parent 5e582a62c4
commit 74ba0f68db
2 changed files with 38 additions and 0 deletions

View File

@ -914,6 +914,8 @@ class Select extends Query implements SelectInterface {
* {@inheritdoc}
*/
public function __clone() {
parent::__clone();
// On cloning, also clone the dependent objects. However, we do not
// want to clone the database connection object as that would duplicate the
// connection itself.
@ -923,6 +925,11 @@ class Select extends Query implements SelectInterface {
foreach ($this->union as $key => $aggregate) {
$this->union[$key]['query'] = clone($aggregate['query']);
}
foreach ($this->tables as $alias => $table) {
if ($table['table'] instanceof SelectInterface) {
$this->tables[$alias]['table'] = clone $table['table'];
}
}
}
}

View File

@ -22,6 +22,10 @@ class SelectCloneTest extends DatabaseTestBase {
$query->condition('id', $subquery, 'IN');
$clone = clone $query;
// Cloned query should have a different unique identifier.
$this->assertNotEquals($query->uniqueIdentifier(), $clone->uniqueIdentifier());
// Cloned query should not be altered by the following modification
// happening on original query.
$subquery->condition('age', 25, '>');
@ -34,4 +38,31 @@ class SelectCloneTest extends DatabaseTestBase {
$this->assertEqual(2, $query_result, 'The query returns the expected number of rows');
}
/**
* Tests that nested SELECT queries are cloned properly.
*/
public function testNestedQueryCloning() {
$sub_query = $this->connection->select('test', 't');
$sub_query->addField('t', 'id', 'id');
$sub_query->condition('age', 28, '<');
$query = $this->connection->select($sub_query, 't');
$clone = clone $query;
// Cloned query should have a different unique identifier.
$this->assertNotEquals($query->uniqueIdentifier(), $clone->uniqueIdentifier());
// Cloned query should not be altered by the following modification
// happening on original query.
$sub_query->condition('age', 25, '>');
$clone_result = $clone->countQuery()->execute()->fetchField();
$query_result = $query->countQuery()->execute()->fetchField();
// Make sure the cloned query has not been modified.
$this->assertEquals(3, $clone_result, 'The cloned query returns the expected number of rows');
$this->assertEquals(2, $query_result, 'The query returns the expected number of rows');
}
}