From 48fff177a8f0096c99c77b4e1368cc73f7e86585 Mon Sep 17 00:00:00 2001
From: Nathan Bossart <nbossart@postgresql.org>
Date: Fri, 21 Apr 2023 20:16:25 -0700
Subject: [PATCH v3 1/2] Support parenthesized syntax for CLUSTER without a
 table name.

b5913f6 added a parenthesized syntax for CLUSTER, but it requires
specifying a table name.  This is unlike commands such as VACUUM
and ANALYZE, which do not require specifying a table in the
parenthesized syntax.  This change resolves this inconsistency.

The documentation for the CLUSTER syntax has also been consolidated
in anticipation of a follow-up change that will move the
unparenthesized syntax to the "Compatibility" section.

Author: Nathan Bossart
Reviewed-by: ???
Discussion: https://postgr.es/m/CAAKRu_bc5uHieG1976kGqJKxyWtyQt9yvktjsVX%2Bi7NOigDjOA%40mail.gmail.com
---
 doc/src/sgml/ref/cluster.sgml |  5 ++---
 src/backend/parser/gram.y     | 21 ++++++++++++++-------
 2 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/doc/src/sgml/ref/cluster.sgml b/doc/src/sgml/ref/cluster.sgml
index 29f0f1fd90..0776d01e60 100644
--- a/doc/src/sgml/ref/cluster.sgml
+++ b/doc/src/sgml/ref/cluster.sgml
@@ -21,9 +21,8 @@ PostgreSQL documentation
 
  <refsynopsisdiv>
 <synopsis>
-CLUSTER [VERBOSE] <replaceable class="parameter">table_name</replaceable> [ USING <replaceable class="parameter">index_name</replaceable> ]
-CLUSTER ( <replaceable class="parameter">option</replaceable> [, ...] ) <replaceable class="parameter">table_name</replaceable> [ USING <replaceable class="parameter">index_name</replaceable> ]
-CLUSTER [VERBOSE]
+CLUSTER [VERBOSE] [ <replaceable class="parameter">table_name</replaceable> [ USING <replaceable class="parameter">index_name</replaceable> ] ]
+CLUSTER [ ( <replaceable class="parameter">option</replaceable> [, ...] ) ] [ <replaceable class="parameter">table_name</replaceable> [ USING <replaceable class="parameter">index_name</replaceable> ] ]
 
 <phrase>where <replaceable class="parameter">option</replaceable> can be one of:</phrase>
 
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index acf6cf4866..9a8ffed595 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -11574,9 +11574,8 @@ CreateConversionStmt:
 /*****************************************************************************
  *
  *		QUERY:
- *				CLUSTER [VERBOSE] <qualified_name> [ USING <index_name> ]
- *				CLUSTER [ (options) ] <qualified_name> [ USING <index_name> ]
- *				CLUSTER [VERBOSE]
+ *				CLUSTER [VERBOSE] [ <qualified_name> [ USING <index_name> ] ]
+ *				CLUSTER [ (options) ] [ <qualified_name> [ USING <index_name> ] ]
  *				CLUSTER [VERBOSE] <index_name> ON <qualified_name> (for pre-8.3)
  *
  *****************************************************************************/
@@ -11593,7 +11592,17 @@ ClusterStmt:
 						n->params = lappend(n->params, makeDefElem("verbose", NULL, @2));
 					$$ = (Node *) n;
 				}
+			| CLUSTER opt_verbose
+				{
+					ClusterStmt *n = makeNode(ClusterStmt);
 
+					n->relation = NULL;
+					n->indexname = NULL;
+					n->params = NIL;
+					if ($2)
+						n->params = lappend(n->params, makeDefElem("verbose", NULL, @2));
+					$$ = (Node *) n;
+				}
 			| CLUSTER '(' utility_option_list ')' qualified_name cluster_index_specification
 				{
 					ClusterStmt *n = makeNode(ClusterStmt);
@@ -11603,15 +11612,13 @@ ClusterStmt:
 					n->params = $3;
 					$$ = (Node *) n;
 				}
-			| CLUSTER opt_verbose
+			| CLUSTER '(' utility_option_list ')'
 				{
 					ClusterStmt *n = makeNode(ClusterStmt);
 
 					n->relation = NULL;
 					n->indexname = NULL;
-					n->params = NIL;
-					if ($2)
-						n->params = lappend(n->params, makeDefElem("verbose", NULL, @2));
+					n->params = $3;
 					$$ = (Node *) n;
 				}
 			/* kept for pre-8.3 compatibility */
-- 
2.25.1

