diff --git a/core/lib/Drupal/Core/Config/Entity/Query/Query.php b/core/lib/Drupal/Core/Config/Entity/Query/Query.php
index b8660aa050fc5815314d7d3169a905ae239f85cb..2ad4db5ee5ff6dfc95a06215c7eae487cff5e4f9 100644
--- a/core/lib/Drupal/Core/Config/Entity/Query/Query.php
+++ b/core/lib/Drupal/Core/Config/Entity/Query/Query.php
@@ -8,7 +8,6 @@
 namespace Drupal\Core\Config\Entity\Query;
 
 use Drupal\Core\Config\ConfigFactoryInterface;
-use Drupal\Core\Entity\EntityManagerInterface;
 use Drupal\Core\Entity\EntityTypeInterface;
 use Drupal\Core\Entity\Query\QueryBase;
 use Drupal\Core\Entity\Query\QueryInterface;
diff --git a/core/lib/Drupal/Core/Entity/Query/QueryBase.php b/core/lib/Drupal/Core/Entity/Query/QueryBase.php
index 4465efd0a380da6cac37860294e9150abc81f1db..6f3d6aa4ce25e8c1a8f696cece60ebb6bdaba962 100644
--- a/core/lib/Drupal/Core/Entity/Query/QueryBase.php
+++ b/core/lib/Drupal/Core/Entity/Query/QueryBase.php
@@ -8,7 +8,6 @@
 namespace Drupal\Core\Entity\Query;
 
 use Drupal\Core\Database\Query\PagerSelectExtender;
-use Drupal\Core\Entity\EntityStorageInterface;
 use Drupal\Core\Entity\EntityTypeInterface;
 
 /**
@@ -110,12 +109,9 @@ abstract class QueryBase implements QueryInterface {
   /**
    * Flag indicating whether to query the current revision or all revisions.
    *
-   * Can be either EntityStorageInterface::FIELD_LOAD_CURRENT or
-   * EntityStorageInterface::FIELD_LOAD_REVISION.
-   *
-   * @var string
+   * @var bool
    */
-  protected $age = EntityStorageInterface::FIELD_LOAD_CURRENT;
+  protected $allRevisions = FALSE;
 
   /**
    * The query pager data.
@@ -257,10 +253,18 @@ public function accessCheck($access_check = TRUE) {
   }
 
   /**
-   * Implements \Drupal\Core\Entity\Query\QueryInterface::age().
+   * {@inheritdoc}
+   */
+  public function currentRevision() {
+    $this->allRevisions = FALSE;
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
    */
-  public function age($age = EntityStorageInterface::FIELD_LOAD_CURRENT) {
-    $this->age = $age;
+  public function allRevisions() {
+    $this->allRevisions = TRUE;
     return $this;
   }
 
diff --git a/core/lib/Drupal/Core/Entity/Query/QueryInterface.php b/core/lib/Drupal/Core/Entity/Query/QueryInterface.php
index 0fad28ca0d911e81e59b2e3dcec5e152546f9d28..2ddbd5dbf3357a4adb400ff2405f5da1c1edca6a 100644
--- a/core/lib/Drupal/Core/Entity/Query/QueryInterface.php
+++ b/core/lib/Drupal/Core/Entity/Query/QueryInterface.php
@@ -7,7 +7,6 @@
 
 namespace Drupal\Core\Entity\Query;
 
-use Drupal\Core\Entity\EntityStorageInterface;
 use Drupal\Core\Database\Query\AlterableInterface;
 
 /**
@@ -165,24 +164,6 @@ public function tableSort(&$headers);
    */
   public function accessCheck($access_check = TRUE);
 
-  /**
-   * Queries the current or every revision.
-   *
-   * Note that this only affects field conditions. Property conditions always
-   * apply to the current revision.
-   * @TODO: Once revision tables have been cleaned up, revisit this.
-   *
-   * @param $age
-   *   - EntityStorageInterface::FIELD_LOAD_CURRENT (default): Query
-   *     the most recent revisions only,
-   *   - EntityStorageInterface::FIELD_LOAD_REVISION: Query all
-   *     revisions.
-   *
-   * @return \Drupal\Core\Entity\Query\QueryInterface
-   *   The called object.
-   */
-  public function age($age = EntityStorageInterface::FIELD_LOAD_CURRENT);
-
   /**
    * Execute the query.
    *
@@ -244,4 +225,18 @@ public function andConditionGroup();
    */
   public function orConditionGroup();
 
+  /**
+   * Queries the current revision.
+   *
+   * @return $this
+   */
+  public function currentRevision();
+
+  /**
+   * Queries all the revisions.
+   *
+   * @return $this
+   */
+  public function allRevisions();
+
 }
diff --git a/core/lib/Drupal/Core/Entity/Query/Sql/Query.php b/core/lib/Drupal/Core/Entity/Query/Sql/Query.php
index cf8eb39502cf543eb6e445b118655179a2436d6d..626961724dccc2430839f4c77cb072dc8f4baddb 100644
--- a/core/lib/Drupal/Core/Entity/Query/Sql/Query.php
+++ b/core/lib/Drupal/Core/Entity/Query/Sql/Query.php
@@ -9,7 +9,6 @@
 
 use Drupal\Core\Database\Connection;
 use Drupal\Core\Database\Query\SelectInterface;
-use Drupal\Core\Entity\EntityManagerInterface;
 use Drupal\Core\Entity\EntityTypeInterface;
 use Drupal\Core\Entity\Query\QueryBase;
 use Drupal\Core\Entity\Query\QueryException;
@@ -100,8 +99,15 @@ public function execute() {
    *   Returns the called object.
    */
   protected function prepare() {
-    if (!$base_table = $this->entityType->getBaseTable()) {
-      throw new QueryException("No base table, invalid query.");
+    if ($this->allRevisions) {
+      if (!$base_table = $this->entityType->getRevisionTable()) {
+        throw new QueryException("No revision table for " . $this->entityTypeId . ", invalid query.");
+      }
+    }
+    else {
+      if (!$base_table = $this->entityType->getBaseTable()) {
+        throw new QueryException("No base table for " . $this->entityTypeId . ", invalid query.");
+      }
     }
     $simple_query = TRUE;
     if ($this->entityType->getDataTable()) {
@@ -146,7 +152,7 @@ protected function prepare() {
     }
     // This now contains first the table containing entity properties and
     // last the entity base table. They might be the same.
-    $this->sqlQuery->addMetaData('age', $this->age);
+    $this->sqlQuery->addMetaData('all_revisions', $this->allRevisions);
     $this->sqlQuery->addMetaData('simple_query', $simple_query);
     return $this;
   }
diff --git a/core/lib/Drupal/Core/Entity/Query/Sql/Tables.php b/core/lib/Drupal/Core/Entity/Query/Sql/Tables.php
index 6e1ecf1703956d92a727a8b787f24284008006a1..31925b40a82d80211209a95979865c67984a7011 100644
--- a/core/lib/Drupal/Core/Entity/Query/Sql/Tables.php
+++ b/core/lib/Drupal/Core/Entity/Query/Sql/Tables.php
@@ -8,7 +8,6 @@
 namespace Drupal\Core\Entity\Query\Sql;
 
 use Drupal\Core\Database\Query\SelectInterface;
-use Drupal\Core\Entity\EntityStorageInterface;
 use Drupal\Core\Entity\Query\QueryException;
 use Drupal\Core\Entity\Sql\SqlEntityStorageInterface;
 
@@ -68,7 +67,7 @@ public function __construct(SelectInterface $sql_query) {
    */
   public function addField($field, $type, $langcode) {
     $entity_type_id = $this->sqlQuery->getMetaData('entity_type');
-    $age = $this->sqlQuery->getMetaData('age');
+    $all_revisions = $this->sqlQuery->getMetaData('all_revisions');
     // This variable ensures grouping works correctly. For example:
     // ->condition('tags', 2, '>')
     // ->condition('tags', 20, '<')
@@ -89,7 +88,7 @@ public function addField($field, $type, $langcode) {
     for ($key = 0; $key <= $count; $key ++) {
       // If there is revision support and only the current revision is being
       // queried then use the revision id. Otherwise, the entity id will do.
-      if (($revision_key = $entity_type->getKey('revision')) && $age == EntityStorageInterface::FIELD_LOAD_CURRENT) {
+      if (($revision_key = $entity_type->getKey('revision')) && $all_revisions) {
         // This contains the relevant SQL field to be used when joining entity
         // tables.
         $entity_id_field = $revision_key;
@@ -158,11 +157,11 @@ public function addField($field, $type, $langcode) {
         // finds the property first. The data table is preferred, which is why
         // it gets added before the base table.
         $entity_tables = array();
-        if ($data_table = $entity_type->getDataTable()) {
+        if ($data_table = $all_revisions ? $entity_type->getRevisionDataTable() : $entity_type->getDataTable()) {
           $this->sqlQuery->addMetaData('simple_query', FALSE);
           $entity_tables[$data_table] = $this->getTableMapping($data_table, $entity_type_id);
         }
-        $entity_base_table = $entity_type->getBaseTable();
+        $entity_base_table = $all_revisions ? $entity_type->getRevisionTable() : $entity_type->getBaseTable();
         $entity_tables[$entity_base_table] = $this->getTableMapping($entity_base_table, $entity_type_id);
         $sql_column = $specifier;
 
@@ -265,7 +264,7 @@ protected function ensureFieldTable($index_prefix, &$field, $type, $langcode, $b
       $entity_type_id = $this->sqlQuery->getMetaData('entity_type');
       /** @var \Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping */
       $table_mapping = $this->entityManager->getStorage($entity_type_id)->getTableMapping();
-      $table = $this->sqlQuery->getMetaData('age') == EntityStorageInterface::FIELD_LOAD_CURRENT ? $table_mapping->getDedicatedDataTableName($field) : $table_mapping->getDedicatedRevisionTableName($field);
+      $table = !$this->sqlQuery->getMetaData('all_revisions') ? $table_mapping->getDedicatedDataTableName($field) : $table_mapping->getDedicatedRevisionTableName($field);
       if ($field->getCardinality() != 1) {
         $this->sqlQuery->addMetaData('simple_query', FALSE);
       }
diff --git a/core/modules/system/src/Tests/Entity/EntityQueryTest.php b/core/modules/system/src/Tests/Entity/EntityQueryTest.php
index f66ab4e0d688f9efd607f60135b59acafa4bafbf..a46eb14cfc73ab7122da28d26193b26db98185ec 100644
--- a/core/modules/system/src/Tests/Entity/EntityQueryTest.php
+++ b/core/modules/system/src/Tests/Entity/EntityQueryTest.php
@@ -8,7 +8,6 @@
 namespace Drupal\system\Tests\Entity;
 
 use Drupal\Component\Utility\Unicode;
-use Drupal\Core\Entity\EntityStorageInterface;
 use Drupal\entity_test\Entity\EntityTestMulRev;
 use Drupal\field\Entity\FieldConfig;
 use Drupal\field\Entity\FieldStorageConfig;
@@ -225,11 +224,26 @@ function testEntityQuery() {
       ->sort('id')
       ->execute();
     $entities = entity_load_multiple('entity_test_mulrev', $ids);
+    $first_entity = reset($entities);
+    $old_name = $first_entity->name->value;
     foreach ($entities as $entity) {
       $entity->setNewRevision();
       $entity->getTranslation('tr')->$greetings->value = 'xsiemax';
+      $entity->name->value .= 'x';
       $entity->save();
     }
+    // We changed the entity names, so the current revision should not match.
+    $this->queryResults = $this->factory->get('entity_test_mulrev')
+      ->condition('name.value', $old_name)
+      ->execute();
+    $this->assertResult();
+    // Only if all revisions are queried, we find the old revision.
+    $this->queryResults = $this->factory->get('entity_test_mulrev')
+      ->condition('name.value', $old_name)
+      ->allRevisions()
+      ->sort('revision_id')
+      ->execute();
+    $this->assertRevisionResult(array($first_entity->id()), array($first_entity->id()));
     // When querying current revisions, this string is no longer found.
     $this->queryResults = $this->factory->get('entity_test_mulrev')
       ->condition("$greetings.value", 'merhaba')
@@ -237,21 +251,18 @@ function testEntityQuery() {
     $this->assertResult();
     $this->queryResults = $this->factory->get('entity_test_mulrev')
       ->condition("$greetings.value", 'merhaba')
-      ->age(EntityStorageInterface::FIELD_LOAD_REVISION)
+      ->allRevisions()
       ->sort('revision_id')
       ->execute();
-    // Bit 2 needs to be set.
-    // The keys must be 16-23 because the first batch stopped at 15 so the
-    // second started at 16 and eight entities were saved.
-    $assert = $this->assertRevisionResult(range(16, 23), array(4, 5, 6, 7, 12, 13, 14, 15));
+    // The query only matches the original revisions.
+    $this->assertRevisionResult(array(4, 5, 6, 7, 12, 13, 14, 15), array(4, 5, 6, 7, 12, 13, 14, 15));
     $results = $this->factory->get('entity_test_mulrev')
       ->condition("$greetings.value", 'siema', 'CONTAINS')
       ->sort('id')
       ->execute();
-    // This is the same as the previous one because xsiemax replaced merhaba
-    // but also it contains the entities that siema originally but not
-    // merhaba.
-    $assert = array_slice($assert, 0, 4, TRUE) + array(8 => '8', 9 => '9', 10 => '10', 11 => '11') + array_slice($assert, 4, 4, TRUE);
+    // This matches both the original and new current revisions, multiple
+    // revisions are returned for some entities.
+    $assert = array(16 => '4', 17 => '5', 18 => '6', 19 => '7', 8 => '8', 9 => '9', 10 => '10', 11 => '11', 20 => '12', 21 => '13', 22 => '14', 23 => '15');
     $this->assertIdentical($results, $assert);
     $results = $this->factory->get('entity_test_mulrev')
       ->condition("$greetings.value", 'siema', 'STARTS_WITH')
@@ -269,10 +280,12 @@ function testEntityQuery() {
     $this->assertIdentical($results, array_slice($assert, 4, 8, TRUE));
     $results = $this->factory->get('entity_test_mulrev')
       ->condition("$greetings.value", 'a', 'ENDS_WITH')
-      ->age(EntityStorageInterface::FIELD_LOAD_REVISION)
+      ->allRevisions()
       ->sort('id')
+      ->sort('revision_id')
       ->execute();
     // Now we get everything.
+    $assert = array(4 => '4', 5 => '5', 6 => '6', 7 => '7', 8 => '8', 9 => '9', 10 => '10', 11 => '11', 12 => '12', 20 => '12', 13 => '13', 21 => '13', 14 => '14', 22 => '14', 15 => '15', 23 => '15');
     $this->assertIdentical($results, $assert);
   }
 
@@ -706,4 +719,47 @@ public function testBaseFieldMultipleColumns() {
     $this->assertEqual($term1->id(), reset($ids));
   }
 
+  /**
+   * Test forward-revisions.
+   */
+  public function testForwardRevisions() {
+    // Ensure entity 14 is returned.
+    $result = \Drupal::entityQuery('entity_test_mulrev')
+      ->condition('id', [14], 'IN')
+      ->execute();
+    $this->assertEqual(count($result), 1);
+
+    // Set a revision on entity 14 that isn't the current default.
+    $entity = EntityTestMulRev::load(14);
+    $current_values = $entity->{$this->figures}->getValue();
+
+    $entity->setNewRevision(TRUE);
+    $entity->isDefaultRevision(FALSE);
+    $entity->{$this->figures}->setValue([
+      'color' => 'red',
+      'shape' => 'square'
+    ]);
+    $entity->save();
+
+    // Entity query should still return entity 14.
+    $result = \Drupal::entityQuery('entity_test_mulrev')
+      ->condition('id', [14], 'IN')
+      ->execute();
+    $this->assertEqual(count($result), 1);
+
+    // Verify that field conditions on the default and forward revision are
+    // work as expected.
+    $result = \Drupal::entityQuery('entity_test_mulrev')
+      ->condition('id', [14], 'IN')
+      ->condition("$this->figures.color", $current_values[0]['color'])
+      ->execute();
+    $this->assertEqual($result, [14 => '14']);
+    $result = $this->factory->get('entity_test_mulrev')
+      ->condition('id', [14], 'IN')
+      ->condition("$this->figures.color", 'red')
+      ->allRevisions()
+      ->execute();
+    $this->assertEqual($result, [16 => '14']);
+  }
+
 }
diff --git a/core/tests/Drupal/Tests/Core/Entity/Query/Sql/QueryTest.php b/core/tests/Drupal/Tests/Core/Entity/Query/Sql/QueryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..1a053839cc64815f9657aaed4784e8e193681d62
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Entity/Query/Sql/QueryTest.php
@@ -0,0 +1,64 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\Core\Entity\Query\Sql\QueryTest.
+ */
+
+namespace Drupal\Tests\Core\Entity\Query\Sql;
+
+use Drupal\Core\Entity\EntityType;
+use Drupal\Tests\UnitTestCase;
+use Drupal\Core\Entity\Query\Sql\Query;
+
+/**
+ * @coversDefaultClass \Drupal\Core\Entity\Query\Sql\Query
+ * @group Entity
+ */
+class QueryTest extends UnitTestCase {
+
+  /**
+   * The query object.
+   *
+   * @var \Drupal\Core\Entity\Query\Sql\Query
+   */
+  protected $query;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $entity_type = new EntityType(['id' => 'example_entity_query']);
+    $conjunction = 'AND';
+    $connection = $this->getMockBuilder('Drupal\Core\Database\Connection')->disableOriginalConstructor()->getMock();
+    $namespaces = ['Drupal\Core\Entity\Query\Sql'];
+
+    $this->query = new Query($entity_type, $conjunction, $connection, $namespaces);
+  }
+
+  /**
+   * Tests entity query for entity type without base table.
+   *
+   * @covers ::prepare
+   *
+   * @expectedException \Drupal\Core\Entity\Query\QueryException
+   * @expectedExceptionMessage No base table for example_entity_query, invalid query.
+   */
+  public function testNoBaseTable() {
+    $this->query->execute();
+  }
+
+  /**
+   * Tests revision entity query for entity type without revision table.
+   *
+   * @covers ::prepare
+   *
+   * @expectedException \Drupal\Core\Entity\Query\QueryException
+   * @expectedExceptionMessage No revision table for example_entity_query, invalid query.
+   */
+  public function testNoRevisionTable() {
+    $this->query->allRevisions()->execute();
+  }
+
+}