[ 
https://issues.apache.org/jira/browse/CALCITE-4334?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Julian Hyde updated CALCITE-4334:
---------------------------------
    Description: 
It would be useful to have an aggregate function that returns a constant value, 
regardless of how many rows are in the group. We propose {{LITERAL_AGG}}, an 
internal aggregate function. As an aggregate function it has no arguments 
(meaning that it does not read any columns from the input), but a call will 
have a RexLiteral (constant expression).

This aggregate function is internal, so there is no SQL syntax. But if I were 
to write
{code}
SELECT deptno, SUM(sal), true
FROM Emp
GROUP BY deptno
{code}
I should get the following plan:
{code}
Aggregate(group={deptno}, aggCalls=SUM($4), LITERAL_AGG(true))
  Scan(Emp)
{code}

Today, the plan would require an extra {{Project}} to add {{RexLiteral(true)}}. 
Planner rules have to look for a {{Project}} of a literal on top of an 
{{Aggregate}}; by removing the {{Project}} we simplify planning.

For example, when rewriting sub-queries (see {{SubQueryRemoveRule}}) we 
introduce add "true as indicator" to the SELECT clause of sub-queries. It can 
be used to detect rows generated by an outer join. If it is an aggregate query, 
we would have to write "min(true) as indicator", which necessitates an extra 
{{Project}} below the {{Aggregate}} to provide the  "true" value. The 
LITERAL_AGG aggregate function allows us to avoid the extra {{Project}}.

Another example came up during CALCITE-4317. We would like to make 
{{RelBuilder.aggregate(groupKey())}} throw when given an empty group key and no 
aggregate calls. (Because it would create an {{Aggregate}} that has zero 
fields, and that is problematic elsewhere in Calcite.) But we would also like a 
pattern where an aggregate with an empty group key becomes a constant 
single-row relational expression. So, {{RelBulder.aggregate(groupKey(), 
aggregateCall(LITERAL_AGG(true)))}} should generate {{VALUES TRUE}}.

{{LITERAL_AGG}} uses {{interface SqlStaticAggFunction}}, an interface that can 
optionally be implemented (or wrapped, via {{SqlAggFunction.unwrap(Class)}}), 
to make the planner and code-generator aware of its properties.

The implementation adds a {{List<RexNode> rexList}} field to {{AggregateCall}}. 
This field is empty in all conventional aggregate functions, and has one 
element in {{LITERAL_AGG}}.

  was:
It would be useful to have an (internal) aggregate function that has no 
arguments and returns a constant value, regardless of how many rows are in the 
group. We suggest {{TRUE_AGG}}, which always returns the {{BOOLEAN}} value 
{{TRUE}}.

If there are reasons why it would be better to return other constants (such as 
0, 1, FALSE or the empty string) we will consider them.

For example, when rewriting sub-queries (see SubQueryRemoveRule) we introduce 
add "true as indicator" to the SELECT clause of sub-queries. It can be used to 
detect rows generated by an outer join. If it is an aggregate query, we would 
have to write "min(true) as indicator", which necessitates an extra {{Project}} 
below the {{Aggregate}} to provide the  "true" value. A TRUE_AGG aggregate 
function allows us to avoid the extra {{Project}}.

Another example came up during CALCITE-4317. We would like to make 
{{RelBuilder.aggregate(groupKey())}} throw when given an empty group key and no 
aggregate calls. (Because it would create an {{Aggregate}} that has zero 
fields, and that is problematic elsewhere in Calcite.) But we would also like a 
pattern where an aggregate with an empty group key becomes a constant 
single-row relational expression. So, {{RelBulder.aggregate(groupKey(), 
aggregateCall(TRUE_AGG))}} should generate {{VALUES TRUE}}.


> LITERAL_AGG, an aggregate function that returns a constant value
> ----------------------------------------------------------------
>
>                 Key: CALCITE-4334
>                 URL: https://issues.apache.org/jira/browse/CALCITE-4334
>             Project: Calcite
>          Issue Type: Bug
>            Reporter: Julian Hyde
>            Assignee: Julian Hyde
>            Priority: Major
>
> It would be useful to have an aggregate function that returns a constant 
> value, regardless of how many rows are in the group. We propose 
> {{LITERAL_AGG}}, an internal aggregate function. As an aggregate function it 
> has no arguments (meaning that it does not read any columns from the input), 
> but a call will have a RexLiteral (constant expression).
> This aggregate function is internal, so there is no SQL syntax. But if I were 
> to write
> {code}
> SELECT deptno, SUM(sal), true
> FROM Emp
> GROUP BY deptno
> {code}
> I should get the following plan:
> {code}
> Aggregate(group={deptno}, aggCalls=SUM($4), LITERAL_AGG(true))
>   Scan(Emp)
> {code}
> Today, the plan would require an extra {{Project}} to add 
> {{RexLiteral(true)}}. Planner rules have to look for a {{Project}} of a 
> literal on top of an {{Aggregate}}; by removing the {{Project}} we simplify 
> planning.
> For example, when rewriting sub-queries (see {{SubQueryRemoveRule}}) we 
> introduce add "true as indicator" to the SELECT clause of sub-queries. It can 
> be used to detect rows generated by an outer join. If it is an aggregate 
> query, we would have to write "min(true) as indicator", which necessitates an 
> extra {{Project}} below the {{Aggregate}} to provide the  "true" value. The 
> LITERAL_AGG aggregate function allows us to avoid the extra {{Project}}.
> Another example came up during CALCITE-4317. We would like to make 
> {{RelBuilder.aggregate(groupKey())}} throw when given an empty group key and 
> no aggregate calls. (Because it would create an {{Aggregate}} that has zero 
> fields, and that is problematic elsewhere in Calcite.) But we would also like 
> a pattern where an aggregate with an empty group key becomes a constant 
> single-row relational expression. So, {{RelBulder.aggregate(groupKey(), 
> aggregateCall(LITERAL_AGG(true)))}} should generate {{VALUES TRUE}}.
> {{LITERAL_AGG}} uses {{interface SqlStaticAggFunction}}, an interface that 
> can optionally be implemented (or wrapped, via 
> {{SqlAggFunction.unwrap(Class)}}), to make the planner and code-generator 
> aware of its properties.
> The implementation adds a {{List<RexNode> rexList}} field to 
> {{AggregateCall}}. This field is empty in all conventional aggregate 
> functions, and has one element in {{LITERAL_AGG}}.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to