diff --git a/core/lib/Drupal/Core/Database/Driver/pgsql/Connection.php b/core/lib/Drupal/Core/Database/Driver/pgsql/Connection.php
index 4688cdebdc5220714fae3b1c74386e3a1a532b7c..80497962cb2469a97377c6d8cac11381581fe5ed 100644
--- a/core/lib/Drupal/Core/Database/Driver/pgsql/Connection.php
+++ b/core/lib/Drupal/Core/Database/Driver/pgsql/Connection.php
@@ -210,13 +210,8 @@ public function escapeField($field) {
       // need to be escaped.
       $escaped = $this->escapeTable($table) . '.' . $this->escapeAlias($column);
     }
-    elseif (preg_match('/[A-Z]/', $escaped)) {
-      // Quote the field name for case-sensitivity.
-      $escaped = '"' . $escaped . '"';
-    }
-    elseif (in_array(strtolower($escaped), $this->postgresqlReservedKeyWords)) {
-      // Quote the field name for PostgreSQL reserved key words.
-      $escaped = '"' . $escaped . '"';
+    else {
+      $escaped = $this->doEscape($escaped);
     }
 
     return $escaped;
@@ -227,16 +222,7 @@ public function escapeField($field) {
    */
   public function escapeAlias($field) {
     $escaped = preg_replace('/[^A-Za-z0-9_]+/', '', $field);
-
-    // Escape the alias in quotes for case-sensitivity.
-    if (preg_match('/[A-Z]/', $escaped)) {
-      $escaped = '"' . $escaped . '"';
-    }
-    elseif (in_array(strtolower($escaped), $this->postgresqlReservedKeyWords)) {
-      // Quote the alias name for PostgreSQL reserved key words.
-      $escaped = '"' . $escaped . '"';
-    }
-
+    $escaped = $this->doEscape($escaped);
     return $escaped;
   }
 
@@ -246,16 +232,33 @@ public function escapeAlias($field) {
   public function escapeTable($table) {
     $escaped = parent::escapeTable($table);
 
+    // Ensure that each part (database, schema and table) of the table name is
+    // properly and independently escaped.
+    $parts = explode('.', $escaped);
+    $parts = array_map([$this, 'doEscape'], $parts);
+    $escaped = implode('.', $parts);
+
+    return $escaped;
+  }
+
+  /**
+   * Escape a string if needed.
+   *
+   * @param $string
+   *   The string to escape.
+   * @return string
+   *   The escaped string.
+   */
+  protected function doEscape($string) {
     // Quote identifier to make it case-sensitive.
-    if (preg_match('/[A-Z]/', $escaped)) {
-      $escaped = '"' . $escaped . '"';
+    if (preg_match('/[A-Z]/', $string)) {
+      $string = '"' . $string . '"';
     }
-    elseif (in_array(strtolower($escaped), $this->postgresqlReservedKeyWords)) {
-      // Quote the table name for PostgreSQL reserved key words.
-      $escaped = '"' . $escaped . '"';
+    elseif (in_array(strtolower($string), $this->postgresqlReservedKeyWords)) {
+      // Quote the string for PostgreSQL reserved key words.
+      $string = '"' . $string . '"';
     }
-
-    return $escaped;
+    return $string;
   }
 
   public function driver() {
diff --git a/core/tests/Drupal/Tests/Core/Database/Driver/pgsql/PostgresqlConnectionTest.php b/core/tests/Drupal/Tests/Core/Database/Driver/pgsql/PostgresqlConnectionTest.php
index 2bf263962d9de300e9ff87a2d14d7ea072a5b24e..883f851d950a1b4d4e9c58a83c1ffac7699618cb 100644
--- a/core/tests/Drupal/Tests/Core/Database/Driver/pgsql/PostgresqlConnectionTest.php
+++ b/core/tests/Drupal/Tests/Core/Database/Driver/pgsql/PostgresqlConnectionTest.php
@@ -40,6 +40,11 @@ public function providerEscapeTables() {
       array('"camelCase"', 'camelCase'),
       array('"camelCase"', '"camelCase"'),
       array('"camelCase"', 'camel/Case'),
+      // Sometimes, table names are following the pattern database.schema.table.
+      array('"camelCase".nocase.nocase', 'camelCase.nocase.nocase'),
+      array('nocase."camelCase".nocase', 'nocase.camelCase.nocase'),
+      array('nocase.nocase."camelCase"', 'nocase.nocase.camelCase'),
+      array('"camelCase"."camelCase"."camelCase"', 'camelCase.camelCase.camelCase'),
     );
   }