Skip to content

Commit

Permalink
Aggregate functions: brand-new content (#5993)
Browse files Browse the repository at this point in the history
Fixed txn_set.md

Removed immutable throughout JSON, Arrays, Window functions, and Aggregate functions. Typos corrected.

removed SET TABLESPACE to mimic Dorian's PR #5998

re-ran diagram generator for removed SET TABLESPACE
  • Loading branch information
bllewell committed Oct 15, 2020
1 parent e75eef6 commit 9baf00d
Show file tree
Hide file tree
Showing 74 changed files with 4,953 additions and 303 deletions.
56 changes: 49 additions & 7 deletions docs/content/latest/api/ysql/commands/dml_select.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,27 +38,69 @@ The same syntax rules govern a subquery, wherever you might use one—like, for

<div class="tab-content">
<div id="grammar" class="tab-pane fade show active" role="tabpanel" aria-labelledby="grammar-tab">
{{% includeMarkdown "../syntax_resources/commands/select,fn_over_window,order_expr.grammar.md" /%}}
{{% includeMarkdown "../syntax_resources/commands/select,fn_over_window,ordinary_aggregate_fn_invocation,within_group_aggregate_fn_invocation,grouping_element,order_expr.grammar.md" /%}}
</div>
<div id="diagram" class="tab-pane fade" role="tabpanel" aria-labelledby="diagram-tab">
{{% includeMarkdown "../syntax_resources/commands/select,fn_over_window,order_expr.diagram.md" /%}}
{{% includeMarkdown "../syntax_resources/commands/select,fn_over_window,ordinary_aggregate_fn_invocation,within_group_aggregate_fn_invocation,grouping_element,order_expr.diagram.md" /%}}
</div>
</div>

**Note:** The **fn_over_window** rule denotes the special kind of `SELECT` list item that must be used to invoke a window function and that may be used to invoke an aggregate function. (Window functions are known as analytic functions in the terminology of some database systems.) The dedicated diagram that follows the main diagram for the **select** rule shows the `FILTER` and the `OVER` keywords. You can see that you _cannot_ invoke a function in this way without specifying an `OVER` clause—and that the `OVER` clause requires the specification of the so-called [_window_](../../exprs/window_functions/sql-syntax-semantics/#the-window-definition-rule) that gives this invocation style its name. The `FILTER` clause is optional and may be used _only_ when you invoke an aggregate function in this way. All of this is explained in the major section [Window functions](../../exprs/window_functions/).

## Semantics

- An error is raised if the specified `table_name` does not exist.
- `*` represents all columns.

While the where clause allows a wide range of operators, the exact conditions used in the where clause have significant performance considerations (especially for large datasets).

### *condition*
For details on `from_item` and `with_query` see [SELECT](https://www.postgresql.org/docs/10/static/sql-select.html) in the PostgreSQL documentation.

The `fn_over_window` rule denotes the special kind of `SELECT` list item that must be used to invoke a window function and that may be used to invoke an aggregate function. (Window functions are known as analytic functions in the terminology of some SQL database systems.) The dedicated diagram that follows the main diagram for the `select` rule shows the `FILTER` and the `OVER` keywords. You can see that you _cannot_ invoke a function in this way without specifying an `OVER` clause—and that the `OVER` clause requires the specification of the so-called [_window_](../../exprs/window_functions/invocation-syntax-semantics/#the-window-definition-rule) that gives this invocation style its name. The `FILTER` clause is optional and may be used _only_ when you invoke an aggregate function in this way. All of this is explained in the [Window function invocation—SQL syntax and semantics](../../exprs/window_functions/invocation-syntax-semantics/) section within the major section [Window functions](../../exprs/window_functions/).

The `ordinary_aggregate_fn_invocation` rule and the `within_group_aggregate_fn_invocation` rule denote the special kinds of `SELECT` list item that are used to invoke an aggregate function (when it isn't invoked as a window function). When an aggregate function is invoked in either of these two ways, it's very common to do so in conjunction with the `GROUP BY` and `HAVING` clauses. All of this is explained in the [Aggregate function invocation—SQL syntax and semantics](../../exprs/aggregate_functions/invocation-syntax-semantics/) section within the major section [Aggregate functions](../../exprs/aggregate_functions/).

When you understand the story of the invocation of these two kinds of functions from the accounts in the [Window functions](../../exprs/window_functions/) section and the [Aggregate functions](../../exprs/aggregate_functions/) section, you can use the `\df` metacommand in `ysqlsh` to discover the status of a particular function, thus:

```
\df row_number
... | Argument data types | Type
... +----------------------------------------+--------
... | | window
\df rank
... | Argument data types | Type
... +----------------------------------------+--------
... | | window
... | VARIADIC "any" ORDER BY VARIADIC "any" | agg
\df avg
... | Argument data types | Type
... +----------------------------------------+--------
... | bigint | agg
... | <other data types> | agg
```

- A function whose type is listed as _"window"_ can be invoked _only_ as a window function. See this account of [`row_number()`](../../exprs/window_functions/function-syntax-semantics/row-number-rank-dense-rank/#row-number).

- A function whose type is listed _both_ as _"window"_ and as _agg_ can be invoked:

- _either_ as a window function using the `fn_over_window` syntax—see this account of [`rank()`](../../exprs/window_functions/function-syntax-semantics/row-number-rank-dense-rank/#rank)

- _or_ as a so-called [within-group hypothetical-set aggregate function](../../exprs/aggregate_functions/function-syntax-semantics/#within-group-hypothetical-set-aggregate-functions) using the `within_group_aggregate_fn_invocation` syntax—see this account of [`rank()`](../../exprs/aggregate_functions/function-syntax-semantics/rank-dense-rank-percent-rank-cume-dist/#rank).

- A function whose type is listed only as _"agg"_ can, in fact, be invoked _either_ as an aggregate function using the `ordinary_aggregate_fn_invocation` syntax _or_ as a window function using the `fn_over_window` syntax. The `avg()` function is described in the "Aggregate functions" major section section in the subsection [`avg()`, `count()`, `max()`, `min()`, `sum()`](../../exprs/aggregate_functions/function-syntax-semantics/avg-count-max-min-sum/). See its subsections [`GROUP BY` syntax](../../exprs/aggregate_functions/function-syntax-semantics/avg-count-max-min-sum/#group-by-syntax) and [`OVER` syntax](../../exprs/aggregate_functions/function-syntax-semantics/avg-count-max-min-sum/#over-syntax) for, respectively, the `ordinary_aggregate_fn_invocation` and the `fn_over_window` invocation alternatives.

- Notice that the three functions [`mode()`](../../exprs/aggregate_functions/function-syntax-semantics/mode-percentile-disc-percentile-cont/#mode), [`percentile_disc()`](../../exprs/aggregate_functions/function-syntax-semantics/mode-percentile-disc-percentile-cont/#percentile-disc-percentile-cont), and [`percentile_cont()`](../../exprs/aggregate_functions/function-syntax-semantics/mode-percentile-disc-percentile-cont/#percentile-disc-percentile-cont) are exceptions to this general rule (and they are the _only_ exceptions). These functions are referred to as [within-group ordered-set aggregate functions](../../exprs/aggregate_functions/function-syntax-semantics/#within-group-ordered-set-aggregate-functions). `\df` lists the type of these functions only as _"agg"_. But these _cannot_ be invoked as window functions. The attempt causes this error:

Specify an expression that evaluates to a Boolean value.
```
42809: WITHIN GROUP is required for ordered-set aggregate mode
```

For details on `from_item`, `grouping_element`, and `with_query` see [SELECT](https://www.postgresql.org/docs/10/static/sql-select.html) in the PostgreSQL documentation.
**Note:** The documentation in the [Aggregate functions](../../exprs/aggregate_functions/) major section usually refers to the syntax that the `ordinary_aggregate_fn_invocation` rule and the `within_group_aggregate_fn_invocation` rule jointly govern as the [`GROUP BY` syntax](../../exprs/aggregate_functions/function-syntax-semantics/avg-count-max-min-sum/#group-by-syntax) because it's these two syntax variants (and _only_ these two) can be used together with the `GROUP BY` clause (and therefore the `HAVING` clause). And it usually refers to the syntax that the `fn_over_window` rule governs as the [`OVER` syntax](../../exprs/aggregate_functions/function-syntax-semantics/avg-count-max-min-sum/#over-syntax) because this syntax variant _requires_ the use of the `OVER` clause. Moreover, the use of the `GROUP BY` clause (and therefore the `HAVING` clause) is illegal with this syntax variant.

## Examples

Expand Down
4 changes: 2 additions & 2 deletions docs/content/latest/api/ysql/commands/txn_set.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ Use the `SET TRANSACTION` statement to set the current transaction isolation lev

<div class="tab-content">
<div id="grammar" class="tab-pane fade show active" role="tabpanel" aria-labelledby="grammar-tab">
{{% includeMarkdown "../syntax_resources/commands/set_transaction.grammar.md" /%}}
{{% includeMarkdown "../syntax_resources/commands/set_transaction,transaction_mode,isolation_level,read_write_mode,deferrable_mode.grammar.md" /%}}
</div>
<div id="diagram" class="tab-pane fade" role="tabpanel" aria-labelledby="diagram-tab">
{{% includeMarkdown "../syntax_resources/commands/set_transaction.diagram.md" /%}}
{{% includeMarkdown "../syntax_resources/commands/set_transaction,transaction_mode,isolation_level,read_write_mode,deferrable_mode.diagram.md" /%}}
</div>
</div>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,6 @@ Typecasting cannot come to the rescue here. But this function produces the requi
\set VERBOSITY default
create or replace function array_agg_v()
returns arrays_t
immutable
language plpgsql
as $body$
<<b>>declare
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ values
Next, create a view that encodes the fully projected, unrestricted _inner join_ of the original data, and inspect the result set that it represents:

```plpgsql
create view original_data as
create or replace view original_data as
select
master_pk,
m.master_name,
Expand Down Expand Up @@ -474,7 +474,6 @@ Here's a helper function to show the primitive values that the _"details&#95;t[]
```plpgsql
create function pretty_details(arr in details_t[])
returns text
immutable
language plpgsql
as $body$
declare
Expand Down Expand Up @@ -524,7 +523,7 @@ It produces this result:
Next, create a view that uses `unnest()` to re-create the effect of the fully projected, unrestricted _inner join_ of the original data, and inspect the result set that it represents:

```plpgsql
create view new_data as
create or replace view new_data as
with v as (
select
master_pk,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ These functions require that the to-be-searched array is one-dimensional. They r

Create _"view v"_ now. The examples below use it.
```plpgsql
create view v as
create or replace view v as
select array[
'sun', -- 1
'mon', -- 2
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,9 @@ You can work out the rules for a multidimensional array of _"row"_ type values,

This pseudocode shows how to create an array literal of _"row"_ type values that have the same shape as _"type rt"_ in the example above. The input is a succession of an arbitrary number of _"(n, s, t, b)"_ tuples. The text below was derived by straightforward manual massage from actual working, and tested, Python code. The code was written as an exercise to verify the correctness of the algorithm.

The pseudocode does retain Python locutions, but don't be distracted by this. The meaning is clear enough to allow the algorithm r=to be described. The various special characters were all set up as manifest constants with self-describing names.
The pseudocode does retain Python locutions, but don't be distracted by this. The meaning is clear enough to allow the algorithm to be described. The various special characters were all set up as manifest constants with self-describing names.
Notice that the algorithm inserts a newline after the opening curly brace, between the pairs of representations of each _"row"_ type value, and before the closing curly brace. While, strictly speaking, this means that the literal it produces is not in canonical form, this has no effect (as has been shown many times by example throughout this _"Array data types and functionality"_ major section.
Notice that the algorithm inserts a newline after the opening curly brace, between the pairs of representations of each _"row"_ type value, and before the closing curly brace. While, strictly speaking, this means that the literal it produces is not in canonical form, this has no effect (as has been shown many times by example throughout this _"Array data types and functionality"_ major section).
```
"Start a new array literal":
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,6 @@ Recall that the iterator for `SLICE 0` is a scalar and that the iterators for ot
-- First overload
create function array_slices(arr in anyarray)
returns table(ret anyelement)
immutable
language plpgsql
as $body$
declare
Expand All @@ -416,7 +415,6 @@ And:
-- Second overload
create function array_slices(arr in anyarray, slice_operand in int)
returns table(ret anyarray)
immutable
language plpgsql
as $body$
declare
Expand Down Expand Up @@ -584,7 +582,6 @@ Here is a function to generate a four-dimensional array. Notice that the actual
```plpgsql
create function four_d_array(lengths in int[])
returns text[]
immutable
language plpgsql
as $body$
declare
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@ The high-level point is that YSQL allows you to express a constraint using any e
```plpgsql
create function top_level_keys_ok(json_obj in jsonb)
returns boolean
immutable
language plpgsql
as
$body$
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ The following `ysqlsh` script shows a feasible general workaround for this use c

```plpgsql
create function f(variadic_array_elements in text) returns jsonb
immutable
language plpgsql
as $body$
declare
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ The following `ysqlsh` script shows a feasible general workaround for this use c

```plpgsql
create function f(variadic_array_elements in text) returns jsonb
immutable
language plpgsql
as $body$
declare
Expand Down
3 changes: 2 additions & 1 deletion docs/content/latest/api/ysql/exprs/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ YSQL supports all PostgreSQL-compatible built-in functions and operators. The fo
| [`nextval`](func_nextval) | Returns the next value from the session's sequence cache |
| [`JSON functions and operators`](../datatypes/type_json/functions-operators/) | Detailed list of JSON-specific functions and operators |
| [`Array functions and operators`](../datatypes/type_array/functions-operators/) | Detailed list of array-specific functions and operators |
| [`Window functions`](./window_functions/) | Detailed list of SQL window functions |
| [`Aggregate functions`](./aggregate_functions/) | Detailed list of YSQL aggregate functions |
| [`Window functions`](./window_functions/) | Detailed list of YSQL window functions |
Loading

0 comments on commit 9baf00d

Please sign in to comment.