From 9041e7225262a3ab81e85a69288c2bdbd9a6f684 Mon Sep 17 00:00:00 2001 From: Hari Date: Fri, 9 Jun 2017 11:36:35 +1000 Subject: [PATCH 08/10] Replace heap_* functions with storage access methods Replace all heap_* functions with storage access methods in the entire code, but these are not yet removed the HeapTuple and HeapScanDesc use. --- contrib/pgrowlocks/pgrowlocks.c | 14 +++++--- contrib/pgstattuple/pgstattuple.c | 9 ++--- contrib/postgres_fdw/postgres_fdw.c | 2 +- contrib/tsm_system_rows/tsm_system_rows.c | 8 ++--- contrib/tsm_system_time/tsm_system_time.c | 2 +- src/backend/access/index/genam.c | 8 +++-- src/backend/bootstrap/bootstrap.c | 30 ++++++++++------- src/backend/catalog/aclchk.c | 17 ++++++---- src/backend/catalog/index.c | 32 +++++++++++------- src/backend/catalog/pg_conversion.c | 10 +++--- src/backend/catalog/pg_db_role_setting.c | 10 +++--- src/backend/catalog/pg_publication.c | 8 +++-- src/backend/catalog/pg_subscription.c | 7 ++-- src/backend/commands/cluster.c | 18 ++++++---- src/backend/commands/copy.c | 7 ++-- src/backend/commands/dbcommands.c | 26 +++++++++----- src/backend/commands/indexcmds.c | 9 +++-- src/backend/commands/tablecmds.c | 42 +++++++++++++---------- src/backend/commands/tablespace.c | 54 +++++++++++++++++------------- src/backend/commands/typecmds.c | 15 +++++---- src/backend/commands/vacuum.c | 18 ++++++---- src/backend/executor/execReplication.c | 12 ++++--- src/backend/executor/nodeBitmapHeapscan.c | 13 +++---- src/backend/executor/nodeSamplescan.c | 6 ++-- src/backend/executor/nodeSeqscan.c | 11 +++--- src/backend/postmaster/autovacuum.c | 23 ++++++++----- src/backend/postmaster/pgstat.c | 9 +++-- src/backend/replication/logical/launcher.c | 8 +++-- src/backend/rewrite/rewriteDefine.c | 9 +++-- src/backend/utils/init/postinit.c | 9 +++-- 30 files changed, 269 insertions(+), 177 deletions(-) diff --git a/contrib/pgrowlocks/pgrowlocks.c b/contrib/pgrowlocks/pgrowlocks.c index 00e2015..97ee00f 100644 --- a/contrib/pgrowlocks/pgrowlocks.c +++ b/contrib/pgrowlocks/pgrowlocks.c @@ -26,6 +26,7 @@ #include "access/multixact.h" #include "access/relscan.h" +#include "access/storageamapi.h" #include "access/xact.h" #include "catalog/namespace.h" #include "catalog/pg_authid.h" @@ -55,7 +56,7 @@ PG_FUNCTION_INFO_V1(pgrowlocks); typedef struct { Relation rel; - HeapScanDesc scan; + StorageScanDesc scan; int ncolumns; } MyData; @@ -70,13 +71,16 @@ Datum pgrowlocks(PG_FUNCTION_ARGS) { FuncCallContext *funcctx; - HeapScanDesc scan; + StorageScanDesc scan; HeapTuple tuple; TupleDesc tupdesc; AttInMetadata *attinmeta; Datum result; MyData *mydata; Relation rel; + StorageAmRoutine *method; + + method = rel->rd_stamroutine; if (SRF_IS_FIRSTCALL()) { @@ -112,7 +116,7 @@ pgrowlocks(PG_FUNCTION_ARGS) aclcheck_error(aclresult, ACL_KIND_CLASS, RelationGetRelationName(rel)); - scan = heap_beginscan(rel, GetActiveSnapshot(), 0, NULL); + scan = method->scan_begin(rel, GetActiveSnapshot(), 0, NULL); mydata = palloc(sizeof(*mydata)); mydata->rel = rel; mydata->scan = scan; @@ -128,7 +132,7 @@ pgrowlocks(PG_FUNCTION_ARGS) scan = mydata->scan; /* scan the relation */ - while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) + while ((tuple = method->scan_getnext(scan, ForwardScanDirection)) != NULL) { HTSU_Result htsu; TransactionId xmax; @@ -293,7 +297,7 @@ pgrowlocks(PG_FUNCTION_ARGS) } } - heap_endscan(scan); + method->scan_end(scan); heap_close(mydata->rel, AccessShareLock); SRF_RETURN_DONE(funcctx); diff --git a/contrib/pgstattuple/pgstattuple.c b/contrib/pgstattuple/pgstattuple.c index eb02ec5..5ff67e4 100644 --- a/contrib/pgstattuple/pgstattuple.c +++ b/contrib/pgstattuple/pgstattuple.c @@ -314,7 +314,7 @@ pgstat_relation(Relation rel, FunctionCallInfo fcinfo) static Datum pgstat_heap(Relation rel, FunctionCallInfo fcinfo) { - HeapScanDesc scan; + StorageScanDesc scan; HeapTuple tuple; BlockNumber nblocks; BlockNumber block = 0; /* next block to count free space in */ @@ -322,15 +322,16 @@ pgstat_heap(Relation rel, FunctionCallInfo fcinfo) Buffer buffer; pgstattuple_type stat = {0}; SnapshotData SnapshotDirty; + StorageAmRoutine *method = rel->rd_stamroutine; /* Disable syncscan because we assume we scan from block zero upwards */ - scan = heap_beginscan_strat(rel, SnapshotAny, 0, NULL, true, false); + scan = method->scan_begin_strat(rel, SnapshotAny, 0, NULL, true, false); InitDirtySnapshot(SnapshotDirty); nblocks = scan->rs_nblocks; /* # blocks to be scanned */ /* scan the relation */ - while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) + while ((tuple = method->scan_getnext(scan, ForwardScanDirection)) != NULL) { CHECK_FOR_INTERRUPTS(); @@ -383,7 +384,7 @@ pgstat_heap(Relation rel, FunctionCallInfo fcinfo) block++; } - heap_endscan(scan); + method->scan_end(scan); relation_close(rel, AccessShareLock); stat.table_len = (uint64) nblocks *BLCKSZ; diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c index 080cb0a..498b812 100644 --- a/contrib/postgres_fdw/postgres_fdw.c +++ b/contrib/postgres_fdw/postgres_fdw.c @@ -3219,7 +3219,7 @@ convert_prep_stmt_params(PgFdwModifyState *fmstate, Datum value; bool isnull; - value = slot_getattr(slot, attnum, &isnull); + value = slot->tts_storageam->slot_getattr(slot, attnum, &isnull); if (isnull) p_values[pindex] = NULL; else diff --git a/contrib/tsm_system_rows/tsm_system_rows.c b/contrib/tsm_system_rows/tsm_system_rows.c index 544458e..ed0078e 100644 --- a/contrib/tsm_system_rows/tsm_system_rows.c +++ b/contrib/tsm_system_rows/tsm_system_rows.c @@ -71,7 +71,7 @@ static BlockNumber system_rows_nextsampleblock(SampleScanState *node); static OffsetNumber system_rows_nextsampletuple(SampleScanState *node, BlockNumber blockno, OffsetNumber maxoffset); -static bool SampleOffsetVisible(OffsetNumber tupoffset, HeapScanDesc scan); +static bool SampleOffsetVisible(OffsetNumber tupoffset, StorageScanDesc scan); static uint32 random_relative_prime(uint32 n, SamplerRandomState randstate); @@ -209,7 +209,7 @@ static BlockNumber system_rows_nextsampleblock(SampleScanState *node) { SystemRowsSamplerData *sampler = (SystemRowsSamplerData *) node->tsm_state; - HeapScanDesc scan = node->ss.ss_currentScanDesc; + StorageScanDesc scan = node->ss.ss_currentScanDesc; /* First call within scan? */ if (sampler->doneblocks == 0) @@ -278,7 +278,7 @@ system_rows_nextsampletuple(SampleScanState *node, OffsetNumber maxoffset) { SystemRowsSamplerData *sampler = (SystemRowsSamplerData *) node->tsm_state; - HeapScanDesc scan = node->ss.ss_currentScanDesc; + StorageScanDesc scan = node->ss.ss_currentScanDesc; OffsetNumber tupoffset = sampler->lt; /* Quit if we've returned all needed tuples */ @@ -327,7 +327,7 @@ system_rows_nextsampletuple(SampleScanState *node, * so just look at the info it left in rs_vistuples[]. */ static bool -SampleOffsetVisible(OffsetNumber tupoffset, HeapScanDesc scan) +SampleOffsetVisible(OffsetNumber tupoffset, StorageScanDesc scan) { int start = 0, end = scan->rs_ntuples - 1; diff --git a/contrib/tsm_system_time/tsm_system_time.c b/contrib/tsm_system_time/tsm_system_time.c index af8d025..4c32166 100644 --- a/contrib/tsm_system_time/tsm_system_time.c +++ b/contrib/tsm_system_time/tsm_system_time.c @@ -219,7 +219,7 @@ static BlockNumber system_time_nextsampleblock(SampleScanState *node) { SystemTimeSamplerData *sampler = (SystemTimeSamplerData *) node->tsm_state; - HeapScanDesc scan = node->ss.ss_currentScanDesc; + StorageScanDesc scan = node->ss.ss_currentScanDesc; instr_time cur_time; /* First call within scan? */ diff --git a/src/backend/access/index/genam.c b/src/backend/access/index/genam.c index a91fda7..7b85395 100644 --- a/src/backend/access/index/genam.c +++ b/src/backend/access/index/genam.c @@ -20,6 +20,7 @@ #include "postgres.h" #include "access/relscan.h" +#include "access/storageamapi.h" #include "access/transam.h" #include "catalog/index.h" #include "lib/stringinfo.h" @@ -387,6 +388,7 @@ systable_beginscan(Relation heapRelation, } else { + StorageAmRoutine *method = heapRelation->rd_stamroutine; /* * We disallow synchronized scans when forced to use a heapscan on a * catalog. In most cases the desired rows are near the front, so @@ -394,7 +396,7 @@ systable_beginscan(Relation heapRelation, * disadvantage; and there are no compensating advantages, because * it's unlikely that such scans will occur in parallel. */ - sysscan->scan = heap_beginscan_strat(heapRelation, snapshot, + sysscan->scan = method->scan_begin_strat(heapRelation, snapshot, nkeys, key, true, false); sysscan->iscan = NULL; @@ -432,7 +434,7 @@ systable_getnext(SysScanDesc sysscan) elog(ERROR, "system catalog scans with lossy index conditions are not implemented"); } else - htup = heap_getnext(sysscan->scan, ForwardScanDirection); + htup = sysscan->heap_rel->rd_stamroutine->scan_getnext(sysscan->scan, ForwardScanDirection); return htup; } @@ -504,7 +506,7 @@ systable_endscan(SysScanDesc sysscan) index_close(sysscan->irel, AccessShareLock); } else - heap_endscan(sysscan->scan); + sysscan->heap_rel->rd_stamroutine->scan_end(sysscan->scan); if (sysscan->snapshot) UnregisterSnapshot(sysscan->snapshot); diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c index 4c28b2b..9b7241a 100644 --- a/src/backend/bootstrap/bootstrap.c +++ b/src/backend/bootstrap/bootstrap.c @@ -18,6 +18,7 @@ #include #include "access/htup_details.h" +#include "access/storageamapi.h" #include "access/xact.h" #include "bootstrap/bootstrap.h" #include "catalog/index.h" @@ -571,20 +572,23 @@ boot_openrel(char *relname) if (Typ == NULL) { + StorageAmRoutine *method; + /* We can now load the pg_type data */ rel = heap_open(TypeRelationId, NoLock); - scan = heap_beginscan_catalog(rel, 0, NULL); + method = rel->rd_stamroutine; + scan = method->scan_begin_catalog(rel, 0, NULL); i = 0; - while ((tup = heap_getnext(scan, ForwardScanDirection)) != NULL) + while ((tup = method->scan_getnext(scan, ForwardScanDirection)) != NULL) ++i; - heap_endscan(scan); + method->scan_end(scan); app = Typ = ALLOC(struct typmap *, i + 1); while (i-- > 0) *app++ = ALLOC(struct typmap, 1); *app = NULL; - scan = heap_beginscan_catalog(rel, 0, NULL); + scan = method->scan_begin_catalog(rel, 0, NULL); app = Typ; - while ((tup = heap_getnext(scan, ForwardScanDirection)) != NULL) + while ((tup = method->scan_getnext(scan, ForwardScanDirection)) != NULL) { (*app)->am_oid = HeapTupleGetOid(tup); memcpy((char *) &(*app)->am_typ, @@ -592,7 +596,7 @@ boot_openrel(char *relname) sizeof((*app)->am_typ)); app++; } - heap_endscan(scan); + method->scan_end(scan); heap_close(rel, NoLock); } @@ -877,6 +881,7 @@ gettype(char *type) HeapScanDesc scan; HeapTuple tup; struct typmap **app; + StorageAmRoutine *method; if (Typ != NULL) { @@ -898,25 +903,26 @@ gettype(char *type) } elog(DEBUG4, "external type: %s", type); rel = heap_open(TypeRelationId, NoLock); - scan = heap_beginscan_catalog(rel, 0, NULL); + method = rel->rd_stamroutine; + scan = method->scan_begin_catalog(rel, 0, NULL); i = 0; - while ((tup = heap_getnext(scan, ForwardScanDirection)) != NULL) + while ((tup = method->scan_getnext(scan, ForwardScanDirection)) != NULL) ++i; - heap_endscan(scan); + method->scan_end(scan); app = Typ = ALLOC(struct typmap *, i + 1); while (i-- > 0) *app++ = ALLOC(struct typmap, 1); *app = NULL; - scan = heap_beginscan_catalog(rel, 0, NULL); + scan = method->scan_begin_catalog(rel, 0, NULL); app = Typ; - while ((tup = heap_getnext(scan, ForwardScanDirection)) != NULL) + while ((tup = method->scan_getnext(scan, ForwardScanDirection)) != NULL) { (*app)->am_oid = HeapTupleGetOid(tup); memmove((char *) &(*app++)->am_typ, (char *) GETSTRUCT(tup), sizeof((*app)->am_typ)); } - heap_endscan(scan); + method->scan_end(scan); heap_close(rel, NoLock); return gettype(type); } diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c index 387a3be..22ccd34 100644 --- a/src/backend/catalog/aclchk.c +++ b/src/backend/catalog/aclchk.c @@ -20,6 +20,7 @@ #include "access/genam.h" #include "access/heapam.h" #include "access/htup_details.h" +#include "access/storageamapi.h" #include "access/sysattr.h" #include "access/xact.h" #include "catalog/binary_upgrade.h" @@ -790,6 +791,7 @@ objectsInSchemaToOids(GrantObjectType objtype, List *nspnames) Relation rel; HeapScanDesc scan; HeapTuple tuple; + StorageAmRoutine *method; ScanKeyInit(&key[0], Anum_pg_proc_pronamespace, @@ -797,14 +799,15 @@ objectsInSchemaToOids(GrantObjectType objtype, List *nspnames) ObjectIdGetDatum(namespaceId)); rel = heap_open(ProcedureRelationId, AccessShareLock); - scan = heap_beginscan_catalog(rel, 1, key); + method = rel->rd_stamroutine; + scan = method->scan_begin_catalog(rel, 1, key); - while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) + while ((tuple = method->scan_getnext(scan, ForwardScanDirection)) != NULL) { objects = lappend_oid(objects, HeapTupleGetOid(tuple)); } - heap_endscan(scan); + method->scan_end(scan); heap_close(rel, AccessShareLock); } break; @@ -831,6 +834,7 @@ getRelationsInNamespace(Oid namespaceId, char relkind) Relation rel; HeapScanDesc scan; HeapTuple tuple; + StorageAmRoutine *method; ScanKeyInit(&key[0], Anum_pg_class_relnamespace, @@ -842,14 +846,15 @@ getRelationsInNamespace(Oid namespaceId, char relkind) CharGetDatum(relkind)); rel = heap_open(RelationRelationId, AccessShareLock); - scan = heap_beginscan_catalog(rel, 2, key); + method = rel->rd_stamroutine; + scan = method->scan_begin_catalog(rel, 2, key); - while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) + while ((tuple = method->scan_getnext(scan, ForwardScanDirection)) != NULL) { relations = lappend_oid(relations, HeapTupleGetOid(tuple)); } - heap_endscan(scan); + method->scan_end(scan); heap_close(rel, AccessShareLock); return relations; diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 558dbbc..42be25b 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -1892,16 +1892,18 @@ index_update_stats(Relation rel, /* don't assume syscache will work */ HeapScanDesc pg_class_scan; ScanKeyData key[1]; + StorageAmRoutine *method; ScanKeyInit(&key[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(relid)); - pg_class_scan = heap_beginscan_catalog(pg_class, 1, key); - tuple = heap_getnext(pg_class_scan, ForwardScanDirection); + method = pg_class->rd_stamroutine; + pg_class_scan = method->scan_begin_catalog(pg_class, 1, key); + tuple = method->scan_getnext(pg_class_scan, ForwardScanDirection); tuple = heap_copytuple(tuple); - heap_endscan(pg_class_scan); + method->scan_end(pg_class_scan); } else { @@ -2216,6 +2218,7 @@ IndexBuildHeapRangeScan(Relation heapRelation, TransactionId OldestXmin; BlockNumber root_blkno = InvalidBlockNumber; OffsetNumber root_offsets[MaxHeapTuplesPerPage]; + StorageAmRoutine *method; /* * sanity checks @@ -2271,7 +2274,8 @@ IndexBuildHeapRangeScan(Relation heapRelation, OldestXmin = GetOldestXmin(heapRelation, PROCARRAY_FLAGS_VACUUM); } - scan = heap_beginscan_strat(heapRelation, /* relation */ + method = heapRelation->rd_stamroutine; + scan = method->scan_begin_strat(heapRelation, /* relation */ snapshot, /* snapshot */ 0, /* number of keys */ NULL, /* scan key */ @@ -2280,7 +2284,7 @@ IndexBuildHeapRangeScan(Relation heapRelation, /* set our scan endpoints */ if (!allow_sync) - heap_setscanlimits(scan, start_blockno, numblocks); + method->scansetlimits(scan, start_blockno, numblocks); else { /* syncscan can only be requested on whole relation */ @@ -2293,7 +2297,7 @@ IndexBuildHeapRangeScan(Relation heapRelation, /* * Scan all tuples in the base relation. */ - while ((heapTuple = heap_getnext(scan, ForwardScanDirection)) != NULL) + while ((heapTuple = method->scan_getnext(scan, ForwardScanDirection)) != NULL) { bool tupleIsAlive; @@ -2605,7 +2609,7 @@ IndexBuildHeapRangeScan(Relation heapRelation, } } - heap_endscan(scan); + method->scan_end(scan); /* we can now forget our snapshot, if set */ if (IsBootstrapProcessingMode() || indexInfo->ii_Concurrent) @@ -2649,6 +2653,7 @@ IndexCheckExclusion(Relation heapRelation, EState *estate; ExprContext *econtext; Snapshot snapshot; + StorageAmRoutine *method = heapRelation->rd_stamroutine; /* * If we are reindexing the target index, mark it as no longer being @@ -2676,14 +2681,14 @@ IndexCheckExclusion(Relation heapRelation, * Scan all live tuples in the base relation. */ snapshot = RegisterSnapshot(GetLatestSnapshot()); - scan = heap_beginscan_strat(heapRelation, /* relation */ + scan = method->scan_begin_strat(heapRelation, /* relation */ snapshot, /* snapshot */ 0, /* number of keys */ NULL, /* scan key */ true, /* buffer access strategy OK */ true); /* syncscan OK */ - while ((heapTuple = heap_getnext(scan, ForwardScanDirection)) != NULL) + while ((heapTuple = method->scan_getnext(scan, ForwardScanDirection)) != NULL) { CHECK_FOR_INTERRUPTS(); @@ -2719,7 +2724,7 @@ IndexCheckExclusion(Relation heapRelation, estate, true); } - heap_endscan(scan); + method->scan_end(scan); UnregisterSnapshot(snapshot); ExecDropSingleTupleTableSlot(slot); @@ -2970,6 +2975,7 @@ validate_index_heapscan(Relation heapRelation, ItemPointer indexcursor = NULL; ItemPointerData decoded; bool tuplesort_empty = false; + StorageAmRoutine *method = heapRelation->rd_stamroutine; /* * sanity checks @@ -2996,7 +3002,7 @@ validate_index_heapscan(Relation heapRelation, * here, because it's critical that we read from block zero forward to * match the sorted TIDs. */ - scan = heap_beginscan_strat(heapRelation, /* relation */ + scan = method->scan_begin_strat(heapRelation, /* relation */ snapshot, /* snapshot */ 0, /* number of keys */ NULL, /* scan key */ @@ -3006,7 +3012,7 @@ validate_index_heapscan(Relation heapRelation, /* * Scan all tuples matching the snapshot. */ - while ((heapTuple = heap_getnext(scan, ForwardScanDirection)) != NULL) + while ((heapTuple = method->scan_getnext(scan, ForwardScanDirection)) != NULL) { ItemPointer heapcursor = &heapTuple->t_self; ItemPointerData rootTuple; @@ -3163,7 +3169,7 @@ validate_index_heapscan(Relation heapRelation, } } - heap_endscan(scan); + method->scan_end(scan); ExecDropSingleTupleTableSlot(slot); diff --git a/src/backend/catalog/pg_conversion.c b/src/backend/catalog/pg_conversion.c index 5746dc3..01fb130 100644 --- a/src/backend/catalog/pg_conversion.c +++ b/src/backend/catalog/pg_conversion.c @@ -16,6 +16,7 @@ #include "access/heapam.h" #include "access/htup_details.h" +#include "access/storageamapi.h" #include "access/sysattr.h" #include "catalog/dependency.h" #include "catalog/indexing.h" @@ -152,6 +153,7 @@ RemoveConversionById(Oid conversionOid) HeapTuple tuple; HeapScanDesc scan; ScanKeyData scanKeyData; + StorageAmRoutine *method; ScanKeyInit(&scanKeyData, ObjectIdAttributeNumber, @@ -160,15 +162,15 @@ RemoveConversionById(Oid conversionOid) /* open pg_conversion */ rel = heap_open(ConversionRelationId, RowExclusiveLock); - - scan = heap_beginscan_catalog(rel, 1, &scanKeyData); + method = rel->rd_stamroutine; + scan = method->scan_begin_catalog(rel, 1, &scanKeyData); /* search for the target tuple */ - if (HeapTupleIsValid(tuple = heap_getnext(scan, ForwardScanDirection))) + if (HeapTupleIsValid(tuple = method->scan_getnext(scan, ForwardScanDirection))) CatalogTupleDelete(rel, &tuple->t_self); else elog(ERROR, "could not find tuple for conversion %u", conversionOid); - heap_endscan(scan); + method->scan_end(scan); heap_close(rel, RowExclusiveLock); } diff --git a/src/backend/catalog/pg_db_role_setting.c b/src/backend/catalog/pg_db_role_setting.c index 323471b..c0adb61 100644 --- a/src/backend/catalog/pg_db_role_setting.c +++ b/src/backend/catalog/pg_db_role_setting.c @@ -13,6 +13,7 @@ #include "access/genam.h" #include "access/heapam.h" #include "access/htup_details.h" +#include "access/storageamapi.h" #include "catalog/indexing.h" #include "catalog/objectaccess.h" #include "catalog/pg_db_role_setting.h" @@ -174,9 +175,10 @@ DropSetting(Oid databaseid, Oid roleid) ScanKeyData keys[2]; HeapTuple tup; int numkeys = 0; + StorageAmRoutine *method; relsetting = heap_open(DbRoleSettingRelationId, RowExclusiveLock); - + method = relsetting->rd_stamroutine; if (OidIsValid(databaseid)) { ScanKeyInit(&keys[numkeys], @@ -196,12 +198,12 @@ DropSetting(Oid databaseid, Oid roleid) numkeys++; } - scan = heap_beginscan_catalog(relsetting, numkeys, keys); - while (HeapTupleIsValid(tup = heap_getnext(scan, ForwardScanDirection))) + scan = method->scan_begin_catalog(relsetting, numkeys, keys); + while (HeapTupleIsValid(tup = method->scan_getnext(scan, ForwardScanDirection))) { CatalogTupleDelete(relsetting, &tup->t_self); } - heap_endscan(scan); + method->scan_end(scan); heap_close(relsetting, RowExclusiveLock); } diff --git a/src/backend/catalog/pg_publication.c b/src/backend/catalog/pg_publication.c index 17105f4..f1eeccb 100644 --- a/src/backend/catalog/pg_publication.c +++ b/src/backend/catalog/pg_publication.c @@ -292,17 +292,19 @@ GetAllTablesPublicationRelations(void) HeapScanDesc scan; HeapTuple tuple; List *result = NIL; + StorageAmRoutine *method; classRel = heap_open(RelationRelationId, AccessShareLock); + method = classRel->rd_stamroutine; ScanKeyInit(&key[0], Anum_pg_class_relkind, BTEqualStrategyNumber, F_CHAREQ, CharGetDatum(RELKIND_RELATION)); - scan = heap_beginscan_catalog(classRel, 1, key); + scan = method->scan_begin_catalog(classRel, 1, key); - while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) + while ((tuple = method->scan_getnext(scan, ForwardScanDirection)) != NULL) { Oid relid = HeapTupleGetOid(tuple); Form_pg_class relForm = (Form_pg_class) GETSTRUCT(tuple); @@ -311,7 +313,7 @@ GetAllTablesPublicationRelations(void) result = lappend_oid(result, relid); } - heap_endscan(scan); + method->scan_end(scan); heap_close(classRel, AccessShareLock); return result; diff --git a/src/backend/catalog/pg_subscription.c b/src/backend/catalog/pg_subscription.c index ab5f371..93d89d2 100644 --- a/src/backend/catalog/pg_subscription.c +++ b/src/backend/catalog/pg_subscription.c @@ -19,6 +19,7 @@ #include "access/genam.h" #include "access/heapam.h" #include "access/htup_details.h" +#include "access/storageamapi.h" #include "access/xact.h" #include "catalog/indexing.h" @@ -393,12 +394,12 @@ RemoveSubscriptionRel(Oid subid, Oid relid) } /* Do the search and delete what we found. */ - scan = heap_beginscan_catalog(rel, nkeys, skey); - while (HeapTupleIsValid(tup = heap_getnext(scan, ForwardScanDirection))) + scan = rel->rd_stamroutine->scan_begin_catalog(rel, nkeys, skey); + while (HeapTupleIsValid(tup = rel->rd_stamroutine->scan_getnext(scan, ForwardScanDirection))) { simple_heap_delete(rel, &tup->t_self); } - heap_endscan(scan); + rel->rd_stamroutine->scan_end(scan); heap_close(rel, RowExclusiveLock); } diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c index ef1abf3..5786226 100644 --- a/src/backend/commands/cluster.c +++ b/src/backend/commands/cluster.c @@ -21,6 +21,7 @@ #include "access/multixact.h" #include "access/relscan.h" #include "access/rewriteheap.h" +#include "access/storageamapi.h" #include "access/transam.h" #include "access/tuptoaster.h" #include "access/xact.h" @@ -758,6 +759,7 @@ copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex, bool verbose, tups_recently_dead = 0; int elevel = verbose ? INFO : DEBUG2; PGRUsage ru0; + StorageAmRoutine *method; pg_rusage_init(&ru0); @@ -771,6 +773,8 @@ copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex, bool verbose, else OldIndex = NULL; + method = OldHeap->rd_stamroutine; + /* * Their tuple descriptors should be exactly alike, but here we only need * assume that they have the same number of columns. @@ -908,7 +912,7 @@ copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex, bool verbose, } else { - heapScan = heap_beginscan(OldHeap, SnapshotAny, 0, (ScanKey) NULL); + heapScan = method->scan_begin(OldHeap, SnapshotAny, 0, (ScanKey) NULL); indexScan = NULL; } @@ -958,7 +962,7 @@ copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex, bool verbose, } else { - tuple = heap_getnext(heapScan, ForwardScanDirection); + tuple = method->scan_getnext(heapScan, ForwardScanDirection); if (tuple == NULL) break; @@ -1044,7 +1048,7 @@ copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex, bool verbose, if (indexScan != NULL) index_endscan(indexScan); if (heapScan != NULL) - heap_endscan(heapScan); + method->scan_end(heapScan); /* * In scan-and-sort mode, complete the sort, then read out all live tuples @@ -1643,6 +1647,7 @@ get_tables_to_cluster(MemoryContext cluster_context) MemoryContext old_context; RelToCluster *rvtc; List *rvs = NIL; + StorageAmRoutine *method; /* * Get all indexes that have indisclustered set and are owned by @@ -1651,12 +1656,13 @@ get_tables_to_cluster(MemoryContext cluster_context) * called with one of them as argument. */ indRelation = heap_open(IndexRelationId, AccessShareLock); + method = indRelation->rd_stamroutine; ScanKeyInit(&entry, Anum_pg_index_indisclustered, BTEqualStrategyNumber, F_BOOLEQ, BoolGetDatum(true)); - scan = heap_beginscan_catalog(indRelation, 1, &entry); - while ((indexTuple = heap_getnext(scan, ForwardScanDirection)) != NULL) + scan = method->scan_begin_catalog(indRelation, 1, &entry); + while ((indexTuple = method->scan_getnext(scan, ForwardScanDirection)) != NULL) { index = (Form_pg_index) GETSTRUCT(indexTuple); @@ -1676,7 +1682,7 @@ get_tables_to_cluster(MemoryContext cluster_context) MemoryContextSwitchTo(old_context); } - heap_endscan(scan); + method->scan_end(scan); relation_close(indRelation, AccessShareLock); diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index afa4cb1..810c0cd 100644 --- a/src/backend/commands/copy.c +++ b/src/backend/commands/copy.c @@ -2042,14 +2042,15 @@ CopyTo(CopyState cstate) bool *nulls; HeapScanDesc scandesc; HeapTuple tuple; + StorageAmRoutine *method = cstate->rel->rd_stamroutine; values = (Datum *) palloc(num_phys_attrs * sizeof(Datum)); nulls = (bool *) palloc(num_phys_attrs * sizeof(bool)); - scandesc = heap_beginscan(cstate->rel, GetActiveSnapshot(), 0, NULL); + scandesc = method->scan_begin(cstate->rel, GetActiveSnapshot(), 0, NULL); processed = 0; - while ((tuple = heap_getnext(scandesc, ForwardScanDirection)) != NULL) + while ((tuple = method->scan_getnext(scandesc, ForwardScanDirection)) != NULL) { CHECK_FOR_INTERRUPTS(); @@ -2061,7 +2062,7 @@ CopyTo(CopyState cstate) processed++; } - heap_endscan(scandesc); + method->scan_end(scandesc); pfree(values); pfree(nulls); diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c index 11038f6..ed19018 100644 --- a/src/backend/commands/dbcommands.c +++ b/src/backend/commands/dbcommands.c @@ -26,6 +26,7 @@ #include "access/genam.h" #include "access/heapam.h" #include "access/htup_details.h" +#include "access/storageamapi.h" #include "access/xact.h" #include "access/xloginsert.h" #include "access/xlogutils.h" @@ -585,13 +586,16 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt) PG_ENSURE_ERROR_CLEANUP(createdb_failure_callback, PointerGetDatum(&fparms)); { + StorageAmRoutine *method; + /* * Iterate through all tablespaces of the template database, and copy * each one to the new database. */ rel = heap_open(TableSpaceRelationId, AccessShareLock); - scan = heap_beginscan_catalog(rel, 0, NULL); - while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) + method = rel->rd_stamroutine; + scan = method->scan_begin_catalog(rel, 0, NULL); + while ((tuple = method->scan_getnext(scan, ForwardScanDirection)) != NULL) { Oid srctablespace = HeapTupleGetOid(tuple); Oid dsttablespace; @@ -643,7 +647,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt) XLOG_DBASE_CREATE | XLR_SPECIAL_REL_UPDATE); } } - heap_endscan(scan); + method->scan_end(scan); heap_close(rel, AccessShareLock); /* @@ -1873,10 +1877,12 @@ remove_dbtablespaces(Oid db_id) Relation rel; HeapScanDesc scan; HeapTuple tuple; + StorageAmRoutine *method; rel = heap_open(TableSpaceRelationId, AccessShareLock); - scan = heap_beginscan_catalog(rel, 0, NULL); - while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) + method = rel->rd_stamroutine; + scan = method->scan_begin_catalog(rel, 0, NULL); + while ((tuple = method->scan_getnext(scan, ForwardScanDirection)) != NULL) { Oid dsttablespace = HeapTupleGetOid(tuple); char *dstpath; @@ -1917,7 +1923,7 @@ remove_dbtablespaces(Oid db_id) pfree(dstpath); } - heap_endscan(scan); + method->scan_end(scan); heap_close(rel, AccessShareLock); } @@ -1940,10 +1946,12 @@ check_db_file_conflict(Oid db_id) Relation rel; HeapScanDesc scan; HeapTuple tuple; + StorageAmRoutine *method; rel = heap_open(TableSpaceRelationId, AccessShareLock); - scan = heap_beginscan_catalog(rel, 0, NULL); - while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) + method = rel->rd_stamroutine; + scan = method->scan_begin_catalog(rel, 0, NULL); + while ((tuple = method->scan_getnext(scan, ForwardScanDirection)) != NULL) { Oid dsttablespace = HeapTupleGetOid(tuple); char *dstpath; @@ -1966,7 +1974,7 @@ check_db_file_conflict(Oid db_id) pfree(dstpath); } - heap_endscan(scan); + method->scan_end(scan); heap_close(rel, AccessShareLock); return result; diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index 4861799..d5554c5 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -18,6 +18,7 @@ #include "access/amapi.h" #include "access/htup_details.h" #include "access/reloptions.h" +#include "access/storageamapi.h" #include "access/sysattr.h" #include "access/xact.h" #include "catalog/catalog.h" @@ -1869,6 +1870,7 @@ ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind, List *relids = NIL; ListCell *l; int num_keys; + StorageAmRoutine *method; AssertArg(objectName); Assert(objectKind == REINDEX_OBJECT_SCHEMA || @@ -1935,8 +1937,9 @@ ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind, * rels will be processed indirectly by reindex_relation). */ relationRelation = heap_open(RelationRelationId, AccessShareLock); - scan = heap_beginscan_catalog(relationRelation, num_keys, scan_keys); - while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) + method = relationRelation->rd_stamroutine; + scan = method->scan_begin_catalog(relationRelation, num_keys, scan_keys); + while ((tuple = method->scan_getnext(scan, ForwardScanDirection)) != NULL) { Form_pg_class classtuple = (Form_pg_class) GETSTRUCT(tuple); Oid relid = HeapTupleGetOid(tuple); @@ -1976,7 +1979,7 @@ ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind, MemoryContextSwitchTo(old); } - heap_endscan(scan); + method->scan_end(scan); heap_close(relationRelation, AccessShareLock); /* Now reindex each rel in a separate transaction */ diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index fb961e4..8256145 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -4424,6 +4424,7 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode) List *dropped_attrs = NIL; ListCell *lc; Snapshot snapshot; + StorageAmRoutine *method = oldrel->rd_stamroutine; if (newrel) ereport(DEBUG1, @@ -4477,7 +4478,7 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode) * checking all the constraints. */ snapshot = RegisterSnapshot(GetLatestSnapshot()); - scan = heap_beginscan(oldrel, snapshot, 0, NULL); + scan = method->scan_begin(oldrel, snapshot, 0, NULL); /* * Switch to per-tuple memory context and reset it for each tuple @@ -4485,7 +4486,7 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode) */ oldCxt = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate)); - while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) + while ((tuple = method->scan_getnext(scan, ForwardScanDirection)) != NULL) { if (tab->rewrite > 0) { @@ -4579,7 +4580,7 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode) /* Write the tuple out to the new relation */ if (newrel) - heap_insert(newrel, tuple, mycid, hi_options, bistate); + newrel->rd_stamroutine->tuple_insert(newrel, newslot, mycid, hi_options, bistate, &tuple->t_self); ResetExprContext(econtext); @@ -4587,7 +4588,7 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode) } MemoryContextSwitchTo(oldCxt); - heap_endscan(scan); + method->scan_end(scan); UnregisterSnapshot(snapshot); ExecDropSingleTupleTableSlot(oldslot); @@ -4969,17 +4970,18 @@ find_typed_table_dependencies(Oid typeOid, const char *typeName, DropBehavior be HeapScanDesc scan; HeapTuple tuple; List *result = NIL; + StorageAmRoutine *method; classRel = heap_open(RelationRelationId, AccessShareLock); - + method = classRel->rd_stamroutine; ScanKeyInit(&key[0], Anum_pg_class_reloftype, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(typeOid)); - scan = heap_beginscan_catalog(classRel, 1, key); + scan = method->scan_begin_catalog(classRel, 1, key); - while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) + while ((tuple = method->scan_getnext(scan, ForwardScanDirection)) != NULL) { if (behavior == DROP_RESTRICT) ereport(ERROR, @@ -4991,7 +4993,7 @@ find_typed_table_dependencies(Oid typeOid, const char *typeName, DropBehavior be result = lappend_oid(result, HeapTupleGetOid(tuple)); } - heap_endscan(scan); + method->scan_end(scan); heap_close(classRel, AccessShareLock); return result; @@ -8090,6 +8092,7 @@ validateCheckConstraint(Relation rel, HeapTuple constrtup) Form_pg_constraint constrForm; bool isnull; Snapshot snapshot; + StorageAmRoutine *method; /* * VALIDATE CONSTRAINT is a no-op for foreign tables and partitioned @@ -8123,7 +8126,8 @@ validateCheckConstraint(Relation rel, HeapTuple constrtup) econtext->ecxt_scantuple = slot; snapshot = RegisterSnapshot(GetLatestSnapshot()); - scan = heap_beginscan(rel, snapshot, 0, NULL); + method = rel->rd_stamroutine; + scan = method->scan_begin(rel, snapshot, 0, NULL); /* * Switch to per-tuple memory context and reset it for each tuple @@ -8131,7 +8135,7 @@ validateCheckConstraint(Relation rel, HeapTuple constrtup) */ oldcxt = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate)); - while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) + while ((tuple = method->scan_getnext(scan, ForwardScanDirection)) != NULL) { ExecStoreTuple(tuple, slot, InvalidBuffer, false); @@ -8146,7 +8150,7 @@ validateCheckConstraint(Relation rel, HeapTuple constrtup) } MemoryContextSwitchTo(oldcxt); - heap_endscan(scan); + method->scan_end(scan); UnregisterSnapshot(snapshot); ExecDropSingleTupleTableSlot(slot); FreeExecutorState(estate); @@ -8169,6 +8173,7 @@ validateForeignKeyConstraint(char *conname, HeapTuple tuple; Trigger trig; Snapshot snapshot; + StorageAmRoutine *method; ereport(DEBUG1, (errmsg("validating foreign key constraint \"%s\"", conname))); @@ -8201,9 +8206,10 @@ validateForeignKeyConstraint(char *conname, * ereport(ERROR) and that's that. */ snapshot = RegisterSnapshot(GetLatestSnapshot()); - scan = heap_beginscan(rel, snapshot, 0, NULL); + method = rel->rd_stamroutine; + scan = method->scan_begin(rel, snapshot, 0, NULL); - while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) + while ((tuple = method->scan_getnext(scan, ForwardScanDirection)) != NULL) { FunctionCallInfoData fcinfo; TriggerData trigdata; @@ -8232,7 +8238,7 @@ validateForeignKeyConstraint(char *conname, RI_FKey_check_ins(&fcinfo); } - heap_endscan(scan); + method->scan_end(scan); UnregisterSnapshot(snapshot); } @@ -10620,6 +10626,7 @@ AlterTableMoveAll(AlterTableMoveAllStmt *stmt) Oid orig_tablespaceoid; Oid new_tablespaceoid; List *role_oids = roleSpecsToIds(stmt->roles); + StorageAmRoutine *method; /* Ensure we were not asked to move something we can't */ if (stmt->objtype != OBJECT_TABLE && stmt->objtype != OBJECT_INDEX && @@ -10680,8 +10687,9 @@ AlterTableMoveAll(AlterTableMoveAllStmt *stmt) ObjectIdGetDatum(orig_tablespaceoid)); rel = heap_open(RelationRelationId, AccessShareLock); - scan = heap_beginscan_catalog(rel, 1, key); - while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) + method = rel->rd_stamroutine; + scan = method->scan_begin_catalog(rel, 1, key); + while ((tuple = method->scan_getnext(scan, ForwardScanDirection)) != NULL) { Oid relOid = HeapTupleGetOid(tuple); Form_pg_class relForm; @@ -10740,7 +10748,7 @@ AlterTableMoveAll(AlterTableMoveAllStmt *stmt) relations = lappend_oid(relations, relOid); } - heap_endscan(scan); + method->scan_end(scan); heap_close(rel, AccessShareLock); if (relations == NIL) diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c index f9c2620..ca7145e 100644 --- a/src/backend/commands/tablespace.c +++ b/src/backend/commands/tablespace.c @@ -53,6 +53,7 @@ #include "access/heapam.h" #include "access/reloptions.h" #include "access/htup_details.h" +#include "access/storageamapi.h" #include "access/sysattr.h" #include "access/xact.h" #include "access/xlog.h" @@ -406,18 +407,19 @@ DropTableSpace(DropTableSpaceStmt *stmt) HeapTuple tuple; ScanKeyData entry[1]; Oid tablespaceoid; + StorageAmRoutine *method; /* * Find the target tuple */ rel = heap_open(TableSpaceRelationId, RowExclusiveLock); - + method = rel->rd_stamroutine; ScanKeyInit(&entry[0], Anum_pg_tablespace_spcname, BTEqualStrategyNumber, F_NAMEEQ, CStringGetDatum(tablespacename)); - scandesc = heap_beginscan_catalog(rel, 1, entry); - tuple = heap_getnext(scandesc, ForwardScanDirection); + scandesc = method->scan_begin_catalog(rel, 1, entry); + tuple = method->scan_getnext(scandesc, ForwardScanDirection); if (!HeapTupleIsValid(tuple)) { @@ -434,7 +436,7 @@ DropTableSpace(DropTableSpaceStmt *stmt) (errmsg("tablespace \"%s\" does not exist, skipping", tablespacename))); /* XXX I assume I need one or both of these next two calls */ - heap_endscan(scandesc); + method->scan_end(scandesc); heap_close(rel, NoLock); } return; @@ -461,7 +463,7 @@ DropTableSpace(DropTableSpaceStmt *stmt) */ CatalogTupleDelete(rel, &tuple->t_self); - heap_endscan(scandesc); + method->scan_end(scandesc); /* * Remove any comments or security labels on this tablespace. @@ -917,16 +919,17 @@ RenameTableSpace(const char *oldname, const char *newname) HeapTuple newtuple; Form_pg_tablespace newform; ObjectAddress address; + StorageAmRoutine *method; /* Search pg_tablespace */ rel = heap_open(TableSpaceRelationId, RowExclusiveLock); - + method = rel->rd_stamroutine; ScanKeyInit(&entry[0], Anum_pg_tablespace_spcname, BTEqualStrategyNumber, F_NAMEEQ, CStringGetDatum(oldname)); - scan = heap_beginscan_catalog(rel, 1, entry); - tup = heap_getnext(scan, ForwardScanDirection); + scan = method->scan_begin_catalog(rel, 1, entry); + tup = method->scan_getnext(scan, ForwardScanDirection); if (!HeapTupleIsValid(tup)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), @@ -937,7 +940,7 @@ RenameTableSpace(const char *oldname, const char *newname) newtuple = heap_copytuple(tup); newform = (Form_pg_tablespace) GETSTRUCT(newtuple); - heap_endscan(scan); + method->scan_end(scan); /* Must be owner */ if (!pg_tablespace_ownercheck(HeapTupleGetOid(newtuple), GetUserId())) @@ -955,15 +958,15 @@ RenameTableSpace(const char *oldname, const char *newname) Anum_pg_tablespace_spcname, BTEqualStrategyNumber, F_NAMEEQ, CStringGetDatum(newname)); - scan = heap_beginscan_catalog(rel, 1, entry); - tup = heap_getnext(scan, ForwardScanDirection); + scan = method->scan_begin_catalog(rel, 1, entry); + tup = method->scan_getnext(scan, ForwardScanDirection); if (HeapTupleIsValid(tup)) ereport(ERROR, (errcode(ERRCODE_DUPLICATE_OBJECT), errmsg("tablespace \"%s\" already exists", newname))); - heap_endscan(scan); + method->scan_end(scan); /* OK, update the entry */ namestrcpy(&(newform->spcname), newname); @@ -997,16 +1000,17 @@ AlterTableSpaceOptions(AlterTableSpaceOptionsStmt *stmt) bool repl_null[Natts_pg_tablespace]; bool repl_repl[Natts_pg_tablespace]; HeapTuple newtuple; + StorageAmRoutine *method; /* Search pg_tablespace */ rel = heap_open(TableSpaceRelationId, RowExclusiveLock); - + method = rel->rd_stamroutine; ScanKeyInit(&entry[0], Anum_pg_tablespace_spcname, BTEqualStrategyNumber, F_NAMEEQ, CStringGetDatum(stmt->tablespacename)); - scandesc = heap_beginscan_catalog(rel, 1, entry); - tup = heap_getnext(scandesc, ForwardScanDirection); + scandesc = method->scan_begin_catalog(rel, 1, entry); + tup = method->scan_getnext(scandesc, ForwardScanDirection); if (!HeapTupleIsValid(tup)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), @@ -1047,7 +1051,7 @@ AlterTableSpaceOptions(AlterTableSpaceOptionsStmt *stmt) heap_freetuple(newtuple); /* Conclude heap scan. */ - heap_endscan(scandesc); + method->scan_end(scandesc); heap_close(rel, NoLock); return tablespaceoid; @@ -1384,6 +1388,7 @@ get_tablespace_oid(const char *tablespacename, bool missing_ok) HeapScanDesc scandesc; HeapTuple tuple; ScanKeyData entry[1]; + StorageAmRoutine *method; /* * Search pg_tablespace. We use a heapscan here even though there is an @@ -1391,13 +1396,13 @@ get_tablespace_oid(const char *tablespacename, bool missing_ok) * a few entries and so an indexed lookup is a waste of effort. */ rel = heap_open(TableSpaceRelationId, AccessShareLock); - + method = rel->rd_stamroutine; ScanKeyInit(&entry[0], Anum_pg_tablespace_spcname, BTEqualStrategyNumber, F_NAMEEQ, CStringGetDatum(tablespacename)); - scandesc = heap_beginscan_catalog(rel, 1, entry); - tuple = heap_getnext(scandesc, ForwardScanDirection); + scandesc = method->scan_begin_catalog(rel, 1, entry); + tuple = method->scan_getnext(scandesc, ForwardScanDirection); /* We assume that there can be at most one matching tuple */ if (HeapTupleIsValid(tuple)) @@ -1405,7 +1410,7 @@ get_tablespace_oid(const char *tablespacename, bool missing_ok) else result = InvalidOid; - heap_endscan(scandesc); + method->scan_end(scandesc); heap_close(rel, AccessShareLock); if (!OidIsValid(result) && !missing_ok) @@ -1430,6 +1435,7 @@ get_tablespace_name(Oid spc_oid) HeapScanDesc scandesc; HeapTuple tuple; ScanKeyData entry[1]; + StorageAmRoutine *method; /* * Search pg_tablespace. We use a heapscan here even though there is an @@ -1437,13 +1443,13 @@ get_tablespace_name(Oid spc_oid) * few entries and so an indexed lookup is a waste of effort. */ rel = heap_open(TableSpaceRelationId, AccessShareLock); - + method = rel->rd_stamroutine; ScanKeyInit(&entry[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(spc_oid)); - scandesc = heap_beginscan_catalog(rel, 1, entry); - tuple = heap_getnext(scandesc, ForwardScanDirection); + scandesc = method->scan_begin_catalog(rel, 1, entry); + tuple = method->scan_getnext(scandesc, ForwardScanDirection); /* We assume that there can be at most one matching tuple */ if (HeapTupleIsValid(tuple)) @@ -1451,7 +1457,7 @@ get_tablespace_name(Oid spc_oid) else result = NULL; - heap_endscan(scandesc); + method->scan_end(scandesc); heap_close(rel, AccessShareLock); return result; diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c index c765e97..2c494cc 100644 --- a/src/backend/commands/typecmds.c +++ b/src/backend/commands/typecmds.c @@ -2312,11 +2312,13 @@ AlterDomainNotNull(List *names, bool notNull) HeapScanDesc scan; HeapTuple tuple; Snapshot snapshot; + StorageAmRoutine *method; /* Scan all tuples in this relation */ snapshot = RegisterSnapshot(GetLatestSnapshot()); - scan = heap_beginscan(testrel, snapshot, 0, NULL); - while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) + method = testrel->rd_stamroutine; + scan = method->scan_begin(testrel, snapshot, 0, NULL); + while ((tuple = method->scan_getnext(scan, ForwardScanDirection)) != NULL) { int i; @@ -2344,7 +2346,7 @@ AlterDomainNotNull(List *names, bool notNull) } } } - heap_endscan(scan); + method->scan_end(scan); UnregisterSnapshot(snapshot); /* Close each rel after processing, but keep lock */ @@ -2707,11 +2709,12 @@ validateDomainConstraint(Oid domainoid, char *ccbin) HeapScanDesc scan; HeapTuple tuple; Snapshot snapshot; + StorageAmRoutine *method = testrel->rd_stamroutine; /* Scan all tuples in this relation */ snapshot = RegisterSnapshot(GetLatestSnapshot()); - scan = heap_beginscan(testrel, snapshot, 0, NULL); - while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) + scan = method->scan_begin(testrel, snapshot, 0, NULL); + while ((tuple = method->scan_getnext(scan, ForwardScanDirection)) != NULL) { int i; @@ -2753,7 +2756,7 @@ validateDomainConstraint(Oid domainoid, char *ccbin) ResetExprContext(econtext); } - heap_endscan(scan); + method->scan_end(scan); UnregisterSnapshot(snapshot); /* Hold relation lock till commit (XXX bad for concurrency) */ diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 9fbb0eb..e30f270 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -28,6 +28,7 @@ #include "access/heapam.h" #include "access/htup_details.h" #include "access/multixact.h" +#include "access/storageamapi.h" #include "access/transam.h" #include "access/xact.h" #include "catalog/namespace.h" @@ -444,12 +445,14 @@ get_rel_oids(Oid relid, const RangeVar *vacrel) Relation pgclass; HeapScanDesc scan; HeapTuple tuple; + StorageAmRoutine *method; pgclass = heap_open(RelationRelationId, AccessShareLock); + method = pgclass->rd_stamroutine; - scan = heap_beginscan_catalog(pgclass, 0, NULL); + scan = method->scan_begin_catalog(pgclass, 0, NULL); - while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) + while ((tuple = method->scan_getnext(scan, ForwardScanDirection)) != NULL) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); @@ -469,7 +472,7 @@ get_rel_oids(Oid relid, const RangeVar *vacrel) MemoryContextSwitchTo(oldcontext); } - heap_endscan(scan); + method->scan_end(scan); heap_close(pgclass, AccessShareLock); } @@ -1096,6 +1099,7 @@ vac_truncate_clog(TransactionId frozenXID, Oid minmulti_datoid; bool bogus = false; bool frozenAlreadyWrapped = false; + StorageAmRoutine *method; /* init oldest datoids to sync with my frozenXID/minMulti values */ oldestxid_datoid = MyDatabaseId; @@ -1120,10 +1124,10 @@ vac_truncate_clog(TransactionId frozenXID, * as it could be. */ relation = heap_open(DatabaseRelationId, AccessShareLock); + method = relation->rd_stamroutine; + scan = method->scan_begin_catalog(relation, 0, NULL); - scan = heap_beginscan_catalog(relation, 0, NULL); - - while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) + while ((tuple = method->scan_getnext(scan, ForwardScanDirection)) != NULL) { volatile FormData_pg_database *dbform = (Form_pg_database) GETSTRUCT(tuple); TransactionId datfrozenxid = dbform->datfrozenxid; @@ -1160,7 +1164,7 @@ vac_truncate_clog(TransactionId frozenXID, } } - heap_endscan(scan); + method->scan_end(scan); heap_close(relation, AccessShareLock); diff --git a/src/backend/executor/execReplication.c b/src/backend/executor/execReplication.c index 206238a..dca2f08 100644 --- a/src/backend/executor/execReplication.c +++ b/src/backend/executor/execReplication.c @@ -270,25 +270,27 @@ RelationFindReplTupleSeq(Relation rel, LockTupleMode lockmode, TupleTableSlot *searchslot, TupleTableSlot *outslot) { StorageTuple scantuple; - HeapScanDesc scan; + StorageScanDesc scan; SnapshotData snap; TransactionId xwait; bool found; TupleDesc desc = RelationGetDescr(rel); + StorageAmRoutine *method; Assert(equalTupleDescs(desc, outslot->tts_tupleDescriptor)); /* Start an index scan. */ InitDirtySnapshot(snap); - scan = heap_beginscan(rel, &snap, 0, NULL); + method = rel->rd_stamroutine; + scan = method->scan_begin(rel, &snap, 0, NULL); retry: found = false; - heap_rescan(scan, NULL); + method->scan_rescan(scan, NULL); /* Try to find the tuple */ - while ((scantuple = heap_getnext(scan, ForwardScanDirection)) != NULL) + while ((scantuple = method->scan_getnext(scan, ForwardScanDirection)) != NULL) { if (!tuple_equals_slot(desc, scantuple, searchslot)) continue; @@ -353,7 +355,7 @@ retry: } } - heap_endscan(scan); + method->scan_end(scan); return found; } diff --git a/src/backend/executor/nodeBitmapHeapscan.c b/src/backend/executor/nodeBitmapHeapscan.c index f8a4e7d..51d8f74 100644 --- a/src/backend/executor/nodeBitmapHeapscan.c +++ b/src/backend/executor/nodeBitmapHeapscan.c @@ -690,7 +690,7 @@ ExecReScanBitmapHeapScan(BitmapHeapScanState *node) PlanState *outerPlan = outerPlanState(node); /* rescan to release any page pin */ - heap_rescan(node->ss.ss_currentScanDesc, NULL); + node->ss.ss_currentRelation->rd_stamroutine->scan_rescan(node->ss.ss_currentScanDesc, NULL); if (node->tbmiterator) tbm_end_iterate(node->tbmiterator); @@ -745,7 +745,7 @@ void ExecEndBitmapHeapScan(BitmapHeapScanState *node) { Relation relation; - HeapScanDesc scanDesc; + StorageScanDesc scanDesc; /* * extract information from the node @@ -786,7 +786,7 @@ ExecEndBitmapHeapScan(BitmapHeapScanState *node) /* * close heap scan */ - heap_endscan(scanDesc); + relation->rd_stamroutine->scan_end(scanDesc); /* * close the heap relation. @@ -884,9 +884,10 @@ ExecInitBitmapHeapScan(BitmapHeapScan *node, EState *estate, int eflags) /* * Even though we aren't going to do a conventional seqscan, it is useful - * to create a HeapScanDesc --- most of the fields in it are usable. + * to create a StorageScanDesc --- most of the fields in it are usable. */ - scanstate->ss.ss_currentScanDesc = heap_beginscan_bm(currentRelation, + scanstate->ss.ss_currentScanDesc + = currentRelation->rd_stamroutine->scan_begin_bm(currentRelation, estate->es_snapshot, 0, NULL); @@ -1019,5 +1020,5 @@ ExecBitmapHeapInitializeWorker(BitmapHeapScanState *node, shm_toc *toc) node->pstate = pstate; snapshot = RestoreSnapshot(pstate->phs_snapshot_data); - heap_update_snapshot(node->ss.ss_currentScanDesc, snapshot); + node->ss.ss_currentRelation->rd_stamroutine->scan_update_snapshot(node->ss.ss_currentScanDesc, snapshot); } diff --git a/src/backend/executor/nodeSamplescan.c b/src/backend/executor/nodeSamplescan.c index 51fb182..a7d2ba8 100644 --- a/src/backend/executor/nodeSamplescan.c +++ b/src/backend/executor/nodeSamplescan.c @@ -242,7 +242,7 @@ ExecEndSampleScan(SampleScanState *node) * close heap scan */ if (node->ss.ss_currentScanDesc) - heap_endscan(node->ss.ss_currentScanDesc); + node->ss.ss_currentRelation->rd_stamroutine->scan_end(node->ss.ss_currentScanDesc); /* * close the heap relation. @@ -347,7 +347,7 @@ tablesample_init(SampleScanState *scanstate) if (scanstate->ss.ss_currentScanDesc == NULL) { scanstate->ss.ss_currentScanDesc = - heap_beginscan_sampling(scanstate->ss.ss_currentRelation, + scanstate->ss.ss_currentRelation->rd_stamroutine->scan_begin_sampling(scanstate->ss.ss_currentRelation, scanstate->ss.ps.state->es_snapshot, 0, NULL, scanstate->use_bulkread, @@ -356,7 +356,7 @@ tablesample_init(SampleScanState *scanstate) } else { - heap_rescan_set_params(scanstate->ss.ss_currentScanDesc, NULL, + scanstate->ss.ss_currentRelation->rd_stamroutine->scan_rescan_set_params(scanstate->ss.ss_currentScanDesc, NULL, scanstate->use_bulkread, allow_sync, scanstate->use_pagemode); diff --git a/src/backend/executor/nodeSeqscan.c b/src/backend/executor/nodeSeqscan.c index 9cba6b3..5096248 100644 --- a/src/backend/executor/nodeSeqscan.c +++ b/src/backend/executor/nodeSeqscan.c @@ -27,6 +27,7 @@ #include "postgres.h" #include "access/relscan.h" +#include "access/storageamapi.h" #include "executor/execdebug.h" #include "executor/nodeSeqscan.h" #include "utils/rel.h" @@ -53,10 +54,12 @@ SeqNext(SeqScanState *node) EState *estate; ScanDirection direction; TupleTableSlot *slot; + StorageAmRoutine *method; /* * get information from the estate and scan state */ + method = node->ss.ss_currentRelation->rd_stamroutine; scandesc = node->ss.ss_currentScanDesc; estate = node->ss.ps.state; direction = estate->es_direction; @@ -68,7 +71,7 @@ SeqNext(SeqScanState *node) * We reach here if the scan is not parallel, or if we're executing a * scan that was intended to be parallel serially. */ - scandesc = heap_beginscan(node->ss.ss_currentRelation, + scandesc = method->scan_begin(node->ss.ss_currentRelation, estate->es_snapshot, 0, NULL); node->ss.ss_currentScanDesc = scandesc; @@ -77,7 +80,7 @@ SeqNext(SeqScanState *node) /* * get the next tuple from the table */ - tuple = heap_getnext(scandesc, direction); + tuple = method->scan_getnext(scandesc, direction); /* * save the tuple and the buffer returned to us by the access methods in @@ -245,7 +248,7 @@ ExecEndSeqScan(SeqScanState *node) * close heap scan */ if (scanDesc != NULL) - heap_endscan(scanDesc); + relation->rd_stamroutine->scan_end(scanDesc); /* * close the heap relation. @@ -272,7 +275,7 @@ ExecReScanSeqScan(SeqScanState *node) scan = node->ss.ss_currentScanDesc; if (scan != NULL) - heap_rescan(scan, /* scan desc */ + node->ss.ss_currentRelation->rd_stamroutine->scan_rescan(scan, /* scan desc */ NULL); /* new scan keys */ ExecScanReScan((ScanState *) node); diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index 89dd3b3..e6b8ee0 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -69,6 +69,7 @@ #include "access/htup_details.h" #include "access/multixact.h" #include "access/reloptions.h" +#include "access/storageamapi.h" #include "access/transam.h" #include "access/xact.h" #include "catalog/dependency.h" @@ -1887,6 +1888,7 @@ get_database_list(void) HeapScanDesc scan; HeapTuple tup; MemoryContext resultcxt; + StorageAmRoutine *method; /* This is the context that we will allocate our output data in */ resultcxt = CurrentMemoryContext; @@ -1902,9 +1904,10 @@ get_database_list(void) (void) GetTransactionSnapshot(); rel = heap_open(DatabaseRelationId, AccessShareLock); - scan = heap_beginscan_catalog(rel, 0, NULL); + method = rel->rd_stamroutine; + scan = method->scan_begin_catalog(rel, 0, NULL); - while (HeapTupleIsValid(tup = heap_getnext(scan, ForwardScanDirection))) + while (HeapTupleIsValid(tup = method->scan_getnext(scan, ForwardScanDirection))) { Form_pg_database pgdatabase = (Form_pg_database) GETSTRUCT(tup); avw_dbase *avdb; @@ -1931,7 +1934,7 @@ get_database_list(void) MemoryContextSwitchTo(oldcxt); } - heap_endscan(scan); + method->scan_end(scan); heap_close(rel, AccessShareLock); CommitTransactionCommand(); @@ -1965,6 +1968,7 @@ do_autovacuum(void) int effective_multixact_freeze_max_age; bool did_vacuum = false; bool found_concurrent_worker = false; + StorageAmRoutine *method; /* * StartTransactionCommand and CommitTransactionCommand will automatically @@ -2033,6 +2037,7 @@ do_autovacuum(void) shared = pgstat_fetch_stat_dbentry(InvalidOid); classRel = heap_open(RelationRelationId, AccessShareLock); + method = classRel->rd_stamroutine; /* create a copy so we can use it after closing pg_class */ pg_class_desc = CreateTupleDescCopy(RelationGetDescr(classRel)); @@ -2061,13 +2066,13 @@ do_autovacuum(void) * wide tables there might be proportionally much more activity in the * TOAST table than in its parent. */ - relScan = heap_beginscan_catalog(classRel, 0, NULL); + relScan = method->scan_begin_catalog(classRel, 0, NULL); /* * On the first pass, we collect main tables to vacuum, and also the main * table relid to TOAST relid mapping. */ - while ((tuple = heap_getnext(relScan, ForwardScanDirection)) != NULL) + while ((tuple = method->scan_getnext(relScan, ForwardScanDirection)) != NULL) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); PgStat_StatTabEntry *tabentry; @@ -2153,7 +2158,7 @@ do_autovacuum(void) } } - heap_endscan(relScan); + method->scan_end(relScan); /* second pass: check TOAST tables */ ScanKeyInit(&key, @@ -2161,8 +2166,8 @@ do_autovacuum(void) BTEqualStrategyNumber, F_CHAREQ, CharGetDatum(RELKIND_TOASTVALUE)); - relScan = heap_beginscan_catalog(classRel, 1, &key); - while ((tuple = heap_getnext(relScan, ForwardScanDirection)) != NULL) + relScan = method->scan_begin_catalog(classRel, 1, &key); + while ((tuple = method->scan_getnext(relScan, ForwardScanDirection)) != NULL) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); PgStat_StatTabEntry *tabentry; @@ -2208,7 +2213,7 @@ do_autovacuum(void) table_oids = lappend_oid(table_oids, relid); } - heap_endscan(relScan); + method->scan_end(relScan); heap_close(classRel, AccessShareLock); /* diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c index f453dad..d07914b 100644 --- a/src/backend/postmaster/pgstat.c +++ b/src/backend/postmaster/pgstat.c @@ -36,6 +36,7 @@ #include "access/heapam.h" #include "access/htup_details.h" +#include "access/storageamapi.h" #include "access/transam.h" #include "access/twophase_rmgr.h" #include "access/xact.h" @@ -1209,6 +1210,7 @@ pgstat_collect_oids(Oid catalogid) HeapScanDesc scan; HeapTuple tup; Snapshot snapshot; + StorageAmRoutine *method; memset(&hash_ctl, 0, sizeof(hash_ctl)); hash_ctl.keysize = sizeof(Oid); @@ -1221,8 +1223,9 @@ pgstat_collect_oids(Oid catalogid) rel = heap_open(catalogid, AccessShareLock); snapshot = RegisterSnapshot(GetLatestSnapshot()); - scan = heap_beginscan(rel, snapshot, 0, NULL); - while ((tup = heap_getnext(scan, ForwardScanDirection)) != NULL) + method = rel->rd_stamroutine; + scan = method->scan_begin(rel, snapshot, 0, NULL); + while ((tup = method->scan_getnext(scan, ForwardScanDirection)) != NULL) { Oid thisoid = HeapTupleGetOid(tup); @@ -1230,7 +1233,7 @@ pgstat_collect_oids(Oid catalogid) (void) hash_search(htab, (void *) &thisoid, HASH_ENTER, NULL); } - heap_endscan(scan); + method->scan_end(scan); UnregisterSnapshot(snapshot); heap_close(rel, AccessShareLock); diff --git a/src/backend/replication/logical/launcher.c b/src/backend/replication/logical/launcher.c index 4e2c350..9813efc 100644 --- a/src/backend/replication/logical/launcher.c +++ b/src/backend/replication/logical/launcher.c @@ -102,6 +102,7 @@ get_subscription_list(void) HeapScanDesc scan; HeapTuple tup; MemoryContext resultcxt; + StorageAmRoutine *method; /* This is the context that we will allocate our output data in */ resultcxt = CurrentMemoryContext; @@ -117,9 +118,10 @@ get_subscription_list(void) (void) GetTransactionSnapshot(); rel = heap_open(SubscriptionRelationId, AccessShareLock); - scan = heap_beginscan_catalog(rel, 0, NULL); + method = rel->rd_stamroutine; + scan = method->scan_begin_catalog(rel, 0, NULL); - while (HeapTupleIsValid(tup = heap_getnext(scan, ForwardScanDirection))) + while (HeapTupleIsValid(tup = method->scan_getnext(scan, ForwardScanDirection))) { Form_pg_subscription subform = (Form_pg_subscription) GETSTRUCT(tup); Subscription *sub; @@ -145,7 +147,7 @@ get_subscription_list(void) MemoryContextSwitchTo(oldcxt); } - heap_endscan(scan); + method->scan_end(scan); heap_close(rel, AccessShareLock); CommitTransactionCommand(); diff --git a/src/backend/rewrite/rewriteDefine.c b/src/backend/rewrite/rewriteDefine.c index fd3768d..3db218d 100644 --- a/src/backend/rewrite/rewriteDefine.c +++ b/src/backend/rewrite/rewriteDefine.c @@ -17,6 +17,7 @@ #include "access/heapam.h" #include "access/htup_details.h" #include "access/multixact.h" +#include "access/storageamapi.h" #include "access/transam.h" #include "access/xact.h" #include "catalog/catalog.h" @@ -421,6 +422,7 @@ DefineQueryRewrite(char *rulename, { HeapScanDesc scanDesc; Snapshot snapshot; + StorageAmRoutine *method; if (event_relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) ereport(ERROR, @@ -429,13 +431,14 @@ DefineQueryRewrite(char *rulename, RelationGetRelationName(event_relation)))); snapshot = RegisterSnapshot(GetLatestSnapshot()); - scanDesc = heap_beginscan(event_relation, snapshot, 0, NULL); - if (heap_getnext(scanDesc, ForwardScanDirection) != NULL) + method = event_relation->rd_stamroutine; + scanDesc = method->scan_begin(event_relation, snapshot, 0, NULL); + if (method->scan_getnext(scanDesc, ForwardScanDirection) != NULL) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("could not convert table \"%s\" to a view because it is not empty", RelationGetRelationName(event_relation)))); - heap_endscan(scanDesc); + method->scan_end(scanDesc); UnregisterSnapshot(snapshot); if (event_relation->rd_rel->relhastriggers) diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c index b8b4a06..400da47 100644 --- a/src/backend/utils/init/postinit.c +++ b/src/backend/utils/init/postinit.c @@ -21,6 +21,7 @@ #include "access/heapam.h" #include "access/htup_details.h" +#include "access/storageamapi.h" #include "access/sysattr.h" #include "access/xact.h" #include "access/xlog.h" @@ -1205,13 +1206,15 @@ ThereIsAtLeastOneRole(void) Relation pg_authid_rel; HeapScanDesc scan; bool result; + StorageAmRoutine *method; pg_authid_rel = heap_open(AuthIdRelationId, AccessShareLock); + method = pg_authid_rel->rd_stamroutine; - scan = heap_beginscan_catalog(pg_authid_rel, 0, NULL); - result = (heap_getnext(scan, ForwardScanDirection) != NULL); + scan = method->scan_begin_catalog(pg_authid_rel, 0, NULL); + result = (method->scan_getnext(scan, ForwardScanDirection) != NULL); - heap_endscan(scan); + method->scan_end(scan); heap_close(pg_authid_rel, AccessShareLock); return result; -- 2.7.4.windows.1