Skip to content

Commit b5913f6

Browse files
committed
Refactor CLUSTER and REINDEX grammar to use DefElem for option lists
This changes CLUSTER and REINDEX so as a parenthesized grammar becomes possible for options, while unifying the grammar parsing rules for option lists with the existing ones. This is a follow-up of the work done in 873ea9e for VACUUM, ANALYZE and EXPLAIN. This benefits REINDEX for a potential backend-side filtering for collatable-sensitive indexes and TABLESPACE, while CLUSTER would benefit from the latter. Author: Alexey Kondratov, Justin Pryzby Discussion: https://postgr.es/m/8a8f5f73-00d3-55f8-7583-1375ca8f6a91@postgrespro.ru
1 parent dc11f31 commit b5913f6

File tree

15 files changed

+180
-62
lines changed

15 files changed

+180
-62
lines changed

doc/src/sgml/ref/cluster.sgml

+20
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,13 @@ PostgreSQL documentation
2222
<refsynopsisdiv>
2323
<synopsis>
2424
CLUSTER [VERBOSE] <replaceable class="parameter">table_name</replaceable> [ USING <replaceable class="parameter">index_name</replaceable> ]
25+
CLUSTER ( <replaceable class="parameter">option</replaceable> [, ...] ) <replaceable class="parameter">table_name</replaceable> [ USING <replaceable class="parameter">index_name</replaceable> ]
2526
CLUSTER [VERBOSE]
27+
28+
<phrase>where <replaceable class="parameter">option</replaceable> can be one of:</phrase>
29+
30+
VERBOSE [ <replaceable class="parameter">boolean</replaceable> ]
31+
2632
</synopsis>
2733
</refsynopsisdiv>
2834

@@ -107,6 +113,20 @@ CLUSTER [VERBOSE]
107113
</para>
108114
</listitem>
109115
</varlistentry>
116+
117+
<varlistentry>
118+
<term><replaceable class="parameter">boolean</replaceable></term>
119+
<listitem>
120+
<para>
121+
Specifies whether the selected option should be turned on or off.
122+
You can write <literal>TRUE</literal>, <literal>ON</literal>, or
123+
<literal>1</literal> to enable the option, and <literal>FALSE</literal>,
124+
<literal>OFF</literal>, or <literal>0</literal> to disable it. The
125+
<replaceable class="parameter">boolean</replaceable> value can also
126+
be omitted, in which case <literal>TRUE</literal> is assumed.
127+
</para>
128+
</listitem>
129+
</varlistentry>
110130
</variablelist>
111131
</refsect1>
112132

doc/src/sgml/ref/reindex.sgml

+17-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ REINDEX [ ( <replaceable class="parameter">option</replaceable> [, ...] ) ] { IN
2525

2626
<phrase>where <replaceable class="parameter">option</replaceable> can be one of:</phrase>
2727

28-
VERBOSE
28+
CONCURRENTLY [ <replaceable class="parameter">boolean</replaceable> ]
29+
VERBOSE [ <replaceable class="parameter">boolean</replaceable> ]
2930
</synopsis>
3031
</refsynopsisdiv>
3132

@@ -194,6 +195,21 @@ REINDEX [ ( <replaceable class="parameter">option</replaceable> [, ...] ) ] { IN
194195
</para>
195196
</listitem>
196197
</varlistentry>
198+
199+
<varlistentry>
200+
<term><replaceable class="parameter">boolean</replaceable></term>
201+
<listitem>
202+
<para>
203+
Specifies whether the selected option should be turned on or off.
204+
You can write <literal>TRUE</literal>, <literal>ON</literal>, or
205+
<literal>1</literal> to enable the option, and <literal>FALSE</literal>,
206+
<literal>OFF</literal>, or <literal>0</literal> to disable it. The
207+
<replaceable class="parameter">boolean</replaceable> value can also
208+
be omitted, in which case <literal>TRUE</literal> is assumed.
209+
</para>
210+
</listitem>
211+
</varlistentry>
212+
197213
</variablelist>
198214
</refsect1>
199215

src/backend/commands/cluster.c

+25-3
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "catalog/pg_am.h"
3636
#include "catalog/toasting.h"
3737
#include "commands/cluster.h"
38+
#include "commands/defrem.h"
3839
#include "commands/progress.h"
3940
#include "commands/tablecmds.h"
4041
#include "commands/vacuum.h"
@@ -99,8 +100,29 @@ static List *get_tables_to_cluster(MemoryContext cluster_context);
99100
*---------------------------------------------------------------------------
100101
*/
101102
void
102-
cluster(ClusterStmt *stmt, bool isTopLevel)
103+
cluster(ParseState *pstate, ClusterStmt *stmt, bool isTopLevel)
103104
{
105+
ListCell *lc;
106+
int options = 0;
107+
bool verbose = false;
108+
109+
/* Parse option list */
110+
foreach(lc, stmt->params)
111+
{
112+
DefElem *opt = (DefElem *) lfirst(lc);
113+
114+
if (strcmp(opt->defname, "verbose") == 0)
115+
verbose = defGetBoolean(opt);
116+
else
117+
ereport(ERROR,
118+
(errcode(ERRCODE_SYNTAX_ERROR),
119+
errmsg("unrecognized CLUSTER option \"%s\"",
120+
opt->defname),
121+
parser_errposition(pstate, opt->location)));
122+
}
123+
124+
options = (verbose ? CLUOPT_VERBOSE : 0);
125+
104126
if (stmt->relation != NULL)
105127
{
106128
/* This is the single-relation case. */
@@ -170,7 +192,7 @@ cluster(ClusterStmt *stmt, bool isTopLevel)
170192
table_close(rel, NoLock);
171193

172194
/* Do the job. */
173-
cluster_rel(tableOid, indexOid, stmt->options);
195+
cluster_rel(tableOid, indexOid, options);
174196
}
175197
else
176198
{
@@ -219,7 +241,7 @@ cluster(ClusterStmt *stmt, bool isTopLevel)
219241
PushActiveSnapshot(GetTransactionSnapshot());
220242
/* Do the job. */
221243
cluster_rel(rvtc->tableOid, rvtc->indexOid,
222-
stmt->options | CLUOPT_RECHECK);
244+
options | CLUOPT_RECHECK);
223245
PopActiveSnapshot();
224246
CommitTransactionCommand();
225247
}

src/backend/commands/indexcmds.c

+36
Original file line numberDiff line numberDiff line change
@@ -2451,6 +2451,42 @@ ChooseIndexColumnNames(List *indexElems)
24512451
return result;
24522452
}
24532453

2454+
/*
2455+
* ReindexParseOptions
2456+
* Parse list of REINDEX options, returning a bitmask of ReindexOption.
2457+
*/
2458+
int
2459+
ReindexParseOptions(ParseState *pstate, ReindexStmt *stmt)
2460+
{
2461+
ListCell *lc;
2462+
int options = 0;
2463+
bool concurrently = false;
2464+
bool verbose = false;
2465+
2466+
/* Parse option list */
2467+
foreach(lc, stmt->params)
2468+
{
2469+
DefElem *opt = (DefElem *) lfirst(lc);
2470+
2471+
if (strcmp(opt->defname, "verbose") == 0)
2472+
verbose = defGetBoolean(opt);
2473+
else if (strcmp(opt->defname, "concurrently") == 0)
2474+
concurrently = defGetBoolean(opt);
2475+
else
2476+
ereport(ERROR,
2477+
(errcode(ERRCODE_SYNTAX_ERROR),
2478+
errmsg("unrecognized REINDEX option \"%s\"",
2479+
opt->defname),
2480+
parser_errposition(pstate, opt->location)));
2481+
}
2482+
2483+
options =
2484+
(verbose ? REINDEXOPT_VERBOSE : 0) |
2485+
(concurrently ? REINDEXOPT_CONCURRENTLY : 0);
2486+
2487+
return options;
2488+
}
2489+
24542490
/*
24552491
* ReindexIndex
24562492
* Recreate a specific index.

src/backend/nodes/copyfuncs.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -3349,7 +3349,7 @@ _copyClusterStmt(const ClusterStmt *from)
33493349

33503350
COPY_NODE_FIELD(relation);
33513351
COPY_STRING_FIELD(indexname);
3352-
COPY_SCALAR_FIELD(options);
3352+
COPY_NODE_FIELD(params);
33533353

33543354
return newnode;
33553355
}
@@ -4443,7 +4443,7 @@ _copyReindexStmt(const ReindexStmt *from)
44434443
COPY_SCALAR_FIELD(kind);
44444444
COPY_NODE_FIELD(relation);
44454445
COPY_STRING_FIELD(name);
4446-
COPY_SCALAR_FIELD(options);
4446+
COPY_NODE_FIELD(params);
44474447

44484448
return newnode;
44494449
}

src/backend/nodes/equalfuncs.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -1210,7 +1210,7 @@ _equalClusterStmt(const ClusterStmt *a, const ClusterStmt *b)
12101210
{
12111211
COMPARE_NODE_FIELD(relation);
12121212
COMPARE_STRING_FIELD(indexname);
1213-
COMPARE_SCALAR_FIELD(options);
1213+
COMPARE_NODE_FIELD(params);
12141214

12151215
return true;
12161216
}
@@ -2130,7 +2130,7 @@ _equalReindexStmt(const ReindexStmt *a, const ReindexStmt *b)
21302130
COMPARE_SCALAR_FIELD(kind);
21312131
COMPARE_NODE_FIELD(relation);
21322132
COMPARE_STRING_FIELD(name);
2133-
COMPARE_SCALAR_FIELD(options);
2133+
COMPARE_NODE_FIELD(params);
21342134

21352135
return true;
21362136
}

src/backend/parser/gram.y

+30-24
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,6 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
515515
%type <list> generic_option_list alter_generic_option_list
516516

517517
%type <ival> reindex_target_type reindex_target_multitable
518-
%type <ival> reindex_option_list reindex_option_elem
519518

520519
%type <node> copy_generic_opt_arg copy_generic_opt_arg_list_item
521520
%type <defelt> copy_generic_opt_elem
@@ -8217,9 +8216,10 @@ ReindexStmt:
82178216
n->kind = $2;
82188217
n->relation = $4;
82198218
n->name = NULL;
8220-
n->options = 0;
8219+
n->params = NIL;
82218220
if ($3)
8222-
n->options |= REINDEXOPT_CONCURRENTLY;
8221+
n->params = lappend(n->params,
8222+
makeDefElem("concurrently", NULL, @3));
82238223
$$ = (Node *)n;
82248224
}
82258225
| REINDEX reindex_target_multitable opt_concurrently name
@@ -8228,31 +8228,34 @@ ReindexStmt:
82288228
n->kind = $2;
82298229
n->name = $4;
82308230
n->relation = NULL;
8231-
n->options = 0;
8231+
n->params = NIL;
82328232
if ($3)
8233-
n->options |= REINDEXOPT_CONCURRENTLY;
8233+
n->params = lappend(n->params,
8234+
makeDefElem("concurrently", NULL, @3));
82348235
$$ = (Node *)n;
82358236
}
8236-
| REINDEX '(' reindex_option_list ')' reindex_target_type opt_concurrently qualified_name
8237+
| REINDEX '(' utility_option_list ')' reindex_target_type opt_concurrently qualified_name
82378238
{
82388239
ReindexStmt *n = makeNode(ReindexStmt);
82398240
n->kind = $5;
82408241
n->relation = $7;
82418242
n->name = NULL;
8242-
n->options = $3;
8243+
n->params = $3;
82438244
if ($6)
8244-
n->options |= REINDEXOPT_CONCURRENTLY;
8245+
n->params = lappend(n->params,
8246+
makeDefElem("concurrently", NULL, @6));
82458247
$$ = (Node *)n;
82468248
}
8247-
| REINDEX '(' reindex_option_list ')' reindex_target_multitable opt_concurrently name
8249+
| REINDEX '(' utility_option_list ')' reindex_target_multitable opt_concurrently name
82488250
{
82498251
ReindexStmt *n = makeNode(ReindexStmt);
82508252
n->kind = $5;
82518253
n->name = $7;
82528254
n->relation = NULL;
8253-
n->options = $3;
8255+
n->params = $3;
82548256
if ($6)
8255-
n->options |= REINDEXOPT_CONCURRENTLY;
8257+
n->params = lappend(n->params,
8258+
makeDefElem("concurrently", NULL, @6));
82568259
$$ = (Node *)n;
82578260
}
82588261
;
@@ -8265,13 +8268,6 @@ reindex_target_multitable:
82658268
| SYSTEM_P { $$ = REINDEX_OBJECT_SYSTEM; }
82668269
| DATABASE { $$ = REINDEX_OBJECT_DATABASE; }
82678270
;
8268-
reindex_option_list:
8269-
reindex_option_elem { $$ = $1; }
8270-
| reindex_option_list ',' reindex_option_elem { $$ = $1 | $3; }
8271-
;
8272-
reindex_option_elem:
8273-
VERBOSE { $$ = REINDEXOPT_VERBOSE; }
8274-
;
82758271

82768272
/*****************************************************************************
82778273
*
@@ -10407,6 +10403,7 @@ CreateConversionStmt:
1040710403
*
1040810404
* QUERY:
1040910405
* CLUSTER [VERBOSE] <qualified_name> [ USING <index_name> ]
10406+
* CLUSTER [ (options) ] <qualified_name> [ USING <index_name> ]
1041010407
* CLUSTER [VERBOSE]
1041110408
* CLUSTER [VERBOSE] <index_name> ON <qualified_name> (for pre-8.3)
1041210409
*
@@ -10418,19 +10415,28 @@ ClusterStmt:
1041810415
ClusterStmt *n = makeNode(ClusterStmt);
1041910416
n->relation = $3;
1042010417
n->indexname = $4;
10421-
n->options = 0;
10418+
n->params = NIL;
1042210419
if ($2)
10423-
n->options |= CLUOPT_VERBOSE;
10420+
n->params = lappend(n->params, makeDefElem("verbose", NULL, @2));
10421+
$$ = (Node*)n;
10422+
}
10423+
10424+
| CLUSTER '(' utility_option_list ')' qualified_name cluster_index_specification
10425+
{
10426+
ClusterStmt *n = makeNode(ClusterStmt);
10427+
n->relation = $5;
10428+
n->indexname = $6;
10429+
n->params = $3;
1042410430
$$ = (Node*)n;
1042510431
}
1042610432
| CLUSTER opt_verbose
1042710433
{
1042810434
ClusterStmt *n = makeNode(ClusterStmt);
1042910435
n->relation = NULL;
1043010436
n->indexname = NULL;
10431-
n->options = 0;
10437+
n->params = NIL;
1043210438
if ($2)
10433-
n->options |= CLUOPT_VERBOSE;
10439+
n->params = lappend(n->params, makeDefElem("verbose", NULL, @2));
1043410440
$$ = (Node*)n;
1043510441
}
1043610442
/* kept for pre-8.3 compatibility */
@@ -10439,9 +10445,9 @@ ClusterStmt:
1043910445
ClusterStmt *n = makeNode(ClusterStmt);
1044010446
n->relation = $5;
1044110447
n->indexname = $3;
10442-
n->options = 0;
10448+
n->params = NIL;
1044310449
if ($2)
10444-
n->options |= CLUOPT_VERBOSE;
10450+
n->params = lappend(n->params, makeDefElem("verbose", NULL, @2));
1044510451
$$ = (Node*)n;
1044610452
}
1044710453
;

src/backend/tcop/utility.c

+8-7
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "access/xact.h"
2323
#include "access/xlog.h"
2424
#include "catalog/catalog.h"
25+
#include "catalog/index.h"
2526
#include "catalog/namespace.h"
2627
#include "catalog/pg_inherits.h"
2728
#include "catalog/toasting.h"
@@ -818,7 +819,7 @@ standard_ProcessUtility(PlannedStmt *pstmt,
818819
break;
819820

820821
case T_ClusterStmt:
821-
cluster((ClusterStmt *) parsetree, isTopLevel);
822+
cluster(pstate, (ClusterStmt *) parsetree, isTopLevel);
822823
break;
823824

824825
case T_VacuumStmt:
@@ -918,20 +919,20 @@ standard_ProcessUtility(PlannedStmt *pstmt,
918919
case T_ReindexStmt:
919920
{
920921
ReindexStmt *stmt = (ReindexStmt *) parsetree;
922+
int options;
921923

922-
if ((stmt->options & REINDEXOPT_CONCURRENTLY) != 0)
924+
options = ReindexParseOptions(pstate, stmt);
925+
if ((options & REINDEXOPT_CONCURRENTLY) != 0)
923926
PreventInTransactionBlock(isTopLevel,
924927
"REINDEX CONCURRENTLY");
925928

926929
switch (stmt->kind)
927930
{
928931
case REINDEX_OBJECT_INDEX:
929-
ReindexIndex(stmt->relation, stmt->options,
930-
isTopLevel);
932+
ReindexIndex(stmt->relation, options, isTopLevel);
931933
break;
932934
case REINDEX_OBJECT_TABLE:
933-
ReindexTable(stmt->relation, stmt->options,
934-
isTopLevel);
935+
ReindexTable(stmt->relation, options, isTopLevel);
935936
break;
936937
case REINDEX_OBJECT_SCHEMA:
937938
case REINDEX_OBJECT_SYSTEM:
@@ -947,7 +948,7 @@ standard_ProcessUtility(PlannedStmt *pstmt,
947948
(stmt->kind == REINDEX_OBJECT_SCHEMA) ? "REINDEX SCHEMA" :
948949
(stmt->kind == REINDEX_OBJECT_SYSTEM) ? "REINDEX SYSTEM" :
949950
"REINDEX DATABASE");
950-
ReindexMultipleTables(stmt->name, stmt->kind, stmt->options);
951+
ReindexMultipleTables(stmt->name, stmt->kind, options);
951952
break;
952953
default:
953954
elog(ERROR, "unrecognized object type: %d",

0 commit comments

Comments
 (0)