Ejemplo n.º 1
0
/*
 * 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();
}
Ejemplo n.º 2
0
/*
 * 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;
}
Ejemplo n.º 3
0
/*
 * 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;
}
Ejemplo n.º 4
0
/*
 * 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);
}
Ejemplo n.º 5
0
/**
 * @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;
}
Ejemplo n.º 6
0
/*
 *--------------------------------------------------------------
 * 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);
}
bool PersistentStore_GetNext(
	PersistentStoreScan			*storeScan,

	Datum						*values,

	ItemPointer					persistentTid,

	int64						*persistentSerialNum)
{
	ItemPointerData			previousFreeTid;

	storeScan->tuple = heap_getnext(storeScan->scan, ForwardScanDirection);
	if (storeScan->tuple == NULL)
		return false;

	PersistentStore_DeformTuple(
							storeScan->storeData,
							storeScan->persistentRel->rd_att,
							storeScan->tuple,
							values);
	PersistentStore_ExtractOurTupleData(
								storeScan->storeData,
								values,
								persistentSerialNum,
								&previousFreeTid);

	*persistentTid = storeScan->tuple->t_self;

	return true;
}
Ejemplo n.º 8
0
/*
 * 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++;
		}
Ejemplo n.º 9
0
/*
 * 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;
}
Ejemplo n.º 10
0
/*
 * 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;
}
Ejemplo n.º 11
0
/*
 * 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;
}
Ejemplo n.º 12
0
/*
 * 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;
}
Ejemplo n.º 13
0
/*
 * 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;
}
Ejemplo n.º 14
0
/*
 * 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;
}
Ejemplo n.º 15
0
/*
 * Load the list of subscriptions.
 *
 * Only the fields interesting for worker start/stop functions are filled for
 * each subscription.
 */
static List *
get_subscription_list(void)
{
	List	   *res = NIL;
	Relation	rel;
	TableScanDesc 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();

	rel = table_open(SubscriptionRelationId, AccessShareLock);
	scan = table_beginscan_catalog(rel, 0, NULL);

	while (HeapTupleIsValid(tup = heap_getnext(scan, ForwardScanDirection)))
	{
		Form_pg_subscription subform = (Form_pg_subscription) GETSTRUCT(tup);
		Subscription *sub;
		MemoryContext oldcxt;

		/*
		 * 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);

		sub = (Subscription *) palloc0(sizeof(Subscription));
		sub->oid = subform->oid;
		sub->dbid = subform->subdbid;
		sub->owner = subform->subowner;
		sub->enabled = subform->subenabled;
		sub->name = pstrdup(NameStr(subform->subname));
		/* We don't fill fields we are not interested in. */

		res = lappend(res, sub);
		MemoryContextSwitchTo(oldcxt);
	}

	table_endscan(scan);
	table_close(rel, AccessShareLock);

	CommitTransactionCommand();

	return res;
}
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);
}
Ejemplo n.º 17
0
/* ----------------------------------------------------------------
 *		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;
}
Ejemplo n.º 18
0
/*
 * 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);
}
Ejemplo n.º 19
0
/*
 * systable_getnext --- get next tuple in a heap-or-index scan
 *
 * Returns NULL if no more tuples available.
 *
 * Note that returned tuple is a reference to data in a disk buffer;
 * it must not be modified, and should be presumed inaccessible after
 * next getnext() or endscan() call.
 */
HeapTuple
systable_getnext(SysScanDesc sysscan)
{
	HeapTuple	htup;

	if (sysscan->irel)
		htup = index_getnext(sysscan->iscan, ForwardScanDirection);
	else
		htup = heap_getnext(sysscan->scan, ForwardScanDirection);

	return htup;
}
Ejemplo n.º 20
0
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);
}
Ejemplo n.º 21
0
/*
 * 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);
}
Ejemplo n.º 22
0
/*
 * 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;
}
Ejemplo n.º 23
0
/*
 * 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_t get_rewrite_oid_without_relid(const char *rulename, oid_t* reloid)
{
	struct relation* RewriteRelation;
	struct heap_scan* scanDesc;
	struct scankey scanKeyData;
	struct heap_tuple* htup;
	oid_t ruleoid;

	/* Search pg_rewrite for such a rule */
	scankey_init(&scanKeyData, Anum_pg_rewrite_rulename,
		BT_EQ_STRAT_NR, F_NAMEEQ, CSTRING_TO_D(rulename));

	RewriteRelation = heap_open(RewriteRelationId, ACCESS_SHR_LOCK);
	scanDesc = heap_beginscan(RewriteRelation, snap_now, 1, &scanKeyData);
	htup = heap_getnext(scanDesc, FORWARD_SCANDIR);
	if (!HT_VALID(htup)) {
		ereport(ERROR, (
		errcode(E_UNDEFINED_OBJECT),
		errmsg("rule \"%s\" does not exist", rulename)));
	}

	ruleoid = HEAPTUP_OID(htup);
	if (reloid != NULL)
		*reloid = ((Form_pg_rewrite) GET_STRUCT(htup))->ev_class;

	if (HT_VALID(htup = heap_getnext(scanDesc, FORWARD_SCANDIR))) {
		ereport(ERROR, (
		errcode(E_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, ACCESS_SHR_LOCK);

	return ruleoid;
}
Ejemplo n.º 24
0
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;
}
Ejemplo n.º 25
0
/*
 * 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;
}
Ejemplo n.º 26
0
/*
 *--------------------------------------------------------------
 * 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?
	 */
}
Ejemplo n.º 27
0
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);
    }
}
Ejemplo n.º 28
0
/*
 * 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;
}
Ejemplo n.º 29
0
/*
 * 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;
}
Ejemplo n.º 30
0
/**
 * @brief Print all databases using catalog table pg_database
 */
void Bridge::GetDatabaseList(void) {
  LOG_WARN("Do not use bridge function(%s) in Peloton !!! ", __func__);
  Relation pg_database_rel;
  HeapScanDesc scan;
  HeapTuple tup;

  // Scan pg database table
  pg_database_rel = heap_open(DatabaseRelationId, AccessShareLock);
  scan = heap_beginscan_catalog(pg_database_rel, 0, NULL);

  while (HeapTupleIsValid(tup = heap_getnext(scan, ForwardScanDirection))) {
    Form_pg_database pg_database = (Form_pg_database)GETSTRUCT(tup);
    Oid database_oid = HeapTupleHeaderGetOid(tup->t_data);
    elog(LOG, "pgdatabase->datname  :: %s oid %d ",
         NameStr(pg_database->datname), (int)database_oid);
  }

  heap_endscan(scan);
  heap_close(pg_database_rel, AccessShareLock);
}