Bug 1384696 - Query folders iteratively to prevent exceeding maximum variable count in a clause. r?Grisha draft
authorJing-wei Wu <topwu.tw@gmail.com>
Thu, 27 Jul 2017 10:42:45 +0800
changeset 668895 66ce2b29437497779221055ae087feffc181994b
parent 668894 9fb93fcf2b8eece6b7b23d12e29cbacc16e90b0c
child 668896 88d8e2df3ee196eba2b0e64b26d26db454e77499
push id81146
push userbmo:topwu.tw@gmail.com
push dateFri, 22 Sep 2017 05:24:51 +0000
reviewersGrisha
bugs1384696
milestone58.0a1
Bug 1384696 - Query folders iteratively to prevent exceeding maximum variable count in a clause. r?Grisha MozReview-Commit-ID: AXAxJbp152l
mobile/android/base/java/org/mozilla/gecko/db/BrowserProvider.java
--- a/mobile/android/base/java/org/mozilla/gecko/db/BrowserProvider.java
+++ b/mobile/android/base/java/org/mozilla/gecko/db/BrowserProvider.java
@@ -2424,45 +2424,57 @@ public class BrowserProvider extends Sha
                 }
             }
         } finally {
             cursor.close();
         }
 
         // Keep finding descendant GUIDs from parent IDs.
         while (!folderQueue.isEmpty()) {
-            // Store all parent IDs in a in clause, and can query their children at once.
-            final String[] inClauseArgs = new String[folderQueue.size()];
-            int count = 0;
-            while (folderQueue.peek() != null) {
-                final long id = folderQueue.poll();
-                inClauseArgs[count++] = String.valueOf(id);
-            }
-
-            final String inClause = DBUtils.computeSQLInClause(count, Bookmarks.PARENT);
-            // We only select distinct parent IDs.
-            final Cursor c = db.query(true, TABLE_BOOKMARKS,
-                                      new String[] { Bookmarks._ID, Bookmarks.TYPE, Bookmarks.GUID },
-                                      inClause, inClauseArgs, null, null, null, null);
-            if (c == null) {
-                continue;
-            }
-            try {
-                while (c.moveToNext()) {
-                    final int type = c.getInt(c.getColumnIndexOrThrow(Bookmarks.TYPE));
-                    if (type == Bookmarks.TYPE_FOLDER) {
-                        final long id = c.getLong(c.getColumnIndexOrThrow(Bookmarks._ID));
-                        folderQueue.add(id);
+            final int folderCount = folderQueue.size();
+            final int chunkCount = folderCount / DBUtils.SQLITE_MAX_VARIABLE_NUMBER;
+            for (int chunk = 0; chunk <= chunkCount; chunk++) {
+                final int chunkStart = chunk * DBUtils.SQLITE_MAX_VARIABLE_NUMBER;
+                int chunkEnd = (chunk + 1) * DBUtils.SQLITE_MAX_VARIABLE_NUMBER;
+                if (chunkEnd > folderCount) {
+                    chunkEnd = folderCount;
+                }
+
+                // Store all parent IDs in a in clause, and can query their children at once.
+                final int inClauseSize = chunkEnd - chunkStart;
+                final String[] inClauseArgs = new String[inClauseSize];
+                int count = 0;
+
+                for (int i = 0; i < inClauseSize; i++) {
+                    final long id = folderQueue.poll();
+                    inClauseArgs[count++] = String.valueOf(id);
+                }
+
+                final String inClause = DBUtils.computeSQLInClause(count, Bookmarks.PARENT);
+                // We only select distinct parent IDs.
+                final Cursor c = db.query(true, TABLE_BOOKMARKS,
+                                          new String[] { Bookmarks._ID, Bookmarks.TYPE, Bookmarks.GUID },
+                                          inClause, inClauseArgs, null, null, null, null);
+                if (c == null) {
+                    continue;
+                }
+                try {
+                    while (c.moveToNext()) {
+                        final int type = c.getInt(c.getColumnIndexOrThrow(Bookmarks.TYPE));
+                        if (type == Bookmarks.TYPE_FOLDER) {
+                            final long id = c.getLong(c.getColumnIndexOrThrow(Bookmarks._ID));
+                            folderQueue.add(id);
+                        }
+
+                        final String guid = c.getString(c.getColumnIndexOrThrow(Bookmarks.GUID));
+                        guids.add(guid);
                     }
-
-                    final String guid = c.getString(c.getColumnIndexOrThrow(Bookmarks.GUID));
-                    guids.add(guid);
+                } finally {
+                    c.close();
                 }
-            } finally {
-                c.close();
             }
         }
         return guids;
     }
 
     private int deleteFavicons(Uri uri, String selection, String[] selectionArgs) {
         debug("Deleting favicons for URI: " + uri);