On 2021-01-13 14:34, Michael Paquier wrote:
On Wed, Jan 13, 2021 at 05:22:49PM +0900, Michael Paquier wrote:
Yeah, that makes sense. I'll send an updated patch based on that.
And here you go as per the attached. I don't think that there was
anything remaining on my radar. This version still needs to be
indented properly though.
Thoughts?
Thanks.
+ bits32 options; /* bitmask of
CLUSTEROPT_* */
This should say '/* bitmask of CLUOPT_* */', I guess, since there are
only CLUOPT's defined. Otherwise, everything looks as per discussed
upthread.
By the way, something went wrong with the last email subject, so I have
changed it back to the original in this response. I also attached your
patch (with only this CLUOPT_* correction) to keep it in the thread for
sure. Although, postgresql.org's web archive is clever enough to link
your email to the same thread even with different subject.
Regards
--
Alexey Kondratov
Postgres Professional https://www.postgrespro.com
Russian Postgres Company
diff --git a/src/include/catalog/index.h b/src/include/catalog/index.h
index 9904a76387..43cfdeaa6b 100644
--- a/src/include/catalog/index.h
+++ b/src/include/catalog/index.h
@@ -30,13 +30,16 @@ typedef enum
} IndexStateFlagsAction;
/* options for REINDEX */
-typedef enum ReindexOption
+typedef struct ReindexParams
{
- 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;
+ bits32 options; /* bitmask of REINDEXOPT_* */
+} ReindexParams;
+
+/* flag bits for ReindexParams->flags */
+#define REINDEXOPT_VERBOSE 0x01 /* print progress info */
+#define REINDEXOPT_REPORT_PROGRESS 0x02 /* report pgstat progress */
+#define REINDEXOPT_MISSING_OK 0x04 /* skip missing relations */
+#define REINDEXOPT_CONCURRENTLY 0x08 /* concurrent mode */
/* state info for validate_index bulkdelete callback */
typedef struct ValidateIndexState
@@ -146,7 +149,7 @@ extern void index_set_state_flags(Oid indexId, IndexStateFlagsAction action);
extern Oid IndexGetRelation(Oid indexId, bool missing_ok);
extern void reindex_index(Oid indexId, bool skip_constraint_checks,
- char relpersistence, int options);
+ char relpersistence, ReindexParams *params);
/* Flag bits for reindex_relation(): */
#define REINDEX_REL_PROCESS_TOAST 0x01
@@ -155,7 +158,7 @@ extern void reindex_index(Oid indexId, bool skip_constraint_checks,
#define REINDEX_REL_FORCE_INDEXES_UNLOGGED 0x08
#define REINDEX_REL_FORCE_INDEXES_PERMANENT 0x10
-extern bool reindex_relation(Oid relid, int flags, int options);
+extern bool reindex_relation(Oid relid, int flags, ReindexParams *params);
extern bool ReindexIsProcessingHeap(Oid heapOid);
extern bool ReindexIsProcessingIndex(Oid indexOid);
diff --git a/src/include/commands/cluster.h b/src/include/commands/cluster.h
index 401a0827ae..1245d944dc 100644
--- a/src/include/commands/cluster.h
+++ b/src/include/commands/cluster.h
@@ -18,16 +18,17 @@
#include "storage/lock.h"
#include "utils/relcache.h"
-
/* options for CLUSTER */
-typedef enum ClusterOption
+#define CLUOPT_RECHECK 0x01 /* recheck relation state */
+#define CLUOPT_VERBOSE 0x02 /* print progress info */
+
+typedef struct ClusterParams
{
- CLUOPT_RECHECK = 1 << 0, /* recheck relation state */
- CLUOPT_VERBOSE = 1 << 1 /* print progress info */
-} ClusterOption;
+ bits32 options; /* bitmask of CLUOPT_* */
+} ClusterParams;
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, ClusterParams *params);
extern void check_index_is_clusterable(Relation OldHeap, Oid indexOid,
bool recheck, LOCKMODE lockmode);
extern void mark_index_clustered(Relation rel, Oid indexOid, bool is_internal);
diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h
index e2d2a77ca4..91281d6f8e 100644
--- a/src/include/commands/defrem.h
+++ b/src/include/commands/defrem.h
@@ -14,6 +14,7 @@
#ifndef DEFREM_H
#define DEFREM_H
+#include "catalog/index.h"
#include "catalog/objectaddress.h"
#include "nodes/params.h"
#include "parser/parse_node.h"
@@ -34,11 +35,7 @@ extern ObjectAddress DefineIndex(Oid relationId,
bool check_not_in_use,
bool skip_build,
bool quiet);
-extern int ReindexParseOptions(ParseState *pstate, ReindexStmt *stmt);
-extern void ReindexIndex(RangeVar *indexRelation, int options, bool isTopLevel);
-extern Oid ReindexTable(RangeVar *relation, int options, bool isTopLevel);
-extern void ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind,
- int options);
+extern void ExecReindex(ParseState *pstate, ReindexStmt *stmt, bool isTopLevel);
extern char *makeObjectName(const char *name1, const char *name2,
const char *label);
extern char *ChooseRelationName(const char *name1, const char *name2,
diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h
index 857509287d..191cbbd004 100644
--- a/src/include/commands/vacuum.h
+++ b/src/include/commands/vacuum.h
@@ -174,17 +174,15 @@ typedef struct VacAttrStats
int rowstride;
} VacAttrStats;
-typedef enum VacuumOption
-{
- VACOPT_VACUUM = 1 << 0, /* do VACUUM */
- VACOPT_ANALYZE = 1 << 1, /* do ANALYZE */
- VACOPT_VERBOSE = 1 << 2, /* print progress info */
- VACOPT_FREEZE = 1 << 3, /* FREEZE option */
- VACOPT_FULL = 1 << 4, /* FULL (non-concurrent) vacuum */
- VACOPT_SKIP_LOCKED = 1 << 5, /* skip if cannot get lock */
- VACOPT_SKIPTOAST = 1 << 6, /* don't process the TOAST table, if any */
- VACOPT_DISABLE_PAGE_SKIPPING = 1 << 7 /* don't skip any pages */
-} VacuumOption;
+/* flag bits for VacuumParams->options */
+#define VACOPT_VACUUM 0x01 /* do VACUUM */
+#define VACOPT_ANALYZE 0x02 /* do ANALYZE */
+#define VACOPT_VERBOSE 0x04 /* print progress info */
+#define VACOPT_FREEZE 0x08 /* FREEZE option */
+#define VACOPT_FULL 0x10 /* FULL (non-concurrent) vacuum */
+#define VACOPT_SKIP_LOCKED 0x20 /* skip if cannot get lock */
+#define VACOPT_SKIPTOAST 0x40 /* don't process the TOAST table, if any */
+#define VACOPT_DISABLE_PAGE_SKIPPING 0x80 /* don't skip any pages */
/*
* A ternary value used by vacuum parameters.
@@ -207,7 +205,7 @@ typedef enum VacOptTernaryValue
*/
typedef struct VacuumParams
{
- int options; /* bitmask of VacuumOption */
+ bits32 options; /* bitmask of VACOPT_* */
int freeze_min_age; /* min freeze age, -1 to use default */
int freeze_table_age; /* age at which to scan whole table */
int multixact_freeze_min_age; /* min multixact freeze age, -1 to
@@ -275,9 +273,10 @@ extern void vacuum_set_xid_limits(Relation rel,
extern void vac_update_datfrozenxid(void);
extern void vacuum_delay_point(void);
extern bool vacuum_is_relation_owner(Oid relid, Form_pg_class reltuple,
- int options);
+ bits32 options);
extern Relation vacuum_open_relation(Oid relid, RangeVar *relation,
- int options, bool verbose, LOCKMODE lmode);
+ bits32 options, bool verbose,
+ LOCKMODE lmode);
/* in commands/analyze.c */
extern void analyze_rel(Oid relid, RangeVar *relation,
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index cffbc0ac38..9d2be3d8da 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3594,7 +3594,7 @@ IndexGetRelation(Oid indexId, bool missing_ok)
*/
void
reindex_index(Oid indexId, bool skip_constraint_checks, char persistence,
- int options)
+ ReindexParams *params)
{
Relation iRel,
heapRelation;
@@ -3602,7 +3602,7 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence,
IndexInfo *indexInfo;
volatile bool skipped_constraint = false;
PGRUsage ru0;
- bool progress = (options & REINDEXOPT_REPORT_PROGRESS) != 0;
+ bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0);
pg_rusage_init(&ru0);
@@ -3611,12 +3611,12 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence,
* we only need to be sure no schema or data changes are going on.
*/
heapId = IndexGetRelation(indexId,
- (options & REINDEXOPT_MISSING_OK) != 0);
+ (params->options & REINDEXOPT_MISSING_OK) != 0);
/* if relation is missing, leave */
if (!OidIsValid(heapId))
return;
- if ((options & REINDEXOPT_MISSING_OK) != 0)
+ if ((params->options & REINDEXOPT_MISSING_OK) != 0)
heapRelation = try_table_open(heapId, ShareLock);
else
heapRelation = table_open(heapId, ShareLock);
@@ -3792,7 +3792,7 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence,
}
/* Log what we did */
- if (options & REINDEXOPT_VERBOSE)
+ if ((params->options & REINDEXOPT_VERBOSE) != 0)
ereport(INFO,
(errmsg("index \"%s\" was reindexed",
get_rel_name(indexId)),
@@ -3846,7 +3846,7 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence,
* index rebuild.
*/
bool
-reindex_relation(Oid relid, int flags, int options)
+reindex_relation(Oid relid, int flags, ReindexParams *params)
{
Relation rel;
Oid toast_relid;
@@ -3861,7 +3861,7 @@ reindex_relation(Oid relid, int flags, int options)
* to prevent schema and data changes in it. The lock level used here
* should match ReindexTable().
*/
- if ((options & REINDEXOPT_MISSING_OK) != 0)
+ if ((params->options & REINDEXOPT_MISSING_OK) != 0)
rel = try_table_open(relid, ShareLock);
else
rel = table_open(relid, ShareLock);
@@ -3935,7 +3935,7 @@ reindex_relation(Oid relid, int flags, int options)
}
reindex_index(indexOid, !(flags & REINDEX_REL_CHECK_CONSTRAINTS),
- persistence, options);
+ persistence, params);
CommandCounterIncrement();
@@ -3965,8 +3965,9 @@ reindex_relation(Oid relid, int flags, int options)
* Note that this should fail if the toast relation is missing, so
* reset REINDEXOPT_MISSING_OK.
*/
- result |= reindex_relation(toast_relid, flags,
- options & ~(REINDEXOPT_MISSING_OK));
+ ReindexParams newparams = *params;
+ newparams.options &= ~(REINDEXOPT_MISSING_OK);
+ result |= reindex_relation(toast_relid, flags, &newparams);
}
return result;
diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c
index d5eeb493ac..096a06f7b3 100644
--- a/src/backend/commands/cluster.c
+++ b/src/backend/commands/cluster.c
@@ -103,7 +103,7 @@ void
cluster(ParseState *pstate, ClusterStmt *stmt, bool isTopLevel)
{
ListCell *lc;
- int options = 0;
+ ClusterParams params = {0};
bool verbose = false;
/* Parse option list */
@@ -121,7 +121,7 @@ cluster(ParseState *pstate, ClusterStmt *stmt, bool isTopLevel)
parser_errposition(pstate, opt->location)));
}
- options = (verbose ? CLUOPT_VERBOSE : 0);
+ params.options = (verbose ? CLUOPT_VERBOSE : 0);
if (stmt->relation != NULL)
{
@@ -192,7 +192,7 @@ cluster(ParseState *pstate, ClusterStmt *stmt, bool isTopLevel)
table_close(rel, NoLock);
/* Do the job. */
- cluster_rel(tableOid, indexOid, options);
+ cluster_rel(tableOid, indexOid, ¶ms);
}
else
{
@@ -234,14 +234,16 @@ cluster(ParseState *pstate, ClusterStmt *stmt, bool isTopLevel)
foreach(rv, rvs)
{
RelToCluster *rvtc = (RelToCluster *) lfirst(rv);
+ ClusterParams cluster_params = params;
/* Start a new transaction for each relation. */
StartTransactionCommand();
/* functions in indexes may want a snapshot set */
PushActiveSnapshot(GetTransactionSnapshot());
/* Do the job. */
+ cluster_params.options |= CLUOPT_RECHECK;
cluster_rel(rvtc->tableOid, rvtc->indexOid,
- options | CLUOPT_RECHECK);
+ &cluster_params);
PopActiveSnapshot();
CommitTransactionCommand();
}
@@ -272,11 +274,11 @@ cluster(ParseState *pstate, ClusterStmt *stmt, bool isTopLevel)
* and error messages should refer to the operation as VACUUM not CLUSTER.
*/
void
-cluster_rel(Oid tableOid, Oid indexOid, int options)
+cluster_rel(Oid tableOid, Oid indexOid, ClusterParams *params)
{
Relation OldHeap;
- bool verbose = ((options & CLUOPT_VERBOSE) != 0);
- bool recheck = ((options & CLUOPT_RECHECK) != 0);
+ bool verbose = ((params->options & CLUOPT_VERBOSE) != 0);
+ bool recheck = ((params->options & CLUOPT_RECHECK) != 0);
/* Check for user-requested abort. */
CHECK_FOR_INTERRUPTS();
@@ -1355,6 +1357,7 @@ finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap,
ObjectAddress object;
Oid mapped_tables[4];
int reindex_flags;
+ ReindexParams reindex_params = {0};
int i;
/* Report that we are now swapping relation files */
@@ -1412,7 +1415,7 @@ finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap,
pgstat_progress_update_param(PROGRESS_CLUSTER_PHASE,
PROGRESS_CLUSTER_PHASE_REBUILD_INDEX);
- reindex_relation(OIDOldHeap, reindex_flags, 0);
+ reindex_relation(OIDOldHeap, reindex_flags, &reindex_params);
/* Report that we are now doing clean up */
pgstat_progress_update_param(PROGRESS_CLUSTER_PHASE,
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index 8c9c39a467..f691c34c2e 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -86,12 +86,21 @@ static char *ChooseIndexName(const char *tabname, Oid namespaceId,
bool primary, bool isconstraint);
static char *ChooseIndexNameAddition(List *colnames);
static List *ChooseIndexColumnNames(List *indexElems);
+static void ReindexIndex(RangeVar *indexRelation, ReindexParams *params,
+ bool isTopLevel);
static void RangeVarCallbackForReindexIndex(const RangeVar *relation,
Oid relId, Oid oldRelId, void *arg);
+static Oid ReindexTable(RangeVar *relation, ReindexParams *params,
+ bool isTopLevel);
+static void ReindexMultipleTables(const char *objectName,
+ ReindexObjectType objectKind, ReindexParams *params);
static void reindex_error_callback(void *args);
-static void ReindexPartitions(Oid relid, int options, bool isTopLevel);
-static void ReindexMultipleInternal(List *relids, int options);
-static bool ReindexRelationConcurrently(Oid relationOid, int options);
+static void ReindexPartitions(Oid relid, ReindexParams *params,
+ bool isTopLevel);
+static void ReindexMultipleInternal(List *relids,
+ ReindexParams *params);
+static bool ReindexRelationConcurrently(Oid relationOid,
+ ReindexParams *params);
static void update_relispartition(Oid relationId, bool newval);
static inline void set_indexsafe_procflags(void);
@@ -100,7 +109,7 @@ static inline void set_indexsafe_procflags(void);
*/
struct ReindexIndexCallbackState
{
- int options; /* options from statement */
+ ReindexParams params; /* options from statement */
Oid locked_table_oid; /* tracks previously locked table */
};
@@ -2452,14 +2461,17 @@ ChooseIndexColumnNames(List *indexElems)
}
/*
- * ReindexParseOptions
- * Parse list of REINDEX options, returning a bitmask of ReindexOption.
+ * ExecReindex
+ *
+ * Primary entry point for manual REINDEX commands. This is mainly a
+ * preparation wrapper for the real operations that will happen in
+ * each reindex sub-routine.
*/
-int
-ReindexParseOptions(ParseState *pstate, ReindexStmt *stmt)
+void
+ExecReindex(ParseState *pstate, ReindexStmt *stmt, bool isTopLevel)
{
+ ReindexParams params = {0};
ListCell *lc;
- int options = 0;
bool concurrently = false;
bool verbose = false;
@@ -2480,19 +2492,51 @@ ReindexParseOptions(ParseState *pstate, ReindexStmt *stmt)
parser_errposition(pstate, opt->location)));
}
- options =
+ if (concurrently)
+ PreventInTransactionBlock(isTopLevel,
+ "REINDEX CONCURRENTLY");
+
+ params.options =
(verbose ? REINDEXOPT_VERBOSE : 0) |
(concurrently ? REINDEXOPT_CONCURRENTLY : 0);
- return options;
+ switch (stmt->kind)
+ {
+ case REINDEX_OBJECT_INDEX:
+ ReindexIndex(stmt->relation, ¶ms, isTopLevel);
+ break;
+ case REINDEX_OBJECT_TABLE:
+ ReindexTable(stmt->relation, ¶ms, isTopLevel);
+ break;
+ case REINDEX_OBJECT_SCHEMA:
+ case REINDEX_OBJECT_SYSTEM:
+ case REINDEX_OBJECT_DATABASE:
+
+ /*
+ * This cannot run inside a user transaction block; if
+ * we were inside a transaction, then its commit- and
+ * start-transaction-command calls would not have the
+ * intended effect!
+ */
+ PreventInTransactionBlock(isTopLevel,
+ (stmt->kind == REINDEX_OBJECT_SCHEMA) ? "REINDEX SCHEMA" :
+ (stmt->kind == REINDEX_OBJECT_SYSTEM) ? "REINDEX SYSTEM" :
+ "REINDEX DATABASE");
+ ReindexMultipleTables(stmt->name, stmt->kind, ¶ms);
+ break;
+ default:
+ elog(ERROR, "unrecognized object type: %d",
+ (int) stmt->kind);
+ break;
+ }
}
/*
* ReindexIndex
* Recreate a specific index.
*/
-void
-ReindexIndex(RangeVar *indexRelation, int options, bool isTopLevel)
+static void
+ReindexIndex(RangeVar *indexRelation, ReindexParams *params, bool isTopLevel)
{
struct ReindexIndexCallbackState state;
Oid indOid;
@@ -2509,10 +2553,10 @@ ReindexIndex(RangeVar *indexRelation, int options, bool isTopLevel)
* upgrade the lock, but that's OK, because other sessions can't hold
* locks on our temporary table.
*/
- state.options = options;
+ state.params = *params;
state.locked_table_oid = InvalidOid;
indOid = RangeVarGetRelidExtended(indexRelation,
- (options & REINDEXOPT_CONCURRENTLY) != 0 ?
+ (params->options & REINDEXOPT_CONCURRENTLY) != 0 ?
ShareUpdateExclusiveLock : AccessExclusiveLock,
0,
RangeVarCallbackForReindexIndex,
@@ -2526,13 +2570,17 @@ ReindexIndex(RangeVar *indexRelation, int options, bool isTopLevel)
relkind = get_rel_relkind(indOid);
if (relkind == RELKIND_PARTITIONED_INDEX)
- ReindexPartitions(indOid, options, isTopLevel);
- else if ((options & REINDEXOPT_CONCURRENTLY) != 0 &&
+ ReindexPartitions(indOid, params, isTopLevel);
+ else if ((params->options & REINDEXOPT_CONCURRENTLY) != 0 &&
persistence != RELPERSISTENCE_TEMP)
- ReindexRelationConcurrently(indOid, options);
+ ReindexRelationConcurrently(indOid, params);
else
- reindex_index(indOid, false, persistence,
- options | REINDEXOPT_REPORT_PROGRESS);
+ {
+ ReindexParams newparams = *params;
+
+ newparams.options |= REINDEXOPT_REPORT_PROGRESS;
+ reindex_index(indOid, false, persistence, &newparams);
+ }
}
/*
@@ -2553,7 +2601,7 @@ RangeVarCallbackForReindexIndex(const RangeVar *relation,
* non-concurrent case and table locks used by index_concurrently_*() for
* concurrent case.
*/
- table_lockmode = ((state->options & REINDEXOPT_CONCURRENTLY) != 0) ?
+ table_lockmode = (state->params.options & REINDEXOPT_CONCURRENTLY) != 0 ?
ShareUpdateExclusiveLock : ShareLock;
/*
@@ -2610,8 +2658,8 @@ RangeVarCallbackForReindexIndex(const RangeVar *relation,
* ReindexTable
* Recreate all indexes of a table (and of its toast table, if any)
*/
-Oid
-ReindexTable(RangeVar *relation, int options, bool isTopLevel)
+static Oid
+ReindexTable(RangeVar *relation, ReindexParams *params, bool isTopLevel)
{
Oid heapOid;
bool result;
@@ -2625,17 +2673,17 @@ ReindexTable(RangeVar *relation, int options, bool isTopLevel)
* locks on our temporary table.
*/
heapOid = RangeVarGetRelidExtended(relation,
- (options & REINDEXOPT_CONCURRENTLY) != 0 ?
+ (params->options & REINDEXOPT_CONCURRENTLY) != 0 ?
ShareUpdateExclusiveLock : ShareLock,
0,
RangeVarCallbackOwnsTable, NULL);
if (get_rel_relkind(heapOid) == RELKIND_PARTITIONED_TABLE)
- ReindexPartitions(heapOid, options, isTopLevel);
- else if ((options & REINDEXOPT_CONCURRENTLY) != 0 &&
+ ReindexPartitions(heapOid, params, isTopLevel);
+ else if ((params->options & REINDEXOPT_CONCURRENTLY) != 0 &&
get_rel_persistence(heapOid) != RELPERSISTENCE_TEMP)
{
- result = ReindexRelationConcurrently(heapOid, options);
+ result = ReindexRelationConcurrently(heapOid, params);
if (!result)
ereport(NOTICE,
@@ -2644,10 +2692,13 @@ ReindexTable(RangeVar *relation, int options, bool isTopLevel)
}
else
{
+ ReindexParams newparams = *params;
+
+ newparams.options |= REINDEXOPT_REPORT_PROGRESS;
result = reindex_relation(heapOid,
REINDEX_REL_PROCESS_TOAST |
REINDEX_REL_CHECK_CONSTRAINTS,
- options | REINDEXOPT_REPORT_PROGRESS);
+ &newparams);
if (!result)
ereport(NOTICE,
(errmsg("table \"%s\" has no indexes to reindex",
@@ -2665,9 +2716,9 @@ ReindexTable(RangeVar *relation, int options, bool isTopLevel)
* separate transaction, so we can release the lock on it right away.
* That means this must not be called within a user transaction block!
*/
-void
+static void
ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind,
- int options)
+ ReindexParams *params)
{
Oid objectOid;
Relation relationRelation;
@@ -2686,7 +2737,7 @@ ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind,
objectKind == REINDEX_OBJECT_DATABASE);
if (objectKind == REINDEX_OBJECT_SYSTEM &&
- (options & REINDEXOPT_CONCURRENTLY) != 0)
+ (params->options & REINDEXOPT_CONCURRENTLY) != 0)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("cannot reindex system catalogs concurrently")));
@@ -2794,7 +2845,7 @@ ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind,
* Skip system tables, since index_create() would reject indexing them
* concurrently (and it would likely fail if we tried).
*/
- if ((options & REINDEXOPT_CONCURRENTLY) != 0 &&
+ if ((params->options & REINDEXOPT_CONCURRENTLY) != 0 &&
IsCatalogRelationOid(relid))
{
if (!concurrent_warning)
@@ -2829,7 +2880,7 @@ ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind,
* Process each relation listed in a separate transaction. Note that this
* commits and then starts a new transaction immediately.
*/
- ReindexMultipleInternal(relids, options);
+ ReindexMultipleInternal(relids, params);
MemoryContextDelete(private_context);
}
@@ -2860,7 +2911,7 @@ reindex_error_callback(void *arg)
* by the caller.
*/
static void
-ReindexPartitions(Oid relid, int options, bool isTopLevel)
+ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
{
List *partitions = NIL;
char relkind = get_rel_relkind(relid);
@@ -2937,7 +2988,7 @@ ReindexPartitions(Oid relid, int options, bool isTopLevel)
* Process each partition listed in a separate transaction. Note that
* this commits and then starts a new transaction immediately.
*/
- ReindexMultipleInternal(partitions, options);
+ ReindexMultipleInternal(partitions, params);
/*
* Clean up working storage --- note we must do this after
@@ -2955,7 +3006,7 @@ ReindexPartitions(Oid relid, int options, bool isTopLevel)
* and starts a new transaction when finished.
*/
static void
-ReindexMultipleInternal(List *relids, int options)
+ReindexMultipleInternal(List *relids, ReindexParams *params)
{
ListCell *l;
@@ -2991,35 +3042,37 @@ ReindexMultipleInternal(List *relids, int options)
Assert(relkind != RELKIND_PARTITIONED_INDEX &&
relkind != RELKIND_PARTITIONED_TABLE);
- if ((options & REINDEXOPT_CONCURRENTLY) != 0 &&
+ if ((params->options & REINDEXOPT_CONCURRENTLY) != 0 &&
relpersistence != RELPERSISTENCE_TEMP)
{
- (void) ReindexRelationConcurrently(relid,
- options |
- REINDEXOPT_MISSING_OK);
+ ReindexParams newparams = *params;
+
+ newparams.options |= REINDEXOPT_MISSING_OK;
+ (void) ReindexRelationConcurrently(relid, &newparams);
/* ReindexRelationConcurrently() does the verbose output */
}
else if (relkind == RELKIND_INDEX)
{
- reindex_index(relid, false, relpersistence,
- options |
- REINDEXOPT_REPORT_PROGRESS |
- REINDEXOPT_MISSING_OK);
+ ReindexParams newparams = *params;
+
+ newparams.options |=
+ REINDEXOPT_REPORT_PROGRESS | REINDEXOPT_MISSING_OK;
+ reindex_index(relid, false, relpersistence, &newparams);
PopActiveSnapshot();
/* reindex_index() does the verbose output */
}
else
{
bool result;
-
+ ReindexParams newparams = *params;
+ newparams.options |=
+ REINDEXOPT_REPORT_PROGRESS | REINDEXOPT_MISSING_OK;
result = reindex_relation(relid,
REINDEX_REL_PROCESS_TOAST |
REINDEX_REL_CHECK_CONSTRAINTS,
- options |
- REINDEXOPT_REPORT_PROGRESS |
- REINDEXOPT_MISSING_OK);
+ &newparams);
- if (result && (options & REINDEXOPT_VERBOSE))
+ if (result && (params->options & REINDEXOPT_VERBOSE) != 0)
ereport(INFO,
(errmsg("table \"%s.%s\" was reindexed",
get_namespace_name(get_rel_namespace(relid)),
@@ -3059,7 +3112,7 @@ ReindexMultipleInternal(List *relids, int options)
* anyway, and a non-concurrent reindex is more efficient.
*/
static bool
-ReindexRelationConcurrently(Oid relationOid, int options)
+ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
{
typedef struct ReindexIndexInfo
{
@@ -3098,7 +3151,7 @@ ReindexRelationConcurrently(Oid relationOid, int options)
"ReindexConcurrent",
ALLOCSET_SMALL_SIZES);
- if (options & REINDEXOPT_VERBOSE)
+ if ((params->options & REINDEXOPT_VERBOSE) != 0)
{
/* Save data needed by REINDEX VERBOSE in private context */
oldcontext = MemoryContextSwitchTo(private_context);
@@ -3143,7 +3196,7 @@ ReindexRelationConcurrently(Oid relationOid, int options)
errmsg("cannot reindex system catalogs concurrently")));
/* Open relation to get its indexes */
- if ((options & REINDEXOPT_MISSING_OK) != 0)
+ if ((params->options & REINDEXOPT_MISSING_OK) != 0)
{
heapRelation = try_table_open(relationOid,
ShareUpdateExclusiveLock);
@@ -3250,7 +3303,7 @@ ReindexRelationConcurrently(Oid relationOid, int options)
case RELKIND_INDEX:
{
Oid heapId = IndexGetRelation(relationOid,
- (options & REINDEXOPT_MISSING_OK) != 0);
+ (params->options & REINDEXOPT_MISSING_OK) != 0);
Relation heapRelation;
ReindexIndexInfo *idx;
@@ -3280,7 +3333,7 @@ ReindexRelationConcurrently(Oid relationOid, int options)
* to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
* should not be used once all the session locks are taken.
*/
- if ((options & REINDEXOPT_MISSING_OK) != 0)
+ if ((params->options & REINDEXOPT_MISSING_OK) != 0)
{
heapRelation = try_table_open(heapId,
ShareUpdateExclusiveLock);
@@ -3757,7 +3810,7 @@ ReindexRelationConcurrently(Oid relationOid, int options)
StartTransactionCommand();
/* Log what we did */
- if (options & REINDEXOPT_VERBOSE)
+ if ((params->options & REINDEXOPT_VERBOSE) != 0)
{
if (relkind == RELKIND_INDEX)
ereport(INFO,
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 993da56d43..d79d1faa82 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -1854,6 +1854,7 @@ ExecuteTruncateGuts(List *explicit_rels, List *relids, List *relids_logged,
{
Oid heap_relid;
Oid toast_relid;
+ ReindexParams reindex_params = {0};
/*
* This effectively deletes all rows in the table, and may be done
@@ -1891,7 +1892,8 @@ ExecuteTruncateGuts(List *explicit_rels, List *relids, List *relids_logged,
/*
* Reconstruct the indexes to match, and we're done.
*/
- reindex_relation(heap_relid, REINDEX_REL_PROCESS_TOAST, 0);
+ reindex_relation(heap_relid, REINDEX_REL_PROCESS_TOAST,
+ &reindex_params);
}
pgstat_count_truncate(rel);
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index b97d48ee01..462f9a0f82 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -530,7 +530,7 @@ vacuum(List *relations, VacuumParams *params,
* ANALYZE.
*/
bool
-vacuum_is_relation_owner(Oid relid, Form_pg_class reltuple, int options)
+vacuum_is_relation_owner(Oid relid, Form_pg_class reltuple, bits32 options)
{
char *relname;
@@ -604,7 +604,7 @@ vacuum_is_relation_owner(Oid relid, Form_pg_class reltuple, int options)
* or locked, a log is emitted if possible.
*/
Relation
-vacuum_open_relation(Oid relid, RangeVar *relation, int options,
+vacuum_open_relation(Oid relid, RangeVar *relation, bits32 options,
bool verbose, LOCKMODE lmode)
{
Relation onerel;
@@ -1916,17 +1916,17 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params)
*/
if (params->options & VACOPT_FULL)
{
- int cluster_options = 0;
+ ClusterParams cluster_params = {0};
/* close relation before vacuuming, but hold lock until commit */
relation_close(onerel, NoLock);
onerel = NULL;
if ((params->options & VACOPT_VERBOSE) != 0)
- cluster_options |= CLUOPT_VERBOSE;
+ cluster_params.options |= CLUOPT_VERBOSE;
/* VACUUM FULL is now a variant of CLUSTER; see cluster.c */
- cluster_rel(relid, InvalidOid, cluster_options);
+ cluster_rel(relid, InvalidOid, &cluster_params);
}
else
table_relation_vacuum(onerel, params, vac_strategy);
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 53a511f1da..1d81071c35 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -917,45 +917,7 @@ standard_ProcessUtility(PlannedStmt *pstmt,
break;
case T_ReindexStmt:
- {
- ReindexStmt *stmt = (ReindexStmt *) parsetree;
- int options;
-
- options = ReindexParseOptions(pstate, stmt);
- if ((options & REINDEXOPT_CONCURRENTLY) != 0)
- PreventInTransactionBlock(isTopLevel,
- "REINDEX CONCURRENTLY");
-
- switch (stmt->kind)
- {
- case REINDEX_OBJECT_INDEX:
- ReindexIndex(stmt->relation, options, isTopLevel);
- break;
- case REINDEX_OBJECT_TABLE:
- ReindexTable(stmt->relation, options, isTopLevel);
- break;
- case REINDEX_OBJECT_SCHEMA:
- case REINDEX_OBJECT_SYSTEM:
- case REINDEX_OBJECT_DATABASE:
-
- /*
- * This cannot run inside a user transaction block; if
- * we were inside a transaction, then its commit- and
- * start-transaction-command calls would not have the
- * intended effect!
- */
- PreventInTransactionBlock(isTopLevel,
- (stmt->kind == REINDEX_OBJECT_SCHEMA) ? "REINDEX SCHEMA" :
- (stmt->kind == REINDEX_OBJECT_SYSTEM) ? "REINDEX SYSTEM" :
- "REINDEX DATABASE");
- ReindexMultipleTables(stmt->name, stmt->kind, options);
- break;
- default:
- elog(ERROR, "unrecognized object type: %d",
- (int) stmt->kind);
- break;
- }
- }
+ ExecReindex(pstate, (ReindexStmt *) parsetree, isTopLevel);
break;
/*
diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list
index fb57b8393f..943142ced8 100644
--- a/src/tools/pgindent/typedefs.list
+++ b/src/tools/pgindent/typedefs.list
@@ -347,6 +347,7 @@ ClosePortalStmt
ClosePtrType
Clump
ClusterInfo
+ClusterParams
ClusterStmt
CmdType
CoalesceExpr
@@ -2063,6 +2064,7 @@ RegisteredBgWorker
ReindexErrorInfo
ReindexIndexInfo
ReindexObjectType
+ReindexParams
ReindexStmt
ReindexType
RelFileNode