Skip to content

changes done using ALTER table query with db.execSQL() are not reflecting when using db.query() #605

@muthus55

Description

@muthus55

Steps to Reproduce:

  1. Create an Android application with SQLCipher integration.

  2. Create a database and add some tables into it.

  3. First query any table using the SQLiteDatabase.query(String table, String[] columns, String selection,
    String[] selectionArgs, String groupBy, String having,
    String orderBy) method with null projections

  4. This will return a Cursor object. If you inspect the cursor all the columns and rows will be available

  5. Now alter the table queried in step 3 and add a new column to it using SQLiteDatabase.execSQL()

  6. Use the same query used in step 3. and dump the cursor object. The newly added column in step 5 will not be available in this query.

Example:

  1. Let us a assume a Table "Students" which contains 2 columns "name" & "id"
  2. First query the database using the SQLiteDatabase.query(String table, String[] columns, String selection,
    String[] selectionArgs, String groupBy, String having,
    String orderBy) method with null projections
    method call ->
    {
    SQLiteDatabase.query("Students",null,null,null,null,null,null)
    }
    if the cursor from query method is dumped we can see 2 columns "name" & "id".
  3. Now alter the "Students" table and add a new column to it. Let us assume the new column to "age". This alter query execution is done by using SQLiteDatabase.execSQL()
    method call ->
    {
    SQLiteDatabase.execSQL(" ALTER TABLE STUDENTS ADD age TEXT NULL")
    }
  4. Now query the "Students" table again with the same query used in step 2
    method call ->
    {
    SQLiteDatabase.query("Students",null,null,null,null,null,null)
    }
  5. Dump the cursor object you can see that the newly created column "age" will not be available in the cursor object.

This issue occurs due to caching the prepared statement. The caching is done in "SQLiteDatabase.mCompiledQueries" object. If a table is queried and the SQL statement is cached in "SQLiteDatabase.mCompiledQueries" object we use the same compiled prepared statement. Whenever a SQLiteCursor is initialed we use the SQLiteProgram object and this SQLiteProgram object will try to check if any cached queries available in mCompiledQueries and reuses it. This cached prepared statement will not reflect the newly added columns done using SQLiteDatabase.execSQL();

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions