Commit b5913f61 authored by Michael Paquier's avatar Michael Paquier

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 873ea9ee 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
parent dc11f31a
...@@ -22,7 +22,13 @@ PostgreSQL documentation ...@@ -22,7 +22,13 @@ PostgreSQL documentation
<refsynopsisdiv> <refsynopsisdiv>
<synopsis> <synopsis>
CLUSTER [VERBOSE] <replaceable class="parameter">table_name</replaceable> [ USING <replaceable class="parameter">index_name</replaceable> ] 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]
<phrase>where <replaceable class="parameter">option</replaceable> can be one of:</phrase>
VERBOSE [ <replaceable class="parameter">boolean</replaceable> ]
</synopsis> </synopsis>
</refsynopsisdiv> </refsynopsisdiv>
...@@ -107,6 +113,20 @@ CLUSTER [VERBOSE] ...@@ -107,6 +113,20 @@ CLUSTER [VERBOSE]
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><replaceable class="parameter">boolean</replaceable></term>
<listitem>
<para>
Specifies whether the selected option should be turned on or off.
You can write <literal>TRUE</literal>, <literal>ON</literal>, or
<literal>1</literal> to enable the option, and <literal>FALSE</literal>,
<literal>OFF</literal>, or <literal>0</literal> to disable it. The
<replaceable class="parameter">boolean</replaceable> value can also
be omitted, in which case <literal>TRUE</literal> is assumed.
</para>
</listitem>
</varlistentry>
</variablelist> </variablelist>
</refsect1> </refsect1>
......
...@@ -25,7 +25,8 @@ REINDEX [ ( <replaceable class="parameter">option</replaceable> [, ...] ) ] { IN ...@@ -25,7 +25,8 @@ REINDEX [ ( <replaceable class="parameter">option</replaceable> [, ...] ) ] { IN
<phrase>where <replaceable class="parameter">option</replaceable> can be one of:</phrase> <phrase>where <replaceable class="parameter">option</replaceable> can be one of:</phrase>
VERBOSE CONCURRENTLY [ <replaceable class="parameter">boolean</replaceable> ]
VERBOSE [ <replaceable class="parameter">boolean</replaceable> ]
</synopsis> </synopsis>
</refsynopsisdiv> </refsynopsisdiv>
...@@ -194,6 +195,21 @@ REINDEX [ ( <replaceable class="parameter">option</replaceable> [, ...] ) ] { IN ...@@ -194,6 +195,21 @@ REINDEX [ ( <replaceable class="parameter">option</replaceable> [, ...] ) ] { IN
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><replaceable class="parameter">boolean</replaceable></term>
<listitem>
<para>
Specifies whether the selected option should be turned on or off.
You can write <literal>TRUE</literal>, <literal>ON</literal>, or
<literal>1</literal> to enable the option, and <literal>FALSE</literal>,
<literal>OFF</literal>, or <literal>0</literal> to disable it. The
<replaceable class="parameter">boolean</replaceable> value can also
be omitted, in which case <literal>TRUE</literal> is assumed.
</para>
</listitem>
</varlistentry>
</variablelist> </variablelist>
</refsect1> </refsect1>
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include "catalog/pg_am.h" #include "catalog/pg_am.h"
#include "catalog/toasting.h" #include "catalog/toasting.h"
#include "commands/cluster.h" #include "commands/cluster.h"
#include "commands/defrem.h"
#include "commands/progress.h" #include "commands/progress.h"
#include "commands/tablecmds.h" #include "commands/tablecmds.h"
#include "commands/vacuum.h" #include "commands/vacuum.h"
...@@ -99,8 +100,29 @@ static List *get_tables_to_cluster(MemoryContext cluster_context); ...@@ -99,8 +100,29 @@ static List *get_tables_to_cluster(MemoryContext cluster_context);
*--------------------------------------------------------------------------- *---------------------------------------------------------------------------
*/ */
void void
cluster(ClusterStmt *stmt, bool isTopLevel) cluster(ParseState *pstate, ClusterStmt *stmt, bool isTopLevel)
{ {
ListCell *lc;
int options = 0;
bool verbose = false;
/* Parse option list */
foreach(lc, stmt->params)
{
DefElem *opt = (DefElem *) lfirst(lc);
if (strcmp(opt->defname, "verbose") == 0)
verbose = defGetBoolean(opt);
else
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("unrecognized CLUSTER option \"%s\"",
opt->defname),
parser_errposition(pstate, opt->location)));
}
options = (verbose ? CLUOPT_VERBOSE : 0);
if (stmt->relation != NULL) if (stmt->relation != NULL)
{ {
/* This is the single-relation case. */ /* This is the single-relation case. */
...@@ -170,7 +192,7 @@ cluster(ClusterStmt *stmt, bool isTopLevel) ...@@ -170,7 +192,7 @@ cluster(ClusterStmt *stmt, bool isTopLevel)
table_close(rel, NoLock); table_close(rel, NoLock);
/* Do the job. */ /* Do the job. */
cluster_rel(tableOid, indexOid, stmt->options); cluster_rel(tableOid, indexOid, options);
} }
else else
{ {
...@@ -219,7 +241,7 @@ cluster(ClusterStmt *stmt, bool isTopLevel) ...@@ -219,7 +241,7 @@ cluster(ClusterStmt *stmt, bool isTopLevel)
PushActiveSnapshot(GetTransactionSnapshot()); PushActiveSnapshot(GetTransactionSnapshot());
/* Do the job. */ /* Do the job. */
cluster_rel(rvtc->tableOid, rvtc->indexOid, cluster_rel(rvtc->tableOid, rvtc->indexOid,
stmt->options | CLUOPT_RECHECK); options | CLUOPT_RECHECK);
PopActiveSnapshot(); PopActiveSnapshot();
CommitTransactionCommand(); CommitTransactionCommand();
} }
......
...@@ -2451,6 +2451,42 @@ ChooseIndexColumnNames(List *indexElems) ...@@ -2451,6 +2451,42 @@ ChooseIndexColumnNames(List *indexElems)
return result; return result;
} }
/*
* ReindexParseOptions
* Parse list of REINDEX options, returning a bitmask of ReindexOption.
*/
int
ReindexParseOptions(ParseState *pstate, ReindexStmt *stmt)
{
ListCell *lc;
int options = 0;
bool concurrently = false;
bool verbose = false;
/* Parse option list */
foreach(lc, stmt->params)
{
DefElem *opt = (DefElem *) lfirst(lc);
if (strcmp(opt->defname, "verbose") == 0)
verbose = defGetBoolean(opt);
else if (strcmp(opt->defname, "concurrently") == 0)
concurrently = defGetBoolean(opt);
else
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("unrecognized REINDEX option \"%s\"",
opt->defname),
parser_errposition(pstate, opt->location)));
}
options =
(verbose ? REINDEXOPT_VERBOSE : 0) |
(concurrently ? REINDEXOPT_CONCURRENTLY : 0);
return options;
}
/* /*
* ReindexIndex * ReindexIndex
* Recreate a specific index. * Recreate a specific index.
......
...@@ -3349,7 +3349,7 @@ _copyClusterStmt(const ClusterStmt *from) ...@@ -3349,7 +3349,7 @@ _copyClusterStmt(const ClusterStmt *from)
COPY_NODE_FIELD(relation); COPY_NODE_FIELD(relation);
COPY_STRING_FIELD(indexname); COPY_STRING_FIELD(indexname);
COPY_SCALAR_FIELD(options); COPY_NODE_FIELD(params);
return newnode; return newnode;
} }
...@@ -4443,7 +4443,7 @@ _copyReindexStmt(const ReindexStmt *from) ...@@ -4443,7 +4443,7 @@ _copyReindexStmt(const ReindexStmt *from)
COPY_SCALAR_FIELD(kind); COPY_SCALAR_FIELD(kind);
COPY_NODE_FIELD(relation); COPY_NODE_FIELD(relation);
COPY_STRING_FIELD(name); COPY_STRING_FIELD(name);
COPY_SCALAR_FIELD(options); COPY_NODE_FIELD(params);
return newnode; return newnode;
} }
......
...@@ -1210,7 +1210,7 @@ _equalClusterStmt(const ClusterStmt *a, const ClusterStmt *b) ...@@ -1210,7 +1210,7 @@ _equalClusterStmt(const ClusterStmt *a, const ClusterStmt *b)
{ {
COMPARE_NODE_FIELD(relation); COMPARE_NODE_FIELD(relation);
COMPARE_STRING_FIELD(indexname); COMPARE_STRING_FIELD(indexname);
COMPARE_SCALAR_FIELD(options); COMPARE_NODE_FIELD(params);
return true; return true;
} }
...@@ -2130,7 +2130,7 @@ _equalReindexStmt(const ReindexStmt *a, const ReindexStmt *b) ...@@ -2130,7 +2130,7 @@ _equalReindexStmt(const ReindexStmt *a, const ReindexStmt *b)
COMPARE_SCALAR_FIELD(kind); COMPARE_SCALAR_FIELD(kind);
COMPARE_NODE_FIELD(relation); COMPARE_NODE_FIELD(relation);
COMPARE_STRING_FIELD(name); COMPARE_STRING_FIELD(name);
COMPARE_SCALAR_FIELD(options); COMPARE_NODE_FIELD(params);
return true; return true;
} }
......
...@@ -515,7 +515,6 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); ...@@ -515,7 +515,6 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
%type <list> generic_option_list alter_generic_option_list %type <list> generic_option_list alter_generic_option_list
%type <ival> reindex_target_type reindex_target_multitable %type <ival> reindex_target_type reindex_target_multitable
%type <ival> reindex_option_list reindex_option_elem
%type <node> copy_generic_opt_arg copy_generic_opt_arg_list_item %type <node> copy_generic_opt_arg copy_generic_opt_arg_list_item
%type <defelt> copy_generic_opt_elem %type <defelt> copy_generic_opt_elem
...@@ -8217,9 +8216,10 @@ ReindexStmt: ...@@ -8217,9 +8216,10 @@ ReindexStmt:
n->kind = $2; n->kind = $2;
n->relation = $4; n->relation = $4;
n->name = NULL; n->name = NULL;
n->options = 0; n->params = NIL;
if ($3) if ($3)
n->options |= REINDEXOPT_CONCURRENTLY; n->params = lappend(n->params,
makeDefElem("concurrently", NULL, @3));
$$ = (Node *)n; $$ = (Node *)n;
} }
| REINDEX reindex_target_multitable opt_concurrently name | REINDEX reindex_target_multitable opt_concurrently name
...@@ -8228,31 +8228,34 @@ ReindexStmt: ...@@ -8228,31 +8228,34 @@ ReindexStmt:
n->kind = $2; n->kind = $2;
n->name = $4; n->name = $4;
n->relation = NULL; n->relation = NULL;
n->options = 0; n->params = NIL;
if ($3) if ($3)
n->options |= REINDEXOPT_CONCURRENTLY; n->params = lappend(n->params,
makeDefElem("concurrently", NULL, @3));
$$ = (Node *)n; $$ = (Node *)n;
} }
| REINDEX '(' reindex_option_list ')' reindex_target_type opt_concurrently qualified_name | REINDEX '(' utility_option_list ')' reindex_target_type opt_concurrently qualified_name
{ {
ReindexStmt *n = makeNode(ReindexStmt); ReindexStmt *n = makeNode(ReindexStmt);
n->kind = $5; n->kind = $5;
n->relation = $7; n->relation = $7;
n->name = NULL; n->name = NULL;
n->options = $3; n->params = $3;
if ($6) if ($6)
n->options |= REINDEXOPT_CONCURRENTLY; n->params = lappend(n->params,
makeDefElem("concurrently", NULL, @6));
$$ = (Node *)n; $$ = (Node *)n;
} }
| REINDEX '(' reindex_option_list ')' reindex_target_multitable opt_concurrently name | REINDEX '(' utility_option_list ')' reindex_target_multitable opt_concurrently name
{ {
ReindexStmt *n = makeNode(ReindexStmt); ReindexStmt *n = makeNode(ReindexStmt);
n->kind = $5; n->kind = $5;
n->name = $7; n->name = $7;
n->relation = NULL; n->relation = NULL;
n->options = $3; n->params = $3;
if ($6) if ($6)
n->options |= REINDEXOPT_CONCURRENTLY; n->params = lappend(n->params,
makeDefElem("concurrently", NULL, @6));
$$ = (Node *)n; $$ = (Node *)n;
} }
; ;
...@@ -8265,13 +8268,6 @@ reindex_target_multitable: ...@@ -8265,13 +8268,6 @@ reindex_target_multitable:
| SYSTEM_P { $$ = REINDEX_OBJECT_SYSTEM; } | SYSTEM_P { $$ = REINDEX_OBJECT_SYSTEM; }
| DATABASE { $$ = REINDEX_OBJECT_DATABASE; } | DATABASE { $$ = REINDEX_OBJECT_DATABASE; }
; ;
reindex_option_list:
reindex_option_elem { $$ = $1; }
| reindex_option_list ',' reindex_option_elem { $$ = $1 | $3; }
;
reindex_option_elem:
VERBOSE { $$ = REINDEXOPT_VERBOSE; }
;
/***************************************************************************** /*****************************************************************************
* *
...@@ -10407,6 +10403,7 @@ CreateConversionStmt: ...@@ -10407,6 +10403,7 @@ CreateConversionStmt:
* *
* QUERY: * QUERY:
* CLUSTER [VERBOSE] <qualified_name> [ USING <index_name> ] * CLUSTER [VERBOSE] <qualified_name> [ USING <index_name> ]
* CLUSTER [ (options) ] <qualified_name> [ USING <index_name> ]
* CLUSTER [VERBOSE] * CLUSTER [VERBOSE]
* CLUSTER [VERBOSE] <index_name> ON <qualified_name> (for pre-8.3) * CLUSTER [VERBOSE] <index_name> ON <qualified_name> (for pre-8.3)
* *
...@@ -10418,9 +10415,18 @@ ClusterStmt: ...@@ -10418,9 +10415,18 @@ ClusterStmt:
ClusterStmt *n = makeNode(ClusterStmt); ClusterStmt *n = makeNode(ClusterStmt);
n->relation = $3; n->relation = $3;
n->indexname = $4; n->indexname = $4;
n->options = 0; n->params = NIL;
if ($2) if ($2)
n->options |= CLUOPT_VERBOSE; n->params = lappend(n->params, makeDefElem("verbose", NULL, @2));
$$ = (Node*)n;
}
| CLUSTER '(' utility_option_list ')' qualified_name cluster_index_specification
{
ClusterStmt *n = makeNode(ClusterStmt);
n->relation = $5;
n->indexname = $6;
n->params = $3;
$$ = (Node*)n; $$ = (Node*)n;
} }
| CLUSTER opt_verbose | CLUSTER opt_verbose
...@@ -10428,9 +10434,9 @@ ClusterStmt: ...@@ -10428,9 +10434,9 @@ ClusterStmt:
ClusterStmt *n = makeNode(ClusterStmt); ClusterStmt *n = makeNode(ClusterStmt);
n->relation = NULL; n->relation = NULL;
n->indexname = NULL; n->indexname = NULL;
n->options = 0; n->params = NIL;
if ($2) if ($2)
n->options |= CLUOPT_VERBOSE; n->params = lappend(n->params, makeDefElem("verbose", NULL, @2));
$$ = (Node*)n; $$ = (Node*)n;
} }
/* kept for pre-8.3 compatibility */ /* kept for pre-8.3 compatibility */
...@@ -10439,9 +10445,9 @@ ClusterStmt: ...@@ -10439,9 +10445,9 @@ ClusterStmt:
ClusterStmt *n = makeNode(ClusterStmt); ClusterStmt *n = makeNode(ClusterStmt);
n->relation = $5; n->relation = $5;
n->indexname = $3; n->indexname = $3;
n->options = 0; n->params = NIL;
if ($2) if ($2)
n->options |= CLUOPT_VERBOSE; n->params = lappend(n->params, makeDefElem("verbose", NULL, @2));
$$ = (Node*)n; $$ = (Node*)n;
} }
; ;
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include "access/xact.h" #include "access/xact.h"
#include "access/xlog.h" #include "access/xlog.h"
#include "catalog/catalog.h" #include "catalog/catalog.h"
#include "catalog/index.h"
#include "catalog/namespace.h" #include "catalog/namespace.h"
#include "catalog/pg_inherits.h" #include "catalog/pg_inherits.h"
#include "catalog/toasting.h" #include "catalog/toasting.h"
...@@ -818,7 +819,7 @@ standard_ProcessUtility(PlannedStmt *pstmt, ...@@ -818,7 +819,7 @@ standard_ProcessUtility(PlannedStmt *pstmt,
break; break;
case T_ClusterStmt: case T_ClusterStmt:
cluster((ClusterStmt *) parsetree, isTopLevel); cluster(pstate, (ClusterStmt *) parsetree, isTopLevel);
break; break;
case T_VacuumStmt: case T_VacuumStmt:
...@@ -918,20 +919,20 @@ standard_ProcessUtility(PlannedStmt *pstmt, ...@@ -918,20 +919,20 @@ standard_ProcessUtility(PlannedStmt *pstmt,
case T_ReindexStmt: case T_ReindexStmt:
{ {
ReindexStmt *stmt = (ReindexStmt *) parsetree; ReindexStmt *stmt = (ReindexStmt *) parsetree;
int options;
if ((stmt->options & REINDEXOPT_CONCURRENTLY) != 0) options = ReindexParseOptions(pstate, stmt);
if ((options & REINDEXOPT_CONCURRENTLY) != 0)
PreventInTransactionBlock(isTopLevel, PreventInTransactionBlock(isTopLevel,
"REINDEX CONCURRENTLY"); "REINDEX CONCURRENTLY");
switch (stmt->kind) switch (stmt->kind)
{ {
case REINDEX_OBJECT_INDEX: case REINDEX_OBJECT_INDEX:
ReindexIndex(stmt->relation, stmt->options, ReindexIndex(stmt->relation, options, isTopLevel);
isTopLevel);
break; break;
case REINDEX_OBJECT_TABLE: case REINDEX_OBJECT_TABLE:
ReindexTable(stmt->relation, stmt->options, ReindexTable(stmt->relation, options, isTopLevel);
isTopLevel);
break; break;
case REINDEX_OBJECT_SCHEMA: case REINDEX_OBJECT_SCHEMA:
case REINDEX_OBJECT_SYSTEM: case REINDEX_OBJECT_SYSTEM:
...@@ -947,7 +948,7 @@ standard_ProcessUtility(PlannedStmt *pstmt, ...@@ -947,7 +948,7 @@ standard_ProcessUtility(PlannedStmt *pstmt,
(stmt->kind == REINDEX_OBJECT_SCHEMA) ? "REINDEX SCHEMA" : (stmt->kind == REINDEX_OBJECT_SCHEMA) ? "REINDEX SCHEMA" :
(stmt->kind == REINDEX_OBJECT_SYSTEM) ? "REINDEX SYSTEM" : (stmt->kind == REINDEX_OBJECT_SYSTEM) ? "REINDEX SYSTEM" :
"REINDEX DATABASE"); "REINDEX DATABASE");
ReindexMultipleTables(stmt->name, stmt->kind, stmt->options); ReindexMultipleTables(stmt->name, stmt->kind, options);
break; break;
default: default:
elog(ERROR, "unrecognized object type: %d", elog(ERROR, "unrecognized object type: %d",
......
...@@ -2287,21 +2287,33 @@ psql_completion(const char *text, int start, int end) ...@@ -2287,21 +2287,33 @@ psql_completion(const char *text, int start, int end)
/* CLUSTER */ /* CLUSTER */
else if (Matches("CLUSTER")) else if (Matches("CLUSTER"))
COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_clusterables, "UNION SELECT 'VERBOSE'"); COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_clusterables, "UNION SELECT 'VERBOSE'");
else if (Matches("CLUSTER", "VERBOSE")) else if (Matches("CLUSTER", "VERBOSE") ||
Matches("CLUSTER", "(*)"))
COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_clusterables, NULL); COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_clusterables, NULL);
/* If we have CLUSTER <sth>, then add "USING" */ /* If we have CLUSTER <sth>, then add "USING" */
else if (Matches("CLUSTER", MatchAnyExcept("VERBOSE|ON"))) else if (Matches("CLUSTER", MatchAnyExcept("VERBOSE|ON|(|(*)")))
COMPLETE_WITH("USING"); COMPLETE_WITH("USING");
/* If we have CLUSTER VERBOSE <sth>, then add "USING" */ /* If we have CLUSTER VERBOSE <sth>, then add "USING" */
else if (Matches("CLUSTER", "VERBOSE", MatchAny)) else if (Matches("CLUSTER", "VERBOSE|(*)", MatchAny))
COMPLETE_WITH("USING"); COMPLETE_WITH("USING");
/* If we have CLUSTER <sth> USING, then add the index as well */ /* If we have CLUSTER <sth> USING, then add the index as well */
else if (Matches("CLUSTER", MatchAny, "USING") || else if (Matches("CLUSTER", MatchAny, "USING") ||
Matches("CLUSTER", "VERBOSE", MatchAny, "USING")) Matches("CLUSTER", "VERBOSE|(*)", MatchAny, "USING"))
{ {
completion_info_charp = prev2_wd; completion_info_charp = prev2_wd;
COMPLETE_WITH_QUERY(Query_for_index_of_table); COMPLETE_WITH_QUERY(Query_for_index_of_table);
} }
else if (HeadMatches("CLUSTER", "(*") &&
!HeadMatches("CLUSTER", "(*)"))
{
/*
* This fires if we're in an unfinished parenthesized option list.
* get_previous_words treats a completed parenthesized option list as
* one word, so the above test is correct.
*/
if (ends_with(prev_wd, '(') || ends_with(prev_wd, ','))
COMPLETE_WITH("VERBOSE");
}
/* COMMENT */ /* COMMENT */
else if (Matches("COMMENT")) else if (Matches("COMMENT"))
...@@ -3565,7 +3577,7 @@ psql_completion(const char *text, int start, int end) ...@@ -3565,7 +3577,7 @@ psql_completion(const char *text, int start, int end)
* one word, so the above test is correct. * one word, so the above test is correct.
*/ */
if (ends_with(prev_wd, '(') || ends_with(prev_wd, ',')) if (ends_with(prev_wd, '(') || ends_with(prev_wd, ','))
COMPLETE_WITH("VERBOSE"); COMPLETE_WITH("CONCURRENTLY", "VERBOSE");
} }
/* SECURITY LABEL */ /* SECURITY LABEL */
......
...@@ -29,6 +29,15 @@ typedef enum ...@@ -29,6 +29,15 @@ typedef enum
INDEX_DROP_SET_DEAD INDEX_DROP_SET_DEAD
} IndexStateFlagsAction; } IndexStateFlagsAction;
/* options for REINDEX */
typedef enum ReindexOption
{
REINDEXOPT_VERBOSE = 1 << 0, /* print progress info */
REINDEXOPT_REPORT_PROGRESS = 1 << 1, /* report pgstat progress */
REINDEXOPT_MISSING_OK = 1 << 2, /* skip missing relations */
REINDEXOPT_CONCURRENTLY = 1 << 3 /* concurrent mode */
} ReindexOption;
/* state info for validate_index bulkdelete callback */ /* state info for validate_index bulkdelete callback */
typedef struct ValidateIndexState typedef struct ValidateIndexState
{ {
......
...@@ -14,11 +14,19 @@ ...@@ -14,11 +14,19 @@
#define CLUSTER_H #define CLUSTER_H
#include "nodes/parsenodes.h" #include "nodes/parsenodes.h"
#include "parser/parse_node.h"
#include "storage/lock.h" #include "storage/lock.h"
#include "utils/relcache.h" #include "utils/relcache.h"
extern void cluster(ClusterStmt *stmt, bool isTopLevel); /* options for CLUSTER */
typedef enum ClusterOption
{
CLUOPT_RECHECK = 1 << 0, /* recheck relation state */
CLUOPT_VERBOSE = 1 << 1 /* print progress info */
} ClusterOption;
extern void cluster(ParseState *pstate, ClusterStmt *stmt, bool isTopLevel);
extern void cluster_rel(Oid tableOid, Oid indexOid, int options); extern void cluster_rel(Oid tableOid, Oid indexOid, int options);
extern void check_index_is_clusterable(Relation OldHeap, Oid indexOid, extern void check_index_is_clusterable(Relation OldHeap, Oid indexOid,
bool recheck, LOCKMODE lockmode); bool recheck, LOCKMODE lockmode);
......
...@@ -34,6 +34,7 @@ extern ObjectAddress DefineIndex(Oid relationId, ...@@ -34,6 +34,7 @@ extern ObjectAddress DefineIndex(Oid relationId,
bool check_not_in_use, bool check_not_in_use,
bool skip_build, bool skip_build,
bool quiet); bool quiet);
extern int ReindexParseOptions(ParseState *pstate, ReindexStmt *stmt);
extern void ReindexIndex(RangeVar *indexRelation, int options, bool isTopLevel); extern void ReindexIndex(RangeVar *indexRelation, int options, bool isTopLevel);
extern Oid ReindexTable(RangeVar *relation, int options, bool isTopLevel); extern Oid ReindexTable(RangeVar *relation, int options, bool isTopLevel);
extern void ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind, extern void ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind,
......
...@@ -3197,18 +3197,12 @@ typedef struct AlterSystemStmt ...@@ -3197,18 +3197,12 @@ typedef struct AlterSystemStmt
* Cluster Statement (support pbrown's cluster index implementation) * Cluster Statement (support pbrown's cluster index implementation)
* ---------------------- * ----------------------
*/ */
typedef enum ClusterOption
{
CLUOPT_RECHECK = 1 << 0, /* recheck relation state */
CLUOPT_VERBOSE = 1 << 1 /* print progress info */
} ClusterOption;
typedef struct ClusterStmt typedef struct ClusterStmt
{ {
NodeTag type; NodeTag type;
RangeVar *relation; /* relation being indexed, or NULL if all */ RangeVar *relation; /* relation being indexed, or NULL if all */
char *indexname; /* original index defined */ char *indexname; /* original index defined */
int options; /* OR of ClusterOption flags */ List *params; /* list of DefElem nodes */
} ClusterStmt; } ClusterStmt;
/* ---------------------- /* ----------------------
...@@ -3346,13 +3340,6 @@ typedef struct ConstraintsSetStmt ...@@ -3346,13 +3340,6 @@ typedef struct ConstraintsSetStmt
* REINDEX Statement * REINDEX Statement
* ---------------------- * ----------------------
*/ */
/* Reindex options */
#define REINDEXOPT_VERBOSE (1 << 0) /* print progress info */
#define REINDEXOPT_REPORT_PROGRESS (1 << 1) /* report pgstat progress */
#define REINDEXOPT_MISSING_OK (1 << 2) /* skip missing relations */
#define REINDEXOPT_CONCURRENTLY (1 << 3) /* concurrent mode */
typedef enum ReindexObjectType typedef enum ReindexObjectType
{ {
REINDEX_OBJECT_INDEX, /* index */ REINDEX_OBJECT_INDEX, /* index */
...@@ -3369,7 +3356,7 @@ typedef struct ReindexStmt ...@@ -3369,7 +3356,7 @@ typedef struct ReindexStmt
* etc. */ * etc. */
RangeVar *relation; /* Table or index to reindex */ RangeVar *relation; /* Table or index to reindex */
const char *name; /* name of database to reindex */ const char *name; /* name of database to reindex */
int options; /* Reindex options flags */ List *params; /* list of DefElem nodes */
} ReindexStmt; } ReindexStmt;
/* ---------------------- /* ----------------------
......
...@@ -2024,7 +2024,7 @@ CREATE TABLE concur_reindex_tab (c1 int); ...@@ -2024,7 +2024,7 @@ CREATE TABLE concur_reindex_tab (c1 int);
-- REINDEX -- REINDEX
REINDEX TABLE concur_reindex_tab; -- notice REINDEX TABLE concur_reindex_tab; -- notice
NOTICE: table "concur_reindex_tab" has no indexes to reindex NOTICE: table "concur_reindex_tab" has no indexes to reindex
REINDEX TABLE CONCURRENTLY concur_reindex_tab; -- notice REINDEX (CONCURRENTLY) TABLE concur_reindex_tab; -- notice
NOTICE: table "concur_reindex_tab" has no indexes that can be reindexed concurrently NOTICE: table "concur_reindex_tab" has no indexes that can be reindexed concurrently
ALTER TABLE concur_reindex_tab ADD COLUMN c2 text; -- add toast index ALTER TABLE concur_reindex_tab ADD COLUMN c2 text; -- add toast index
-- Normal index with integer column -- Normal index with integer column
......
...@@ -796,7 +796,7 @@ DROP TABLE reindex_verbose; ...@@ -796,7 +796,7 @@ DROP TABLE reindex_verbose;
CREATE TABLE concur_reindex_tab (c1 int); CREATE TABLE concur_reindex_tab (c1 int);
-- REINDEX -- REINDEX
REINDEX TABLE concur_reindex_tab; -- notice REINDEX TABLE concur_reindex_tab; -- notice
REINDEX TABLE CONCURRENTLY concur_reindex_tab; -- notice REINDEX (CONCURRENTLY) TABLE concur_reindex_tab; -- notice
ALTER TABLE concur_reindex_tab ADD COLUMN c2 text; -- add toast index ALTER TABLE concur_reindex_tab ADD COLUMN c2 text; -- add toast index
-- Normal index with integer column -- Normal index with integer column
CREATE UNIQUE INDEX concur_reindex_ind1 ON concur_reindex_tab(c1); CREATE UNIQUE INDEX concur_reindex_ind1 ON concur_reindex_tab(c1);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment