rawQuery returning 0 results when arrayOf() passed as parameter

Hello SQLcipher developers/users. I’ve been in Android development for now 13 years and I’ve never seen anything like this.

Yesterday I found out that we need to do the migration from original SQLCipher android lib to the new long-term remplaement. I did just that.

Replaced net.zetetic:android-database-sqlcipher:4.5.4 with net.zetetic:sqlcipher-android:4.7.2@aar
Also I already had androidx.sqlite:sqlite:2.3.1 in the codebase.

Project built correctly. Also, it ran correctly after a modification of passing password to the database unlocking (in SQLiteOpenHelper instead of passing it to in getWritableDatabase or getReadableDatabase).

Now, the only problem I have is with functionality of the app. Everything works fine with the app until you get to a screen needing to show one specific label.

I fetch it like this:

database.rawQuery(sql, arrayOf(testStringId, testIntegerId)).use { cursor →
hasRecords = c.moveToFirst()

hasRecords is always false even though the data is there (I downloaded the database locally, opened it with DB Browser for SQLite, unlocked it with the password and run the same query and it returned the needed results.

Now, the interesting part.
When I fetch it like this:

val sql = “SELECT * FROM TestTable WHERE testStringId = ‘2df6bfd8-9418-4e25-a7ca-29d0a08c6275’ AND testIntegerId = 0”

database.rawQuery(sql, null).use { cursor →
hasRecords = c.moveToFirst()

hasRecords is on true and cursor contains data.

How is that possible? What am I missing? I’ve been on this problem from this morning and I’ve ran out of ideas. Also I’m ready for some mental institution :sweat_smile:

If anyone experienced something similar I would appreciate the help.

Ok, I’ve found out a solution, but still have no idea why it’s working like that in the SQLiteDatabase implementation in sqlcipher lib.

This works:

database.rawQuery(sql, testStringId, testIntegerId).use { cursor →

I have to pass the arguments as varargs. If sent as arrayOf, it’s hitting another override of method passing arguments as Objects and it’s not working.

Anyone from development team to clear the confusion? Have I found some issue in the lib or I totally have no idea how it works?

Hi @tosulc,

I am happy to hear you were able to resolve the issue by passing your arguments for the query as varargs, sorry for the troubling behavior. I suspect when you are invoking the query with arrayOf(...), it may be dispatching to the other override for rawQuery which will accept a String[] as arguments. In that situation, each parameter will be bound as a String value using sqlite3_bind_text16, but if your column for testIntegerId has a column of type INTEGER, the query would not resolve properly to the record you are searching for. As you have observed, when you utilize rawQuery with varargs, each parameter type is inspected during the binding operation. In your case, the testIntegerId would be bound using sqlite3_bind_int64.

As an aside, since you are just updating to sqlcipher-android, you may wish to update to the latest release which is currently 4.9.0.