Index: /trunk/src/VBox/ValidationKit/testmanager/core/base.py
===================================================================
--- /trunk/src/VBox/ValidationKit/testmanager/core/base.py	(revision 65073)
+++ /trunk/src/VBox/ValidationKit/testmanager/core/base.py	(revision 65074)
@@ -1241,4 +1241,12 @@
             elif oCriterion.sType == FilterCriterion.ksType_String:
                 oCriterion.aoSelected = oDisp.getListOfStrParams(oCriterion.sVarNm, asDefaults = []);
+                if len(oCriterion.aoSelected) > 100:
+                    raise TMExceptionBase('Variable %s has %u value, max allowed is 100!'
+                                          % (oCriterion.sVarNm, len(oCriterion.aoSelected)));
+                for sValue in oCriterion.aoSelected:
+                    if   len(sValue) > 64 \
+                      or '\'' in sValue \
+                      or sValue[-1] == '\\':
+                        raise TMExceptionBase('Variable %s has an illegal value "%s"!' % (oCriterion.sVarNm, sValue));
             else:
                 assert False;
Index: /trunk/src/VBox/ValidationKit/testmanager/core/report.py
===================================================================
--- /trunk/src/VBox/ValidationKit/testmanager/core/report.py	(revision 65073)
+++ /trunk/src/VBox/ValidationKit/testmanager/core/report.py	(revision 65074)
@@ -864,5 +864,5 @@
         Fetches possible filtering options.
         """
-        return TestResultLogic(self._oDb).fetchPossibleFilterOptions(oFilter, tsNow, sPeriod);
+        return TestResultLogic(self._oDb).fetchPossibleFilterOptions(oFilter, tsNow, sPeriod, oReportModel = self);
 
 
Index: /trunk/src/VBox/ValidationKit/testmanager/core/testresults.py
===================================================================
--- /trunk/src/VBox/ValidationKit/testmanager/core/testresults.py	(revision 65073)
+++ /trunk/src/VBox/ValidationKit/testmanager/core/testresults.py	(revision 65074)
@@ -41,5 +41,5 @@
                                                    TMExceptionBase, TMTooManyRows, TMRowNotFound;
 from testmanager.core.testgroup             import TestGroupData;
-from testmanager.core.build                 import BuildDataEx, BuildCategoryData, BuildLogic, BuildCategoryLogic;
+from testmanager.core.build                 import BuildDataEx, BuildCategoryData, BuildLogic;
 from testmanager.core.failurereason         import FailureReasonLogic;
 from testmanager.core.testbox               import TestBoxData, TestBoxLogic;
@@ -1438,5 +1438,5 @@
             return None
 
-    def fetchPossibleFilterOptions(self, oFilter, tsNow, sPeriod):
+    def fetchPossibleFilterOptions(self, oFilter, tsNow, sPeriod, oReportModel = None):
         """
         Fetches the available filter criteria, given the current filtering.
@@ -1445,4 +1445,16 @@
         """
         assert isinstance(oFilter, TestResultFilter);
+
+        # Hack to avoid lot's of conditionals or duplicate this code.
+        if oReportModel is None:
+            class DummyReportModel(object):
+                """ Dummy """
+                def getExtraSubjectTables(self):
+                    """ Dummy """
+                    return [];
+                def getExtraSubjectWhereExpr(self):
+                    """ Dummy """
+                    return '';
+            oReportModel = DummyReportModel();
 
         def workerDoFetch(oMissingLogicType, sNameAttr = 'sName', fIdIsName = False):
@@ -1471,6 +1483,8 @@
         self._oDb.execute('SELECT TestSets.enmStatus, TestSets.enmStatus, COUNT(TestSets.idTestSet)\n'
                           'FROM   TestSets\n' + oFilter.getTableJoins(iOmit = TestResultFilter.kiTestStatus) +
+                          ''.join('        , %s\n' % (sTable,) for sTable in oReportModel.getExtraSubjectTables()) +
                           'WHERE  ' + self._getTimePeriodQueryPart(tsNow, sPeriod) +
                           oFilter.getWhereConditions(iOmit = TestResultFilter.kiTestStatus) +
+                          oReportModel.getExtraSubjectWhereExpr() +
                           'GROUP BY TestSets.enmStatus\n'
                           'ORDER BY TestSets.enmStatus\n');
@@ -1483,6 +1497,8 @@
                           '                MAX(TestSets.tsCreated) AS tsNow\n'
                           '         FROM   TestSets\n' + oFilter.getTableJoins(iOmit = TestResultFilter.kiSchedGroups) +
+                          ''.join('                , %s\n' % (sTable,) for sTable in oReportModel.getExtraSubjectTables()) +
                           '         WHERE  ' + self._getTimePeriodQueryPart(tsNow, sPeriod, '         ') +
                           oFilter.getWhereConditions(iOmit = TestResultFilter.kiSchedGroups) +
+                          oReportModel.getExtraSubjectWhereExpr() +
                           '         GROUP BY TestSets.idSchedGroup\n'
                           '       ) AS SchedGroupIDs\n'
@@ -1500,6 +1516,8 @@
                           '                MAX(TestSets.idGenTestBox) AS idGenTestBox\n'
                           '         FROM   TestSets\n' + oFilter.getTableJoins(iOmit = TestResultFilter.kiTestBoxes) +
+                          ''.join('                , %s\n' % (sTable,) for sTable in oReportModel.getExtraSubjectTables()) +
                           '         WHERE  ' + self._getTimePeriodQueryPart(tsNow, sPeriod, '        ') +
                           oFilter.getWhereConditions(iOmit = TestResultFilter.kiTestBoxes) +
+                          oReportModel.getExtraSubjectWhereExpr() +
                           '         GROUP BY TestSets.idTestBox\n'
                           '       ) AS TestBoxIDs\n'
@@ -1514,6 +1532,8 @@
                           'FROM   ( SELECT DISTINCT TestSets.idGenTestBox\n'
                           '         FROM   TestSets\n' + oFilter.getTableJoins(iOmit = TestResultFilter.kiOses) +
+                          ''.join('                , %s\n' % (sTable,) for sTable in oReportModel.getExtraSubjectTables()) +
                           '         WHERE  ' + self._getTimePeriodQueryPart(tsNow, sPeriod, '        ') +
                           oFilter.getWhereConditions(iOmit = TestResultFilter.kiOses) +
+                          oReportModel.getExtraSubjectWhereExpr() +
                           '       ) AS TestBoxGenIDs\n'
                           '       LEFT OUTER JOIN TestBoxesWithStrings\n'
@@ -1527,6 +1547,8 @@
                           'FROM   ( SELECT DISTINCT TestSets.idGenTestBox AS idGenTestBox\n'
                           '         FROM   TestSets\n' + oFilter.getTableJoins(iOmit = TestResultFilter.kiOsVersions) +
+                          ''.join('                , %s\n' % (sTable,) for sTable in oReportModel.getExtraSubjectTables()) +
                           '         WHERE  ' + self._getTimePeriodQueryPart(tsNow, sPeriod, '        ') +
                           oFilter.getWhereConditions(iOmit = TestResultFilter.kiOsVersions) +
+                          oReportModel.getExtraSubjectWhereExpr() +
                           '       ) AS TestBoxGenIDs\n'
                           '       LEFT OUTER JOIN TestBoxesWithStrings\n'
@@ -1540,6 +1562,8 @@
                           'FROM   ( SELECT DISTINCT TestSets.idGenTestBox\n'
                           '         FROM   TestSets\n' + oFilter.getTableJoins(iOmit = TestResultFilter.kiCpuArches) +
+                          ''.join('                , %s\n' % (sTable,) for sTable in oReportModel.getExtraSubjectTables()) +
                           '         WHERE  ' + self._getTimePeriodQueryPart(tsNow, sPeriod, '        ') +
                           oFilter.getWhereConditions(iOmit = TestResultFilter.kiCpuArches) +
+                          oReportModel.getExtraSubjectWhereExpr() +
                           '       ) AS TestBoxGenIDs\n'
                           '       LEFT OUTER JOIN TestBoxesWithStrings\n'
@@ -1553,6 +1577,8 @@
                           'FROM   ( SELECT DISTINCT TestSets.idGenTestBox\n'
                           '         FROM   TestSets\n' + oFilter.getTableJoins(iOmit = TestResultFilter.kiCpuVendors) +
+                          ''.join('                , %s\n' % (sTable,) for sTable in oReportModel.getExtraSubjectTables()) +
                           '         WHERE  ' + self._getTimePeriodQueryPart(tsNow, sPeriod, '        ') +
                           oFilter.getWhereConditions(iOmit = TestResultFilter.kiCpuVendors) +
+                          oReportModel.getExtraSubjectWhereExpr() +
                           '       ) AS TestBoxGenIDs\n'
                           '       LEFT OUTER JOIN TestBoxesWithStrings\n'
@@ -1567,6 +1593,8 @@
                           '                MAX(TestSets.idGenTestCase) AS idGenTestCase\n'
                           '         FROM   TestSets\n' + oFilter.getTableJoins(iOmit = TestResultFilter.kiTestCases) +
+                          ''.join('                , %s\n' % (sTable,) for sTable in oReportModel.getExtraSubjectTables()) +
                           '         WHERE  ' + self._getTimePeriodQueryPart(tsNow, sPeriod, '        ') +
                           oFilter.getWhereConditions(iOmit = TestResultFilter.kiTestCases) +
+                          oReportModel.getExtraSubjectWhereExpr() +
                           '         GROUP BY TestSets.idTestCase\n'
                           '       ) AS TestCasesIDs\n'
@@ -1581,6 +1609,8 @@
                           '                MAX(TestSets.tsCreated) AS tsNow\n'
                           '         FROM   TestSets\n' + oFilter.getTableJoins(iOmit = TestResultFilter.kiRevisions) +
+                          ''.join('                , %s\n' % (sTable,) for sTable in oReportModel.getExtraSubjectTables()) +
                           '         WHERE  ' + self._getTimePeriodQueryPart(tsNow, sPeriod, '        ') +
                           oFilter.getWhereConditions(iOmit = TestResultFilter.kiRevisions) +
+                          oReportModel.getExtraSubjectWhereExpr() +
                           '         GROUP BY TestSets.idBuild\n'
                           '       ) AS BuildIDs\n'
@@ -1598,6 +1628,8 @@
                           'FROM   ( SELECT DISTINCT TestSets.idBuildCategory\n'
                           '         FROM   TestSets\n' + oFilter.getTableJoins(iOmit = TestResultFilter.kiBranches) +
+                          ''.join('                , %s\n' % (sTable,) for sTable in oReportModel.getExtraSubjectTables()) +
                           '         WHERE  ' + self._getTimePeriodQueryPart(tsNow, sPeriod, '        ') +
                           oFilter.getWhereConditions(iOmit = TestResultFilter.kiBranches) +
+                          oReportModel.getExtraSubjectWhereExpr() +
                           '       ) AS BuildCategoryIDs\n'
                           '       INNER JOIN BuildCategories\n'
@@ -1615,6 +1647,8 @@
                           '                    AND TestResultFailures.tsExpire  = \'infinity\'::TIMESTAMP\n' +
                           oFilter.getTableJoins(iOmit = TestResultFilter.kiFailReasons) +
+                          ''.join('                , %s\n' % (sTable,) for sTable in oReportModel.getExtraSubjectTables()) +
                           '         WHERE  ' + self._getTimePeriodQueryPart(tsNow, sPeriod, '        ') +
                           oFilter.getWhereConditions(iOmit = TestResultFilter.kiFailReasons) +
+                          oReportModel.getExtraSubjectWhereExpr() +
                           '         GROUP BY TestResultFailures.idFailureReason\n'
                           '       ) AS FailureReasonIDs\n'
