[
https://issues.apache.org/jira/browse/CALCITE-4334?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17726294#comment-17726294
]
Julian Hyde commented on CALCITE-4334:
--------------------------------------
{{rexList}} seems like an abstraction that will find use in future.
For example, when you call {{PERCENTILE(0.5) WITHIN GROUP (sal)}} to find the
median, it's more natural for the 0.5 to be provided at the start of the query
(or start of the group) rather than per-row.
> 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
> Labels: pull-request-available
>
> 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)