Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 25095c08 authored by Fyodor Kupolov's avatar Fyodor Kupolov
Browse files

Close available secondary connections if schema changes

If DDL statement is executed on one connection, the schema change is
not always visible to other connections due to sqlite3_column_count()
API limitation. We have to close secondary connections to prevent the
issue.

Test: cts/SQLiteOpenHelperTest
Bug: 33695159
Change-Id: I862da71ecec5b1edc880dbfadf22efb2274ca10a
parent 04dacb54
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -570,6 +570,16 @@ public final class SQLiteConnectionPool implements Closeable {
        mAvailableNonPrimaryConnections.clear();
    }

    /**
     * Close non-primary connections that are not currently in use. This method is safe to use
     * in finalize block as it doesn't throw RuntimeExceptions.
     */
    void closeAvailableNonPrimaryConnectionsAndLogExceptions() {
        synchronized (mLock) {
            closeAvailableNonPrimaryConnectionsAndLogExceptionsLocked();
        }
    }

    // Can't throw.
    private void closeExcessConnectionsAndLogExceptionsLocked() {
        int availableCount = mAvailableNonPrimaryConnections.size();
+8 −4
Original line number Diff line number Diff line
@@ -1740,7 +1740,8 @@ public final class SQLiteDatabase extends SQLiteClosable {
    private int executeSql(String sql, Object[] bindArgs) throws SQLException {
        acquireReference();
        try {
            if (DatabaseUtils.getSqlStatementType(sql) == DatabaseUtils.STATEMENT_ATTACH) {
            final int statementType = DatabaseUtils.getSqlStatementType(sql);
            if (statementType == DatabaseUtils.STATEMENT_ATTACH) {
                boolean disableWal = false;
                synchronized (mLock) {
                    if (!mHasAttachedDbsLocked) {
@@ -1754,11 +1755,14 @@ public final class SQLiteDatabase extends SQLiteClosable {
                }
            }

            SQLiteStatement statement = new SQLiteStatement(this, sql, bindArgs);
            try {
            try (SQLiteStatement statement = new SQLiteStatement(this, sql, bindArgs)) {
                return statement.executeUpdateDelete();
            } finally {
                statement.close();
                // If schema was updated, close non-primary connections, otherwise they might
                // have outdated schema information
                if (statementType == DatabaseUtils.STATEMENT_DDL) {
                    mConnectionPoolLocked.closeAvailableNonPrimaryConnectionsAndLogExceptions();
                }
            }
        } finally {
            releaseReference();