/** * @brief Get the pg class tuple * @param tuple relevant tuple if it exists, NULL otherwise */ HeapTuple Bridge::GetPGClassTupleForRelationName(const char *relation_name) { LOG_WARN("Do not use bridge function(%s) in Peloton !!! ", __func__); Relation pg_class_rel; HeapTuple tuple = NULL; HeapScanDesc scan; // Open pg_class table pg_class_rel = heap_open(RelationRelationId, AccessShareLock); // Search the pg_class table with given relation name scan = heap_beginscan_catalog(pg_class_rel, 0, NULL); while (HeapTupleIsValid(tuple = heap_getnext(scan, ForwardScanDirection))) { Form_pg_class pgclass = (Form_pg_class)GETSTRUCT(tuple); if (pgclass->relnamespace == PG_PUBLIC_NAMESPACE) { if (strcmp(NameStr(pgclass->relname), relation_name) == 0) { // We need to end scan and close heap break; } } } heap_endscan(scan); heap_close(pg_class_rel, AccessShareLock); return tuple; }
/* ---------------------------------------------------------------- * ExecEndSeqScan * * frees any storage allocated through C routines. * ---------------------------------------------------------------- */ void ExecEndSeqScan(SeqScanState *node) { Relation relation; HeapScanDesc scanDesc; /* * get information from node */ relation = node->ss_currentRelation; scanDesc = node->ss_currentScanDesc; /* * Free the exprcontext */ ExecFreeExprContext(&node->ps); /* * clean out the tuple table */ ExecClearTuple(node->ps.ps_ResultTupleSlot); ExecClearTuple(node->ss_ScanTupleSlot); /* * close heap scan */ heap_endscan(scanDesc); /* * close the heap relation. */ ExecCloseScanRelation(relation); }
void PersistentStore_EndScan( PersistentStoreScan *storeScan) { heap_endscan(storeScan->scan); (*storeScan->storeData->closeRel)(storeScan->persistentRel); }
/* * worker_cleanup_job_schema_cache walks over all schemas in the database, and * removes schemas whose names start with the job schema prefix. Note that this * function does not perform any locking; we expect it to be called at process * start-up time before any merge tasks are run. Further note that this function * runs within the scope of a particular database (template1, postgres) and can * only delete schemas within that database. */ Datum worker_cleanup_job_schema_cache(PG_FUNCTION_ARGS) { Relation pgNamespace = NULL; HeapScanDesc scanDescriptor = NULL; ScanKey scanKey = NULL; int scanKeyCount = 0; HeapTuple heapTuple = NULL; pgNamespace = heap_open(NamespaceRelationId, AccessExclusiveLock); scanDescriptor = heap_beginscan_catalog(pgNamespace, scanKeyCount, scanKey); heapTuple = heap_getnext(scanDescriptor, ForwardScanDirection); while (HeapTupleIsValid(heapTuple)) { Form_pg_namespace schemaForm = (Form_pg_namespace) GETSTRUCT(heapTuple); char *schemaName = NameStr(schemaForm->nspname); char *jobSchemaFound = strstr(schemaName, JOB_SCHEMA_PREFIX); if (jobSchemaFound != NULL) { StringInfo jobSchemaName = makeStringInfo(); appendStringInfoString(jobSchemaName, schemaName); RemoveJobSchema(jobSchemaName); } heapTuple = heap_getnext(scanDescriptor, ForwardScanDirection); } heap_endscan(scanDescriptor); heap_close(pgNamespace, AccessExclusiveLock); PG_RETURN_VOID(); }
/* * Gets list of all relation published by FOR ALL TABLES publication(s). */ List * GetAllTablesPublicationRelations(void) { Relation classRel; ScanKeyData key[1]; HeapScanDesc scan; HeapTuple tuple; List *result = NIL; classRel = heap_open(RelationRelationId, AccessShareLock); ScanKeyInit(&key[0], Anum_pg_class_relkind, BTEqualStrategyNumber, F_CHAREQ, CharGetDatum(RELKIND_RELATION)); scan = heap_beginscan_catalog(classRel, 1, key); while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) { Form_pg_class relForm = (Form_pg_class) GETSTRUCT(tuple); Oid relid = relForm->oid; if (is_publishable_class(relid, relForm)) result = lappend_oid(result, relid); } heap_endscan(scan); heap_close(classRel, AccessShareLock); return result; }
/* * get_tablespace_name - given a tablespace OID, look up the name * * Returns a palloc'd string, or NULL if no such tablespace. */ char * get_tablespace_name(Oid spc_oid) { char *result; Relation rel; HeapScanDesc scandesc; HeapTuple tuple; ScanKeyData entry[1]; /* Search pg_tablespace */ rel = heap_open(TableSpaceRelationId, AccessShareLock); ScanKeyInit(&entry[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(spc_oid)); scandesc = heap_beginscan(rel, SnapshotNow, 1, entry); tuple = heap_getnext(scandesc, ForwardScanDirection); /* We assume that there can be at most one matching tuple */ if (HeapTupleIsValid(tuple)) result = pstrdup(NameStr(((Form_pg_tablespace) GETSTRUCT(tuple))->spcname)); else result = NULL; heap_endscan(scandesc); heap_close(rel, AccessShareLock); return result; }
/* * RemoveConversionById * * Remove a tuple from pg_conversion by Oid. This function is solely * called inside catalog/dependency.c */ void RemoveConversionById(Oid conversionOid) { Relation rel; HeapTuple tuple; HeapScanDesc scan; ScanKeyData scanKeyData; ScanKeyInit(&scanKeyData, ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(conversionOid)); /* open pg_conversion */ rel = heap_open(ConversionRelationId, RowExclusiveLock); scan = heap_beginscan_catalog(rel, 1, &scanKeyData); /* search for the target tuple */ if (HeapTupleIsValid(tuple = heap_getnext(scan, ForwardScanDirection))) simple_heap_delete(rel, &tuple->t_self); else elog(ERROR, "could not find tuple for conversion %u", conversionOid); heap_endscan(scan); heap_close(rel, RowExclusiveLock); }
static void nodeCheckCleanup(Datum arg) { node_check_data *fdata = (node_check_data*) DatumGetPointer(arg); if (fdata->databaseDir != NULL) { FreeDir(fdata->databaseDir); fdata->databaseDir = NULL; } if (fdata->tablespaceDir != NULL) { FreeDir(fdata->tablespaceDir); fdata->tablespaceDir = NULL; } if (fdata->scandesc != NULL) { heap_endscan(fdata->scandesc); fdata->scandesc = NULL; } if (fdata->tablespaceRelation != NULL) { heap_close(fdata->tablespaceRelation, AccessShareLock); fdata->tablespaceRelation = NULL; } pfree(fdata); }
/* * get_all_brokers * * Return a list of all brokers in pipeline_kafka_brokers */ static List * get_all_brokers(void) { HeapTuple tup = NULL; HeapScanDesc scan; Relation brokers = open_pipeline_kafka_brokers(); TupleTableSlot *slot = MakeSingleTupleTableSlot(RelationGetDescr(brokers)); List *result = NIL; scan = heap_beginscan(brokers, GetTransactionSnapshot(), 0, NULL); while ((tup = heap_getnext(scan, ForwardScanDirection)) != NULL) { char *host; Datum d; bool isnull; ExecStoreTuple(tup, slot, InvalidBuffer, false); d = slot_getattr(slot, BROKER_ATTR_HOST, &isnull); host = TextDatumGetCString(d); result = lappend(result, host); } ExecDropSingleTupleTableSlot(slot); heap_endscan(scan); heap_close(brokers, NoLock); return result; }
/* *-------------------------------------------------------------- * Async_UnlistenAll * * Unlisten all relations for this backend. * * This is invoked by UNLISTEN "*" command, and also at backend exit. * * Results: * XXX * * Side effects: * pg_listener is updated. * *-------------------------------------------------------------- */ static void Async_UnlistenAll(void) { Relation lRel; TupleDesc tdesc; HeapScanDesc scan; HeapTuple lTuple; ScanKeyData key[1]; if (Trace_notify) elog(DEBUG1, "Async_UnlistenAll"); lRel = heap_open(ListenerRelationId, ExclusiveLock); tdesc = RelationGetDescr(lRel); /* Find and delete all entries with my listenerPID */ ScanKeyInit(&key[0], Anum_pg_listener_pid, BTEqualStrategyNumber, F_INT4EQ, Int32GetDatum(MyProcPid)); scan = heap_beginscan(lRel, SnapshotNow, 1, key); while ((lTuple = heap_getnext(scan, ForwardScanDirection)) != NULL) simple_heap_delete(lRel, &lTuple->t_self); heap_endscan(scan); heap_close(lRel, ExclusiveLock); }
/* * get_next_id * * Gets the smallest possible id to assign to the next continuous view. * We keep this minimal so that we can minimize the size of bitmaps used * to tag stream buffer events with. */ static int32 get_next_id(Relation rel) { HeapScanDesc scandesc; HeapTuple tup; int32 id = 1; List *idsList = NIL; ListCell *lc; scandesc = heap_beginscan_catalog(rel, 0, NULL); while ((tup = heap_getnext(scandesc, ForwardScanDirection)) != NULL) { Form_pipeline_query row = (Form_pipeline_query) GETSTRUCT(tup); idsList = lappend_int(idsList, row->id); } heap_endscan(scandesc); if (idsList != NIL) { int32 ids[idsList->length]; int i = 0; foreach(lc, idsList) { ids[i] = lfirst_int(lc); i++; }
/* * Returns true if the relation has no tuples. Prepare phase of * compaction invokes this function on each QE. * * Examples of empty tables: * 1. parent of a partitioned table * 2. table that is created but no tuples have been inserted yet * 3. table from which all existing tuples are deleted and the table * is vacuumed. This is a special case in which pg_aoseg_<oid> has * non-zero number of rows but tupcount value is zero for all rows. */ bool AppendOnlyCompaction_IsRelationEmpty(Relation aorel) { AppendOnlyEntry *aoEntry; Relation pg_aoseg_rel; TupleDesc pg_aoseg_dsc; HeapTuple tuple; HeapScanDesc aoscan; int Anum_tupcount; bool empty = true; Assert(RelationIsAoRows(aorel) || RelationIsAoCols(aorel)); aoEntry = GetAppendOnlyEntry(RelationGetRelid(aorel), SnapshotNow); pg_aoseg_rel = heap_open(aoEntry->segrelid, AccessShareLock); pg_aoseg_dsc = RelationGetDescr(pg_aoseg_rel); aoscan = heap_beginscan(pg_aoseg_rel, SnapshotNow, 0, NULL); Anum_tupcount = RelationIsAoRows(aorel)? Anum_pg_aoseg_tupcount: Anum_pg_aocs_tupcount; while ((tuple = heap_getnext(aoscan, ForwardScanDirection)) != NULL && empty) { if (0 < fastgetattr(tuple, Anum_tupcount, pg_aoseg_dsc, NULL)) empty = false; } heap_endscan(aoscan); heap_close(pg_aoseg_rel, AccessShareLock); return empty; }
/* * get_tablespace_oid - given a tablespace name, look up the OID * * Returns InvalidOid if tablespace name not found. */ Oid get_tablespace_oid(const char *tablespacename) { Oid result; Relation rel; HeapScanDesc scandesc; HeapTuple tuple; ScanKeyData entry[1]; /* Search pg_tablespace */ rel = heap_open(TableSpaceRelationId, AccessShareLock); ScanKeyInit(&entry[0], Anum_pg_tablespace_spcname, BTEqualStrategyNumber, F_NAMEEQ, CStringGetDatum(tablespacename)); scandesc = heap_beginscan(rel, SnapshotNow, 1, entry); tuple = heap_getnext(scandesc, ForwardScanDirection); if (HeapTupleIsValid(tuple)) result = HeapTupleGetOid(tuple); else result = InvalidOid; heap_endscan(scandesc); heap_close(rel, AccessShareLock); return result; }
/* * get_database_oids * * Returns a list of all database OIDs found in pg_database. */ static List * get_database_list(void) { List *dbs = NIL; Relation rel; HeapScanDesc scan; HeapTuple tup; MemoryContext resultcxt; /* This is the context that we will allocate our output data in */ resultcxt = CurrentMemoryContext; /* * Start a transaction so we can access pg_database, and get a snapshot. * We don't have a use for the snapshot itself, but we're interested in * the secondary effect that it sets RecentGlobalXmin. (This is critical * for anything that reads heap pages, because HOT may decide to prune * them even if the process doesn't attempt to modify any tuples.) */ StartTransactionCommand(); (void) GetTransactionSnapshot(); /* We take a AccessExclusiveLock so we don't conflict with any DATABASE commands */ rel = heap_open(DatabaseRelationId, AccessExclusiveLock); scan = heap_beginscan_catalog(rel, 0, NULL); while (HeapTupleIsValid(tup = heap_getnext(scan, ForwardScanDirection))) { MemoryContext oldcxt; Form_pg_database pgdatabase = (Form_pg_database) GETSTRUCT(tup); DatabaseEntry *db_entry; /* Ignore template databases or ones that don't allow connections. */ if (pgdatabase->datistemplate || !pgdatabase->datallowconn) continue; /* * Allocate our results in the caller's context, not the * transaction's. We do this inside the loop, and restore the original * context at the end, so that leaky things like heap_getnext() are * not called in a potentially long-lived context. */ oldcxt = MemoryContextSwitchTo(resultcxt); db_entry = palloc0(sizeof(DatabaseEntry)); db_entry->oid = HeapTupleGetOid(tup); StrNCpy(NameStr(db_entry->name), NameStr(pgdatabase->datname), NAMEDATALEN); dbs = lappend(dbs, db_entry); MemoryContextSwitchTo(oldcxt); } heap_endscan(scan); heap_close(rel, AccessExclusiveLock); CommitTransactionCommand(); return dbs; }
/* * calculate size of database in all tablespaces */ static int64 calculate_database_size(Oid dbOid) { int64 totalsize = 0; char pathname[MAXPGPATH]; Relation rel; HeapScanDesc scandesc; HeapTuple tuple; AclResult aclresult; Assert(Gp_role != GP_ROLE_EXECUTE); if (dbOid == HcatalogDbOid) ereport(ERROR, (ERRCODE_UNDEFINED_DATABASE, errmsg("database hcatalog (OID 6120) is reserved"))); /* User must have connect privilege for target database */ aclresult = pg_database_aclcheck(dbOid, GetUserId(), ACL_CONNECT); if (aclresult != ACLCHECK_OK) { aclcheck_error(aclresult, ACL_KIND_DATABASE, get_database_name(dbOid)); } /* Scan through all tablespaces */ rel = heap_open(TableSpaceRelationId, AccessShareLock); scandesc = heap_beginscan(rel, SnapshotNow, 0, NULL); tuple = heap_getnext(scandesc, ForwardScanDirection); while (HeapTupleIsValid(tuple)) { char *filespace; Oid tsOid; tsOid = HeapTupleGetOid(tuple); /* Don't include shared relations */ if (tsOid != GLOBALTABLESPACE_OID) { /* Find the filespace path for this tablespace */ /* Master access its own database first. */ PersistentTablespace_GetFilespacePath(tsOid, FALSE, &filespace); /* Build the path for this database in this tablespace */ FormDatabasePath(pathname, filespace, tsOid, dbOid); totalsize += db_dir_size(pathname); } tuple = heap_getnext(scandesc, ForwardScanDirection); } heap_endscan(scandesc); heap_close(rel, AccessShareLock); /* Complain if we found no trace of the DB at all */ if (totalsize == 0) ereport(ERROR, (ERRCODE_UNDEFINED_DATABASE, errmsg("database with OID %u does not exist", dbOid))); return totalsize; }
/* * load_consumer_offsets * * Load all offsets for all of this consumer's partitions */ static void load_consumer_offsets(KafkaConsumer *consumer, struct rd_kafka_metadata_topic *meta, int64_t offset) { MemoryContext old; ScanKeyData skey[1]; HeapTuple tup = NULL; HeapScanDesc scan; Relation offsets = open_pipeline_kafka_offsets(); TupleTableSlot *slot = MakeSingleTupleTableSlot(RelationGetDescr(offsets)); int i; ScanKeyInit(&skey[0], OFFSETS_ATTR_CONSUMER, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(consumer->id)); scan = heap_beginscan(offsets, GetTransactionSnapshot(), 1, skey); old = MemoryContextSwitchTo(CacheMemoryContext); consumer->offsets = palloc0(meta->partition_cnt * sizeof(int64_t)); MemoryContextSwitchTo(old); /* by default, begin consuming from the end of a stream */ for (i = 0; i < meta->partition_cnt; i++) consumer->offsets[i] = offset; consumer->num_partitions = meta->partition_cnt; while ((tup = heap_getnext(scan, ForwardScanDirection)) != NULL) { Datum d; bool isnull; int partition; ExecStoreTuple(tup, slot, InvalidBuffer, false); d = slot_getattr(slot, OFFSETS_ATTR_PARTITION, &isnull); partition = DatumGetInt32(d); if(partition > consumer->num_partitions) elog(ERROR, "invalid partition id: %d", partition); if (offset == RD_KAFKA_OFFSET_NULL) { d = slot_getattr(slot, OFFSETS_ATTR_OFFSET, &isnull); if (isnull) offset = RD_KAFKA_OFFSET_END; else offset = DatumGetInt64(d); } consumer->offsets[partition] = DatumGetInt64(offset); } ExecDropSingleTupleTableSlot(slot); heap_endscan(scan); heap_close(offsets, RowExclusiveLock); }
Datum gp_persistent_set_relation_bufpool_kind_all(PG_FUNCTION_ARGS) { Relation pg_database; HeapScanDesc scan; HeapTuple tuple; if (!gp_upgrade_mode) ereport(ERROR, (errcode(ERRCODE_GP_FEATURE_NOT_SUPPORTED), errmsg("function is not supported"), errOmitLocation(true))); // UNDONE: Verify we are in some sort of single-user mode. /* * Special call here to scan the persistent meta-data structures so we are open for * business and then we can add information. */ PersistentFileSysObj_BuildInitScan(); pg_database = heap_open( DatabaseRelationId, AccessShareLock); scan = heap_beginscan(pg_database, SnapshotNow, 0, NULL); while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) { Form_pg_database form_pg_database = (Form_pg_database)GETSTRUCT(tuple); Oid dbOid; Oid dattablespace; dbOid = HeapTupleGetOid(tuple); dattablespace = form_pg_database->dattablespace; if (Debug_persistent_print) elog(Persistent_DebugPrintLevel(), "gp_persistent_set_relation_bufpool_kind_all: dbOid %u", dbOid); PersistentBuild_SetRelationBufpoolKind( dattablespace, dbOid); } heap_endscan(scan); heap_close(pg_database, AccessShareLock); PG_RETURN_INT32(1); }
/* ---------------------------------------------------------------- * ExecEndBitmapHeapScan * ---------------------------------------------------------------- */ void ExecEndBitmapHeapScan(BitmapHeapScanState *node) { Relation relation; HeapScanDesc scanDesc; /* * extract information from the node */ relation = node->ss.ss_currentRelation; scanDesc = node->ss.ss_currentScanDesc; /* * Free the exprcontext */ ExecFreeExprContext(&node->ss.ps); /* * clear out tuple table slots */ ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); ExecClearTuple(node->ss.ss_ScanTupleSlot); /* * close down subplans */ ExecEndNode(outerPlanState(node)); /* * release bitmap if any */ if (node->tbm) tbm_free(node->tbm); if (node->odbm) odbm_free(node->odbm); /* * close heap scan */ heap_endscan(scanDesc); /* * close the heap relation. * * Currently, we do not release the AccessShareLock acquired by * ExecInitBitmapHeapScan. This lock should be held till end of * transaction. (There is a faction that considers this too much locking, * however.) */ heap_close(relation, NoLock); }
/* ---------------------------------------------------------------- * ExecEndBitmapHeapScan * ---------------------------------------------------------------- */ void ExecEndBitmapHeapScan(BitmapHeapScanState *node) { Relation relation; HeapScanDesc scanDesc; /* * extract information from the node */ relation = node->ss.ss_currentRelation; scanDesc = node->ss.ss_currentScanDesc; /* * Free the exprcontext */ ExecFreeExprContext(&node->ss.ps); /* * clear out tuple table slots */ ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); ExecClearTuple(node->ss.ss_ScanTupleSlot); /* * close down subplans */ ExecEndNode(outerPlanState(node)); /* * release bitmap if any */ if (node->tbmiterator) tbm_end_iterate(node->tbmiterator); if (node->prefetch_iterator) tbm_end_iterate(node->prefetch_iterator); if (node->tbm) tbm_free(node->tbm); if (node->shared_tbmiterator) tbm_end_shared_iterate(node->shared_tbmiterator); if (node->shared_prefetch_iterator) tbm_end_shared_iterate(node->shared_prefetch_iterator); /* * close heap scan */ heap_endscan(scanDesc); /* * close the heap relation. */ ExecCloseScanRelation(relation); }
static void DatabaseInfo_CollectGpRelationNode( DatabaseInfo *info, HTAB *dbInfoRelHashTable) { HeapScanDesc scan; Relation gp_relation_node_rel; HeapTuple tuple; gp_relation_node_rel = DirectOpen_GpRelationNodeOpen( info->defaultTablespace, info->database); scan = heap_beginscan(gp_relation_node_rel, SnapshotNow, 0, NULL); while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) { bool nulls[Natts_gp_relation_node]; Datum values[Natts_gp_relation_node]; Oid relfilenode; int32 segmentFileNum; int64 createMirrorDataLossTrackingSessionNum; ItemPointerData persistentTid; int64 persistentSerialNum; heap_deform_tuple(tuple, RelationGetDescr(gp_relation_node_rel), values, nulls); GpRelationNode_GetValues( values, &relfilenode, &segmentFileNum, &createMirrorDataLossTrackingSessionNum, &persistentTid, &persistentSerialNum); if (!DatabaseInfo_AddGpRelationNode( info, dbInfoRelHashTable, relfilenode, segmentFileNum, &persistentTid, persistentSerialNum, &tuple->t_self)) { elog(WARNING, "Did not find matching pg_class entry for gp_relation_node entry relfilenode %u (parentless!!!)", relfilenode); } } heap_endscan(scan); DirectOpen_GpRelationNodeClose(gp_relation_node_rel); }
/* * Set mirror for all relation files. */ void PersistentRelation_AddMirrorAll(int16 pridbid, int16 mirdbid) { Relation rel; HeapScanDesc scandesc; HeapTuple tuple; WRITE_PERSISTENT_STATE_ORDERED_LOCK_DECLARE; if (Persistent_BeforePersistenceWork()) elog(ERROR, "persistent table changes forbidden"); rel = heap_open(GpPersistentRelationNodeRelationId, AccessExclusiveLock); scandesc = heap_beginscan(rel, SnapshotNow, 0, NULL); WRITE_PERSISTENT_STATE_ORDERED_LOCK; while ((tuple = heap_getnext(scandesc, ForwardScanDirection)) != NULL) { Form_gp_persistent_relation_node form = (Form_gp_persistent_relation_node)GETSTRUCT(tuple); Oid tblspcoid = form->tablespace_oid; Oid dboid = form->database_oid; Oid relfilenode_oid = form->relfilenode_oid; int32 segment_file_num = form->segment_file_num; int64 serial = form->persistent_serial_num; PersistentFileSysObjName fsObjName; RelFileNode node; node.spcNode = tblspcoid; node.dbNode = dboid; node.relNode = relfilenode_oid; PersistentFileSysObjName_SetRelationFile(&fsObjName, &node, segment_file_num); PersistentFileSysObj_AddMirror(&fsObjName, &tuple->t_self, serial, pridbid, mirdbid, NULL, true, /* flushToXlog */ false); } WRITE_PERSISTENT_STATE_ORDERED_UNLOCK; heap_endscan(scandesc); heap_close(rel, NoLock); }
/* * systable_endscan --- close scan, release resources * * Note that it's still up to the caller to close the heap relation. */ void systable_endscan(SysScanDesc sysscan) { if (sysscan->irel) { index_endscan(sysscan->iscan); index_close(sysscan->irel, AccessShareLock); } else heap_endscan(sysscan->scan); pfree(sysscan); }
/* * Returns true if at least one role is defined in this database cluster. */ static bool ThereIsAtLeastOneRole(void) { struct relation* pg_authid_rel; struct heap_scan* scan; bool result; pg_authid_rel = heap_open(AuthIdRelationId, ACCESS_SHR_LOCK); scan = heap_beginscan(pg_authid_rel, snap_now, 0, NULL); result = (heap_getnext(scan, FORWARD_SCANDIR) != NULL); heap_endscan(scan); heap_close(pg_authid_rel, ACCESS_SHR_LOCK); return result; }
/* ---------------------------------------------------------------- * Close the scanned relation. * Close means release resource. * ---------------------------------------------------------------- */ static void CloseScanRelation(SeqScanState *node) { Assert((node->scan_state & SCAN_SCAN) != 0); heap_endscan(node->ss_currentScanDesc); node->ss_heapTupleData.top = 0; node->ss_heapTupleData.bot = 0; node->ss_heapTupleData.seen_EOS = 1; node->ss_heapTupleData.last = NULL; node->ss_currentScanDesc = NULL; node->scan_state = SCAN_INIT; }
/* ---------------------------------------------------------------- * ExecEndBitmapHeapScan * ---------------------------------------------------------------- */ void ExecEndBitmapHeapScan(BitmapHeapScanState *node) { HeapScanDesc scanDesc; /* * extract information from the node */ scanDesc = node->ss.ss_currentScanDesc; /* * Free the exprcontext */ ExecFreeExprContext(&node->ss.ps); /* * clear out tuple table slots */ if (node->ss.ps.ps_ResultTupleSlot) ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); ExecClearTuple(node->ss.ss_ScanTupleSlot); /* * close down subplans */ ExecEndNode(outerPlanState(node)); /* * release bitmaps and buffers if any */ if (node->tbmiterator) tbm_end_iterate(node->tbmiterator); if (node->prefetch_iterator) tbm_end_iterate(node->prefetch_iterator); if (node->tbm) tbm_free(node->tbm); if (node->shared_tbmiterator) tbm_end_shared_iterate(node->shared_tbmiterator); if (node->shared_prefetch_iterator) tbm_end_shared_iterate(node->shared_prefetch_iterator); if (node->vmbuffer != InvalidBuffer) ReleaseBuffer(node->vmbuffer); if (node->pvmbuffer != InvalidBuffer) ReleaseBuffer(node->pvmbuffer); /* * close heap scan */ heap_endscan(scanDesc); }
static Segment * IterateSegmentConfiguration(SegmentConfigurationIterator *iterator) { HeapTuple gp_seg_config_tuple; while (HeapTupleIsValid(gp_seg_config_tuple = heap_getnext(iterator->gp_seg_config_scan, ForwardScanDirection))) { return ParseSegmentConfigurationRow(iterator, gp_seg_config_tuple); } /* No more data. */ heap_endscan(iterator->gp_seg_config_scan); heap_close(iterator->gp_seg_config_rel, AccessShareLock); return NULL; }
/* * Returns true if at least one role is defined in this database cluster. */ static bool ThereIsAtLeastOneRole(void) { Relation pg_authid_rel; HeapScanDesc scan; bool result; pg_authid_rel = heap_open(AuthIdRelationId, AccessShareLock); scan = heap_beginscan_catalog(pg_authid_rel, 0, NULL); result = (heap_getnext(scan, ForwardScanDirection) != NULL); heap_endscan(scan); heap_close(pg_authid_rel, AccessShareLock); return result; }
void EndScanHeapRelation(ScanState *scanState) { Assert(IsA(scanState, TableScanState) || IsA(scanState, DynamicTableScanState)); SeqScanState *node = (SeqScanState *)scanState; Assert((node->ss.scan_state & SCAN_SCAN) != 0); Assert(node->opaque != NULL && node->opaque->ss_currentScanDesc != NULL); heap_endscan(node->opaque->ss_currentScanDesc); FreeHeapScanOpaque(scanState); node->ss.scan_state = SCAN_INIT; }
/* *-------------------------------------------------------------- * Async_Unlisten * * This is executed by the SQL unlisten command. * * Remove the current backend from the list of listening backends * for the specified relation. * * Side effects: * pg_listener is updated. * *-------------------------------------------------------------- */ void Async_Unlisten(const char *relname) { Relation lRel; HeapScanDesc scan; HeapTuple tuple; /* Handle specially the `unlisten "*"' command */ if ((!relname) || (*relname == '\0') || (strcmp(relname, "*") == 0)) { Async_UnlistenAll(); return; } if (Trace_notify) elog(DEBUG1, "Async_Unlisten(%s,%d)", relname, MyProcPid); lRel = heap_open(ListenerRelationId, ExclusiveLock); scan = heap_beginscan(lRel, SnapshotNow, 0, NULL); while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) { Form_pg_listener listener = (Form_pg_listener) GETSTRUCT(tuple); if (listener->listenerpid == MyProcPid && strncmp(NameStr(listener->relname), relname, NAMEDATALEN) == 0) { /* Found the matching tuple, delete it */ simple_heap_delete(lRel, &tuple->t_self); /* * We assume there can be only one match, so no need to scan the * rest of the table */ break; } } heap_endscan(scan); heap_close(lRel, ExclusiveLock); /* * We do not complain about unlistening something not being listened; * should we? */ }
/* * Find rule oid, given only a rule name but no rel OID. * * If there's more than one, it's an error. If there aren't any, that's an * error, too. In general, this should be avoided - it is provided to support * syntax that is compatible with pre-7.3 versions of PG, where rule names * were unique across the entire database. */ Oid get_rewrite_oid_without_relid(const char *rulename, Oid *reloid, bool missing_ok) { Relation RewriteRelation; HeapScanDesc scanDesc; ScanKeyData scanKeyData; HeapTuple htup; Oid ruleoid; /* Search pg_rewrite for such a rule */ ScanKeyInit(&scanKeyData, Anum_pg_rewrite_rulename, BTEqualStrategyNumber, F_NAMEEQ, CStringGetDatum(rulename)); RewriteRelation = heap_open(RewriteRelationId, AccessShareLock); scanDesc = heap_beginscan(RewriteRelation, SnapshotNow, 1, &scanKeyData); htup = heap_getnext(scanDesc, ForwardScanDirection); if (!HeapTupleIsValid(htup)) { if (!missing_ok) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("rule \"%s\" does not exist", rulename))); ruleoid = InvalidOid; } else { ruleoid = HeapTupleGetOid(htup); if (reloid != NULL) *reloid = ((Form_pg_rewrite) GETSTRUCT(htup))->ev_class; htup = heap_getnext(scanDesc, ForwardScanDirection); if (HeapTupleIsValid(htup)) ereport(ERROR, (errcode(ERRCODE_DUPLICATE_OBJECT), errmsg("there are multiple rules named \"%s\"", rulename), errhint("Specify a relation name as well as a rule name."))); } heap_endscan(scanDesc); heap_close(RewriteRelation, AccessShareLock); return ruleoid; }