Clone a SelectQuery instance : what am I doing wrong? I've got a SelectQuery which I've created using db_select(). Then, after I've executed the query, I'm trying to clone it as I need to generate a few more queries based on the original one.

However, for some reason the clones I get from the original query doesn't seem to be clones. This is what I do.

// Create query
$q0 = db_select('track', 't');
$q0-&gt;fields('t', array('id','number','title');
[...]
$tracks = $q0-&gt;execute()-&gt;fetchAll();

// Clear fields on original query.
$fields = &amp;$q0-&gt;getFields();
$fields = array();

// Clone original query. The below queries should not have
// any fields set as they just got cleared above.
$q1 = clone $q0;
$q2 = clone $q0;

// This gets weird. The queries $q1 and $q2 should be separate
// clones, independent of each other. So should their fields. 
// However, setting fields on $q1 also sets fields on $q2.
$q1-&gt;fields('t', array('id'));

// Output : Array ( [id] =&gt; Array ( [field] =&gt; id [table] =&gt; t [alias] =&gt; id ) )
print_r($q2);


The fields() function on SelectQuery simply sets an array (see below). I thought that cloning an instance of a class containing an array would copy those arrays by value...and not by reference? Is this a special cloning "feature"?

protected $fields = array();

public function &amp;getFields() {
  return $this-&gt;fields;
}
As you have seen in bug report #1671848 the special getters of these special drupal objects breaks the clone behavior. The problem is that by reference getter are used and this imply hazardous behaviors in PHP internals of returned values.

I think it will be quite very long until this bug get fixed. So one of the solution is to avoid such writings:

$fields = &amp;$q0-&gt;getFields();
$fields = array();


This is not the way to empty something in an object. here the &amp; is the fault. after such a write the internal array stored in the object is broken and the object record it as a reference, you've been breaking object encapsulation and bad things happen (sse the bug report). Use a setter, And if there is not setter to do that clone the queries before havinf any field added to the query (so it's empty).