Example #1
0
/*
 * Logic for set-returning functions.
 *
 * Currently it uses the simplest, return
 * one value/tuple per call mechanism.
 */
static Datum
handle_ret_set(FunctionCallInfo fcinfo)
{
	ProxyFunction *func;
	FuncCallContext *ret_ctx;

	if (SRF_IS_FIRSTCALL())
	{
		func = compile_and_execute(fcinfo);
		ret_ctx = SRF_FIRSTCALL_INIT();
		ret_ctx->user_fctx = func;
	}

	ret_ctx = SRF_PERCALL_SETUP();
	func = ret_ctx->user_fctx;

	if (func->cur_cluster->ret_total > 0)
	{
		SRF_RETURN_NEXT(ret_ctx, plproxy_result(func, fcinfo));
	}
	else
	{
		plproxy_clean_results(func->cur_cluster);
		SRF_RETURN_DONE(ret_ctx);
	}
}
Example #2
0
/*
 * The PostgreSQL function & trigger manager calls this function
 * for execution of PL/Proxy procedures.
 *
 * Main entry point for rest of the code.
 */
Datum
plproxy_call_handler(PG_FUNCTION_ARGS)
{
	ProxyFunction *func;
	Datum		ret;

	if (CALLED_AS_TRIGGER(fcinfo))
		elog(ERROR, "PL/Proxy procedures can't be used as triggers");

	/* clean old results */
	if (!fcinfo->flinfo->fn_retset || SRF_IS_FIRSTCALL())
		run_maint();

	if (fcinfo->flinfo->fn_retset)
	{
		ret = handle_ret_set(fcinfo);
	}
	else
	{
		func = compile_and_execute(fcinfo);
		if (func->cur_cluster->ret_total != 1)
			plproxy_error_with_state(func,
				(func->cur_cluster->ret_total < 1) ? ERRCODE_NO_DATA_FOUND : ERRCODE_TOO_MANY_ROWS,
				"Non-SETOF function requires 1 row from remote query, got %d",
					func->cur_cluster->ret_total);
		ret = plproxy_result(func, fcinfo);
		plproxy_clean_results(func->cur_cluster);
	}
	return ret;
}
Example #3
0
/*
 * Centralised error reporting.
 *
 * Also frees any pending results.
 */
void
plproxy_error(ProxyFunction *func, const char *fmt,...)
{
	char		msg[1024];
	va_list		ap;

	va_start(ap, fmt);
	vsnprintf(msg, sizeof(msg), fmt, ap);
	va_end(ap);

	plproxy_clean_results(func->cur_cluster);

	elog(ERROR, "PL/Proxy function %s(%d): %s",
		 func->name, func->arg_count, msg);
}
Example #4
0
/*
 * Centralised error reporting.
 *
 * Also frees any pending results.
 */
void
plproxy_error_with_state(ProxyFunction *func, int sqlstate, const char *fmt, ...)
{
	char		msg[1024];
	va_list		ap;

	va_start(ap, fmt);
	vsnprintf(msg, sizeof(msg), fmt, ap);
	va_end(ap);

	plproxy_clean_results(func->cur_cluster);

	ereport(ERROR, (
		errcode(sqlstate),
		errmsg("PL/Proxy function %s(%d): %s",
			func->name, func->arg_count, msg)));
}