diff --git a/src/rum_debug_funcs.c b/src/rum_debug_funcs.c index b138ef00de..172573f368 100644 --- a/src/rum_debug_funcs.c +++ b/src/rum_debug_funcs.c @@ -19,6 +19,7 @@ #include "miscadmin.h" #include "storage/bufmgr.h" #include "storage/bufpage.h" +#include "storage/lmgr.h" #include "storage/lockdefs.h" #include "utils/array.h" #include "utils/builtins.h" @@ -269,20 +270,17 @@ typedef struct RumPageItemsStateData typedef RumPageItemsStateData *RumPageItemsState; /* - * This function and get_rel_raw_page() are derived - * from the separation of the get_raw_page_internal() - * function, which was copied from the pageinspect code. - * It is needed in order to call the initRumState() - * function if necessary. + * Open the relation named by relname, acquire specified type of lock, + * Caller must close rel when done with it. */ static Relation -get_rel_from_name(text *relName) +get_rel_from_relname(text *relName, LOCKMODE lockmode) { RangeVar *relrv; Relation rel; relrv = makeRangeVarFromNameList(textToQualifiedNameList(relName)); - rel = relation_openrv(relrv, AccessShareLock); + rel = relation_openrv(relrv, lockmode); #if PG_VERSION_NUM >= 150000 if (!RELKIND_HAS_STORAGE(rel->rd_rel->relkind)) @@ -929,20 +927,17 @@ find_attnum_posting_tree_key(RumPageItemsState piState) * piState and makes the necessary checks. */ static bool -prepare_scan(text *relName, uint32 blkNo, +prepare_scan(Relation rel, uint32 blkNo, RumPageItemsState * piState, FuncCallContext *srfFctx, pageTypeFlags pageType) { - Relation rel; /* needed to initialize the RumState structure */ - Page page; /* the page to be scanned */ RumPageOpaque opaq; /* data from the opaque area of the page */ int resSize; - /* Getting rel by name and page by number */ - rel = get_rel_from_name(relName); + /* Getting page by number */ page = get_rel_page(rel, blkNo); /* The page cannot be new */ @@ -962,8 +957,6 @@ prepare_scan(text *relName, uint32 blkNo, (*piState)->rumState = palloc(sizeof(RumState)); initRumState((*piState)->rumState, rel); - relation_close(rel, AccessShareLock); - /* Writing the page and page type into a long-lived structure */ (*piState)->srfFctx = srfFctx; (*piState)->page = page; @@ -1383,8 +1376,8 @@ rum_metapage_info(PG_FUNCTION_ARGS) /* Only the superuser can use this */ check_superuser(); - /* Getting rel by name and page by number */ - rel = get_rel_from_name(relName); + /* Open target relation by name and getting page by number */ + rel = get_rel_from_relname(relName, AccessShareLock); page = get_rel_page(rel, blkNo); relation_close(rel, AccessShareLock); @@ -1466,8 +1459,8 @@ rum_page_opaque_info(PG_FUNCTION_ARGS) /* Only the superuser can use this */ check_superuser(); - /* Getting rel by name and raw page by number */ - rel = get_rel_from_name(relName); + /* Open target relation by name and getting raw page by number */ + rel = get_rel_from_relname(relName, AccessShareLock); page = get_rel_page(rel, blkNo); relation_close(rel, AccessShareLock); @@ -1551,6 +1544,7 @@ rum_page_items_info(PG_FUNCTION_ARGS) text *relName = PG_GETARG_TEXT_PP(0); uint32 blkNo = PG_GETARG_UINT32(1); pageTypeFlags pageType = PG_GETARG_UINT32(2); + Relation rel; /* needed to initialize the RumState structure */ int counter; @@ -1573,6 +1567,9 @@ rum_page_items_info(PG_FUNCTION_ARGS) TupleDesc tupDesc; /* description of the result tuple */ MemoryContext oldMctx; /* the old function memory context */ + /* open target relation */ + rel = get_rel_from_relname(relName, AccessShareLock); + /* * Initializing the FuncCallContext structure and switching the memory * context to the one needed for structures that must be saved during @@ -1582,9 +1579,10 @@ rum_page_items_info(PG_FUNCTION_ARGS) oldMctx = MemoryContextSwitchTo(fctx->multi_call_memory_ctx); /* Before scanning the page, you need to prepare piState */ - if (!prepare_scan(relName, blkNo, &piState, fctx, pageType)) + if (!prepare_scan(rel, blkNo, &piState, fctx, pageType)) { MemoryContextSwitchTo(oldMctx); + relation_close(rel, AccessShareLock); PG_RETURN_NULL(); } @@ -1614,6 +1612,13 @@ rum_page_items_info(PG_FUNCTION_ARGS) /* In the current call, we are reading data from the previous one */ piState = fctx->user_fctx; + /* + * Need set rel if it is not first call. Anyway, relation has been already + * locked here. + */ + rel = piState->rumState->index; + Assert(CheckRelationLockedByMe(rel, AccessShareLock, false)); + /* The counter is defined differently on different pages */ if (RumIsDataPage(piState)) counter = fctx->call_cntr; @@ -1645,6 +1650,8 @@ rum_page_items_info(PG_FUNCTION_ARGS) SRF_RETURN_NEXT(fctx, piState->result); } + relation_close(rel, AccessShareLock); + /* Completing the function */ SRF_RETURN_DONE(fctx); }