mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-21 08:29:39 +08:00
Allow mixing of traditional and SQL:2008 LIMIT/OFFSET syntax. Being rigid
about it doesn't simplify the grammar at all, and it does invite confusion among those who only read the SELECT syntax summary and not the full details. Per gripe from Jaime Casanova.
This commit is contained in:
parent
514c3f19a2
commit
be4cd18f71
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$PostgreSQL: pgsql/doc/src/sgml/ref/select.sgml,v 1.122 2009/05/03 20:45:43 tgl Exp $
|
$PostgreSQL: pgsql/doc/src/sgml/ref/select.sgml,v 1.123 2009/08/18 23:40:20 tgl Exp $
|
||||||
PostgreSQL documentation
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -1005,14 +1005,15 @@ OFFSET <replaceable class="parameter">start</replaceable>
|
|||||||
|
|
||||||
<para>
|
<para>
|
||||||
SQL:2008 introduced a different syntax to achieve the same thing,
|
SQL:2008 introduced a different syntax to achieve the same thing,
|
||||||
which PostgreSQL also supports. It is:
|
which <productname>PostgreSQL</> also supports. It is:
|
||||||
<synopsis>
|
<synopsis>
|
||||||
OFFSET <replaceable class="parameter">start</replaceable> { ROW | ROWS }
|
OFFSET <replaceable class="parameter">start</replaceable> { ROW | ROWS }
|
||||||
FETCH { FIRST | NEXT } [ <replaceable class="parameter">count</replaceable> ] { ROW | ROWS } ONLY
|
FETCH { FIRST | NEXT } [ <replaceable class="parameter">count</replaceable> ] { ROW | ROWS } ONLY
|
||||||
</synopsis>
|
</synopsis>
|
||||||
Both clauses are optional, but if present
|
According to the standard, the <literal>OFFSET</literal> clause must come
|
||||||
the <literal>OFFSET</literal> clause must come before
|
before the <literal>FETCH</literal> clause if both are present; but
|
||||||
the <literal>FETCH</literal> clause. <literal>ROW</literal>
|
<productname>PostgreSQL</> is laxer and allows either order.
|
||||||
|
<literal>ROW</literal>
|
||||||
and <literal>ROWS</literal> as well as <literal>FIRST</literal>
|
and <literal>ROWS</literal> as well as <literal>FIRST</literal>
|
||||||
and <literal>NEXT</literal> are noise words that don't influence
|
and <literal>NEXT</literal> are noise words that don't influence
|
||||||
the effects of these clauses. In this syntax, when using expressions
|
the effects of these clauses. In this syntax, when using expressions
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.676 2009/08/02 22:14:52 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.677 2009/08/18 23:40:20 tgl Exp $
|
||||||
*
|
*
|
||||||
* HISTORY
|
* HISTORY
|
||||||
* AUTHOR DATE MAJOR EVENT
|
* AUTHOR DATE MAJOR EVENT
|
||||||
@ -331,7 +331,8 @@ static TypeName *TableFuncTypeName(List *columns);
|
|||||||
%type <ival> opt_column event cursor_options opt_hold opt_set_data
|
%type <ival> opt_column event cursor_options opt_hold opt_set_data
|
||||||
%type <objtype> reindex_type drop_type comment_type
|
%type <objtype> reindex_type drop_type comment_type
|
||||||
|
|
||||||
%type <node> fetch_direction select_limit_value select_offset_value
|
%type <node> fetch_direction limit_clause select_limit_value
|
||||||
|
offset_clause select_offset_value
|
||||||
select_offset_value2 opt_select_fetch_first_value
|
select_offset_value2 opt_select_fetch_first_value
|
||||||
%type <ival> row_or_rows first_or_next
|
%type <ival> row_or_rows first_or_next
|
||||||
|
|
||||||
@ -7228,14 +7229,20 @@ sortby: a_expr USING qual_all_Op opt_nulls_order
|
|||||||
|
|
||||||
|
|
||||||
select_limit:
|
select_limit:
|
||||||
LIMIT select_limit_value OFFSET select_offset_value
|
limit_clause offset_clause { $$ = list_make2($2, $1); }
|
||||||
{ $$ = list_make2($4, $2); }
|
| offset_clause limit_clause { $$ = list_make2($1, $2); }
|
||||||
| OFFSET select_offset_value LIMIT select_limit_value
|
| limit_clause { $$ = list_make2(NULL, $1); }
|
||||||
{ $$ = list_make2($2, $4); }
|
| offset_clause { $$ = list_make2($1, NULL); }
|
||||||
| LIMIT select_limit_value
|
;
|
||||||
{ $$ = list_make2(NULL, $2); }
|
|
||||||
| OFFSET select_offset_value
|
opt_select_limit:
|
||||||
{ $$ = list_make2($2, NULL); }
|
select_limit { $$ = $1; }
|
||||||
|
| /* EMPTY */ { $$ = list_make2(NULL,NULL); }
|
||||||
|
;
|
||||||
|
|
||||||
|
limit_clause:
|
||||||
|
LIMIT select_limit_value
|
||||||
|
{ $$ = $2; }
|
||||||
| LIMIT select_limit_value ',' select_offset_value
|
| LIMIT select_limit_value ',' select_offset_value
|
||||||
{
|
{
|
||||||
/* Disabled because it was too confusing, bjm 2002-02-18 */
|
/* Disabled because it was too confusing, bjm 2002-02-18 */
|
||||||
@ -7245,19 +7252,17 @@ select_limit:
|
|||||||
errhint("Use separate LIMIT and OFFSET clauses."),
|
errhint("Use separate LIMIT and OFFSET clauses."),
|
||||||
parser_errposition(@1)));
|
parser_errposition(@1)));
|
||||||
}
|
}
|
||||||
/* SQL:2008 syntax variants */
|
/* SQL:2008 syntax */
|
||||||
| OFFSET select_offset_value2 row_or_rows
|
|
||||||
{ $$ = list_make2($2, NULL); }
|
|
||||||
| FETCH first_or_next opt_select_fetch_first_value row_or_rows ONLY
|
| FETCH first_or_next opt_select_fetch_first_value row_or_rows ONLY
|
||||||
{ $$ = list_make2(NULL, $3); }
|
{ $$ = $3; }
|
||||||
| OFFSET select_offset_value2 row_or_rows FETCH first_or_next opt_select_fetch_first_value row_or_rows ONLY
|
|
||||||
{ $$ = list_make2($2, $6); }
|
|
||||||
;
|
;
|
||||||
|
|
||||||
opt_select_limit:
|
offset_clause:
|
||||||
select_limit { $$ = $1; }
|
OFFSET select_offset_value
|
||||||
| /* EMPTY */
|
{ $$ = $2; }
|
||||||
{ $$ = list_make2(NULL,NULL); }
|
/* SQL:2008 syntax */
|
||||||
|
| OFFSET select_offset_value2 row_or_rows
|
||||||
|
{ $$ = $2; }
|
||||||
;
|
;
|
||||||
|
|
||||||
select_limit_value:
|
select_limit_value:
|
||||||
@ -7269,19 +7274,20 @@ select_limit_value:
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
select_offset_value:
|
||||||
|
a_expr { $$ = $1; }
|
||||||
|
;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allowing full expressions without parentheses causes various parsing
|
* Allowing full expressions without parentheses causes various parsing
|
||||||
* problems with the trailing ROW/ROWS key words. SQL only calls for
|
* problems with the trailing ROW/ROWS key words. SQL only calls for
|
||||||
* constants, so we allow the rest only with parentheses.
|
* constants, so we allow the rest only with parentheses. If omitted,
|
||||||
|
* default to 1.
|
||||||
*/
|
*/
|
||||||
opt_select_fetch_first_value:
|
opt_select_fetch_first_value:
|
||||||
SignedIconst { $$ = makeIntConst($1, @1); }
|
SignedIconst { $$ = makeIntConst($1, @1); }
|
||||||
| '(' a_expr ')' { $$ = $2; }
|
| '(' a_expr ')' { $$ = $2; }
|
||||||
| /*EMPTY*/ { $$ = makeIntConst(1, -1); }
|
| /*EMPTY*/ { $$ = makeIntConst(1, -1); }
|
||||||
;
|
|
||||||
|
|
||||||
select_offset_value:
|
|
||||||
a_expr { $$ = $1; }
|
|
||||||
;
|
;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -7293,16 +7299,14 @@ select_offset_value2:
|
|||||||
;
|
;
|
||||||
|
|
||||||
/* noise words */
|
/* noise words */
|
||||||
row_or_rows:
|
row_or_rows: ROW { $$ = 0; }
|
||||||
ROW { $$ = 0; }
|
| ROWS { $$ = 0; }
|
||||||
| ROWS { $$ = 0; }
|
;
|
||||||
;
|
|
||||||
|
first_or_next: FIRST_P { $$ = 0; }
|
||||||
|
| NEXT { $$ = 0; }
|
||||||
|
;
|
||||||
|
|
||||||
/* noise words */
|
|
||||||
first_or_next:
|
|
||||||
FIRST_P { $$ = 0; }
|
|
||||||
| NEXT { $$ = 0; }
|
|
||||||
;
|
|
||||||
|
|
||||||
group_clause:
|
group_clause:
|
||||||
GROUP_P BY expr_list { $$ = $3; }
|
GROUP_P BY expr_list { $$ = $3; }
|
||||||
|
Loading…
Reference in New Issue
Block a user