From 774446b0bbb6b1beedc7d8d2c045ed8e32db3345 Mon Sep 17 00:00:00 2001 From: Alexander Korotkov Date: Sat, 17 Jun 2023 22:01:01 +0300 Subject: [PATCH 10/12] Notify table AM about index creation This allows table AM to do some preparation with index build. In particular, table AM could update its specific meta-information. That could be also useful if table AM overrides index implementations. --- src/backend/access/heap/heapam_handler.c | 2 ++ src/backend/catalog/index.c | 2 ++ src/backend/commands/indexcmds.c | 41 +++++++++++++---------- src/include/access/tableam.h | 42 ++++++++++++++++++++++++ 4 files changed, 69 insertions(+), 18 deletions(-) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index d3b8edc73ee..de38174f83d 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -3237,6 +3237,8 @@ static const TableAmRoutine heapam_methods = { .index_build_range_scan = heapam_index_build_range_scan, .index_validate_scan = heapam_index_validate_scan, .relation_analyze = heapam_analyze, + .define_index_validate = NULL, + .define_index = NULL, .free_rd_amcache = NULL, .relation_size = table_block_relation_size, diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 143fae01ebd..9bb09e9bfb8 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3823,6 +3823,8 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence, /* Close rels, but keep locks */ index_close(iRel, NoLock); + table_define_index(heapRelation, indexId, true, + skip_constraint_checks, false, NULL); table_close(heapRelation, NoLock); if (progress) diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index 43a914f44b1..cda39711180 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -576,6 +576,7 @@ DefineIndex(Oid tableId, Oid root_save_userid; int root_save_sec_context; int root_save_nestlevel; + void *arg; root_save_nestlevel = NewGUCNestLevel(); @@ -620,6 +621,26 @@ DefineIndex(Oid tableId, pgstat_progress_update_param(PROGRESS_CREATEIDX_INDEX_OID, InvalidOid); + /* + * Only SELECT ... FOR UPDATE/SHARE are allowed while doing a standard + * index build; but for concurrent builds we allow INSERT/UPDATE/DELETE + * (but not VACUUM). + * + * NB: Caller is responsible for making sure that relationId refers to the + * relation on which the index should be built; except in bootstrap mode, + * this will typically require the caller to have already locked the + * relation. To avoid lock upgrade hazards, that lock should be at least + * as strong as the one we take here. + * + * NB: If the lock strength here ever changes, code that is run by + * parallel workers under the control of certain particular ambuild + * functions will need to be updated, too. + */ + lockmode = concurrent ? ShareUpdateExclusiveLock : ShareLock; + rel = table_open(tableId, lockmode); + + table_define_index_validate(rel, stmt, skip_build, &arg); + /* * count key attributes in index */ @@ -647,24 +668,6 @@ DefineIndex(Oid tableId, errmsg("cannot use more than %d columns in an index", INDEX_MAX_KEYS))); - /* - * Only SELECT ... FOR UPDATE/SHARE are allowed while doing a standard - * index build; but for concurrent builds we allow INSERT/UPDATE/DELETE - * (but not VACUUM). - * - * NB: Caller is responsible for making sure that tableId refers to the - * relation on which the index should be built; except in bootstrap mode, - * this will typically require the caller to have already locked the - * relation. To avoid lock upgrade hazards, that lock should be at least - * as strong as the one we take here. - * - * NB: If the lock strength here ever changes, code that is run by - * parallel workers under the control of certain particular ambuild - * functions will need to be updated, too. - */ - lockmode = concurrent ? ShareUpdateExclusiveLock : ShareLock; - rel = table_open(tableId, lockmode); - /* * Switch to the table owner's userid, so that any index functions are run * as that user. Also lock down security-restricted operations. We @@ -1194,6 +1197,8 @@ DefineIndex(Oid tableId, ObjectAddressSet(address, RelationRelationId, indexRelationId); + table_define_index(rel, address.objectId, false, false, + skip_build, arg); if (!OidIsValid(indexRelationId)) { /* diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index 32afea79c86..b2b397023c7 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -690,6 +690,16 @@ typedef struct TableAmRoutine BlockNumber *totalpages, BufferAccessStrategy bstrategy); + /* See table_define_index_validate() */ + bool (*define_index_validate) (Relation rel, IndexStmt *stmt, + bool skip_build, void **arg); + + /* See table_define_index() */ + bool (*define_index) (Relation rel, Oid indoid, bool reindex, + bool skip_constraint_checks, bool skip_build, + void *arg); + + /* ------------------------------------------------------------------------ * Miscellaneous functions. @@ -1876,6 +1886,38 @@ table_relation_analyze(Relation relation, AcquireSampleRowsFunc *func, totalpages, bstrategy); } +/* + * Let table AM validate the index to be created on `rel` with statement + * `*stmt`. `skip_build` indicates that only catalog entries are to be + * created without index data. This method can save some information into + * `arg`, and it shoud be passed to table_define_index(). + */ +static inline bool +table_define_index_validate(Relation rel, IndexStmt *stmt, + bool skip_build, void **arg) +{ + if (rel->rd_tableam && rel->rd_tableam->define_index_validate) + return rel->rd_tableam->define_index_validate(rel, stmt, + skip_build, arg); + else + return true; +} + +/* + * Notifies table AM about index creation on `rel` with oid `indoid`. + */ +static inline bool +table_define_index(Relation rel, Oid indoid, bool reindex, + bool skip_constraint_checks, bool skip_build, void *arg) +{ + if (rel->rd_tableam && rel->rd_tableam->define_index) + return rel->rd_tableam->define_index(rel, indoid, reindex, + skip_constraint_checks, + skip_build, arg); + else + return true; +} + /* ---------------------------------------------------------------------------- * Miscellaneous functionality * ---------------------------------------------------------------------------- -- 2.39.3 (Apple Git-145)