Index: includes/database/database.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/database/database.inc,v
retrieving revision 1.136
diff -u -p -r1.136 database.inc
--- includes/database/database.inc	18 Sep 2010 01:34:37 -0000	1.136
+++ includes/database/database.inc	23 Sep 2010 19:22:28 -0000
@@ -815,6 +815,7 @@ abstract class DatabaseConnection extend
    * Force all alias names to be strictly alphanumeric-plus-underscore. In
    * contrast to DatabaseConnection::escapeField() /
    * DatabaseConnection::escapeTable(), this doesn't allow the period (".")
+   * because that is not allowed in aliases.
    *
    * @return
    *   The sanitized field name string.
Index: includes/database/select.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/database/select.inc,v
retrieving revision 1.48
diff -u -p -r1.48 select.inc
--- includes/database/select.inc	3 Sep 2010 19:06:55 -0000	1.48
+++ includes/database/select.inc	23 Sep 2010 19:22:29 -0000
@@ -366,6 +366,13 @@ interface SelectQueryInterface extends Q
    * If called multiple times, the query will order by each specified field in the
    * order this method is called.
    *
+   * If the query uses DISTINCT or GROUP BY conditions, fields or expressions
+   * that are used for the order must be selected to be compatible with some
+   * databases like PostgreSQL. The PostgreSQL driver can handle simple cases
+   * automatically but it is suggested to explicitly specify them. Additionally,
+   * when ordering on an alias, the alias must be added before orderBy() is
+   * called.
+   *
    * @param $field
    *   The field on which to order.
    * @param $direction
@@ -1387,10 +1394,10 @@ class SelectQuery extends Query implemen
     foreach ($this->fields as $alias => $field) {
       // Always use the AS keyword for field aliases, as some
       // databases require it (e.g., PostgreSQL).
-      $fields[] = (isset($field['table']) ? $this->connection->escapeTable($field['table']) . '.' : '') . $this->connection->escapeField($field['field']) . ' AS ' . $this->connection->escapeField($field['alias']);
+      $fields[] = (isset($field['table']) ? $this->connection->escapeTable($field['table']) . '.' : '') . $this->connection->escapeField($field['field']) . ' AS ' . $this->connection->escapeAlias($field['alias']);
     }
     foreach ($this->expressions as $alias => $expression) {
-      $fields[] = $expression['expression'] . ' AS ' . $expression['alias'];
+      $fields[] = $expression['expression'] . ' AS ' . $this->connection->escapeAlias($expression['alias']);
     }
     $query .= implode(', ', $fields);
 
Index: includes/database/pgsql/query.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/database/pgsql/query.inc,v
retrieving revision 1.22
diff -u -p -r1.22 query.inc
--- includes/database/pgsql/query.inc	1 Sep 2010 01:43:50 -0000	1.22
+++ includes/database/pgsql/query.inc	23 Sep 2010 19:22:29 -0000
@@ -217,4 +217,86 @@ class SelectQuery_pgsql extends SelectQu
     return $this;
   }
 
+  /**
+   * Overrides SelectQuery::orderBy().
+   *
+   * PostgreSQL adheres strictly to the SQL-92 standard and requires that when
+   * using DISTINCT or GROUP BY conditions, fields and expressions that are
+   * ordered on also need to be selected. This is a best effort implementation
+   * to handle the cases that can be automated by adding the field if it is not
+   * yet selected.
+   *
+   * @code
+   *   $query = db_select('node', 'n');
+   *   $query->join('node_revision', 'nr', 'n.vid = nr.vid');
+   *   $query
+   *     ->distinct()
+   *     ->fields('n')
+   *     ->orderBy('timestamp');
+   * @endcode
+   *
+   * In this query, it is not possible (without relying on the schema) to know
+   * whether timestamp belongs to node_revisions and needs to be added or
+   * belongs to node and is already selected. Queries like this will need to be
+   * corrected in the original query by adding an explicit call to
+   * SelectQuery::addField() or SelectQuery::fields().
+   *
+   * Since this has a small performance impact, both by the additional
+   * processing in this function and in the database that needs to return the
+   * additional fields, this is done as an override instead of implementing it
+   * directly in SelectQuery::orderBy().
+   */
+  public function orderBy($field, $direction = 'ASC') {
+    // Call parent function to order on this.
+    $return = parent::orderBy($field, $direction);
+
+    // If there is a table alias specified, split it up.
+    if (strpos($field, '.') !== FALSE) {
+      list($table, $table_field) = explode('.', $field);
+    }
+    // Figure out if the field has already been added.
+    foreach ($this->fields as $existing_field) {
+      if (!empty($table)) {
+        // If table alias is given, check if field and table exists.
+        if ($existing_field['table'] == $table && $existing_field['field'] == $table_field) {
+          return $return;
+        }
+      }
+      else {
+        // If there is no table, simply check if the field exists as a field or
+        // an aliased field.
+        if ($existing_field['alias'] == $field) {
+          return $return;
+        }
+      }
+    }
+
+    // Also check expression aliases.
+    foreach ($this->expressions as $expression) {
+      if ($expression['alias'] == $field) {
+        return $return;
+      }
+    }
+
+    // If a table loads all fields, it can not be added again. It would
+    // result in an ambigious alias error because that field would be loaded
+    // twice: Once through table_alias.* and once directly. If the field
+    // actually belongs to a different table, it must be added manually.
+    foreach ($this->tables as $table) {
+      if (!empty($table['all_fields'])) {
+        return $return;
+      }
+    }
+
+    // If $field contains an characters which are not allowed in a field name
+    // it is considered an expression, these can't be handeld automatically
+    // either.
+    if ($this->connection->escapeField($field) != $field) {
+      return $return;
+    }
+
+    // This is a case that can be handled automatically, add the field.
+    $this->addField(NULL, $field);
+    return $return;
+  }
 }
Index: modules/search/search.extender.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/search/search.extender.inc,v
retrieving revision 1.7
diff -u -p -r1.7 search.extender.inc
--- modules/search/search.extender.inc	1 Sep 2010 01:43:50 -0000	1.7
+++ modules/search/search.extender.inc	23 Sep 2010 19:22:30 -0000
@@ -415,10 +415,6 @@ class SearchQuery extends SelectQueryExt
       // Add default score.
       $this->addScore('i.relevance');
     }
-    if (count($this->getOrderBy()) == 0) {
-      // Add default order.
-      $this->orderBy('calculated_score', 'DESC');
-    }
 
     if (count($this->multiply)) {
       // Add the total multiplicator as many times as requested to maintain
@@ -436,6 +432,11 @@ class SearchQuery extends SelectQueryExt
     // Convert scores to an expression.
     $this->addExpression('SUM(' . implode(' + ', $this->scores) . ')', 'calculated_score', $this->scoresArguments);
 
+    if (count($this->getOrderBy()) == 0) {
+      // Add default order after adding the expression.
+      $this->orderBy('calculated_score', 'DESC');
+    }
+
     // Add tag and useful metadata.
     $this
       ->addTag('search_' . $this->type)
Index: modules/simpletest/tests/entity_query.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/tests/entity_query.test,v
retrieving revision 1.11
diff -u -p -r1.11 entity_query.test
--- modules/simpletest/tests/entity_query.test	13 Sep 2010 06:03:21 -0000	1.11
+++ modules/simpletest/tests/entity_query.test	23 Sep 2010 19:22:31 -0000
@@ -652,16 +652,20 @@ class EntityFieldQueryTestCase extends D
     $query = new EntityFieldQuery();
     $query
       ->entityCondition('entity_type', 'test_entity_bundle_key')
-      ->propertyCondition('ftid', 1, 'CONTAINS');
+      ->propertyCondition('fttype', 'und', 'CONTAINS');
     $this->assertEntityFieldQuery($query, array(
       array('test_entity_bundle_key', 1),
+      array('test_entity_bundle_key', 2),
+      array('test_entity_bundle_key', 3),
+      array('test_entity_bundle_key', 4),
+      array('test_entity_bundle_key', 5),
+      array('test_entity_bundle_key', 6),
     ), t('Test the "contains" operation on a property.'));
 
     $query = new EntityFieldQuery();
-    $query->fieldCondition($this->fields[0], 'value', 3, 'CONTAINS');
+    $query->fieldCondition($this->fields[1], 'shape', 'uar', 'CONTAINS');
     $this->assertEntityFieldQuery($query, array(
-      array('test_entity_bundle_key', 3),
-      array('test_entity', 3),
+      array('test_entity_bundle', 5),
     ), t('Test the "contains" operation on a field.'));
 
     $query = new EntityFieldQuery();
