[ https://issues.apache.org/jira/browse/CALCITE-4334?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17724529#comment-17724529 ]
Benchao Li commented on CALCITE-4334: ------------------------------------- I understand the intention and benefit of introducing LITERAL_AGG, what I'm thinking is about the limitations it may introduce, some points are below: - Does the new LITERAL_AGG affect the predicate deducing and expression simplifying, e.g. constant folding? - Is the new LITERAL_AGG properly handled in Rel2SqlConverter, since this is an internal aggregate function, we may need to prevent it being translated to other dialects. > 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)