/* * 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(rel, SnapshotNow, 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); }
/* * 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; }
/* ---------------------------------------------------------------- * InitScanRelation * * This does the initialization for scan relations and * subplans of scans. * ---------------------------------------------------------------- */ static void InitScanRelation(SeqScanState *node, EState *estate) { Relation currentRelation; HeapScanDesc currentScanDesc; /* * get the relation object id from the relid'th entry in the range table, * open that relation and acquire appropriate lock on it. */ /*CHANGED BY YASIN*/ if (node->ps.ps_InAround) /*If this is in the around branch*/ /*currentRelation = ExecOpenScanRelationAround(estate,((SeqScan *) node->ps.plan)->scanrelid);*/ currentRelation = ExecOpenScanRelation(estate,((SeqScan *) node->ps.plan)->scanrelid); else /*Original code*/ currentRelation = ExecOpenScanRelation(estate,((SeqScan *) node->ps.plan)->scanrelid); currentScanDesc = heap_beginscan(currentRelation, estate->es_snapshot, 0, NULL); node->ss_currentRelation = currentRelation; node->ss_currentScanDesc = currentScanDesc; ExecAssignScanType(node, RelationGetDescr(currentRelation)); }
/* ---------------------------------------------------------------- * InitScanRelation * * Set up to access the scan relation. * ---------------------------------------------------------------- */ static void InitScanRelation(SeqScanState *node, EState *estate, int eflags) { Relation currentRelation; HeapScanDesc currentScanDesc; /* * get the relation object id from the relid'th entry in the range table, * open that relation and acquire appropriate lock on it. */ currentRelation = ExecOpenScanRelation(estate, ((SeqScan *) node->ps.plan)->scanrelid, eflags); /* initialize a heapscan */ currentScanDesc = heap_beginscan(currentRelation, estate->es_snapshot, 0, NULL); node->ss_currentRelation = currentRelation; node->ss_currentScanDesc = currentScanDesc; /* and report the scan tuple slot's rowtype */ ExecAssignScanType(node, RelationGetDescr(currentRelation)); }
/* *-------------------------------------------------------------- * 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); }
/* ---------------------------------------------------------------- * InitScanRelation * * This does the initialization for scan relations and * subplans of scans. * ---------------------------------------------------------------- */ static void InitScanRelation(SeqScanState *node, EState *estate) { Relation currentRelation; HeapScanDesc currentScanDesc; //elog(WARNING, "InitScanRelation"); /* * get the relation object id from the relid'th entry in the range table, * open that relation and acquire appropriate lock on it. */ currentRelation = ExecOpenScanRelation(estate, ((SeqScan *) node->ps.plan)->scanrelid); //elog(WARNING, "Rel kind %c",currentRelation->rd_rel->relkind); if(currentRelation->rd_rel->relkind== RELKIND_ARRAY) currentScanDesc = heap_beginscan_ar(currentRelation, estate->es_snapshot, 0, NULL); else currentScanDesc = heap_beginscan(currentRelation, estate->es_snapshot, 0, NULL); node->ss_currentRelation = currentRelation; node->ss_currentScanDesc = currentScanDesc; ExecAssignScanType(node, RelationGetDescr(currentRelation)); }
/* * 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_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; }
void BeginScanHeapRelation(ScanState *scanState) { Assert(IsA(scanState, TableScanState) || IsA(scanState, DynamicTableScanState)); SeqScanState *node = (SeqScanState *)scanState; Assert(node->opaque == NULL); Assert(node->ss.scan_state == SCAN_INIT || node->ss.scan_state == SCAN_DONE); InitHeapScanOpaque(scanState); Assert(node->opaque != NULL); node->opaque->ss_currentScanDesc = heap_beginscan( node->ss.ss_currentRelation, node->ss.ps.state->es_snapshot, 0, NULL); node->opaque->ss_heapTupleData.bot = 0; node->opaque->ss_heapTupleData.top = 0; node->opaque->ss_heapTupleData.seen_EOS = 0; node->opaque->ss_heapTupleData.last = NULL; node->ss.scan_state = SCAN_SCAN; }
/* * 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; }
/* * 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; }
/* * systable_beginscan --- set up for heap-or-index scan * * rel: catalog to scan, already opened and suitably locked * indexRelname: name of index to conditionally use * indexOK: if false, forces a heap scan (see notes below) * snapshot: time qual to use (usually should be SnapshotNow) * nkeys, key: scan keys * * The attribute numbers in the scan key should be set for the heap case. * If we choose to index, we reset them to 1..n to reference the index * columns. Note this means there must be one scankey qualification per * index column! This is checked by the Asserts in the normal, index-using * case, but won't be checked if the heapscan path is taken. * * The routine checks the normal cases for whether an indexscan is safe, * but caller can make additional checks and pass indexOK=false if needed. * In standard case indexOK can simply be constant TRUE. */ SysScanDesc systable_beginscan(Relation heapRelation, const char *indexRelname, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key) { SysScanDesc sysscan; Relation irel; if (indexOK && !IsIgnoringSystemIndexes()) { /* We assume it's a system index, so index_openr is OK */ irel = index_openr(indexRelname); if (ReindexIsProcessingIndex(RelationGetRelid(irel))) { /* oops, can't use index that's being rebuilt */ index_close(irel); irel = NULL; } } else irel = NULL; sysscan = (SysScanDesc) palloc(sizeof(SysScanDescData)); sysscan->heap_rel = heapRelation; sysscan->irel = irel; if (irel) { int i; /* * Change attribute numbers to be index column numbers. * * This code could be generalized to search for the index key numbers * to substitute, but for now there's no need. */ for (i = 0; i < nkeys; i++) { Assert(key[i].sk_attno == irel->rd_index->indkey[i]); key[i].sk_attno = i + 1; } sysscan->iscan = index_beginscan(heapRelation, irel, snapshot, nkeys, key); sysscan->scan = NULL; } else { sysscan->scan = heap_beginscan(heapRelation, snapshot, nkeys, key); sysscan->iscan = NULL; } return sysscan; }
/* * systable_beginscan --- set up for heap-or-index scan * * rel: catalog to scan, already opened and suitably locked * indexId: OID of index to conditionally use * indexOK: if false, forces a heap scan (see notes below) * snapshot: time qual to use (usually should be SnapshotNow) * nkeys, key: scan keys * * The attribute numbers in the scan key should be set for the heap case. * If we choose to index, we reset them to 1..n to reference the index * columns. Note this means there must be one scankey qualification per * index column! This is checked by the Asserts in the normal, index-using * case, but won't be checked if the heapscan path is taken. * * The routine checks the normal cases for whether an indexscan is safe, * but caller can make additional checks and pass indexOK=false if needed. * In standard case indexOK can simply be constant TRUE. */ SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key) { SysScanDesc sysscan; Relation irel; if (indexOK && !IgnoreSystemIndexes && !ReindexIsProcessingIndex(indexId)) irel = index_open(indexId, AccessShareLock); else irel = NULL; sysscan = (SysScanDesc) palloc(sizeof(SysScanDescData)); sysscan->heap_rel = heapRelation; sysscan->irel = irel; if (irel) { int i; /* Change attribute numbers to be index column numbers. */ for (i = 0; i < nkeys; i++) { int j; for (j = 0; j < irel->rd_index->indnatts; j++) { if (key[i].sk_attno == irel->rd_index->indkey.values[j]) { key[i].sk_attno = j + 1; break; } } if (j == irel->rd_index->indnatts) elog(ERROR, "column is not in index"); } sysscan->iscan = index_beginscan(heapRelation, irel, snapshot, nkeys, key); sysscan->scan = NULL; } else { sysscan->scan = heap_beginscan(heapRelation, snapshot, nkeys, key); sysscan->iscan = NULL; } return sysscan; }
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); }
/* ---------------------------------------------------------------- * SeqNext * * This is a workhorse for ExecSeqScan * ---------------------------------------------------------------- */ static TupleTableSlot * SeqNext(SeqScanState *node) { HeapTuple tuple; HeapScanDesc scandesc; EState *estate; ScanDirection direction; TupleTableSlot *slot; /* * get information from the estate and scan state */ scandesc = node->ss.ss_currentScanDesc; estate = node->ss.ps.state; direction = estate->es_direction; slot = node->ss.ss_ScanTupleSlot; if (scandesc == NULL) { /* * 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, estate->es_snapshot, 0, NULL); node->ss.ss_currentScanDesc = scandesc; } /* * get the next tuple from the table */ tuple = heap_getnext(scandesc, direction); /* * save the tuple and the buffer returned to us by the access methods in * our scan tuple slot and return the slot. Note: we pass 'false' because * tuples returned by heap_getnext() are pointers onto disk pages and were * not created with palloc() and so should not be pfree()'d. Note also * that ExecStoreTuple will increment the refcount of the buffer; the * refcount will not be dropped until the tuple table slot is cleared. */ if (tuple) ExecStoreTuple(tuple, /* tuple to store */ slot, /* slot to store in */ scandesc->rs_cbuf, /* buffer associated with this * tuple */ false); /* don't pfree this pointer */ else ExecClearTuple(slot); return slot; }
/* * 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); }
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_beginscan --- set up for heap-or-index scan * * rel: catalog to scan, already opened and suitably locked * indexId: OID of index to conditionally use * indexOK: if false, forces a heap scan (see notes below) * snapshot: time qual to use (usually should be SnapshotNow) * nkeys, key: scan keys * * The attribute numbers in the scan key should be set for the heap case. * If we choose to index, we reset them to 1..n to reference the index * columns. Note this means there must be one scankey qualification per * index column! This is checked by the Asserts in the normal, index-using * case, but won't be checked if the heapscan path is taken. * * The routine checks the normal cases for whether an indexscan is safe, * but caller can make additional checks and pass indexOK=false if needed. * In standard case indexOK can simply be constant TRUE. */ SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key) { SysScanDesc sysscan; Relation irel; if (indexOK && !IgnoreSystemIndexes && !ReindexIsProcessingIndex(indexId)) irel = index_open(indexId, AccessShareLock); else irel = NULL; sysscan = (SysScanDesc) palloc(sizeof(SysScanDescData)); sysscan->heap_rel = heapRelation; sysscan->irel = irel; if (irel) { int i; /* * Change attribute numbers to be index column numbers. * * This code could be generalized to search for the index key numbers * to substitute, but for now there's no need. */ for (i = 0; i < nkeys; i++) { Assert(key[i].sk_attno == irel->rd_index->indkey.values[i]); key[i].sk_attno = i + 1; } sysscan->iscan = index_beginscan(heapRelation, irel, snapshot, nkeys, key); sysscan->scan = NULL; } else { sysscan->scan = heap_beginscan(heapRelation, snapshot, nkeys, key); sysscan->iscan = NULL; } return 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; }
/* * 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(pg_authid_rel, SnapshotNow, 0, NULL); result = (heap_getnext(scan, ForwardScanDirection) != NULL); heap_endscan(scan); heap_close(pg_authid_rel, AccessShareLock); return result; }
/* * 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; }
/* *-------------------------------------------------------------- * 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? */ }
Datum pg_dirtyread(PG_FUNCTION_ARGS) { FuncCallContext *funcctx; MemoryContext oldcontext; pg_dirtyread_ctx *usr_ctx; Oid relid; HeapTuple tuplein, tupleout; TupleDesc tupdesc; if (SRF_IS_FIRSTCALL()) { relid = PG_GETARG_OID(0); if (OidIsValid(relid)) { funcctx = SRF_FIRSTCALL_INIT(); oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); usr_ctx = (pg_dirtyread_ctx *) palloc(sizeof(pg_dirtyread_ctx)); usr_ctx->rel = heap_open(relid, AccessShareLock); usr_ctx->reltupdesc = RelationGetDescr(usr_ctx->rel); get_call_result_type(fcinfo, NULL, &tupdesc); funcctx->tuple_desc = BlessTupleDesc(tupdesc); usr_ctx->map = convert_tuples_by_position(usr_ctx->reltupdesc, funcctx->tuple_desc, "Error converting tuple descriptors!"); usr_ctx->scan = heap_beginscan(usr_ctx->rel, SnapshotAny, 0, NULL); funcctx->user_fctx = (void *) usr_ctx; MemoryContextSwitchTo(oldcontext); } } funcctx = SRF_PERCALL_SETUP(); usr_ctx = (pg_dirtyread_ctx *) funcctx->user_fctx; if ((tuplein = heap_getnext(usr_ctx->scan, ForwardScanDirection)) != NULL) { tupleout = do_convert_tuple(tuplein, usr_ctx->map); SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(tupleout)); } else { heap_endscan(usr_ctx->scan); heap_close(usr_ctx->rel, AccessShareLock); SRF_RETURN_DONE(funcctx); } }
/* * Get a superuser name; return in malloc()ed buffer. */ static char * getDBSuperuserName(const char *errPrefix) { char *suser = NULL; Relation auth_rel; HeapTuple auth_tup; HeapScanDesc auth_scan; ScanKeyData key[2]; bool isNull; ScanKeyInit(&key[0], Anum_pg_authid_rolsuper, BTEqualStrategyNumber, F_BOOLEQ, BoolGetDatum(true)); ScanKeyInit(&key[1], Anum_pg_authid_rolcanlogin, BTEqualStrategyNumber, F_BOOLEQ, BoolGetDatum(true)); auth_rel = heap_open(AuthIdRelationId, AccessShareLock); auth_scan = heap_beginscan(auth_rel, SnapshotNow, 2, key); while (HeapTupleIsValid(auth_tup = heap_getnext(auth_scan, ForwardScanDirection))) { Datum attrName; Datum validuntil; validuntil = heap_getattr(auth_tup, Anum_pg_authid_rolvaliduntil, auth_rel->rd_att, &isNull); /* we actually want it to be NULL, that means always valid */ if (!isNull) continue; attrName = heap_getattr(auth_tup, Anum_pg_authid_rolname, auth_rel->rd_att, &isNull); Assert(!isNull); suser = strdup(DatumGetCString(attrName)); } heap_endscan(auth_scan); heap_close(auth_rel, AccessShareLock); return suser; }
/* * Returns true if at least one user is defined in this database cluster. */ static bool ThereIsAtLeastOneUser(void) { Relation pg_shadow_rel; TupleDesc pg_shadow_dsc; HeapScanDesc scan; bool result; pg_shadow_rel = heap_openr(ShadowRelationName, AccessExclusiveLock); pg_shadow_dsc = RelationGetDescr(pg_shadow_rel); scan = heap_beginscan(pg_shadow_rel, SnapshotNow, 0, NULL); result = (heap_getnext(scan, ForwardScanDirection) != NULL); heap_endscan(scan); heap_close(pg_shadow_rel, AccessExclusiveLock); return result; }
/* --------------------------------------------------------------- * Open underlying relation for scan. * Open means resource acquisition, in seq scan, file descriptor. * * We delay open as much as possible, and later, close as early as * possible to prevent from hogging lots of resources. This is * very important because now some user partition a talbe to thousands * of smaller ones. If we are not careful, we cannot even do a * scan on the table. * * We need to do this for all the scanners. See nodeAppendOnlyscan.c * as well. * -------------------------------------------------------------- */ static void OpenScanRelation(SeqScanState *node) { Assert(node->scan_state == SCAN_INIT || node->scan_state == SCAN_DONE); Assert(!node->ss_currentScanDesc); node->ss_currentScanDesc = heap_beginscan( node->ss_currentRelation, node->ps.state->es_snapshot, 0, NULL); /* CKTAN- */ node->ss_heapTupleData.bot = node->ss_heapTupleData.top = node->ss_heapTupleData.seen_EOS = 0; node->ss_heapTupleData.last = NULL; node->scan_state = SCAN_SCAN; }
void PersistentStore_BeginScan( PersistentStoreData *storeData, PersistentStoreSharedData *storeSharedData, PersistentStoreScan *storeScan) { MemSet(storeScan, 0, sizeof(PersistentStoreScan)); storeScan->storeData = storeData; storeScan->storeSharedData = storeSharedData; storeScan->persistentRel = (*storeData->openRel)(); storeScan->scan = heap_beginscan( storeScan->persistentRel, SnapshotNow, 0, NULL); storeScan->tuple = NULL; }
/* * get_consumer_id * * Get the pipeline_kafka_consumers oid for the given relation-topic pair * */ static Oid get_consumer_id(Relation consumers, text *relation, text *topic) { ScanKeyData skey[2]; HeapTuple tup = NULL; HeapScanDesc scan; Oid oid = InvalidOid; ScanKeyInit(&skey[0], 1, BTEqualStrategyNumber, F_TEXTEQ, PointerGetDatum(relation)); ScanKeyInit(&skey[1], 2, BTEqualStrategyNumber, F_TEXTEQ, PointerGetDatum(topic)); scan = heap_beginscan(consumers, GetTransactionSnapshot(), 2, skey); tup = heap_getnext(scan, ForwardScanDirection); if (HeapTupleIsValid(tup)) oid = HeapTupleGetOid(tup); heap_endscan(scan); return oid; }
Datum kafka_consume_begin_all(PG_FUNCTION_ARGS) { HeapTuple tup = NULL; HeapScanDesc scan; Relation consumers = open_pipeline_kafka_consumers(); scan = heap_beginscan(consumers, GetTransactionSnapshot(), 0, NULL); while ((tup = heap_getnext(scan, ForwardScanDirection)) != NULL) { Oid id = HeapTupleGetOid(tup); KafkaConsumer consumer; load_consumer_state(id, &consumer); if (!launch_consumer_group(consumers, &consumer, RD_KAFKA_OFFSET_END)) RETURN_FAILURE(); } heap_endscan(scan); heap_close(consumers, NoLock); RETURN_SUCCESS(); }