=== modified file 'includes/database/database.inc'
--- includes/database/database.inc	2009-12-04 16:31:04 +0000
+++ includes/database/database.inc	2009-12-10 07:21:45 +0000
@@ -1980,6 +1980,89 @@ class DatabaseStatementBase extends PDOS
 }
 
 /**
+ * Empty implementation of a database statement.
+ *
+ * This class satisfies the requirements of being a database statement/result
+ * object, but does not actually contain data.  It is useful when developers
+ * need to safely return an "empty" result set without connecting to an actual
+ * database.  Calling code can then treat it the same as if it were an actual
+ * result set that happens to contain no records.
+ */
+class DatabaseStatementEmpty implements Iterator, DatabaseStatementInterface {
+
+  public function execute($args = array(), $options = array()) {
+    return FALSE;
+  }
+
+  public function getQueryString() {
+    return '';
+  }
+
+  public function rowCount() {
+    return 0;
+  }
+
+  public function setFetchMode($mode, $a1 = NULL, $a2 = array()) {
+    return;
+  }
+
+  public function fetch($mode = NULL, $cursor_orientation = NULL, $cursor_offset = NULL) {
+    return NULL;
+  }
+
+  public function fetchField($index = 0) {
+    return NULL;
+  }
+
+  public function fetchObject() {
+    return NULL;
+  }
+
+  public function fetchAssoc() {
+    return NULL;
+  }
+
+  function fetchAll($mode = NULL, $column_index = NULL, array $constructor_arguments = array()) {
+    return array();
+  }
+
+  public function fetchCol($index = 0) {
+    return array();
+  }
+
+  public function fetchAllKeyed($key_index = 0, $value_index = 1) {
+    return array();
+  }
+
+  public function fetchAllAssoc($key, $fetch = PDO::FETCH_OBJ) {
+    return array();
+  }
+
+  /* Implementations of Iterator. */
+
+  public function current() {
+    return NULL;
+  }
+
+  public function key() {
+    return NULL;
+  }
+
+  public function rewind() {
+    // Nothing to do: our DatabaseStatement can't be rewound.
+  }
+
+  public function next() {
+    // Do nothing, since this is an always-empty implementation.
+  }
+
+  public function valid() {
+    return FALSE;
+  }
+}
+
+
+/**
  * The following utility functions are simply convenience wrappers.
  * They should never, ever have any database-specific code in them.
  */

=== modified file 'modules/search/search.extender.inc'
--- modules/search/search.extender.inc	2009-08-29 12:43:18 +0000
+++ modules/search/search.extender.inc	2009-12-10 07:24:45 +0000
@@ -404,7 +404,7 @@ class SearchQuery extends SelectQueryExt
       $this->executeFirstPass();
     }
     if (!$this->normalize) {
-      return FALSE;
+      return new DatabaseStatementEmpty();
     }
 
     $this->join('search_dataset', 'd', 'i.sid = d.sid AND i.type = d.type');

=== modified file 'modules/simpletest/tests/database_test.test'
--- modules/simpletest/tests/database_test.test	2009-12-09 19:01:14 +0000
+++ modules/simpletest/tests/database_test.test	2009-12-10 06:36:58 +0000
@@ -1889,19 +1889,19 @@ class DatabaseSelectComplexTestCase exte
     $query->fields('test');
     $query->orderBy('name');
     $count = $query->countQuery();
-    
+
     // Check that the 'all_fields' statement is handled properly.
     $tables = $query->getTables();
     $this->assertEqual($tables['test']['all_fields'], 1, t('Query correctly sets \'all_fields\' statement.'));
     $tables = $count->getTables();
-    $this->assertFalse(isset($tables['test']['all_fields']), t('Count query correctly unsets \'all_fields\' statement.'));  
+    $this->assertFalse(isset($tables['test']['all_fields']), t('Count query correctly unsets \'all_fields\' statement.'));
 
     // Check that the ordering clause is handled properly.
     $orderby = $query->getOrderBy();
     $this->assertEqual($orderby['name'], 'ASC', t('Query correctly sets ordering clause.'));
     $orderby = $count->getOrderBy();
     $this->assertFalse(isset($orderby['name']), t('Count query correctly unsets ordering caluse.'));
-    
+
     // Make sure that the count query works.
     $count = $count->execute()->fetchField();
 
@@ -3098,3 +3098,48 @@ class DatabaseNextIdCase extends DrupalW
     $this->assertEqual($result, 1001, t('Sequence provides a larger number than the existing ID.'));
   }
 }
+
+
+class DatabaseEmptyStatementTestCase extends DrupalWebTestCase {
+  function getInfo() {
+    return array(
+      'name' => t('Empty statement'),
+      'description' => t('Test the empty pseudo-statement class.'),
+      'group' => t('Database'),
+    );
+  }
+
+  /**
+   * Test that the empty result set behaves as empty.
+   */
+  function testEmpty() {
+    $result = new DatabaseStatementEmpty();
+
+    $this->assertTrue($result instanceof DatabaseStatementInterface, t('Class implements expected interface'));
+    $this->assertNull($result->fetchObject(), t('Null result returned.'));
+  }
+
+  /**
+   * Test that the empty result set iterates safely.
+   */
+  function testEmptyIteration() {
+    $result = new DatabaseStatementEmpty();
+
+    foreach ($result as $record) {
+      $this->fail(t('Iterating empty result set should not iterate.'));
+      return;
+    }
+
+    $this->pass(t('Iterating empty result set skipped iteration.'));
+  }
+
+  /**
+   * Test that the empty result set mass-fetches in an expected way.
+   */
+  function testEmptyFetchAll() {
+    $result = new DatabaseStatementEmpty();
+
+    $this->assertEqual($result->fetchAll(), array(), t('Empty array returned from empty result set.'));
+  }
+
+}

