Пример #1
0
/*
 * ResQueueIdForName -- Return the Oid for a resource queue name
 *
 * Notes:
 *	Used by the various admin commands to convert a user supplied queue name
 *	to Oid.
 */
Oid
GetResQueueIdForName(char	*name)
{
	Oid					queueid = InvalidOid;

	queueid = caql_getoid(
			NULL,
			cql("SELECT oid FROM pg_resqueue "
				" WHERE rsqname = :1 ",
				CStringGetDatum(name)));

	return queueid;
}
Пример #2
0
/*
 * IsErrorTable
 *
 * Returns true if relid is used as an error table, which has dependent object
 * that is an external table.  Though it's not great we didn't have a clear
 * definition of Error Table, it satisfies the current requirements.
 */
bool
IsErrorTable(Relation rel)
{
	cqContext	   *pcqCtx, *pcqCtxExt, ctxExt;
	HeapTuple		tup;
	Relation		extrel;
	bool			result = false;

	/* fast path to quick check */
	if (!RelationIsHeap(rel))
		return false;

	/*
	 * Otherwise, go deeper and play with pg_depend...
	 */
	pcqCtx = caql_beginscan(NULL,
							cql("SELECT * FROM pg_depend "
								" WHERE refclassid = :1 "
								" AND refobjid = :2 "
								" AND refobjsubid = :3 ",
								ObjectIdGetDatum(RelationRelationId),
								ObjectIdGetDatum(RelationGetRelid(rel)),
								Int32GetDatum(0)));

	extrel = relation_open(ExtTableRelationId, AccessShareLock);
	pcqCtxExt = caql_addrel(cqclr(&ctxExt), extrel);

	while (HeapTupleIsValid(tup = caql_getnext(pcqCtx)))
	{
		Form_pg_depend dep = (Form_pg_depend) GETSTRUCT(tup);
		Oid				fmterrtbl;

		fmterrtbl = caql_getoid(pcqCtxExt,
								cql("SELECT fmterrtbl FROM pg_exttable "
									" WHERE reloid = :1",
									ObjectIdGetDatum(dep->objid)));
		if (RelationGetRelid(rel) == fmterrtbl)
		{
			result = true;
			break;
		}
	}

	relation_close(extrel, AccessShareLock);

	caql_endscan(pcqCtx);

	return result;
}
Пример #3
0
Datum
pg_relation_size_name(PG_FUNCTION_ARGS)
{
	text	   *relname = PG_GETARG_TEXT_P(0);
	RangeVar   *relrv;
	Relation	rel;
	int64		size;
	
	/**
	 * This function is peculiar in that it does its own dispatching.
	 * It does not work on entry db since we do not support dispatching
	 * from entry-db currently.
	 */
	if (Gp_role == GP_ROLE_EXECUTE && Gp_segment == -1)
	{
		elog(ERROR, "This query is not currently supported by GPDB.");
	}
	
	relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname));
	
	if (Gp_role == GP_ROLE_EXECUTE && relrv->schemaname != NULL)
	{
		Oid namespaceId;
		Oid relOid;
		/*
		 * Do this the hard way, because the optimizer wants to be
		 * able to use this function on relations the user might not
		 * have direct access to.
		 */

		AcceptInvalidationMessages();

		namespaceId = caql_getoid(
				NULL,
				cql("SELECT oid FROM pg_namespace "
					" WHERE nspname = :1 ",
					CStringGetDatum(relrv->schemaname)));

		relOid = get_relname_relid(relrv->relname, namespaceId);
		
		if (!OidIsValid(relOid))
		{
			size = 0;
			PG_RETURN_INT64(size);
		}
		
		/* Let relation_open do the rest */
		rel = try_relation_open(relOid, AccessShareLock, false);
	}
	else
		rel = try_relation_openrv(relrv, AccessShareLock, false);
		
	/*
	 * While we scan pg_class with an MVCC snapshot,
	 * someone else might drop the table. It's better to return NULL for
	 * already-dropped tables than throw an error and abort the whole query.
	 */
	if (!RelationIsValid(rel))
  		PG_RETURN_NULL();
	
	if (rel->rd_node.relNode == 0)
		size = 0;
	else
		size = calculate_relation_size(rel); 
	
	if (Gp_role == GP_ROLE_DISPATCH)
	{
		char * rawname;
		StringInfoData buffer;
		
		initStringInfo(&buffer);
		
		rawname = DatumGetCString(DirectFunctionCall1(textout,
													  PointerGetDatum(relname)));
		
		initStringInfo(&buffer);

		appendStringInfo(&buffer, "select sum(pg_relation_size('%s'))::int8 from gp_dist_random('gp_id');", rawname);

		size += get_size_from_segDBs(buffer.data);
	}

	relation_close(rel, AccessShareLock);

	PG_RETURN_INT64(size);
}