aboutsummaryrefslogtreecommitdiff
path: root/src/com/android/providers/contacts/ContactsProvider2.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/providers/contacts/ContactsProvider2.java')
-rw-r--r--src/com/android/providers/contacts/ContactsProvider2.java45
1 files changed, 34 insertions, 11 deletions
diff --git a/src/com/android/providers/contacts/ContactsProvider2.java b/src/com/android/providers/contacts/ContactsProvider2.java
index 7b3c7f0f..57e1e5d7 100644
--- a/src/com/android/providers/contacts/ContactsProvider2.java
+++ b/src/com/android/providers/contacts/ContactsProvider2.java
@@ -3594,25 +3594,48 @@ public class ContactsProvider2 extends SQLiteContentProvider implements OnAccoun
case EMAILS_FILTER: {
setTablesAndProjectionMapForData(qb, uri, projection, true);
- qb.appendWhere(" AND " + Data.MIMETYPE + " = '" + Email.CONTENT_ITEM_TYPE + "'");
- if (uri.getPathSegments().size() > 2) {
- String filterParam = uri.getLastPathSegment();
- StringBuilder sb = new StringBuilder();
- sb.append("(");
+ String filterParam = null;
+ if (uri.getPathSegments().size() > 3) {
+ filterParam = uri.getLastPathSegment();
+ if (TextUtils.isEmpty(filterParam)) {
+ filterParam = null;
+ }
+ }
+ if (filterParam == null) {
+ // If the filter is unspecified, return nothing
+ qb.appendWhere(" AND 0");
+ } else {
+ StringBuilder sb = new StringBuilder();
+ sb.append(" AND " + Data._ID + " IN (");
+ sb.append(
+ "SELECT " + Data._ID +
+ " FROM " + Tables.DATA +
+ " WHERE " + DataColumns.MIMETYPE_ID + "=" + mMimeTypeIdEmail +
+ " AND " + Data.DATA1 + " LIKE ");
+ DatabaseUtils.appendEscapedSQLString(sb, filterParam + '%');
if (!filterParam.contains("@")) {
String normalizedName = NameNormalizer.normalize(filterParam);
if (normalizedName.length() > 0) {
- sb.append(Data.RAW_CONTACT_ID + " IN ");
+
+ /*
+ * Using a UNION instead of an "OR" to make SQLite use the right
+ * indexes. We need it to use the (mimetype,data1) index for the
+ * email lookup (see above), but not for the name lookup.
+ * SQLite is not smart enough to use the index on one side of an OR
+ * but not on the other. Using two separate nested queries
+ * and a UNION between them does the job.
+ */
+ sb.append(
+ " UNION SELECT " + Data._ID +
+ " FROM " + Tables.DATA +
+ " WHERE +" + DataColumns.MIMETYPE_ID + "=" + mMimeTypeIdEmail +
+ " AND " + Data.RAW_CONTACT_ID + " IN ");
appendRawContactsByNormalizedNameFilter(sb, normalizedName, null, false);
- sb.append(" OR ");
}
}
-
- sb.append(Email.DATA + " LIKE ");
- sb.append(DatabaseUtils.sqlEscapeString(filterParam + '%'));
sb.append(")");
- qb.appendWhere(" AND " + sb);
+ qb.appendWhere(sb);
}
groupBy = Email.DATA + "," + RawContacts.CONTACT_ID;
if (sortOrder == null) {