Index: includes/database/database.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/database/database.inc,v
retrieving revision 1.36
diff -u -p -r1.36 database.inc
--- includes/database/database.inc	24 Dec 2008 09:53:40 -0000	1.36
+++ includes/database/database.inc	25 Dec 2008 09:04:39 -0000
@@ -349,7 +349,7 @@ abstract class DatabaseConnection extend
    * @param $query
    *   The query string as SQL, with curly-braces surrounding the
    *   table names.
-   * @param $query
+   * @param $cache
    *   Whether or not to cache the prepared statement for later reuse in this
    *   same request.  Usually we want to, but queries that require preprocessing
    *   cannot be safely cached.
@@ -529,17 +529,17 @@ abstract class DatabaseConnection extend
     $modified = FALSE;
 
     foreach ($args as $key => $data) {
-      // is_array() is slower than checking a string value, so do that first.
+      // If the placeholder value to insert is an array, assume that we need
+      // to expand it out into a comma-delimited set of placeholders.
       if (is_array($data)) {
         $new_keys = array();
-        $base = $key;
-        $base[0] = ':';
         foreach ($data as $i => $value) {
-          $candidate_placeholder = $base . '_' . $i;
-          while (isset($args[$candidate_placeholder])) {
-            $candidate_placeholder .= mt_rand();
-          }
-          $new_keys[$candidate_placeholder] = $value;
+          // This assumes that there are no other placeholders that use the same
+          // name.  For example, if the array placeholder is defined as :example
+          // and there is already an :example_2 placeholder, this will generate
+          // a duplicate key.  We do not account for that as the calling code
+          // is already broken if that happens.
+          $new_keys[$key . '_' . $i] = $value;
         }
 
         // Update the query with the new placeholders.
Index: includes/database/pgsql/database.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/database/pgsql/database.inc,v
retrieving revision 1.14
diff -u -p -r1.14 database.inc
--- includes/database/pgsql/database.inc	20 Dec 2008 18:24:34 -0000	1.14
+++ includes/database/pgsql/database.inc	25 Dec 2008 09:04:40 -0000
@@ -41,7 +41,8 @@ class DatabaseConnection_pgsql extends D
         $stmt->execute(NULL, $options);
       }
       else {
-        $stmt = $this->prepareQuery($query);
+        $modified = $this->expandArguments($query, $args);
+        $stmt = $this->prepareQuery($query, !$modified);
         $stmt->execute($args, $options);
       }
 
Index: modules/simpletest/tests/database_test.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/tests/database_test.test,v
retrieving revision 1.30
diff -u -p -r1.30 database_test.test
--- modules/simpletest/tests/database_test.test	24 Dec 2008 10:21:32 -0000	1.30
+++ modules/simpletest/tests/database_test.test	25 Dec 2008 09:04:41 -0000
@@ -2085,10 +2085,10 @@ class DatabaseQueryTestCase extends Data
   }
 
   /**
-   * Confirm that temporary tables work and are limited to one request.
+   * Test that we can specify an array of values in the query by simply passing in an array.
    */
   function testArraySubstitution() {
-    $names = db_query("SELECT name FROM {test} WHERE age IN (@ages) ORDER BY age", array('@ages' => array(25, 26, 27)))->fetchAll();
+    $names = db_query("SELECT name FROM {test} WHERE age IN (:ages) ORDER BY age", array(':ages' => array(25, 26, 27)))->fetchAll();
 
     $this->assertEqual(count($names), 3, t('Correct number of names returned'));
   }
