Skip to content

Commit 96fe2e7

Browse files
committed
use numbered sqlite parameters so we can fit more updates into a single statement
1 parent 21580d1 commit 96fe2e7

File tree

2 files changed

+43
-44
lines changed

2 files changed

+43
-44
lines changed

firebase-firestore/src/main/java/com/google/firebase/firestore/local/SQLitePersistence.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,7 @@ static class LongQuery {
616616
// attempt to check for placeholders in the query {@link head}; if it only relied on the number
617617
// of placeholders it itself generates, in that situation it would still exceed the SQLite
618618
// limit.
619-
private static final int LIMIT = 900;
619+
static final int LIMIT = 900;
620620

621621
/**
622622
* Creates a new {@code LongQuery} with parameters that describe a template for creating each

firebase-firestore/src/main/java/com/google/firebase/firestore/local/SQLiteRemoteDocumentCache.java

Lines changed: 42 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import static com.google.firebase.firestore.util.Util.repeatSequence;
2222

2323
import android.database.Cursor;
24-
import android.util.Log;
2524
import androidx.annotation.NonNull;
2625
import androidx.annotation.VisibleForTesting;
2726
import com.google.firebase.Timestamp;
@@ -378,58 +377,58 @@ void add(String path, int readTimeSeconds, int readTimeNanos, MutableDocument do
378377
}
379378

380379
BackfillResult backfill(SQLitePersistence db) {
381-
ArrayList<String> caseClauses = new ArrayList<>();
382-
ArrayList<Object> caseClauseBindings = new ArrayList<>();
383-
ArrayList<String> whereClauses = new ArrayList<>();
384-
ArrayList<Object> whereClauseBindings = new ArrayList<>();
380+
StringBuilder caseClauses = new StringBuilder();
381+
StringBuilder whereClauses = new StringBuilder();
382+
ArrayList<Object> bindings = new ArrayList<>();
385383

386384
Iterator<BackfillKey> backfillKeys = documentTypeByBackfillKey.keySet().iterator();
387-
while (backfillKeys.hasNext()
388-
&& caseClauseBindings.size() + whereClauseBindings.size() < 900) {
385+
while (backfillKeys.hasNext() && bindings.size() < SQLitePersistence.LongQuery.LIMIT) {
389386
BackfillKey backfillKey = backfillKeys.next();
390387
DocumentType documentType = documentTypeByBackfillKey.remove(backfillKey);
391388
if (documentType == null) {
392389
continue;
393390
}
394391

395-
caseClauses.add("WHEN path=? AND read_time_seconds=? AND read_time_nanos=? THEN ?");
396-
caseClauseBindings.add(backfillKey.path);
397-
caseClauseBindings.add(backfillKey.readTimeSeconds);
398-
caseClauseBindings.add(backfillKey.readTimeNanos);
399-
caseClauseBindings.add(documentType.dbValue);
400-
401-
whereClauses.add("(path=? AND read_time_seconds=? AND read_time_nanos=?)");
402-
whereClauseBindings.add(backfillKey.path);
403-
whereClauseBindings.add(backfillKey.readTimeSeconds);
404-
whereClauseBindings.add(backfillKey.readTimeNanos);
405-
}
406-
407-
if (!caseClauseBindings.isEmpty()) {
408-
String sql;
409-
{
410-
StringBuilder sb = new StringBuilder("UPDATE remote_documents SET document_type = CASE");
411-
for (String caseClause : caseClauses) {
412-
sb.append(' ').append(caseClause);
413-
}
414-
sb.append(" ELSE NULL END WHERE ");
415-
boolean isFirstWhereClause = true;
416-
for (String whereClause : whereClauses) {
417-
if (isFirstWhereClause) {
418-
isFirstWhereClause = false;
419-
} else {
420-
sb.append(" OR ");
421-
}
422-
sb.append(whereClause);
423-
}
424-
sql = sb.toString();
392+
bindings.add(backfillKey.path);
393+
int pathBindingNumber = bindings.size();
394+
bindings.add(backfillKey.readTimeSeconds);
395+
int readTimeSecondsBindingNumber = bindings.size();
396+
bindings.add(backfillKey.readTimeNanos);
397+
int readTimeNanosBindingNumber = bindings.size();
398+
bindings.add(documentType.dbValue);
399+
int dbValueBindingNumber = bindings.size();
400+
401+
caseClauses
402+
.append(" WHEN path=?")
403+
.append(pathBindingNumber)
404+
.append(" AND read_time_seconds=?")
405+
.append(readTimeSecondsBindingNumber)
406+
.append(" AND read_time_nanos=?")
407+
.append(readTimeNanosBindingNumber)
408+
.append(" THEN ?")
409+
.append(dbValueBindingNumber);
410+
411+
if (whereClauses.length() > 0) {
412+
whereClauses.append(" OR");
425413
}
414+
whereClauses
415+
.append(" (path=?")
416+
.append(pathBindingNumber)
417+
.append(" AND read_time_seconds=?")
418+
.append(readTimeSecondsBindingNumber)
419+
.append(" AND read_time_nanos=?")
420+
.append(readTimeNanosBindingNumber)
421+
.append(')');
422+
}
426423

427-
caseClauseBindings.addAll(whereClauseBindings);
428-
Object[] bindings = caseClauseBindings.toArray();
429-
430-
Log.i("zzyzx", "sql=sql");
431-
432-
db.execute(sql, bindings);
424+
if (!bindings.isEmpty()) {
425+
String sql =
426+
"UPDATE remote_documents SET document_type = CASE"
427+
+ caseClauses
428+
+ " ELSE NULL END WHERE"
429+
+ whereClauses;
430+
android.util.Log.i("zzyzx", sql);
431+
db.execute(sql, bindings.toArray());
433432
}
434433

435434
return documentTypeByBackfillKey.isEmpty()

0 commit comments

Comments
 (0)