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

Julian Hyde updated CALCITE-5692:
---------------------------------
    Description: 
In CALCITE-4496 we added measures, and the ability to evaluate a measure in a 
context determined by the GROUP BY clause. In this change, we add the ability 
to change that context using the AT operator.

When used as a clause of an aggregate function call, {{AT}} is similar to 
{{{}FILTER{}}}. For example, in the query
{code:java}
SELECT deptno,
  AVG(sal) FILTER (WHERE job <> 'MANAGER') AS a1,
  AVG(sal) AT (VISIBLE WHERE job <> 'MANAGER') AS a2,
  AVG(sal) AT (WHERE job <> 'MANAGER') AS a3
FROM emp
WHERE sal > 1000
GROUP BY deptno;
{code}
{{a1}} and {{a2}} always return the same value - the average salary of 
non-managers who earn more than $1000. But {{a3}} (similar to {{a2}} but 
missing the {{VISIBLE}} keyword) computes the average of all non-managers (not 
just those earning more than $1000).
h2. Syntax

Sub-clauses of {{{}AT{}}}:
 * {{VISIBLE}} adds a filter equivalent to the {{WHERE}} clause (has no effect 
when used in the {{WHERE}} or {{ON}} clauses);
 * {{WHERE}} adds the given predicate as a filter;
 * {{CLEAR GROUP}} clears the predicate of the current group, if any (e.g. 
"deptno = 10 AND job = 'ANALYST'" if we are in the SELECT clause of a query 
with "GROUP BY deptno, job" evaluating the row (10, 'ANALYST');
 * {{CLEAR WHERE}} clears the predicate of the {{WHERE}} clause (has no effect 
when used in the {{WHERE}} or {{ON}} clauses);
 * {{SET dimension = expression}} clears the predicate on {{dimension}} (if 
any) and adds a filter "dimension = expression".

{{AT}} can be applied to any expression (not just aggregate functions like 
{{{}FILTER{}}}). For example,
 * {{avg_sal AT (CLEAR deptno)}} // applied to a measure
 * {{(COUNT(comm) + 4) AT (CLEAR deptno)}} // applied to an aggregateable 
expression

If the expression's syntax is not a function call or an identifier, you need to 
use parentheses.
h2. Implementation

First, push down expressions, so that the left side of {{AT}} is always a 
measure, and the right side is always in terms of (dimension) columns. For 
example, given the query
{code:java}
SELECT deptno, (1 + AVG(sal * sal)) AT (SET YEAR(hiredate) = 1981)
FROM Emp
GROUP BY deptno {code}
 we transform to the following, with a {{e2}} containing the pushed down 
expressions:
{code:java}
WITH e2 AS (
  SELECT *, 1 + AVG(sal * sal) AS MEASURE m, YEAR(hiredate) AS y
  FROM Emp)
SELECT deptno, m AT (SET y = 1981)
FROM e2
GROUP BY deptno{code}
If {{AT}} occurs in the definition of a measure, the context is modified. For 
example, in the query
{code:java}
WITH e2 AS (
  SELECT *,
      AVG(sal) AS MEASURE avg_sal,
      avg_sal AT (SET job = 'MANAGER') AS MEASURE avg_mgr_sal
  FROM Emp)
SELECT deptno, job, avg_sal, avg_sal AT (SET job = 'MANAGER'), avg_mgr_sal
FROM e2
GROUP BY deptno, job{code}
the measure {{avg_mgr_sal}} is expanded at the call site as if the user had 
written {{{}avg_sal AT (SET job = 'MANAGER'){}}}. 

  was:
In CALCITE-4496 we added measures, and the ability to evaluate a measure in a 
context determined by the GROUP BY clause. In this change, we add the ability 
to change that context using the AT operator.

When used as a clause of an aggregate function call, {{AT}} is similar to 
{{FILTER}}. For example, in the query
{code}
SELECT deptno,
  AVG(sal) FILTER (WHERE job <> 'MANAGER') AS a1,
  AVG(sal) AT (VISIBLE WHERE job <> 'MANAGER') AS a2,
  AVG(sal) AT (WHERE job <> 'MANAGER') AS a3
FROM emp
WHERE sal > 1000
GROUP BY deptno;
{code}
{{a1}} and {{a2}} always return the same value - the average salary of 
non-managers who earn more than $1000. But {{a3}} (similar to {{a2}} but 
missing the {{VISIBLE}} keyword) computes the average of all non-managers (not 
just those earning more than $1000).

Sub-clauses of {{AT}}:
 * {{VISIBLE}} adds a filter equivalent to the {{WHERE}} clause (has no effect 
when used in the {{WHERE}} or {{ON}} clauses);
 * {{WHERE}} adds the given predicate as a filter;
 * {{CLEAR GROUP}} clears the predicate of the current group, if any (e.g. 
"deptno = 10 AND job = 'ANALYST'" if we are in the SELECT clause of a query 
with "GROUP BY deptno, job" evaluating the row (10, 'ANALYST');
 * {{CLEAR WHERE}} clears the predicate of the {{WHERE}} clause (has no effect 
when used in the {{WHERE}} or {{ON}} clauses);
 * {{SET dimension = expression}} clears the predicate on {{dimension}} (if 
any) and adds a filter "dimension = expression".

{{AT}} can be applied to any expression (not just aggregate functions like 
{{FILTER}}). For example,
 * {{avg_sal AT (CLEAR deptno)}} // applied to a measure
 * {{(COUNT(comm) + 4) AT (CLEAR deptno)}} // applied to an aggregateable 
expression

If the expression's syntax is not a function call or an identifier, you need to 
use parentheses.


> Add AT operator, for context-sensitive expressions
> --------------------------------------------------
>
>                 Key: CALCITE-5692
>                 URL: https://issues.apache.org/jira/browse/CALCITE-5692
>             Project: Calcite
>          Issue Type: Bug
>            Reporter: Julian Hyde
>            Priority: Major
>
> In CALCITE-4496 we added measures, and the ability to evaluate a measure in a 
> context determined by the GROUP BY clause. In this change, we add the ability 
> to change that context using the AT operator.
> When used as a clause of an aggregate function call, {{AT}} is similar to 
> {{{}FILTER{}}}. For example, in the query
> {code:java}
> SELECT deptno,
>   AVG(sal) FILTER (WHERE job <> 'MANAGER') AS a1,
>   AVG(sal) AT (VISIBLE WHERE job <> 'MANAGER') AS a2,
>   AVG(sal) AT (WHERE job <> 'MANAGER') AS a3
> FROM emp
> WHERE sal > 1000
> GROUP BY deptno;
> {code}
> {{a1}} and {{a2}} always return the same value - the average salary of 
> non-managers who earn more than $1000. But {{a3}} (similar to {{a2}} but 
> missing the {{VISIBLE}} keyword) computes the average of all non-managers 
> (not just those earning more than $1000).
> h2. Syntax
> Sub-clauses of {{{}AT{}}}:
>  * {{VISIBLE}} adds a filter equivalent to the {{WHERE}} clause (has no 
> effect when used in the {{WHERE}} or {{ON}} clauses);
>  * {{WHERE}} adds the given predicate as a filter;
>  * {{CLEAR GROUP}} clears the predicate of the current group, if any (e.g. 
> "deptno = 10 AND job = 'ANALYST'" if we are in the SELECT clause of a query 
> with "GROUP BY deptno, job" evaluating the row (10, 'ANALYST');
>  * {{CLEAR WHERE}} clears the predicate of the {{WHERE}} clause (has no 
> effect when used in the {{WHERE}} or {{ON}} clauses);
>  * {{SET dimension = expression}} clears the predicate on {{dimension}} (if 
> any) and adds a filter "dimension = expression".
> {{AT}} can be applied to any expression (not just aggregate functions like 
> {{{}FILTER{}}}). For example,
>  * {{avg_sal AT (CLEAR deptno)}} // applied to a measure
>  * {{(COUNT(comm) + 4) AT (CLEAR deptno)}} // applied to an aggregateable 
> expression
> If the expression's syntax is not a function call or an identifier, you need 
> to use parentheses.
> h2. Implementation
> First, push down expressions, so that the left side of {{AT}} is always a 
> measure, and the right side is always in terms of (dimension) columns. For 
> example, given the query
> {code:java}
> SELECT deptno, (1 + AVG(sal * sal)) AT (SET YEAR(hiredate) = 1981)
> FROM Emp
> GROUP BY deptno {code}
>  we transform to the following, with a {{e2}} containing the pushed down 
> expressions:
> {code:java}
> WITH e2 AS (
>   SELECT *, 1 + AVG(sal * sal) AS MEASURE m, YEAR(hiredate) AS y
>   FROM Emp)
> SELECT deptno, m AT (SET y = 1981)
> FROM e2
> GROUP BY deptno{code}
> If {{AT}} occurs in the definition of a measure, the context is modified. For 
> example, in the query
> {code:java}
> WITH e2 AS (
>   SELECT *,
>       AVG(sal) AS MEASURE avg_sal,
>       avg_sal AT (SET job = 'MANAGER') AS MEASURE avg_mgr_sal
>   FROM Emp)
> SELECT deptno, job, avg_sal, avg_sal AT (SET job = 'MANAGER'), avg_mgr_sal
> FROM e2
> GROUP BY deptno, job{code}
> the measure {{avg_mgr_sal}} is expanded at the call site as if the user had 
> written {{{}avg_sal AT (SET job = 'MANAGER'){}}}. 



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

Reply via email to