From cc88102d298ae5ea470b606fc8e8e7d71562a050 Mon Sep 17 00:00:00 2001
From: Nathaniel Catchpole <catch@35733.no-reply.drupal.org>
Date: Tue, 29 Mar 2016 08:25:43 +0900
Subject: [PATCH] Issue #2664748 by amateescu, alexpott, TravisCarden: Node
 revision queries tagged for node access cause "no node table" exception

---
 core/modules/node/node.module                  | 15 +++++++++++++--
 .../node/src/Tests/NodeQueryAlterTest.php      | 18 ++++++++++++++++++
 2 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index ff8e05176fcb..ebfd07ff9f2d 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -1047,18 +1047,29 @@ function node_query_node_access_alter(AlterableInterface $query) {
 
   $tables = $query->getTables();
   $base_table = $query->getMetaData('base_table');
-  // If the base table is not given, default to node if present.
+  // If the base table is not given, default to one of the node base tables.
   if (!$base_table) {
+    /** @var \Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping */
+    $table_mapping = \Drupal::entityTypeManager()->getStorage('node')->getTableMapping();
+    $node_base_tables = $table_mapping->getTableNames();
+
     foreach ($tables as $table_info) {
       if (!($table_info instanceof SelectInterface)) {
         $table = $table_info['table'];
-        // If the node table is in the query, it wins immediately.
+        // Ensure that 'node' and 'node_field_data' are always preferred over
+        // 'node_revision' and 'node_field_revision'.
         if ($table == 'node' || $table == 'node_field_data') {
           $base_table = $table;
           break;
         }
+        // If one of the node base tables are in the query, add it to the list
+        // of possible base tables to join against.
+        if (in_array($table, $node_base_tables)) {
+          $base_table = $table;
+        }
       }
     }
+
     // Bail out if the base table is missing.
     if (!$base_table) {
       throw new Exception(t('Query tagged for node access but there is no node table, specify the base_table using meta data.'));
diff --git a/core/modules/node/src/Tests/NodeQueryAlterTest.php b/core/modules/node/src/Tests/NodeQueryAlterTest.php
index d0d615ee74ff..d8e06401c066 100644
--- a/core/modules/node/src/Tests/NodeQueryAlterTest.php
+++ b/core/modules/node/src/Tests/NodeQueryAlterTest.php
@@ -72,6 +72,24 @@ function testNodeQueryAlterLowLevelWithAccess() {
     }
   }
 
+  /**
+   * Tests 'node_access' query alter with revision-enabled nodes.
+   */
+  public function testNodeQueryAlterWithRevisions() {
+    // Execute a query that only deals with the 'node_revision' table.
+    try {
+      $query = \Drupal::entityTypeManager()->getStorage('node')->getQuery();
+      $result = $query
+        ->allRevisions()
+        ->execute();
+
+      $this->assertEqual(count($result), 4, 'User with access can see correct nodes');
+    }
+    catch (\Exception $e) {
+      $this->fail('Altered query is malformed');
+    }
+  }
+
   /**
    * Tests 'node_access' query alter, for user without access.
    *
-- 
GitLab