Skip to content

Commit b13e970

Browse files
michaelpqpull[bot]
authored andcommitted
Add support for REINDEX in event triggers
This commit adds support for REINDEX in event triggers, making this command react for the events ddl_command_start and ddl_command_end. The indexes rebuilt are collected with the ReindexStmt emitted by the caller, for the concurrent and non-concurrent paths. Thanks to that, it is possible to know a full list of the indexes that a single REINDEX command has worked on. Author: Garrett Thornburg, Jian He Reviewed-by: Jim Jones, Michael Paquier Discussion: https://postgr.es/m/CAEEqfk5bm32G7sbhzHbES9WejD8O8DCEOaLkxoBP7HNWxjPpvg@mail.gmail.com
1 parent d216417 commit b13e970

File tree

10 files changed

+188
-43
lines changed

10 files changed

+188
-43
lines changed

doc/src/sgml/event-trigger.sgml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1032,6 +1032,14 @@
10321032
<entry align="center"><literal>-</literal></entry>
10331033
<entry align="left"></entry>
10341034
</row>
1035+
<row>
1036+
<entry align="left"><literal>REINDEX</literal></entry>
1037+
<entry align="center"><literal>X</literal></entry>
1038+
<entry align="center"><literal>X</literal></entry>
1039+
<entry align="center"><literal>-</literal></entry>
1040+
<entry align="center"><literal>-</literal></entry>
1041+
<entry align="left"></entry>
1042+
</row>
10351043
<row>
10361044
<entry align="left"><literal>REVOKE</literal></entry>
10371045
<entry align="center"><literal>X</literal></entry>

src/backend/catalog/index.c

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3558,7 +3558,8 @@ IndexGetRelation(Oid indexId, bool missing_ok)
35583558
* reindex_index - This routine is used to recreate a single index
35593559
*/
35603560
void
3561-
reindex_index(Oid indexId, bool skip_constraint_checks, char persistence,
3561+
reindex_index(const ReindexStmt *stmt, Oid indexId,
3562+
bool skip_constraint_checks, char persistence,
35623563
const ReindexParams *params)
35633564
{
35643565
Relation iRel,
@@ -3630,6 +3631,20 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence,
36303631
pgstat_progress_update_param(PROGRESS_CREATEIDX_ACCESS_METHOD_OID,
36313632
iRel->rd_rel->relam);
36323633

3634+
/*
3635+
* If a statement is available, telling that this comes from a REINDEX
3636+
* command, collect the index for event triggers.
3637+
*/
3638+
if (stmt)
3639+
{
3640+
ObjectAddress address;
3641+
3642+
ObjectAddressSet(address, RelationRelationId, indexId);
3643+
EventTriggerCollectSimpleCommand(address,
3644+
InvalidObjectAddress,
3645+
(Node *) stmt);
3646+
}
3647+
36333648
/*
36343649
* Partitioned indexes should never get processed here, as they have no
36353650
* physical storage.
@@ -3865,7 +3880,8 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence,
38653880
* index rebuild.
38663881
*/
38673882
bool
3868-
reindex_relation(Oid relid, int flags, const ReindexParams *params)
3883+
reindex_relation(const ReindexStmt *stmt, Oid relid, int flags,
3884+
const ReindexParams *params)
38693885
{
38703886
Relation rel;
38713887
Oid toast_relid;
@@ -3953,7 +3969,7 @@ reindex_relation(Oid relid, int flags, const ReindexParams *params)
39533969
continue;
39543970
}
39553971

3956-
reindex_index(indexOid, !(flags & REINDEX_REL_CHECK_CONSTRAINTS),
3972+
reindex_index(stmt, indexOid, !(flags & REINDEX_REL_CHECK_CONSTRAINTS),
39573973
persistence, params);
39583974

39593975
CommandCounterIncrement();
@@ -3990,7 +4006,7 @@ reindex_relation(Oid relid, int flags, const ReindexParams *params)
39904006

39914007
newparams.options &= ~(REINDEXOPT_MISSING_OK);
39924008
newparams.tablespaceOid = InvalidOid;
3993-
result |= reindex_relation(toast_relid, flags, &newparams);
4009+
result |= reindex_relation(stmt, toast_relid, flags, &newparams);
39944010
}
39954011

39964012
return result;

src/backend/commands/cluster.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1518,7 +1518,7 @@ finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap,
15181518
pgstat_progress_update_param(PROGRESS_CLUSTER_PHASE,
15191519
PROGRESS_CLUSTER_PHASE_REBUILD_INDEX);
15201520

1521-
reindex_relation(OIDOldHeap, reindex_flags, &reindex_params);
1521+
reindex_relation(NULL, OIDOldHeap, reindex_flags, &reindex_params);
15221522

15231523
/* Report that we are now doing clean up */
15241524
pgstat_progress_update_param(PROGRESS_CLUSTER_PHASE,

src/backend/commands/indexcmds.c

Lines changed: 48 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -94,20 +94,21 @@ static char *ChooseIndexName(const char *tabname, Oid namespaceId,
9494
bool primary, bool isconstraint);
9595
static char *ChooseIndexNameAddition(const List *colnames);
9696
static List *ChooseIndexColumnNames(const List *indexElems);
97-
static void ReindexIndex(const RangeVar *indexRelation, const ReindexParams *params,
97+
static void ReindexIndex(const ReindexStmt *stmt, const ReindexParams *params,
9898
bool isTopLevel);
9999
static void RangeVarCallbackForReindexIndex(const RangeVar *relation,
100100
Oid relId, Oid oldRelId, void *arg);
101-
static Oid ReindexTable(const RangeVar *relation, const ReindexParams *params,
101+
static Oid ReindexTable(const ReindexStmt *stmt, const ReindexParams *params,
102102
bool isTopLevel);
103-
static void ReindexMultipleTables(const char *objectName,
104-
ReindexObjectType objectKind, const ReindexParams *params);
103+
static void ReindexMultipleTables(const ReindexStmt *stmt,
104+
const ReindexParams *params);
105105
static void reindex_error_callback(void *arg);
106-
static void ReindexPartitions(Oid relid, const ReindexParams *params,
107-
bool isTopLevel);
108-
static void ReindexMultipleInternal(const List *relids,
106+
static void ReindexPartitions(const ReindexStmt *stmt, Oid relid,
107+
const ReindexParams *params, bool isTopLevel);
108+
static void ReindexMultipleInternal(const ReindexStmt *stmt, const List *relids,
109109
const ReindexParams *params);
110-
static bool ReindexRelationConcurrently(Oid relationOid,
110+
static bool ReindexRelationConcurrently(const ReindexStmt *stmt,
111+
Oid relationOid,
111112
const ReindexParams *params);
112113
static void update_relispartition(Oid relationId, bool newval);
113114
static inline void set_indexsafe_procflags(void);
@@ -2735,10 +2736,10 @@ ExecReindex(ParseState *pstate, const ReindexStmt *stmt, bool isTopLevel)
27352736
switch (stmt->kind)
27362737
{
27372738
case REINDEX_OBJECT_INDEX:
2738-
ReindexIndex(stmt->relation, &params, isTopLevel);
2739+
ReindexIndex(stmt, &params, isTopLevel);
27392740
break;
27402741
case REINDEX_OBJECT_TABLE:
2741-
ReindexTable(stmt->relation, &params, isTopLevel);
2742+
ReindexTable(stmt, &params, isTopLevel);
27422743
break;
27432744
case REINDEX_OBJECT_SCHEMA:
27442745
case REINDEX_OBJECT_SYSTEM:
@@ -2754,7 +2755,7 @@ ExecReindex(ParseState *pstate, const ReindexStmt *stmt, bool isTopLevel)
27542755
(stmt->kind == REINDEX_OBJECT_SCHEMA) ? "REINDEX SCHEMA" :
27552756
(stmt->kind == REINDEX_OBJECT_SYSTEM) ? "REINDEX SYSTEM" :
27562757
"REINDEX DATABASE");
2757-
ReindexMultipleTables(stmt->name, stmt->kind, &params);
2758+
ReindexMultipleTables(stmt, &params);
27582759
break;
27592760
default:
27602761
elog(ERROR, "unrecognized object type: %d",
@@ -2768,8 +2769,9 @@ ExecReindex(ParseState *pstate, const ReindexStmt *stmt, bool isTopLevel)
27682769
* Recreate a specific index.
27692770
*/
27702771
static void
2771-
ReindexIndex(const RangeVar *indexRelation, const ReindexParams *params, bool isTopLevel)
2772+
ReindexIndex(const ReindexStmt *stmt, const ReindexParams *params, bool isTopLevel)
27722773
{
2774+
const RangeVar *indexRelation = stmt->relation;
27732775
struct ReindexIndexCallbackState state;
27742776
Oid indOid;
27752777
char persistence;
@@ -2802,16 +2804,16 @@ ReindexIndex(const RangeVar *indexRelation, const ReindexParams *params, bool is
28022804
relkind = get_rel_relkind(indOid);
28032805

28042806
if (relkind == RELKIND_PARTITIONED_INDEX)
2805-
ReindexPartitions(indOid, params, isTopLevel);
2807+
ReindexPartitions(stmt, indOid, params, isTopLevel);
28062808
else if ((params->options & REINDEXOPT_CONCURRENTLY) != 0 &&
28072809
persistence != RELPERSISTENCE_TEMP)
2808-
ReindexRelationConcurrently(indOid, params);
2810+
ReindexRelationConcurrently(stmt, indOid, params);
28092811
else
28102812
{
28112813
ReindexParams newparams = *params;
28122814

28132815
newparams.options |= REINDEXOPT_REPORT_PROGRESS;
2814-
reindex_index(indOid, false, persistence, &newparams);
2816+
reindex_index(stmt, indOid, false, persistence, &newparams);
28152817
}
28162818
}
28172819

@@ -2891,10 +2893,11 @@ RangeVarCallbackForReindexIndex(const RangeVar *relation,
28912893
* Recreate all indexes of a table (and of its toast table, if any)
28922894
*/
28932895
static Oid
2894-
ReindexTable(const RangeVar *relation, const ReindexParams *params, bool isTopLevel)
2896+
ReindexTable(const ReindexStmt *stmt, const ReindexParams *params, bool isTopLevel)
28952897
{
28962898
Oid heapOid;
28972899
bool result;
2900+
const RangeVar *relation = stmt->relation;
28982901

28992902
/*
29002903
* The lock level used here should match reindex_relation().
@@ -2911,11 +2914,11 @@ ReindexTable(const RangeVar *relation, const ReindexParams *params, bool isTopLe
29112914
RangeVarCallbackOwnsTable, NULL);
29122915

29132916
if (get_rel_relkind(heapOid) == RELKIND_PARTITIONED_TABLE)
2914-
ReindexPartitions(heapOid, params, isTopLevel);
2917+
ReindexPartitions(stmt, heapOid, params, isTopLevel);
29152918
else if ((params->options & REINDEXOPT_CONCURRENTLY) != 0 &&
29162919
get_rel_persistence(heapOid) != RELPERSISTENCE_TEMP)
29172920
{
2918-
result = ReindexRelationConcurrently(heapOid, params);
2921+
result = ReindexRelationConcurrently(stmt, heapOid, params);
29192922

29202923
if (!result)
29212924
ereport(NOTICE,
@@ -2927,7 +2930,7 @@ ReindexTable(const RangeVar *relation, const ReindexParams *params, bool isTopLe
29272930
ReindexParams newparams = *params;
29282931

29292932
newparams.options |= REINDEXOPT_REPORT_PROGRESS;
2930-
result = reindex_relation(heapOid,
2933+
result = reindex_relation(stmt, heapOid,
29312934
REINDEX_REL_PROCESS_TOAST |
29322935
REINDEX_REL_CHECK_CONSTRAINTS,
29332936
&newparams);
@@ -2949,9 +2952,9 @@ ReindexTable(const RangeVar *relation, const ReindexParams *params, bool isTopLe
29492952
* That means this must not be called within a user transaction block!
29502953
*/
29512954
static void
2952-
ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind,
2953-
const ReindexParams *params)
2955+
ReindexMultipleTables(const ReindexStmt *stmt, const ReindexParams *params)
29542956
{
2957+
29552958
Oid objectOid;
29562959
Relation relationRelation;
29572960
TableScanDesc scan;
@@ -2963,6 +2966,8 @@ ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind,
29632966
int num_keys;
29642967
bool concurrent_warning = false;
29652968
bool tablespace_warning = false;
2969+
const char *objectName = stmt->name;
2970+
const ReindexObjectType objectKind = stmt->kind;
29662971

29672972
Assert(objectKind == REINDEX_OBJECT_SCHEMA ||
29682973
objectKind == REINDEX_OBJECT_SYSTEM ||
@@ -3158,7 +3163,7 @@ ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind,
31583163
* Process each relation listed in a separate transaction. Note that this
31593164
* commits and then starts a new transaction immediately.
31603165
*/
3161-
ReindexMultipleInternal(relids, params);
3166+
ReindexMultipleInternal(stmt, relids, params);
31623167

31633168
MemoryContextDelete(private_context);
31643169
}
@@ -3188,7 +3193,7 @@ reindex_error_callback(void *arg)
31883193
* by the caller.
31893194
*/
31903195
static void
3191-
ReindexPartitions(Oid relid, const ReindexParams *params, bool isTopLevel)
3196+
ReindexPartitions(const ReindexStmt *stmt, Oid relid, const ReindexParams *params, bool isTopLevel)
31923197
{
31933198
List *partitions = NIL;
31943199
char relkind = get_rel_relkind(relid);
@@ -3264,7 +3269,7 @@ ReindexPartitions(Oid relid, const ReindexParams *params, bool isTopLevel)
32643269
* Process each partition listed in a separate transaction. Note that
32653270
* this commits and then starts a new transaction immediately.
32663271
*/
3267-
ReindexMultipleInternal(partitions, params);
3272+
ReindexMultipleInternal(stmt, partitions, params);
32683273

32693274
/*
32703275
* Clean up working storage --- note we must do this after
@@ -3282,7 +3287,7 @@ ReindexPartitions(Oid relid, const ReindexParams *params, bool isTopLevel)
32823287
* and starts a new transaction when finished.
32833288
*/
32843289
static void
3285-
ReindexMultipleInternal(const List *relids, const ReindexParams *params)
3290+
ReindexMultipleInternal(const ReindexStmt *stmt, const List *relids, const ReindexParams *params)
32863291
{
32873292
ListCell *l;
32883293

@@ -3341,7 +3346,7 @@ ReindexMultipleInternal(const List *relids, const ReindexParams *params)
33413346
ReindexParams newparams = *params;
33423347

33433348
newparams.options |= REINDEXOPT_MISSING_OK;
3344-
(void) ReindexRelationConcurrently(relid, &newparams);
3349+
(void) ReindexRelationConcurrently(stmt, relid, &newparams);
33453350
/* ReindexRelationConcurrently() does the verbose output */
33463351
}
33473352
else if (relkind == RELKIND_INDEX)
@@ -3350,7 +3355,7 @@ ReindexMultipleInternal(const List *relids, const ReindexParams *params)
33503355

33513356
newparams.options |=
33523357
REINDEXOPT_REPORT_PROGRESS | REINDEXOPT_MISSING_OK;
3353-
reindex_index(relid, false, relpersistence, &newparams);
3358+
reindex_index(stmt, relid, false, relpersistence, &newparams);
33543359
PopActiveSnapshot();
33553360
/* reindex_index() does the verbose output */
33563361
}
@@ -3361,7 +3366,7 @@ ReindexMultipleInternal(const List *relids, const ReindexParams *params)
33613366

33623367
newparams.options |=
33633368
REINDEXOPT_REPORT_PROGRESS | REINDEXOPT_MISSING_OK;
3364-
result = reindex_relation(relid,
3369+
result = reindex_relation(stmt, relid,
33653370
REINDEX_REL_PROCESS_TOAST |
33663371
REINDEX_REL_CHECK_CONSTRAINTS,
33673372
&newparams);
@@ -3406,7 +3411,7 @@ ReindexMultipleInternal(const List *relids, const ReindexParams *params)
34063411
* anyway, and a non-concurrent reindex is more efficient.
34073412
*/
34083413
static bool
3409-
ReindexRelationConcurrently(Oid relationOid, const ReindexParams *params)
3414+
ReindexRelationConcurrently(const ReindexStmt *stmt, Oid relationOid, const ReindexParams *params)
34103415
{
34113416
typedef struct ReindexIndexInfo
34123417
{
@@ -3843,6 +3848,20 @@ ReindexRelationConcurrently(Oid relationOid, const ReindexParams *params)
38433848
SetUserIdAndSecContext(save_userid, save_sec_context);
38443849

38453850
table_close(heapRel, NoLock);
3851+
3852+
/*
3853+
* If a statement is available, telling that this comes from a REINDEX
3854+
* command, collect the new index for event triggers.
3855+
*/
3856+
if (stmt)
3857+
{
3858+
ObjectAddress address;
3859+
3860+
ObjectAddressSet(address, RelationRelationId, newIndexId);
3861+
EventTriggerCollectSimpleCommand(address,
3862+
InvalidObjectAddress,
3863+
(Node *) stmt);
3864+
}
38463865
}
38473866

38483867
/*

src/backend/commands/tablecmds.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2169,7 +2169,7 @@ ExecuteTruncateGuts(List *explicit_rels,
21692169
/*
21702170
* Reconstruct the indexes to match, and we're done.
21712171
*/
2172-
reindex_relation(heap_relid, REINDEX_REL_PROCESS_TOAST,
2172+
reindex_relation(NULL, heap_relid, REINDEX_REL_PROCESS_TOAST,
21732173
&reindex_params);
21742174
}
21752175

src/backend/tcop/utility.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -960,10 +960,6 @@ standard_ProcessUtility(PlannedStmt *pstmt,
960960
(RecoveryInProgress() ? 0 : CHECKPOINT_FORCE));
961961
break;
962962

963-
case T_ReindexStmt:
964-
ExecReindex(pstate, (ReindexStmt *) parsetree, isTopLevel);
965-
break;
966-
967963
/*
968964
* The following statements are supported by Event Triggers only
969965
* in some cases, so we "fast path" them in the other cases.
@@ -1574,6 +1570,13 @@ ProcessUtilitySlow(ParseState *pstate,
15741570
}
15751571
break;
15761572

1573+
case T_ReindexStmt:
1574+
ExecReindex(pstate, (ReindexStmt *) parsetree, isTopLevel);
1575+
1576+
/* EventTriggerCollectSimpleCommand is called directly */
1577+
commandCollected = true;
1578+
break;
1579+
15771580
case T_CreateExtensionStmt:
15781581
address = CreateExtension(pstate, (CreateExtensionStmt *) parsetree);
15791582
break;

src/include/catalog/index.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,9 @@ extern void index_set_state_flags(Oid indexId, IndexStateFlagsAction action);
149149

150150
extern Oid IndexGetRelation(Oid indexId, bool missing_ok);
151151

152-
extern void reindex_index(Oid indexId, bool skip_constraint_checks,
153-
char persistence, const ReindexParams *params);
152+
extern void reindex_index(const ReindexStmt *stmt, Oid indexId,
153+
bool skip_constraint_checks, char persistence,
154+
const ReindexParams *params);
154155

155156
/* Flag bits for reindex_relation(): */
156157
#define REINDEX_REL_PROCESS_TOAST 0x01
@@ -159,7 +160,8 @@ extern void reindex_index(Oid indexId, bool skip_constraint_checks,
159160
#define REINDEX_REL_FORCE_INDEXES_UNLOGGED 0x08
160161
#define REINDEX_REL_FORCE_INDEXES_PERMANENT 0x10
161162

162-
extern bool reindex_relation(Oid relid, int flags, const ReindexParams *params);
163+
extern bool reindex_relation(const ReindexStmt *stmt, Oid relid, int flags,
164+
const ReindexParams *params);
163165

164166
extern bool ReindexIsProcessingHeap(Oid heapOid);
165167
extern bool ReindexIsProcessingIndex(Oid indexOid);

src/include/tcop/cmdtaglist.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ PG_CMDTAG(CMDTAG_PREPARE, "PREPARE", false, false, false)
194194
PG_CMDTAG(CMDTAG_PREPARE_TRANSACTION, "PREPARE TRANSACTION", false, false, false)
195195
PG_CMDTAG(CMDTAG_REASSIGN_OWNED, "REASSIGN OWNED", false, false, false)
196196
PG_CMDTAG(CMDTAG_REFRESH_MATERIALIZED_VIEW, "REFRESH MATERIALIZED VIEW", true, false, false)
197-
PG_CMDTAG(CMDTAG_REINDEX, "REINDEX", false, false, false)
197+
PG_CMDTAG(CMDTAG_REINDEX, "REINDEX", true, false, false)
198198
PG_CMDTAG(CMDTAG_RELEASE, "RELEASE", false, false, false)
199199
PG_CMDTAG(CMDTAG_RESET, "RESET", false, false, false)
200200
PG_CMDTAG(CMDTAG_REVOKE, "REVOKE", true, false, false)

0 commit comments

Comments
 (0)