diff --git a/core/lib/Drupal/Core/Database/Connection.php b/core/lib/Drupal/Core/Database/Connection.php
index 5b68cd9a8d5e9b6a89c8bbd39e0c8d3e968d9bad..ba1b0216c8ddf56c38610bb1fe0a6279dd90c4cf 100644
--- a/core/lib/Drupal/Core/Database/Connection.php
+++ b/core/lib/Drupal/Core/Database/Connection.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\Core\Database;
 
+use Drupal\Core\Database\Query\Condition;
+
 /**
  * Base Database API class.
  *
@@ -865,6 +867,11 @@ public function getDriverClass($class) {
       }
       $driver_class = $this->connectionOptions['namespace'] . '\\' . $class;
       $this->driverClasses[$class] = class_exists($driver_class) ? $driver_class : $class;
+      if ($this->driverClasses[$class] === 'Condition') {
+        // @todo Deprecate the fallback for contrib and custom drivers in 9.1.x
+        //   in https://www.drupal.org/project/drupal/issues/3120036.
+        $this->driverClasses[$class] = Condition::class;
+      }
     }
     return $this->driverClasses[$class];
   }
@@ -1026,6 +1033,22 @@ public function schema() {
     return $this->schema;
   }
 
+  /**
+   * Prepares and returns a CONDITION query object.
+   *
+   * @param string $conjunction
+   *   The operator to use to combine conditions: 'AND' or 'OR'.
+   *
+   * @return \Drupal\Core\Database\Query\Condition
+   *   A new Condition query object.
+   *
+   * @see \Drupal\Core\Database\Query\Condition
+   */
+  public function condition($conjunction) {
+    $class = $this->getDriverClass('Condition');
+    return new $class($conjunction);
+  }
+
   /**
    * Escapes a database name string.
    *
diff --git a/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php b/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php
index 1c7670a5a4c3058fcb1a57ce0bd764c408aa47df..d909f7c50b1f867f92c28310493052c94e8f21ea 100644
--- a/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php
+++ b/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Core\Database\Driver\mysql;
 
-use Drupal\Core\Database\Query\Condition;
 use Drupal\Core\Database\SchemaException;
 use Drupal\Core\Database\SchemaObjectExistsException;
 use Drupal\Core\Database\SchemaObjectDoesNotExistException;
@@ -75,7 +74,7 @@ protected function getPrefixInfo($table = 'default', $add_prefix = TRUE) {
   protected function buildTableNameCondition($table_name, $operator = '=', $add_prefix = TRUE) {
     $table_info = $this->getPrefixInfo($table_name, $add_prefix);
 
-    $condition = new Condition('AND');
+    $condition = $this->connection->condition('AND');
     $condition->condition('table_schema', $table_info['database']);
     $condition->condition('table_name', $table_info['table'], $operator);
     return $condition;
diff --git a/core/lib/Drupal/Core/Database/Query/Condition.php b/core/lib/Drupal/Core/Database/Query/Condition.php
index e7038e23c91ee76f14392aa4d7f23fd200d48611..2515bbfdc89ae74e47b1088fbf1b43f67f137b0e 100644
--- a/core/lib/Drupal/Core/Database/Query/Condition.php
+++ b/core/lib/Drupal/Core/Database/Query/Condition.php
@@ -399,7 +399,7 @@ protected function mapConditionOperator($operator) {
    * {@inheritdoc}
    */
   public function conditionGroupFactory($conjunction = 'AND') {
-    return new Condition($conjunction);
+    return new static($conjunction);
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Database/Query/Delete.php b/core/lib/Drupal/Core/Database/Query/Delete.php
index def88385e0beff4b3696eec04710ed4515bfa4c2..658b8342ccded28a6854b13ee5b7d6d9706c42a5 100644
--- a/core/lib/Drupal/Core/Database/Query/Delete.php
+++ b/core/lib/Drupal/Core/Database/Query/Delete.php
@@ -36,7 +36,7 @@ public function __construct(Connection $connection, $table, array $options = [])
     parent::__construct($connection, $options);
     $this->table = $table;
 
-    $this->condition = new Condition('AND');
+    $this->condition = $this->connection->condition('AND');
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Database/Query/Merge.php b/core/lib/Drupal/Core/Database/Query/Merge.php
index 6d895324727605ec3cebcc07c06612b6b389f7f4..5a9bc3db894494a49e1ea45d4b7f0bfceb16cc23 100644
--- a/core/lib/Drupal/Core/Database/Query/Merge.php
+++ b/core/lib/Drupal/Core/Database/Query/Merge.php
@@ -138,7 +138,7 @@ public function __construct(Connection $connection, $table, array $options = [])
     parent::__construct($connection, $options);
     $this->table = $table;
     $this->conditionTable = $table;
-    $this->condition = new Condition('AND');
+    $this->condition = $this->connection->condition('AND');
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Database/Query/QueryConditionTrait.php b/core/lib/Drupal/Core/Database/Query/QueryConditionTrait.php
index 9053a17772aeaa062b86c0b75e85cdef2a437fee..83be429fa581cfa7e4e8360385877c4a72ba6289 100644
--- a/core/lib/Drupal/Core/Database/Query/QueryConditionTrait.php
+++ b/core/lib/Drupal/Core/Database/Query/QueryConditionTrait.php
@@ -108,7 +108,7 @@ public function compiled() {
    * {@inheritdoc}
    */
   public function conditionGroupFactory($conjunction = 'AND') {
-    return new Condition($conjunction);
+    return $this->connection->condition($conjunction);
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Database/Query/Select.php b/core/lib/Drupal/Core/Database/Query/Select.php
index fb74d9f1c13eedaed115286508092d0a49476ec4..78462d0b638f9a1edb1a387e4b4ae5efc93d1abe 100644
--- a/core/lib/Drupal/Core/Database/Query/Select.php
+++ b/core/lib/Drupal/Core/Database/Query/Select.php
@@ -134,8 +134,8 @@ public function __construct(Connection $connection, $table, $alias = NULL, $opti
     $options['return'] = Database::RETURN_STATEMENT;
     parent::__construct($connection, $options);
     $conjunction = isset($options['conjunction']) ? $options['conjunction'] : 'AND';
-    $this->condition = new Condition($conjunction);
-    $this->having = new Condition($conjunction);
+    $this->condition = $this->connection->condition($conjunction);
+    $this->having = $this->connection->condition($conjunction);
     $this->addJoin(NULL, $table, $alias);
   }
 
diff --git a/core/lib/Drupal/Core/Database/Query/SelectExtender.php b/core/lib/Drupal/Core/Database/Query/SelectExtender.php
index dc3531df2f965895e041fa9949702bb1c4d6ff76..e428c21d86bb85d2623136de6e5fae291bb1551a 100644
--- a/core/lib/Drupal/Core/Database/Query/SelectExtender.php
+++ b/core/lib/Drupal/Core/Database/Query/SelectExtender.php
@@ -521,7 +521,7 @@ public function __call($method, $args) {
    * {@inheritdoc}
    */
   public function conditionGroupFactory($conjunction = 'AND') {
-    return new Condition($conjunction);
+    return $this->connection->condition($conjunction);
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Database/Query/Update.php b/core/lib/Drupal/Core/Database/Query/Update.php
index 5de5d682ec3f541bef007d7df710cd60817e21c2..2b08e20d00184b0069806c6f8fa1e1bd591fd2df 100644
--- a/core/lib/Drupal/Core/Database/Query/Update.php
+++ b/core/lib/Drupal/Core/Database/Query/Update.php
@@ -65,7 +65,7 @@ public function __construct(Connection $connection, $table, array $options = [])
     parent::__construct($connection, $options);
     $this->table = $table;
 
-    $this->condition = new Condition('AND');
+    $this->condition = $this->connection->condition('AND');
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Database/Schema.php b/core/lib/Drupal/Core/Database/Schema.php
index 38fde96345c13c4fab2213a7afe69b229d50deeb..1987177a3e55bb89288b865ed8f7c7dfd09bd364 100644
--- a/core/lib/Drupal/Core/Database/Schema.php
+++ b/core/lib/Drupal/Core/Database/Schema.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Core\Database;
 
-use Drupal\Core\Database\Query\Condition;
 use Drupal\Core\Database\Query\PlaceholderInterface;
 
 /**
@@ -150,7 +149,7 @@ protected function buildTableNameCondition($table_name, $operator = '=', $add_pr
     // Retrieve the table name and schema
     $table_info = $this->getPrefixInfo($table_name, $add_prefix);
 
-    $condition = new Condition('AND');
+    $condition = $this->connection->condition('AND');
     $condition->condition('table_catalog', $info['database']);
     $condition->condition('table_schema', $table_info['schema']);
     $condition->condition('table_name', $table_info['table'], $operator);
diff --git a/core/modules/system/tests/modules/database_statement_monitoring_test/src/LoggedStatementsTrait.php b/core/modules/system/tests/modules/database_statement_monitoring_test/src/LoggedStatementsTrait.php
index ceb98ea05d7dc09463637671ffe90b0e06578112..d4f760e093cfe33290c7525c0b3d255c4befb4ac 100644
--- a/core/modules/system/tests/modules/database_statement_monitoring_test/src/LoggedStatementsTrait.php
+++ b/core/modules/system/tests/modules/database_statement_monitoring_test/src/LoggedStatementsTrait.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\database_statement_monitoring_test;
 
+use Drupal\Core\Database\Query\Condition;
+
 /**
  * Trait for Connection classes that can store logged statements.
  */
@@ -48,7 +50,13 @@ public function getDriverClass($class) {
     // based on object, which would break.
     $namespace = (new \ReflectionClass(get_parent_class($this)))->getNamespaceName();
     $driver_class = $namespace . '\\' . $class;
-    return class_exists($driver_class) ? $driver_class : $class;
+    if (class_exists($driver_class)) {
+      return $driver_class;
+    }
+    elseif ($class == 'Condition') {
+      return Condition::class;
+    }
+    return $class;
   }
 
   /**
diff --git a/core/tests/Drupal/KernelTests/Core/Database/ConnectionTest.php b/core/tests/Drupal/KernelTests/Core/Database/ConnectionTest.php
index 7e0a5f89ac35674337d5fd18713d219b92d3ee5d..69b5de82fbde8bf42ed3d7475aa82b1319e4131a 100644
--- a/core/tests/Drupal/KernelTests/Core/Database/ConnectionTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Database/ConnectionTest.php
@@ -4,6 +4,7 @@
 
 use Drupal\Core\Database\Database;
 use Drupal\Core\Database\DatabaseExceptionWrapper;
+use Drupal\Core\Database\Query\Condition;
 
 /**
  * Tests of the core database system.
@@ -155,4 +156,17 @@ public function testMultipleStatements() {
     }
   }
 
+  /**
+   * Test that the method ::condition() returns a Condition object.
+   */
+  public function testCondition() {
+    $connection = Database::getConnection('default', 'default');
+    $namespace = (new \ReflectionObject($connection))->getNamespaceName() . "\\Condition";
+    if (!class_exists($namespace)) {
+      $namespace = Condition::class;
+    }
+    $condition = $connection->condition('AND');
+    $this->assertSame($namespace, get_class($condition));
+  }
+
 }
diff --git a/core/tests/Drupal/Tests/Core/Database/ConditionTest.php b/core/tests/Drupal/Tests/Core/Database/ConditionTest.php
index c38261b86626ab0a3539a5b12746cd6c59d897c5..93eb0ef8a8bd8d74ffcf21411c4f4dca4483ce5a 100644
--- a/core/tests/Drupal/Tests/Core/Database/ConditionTest.php
+++ b/core/tests/Drupal/Tests/Core/Database/ConditionTest.php
@@ -5,6 +5,7 @@
 use Drupal\Core\Database\Connection;
 use Drupal\Core\Database\Query\Condition;
 use Drupal\Core\Database\Query\PlaceholderInterface;
+use Drupal\Tests\Core\Database\Stub\StubPDO;
 use Drupal\Tests\UnitTestCase;
 use Prophecy\Argument;
 use PHPUnit\Framework\Error\Error;
@@ -176,4 +177,34 @@ public function providerTestCompileWithSqlInjectionForOperator() {
     return $data;
   }
 
+  /**
+   * Test that the core Condition can be overridden.
+   */
+  public function testContribCondition() {
+    $mockCondition = $this->getMockBuilder(Condition::class)
+      ->setMockClassName('MockCondition')
+      ->setConstructorArgs([NULL])
+      ->disableOriginalConstructor()
+      ->getMock();
+    $contrib_namespace = 'Drupal\Driver\Database\mock';
+    $mocked_namespace = $contrib_namespace . '\\Condition';
+    class_alias('MockCondition', $mocked_namespace);
+
+    $options['namespace'] = $contrib_namespace;
+    $options['prefix']['default'] = '';
+
+    $mockPdo = $this->createMock(StubPDO::class);
+
+    $connection = $this->getMockBuilder(Connection::class)
+      ->setConstructorArgs([$mockPdo, $options])
+      ->setMethods(['identifierQuote'])
+      ->getMockForAbstractClass();
+    // @todo In drupal:10.0.0 this function will be abstract and the mock
+    // builder will automatically create it. This can be
+    // can be removed at that time.
+    $connection->method('identifierQuote')->willReturn(NULL);
+    $condition = $connection->condition('AND');
+    $this->assertSame('MockCondition', get_class($condition));
+  }
+
 }