[ https://issues.apache.org/jira/browse/CALCITE-4334?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17726266#comment-17726266 ]
Ruben Q L commented on CALCITE-4334: ------------------------------------ I agree with [~libenchao] on the benefits of this change. Just one general question: I can see that the {{LITERAL_AGG}} is ultimately supported by the new {{AggregateCall#rexList}}, i.e. a {{List<RexNode>}} which is documented as "List of pre-arguments". Naively I'd say that just a single {{RexLiteral}} would suffice to implement {{LITERAL_AGG}}, so the decision to have the more flexible and powerful {{List<RexNode>}} is because in the future we intend to use {{AggregateCall#rexList}} for more purposes, and {{LITERAL_AGG}} is just the first use case of it? > 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)