mirror of
https://github.com/postgres/postgres.git
synced 2025-06-16 06:01:02 +03:00
Throw error if a <window definition> references a window that already has a
frame clause, as appears to be required by the fine print in the SQL spec. Per discussion with Pavel, not doing so risks user confusion.
This commit is contained in:
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$PostgreSQL: pgsql/doc/src/sgml/ref/select.sgml,v 1.115 2008/12/31 00:08:35 tgl Exp $
|
$PostgreSQL: pgsql/doc/src/sgml/ref/select.sgml,v 1.116 2008/12/31 23:42:56 tgl Exp $
|
||||||
PostgreSQL documentation
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -583,7 +583,7 @@ WINDOW <replaceable class="parameter">window_name</replaceable> AS ( <replaceabl
|
|||||||
[ <replaceable class="parameter">existing_window_name</replaceable> ]
|
[ <replaceable class="parameter">existing_window_name</replaceable> ]
|
||||||
[ PARTITION BY <replaceable class="parameter">expression</replaceable> [, ...] ]
|
[ PARTITION BY <replaceable class="parameter">expression</replaceable> [, ...] ]
|
||||||
[ ORDER BY <replaceable class="parameter">expression</replaceable> [ ASC | DESC | USING <replaceable class="parameter">operator</replaceable> ] [ NULLS { FIRST | LAST } ] [, ...] ]
|
[ ORDER BY <replaceable class="parameter">expression</replaceable> [ ASC | DESC | USING <replaceable class="parameter">operator</replaceable> ] [ NULLS { FIRST | LAST } ] [, ...] ]
|
||||||
[ <replaceable class="parameter">framing_clause</replaceable> ]
|
[ <replaceable class="parameter">frame_clause</replaceable> ]
|
||||||
</synopsis>
|
</synopsis>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
@ -594,7 +594,8 @@ WINDOW <replaceable class="parameter">window_name</replaceable> AS ( <replaceabl
|
|||||||
as well as its ordering clause if any. In this case the new window cannot
|
as well as its ordering clause if any. In this case the new window cannot
|
||||||
specify its own <literal>PARTITION BY</> clause, and it can specify
|
specify its own <literal>PARTITION BY</> clause, and it can specify
|
||||||
<literal>ORDER BY</> only if the copied window does not have one.
|
<literal>ORDER BY</> only if the copied window does not have one.
|
||||||
The framing clause is never copied from the existing window.
|
The new window always uses its own frame clause; the copied window
|
||||||
|
must not specify a frame clause.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@ -611,7 +612,7 @@ WINDOW <replaceable class="parameter">window_name</replaceable> AS ( <replaceabl
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The optional <replaceable class="parameter">framing_clause</> defines
|
The optional <replaceable class="parameter">frame_clause</> defines
|
||||||
the <firstterm>window frame</> for window functions that depend on the
|
the <firstterm>window frame</> for window functions that depend on the
|
||||||
frame (not all do). It can be one of
|
frame (not all do). It can be one of
|
||||||
<synopsis>
|
<synopsis>
|
||||||
@ -1486,7 +1487,7 @@ SELECT distributors.* WHERE distributors.name = 'Westward';
|
|||||||
|
|
||||||
<para>
|
<para>
|
||||||
The SQL standard provides additional options for the window
|
The SQL standard provides additional options for the window
|
||||||
<replaceable class="parameter">framing_clause</>.
|
<replaceable class="parameter">frame_clause</>.
|
||||||
<productname>PostgreSQL</productname> currently supports only the
|
<productname>PostgreSQL</productname> currently supports only the
|
||||||
options listed above.
|
options listed above.
|
||||||
</para>
|
</para>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/syntax.sgml,v 1.128 2008/12/31 00:08:35 tgl Exp $ -->
|
<!-- $PostgreSQL: pgsql/doc/src/sgml/syntax.sgml,v 1.129 2008/12/31 23:42:56 tgl Exp $ -->
|
||||||
|
|
||||||
<chapter id="sql-syntax">
|
<chapter id="sql-syntax">
|
||||||
<title>SQL Syntax</title>
|
<title>SQL Syntax</title>
|
||||||
@ -1588,12 +1588,12 @@ sqrt(2)
|
|||||||
where <replaceable class="parameter">window_definition</replaceable>
|
where <replaceable class="parameter">window_definition</replaceable>
|
||||||
has the syntax
|
has the syntax
|
||||||
<synopsis>
|
<synopsis>
|
||||||
[ <replaceable class="parameter">window_name</replaceable> ]
|
[ <replaceable class="parameter">existing_window_name</replaceable> ]
|
||||||
[ PARTITION BY <replaceable class="parameter">expression</replaceable> [, ...] ]
|
[ PARTITION BY <replaceable class="parameter">expression</replaceable> [, ...] ]
|
||||||
[ ORDER BY <replaceable class="parameter">expression</replaceable> [ ASC | DESC | USING <replaceable class="parameter">operator</replaceable> ] [ NULLS { FIRST | LAST } ] [, ...] ]
|
[ ORDER BY <replaceable class="parameter">expression</replaceable> [ ASC | DESC | USING <replaceable class="parameter">operator</replaceable> ] [ NULLS { FIRST | LAST } ] [, ...] ]
|
||||||
[ <replaceable class="parameter">framing_clause</replaceable> ]
|
[ <replaceable class="parameter">frame_clause</replaceable> ]
|
||||||
</synopsis>
|
</synopsis>
|
||||||
and the optional <replaceable class="parameter">framing_clause</replaceable>
|
and the optional <replaceable class="parameter">frame_clause</replaceable>
|
||||||
can be one of
|
can be one of
|
||||||
<synopsis>
|
<synopsis>
|
||||||
RANGE UNBOUNDED PRECEDING
|
RANGE UNBOUNDED PRECEDING
|
||||||
@ -1614,7 +1614,8 @@ ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
|
|||||||
Named window specifications are usually referenced with just
|
Named window specifications are usually referenced with just
|
||||||
<literal>OVER</> <replaceable>window_name</replaceable>, but it is
|
<literal>OVER</> <replaceable>window_name</replaceable>, but it is
|
||||||
also possible to write a window name inside the parentheses and then
|
also possible to write a window name inside the parentheses and then
|
||||||
optionally override its ordering clause and/or framing clause.
|
optionally supply an ordering clause and/or frame clause (the referenced
|
||||||
|
window must lack these clauses, if they are supplied here).
|
||||||
This latter syntax follows the same rules as modifying an existing
|
This latter syntax follows the same rules as modifying an existing
|
||||||
window name within the <literal>WINDOW</literal> clause; see the
|
window name within the <literal>WINDOW</literal> clause; see the
|
||||||
<xref linkend="sql-select" endterm="sql-select-title"> reference
|
<xref linkend="sql-select" endterm="sql-select-title"> reference
|
||||||
@ -1622,6 +1623,9 @@ ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
|
The <replaceable class="parameter">frame_clause</replaceable> specifies
|
||||||
|
the set of rows constituting the <firstterm>window frame</>, for those
|
||||||
|
window functions that act on the frame instead of the whole partition.
|
||||||
The default framing option is <literal>RANGE UNBOUNDED PRECEDING</>,
|
The default framing option is <literal>RANGE UNBOUNDED PRECEDING</>,
|
||||||
which is the same as <literal>RANGE BETWEEN UNBOUNDED PRECEDING AND
|
which is the same as <literal>RANGE BETWEEN UNBOUNDED PRECEDING AND
|
||||||
CURRENT ROW</>; it selects rows up through the current row's last
|
CURRENT ROW</>; it selects rows up through the current row's last
|
||||||
@ -1639,8 +1643,9 @@ ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
|
|||||||
|
|
||||||
<para>
|
<para>
|
||||||
The built-in window functions are described in <xref
|
The built-in window functions are described in <xref
|
||||||
linkend="functions-window-table">. Also, any built-in or
|
linkend="functions-window-table">. Other window functions can be added by
|
||||||
user-defined aggregate function can be used as a window function.
|
the user. Also, any built-in or user-defined aggregate function can be
|
||||||
|
used as a window function.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.183 2008/12/31 00:08:37 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.184 2008/12/31 23:42:56 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1554,7 +1554,10 @@ transformWindowDefinitions(ParseState *pstate,
|
|||||||
* Per spec, a windowdef that references a previous one copies the
|
* Per spec, a windowdef that references a previous one copies the
|
||||||
* previous partition clause (and mustn't specify its own). It can
|
* previous partition clause (and mustn't specify its own). It can
|
||||||
* specify its own ordering clause. but only if the previous one
|
* specify its own ordering clause. but only if the previous one
|
||||||
* had none. It always specifies its own framing clause.
|
* had none. It always specifies its own frame clause, and the
|
||||||
|
* previous one must not have a frame clause. (Yeah, it's bizarre
|
||||||
|
* that each of these cases works differently, but SQL:2008 says so;
|
||||||
|
* see 7.11 <window clause> syntax rule 10 and general rule 1.)
|
||||||
*/
|
*/
|
||||||
if (refwc)
|
if (refwc)
|
||||||
{
|
{
|
||||||
@ -1592,6 +1595,12 @@ transformWindowDefinitions(ParseState *pstate,
|
|||||||
wc->orderClause = orderClause;
|
wc->orderClause = orderClause;
|
||||||
wc->copiedOrder = false;
|
wc->copiedOrder = false;
|
||||||
}
|
}
|
||||||
|
if (refwc && refwc->frameOptions != FRAMEOPTION_DEFAULTS)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_WINDOWING_ERROR),
|
||||||
|
errmsg("cannot override frame clause of window \"%s\"",
|
||||||
|
windef->refname),
|
||||||
|
parser_errposition(pstate, windef->location)));
|
||||||
wc->frameOptions = windef->frameOptions;
|
wc->frameOptions = windef->frameOptions;
|
||||||
wc->winref = winref;
|
wc->winref = winref;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user