Index: sql/connection.cc |
diff --git a/sql/connection.cc b/sql/connection.cc |
index 9c7cb7d4099a811bc78b314070ab2fd1eebb1eb4..d55c352cd56538fef3b8c0c1170c5037481a6da8 100644 |
--- a/sql/connection.cc |
+++ b/sql/connection.cc |
@@ -1693,15 +1693,28 @@ bool Connection::OpenInternal(const std::string& file_name, |
err = sqlite3_extended_result_codes(db_, 1); |
DCHECK_EQ(err, SQLITE_OK) << "Could not enable extended result codes"; |
- // sqlite3_open() does not actually read the database file (unless a |
- // hot journal is found). Successfully executing this pragma on an |
- // existing database requires a valid header on page 1. |
+ // sqlite3_open() does not actually read the database file (unless a hot |
+ // journal is found). Successfully executing this pragma on an existing |
+ // database requires a valid header on page 1. ExecuteAndReturnErrorCode() to |
+ // get the error code before error callback (potentially) overwrites. |
// TODO(shess): For now, just probing to see what the lay of the |
// land is. If it's mostly SQLITE_NOTADB, then the database should |
// be razed. |
err = ExecuteAndReturnErrorCode("PRAGMA auto_vacuum"); |
- if (err != SQLITE_OK) |
+ if (err != SQLITE_OK) { |
UMA_HISTOGRAM_SPARSE_SLOWLY("Sqlite.OpenProbeFailure", err); |
+ OnSqliteError(err, nullptr, "PRAGMA auto_vacuum"); |
+ |
+ // Retry or bail out if the error handler poisoned the handle. |
+ // TODO(shess): Move this handling to one place (see also sqlite3_open and |
+ // secure_delete). Possibly a wrapper function? |
+ if (poisoned_) { |
+ Close(); |
+ if (retry_flag == RETRY_ON_POISON) |
+ return OpenInternal(file_name, NO_RETRY); |
+ return false; |
+ } |
+ } |
#if defined(OS_IOS) && defined(USE_SYSTEM_SQLITE) |
// The version of SQLite shipped with iOS doesn't enable ICU, which includes |