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

Commit 4e874edf authored by Vasu Nori's avatar Vasu Nori
Browse files

don't compile statement for certain SQL statements

SQL statements such as Create table, Pragma, Begin, Commit, Rollback
etc don't need a compiled statement.

Change-Id: I55f5e4e6cbb41cbe83e592e25ba852fe23e2b39f
parent 7553cf74
Loading
Loading
Loading
Loading
+33 −0
Original line number Diff line number Diff line
@@ -64538,7 +64538,29 @@
 visibility="public"
>
</field>
<field name="STATEMENT_DDL"
 type="int"
 transient="false"
 volatile="false"
 value="8"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="STATEMENT_OTHER"
 type="int"
 transient="false"
 volatile="false"
 value="99"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="STATEMENT_PRAGMA"
 type="int"
 transient="false"
 volatile="false"
@@ -64560,6 +64582,17 @@
 visibility="public"
>
</field>
<field name="STATEMENT_UNPREPARED"
 type="int"
 transient="false"
 volatile="false"
 value="9"
 static="true"
 final="true"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="STATEMENT_UPDATE"
 type="int"
 transient="false"
+14 −1
Original line number Diff line number Diff line
@@ -66,7 +66,13 @@ public class DatabaseUtils {
    /** One of the values returned by {@link #getSqlStatementType(String)}. */
    public static final int STATEMENT_ABORT = 6;
    /** One of the values returned by {@link #getSqlStatementType(String)}. */
    public static final int STATEMENT_OTHER = 7;
    public static final int STATEMENT_PRAGMA = 7;
    /** One of the values returned by {@link #getSqlStatementType(String)}. */
    public static final int STATEMENT_DDL = 8;
    /** One of the values returned by {@link #getSqlStatementType(String)}. */
    public static final int STATEMENT_UNPREPARED = 9;
    /** One of the values returned by {@link #getSqlStatementType(String)}. */
    public static final int STATEMENT_OTHER = 99;

    /**
     * Special function for writing an exception result at the header of
@@ -1255,6 +1261,13 @@ public class DatabaseUtils {
            return STATEMENT_ABORT;
        } else if (prefixSql.equals("BEG")) {
            return STATEMENT_BEGIN;
        } else if (prefixSql.equals("PRA")) {
            return STATEMENT_PRAGMA;
        } else if (prefixSql.equals("CRE") || prefixSql.equals("DRO") ||
                prefixSql.equals("ALT")) {
            return STATEMENT_DDL;
        } else if (prefixSql.equals("ANA") || prefixSql.equals("DET")) {
            return STATEMENT_UNPREPARED;
        }
        return STATEMENT_OTHER;
    }
+47 −11
Original line number Diff line number Diff line
@@ -86,6 +86,10 @@ public abstract class SQLiteProgram extends SQLiteClosable {
     */
    /* package */ HashMap<Integer, Object> mBindArgs = null;
    /* package */ final int mStatementType;
    /* package */ static final int STATEMENT_CACHEABLE = 16;
    /* package */ static final int STATEMENT_DONT_PREPARE = 32;
    /* package */ static final int STATEMENT_USE_POOLED_CONN = 64;
    /* package */ static final int STATEMENT_TYPE_MASK = 0x0f;

    /* package */ SQLiteProgram(SQLiteDatabase db, String sql) {
        this(db, sql, null, true);
@@ -94,7 +98,25 @@ public abstract class SQLiteProgram extends SQLiteClosable {
    /* package */ SQLiteProgram(SQLiteDatabase db, String sql, Object[] bindArgs,
            boolean compileFlag) {
        mSql = sql.trim();
        mStatementType = DatabaseUtils.getSqlStatementType(mSql);
        int n = DatabaseUtils.getSqlStatementType(mSql);
        switch (n) {
            case DatabaseUtils.STATEMENT_UPDATE:
                mStatementType = n | STATEMENT_CACHEABLE;
                break;
            case DatabaseUtils.STATEMENT_SELECT:
                mStatementType = n | STATEMENT_CACHEABLE | STATEMENT_USE_POOLED_CONN;
                break;
            case DatabaseUtils.STATEMENT_ATTACH:
            case DatabaseUtils.STATEMENT_BEGIN:
            case DatabaseUtils.STATEMENT_COMMIT:
            case DatabaseUtils.STATEMENT_ABORT:
            case DatabaseUtils.STATEMENT_DDL:
            case DatabaseUtils.STATEMENT_UNPREPARED:
                mStatementType = n | STATEMENT_DONT_PREPARE;
                break;
            default:
                mStatementType = n;
        }
        db.acquireReference();
        db.addSQLiteClosable(this);
        mDatabase = db;
@@ -112,8 +134,7 @@ public abstract class SQLiteProgram extends SQLiteClosable {

    private void compileSql() {
        // only cache CRUD statements
        if (mStatementType != DatabaseUtils.STATEMENT_SELECT &&
                mStatementType != DatabaseUtils.STATEMENT_UPDATE) {
        if ((mStatementType & STATEMENT_CACHEABLE) == 0) {
            mCompiledSql = new SQLiteCompiledSql(mDatabase, mSql);
            nStatement = mCompiledSql.nStatement;
            // since it is not in the cache, no need to acquire() it.
@@ -163,6 +184,10 @@ public abstract class SQLiteProgram extends SQLiteClosable {
        if (mCompiledSql == null) {
            return;
        }
        if ((mStatementType & STATEMENT_CACHEABLE) == 0) {
            // this SQL statement was never in cache
            mCompiledSql.releaseSqlStatement();
        } else {
            synchronized(mDatabase.mCompiledQueries) {
                if (!mDatabase.mCompiledQueries.containsValue(mCompiledSql)) {
                    // it is NOT in compiled-sql cache. i.e., responsibility of
@@ -173,6 +198,7 @@ public abstract class SQLiteProgram extends SQLiteClosable {
                    mCompiledSql.release();
                }
            }
        }
        mCompiledSql = null;
        nStatement = 0;
    }
@@ -347,6 +373,16 @@ public abstract class SQLiteProgram extends SQLiteClosable {
    }

    /* package */ synchronized void compileAndbindAllArgs() {
        if ((mStatementType & STATEMENT_DONT_PREPARE) > 0) {
            // no need to prepare this SQL statement
            if (SQLiteDebug.DEBUG_SQL_STATEMENTS) {
                if (mBindArgs != null) {
                    throw new IllegalArgumentException("no need to pass bindargs for this sql :" +
                            mSql);
                }
            }
            return;
        }
        if (nStatement == 0) {
            // SQL statement is not compiled yet. compile it now.
            compileSql();
+20 −8
Original line number Diff line number Diff line
@@ -71,7 +71,7 @@ public class SQLiteStatement extends SQLiteProgram
    }

    /**
     * Execute this SQL statement, if the the number of rows affected by exection of this SQL
     * Execute this SQL statement, if the the number of rows affected by execution of this SQL
     * statement is of any importance to the caller - for example, UPDATE / DELETE SQL statements.
     *
     * @return the number of rows affected by this SQL statement execution.
@@ -82,7 +82,15 @@ public class SQLiteStatement extends SQLiteProgram
        synchronized(this) {
            try {
                long timeStart = acquireAndLock(WRITE);
                int numChanges = native_execute();
                int numChanges = 0;
                if ((mStatementType & STATEMENT_DONT_PREPARE) > 0) {
                    // since the statement doesn't have to be prepared,
                    // call the following native method which will not prepare
                    // the query plan
                    native_executeSql(mSql);
                } else {
                    numChanges = native_execute();
                }
                mDatabase.logTimeStat(mSql, timeStart);
                return numChanges;
            } finally {
@@ -199,8 +207,8 @@ public class SQLiteStatement extends SQLiteProgram
        mState = 0;
        // use pooled database connection handles for SELECT SQL statements
        mDatabase.verifyDbIsOpen();
        SQLiteDatabase db = (mStatementType != DatabaseUtils.STATEMENT_SELECT) ? mDatabase
                : mDatabase.getDbConnection(mSql);
        SQLiteDatabase db = ((mStatementType & SQLiteProgram.STATEMENT_USE_POOLED_CONN) > 0)
                ? mDatabase.getDbConnection(mSql) : mDatabase;
        // use the database connection obtained above
        mOrigDb = mDatabase;
        mDatabase = db;
@@ -217,13 +225,14 @@ public class SQLiteStatement extends SQLiteProgram
         * beginTransaction() methods in SQLiteDatabase call lockForced() before
         * calling execSQL("BEGIN transaction").
         */
        if (mStatementType == DatabaseUtils.STATEMENT_BEGIN) {
        if ((mStatementType & SQLiteProgram.STATEMENT_TYPE_MASK) == DatabaseUtils.STATEMENT_BEGIN) {
            if (!mDatabase.isDbLockedByCurrentThread()) {
                // transaction is  NOT started by calling beginTransaction() methods in
                // SQLiteDatabase
                mDatabase.setTransactionUsingExecSqlFlag();
            }
        } else if (mStatementType == DatabaseUtils.STATEMENT_UPDATE) {
        } else if ((mStatementType & SQLiteProgram.STATEMENT_TYPE_MASK) ==
                DatabaseUtils.STATEMENT_UPDATE) {
            // got update SQL statement. if there is NO pending transaction, start one
            if (!mDatabase.inTransaction()) {
                mDatabase.beginTransactionNonExclusive();
@@ -257,8 +266,10 @@ public class SQLiteStatement extends SQLiteProgram
        } else if (mState == LOCK_ACQUIRED) {
            mDatabase.unlock();
        }
        if (mStatementType == DatabaseUtils.STATEMENT_COMMIT ||
                mStatementType == DatabaseUtils.STATEMENT_ABORT) {
        if ((mStatementType & SQLiteProgram.STATEMENT_TYPE_MASK) ==
                DatabaseUtils.STATEMENT_COMMIT ||
                (mStatementType & SQLiteProgram.STATEMENT_TYPE_MASK) ==
                DatabaseUtils.STATEMENT_ABORT) {
            mDatabase.resetTransactionUsingExecSqlFlag();
        }
        clearBindings();
@@ -275,4 +286,5 @@ public class SQLiteStatement extends SQLiteProgram
    private final native long native_1x1_long();
    private final native String native_1x1_string();
    private final native ParcelFileDescriptor native_1x1_blob_ashmem() throws IOException;
    private final native void native_executeSql(String sql);
}
+12 −0
Original line number Diff line number Diff line
@@ -239,6 +239,17 @@ static jobject native_1x1_blob_ashmem(JNIEnv* env, jobject object)
    return value;
}

static void native_executeSql(JNIEnv* env, jobject object, jstring sql)
{
    char const* sqlString = env->GetStringUTFChars(sql, NULL);
    sqlite3 * handle = GET_HANDLE(env, object);
    int err = sqlite3_exec(handle, sqlString, NULL, NULL, NULL);
    if (err != SQLITE_OK) {
        throw_sqlite3_exception(env, handle);
    }
    env->ReleaseStringUTFChars(sql, sqlString);
}

static JNINativeMethod sMethods[] =
{
     /* name, signature, funcPtr */
@@ -247,6 +258,7 @@ static JNINativeMethod sMethods[] =
    {"native_1x1_long", "()J", (void *)native_1x1_long},
    {"native_1x1_string", "()Ljava/lang/String;", (void *)native_1x1_string},
    {"native_1x1_blob_ashmem", "()Landroid/os/ParcelFileDescriptor;", (void *)native_1x1_blob_ashmem},
    {"native_executeSql", "(Ljava/lang/String;)V", (void *)native_executeSql},
};

int register_android_database_SQLiteStatement(JNIEnv * env)