Support subquery filters in filter chains

Before, combined membership filters were only possible in filter
expressions, e.g. hostgroup_name=(a&b). Now, also
(hostgroup_name=a&hostgroup_name=b) is supported which makes it easier
to build such filters with the filter editor.
This commit is contained in:
Eric Lippmann 2019-07-11 14:46:30 +02:00 committed by Johannes Meyer
parent b8fb193bdd
commit 9a75e101ee
1 changed files with 42 additions and 0 deletions

View File

@ -3,6 +3,7 @@
namespace Icinga\Module\Monitoring\Backend\Ido\Query; namespace Icinga\Module\Monitoring\Backend\Ido\Query;
use Icinga\Data\Filter\FilterNot;
use Zend_Db_Expr; use Zend_Db_Expr;
use Icinga\Application\Icinga; use Icinga\Application\Icinga;
use Icinga\Application\Hook; use Icinga\Application\Hook;
@ -691,6 +692,47 @@ abstract class IdoQuery extends DbQuery
$filter->setColumn($column); $filter->setColumn($column);
} else { } else {
if (! $filter instanceof FilterNot) {
// Allow subquery filters in a filter chain
$columns = $filter->listFilteredColumns();
if (count($columns) === 1) {
$column = $columns[0];
$virtualTable = $this->aliasToTableName($column);
if (isset($this->subQueryTargets[$virtualTable])) {
$lastSign = null;
$filters = [];
$expressions = [];
foreach ($filter->filters() as $child) {
if ($lastSign === null) {
$lastSign = $child->getSign();
} else {
$sign = $child->getSign();
if ($sign !== $lastSign) {
$filters[] = new FilterExpression(
$column,
$lastSign,
$filter->getOperatorSymbol() === '&'
? [implode('&', $expressions)]
: $expressions
);
$expressions = [];
$lastSign = $sign;
}
}
$expressions[] = $child->getExpression();
}
$filters[] = new FilterExpression(
$column,
$lastSign,
$filter->getOperatorSymbol() === '&'
? [implode('&', $expressions)]
: $expressions
);
$filter->setFilters($filters);
}
}
}
foreach ($filter->filters() as $child) { foreach ($filter->filters() as $child) {
$replacement = $this->requireFilterColumns($child); $replacement = $this->requireFilterColumns($child);
if ($replacement !== null) { if ($replacement !== null) {