@@ -389,7 +389,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
389
389
OptTableElementList TableElementList OptInherit definition
390
390
OptTypedTableElementList TypedTableElementList
391
391
reloptions opt_reloptions
392
- OptWith distinct_clause opt_definition func_args func_args_list
392
+ OptWith opt_definition func_args func_args_list
393
393
func_args_with_defaults func_args_with_defaults_list
394
394
aggr_args aggr_args_list
395
395
func_as createfunc_opt_list alterfunc_opt_list
@@ -401,6 +401,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
401
401
name_list role_list from_clause from_list opt_array_bounds
402
402
qualified_name_list any_name any_name_list type_name_list
403
403
any_operator expr_list attrs
404
+ distinct_clause opt_distinct_clause
404
405
target_list opt_target_list insert_column_list set_target_list
405
406
set_clause_list set_clause
406
407
def_list operator_def_list indirection opt_indirection
@@ -11260,6 +11261,11 @@ select_clause:
11260
11261
* As with select_no_parens, simple_select cannot have outer parentheses,
11261
11262
* but can have parenthesized subclauses.
11262
11263
*
11264
+ * It might appear that we could fold the first two alternatives into one
11265
+ * by using opt_distinct_clause. However, that causes a shift/reduce conflict
11266
+ * against INSERT ... SELECT ... ON CONFLICT. We avoid the ambiguity by
11267
+ * requiring SELECT DISTINCT [ON] to be followed by a non-empty target_list.
11268
+ *
11263
11269
* Note that sort clauses cannot be included at this level --- SQL requires
11264
11270
* SELECT foo UNION SELECT bar ORDER BY baz
11265
11271
* to be parsed as
@@ -11497,8 +11503,13 @@ opt_all_clause:
11497
11503
| /* EMPTY*/
11498
11504
;
11499
11505
11506
+ opt_distinct_clause :
11507
+ distinct_clause { $$ = $1 ; }
11508
+ | opt_all_clause { $$ = NIL; }
11509
+ ;
11510
+
11500
11511
opt_sort_clause :
11501
- sort_clause { $$ = $1 ;}
11512
+ sort_clause { $$ = $1 ; }
11502
11513
| /* EMPTY*/ { $$ = NIL; }
11503
11514
;
11504
11515
@@ -15065,32 +15076,33 @@ role_list: RoleSpec
15065
15076
* Therefore the returned struct is a SelectStmt.
15066
15077
*****************************************************************************/
15067
15078
15068
- PLpgSQL_Expr: opt_target_list
15079
+ PLpgSQL_Expr: opt_distinct_clause opt_target_list
15069
15080
from_clause where_clause
15070
15081
group_clause having_clause window_clause
15071
15082
opt_sort_clause opt_select_limit opt_for_locking_clause
15072
15083
{
15073
15084
SelectStmt *n = makeNode (SelectStmt);
15074
15085
15075
- n->targetList = $1 ;
15076
- n->fromClause = $2 ;
15077
- n->whereClause = $3 ;
15078
- n->groupClause = $4 ;
15079
- n->havingClause = $5 ;
15080
- n->windowClause = $6 ;
15081
- n->sortClause = $7 ;
15082
- if ($8 )
15086
+ n->distinctClause = $1 ;
15087
+ n->targetList = $2 ;
15088
+ n->fromClause = $3 ;
15089
+ n->whereClause = $4 ;
15090
+ n->groupClause = $5 ;
15091
+ n->havingClause = $6 ;
15092
+ n->windowClause = $7 ;
15093
+ n->sortClause = $8 ;
15094
+ if ($9 )
15083
15095
{
15084
- n->limitOffset = $8 ->limitOffset ;
15085
- n->limitCount = $8 ->limitCount ;
15096
+ n->limitOffset = $9 ->limitOffset ;
15097
+ n->limitCount = $9 ->limitCount ;
15086
15098
if (!n->sortClause &&
15087
- $8 ->limitOption == LIMIT_OPTION_WITH_TIES)
15099
+ $9 ->limitOption == LIMIT_OPTION_WITH_TIES)
15088
15100
ereport (ERROR,
15089
15101
(errcode (ERRCODE_SYNTAX_ERROR),
15090
15102
errmsg (" WITH TIES cannot be specified without ORDER BY clause" )));
15091
- n->limitOption = $8 ->limitOption ;
15103
+ n->limitOption = $9 ->limitOption ;
15092
15104
}
15093
- n->lockingClause = $9 ;
15105
+ n->lockingClause = $10 ;
15094
15106
$$ = (Node *) n;
15095
15107
}
15096
15108
;
0 commit comments