diff --git a/core/java/android/database/sqlite/SQLiteConnection.java b/core/java/android/database/sqlite/SQLiteConnection.java index 865940e796c83..01e237da2fa03 100644 --- a/core/java/android/database/sqlite/SQLiteConnection.java +++ b/core/java/android/database/sqlite/SQLiteConnection.java @@ -153,7 +153,8 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen int index, byte[] value); private static native void nativeResetStatementAndClearBindings( long connectionPtr, long statementPtr); - private static native void nativeExecute(long connectionPtr, long statementPtr); + private static native void nativeExecute(long connectionPtr, long statementPtr, + boolean isPragmaStmt); private static native long nativeExecuteForLong(long connectionPtr, long statementPtr); private static native String nativeExecuteForString(long connectionPtr, long statementPtr); private static native int nativeExecuteForBlobFileDescriptor( @@ -699,6 +700,8 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen final int cookie = mRecentOperations.beginOperation("execute", sql, bindArgs); try { + final boolean isPragmaStmt = + DatabaseUtils.getSqlStatementType(sql) == DatabaseUtils.STATEMENT_PRAGMA; final PreparedStatement statement = acquirePreparedStatement(sql); try { throwIfStatementForbidden(statement); @@ -706,7 +709,7 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen applyBlockGuardPolicy(statement); attachCancellationSignal(cancellationSignal); try { - nativeExecute(mConnectionPtr, statement.mStatementPtr); + nativeExecute(mConnectionPtr, statement.mStatementPtr, isPragmaStmt); } finally { detachCancellationSignal(cancellationSignal); } diff --git a/core/jni/android_database_SQLiteConnection.cpp b/core/jni/android_database_SQLiteConnection.cpp index c80f1dc28595e..32697aeaa47ff 100644 --- a/core/jni/android_database_SQLiteConnection.cpp +++ b/core/jni/android_database_SQLiteConnection.cpp @@ -518,23 +518,29 @@ static void nativeResetStatementAndClearBindings(JNIEnv* env, jclass clazz, jlon } } -static int executeNonQuery(JNIEnv* env, SQLiteConnection* connection, sqlite3_stmt* statement) { - int err = sqlite3_step(statement); - if (err == SQLITE_ROW) { +static int executeNonQuery(JNIEnv* env, SQLiteConnection* connection, sqlite3_stmt* statement, + bool isPragmaStmt) { + int rc = sqlite3_step(statement); + if (isPragmaStmt) { + while (rc == SQLITE_ROW) { + rc = sqlite3_step(statement); + } + } + if (rc == SQLITE_ROW) { throw_sqlite3_exception(env, "Queries can be performed using SQLiteDatabase query or rawQuery methods only."); - } else if (err != SQLITE_DONE) { + } else if (rc != SQLITE_DONE) { throw_sqlite3_exception(env, connection->db); } - return err; + return rc; } -static void nativeExecute(JNIEnv* env, jclass clazz, jlong connectionPtr, - jlong statementPtr) { +static void nativeExecute(JNIEnv* env, jclass clazz, jlong connectionPtr, jlong statementPtr, + jboolean isPragmaStmt) { SQLiteConnection* connection = reinterpret_cast(connectionPtr); sqlite3_stmt* statement = reinterpret_cast(statementPtr); - executeNonQuery(env, connection, statement); + executeNonQuery(env, connection, statement, isPragmaStmt); } static jint nativeExecuteForChangedRowCount(JNIEnv* env, jclass clazz, @@ -542,7 +548,7 @@ static jint nativeExecuteForChangedRowCount(JNIEnv* env, jclass clazz, SQLiteConnection* connection = reinterpret_cast(connectionPtr); sqlite3_stmt* statement = reinterpret_cast(statementPtr); - int err = executeNonQuery(env, connection, statement); + int err = executeNonQuery(env, connection, statement, false); return err == SQLITE_DONE ? sqlite3_changes(connection->db) : -1; } @@ -551,7 +557,7 @@ static jlong nativeExecuteForLastInsertedRowId(JNIEnv* env, jclass clazz, SQLiteConnection* connection = reinterpret_cast(connectionPtr); sqlite3_stmt* statement = reinterpret_cast(statementPtr); - int err = executeNonQuery(env, connection, statement); + int err = executeNonQuery(env, connection, statement, false); return err == SQLITE_DONE && sqlite3_changes(connection->db) > 0 ? sqlite3_last_insert_rowid(connection->db) : -1; } @@ -912,7 +918,7 @@ static const JNINativeMethod sMethods[] = (void*)nativeBindBlob }, { "nativeResetStatementAndClearBindings", "(JJ)V", (void*)nativeResetStatementAndClearBindings }, - { "nativeExecute", "(JJ)V", + { "nativeExecute", "(JJZ)V", (void*)nativeExecute }, { "nativeExecuteForLong", "(JJ)J", (void*)nativeExecuteForLong },