Index: modules/node/node.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/node.admin.inc,v
retrieving revision 1.83
diff -u -p -r1.83 node.admin.inc
--- modules/node/node.admin.inc	3 Jan 2010 21:01:04 -0000	1.83
+++ modules/node/node.admin.inc	7 Jan 2010 01:25:13 -0000
@@ -133,8 +133,8 @@ function node_build_filter_query(SelectQ
     list($key, $value) = $filter;
     switch ($key) {
       case 'term':
-        $index = 'tn' . $counter++;
-        $query->join('taxonomy_term_node', $index, "n.nid = $index.nid");
+        $index = 'ti' . $counter++;
+        $query->join('taxonomy_index', $index, "n.nid = $index.nid");
         $query->condition($index . '.tid', $value);
         break;
       case 'status':
Index: modules/node/node.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/node.module,v
retrieving revision 1.1198
diff -u -p -r1.1198 node.module
--- modules/node/node.module	6 Jan 2010 14:32:54 -0000	1.1198
+++ modules/node/node.module	7 Jan 2010 01:25:13 -0000
@@ -1576,8 +1576,8 @@ function node_search_execute($keys = NUL
   // Insert special keywords.
   $query->setOption('type', 'n.type');
   $query->setOption('language', 'n.language');
-  if ($query->setOption('term', 'tn.nid')) {
-    $query->join('taxonomy_term_node', 'tn', 'n.vid = tn.vid');
+  if ($query->setOption('term', 'ti.tid')) {
+    $query->join('taxonomy_index', 'ti', 'n.nid = ti.nid');
   }
   // Only continue if the first pass query matches.
   if (!$query->executeFirstPass()) {
@@ -2383,10 +2383,10 @@ function node_search_validate($form, &$f
     }
   }
 
-  if (isset($form_state['values']['term']) && is_array($form_state['values']['term'])) {
+  if (isset($form_state['values']['term']) && is_array($form_state['values']['term']) && count($form_state['values']['term'])) {
     $keys = search_expression_insert($keys, 'term', implode(',', $form_state['values']['term']));
   }
-  if (isset($form_state['values']['language']) && is_array($form_state['values']['language'])) {
+  if (isset($form_state['values']['language']) && is_array($form_state['values']['language']) && count($form_state['values']['language'])) {
     $keys = search_expression_insert($keys, 'language', implode(',', array_filter($form_state['values']['language'])));
   }
   if ($form_state['values']['or'] != '') {
Index: modules/node/node.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/node.test,v
retrieving revision 1.61
diff -u -p -r1.61 node.test
--- modules/node/node.test	29 Dec 2009 19:14:27 -0000	1.61
+++ modules/node/node.test	7 Jan 2010 01:25:13 -0000
@@ -1010,6 +1010,9 @@ class NodeAdminTestCase extends DrupalWe
 
   /**
    * Tests content overview with different user permissions.
+   *
+   * Taxonomy filters are tested separately.
+   * @see TaxonomyNodeFilterTestCase
    */
   function testContentAdminPages() {
     $this->drupalLogin($this->admin_user);
Index: modules/search/search.api.php
===================================================================
RCS file: /cvs/drupal/drupal/modules/search/search.api.php,v
retrieving revision 1.20
diff -u -p -r1.20 search.api.php
--- modules/search/search.api.php	6 Jan 2010 14:07:50 -0000	1.20
+++ modules/search/search.api.php	7 Jan 2010 01:25:13 -0000
@@ -156,8 +156,8 @@ function hook_search_execute($keys = NUL
   // Insert special keywords.
   $query->setOption('type', 'n.type');
   $query->setOption('language', 'n.language');
-  if ($query->setOption('term', 'tn.nid')) {
-    $query->join('taxonomy_term_node', 'tn', 'n.vid = tn.vid');
+  if ($query->setOption('term', 'ti.tid')) {
+    $query->join('taxonomy_index', 'ti', 'n.nid = ti.nid');
   }
   // Only continue if the first pass query matches.
   if (!$query->executeFirstPass()) {
Index: modules/taxonomy/taxonomy.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/taxonomy/taxonomy.test,v
retrieving revision 1.65
diff -u -p -r1.65 taxonomy.test
--- modules/taxonomy/taxonomy.test	4 Jan 2010 18:03:12 -0000	1.65
+++ modules/taxonomy/taxonomy.test	7 Jan 2010 01:25:14 -0000
@@ -834,3 +834,131 @@ class TaxonomyTermFieldTestCase extends 
     $this->assertText($term->name, t('Term name is displayed'));
   }
 }
+
+/**
+ * Test taxonomy filters in node forms.
+ */
+class TaxonomyNodeFilterTestCase extends TaxonomyWebTestCase {
+
+  public static function getInfo() {
+    return array(
+      'name'  => 'Taxonomy term filters in node forms',
+      'description'  => 'Test node form filtering by taxonomy terms.',
+      'group' => 'Taxonomy',
+    );
+  }
+
+  function setUp() {
+    parent::setUp();
+    $this->admin_user = $this->drupalCreateUser(array('access administration pages', 'access content overview', 'bypass node access', 'search content', 'use advanced search'));
+    $this->drupalLogin($this->admin_user);
+    $this->vocabulary = $this->createVocabulary();
+
+    $this->langcode = LANGUAGE_NONE;
+    $this->instance = array(
+      'field_name' => 'taxonomy_' . $this->vocabulary->machine_name,
+      'bundle' => 'article',
+      'object_type' => 'node',
+      'widget' => array(
+        'type' => 'options_select',
+      ),
+      'display' => array(
+        'full' => array(
+          'type' => 'taxonomy_term_reference_link',
+        ),
+      ),
+    );
+    field_create_instance($this->instance);
+  }
+
+  /**
+   * Test node administration page filtering by taxonomy terms.
+   */
+  function testContentAdminPage() {
+    // Create two taxonomy terms.
+    $term1 = $this->createTerm($this->vocabulary);
+    $term2 = $this->createTerm($this->vocabulary);
+
+    // Create nodes with various terms.
+    $nodes['article1'] = $this->drupalCreateNode(array('type' => 'article'));
+    $edit[$this->instance['field_name'] . '[' . $this->langcode . '][]'] = $term1->tid;
+    $this->drupalPost('node/' . $nodes['article1']->nid . '/edit', $edit, t('Save'));
+    
+    $nodes['article2'] = $this->drupalCreateNode(array('type' => 'article'));
+    $edit[$this->instance['field_name'] . '[' . $this->langcode . '][]'] = $term2->tid;
+    $this->drupalPost('node/' . $nodes['article2']->nid . '/edit', $edit, t('Save'));
+
+    $nodes['article1_2'] = $this->drupalCreateNode(array('type' => 'article'));
+    $edit[$this->instance['field_name'] . '[' . $this->langcode . '][]'] = array($term1->tid, $term2->tid);
+    $this->drupalPost('node/' . $nodes['article1_2']->nid . '/edit', $edit, t('Save'));
+
+    // Verify that nodes appear on content admin page.
+    $this->drupalGet('admin/content');
+    $this->assertResponse(200);
+    foreach ($nodes as $node) {
+      $this->assertLinkByHref('node/' . $node->nid);
+    }
+
+    // Verify filtering by term 1.
+    $edit = array(
+      'term' => $term1->tid,
+    );
+    $this->drupalPost(NULL, $edit, t('Filter'));
+    $this->assertRaw(t('<strong>%type</strong> is <strong>%name</strong>', array('%type' => 'term', '%name' => $term1->name)), t('Content list is filtered by term 1.'));
+    $this->assertLinkByHref('node/' . $nodes['article1']->nid . '/edit');
+    $this->assertLinkByHref('node/' . $nodes['article1_2']->nid . '/edit');
+    $this->assertNoLinkByHref('node/' . $nodes['article2']->nid . '/edit');
+
+    // Verify filtering by term 1 and term 2.
+    $edit = array(
+      'term' => $term2->tid,
+    );
+    $this->drupalPost(NULL, $edit, t('Refine'));
+    $this->assertRaw(t('<strong>%type</strong> is <strong>%name</strong>', array('%type' => 'term', '%name' => $term1->name)), t('Content list is filtered by term 1.'));
+    $this->assertRaw(t('<strong>%type</strong> is <strong>%name</strong>', array('%type' => 'term', '%name' => $term2->name)), t('Content list is filtered by term 2.'));
+    $this->assertLinkByHref('node/' . $nodes['article1_2']->nid . '/edit');
+    $this->assertNoLinkByHref('node/' . $nodes['article1']->nid . '/edit');
+    $this->assertNoLinkByHref('node/' . $nodes['article2']->nid . '/edit');
+
+    // Verify filtering by term 2.
+    $this->drupalPost(NULL, $edit, t('Reset'));
+    $edit = array(
+      'term' => $term2->tid,
+    );
+    $this->drupalPost(NULL, $edit, t('Filter'));
+    $this->assertRaw(t('<strong>%type</strong> is <strong>%name</strong>', array('%type' => 'term', '%name' => $term2->name)), t('Content list is filtered by term 2.'));
+    $this->assertLinkByHref('node/' . $nodes['article2']->nid . '/edit');
+    $this->assertLinkByHref('node/' . $nodes['article1_2']->nid . '/edit');
+    $this->assertNoLinkByHref('node/' . $nodes['article1']->nid . '/edit');
+  }
+
+  /**
+   * Test advanced search filtering by taxonomy terms.
+   */
+  function testAdvancedSearch() {
+    // Create two taxonomy terms.
+    $term1 = $this->createTerm($this->vocabulary);
+    $term2 = $this->createTerm($this->vocabulary);
+
+    // Create a node with the term.
+    $node = $this->drupalCreateNode(array('type' => 'article'));
+    $edit[$this->instance['field_name'] . '[' . $this->langcode . '][]'] = $term1->tid;
+    $this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
+
+    // Update the search index.
+    node_update_index();
+    search_update_totals();
+    
+    // Search for the node title.
+    $this->drupalGet('search/node/' . $node->title[$this->langcode][0]['value']);
+    $this->assertText($node->title[$this->langcode][0]['value'], t('Article node found with search.'));
+
+    // Search for the node title, filtering by term 1.
+    $this->drupalGet('search/node/' . $node->title[$this->langcode][0]['value'] . ' term:' . $term1->tid);
+    $this->assertText($node->title[$this->langcode][0]['value'], t('Article node found with search filtering by term 1.'));
+
+    // Search for the node title, filtering by term 2.
+    $this->drupalGet('search/node/' . $node->title[$this->langcode][0]['value'] . ' term:' . $term2->tid);
+    $this->assertNoText($node->title[$this->langcode][0]['value'], t('Article node not found with search filtering by term 2.'));
+  }
+}
