@@ -389,7 +389,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
389389 OptTableElementList TableElementList OptInherit definition
390390 OptTypedTableElementList TypedTableElementList
391391 reloptions opt_reloptions
392- OptWith distinct_clause opt_definition func_args func_args_list
392+ OptWith opt_definition func_args func_args_list
393393 func_args_with_defaults func_args_with_defaults_list
394394 aggr_args aggr_args_list
395395 func_as createfunc_opt_list alterfunc_opt_list
@@ -401,6 +401,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
401401 name_list role_list from_clause from_list opt_array_bounds
402402 qualified_name_list any_name any_name_list type_name_list
403403 any_operator expr_list attrs
404+ distinct_clause opt_distinct_clause
404405 target_list opt_target_list insert_column_list set_target_list
405406 set_clause_list set_clause
406407 def_list operator_def_list indirection opt_indirection
@@ -11260,6 +11261,11 @@ select_clause:
1126011261 * As with select_no_parens, simple_select cannot have outer parentheses,
1126111262 * but can have parenthesized subclauses.
1126211263 *
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+ *
1126311269 * Note that sort clauses cannot be included at this level --- SQL requires
1126411270 * SELECT foo UNION SELECT bar ORDER BY baz
1126511271 * to be parsed as
@@ -11497,8 +11503,13 @@ opt_all_clause:
1149711503 | /* EMPTY*/
1149811504 ;
1149911505
11506+ opt_distinct_clause :
11507+ distinct_clause { $$ = $1 ; }
11508+ | opt_all_clause { $$ = NIL; }
11509+ ;
11510+
1150011511opt_sort_clause :
11501- sort_clause { $$ = $1 ;}
11512+ sort_clause { $$ = $1 ; }
1150211513 | /* EMPTY*/ { $$ = NIL; }
1150311514 ;
1150411515
@@ -15065,32 +15076,33 @@ role_list: RoleSpec
1506515076 * Therefore the returned struct is a SelectStmt.
1506615077 *****************************************************************************/
1506715078
15068- PLpgSQL_Expr: opt_target_list
15079+ PLpgSQL_Expr: opt_distinct_clause opt_target_list
1506915080 from_clause where_clause
1507015081 group_clause having_clause window_clause
1507115082 opt_sort_clause opt_select_limit opt_for_locking_clause
1507215083 {
1507315084 SelectStmt *n = makeNode (SelectStmt);
1507415085
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 )
1508315095 {
15084- n->limitOffset = $8 ->limitOffset ;
15085- n->limitCount = $8 ->limitCount ;
15096+ n->limitOffset = $9 ->limitOffset ;
15097+ n->limitCount = $9 ->limitCount ;
1508615098 if (!n->sortClause &&
15087- $8 ->limitOption == LIMIT_OPTION_WITH_TIES)
15099+ $9 ->limitOption == LIMIT_OPTION_WITH_TIES)
1508815100 ereport (ERROR,
1508915101 (errcode (ERRCODE_SYNTAX_ERROR),
1509015102 errmsg (" WITH TIES cannot be specified without ORDER BY clause" )));
15091- n->limitOption = $8 ->limitOption ;
15103+ n->limitOption = $9 ->limitOption ;
1509215104 }
15093- n->lockingClause = $9 ;
15105+ n->lockingClause = $10 ;
1509415106 $$ = (Node *) n;
1509515107 }
1509615108 ;
0 commit comments