Make the OVER keyword unreserved.

This results in a slightly less specific error message when OVER
is used in a context where we don't accept window functions, but
per discussion, it's worth it to get the benefit of not needing
to reserve this keyword any more.  This same refactoring will
also let us avoid reserving some other keywords that we expect
to add in upcoming patches (specifically, IGNORE, RESPECT, and
FILTER).

Troels Nielsen, with minor changes by me
This commit is contained in:
Robert Haas 2013-06-28 10:18:00 -04:00
parent 5ee73525d5
commit 5893ffa79c
3 changed files with 63 additions and 33 deletions

View File

@ -401,7 +401,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
%type <node> columnDef columnOptions
%type <defelt> def_elem reloption_elem old_aggr_elem
%type <node> def_arg columnElem where_clause where_or_current_clause
a_expr b_expr c_expr func_expr AexprConst indirection_el
a_expr b_expr c_expr AexprConst indirection_el
columnref in_expr having_clause func_table array_expr
ExclusionWhereClause
%type <list> ExclusionConstraintList ExclusionConstraintElem
@ -481,6 +481,8 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
%type <ival> document_or_content
%type <boolean> xml_whitespace_option
%type <node> func_application func_expr_common_subexpr
%type <node> func_expr func_expr_windowless
%type <node> common_table_expr
%type <with> with_clause opt_with_clause
%type <list> cte_list
@ -6132,7 +6134,7 @@ index_elem: ColId opt_collate opt_class opt_asc_desc opt_nulls_order
$$->ordering = $4;
$$->nulls_ordering = $5;
}
| func_expr opt_collate opt_class opt_asc_desc opt_nulls_order
| func_expr_windowless opt_collate opt_class opt_asc_desc opt_nulls_order
{
$$ = makeNode(IndexElem);
$$->name = NULL;
@ -9894,8 +9896,7 @@ relation_expr_opt_alias: relation_expr %prec UMINUS
}
;
func_table: func_expr { $$ = $1; }
func_table: func_expr_windowless { $$ = $1; }
;
@ -11079,15 +11080,7 @@ c_expr: columnref { $$ = $1; }
}
;
/*
* func_expr is split out from c_expr just so that we have a classification
* for "everything that is a function call or looks like one". This isn't
* very important, but it saves us having to document which variants are
* legal in the backwards-compatible functional-index syntax for CREATE INDEX.
* (Note that many of the special SQL functions wouldn't actually make any
* sense as functional index entries, but we ignore that consideration here.)
*/
func_expr: func_name '(' ')' over_clause
func_application: func_name '(' ')'
{
FuncCall *n = makeNode(FuncCall);
n->funcname = $1;
@ -11096,11 +11089,11 @@ func_expr: func_name '(' ')' over_clause
n->agg_star = FALSE;
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = $4;
n->over = NULL;
n->location = @1;
$$ = (Node *)n;
}
| func_name '(' func_arg_list ')' over_clause
| func_name '(' func_arg_list ')'
{
FuncCall *n = makeNode(FuncCall);
n->funcname = $1;
@ -11109,11 +11102,11 @@ func_expr: func_name '(' ')' over_clause
n->agg_star = FALSE;
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = $5;
n->over = NULL;
n->location = @1;
$$ = (Node *)n;
}
| func_name '(' VARIADIC func_arg_expr ')' over_clause
| func_name '(' VARIADIC func_arg_expr ')'
{
FuncCall *n = makeNode(FuncCall);
n->funcname = $1;
@ -11122,11 +11115,11 @@ func_expr: func_name '(' ')' over_clause
n->agg_star = FALSE;
n->agg_distinct = FALSE;
n->func_variadic = TRUE;
n->over = $6;
n->over = NULL;
n->location = @1;
$$ = (Node *)n;
}
| func_name '(' func_arg_list ',' VARIADIC func_arg_expr ')' over_clause
| func_name '(' func_arg_list ',' VARIADIC func_arg_expr ')'
{
FuncCall *n = makeNode(FuncCall);
n->funcname = $1;
@ -11135,11 +11128,11 @@ func_expr: func_name '(' ')' over_clause
n->agg_star = FALSE;
n->agg_distinct = FALSE;
n->func_variadic = TRUE;
n->over = $8;
n->over = NULL;
n->location = @1;
$$ = (Node *)n;
}
| func_name '(' func_arg_list sort_clause ')' over_clause
| func_name '(' func_arg_list sort_clause ')'
{
FuncCall *n = makeNode(FuncCall);
n->funcname = $1;
@ -11148,11 +11141,11 @@ func_expr: func_name '(' ')' over_clause
n->agg_star = FALSE;
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = $6;
n->over = NULL;
n->location = @1;
$$ = (Node *)n;
}
| func_name '(' ALL func_arg_list opt_sort_clause ')' over_clause
| func_name '(' ALL func_arg_list opt_sort_clause ')'
{
FuncCall *n = makeNode(FuncCall);
n->funcname = $1;
@ -11165,11 +11158,11 @@ func_expr: func_name '(' ')' over_clause
* for that in FuncCall at the moment.
*/
n->func_variadic = FALSE;
n->over = $7;
n->over = NULL;
n->location = @1;
$$ = (Node *)n;
}
| func_name '(' DISTINCT func_arg_list opt_sort_clause ')' over_clause
| func_name '(' DISTINCT func_arg_list opt_sort_clause ')'
{
FuncCall *n = makeNode(FuncCall);
n->funcname = $1;
@ -11178,11 +11171,11 @@ func_expr: func_name '(' ')' over_clause
n->agg_star = FALSE;
n->agg_distinct = TRUE;
n->func_variadic = FALSE;
n->over = $7;
n->over = NULL;
n->location = @1;
$$ = (Node *)n;
}
| func_name '(' '*' ')' over_clause
| func_name '(' '*' ')'
{
/*
* We consider AGGREGATE(*) to invoke a parameterless
@ -11201,11 +11194,48 @@ func_expr: func_name '(' ')' over_clause
n->agg_star = TRUE;
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = $5;
n->over = NULL;
n->location = @1;
$$ = (Node *)n;
}
| COLLATION FOR '(' a_expr ')'
;
/*
* func_expr and its cousin func_expr_windowless is split out from c_expr just
* so that we have classifications for "everything that is a function call or
* looks like one". This isn't very important, but it saves us having to document
* which variants are legal in the backwards-compatible functional-index syntax
* for CREATE INDEX.
* (Note that many of the special SQL functions wouldn't actually make any
* sense as functional index entries, but we ignore that consideration here.)
*/
func_expr: func_application over_clause
{
FuncCall *n = (FuncCall*)$1;
n->over = $2;
$$ = (Node*)n;
}
| func_expr_common_subexpr
{ $$ = $1; }
;
/*
* As func_expr but does not accept WINDOW functions directly (they
* can still be contained in arguments for functions etc.)
* Use this when window expressions are not allowed, so to disambiguate
* the grammar. (e.g. in CREATE INDEX)
*/
func_expr_windowless:
func_application { $$ = $1; }
| func_expr_common_subexpr { $$ = $1; }
;
/*
* Special expression
*/
func_expr_common_subexpr:
COLLATION FOR '(' a_expr ')'
{
FuncCall *n = makeNode(FuncCall);
n->funcname = SystemFuncName("pg_collation_for");
@ -12794,6 +12824,7 @@ unreserved_keyword:
| OPERATOR
| OPTION
| OPTIONS
| OVER
| OWNED
| OWNER
| PARSER
@ -12992,7 +13023,6 @@ type_func_name_keyword:
| NATURAL
| NOTNULL
| OUTER_P
| OVER
| OVERLAPS
| RIGHT
| SIMILAR

View File

@ -270,7 +270,7 @@ PG_KEYWORD("or", OR, RESERVED_KEYWORD)
PG_KEYWORD("order", ORDER, RESERVED_KEYWORD)
PG_KEYWORD("out", OUT_P, COL_NAME_KEYWORD)
PG_KEYWORD("outer", OUTER_P, TYPE_FUNC_NAME_KEYWORD)
PG_KEYWORD("over", OVER, TYPE_FUNC_NAME_KEYWORD)
PG_KEYWORD("over", OVER, UNRESERVED_KEYWORD)
PG_KEYWORD("overlaps", OVERLAPS, TYPE_FUNC_NAME_KEYWORD)
PG_KEYWORD("overlay", OVERLAY, COL_NAME_KEYWORD)
PG_KEYWORD("owned", OWNED, UNRESERVED_KEYWORD)

View File

@ -989,9 +989,9 @@ ERROR: window functions are not allowed in GROUP BY
LINE 1: SELECT rank() OVER (ORDER BY 1), count(*) FROM empsalary GRO...
^
SELECT * FROM rank() OVER (ORDER BY random());
ERROR: window functions are not allowed in functions in FROM
ERROR: syntax error at or near "ORDER"
LINE 1: SELECT * FROM rank() OVER (ORDER BY random());
^
^
DELETE FROM empsalary WHERE (rank() OVER (ORDER BY random())) > 10;
ERROR: window functions are not allowed in WHERE
LINE 1: DELETE FROM empsalary WHERE (rank() OVER (ORDER BY random())...