Merge "Resolving bug where Room generates invalid code for a Array<ByteArray> return type query method." into androidx-main
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/DaoPrimitiveTest.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/DaoPrimitiveTest.kt
index 32368bd..80986a4 100644
--- a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/DaoPrimitiveTest.kt
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/DaoPrimitiveTest.kt
@@ -41,6 +41,9 @@
     @Entity(tableName = "stringFoo")
     data class StringFoo(@PrimaryKey val id: String, val description: String)
 
+    @Entity(tableName = "byteArrayFoo")
+    data class ByteArrayFoo(@PrimaryKey val id: ByteArray, val description: String)
+
     /* Interface with generics only */
     interface BaseDao<Key, Value> {
 
@@ -73,6 +76,11 @@
         fun getFirstItemId(): String
     }
 
+    interface ByteArrayBaseDao<ByteArray, Value> {
+        @Query("select id from byteArrayFoo limit 1")
+        fun getByteArray(): Array<ByteArray>
+    }
+
     // Foo interfaces that are using the base
 
     @Dao
@@ -107,17 +115,29 @@
         override fun getFirstItemId(): String
     }
 
+    @Dao
+    interface ByteArrayFooDao : ByteArrayBaseDao<ByteArray, String> {
+
+        @Insert
+        fun insert(item: ByteArrayFoo)
+
+        @Query("select id from byteArrayFoo limit 1")
+        override fun getByteArray(): Array<ByteArray>
+    }
+
     @Database(
         version = 1,
         entities = [
             LongFoo::class,
-            StringFoo::class
+            StringFoo::class,
+            ByteArrayFoo::class
         ],
         exportSchema = false
     )
     abstract class TestDatabase : RoomDatabase() {
         abstract fun longFooDao(): LongFooDao
         abstract fun stringFooDao(): StringFooDao
+        abstract fun byteArrayFooDao(): ByteArrayFooDao
     }
 
     @Test
@@ -151,4 +171,16 @@
         db.stringFooDao().delete("Key")
         assertThat(db.stringFooDao().getItem("Key")).isNull()
     }
+
+    @Test
+    fun testByteArrayFooDao() {
+        val db = Room.inMemoryDatabaseBuilder(
+            InstrumentationRegistry.getInstrumentation()
+                .getTargetContext(),
+            TestDatabase::class.java
+        ).build()
+        val foo = ByteArrayFoo(ByteArray(16), "Elif")
+        db.byteArrayFooDao().insert(foo)
+        assertThat(db.byteArrayFooDao().getByteArray()).isEqualTo(arrayOf(ByteArray(16)))
+    }
 }
\ No newline at end of file
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/solver/query/result/ArrayQueryResultAdapter.kt b/room/room-compiler/src/main/kotlin/androidx/room/solver/query/result/ArrayQueryResultAdapter.kt
index 88cdd1a..cb5b392b 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/solver/query/result/ArrayQueryResultAdapter.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/solver/query/result/ArrayQueryResultAdapter.kt
@@ -16,6 +16,7 @@
 
 package androidx.room.solver.query.result
 
+import androidx.room.compiler.processing.isArray
 import androidx.room.ext.L
 import androidx.room.ext.T
 import androidx.room.solver.CodeGenScope
@@ -31,10 +32,19 @@
             rowAdapter.onCursorReady(cursorVarName, scope)
 
             val arrayType = ArrayTypeName.of(type.typeName)
-            addStatement(
-                "final $T $L = new $T[$L.getCount()]",
-                arrayType, outVarName, type.typeName, cursorVarName
-            )
+
+            if (type.isArray()) {
+                addStatement(
+                    "final $T $L = new $T[$L.getCount()][]",
+                    arrayType, outVarName, type.componentType.typeName, cursorVarName
+                )
+            } else {
+                addStatement(
+                    "final $T $L = new $T[$L.getCount()]",
+                    arrayType, outVarName, type.typeName, cursorVarName
+                )
+            }
+
             val tmpVarName = scope.getTmpVar("_item")
             val indexVar = scope.getTmpVar("_index")
             addStatement("$T $L = 0", TypeName.INT, indexVar)