Fixed query for known vulns.

Used to work, then the default join from `fdroid_app` to `fdroid_apk`
was removed for performance reasons. This adds the join back, but requires
queries to explicitly opt in to the join if they require it. The specific
query for known vulns is not a performance problem, because sqlite is able
to narrow the result set quite substantially before requiring a join onto the
fdroid_apk table anyway (e.g. by using the "installed app" table).
This commit is contained in:
Peter Serwylo 2017-09-27 15:37:09 +10:00
parent 382ee652b8
commit 2bd70fc6b5

View File

@ -157,6 +157,7 @@ public class AppProvider extends FDroidProvider {
protected static class AppQuerySelection extends QuerySelection { protected static class AppQuerySelection extends QuerySelection {
private boolean naturalJoinToInstalled; private boolean naturalJoinToInstalled;
private boolean naturalJoinApks;
private boolean naturalJoinAntiFeatures; private boolean naturalJoinAntiFeatures;
private boolean leftJoinPrefs; private boolean leftJoinPrefs;
@ -178,6 +179,10 @@ public class AppProvider extends FDroidProvider {
return naturalJoinToInstalled; return naturalJoinToInstalled;
} }
public boolean naturalJoinToApks() {
return naturalJoinApks;
}
public boolean naturalJoinAntiFeatures() { public boolean naturalJoinAntiFeatures() {
return naturalJoinAntiFeatures; return naturalJoinAntiFeatures;
} }
@ -194,6 +199,17 @@ public class AppProvider extends FDroidProvider {
return this; return this;
} }
/**
* Note that this has large performance implications, so should only be used if you are already limiting
* the result set based on other, more drastic conditions first.
* See https://gitlab.com/fdroid/fdroidclient/issues/1143 for the investigation which identified these
* performance implications.
*/
public AppQuerySelection requireNaturalJoinApks() {
naturalJoinApks = true;
return this;
}
public AppQuerySelection requireNatrualJoinAntiFeatures() { public AppQuerySelection requireNatrualJoinAntiFeatures() {
naturalJoinAntiFeatures = true; naturalJoinAntiFeatures = true;
return this; return this;
@ -215,6 +231,10 @@ public class AppProvider extends FDroidProvider {
bothWithJoin.requireNaturalInstalledTable(); bothWithJoin.requireNaturalInstalledTable();
} }
if (this.naturalJoinToApks() || query.naturalJoinToApks()) {
bothWithJoin.requireNaturalJoinApks();
}
if (this.leftJoinToPrefs() || query.leftJoinToPrefs()) { if (this.leftJoinToPrefs() || query.leftJoinToPrefs()) {
bothWithJoin.requireLeftJoinPrefs(); bothWithJoin.requireLeftJoinPrefs();
} }
@ -232,6 +252,7 @@ public class AppProvider extends FDroidProvider {
private boolean isSuggestedApkTableAdded; private boolean isSuggestedApkTableAdded;
private boolean requiresInstalledTable; private boolean requiresInstalledTable;
private boolean requiresApkTable;
private boolean requiresAntiFeatures; private boolean requiresAntiFeatures;
private boolean requiresLeftJoinToPrefs; private boolean requiresLeftJoinToPrefs;
private boolean countFieldAppended; private boolean countFieldAppended;
@ -263,6 +284,9 @@ public class AppProvider extends FDroidProvider {
if (selection.naturalJoinToInstalled()) { if (selection.naturalJoinToInstalled()) {
naturalJoinToInstalledTable(); naturalJoinToInstalledTable();
} }
if (selection.naturalJoinToApks()) {
naturalJoinToApkTable();
}
if (selection.leftJoinToPrefs()) { if (selection.leftJoinToPrefs()) {
leftJoinToPrefs(); leftJoinToPrefs();
} }
@ -283,6 +307,17 @@ public class AppProvider extends FDroidProvider {
} }
} }
public void naturalJoinToApkTable() {
if (!requiresApkTable) {
join(
getApkTableName(),
getApkTableName(),
getApkTableName() + "." + ApkTable.Cols.APP_ID + " = " + getTableName() + "." + Cols.ROW_ID
);
requiresApkTable = true;
}
}
public void leftJoinToPrefs() { public void leftJoinToPrefs() {
if (!requiresLeftJoinToPrefs) { if (!requiresLeftJoinToPrefs) {
leftJoin( leftJoin(
@ -720,6 +755,7 @@ public class AppProvider extends FDroidProvider {
return new AppQuerySelection(selection) return new AppQuerySelection(selection)
.requireNaturalInstalledTable() .requireNaturalInstalledTable()
.requireNaturalJoinApks()
.requireNatrualJoinAntiFeatures() .requireNatrualJoinAntiFeatures()
.requireLeftJoinPrefs(); .requireLeftJoinPrefs();
} }