diff --git a/core/lib/Drupal/Core/Database/Driver/sqlite/Connection.php b/core/lib/Drupal/Core/Database/Driver/sqlite/Connection.php
index 4c3f838..c29fe2f 100644
--- a/core/lib/Drupal/Core/Database/Driver/sqlite/Connection.php
+++ b/core/lib/Drupal/Core/Database/Driver/sqlite/Connection.php
@@ -8,7 +8,10 @@
 namespace Drupal\Core\Database\Driver\sqlite;
 
 use Drupal\Core\Database\Database;
+use Drupal\Core\Database\DatabaseExceptionWrapper;
 use Drupal\Core\Database\DatabaseNotFoundException;
+use Drupal\Core\Database\IntegrityConstraintViolationException;
+use Drupal\Core\Database\StatementInterface;
 use Drupal\Core\Database\TransactionNoActiveException;
 use Drupal\Core\Database\TransactionNameNonUniqueException;
 use Drupal\Core\Database\TransactionCommitFailedException;
@@ -334,6 +337,74 @@ protected function expandArguments(&$query, &$args) {
     return $modified;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function query($query, array $args = array(), $options = array()) {
+    // Use default values if not already set.
+    $options += $this->defaultOptions();
+
+    try {
+      // We allow either a pre-bound statement object or a literal string.
+      // In either case, we want to end up with an executed statement object,
+      // which we pass to PDOStatement::execute.
+      if ($query instanceof StatementInterface) {
+        $stmt = $query;
+        $stmt->execute(NULL, $options);
+      }
+      else {
+        $this->expandArguments($query, $args);
+        $stmt = $this->prepareQuery($query);
+        $stmt->execute($args, $options);
+      }
+
+      // Depending on the type of query we may need to return a different value.
+      // See DatabaseConnection::defaultOptions() for a description of each
+      // value.
+      switch ($options['return']) {
+        case Database::RETURN_STATEMENT:
+          return $stmt;
+        case Database::RETURN_AFFECTED:
+          $stmt->allowRowCount = TRUE;
+          return $stmt->rowCount();
+        case Database::RETURN_INSERT_ID:
+          return $this->connection->lastInsertId();
+        case Database::RETURN_NULL:
+          return;
+        default:
+          throw new \PDOException('Invalid return directive: ' . $options['return']);
+      }
+    }
+    catch (\PDOException $e) {
+      // The database schema might be changed by another process in between the
+      // time that the statement was prepared and the time the statement was
+      // run (e.g. usually happens when running tests). In this case, we need to
+      // re-run the query.
+      // @see http://www.sqlite.org/faq.html#q15
+      if (preg_match('/^SQLSTATE\[HY000\]: General error: 17 database schema has changed/', $e->getMessage())) {
+        return $this->query($query, $args, $options);
+      }
+
+      if ($options['throw_exception']) {
+        // Wrap the exception in another exception, because PHP does not allow
+        // overriding Exception::getMessage(). Its message is the extra database
+        // debug information.
+        $query_string = ($query instanceof StatementInterface) ? $stmt->getQueryString() : $query;
+        $message = $e->getMessage() . ": " . $query_string . "; " . print_r($args, TRUE);
+        // Match all SQLSTATE 23xxx errors.
+        if (substr($e->getCode(), -6, -3) == '23') {
+          $exception = new IntegrityConstraintViolationException($message, $e->getCode(), $e);
+        }
+        else {
+          $exception = new DatabaseExceptionWrapper($message, 0, $e);
+        }
+
+        throw $exception;
+      }
+      return NULL;
+    }
+  }
+
   public function queryRange($query, $from, $count, array $args = array(), array $options = array()) {
     return $this->query($query . ' LIMIT ' . (int) $from . ', ' . (int) $count, $args, $options);
   }
