From dc7756c5996a61e2721d7bdda289fdaf154e0af7 Mon Sep 17 00:00:00 2001 From: Johannes Meyer Date: Thu, 12 Nov 2015 09:13:46 +0100 Subject: [PATCH] DbRepository: Fix that PostgreSQL queries do not apply LOWER on order cols refs #10364 refs #9955 --- library/Icinga/Repository/DbRepository.php | 80 +++++++++------------- 1 file changed, 34 insertions(+), 46 deletions(-) diff --git a/library/Icinga/Repository/DbRepository.php b/library/Icinga/Repository/DbRepository.php index 12ef7ebe6..a18a47e73 100644 --- a/library/Icinga/Repository/DbRepository.php +++ b/library/Icinga/Repository/DbRepository.php @@ -592,47 +592,6 @@ abstract class DbRepository extends Repository implements Extensible, Updatable, } } - /** - * Recurse the given filter, require each column for the given table and convert all values - * - * In case of a PostgreSQL connection, this applies LOWER() on the column and strtolower() - * on the value if a COLLATE SQL-instruction is part of the resolved column. - * - * @param string $table The table being filtered - * @param Filter $filter The filter to recurse - * @param RepositoryQuery $query An optional query to pass as context - * (Directly passed through to $this->requireFilterColumn) - * @param bool $clone Whether to clone $filter first - * - * @return Filter The udpated filter - */ - public function requireFilter($table, Filter $filter, RepositoryQuery $query = null, $clone = true) - { - if (! empty($this->caseInsensitiveColumns) && $filter->isExpression()) { - $alias = $filter->getColumn(); - if (! $this->validateQueryColumnAssociation($table, $alias)) { - $origin = $this->findTableName($alias); // It might be a joined column - } else { - $origin = $table; - } - - if ($origin && isset($this->caseInsensitiveColumns[$origin][$alias])) { - $filter = parent::requireFilter($table, $filter, $query, $clone); - $filter->setColumn('LOWER(' . $filter->getColumn() . ')'); - $expression = $filter->getExpression(); - if (is_array($expression)) { - $filter->setExpression(array_map('strtolower', $expression)); - } else { - $filter->setExpression(strtolower($expression)); - } - - return $filter; - } - } - - return parent::requireFilter($table, $filter, $query, $clone); - } - /** * Return the alias for the given query column name or null in case the query column name does not exist * @@ -683,7 +642,8 @@ abstract class DbRepository extends Repository implements Extensible, Updatable, * Validate that the given column is a valid filter target and return it or the actual name if it's an alias * * Attempts to join the given column from a different table if its association to the given table cannot be - * verified. + * verified. In case of a PostgreSQL connection and if a COLLATE SQL-instruction is part of the resolved column, + * this applies LOWER() on the column and, if given, strtolower() on the filter's expression. * * @param string $table The table where to look for the column or alias * @param string $name The name or alias of the column to validate @@ -697,15 +657,43 @@ abstract class DbRepository extends Repository implements Extensible, Updatable, */ public function requireFilterColumn($table, $name, RepositoryQuery $query = null, FilterExpression $filter = null) { + $joined = false; if ($query === null) { - return $this->requireStatementColumn($table, $name); + $column = $this->requireStatementColumn($table, $name); + } elseif ($this->validateQueryColumnAssociation($table, $name)) { + $column = parent::requireFilterColumn($table, $name, $query, $filter); + } else { + $column = $this->joinColumn($name, $table, $query); + $joined = true; } - if ($this->validateQueryColumnAssociation($table, $name)) { - return parent::requireFilterColumn($table, $name, $query, $filter); + if (! empty($this->caseInsensitiveColumns)) { + if ($joined) { + $table = $this->findTableName($name); + } + + if ($column === $name) { + if ($query === null) { + $name = $this->reassembleStatementColumnAlias($table, $name); + } else { + $name = $this->reassembleQueryColumnAlias($table, $name); + } + } + + if (isset($this->caseInsensitiveColumns[$table][$name])) { + $column = 'LOWER(' . $column . ')'; + if ($filter !== null) { + $expression = $filter->getExpression(); + if (is_array($expression)) { + $filter->setExpression(array_map('strtolower', $expression)); + } else { + $filter->setExpression(strtolower($expression)); + } + } + } } - return $this->joinColumn($name, $table, $query); + return $column; } /**