Issue #3190285 by mondrake, anmolgoyal74, daffie: Entity QueryAggregate does not escape the field

merge-requests/37/head
catch 2021-01-15 13:23:54 +00:00
parent 1e1d9a9f7a
commit d99b12fb9e
3 changed files with 12 additions and 6 deletions

View File

@ -38,7 +38,8 @@ class ConditionAggregate extends ConditionAggregateBase {
$condition_class::translateCondition($condition, $sql_query, $tables->isFieldCaseSensitive($condition['field']));
$function = $condition['function'];
$placeholder = ':db_placeholder_' . $conditionContainer->nextPlaceholder();
$conditionContainer->having("$function($field) {$condition['operator']} $placeholder", [$placeholder => $condition['value']]);
$sql_field_escaped = '[' . str_replace('.', '].[', $field) . ']';
$conditionContainer->having("$function($sql_field_escaped) {$condition['operator']} $placeholder", [$placeholder => $condition['value']]);
}
}
}

View File

@ -75,7 +75,8 @@ class QueryAggregate extends Query implements QueryAggregateInterface {
if ($this->aggregate) {
foreach ($this->aggregate as $aggregate) {
$sql_field = $this->getSqlField($aggregate['field'], $aggregate['langcode']);
$this->sqlExpressions[$aggregate['alias']] = $aggregate['function'] . "($sql_field)";
$sql_field_escaped = '[' . str_replace('.', '].[', $sql_field) . ']';
$this->sqlExpressions[$aggregate['alias']] = $aggregate['function'] . "($sql_field_escaped)";
}
}
return $this;

View File

@ -131,10 +131,14 @@ class EntityQueryAggregateTest extends EntityKernelTestBase {
// Apply a simple aggregation for different aggregation functions.
foreach ($function_expected as $aggregation_function => $expected) {
$this->queryResult = $this->entityStorage->getAggregateQuery()
->aggregate('id', $aggregation_function)
->execute();
$this->assertEqual($this->queryResult, $expected);
$query = $this->entityStorage->getAggregateQuery()
->aggregate('id', $aggregation_function);
$this->queryResult = $query->execute();
// We need to check that a character exists before and after the table,
// column and alias identifiers. These would be the quote characters
// specific for each database system.
$this->assertRegExp('/' . $aggregation_function . '\(.entity_test.\..id.\) AS .id_' . $aggregation_function . './', (string) $query, 'The argument to the aggregation function should be a quoted field.');
$this->assertEquals($expected, $this->queryResult);
}
// Apply aggregation and groupby on the same query.