diff --git a/plugins/views_plugin_cache.inc b/plugins/views_plugin_cache.inc
index 7bf733f..81f71bf 100644
--- a/plugins/views_plugin_cache.inc
+++ b/plugins/views_plugin_cache.inc
@@ -256,59 +256,61 @@ class views_plugin_cache extends views_plugin {
   }
 
   function get_results_key() {
-    global $user;
-
     if (!isset($this->_results_key)) {
-
-      $build_info = $this->view->build_info;
-
-      $query_plugin = $this->view->display_handler->get_plugin('query');
-
-      foreach (array('query','count_query') as $index) {
-        // If the default query back-end is used generate SQL query strings from
-        // the query objects.
-        if ($build_info[$index] instanceof SelectQueryInterface) {
-          $query = clone $build_info[$index];
-          $query->preExecute();
-          $build_info[$index] = (string) $query;
-        }
-      }
-      $key_data = array(
-        'build_info' => $build_info,
-        'roles' => array_keys($user->roles),
-        'super-user' => $user->uid == 1, // special caching for super user.
-        'language' => $GLOBALS['language']->language,
-        'base_url' => $GLOBALS['base_url'],
-      );
-      foreach (array('exposed_info', 'page', 'sort', 'order', 'items_per_page', 'offset') as $key) {
-        if (isset($_GET[$key])) {
-          $key_data[$key] = $_GET[$key];
-        }
-      }
-
-      $this->_results_key = $this->view->name . ':' . $this->display->id . ':results:' . md5(serialize($key_data));
+      $this->_results_key = $this->view->name . ':' . $this->display->id . ':results:' . $this->get_cache_key();
     }
 
     return $this->_results_key;
   }
 
   function get_output_key() {
-    global $user;
     if (!isset($this->_output_key)) {
       $key_data = array(
-        'result' => $this->view->result,
-        'roles' => array_keys($user->roles),
-        'super-user' => $user->uid == 1, // special caching for super user.
         'theme' => $GLOBALS['theme'],
-        'language' => $GLOBALS['language']->language,
-        'base_url' => $GLOBALS['base_url'],
       );
-
-      $this->_output_key = $this->view->name . ':' . $this->display->id . ':output:' . md5(serialize($key_data));
+      $this->_output_key = $this->view->name . ':' . $this->display->id . ':output:' . $this->get_cache_key($key_data);
     }
 
     return $this->_output_key;
   }
+
+  /**
+   * Returns cache key.
+   *
+   * @param array $key_data
+   *   Additional data for cache segmentation and/or overrides for default
+   *   segmentation.
+   *
+   * @return string
+   */
+  function get_cache_key($key_data = array()) {
+    global $user;
+
+    $key_data += array(
+      'roles' => array_keys($user->roles),
+      'super-user' => $user->uid == 1, // special caching for super user.
+      'language' => $GLOBALS['language']->language,
+      'base_url' => $GLOBALS['base_url'],
+    );
+
+    if (empty($key_data['build_info'])) {
+      $build_info = $this->view->build_info;
+      foreach (array('query','count_query') as $index) {
+        // If the default query back-end is used generate SQL query strings from
+        // the query objects.
+        if ($build_info[$index] instanceof SelectQueryInterface) {
+          $query = clone $build_info[$index];
+          $query->preExecute();
+          $key_data['build_info'][$index] = array(
+            'sql' => (string) $query,
+            'arguments' => $query->getArguments(),
+          );
+        }
+      }
+    }
+    $key = md5(serialize($key_data));
+    return $key;
+  }
 }
 
 /**
diff --git a/plugins/views_plugin_query_default.inc b/plugins/views_plugin_query_default.inc
index 030c5ea..8a15e8d 100644
--- a/plugins/views_plugin_query_default.inc
+++ b/plugins/views_plugin_query_default.inc
@@ -1365,6 +1365,16 @@ class views_plugin_query_default extends views_plugin_query {
     // Add all query substitutions as metadata.
     $query->addMetaData('views_substitutions', module_invoke_all('views_query_substitutions', $this));
 
+    if (!$get_count) {
+      if (!empty($this->limit) || !empty($this->offset)) {
+        // We can't have an offset without a limit, so provide a very large limit
+        // instead.
+        $limit  = intval(!empty($this->limit) ? $this->limit : 999999);
+        $offset = intval(!empty($this->offset) ? $this->offset : 0);
+        $query->range($offset, $limit);
+      }
+    }
+
     return $query;
   }
 
@@ -1469,16 +1479,8 @@ class views_plugin_query_default extends views_plugin_query {
           $this->pager->execute_count_query($count_query);
         }
 
-        // Let the pager modify the query to add limits.
         $this->pager->pre_execute($query);
 
-        if (!empty($this->limit) || !empty($this->offset)) {
-          // We can't have an offset without a limit, so provide a very large limit instead.
-          $limit  = intval(!empty($this->limit) ? $this->limit : 999999);
-          $offset = intval(!empty($this->offset) ? $this->offset : 0);
-          $query->range($offset, $limit);
-        }
-
         $result = $query->execute();
 
         $view->result = array();
diff --git a/tests/views_cache.test b/tests/views_cache.test
index 3103762..28534a2 100644
--- a/tests/views_cache.test
+++ b/tests/views_cache.test
@@ -241,4 +241,68 @@ class ViewsCacheTest extends ViewsSqlTest {
     $this->assertEqual($first_content_type, $second_content_type, t('Content types of responses are equal.'));
   }
 
+  /**
+   * Test caching of different exposed filter values with the same view result.
+   *
+   * Make sure the output is different.
+   */
+  function testExposedFilterSameResultsCaching() {
+    // Create the view with time-based cache with hour lifetimes and add exposed
+    // filter to it with "Starts with" operator.
+    $view = $this->getBasicView();
+    $view->set_display();
+    $view->display_handler->override_option('cache', array(
+      'type' => 'time',
+      'results_lifespan' => '3600',
+      'output_lifespan' => '3600',
+    ));
+    $view->display_handler->override_option('filters', array(
+      'name' => array(
+        'id' => 'name',
+        'table' => 'views_test',
+        'field' => 'name',
+        'relationship' => 'none',
+        'operator' => 'starts',
+        'exposed' => TRUE,
+        'expose' => array(
+          'operator_id' => 'name_op',
+          'operator' => 'name_op',
+          'identifier' => 'name',
+        ),
+      ),
+    ));
+
+    // Clone the view before setting exposed input.
+    $clone = $view->copy();
+
+    // Pass "Rin" to the exposed filter and check that only one row returned.
+    $view->set_exposed_input(array(
+      'name' => 'Rin',
+    ));
+    $this->executeView($view);
+    $first_result = $view->result;
+    $first_output = $view->render();
+    $this->assertEqual(1, count($first_result), t('The number of rows returned by the first view match.'));
+
+    // Pass full "Ringo" to the exposed filter at the second time and make sure
+    // results are the same.
+    $clone->set_exposed_input(array(
+      'name' => 'Ringo',
+    ));
+    $this->executeView($clone);
+    $second_result = $clone->result;
+    $second_output = $clone->render();
+    $this->assertEqual($first_result, $second_result, t('Results of both views are the same.'));
+
+    // Check that output is not the same and it contains full "Ringo" word in
+    // default value of exposed input.
+    $this->assertNotEqual($first_output, $second_output, t('Output of the second view is different.'));
+    $this->drupalSetContent($second_output);
+    $element = $this->xpath('//input[@name="name" and @value="Ringo"]');
+    $this->assertTrue(!empty($element), t('Input field of exposed filter has the second value.'));
+
+    $view->destroy();
+    $clone->destroy();
+  }
+
 }
