=== modified file 'includes/database/mysql/schema.inc'
--- includes/database/mysql/schema.inc	2009-08-22 19:43:11 +0000
+++ includes/database/mysql/schema.inc	2009-08-28 07:51:27 +0000
@@ -372,11 +372,11 @@ class DatabaseSchema_mysql extends Datab
     $condition = $this->buildTableNameCondition($this->connection->prefixTables('{' . $table . '}'));
     if (isset($column)) {
       $condition->condition('column_name', $column);
-      $condition->compile($this->connection);
+      $condition->compile($this->connection, $this);
       // Don't use {} around information_schema.columns table.
       return db_query("SELECT column_comment FROM information_schema.columns WHERE " . (string) $condition, $condition->arguments())->fetchField();
     }
-    $condition->compile($this->connection);
+    $condition->compile($this->connection, $this);
     // Don't use {} around information_schema.tables table.
     $comment = db_query("SELECT table_comment FROM information_schema.tables WHERE " . (string) $condition, $condition->arguments())->fetchField();
     // Work-around for MySQL 5.0 bug http://bugs.mysql.com/bug.php?id=11379

=== modified file 'includes/database/query.inc'
--- includes/database/query.inc	2009-08-26 04:58:23 +0000
+++ includes/database/query.inc	2009-08-28 21:30:23 +0000
@@ -111,8 +111,11 @@ interface QueryConditionInterface {
    *
    * @param $connection
    *   The database connection for which to compile the conditionals.
+   * @param $query
+   *   The query this condition belongs to. If not given, the current query is
+   *   used.
    */
-  public function compile(DatabaseConnection $connection);
+  public function compile(DatabaseConnection $connection, QueryPlaceholderInterface $query = NULL);
 }
 
 
@@ -197,11 +200,21 @@ interface QueryAlterableInterface {
 }
 
 /**
+ * Interface for a query that accepts placeholders.
+ */
+interface QueryPlaceholderInterface {
+  /**
+   * Returns the next placeholder for the query.
+   */
+  function nextPlaceholder();
+}
+
+/**
  * Base class for the query builders.
  *
  * All query builders inherit from a common base class.
  */
-abstract class Query {
+abstract class Query implements QueryPlaceholderInterface {
 
   /**
    * The connection object on which to run this query.
@@ -217,6 +230,11 @@ abstract class Query {
    */
   protected $queryOptions;
 
+  /**
+   * The placeholder counter.
+   */
+  protected $placeholder = 0;
+
   public function __construct(DatabaseConnection $connection, $options) {
     $this->connection = $connection;
     $this->queryOptions = $options;
@@ -236,6 +254,10 @@ abstract class Query {
    *   A prepared statement query string for this object.
    */
   abstract public function __toString();
+
+  public function nextPlaceholder() {
+    return $this->placeholder++;
+  }
 }
 
 /**
@@ -292,6 +314,11 @@ class InsertQuery extends Query {
    */
   protected $fromQuery;
 
+  /**
+   * The placeholder counter.
+   */
+  protected $placeholder = 0;
+
   public function __construct($connection, $table, array $options = array()) {
     if (!isset($options['return'])) {
       $options['return'] = Database::RETURN_INSERT_ID;
@@ -564,6 +591,11 @@ class MergeQuery extends Query {
   protected $excludeFields = array();
 
   /**
+   * The placeholder counter.
+   */
+  protected $placeholder = 0;
+
+  /**
    * An array of fields to update to an expression in case of a duplicate record.
    *
    * This variable is a nested array in the following format:
@@ -830,6 +862,11 @@ class DeleteQuery extends Query implemen
    */
   protected $condition;
 
+  /**
+   * The placeholder counter.
+   */
+  protected $placeholder = 0;
+
   public function __construct(DatabaseConnection $connection, $table, array $options = array()) {
     $options['return'] = Database::RETURN_AFFECTED;
     parent::__construct($connection, $options);
@@ -866,14 +903,14 @@ class DeleteQuery extends Query implemen
     return $this;
   }
 
-  public function compile(DatabaseConnection $connection) {
-    return $this->condition->compile($connection);
+  public function compile(DatabaseConnection $connection, QueryPlaceholderInterface $query = NULL) {
+    return $this->condition->compile($connection, isset($query) ? $query : $this);
   }
 
   public function execute() {
     $values = array();
     if (count($this->condition)) {
-      $this->condition->compile($this->connection);
+      $this->condition->compile($this->connection, $this);
       $values = $this->condition->arguments();
     }
 
@@ -884,7 +921,7 @@ class DeleteQuery extends Query implemen
     $query = 'DELETE FROM {' . $this->connection->escapeTable($this->table) . '} ';
 
     if (count($this->condition)) {
-      $this->condition->compile($this->connection);
+      $this->condition->compile($this->connection, $this);
       $query .= "\nWHERE " . $this->condition;
     }
 
@@ -905,14 +942,19 @@ class TruncateQuery extends Query {
    */
   protected $table;
 
+  /**
+   * The placeholder counter.
+   */
+  protected $placeholder = 0;
+
   public function __construct(DatabaseConnection $connection, $table, array $options = array()) {
     $options['return'] = Database::RETURN_AFFECTED;
     parent::__construct($connection, $options);
     $this->table = $table;
   }
 
-  public function compile(DatabaseConnection $connection) {
-    return $this->condition->compile($connection);
+  public function compile(DatabaseConnection $connection, QueryPlaceholderInterface $query = NULL) {
+    return $this->condition->compile($connection, isset($query) ? $query : $this);
   }
 
   public function execute() {
@@ -971,6 +1013,10 @@ class UpdateQuery extends Query implemen
    */
   protected $expressionFields = array();
 
+  /**
+   * The placeholder counter.
+   */
+  protected $placeholder = 0;
 
   public function __construct(DatabaseConnection $connection, $table, array $options = array()) {
     $options['return'] = Database::RETURN_AFFECTED;
@@ -1008,8 +1054,8 @@ class UpdateQuery extends Query implemen
     return $this;
   }
 
-  public function compile(DatabaseConnection $connection) {
-    return $this->condition->compile($connection);
+  public function compile(DatabaseConnection $connection, QueryPlaceholderInterface $query = NULL) {
+    return $this->condition->compile($connection, isset($query) ? $query : $this);
   }
 
   /**
@@ -1073,7 +1119,7 @@ class UpdateQuery extends Query implemen
     }
 
     if (count($this->condition)) {
-      $this->condition->compile($this->connection);
+      $this->condition->compile($this->connection, $this);
       $update_values = array_merge($update_values, $this->condition->arguments());
     }
 
@@ -1098,7 +1144,7 @@ class UpdateQuery extends Query implemen
     $query = 'UPDATE {' . $this->connection->escapeTable($this->table) . '} SET ' . implode(', ', $update_fields);
 
     if (count($this->condition)) {
-      $this->condition->compile($this->connection);
+      $this->condition->compile($this->connection, $this);
       // There is an implicit string cast on $this->condition.
       $query .= "\nWHERE " . $this->condition;
     }
@@ -1178,17 +1224,8 @@ class DatabaseCondition implements Query
     return $this->arguments;
   }
 
-  public function compile(DatabaseConnection $connection) {
-    // This value is static, so it will increment across the entire request
-    // rather than just this query. That is OK, because we only need definitive
-    // placeholder names if we're going to use them for _alter hooks, which we
-    // are not. The alter hook would intervene before compilation.
-    // $next_placeholder does not use drupal_static as it increments and should
-    // never be reset during a request.
-    static $next_placeholder = 1;
-
+  public function compile(DatabaseConnection $connection, QueryPlaceholderInterface $query = NULL) {
     if ($this->changed) {
-
       $condition_fragments = array();
       $arguments = array();
 
@@ -1205,7 +1242,7 @@ class DatabaseCondition implements Query
           // It's a structured condition, so parse it out accordingly.
           if ($condition['field'] instanceof QueryConditionInterface) {
             // Compile the sub-condition recursively and add it to the list.
-            $condition['field']->compile($connection);
+            $condition['field']->compile($connection, $query);
             $condition_fragments[] = '(' . (string)$condition['field'] . ')';
             $arguments += $condition['field']->arguments();
           }
@@ -1238,7 +1275,7 @@ class DatabaseCondition implements Query
             }
             if ($operator['use_value']) {
               foreach ($condition['value'] as $value) {
-                $placeholder = ':db_condition_placeholder_' . $next_placeholder++;
+                $placeholder = ':db_condition_placeholder_' . $query->nextPlaceholder();
                 $arguments[$placeholder] = $value;
                 $placeholders[] = $placeholder;
               }
@@ -1263,6 +1300,15 @@ class DatabaseCondition implements Query
     return $this->stringVersion;
   }
 
+  function __clone() {
+    $this->changed = TRUE;
+    foreach ($this->conditions as $key => $condition) {
+      if ($condition['field'] instanceOf QueryConditionInterface) {
+        $this->conditions[$key]['field'] = clone($condition['field']);
+      }
+    }
+  }
+
   /**
    * Gets any special processing requirements for the condition operator.
    *

=== modified file 'includes/database/schema.inc'
--- includes/database/schema.inc	2009-08-02 08:16:15 +0000
+++ includes/database/schema.inc	2009-08-28 07:51:13 +0000
@@ -146,14 +146,24 @@
  * @see drupal_install_schema()
  */
 
-abstract class DatabaseSchema {
+abstract class DatabaseSchema implements QueryPlaceholderInterface {
 
   protected $connection;
 
+  /**
+   * The placeholder counter.
+   */
+  protected $placeholder = 0;
+
+
   public function __construct($connection) {
     $this->connection = $connection;
   }
 
+  public function nextPlaceholder() {
+    return $this->placeholder++;
+  }
+
   /**
    * Build a condition to match a table name against a standard information_schema.
    *
@@ -204,7 +214,7 @@ abstract class DatabaseSchema {
    */
   public function tableExists($table) {
     $condition = $this->buildTableNameCondition($this->connection->prefixTables('{' . $table . '}'));
-    $condition->compile($this->connection);
+    $condition->compile($this->connection, $this);
     // Normally, we would heartily discourage the use of string
     // concatination for conditionals like this however, we
     // couldn't use db_select() here because it would prefix
@@ -224,7 +234,7 @@ abstract class DatabaseSchema {
    */
   public function findTables($table_expression) {
     $condition = $this->buildTableNameCondition($table_expression, 'LIKE');
-    $condition->compile($this->connection);
+    $condition->compile($this->connection, $this);
     // Normally, we would heartily discourage the use of string
     // concatination for conditionals like this however, we
     // couldn't use db_select() here because it would prefix
@@ -239,7 +249,7 @@ abstract class DatabaseSchema {
   public function columnExists($table, $column) {
     $condition = $this->buildTableNameCondition($this->connection->prefixTables('{' . $table . '}'));
     $condition->condition('column_name', $column);
-    $condition->compile($this->connection);
+    $condition->compile($this->connection, $this);
     // Normally, we would heartily discourage the use of string
     // concatination for conditionals like this however, we
     // couldn't use db_select() here because it would prefix

=== modified file 'includes/database/select.inc'
--- includes/database/select.inc	2009-08-26 04:58:23 +0000
+++ includes/database/select.inc	2009-08-28 21:40:27 +0000
@@ -35,7 +35,7 @@ interface QueryExtendableInterface {
 /**
  * Interface definition for a Select Query object.
  */
-interface SelectQueryInterface extends QueryConditionInterface, QueryAlterableInterface, QueryExtendableInterface {
+interface SelectQueryInterface extends QueryConditionInterface, QueryAlterableInterface, QueryExtendableInterface, QueryPlaceholderInterface {
 
   /* Alter accessors to expose the query data to alter hooks. */
 
@@ -114,10 +114,14 @@ interface SelectQueryInterface extends Q
   /**
    * Compiles and returns an associative array of the arguments for this prepared statement.
    *
+   * @param $query
+   *   When collecting the arguments of a subquery, the main query should be
+   *   passed to this parameter.
+   *
    * @return
    *   An associative array of all placeholder arguments for this query.
    */
-  public function getArguments();
+  public function getArguments(QueryPlaceholderInterface $query = NULL);
 
   /* Query building operations */
 
@@ -400,12 +404,22 @@ class SelectQueryExtender implements Sel
    */
   protected $connection;
 
+  /**
+   * The placeholder counter.
+   */
+  protected $placeholder = 0;
 
   public function __construct(SelectQueryInterface $query, DatabaseConnection $connection) {
     $this->query = $query;
     $this->connection = $connection;
   }
 
+  /* Implementations of QueryPlaceholderInterface. */
+
+  public function nextPlaceholder() {
+    return $this->placeholder++;
+  }
+
   /* Implementations of QueryAlterableInterface. */
 
   public function addTag($tag) {
@@ -454,8 +468,8 @@ class SelectQueryExtender implements Sel
     return $this;
   }
 
-  public function compile(DatabaseConnection $connection) {
-    return $this->query->compile($connection);
+  public function compile(DatabaseConnection $connection, QueryPlaceholderInterface $query = NULL) {
+    return $this->condition->compile($connection, isset($query) ? $query : $this);
   }
 
   /* Implmeentations of QueryConditionInterface for the HAVING clause. */
@@ -510,8 +524,8 @@ class SelectQueryExtender implements Sel
     return $this->query->getTables();
   }
 
-  public function getArguments() {
-    return $this->query->getArguments();
+  public function getArguments(QueryPlaceholderInterface $query = NULL) {
+    return $this->query->getArguments($query);
   }
 
   public function isPrepared() {
@@ -826,9 +840,8 @@ class SelectQuery extends Query implemen
     return $this;
   }
 
-
-  public function compile(DatabaseConnection $connection) {
-    return $this->where->compile($connection);
+  public function compile(DatabaseConnection $connection, QueryPlaceholderInterface $query = NULL) {
+    return $this->where->compile($connection, isset($query) ? $query : $this);
   }
 
   /* Implmeentations of QueryConditionInterface for the HAVING clause. */
@@ -855,7 +868,7 @@ class SelectQuery extends Query implemen
   }
 
   public function havingCompile(DatabaseConnection $connection) {
-    return $this->having->compile($connection);
+    return $this->having->compile($connection, $this);
   }
 
   /* Implementations of QueryExtendableInterface. */
@@ -897,9 +910,12 @@ class SelectQuery extends Query implemen
     return $this->tables;
   }
 
-  public function getArguments() {
-    $this->where->compile($this->connection);
-    $this->having->compile($this->connection);
+  public function getArguments(QueryPlaceholderInterface $query = NULL) {
+    if (!isset($query)) {
+      $query = $this;
+    }
+    $this->where->compile($this->connection, $query);
+    $this->having->compile($this->connection, $query);
     $args = $this->where->arguments() + $this->having->arguments();
     foreach ($this->tables as $table) {
       if ($table['arguments']) {
@@ -907,7 +923,7 @@ class SelectQuery extends Query implemen
       }
       // If this table is a subquery, grab its arguments recursively.
       if ($table['table'] instanceof SelectQueryInterface) {
-        $args += $table['table']->getArguments();
+        $args += $table['table']->getArguments($query);
       }
     }
     foreach ($this->expressions as $expression) {
@@ -1179,7 +1195,7 @@ class SelectQuery extends Query implemen
 
     // WHERE
     if (count($this->where)) {
-      $this->where->compile($this->connection);
+      $this->where->compile($this->connection, $this);
       // There is an implicit string cast on $this->condition.
       $query .= "\nWHERE " . $this->where;
     }
@@ -1191,7 +1207,7 @@ class SelectQuery extends Query implemen
 
     // HAVING
     if (count($this->having)) {
-      $this->having->compile($this->connection);
+      $this->having->compile($this->connection, $this);
       // There is an implicit string cast on $this->having.
       $query .= "\nHAVING " . $this->having;
     }
@@ -1207,7 +1223,6 @@ class SelectQuery extends Query implemen
     }
 
     // RANGE is database specific, so we can't do it here.
-
     return $query;
   }
 

