Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mobile: Fixes #11571: Use alternative fix to set the sqlite CursorWindow size to 50mb #11726

Open
wants to merge 2 commits into
base: dev
Choose a base branch
from

Conversation

mrjo118
Copy link
Contributor

@mrjo118 mrjo118 commented Jan 25, 2025

There is an issue that on certain Android devices, it is possible to get the "Row too big to fit into CursorWindow" error when synchronizing and handling notes which are large in size (at least 1-2mb depending on whether E2E encryption is enabled and the version of Android). This is due to a limitation which is put in place in the Android versions of sqlite specifically. Attempts have been made to workaround this in the past by a change to MainApplication.kt, but unfortunately some users report the issue still occurring.

On my own device (a Samsung Galaxy S9+ on Android 10) I can reproduce the "Row too big to fit into CursorWindow" error by importing a large note which is over 4mb in size and then deleting it (among other ways to produce the error). The example I have been using for this is big.jex (attached at the bottom). Upon deletion of the imported note, I am presented with an alert saying: "This note could not be deleted: On query {"sql":"SELECT * FROM notes WHERE id IN ('xxxxxxxxxxxxxxxxxxxxxxx')","params":[]}: Row too big to fit into CursorWindow requiredPos=0, totalRows=1".
If I do the same on Android 10 on emulator, I get no error, which is evidence that the workaround in MainApplication.kt is working correctly on some devices.

From testing via hacked versions of the Joplin app which I built, I have confirmed that the logic for extending the CursorWindow size in MainApplication.kt executes without errors on my device (where the workaround does not work). The value of the sCursorWindowSize field on the android.database.CursorWindow class is indeed changed to the desired value via reflection. However, the CursorWindow size used by sqlite queries throughout the application in practice is not extended, when running on my device. This is despite the fact that when I write the sqlite version on my device to the log, it returns v3.22.0, which is the expected version for API 29, as per the documentation here https://developer.android.com/reference/android/database/sqlite/package-summary . This page also specifies that the vendor may include their own version of sqlite on the device instead, so although the version specified is the same, the binary still may be a custom build.

I believe the issue occurs on some devices, because the version of sqlite included with the device does not make use of a Cursor implementation which makes use of the CursorWindow class. To ensure that the desired cursor window size is always used, the change can be made at a lower level by patching the react-native-sqlite-storage code to use the new constructor available in api 28 and above. The patch also includes logic to not make use of this new constructor when the api level is below 28 (increasing the cursor size is not supported on versions lower than this anyway), to avoid breaking the code on older devices. There is also only a need to patch the SQLitePlugin class used for the device version of sqlite, because if you use the native sqlite mode of this library, there is no such limitation of cursor window size being enforced. However using the native sqlite mode is not the best option, as the sqlite version is not the most up to date and some users have reported issues with it not working on their device.

Testing:
I have verified that this patch to react-native-sqlite-storage does indeed fix the issue on my device, as when using this version, I am able to import big.jex, view it and delete it without issues or errors in the log. This signifies that increasing the CursorWindow size has indeed worked. Also browsing, opening, editing and tagging notes all work as normal. I have also tested the change using the app on emulator using Android O (API 27) and can confirm that browsing, opening, editing and tagging notes all work as normal, meaning the logic to only apply the workaround if API level is 28 or above is working.

big.zip

+ cur = ac;
+ }
+
// If query result has rows
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Sync fails on Android mobile with error [object Object]
2 participants