Esempio n. 1
0
/*
 * ProcessRoleGUC --
 * We now process pg_authid.rolconfig separately from InitializeSessionUserId,
 * since it's too early to access toast table before initializing all
 * relcaches in phase3.
 */
static void
ProcessRoleGUC(void)
{
	cqContext  *pcqCtx;
	Oid			roleId;
	HeapTuple	roleTup;
	Datum		datum;
	bool		isnull;

	/* This should have been set by now */
	roleId = GetUserId();
	Assert(OidIsValid(roleId));

	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_authid "
				" WHERE oid = :1",
				ObjectIdGetDatum(roleId)));

	roleTup = caql_getnext(pcqCtx);

	if (!HeapTupleIsValid(roleTup))
		ereport(FATAL,
				(errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
				 errmsg("role %u does not exist", roleId), errSendAlert(false)));

	/*
	 * Set up user-specific configuration variables.  This is a good place to
	 * do it so we don't have to read pg_authid twice during session startup.
	 */
	datum = caql_getattr(pcqCtx,
						 Anum_pg_authid_rolconfig, &isnull);
	if (!isnull)
	{
		ArrayType  *a = DatumGetArrayTypeP(datum);

		/*
		 * We process all the options at SUSET level.  We assume that the
		 * right to insert an option into pg_authid was checked when it was
		 * inserted.
		 */
		ProcessGUCArray(a, PGC_SUSET, PGC_S_USER, GUC_ACTION_SET);
	}

	caql_endscan(pcqCtx);
}
Esempio n. 2
0
/*
 * get_func_result_name
 *
 * If the function has exactly one output parameter, and that parameter
 * is named, return the name (as a palloc'd string).  Else return NULL.
 *
 * This is used to determine the default output column name for functions
 * returning scalar types.
 */
char *
get_func_result_name(Oid functionId)
{
	char	   *result;
	HeapTuple	procTuple;
	Datum		proargmodes;
	Datum		proargnames;
	bool		isnull;
	ArrayType  *arr;
	int			numargs;
	char	   *argmodes;
	Datum	   *argnames;
	int			numoutargs;
	int			nargnames;
	int			i;
	cqContext  *pcqCtx;

	/* First fetch the function's pg_proc row */
	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_proc "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(functionId)));

	procTuple = caql_getnext(pcqCtx);

	if (!HeapTupleIsValid(procTuple))
		elog(ERROR, "cache lookup failed for function %u", functionId);

	/* If there are no named OUT parameters, return NULL */
	if (heap_attisnull(procTuple, Anum_pg_proc_proargmodes) ||
		heap_attisnull(procTuple, Anum_pg_proc_proargnames))
		result = NULL;
	else
	{
		/* Get the data out of the tuple */
		proargmodes = caql_getattr(pcqCtx,
								   Anum_pg_proc_proargmodes,
								   &isnull);
		Assert(!isnull);
		proargnames = caql_getattr(pcqCtx,
								   Anum_pg_proc_proargnames,
								   &isnull);
		Assert(!isnull);

		/*
		 * We expect the arrays to be 1-D arrays of the right types; verify
		 * that.  For the char array, we don't need to use deconstruct_array()
		 * since the array data is just going to look like a C array of
		 * values.
		 */
		arr = DatumGetArrayTypeP(proargmodes);	/* ensure not toasted */
		numargs = ARR_DIMS(arr)[0];
		if (ARR_NDIM(arr) != 1 ||
			numargs < 0 ||
			ARR_HASNULL(arr) ||
			ARR_ELEMTYPE(arr) != CHAROID)
			elog(ERROR, "proargmodes is not a 1-D char array");
		argmodes = (char *) ARR_DATA_PTR(arr);
		arr = DatumGetArrayTypeP(proargnames);	/* ensure not toasted */
		if (ARR_NDIM(arr) != 1 ||
			ARR_DIMS(arr)[0] != numargs ||
			ARR_HASNULL(arr) ||
			ARR_ELEMTYPE(arr) != TEXTOID)
			elog(ERROR, "proargnames is not a 1-D text array");
		deconstruct_array(arr, TEXTOID, -1, false, 'i',
						  &argnames, NULL, &nargnames);
		Assert(nargnames == numargs);

		/* scan for output argument(s) */
		result = NULL;
		numoutargs = 0;
		for (i = 0; i < numargs; i++)
		{
			if (argmodes[i] == PROARGMODE_IN ||
				argmodes[i] == PROARGMODE_VARIADIC)
				continue;
			Assert(argmodes[i] == PROARGMODE_OUT ||
				   argmodes[i] == PROARGMODE_INOUT ||
				   argmodes[i] == PROARGMODE_TABLE);
			if (++numoutargs > 1)
			{
				/* multiple out args, so forget it */
				result = NULL;
				break;
			}
			result = DatumGetCString(DirectFunctionCall1(textout,
														 argnames[i]));
			if (result == NULL || result[0] == '\0')
			{
				/* Parameter is not named, so forget it */
				result = NULL;
				break;
			}
		}
	}

	caql_endscan(pcqCtx);

	return result;
}
Esempio n. 3
0
Datum
caql_insert_to_in_memory_pg_namespace(PG_FUNCTION_ARGS)
{
	Oid nspid = PG_GETARG_OID(0);
	char *nspname = text_to_cstring(PG_GETARG_TEXT_P(1));
	Oid nspdboid = PG_GETARG_OID(2);
	HeapTuple tuple;

	Datum values[Natts_pg_namespace];
	bool nulls[Natts_pg_namespace];

	/* initialize nulls and values */
	for (int i = 0; i < Natts_pg_namespace; i++)
	{
		nulls[i] = true;
		values[i] = (Datum) 0;
	}

	NameData name;
	namestrcpy(&name, nspname);

	values[Anum_pg_namespace_nspname - 1] = NameGetDatum(&name);
	values[Anum_pg_namespace_nspdboid - 1] = ObjectIdGetDatum(nspdboid);
	nulls[Anum_pg_namespace_nspname - 1] = false;
	nulls[Anum_pg_namespace_nspdboid - 1] = false;
	
	cqContext  *pcqCtx = caql_beginscan(
			NULL,
			cql("INSERT INTO pg_namespace", NULL));

	HeapTuple tup = caql_form_tuple(pcqCtx, values, nulls);
	HeapTupleSetOid(tup, nspid);

	caql_insert_inmem(pcqCtx, tup);
	caql_endscan(pcqCtx);

	StringInfoData buf;
	initStringInfo(&buf);
	appendStringInfo(&buf, "inserted tuple to pg_namespace (oid %d, nspname %s, nspdboid %d)", nspid, nspname, nspdboid);

	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_namespace "
					"WHERE nspname = :1",
					CStringGetDatum((char *) nspname)));

	while (HeapTupleIsValid(tuple = caql_getnext(pcqCtx)))
	{
		Oid thisoid = HeapTupleGetOid(tuple);

		bool isNull;
		Datum data = caql_getattr(pcqCtx, Anum_pg_namespace_nspdboid, &isNull);
		Oid namespacedboid = DatumGetObjectId(data);
		data = caql_getattr(pcqCtx, Anum_pg_namespace_nspname, &isNull);
		char *namespacename = DatumGetCString(data);

		appendStringInfo(&buf, "\nresult tuple: (oid %d, nspname %s, nspdboid %d)", thisoid, namespacename, namespacedboid);
	}

	caql_endscan(pcqCtx);

	PG_RETURN_TEXT_P(cstring_to_text(buf.data));
}