citus/src/backend/distributed/utils/function_utils.c

99 lines
2.9 KiB
C

/*-------------------------------------------------------------------------
*
* function_utils.c
* Utilities regarding calls to PG functions
*
* Copyright (c) Citus Data, Inc.
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "catalog/namespace.h"
#include "distributed/function_utils.h"
#include "distributed/version_compat.h"
#include "executor/executor.h"
#include "utils/builtins.h"
#include "utils/regproc.h"
/*
* FunctionOid searches for a function that has the given name and the given
* number of arguments, and returns the corresponding function's oid. The
* function reports error if the target function is not found, or it found more
* matching instances.
*/
Oid
FunctionOid(const char *schemaName, const char *functionName, int argumentCount)
{
return FunctionOidExtended(schemaName, functionName, argumentCount, false);
}
/*
* FunctionOidExtended searches for a given function identified by schema,
* functionName, and argumentCount. It reports error if the function is not
* found or there are more than one match. If the missingOK parameter is set
* and there are no matches, then the function returns InvalidOid.
*/
Oid
FunctionOidExtended(const char *schemaName, const char *functionName, int argumentCount,
bool missingOK)
{
char *qualifiedFunctionName = quote_qualified_identifier(schemaName, functionName);
List *qualifiedFunctionNameList = stringToQualifiedNameList(qualifiedFunctionName);
List *argumentList = NIL;
const bool findVariadics = false;
const bool findDefaults = false;
FuncCandidateList functionList = FuncnameGetCandidates(qualifiedFunctionNameList,
argumentCount,
argumentList, findVariadics,
findDefaults, true);
if (functionList == NULL)
{
if (missingOK)
{
return InvalidOid;
}
ereport(ERROR, (errcode(ERRCODE_UNDEFINED_FUNCTION),
errmsg("function \"%s\" does not exist", functionName)));
}
else if (functionList->next != NULL)
{
ereport(ERROR, (errcode(ERRCODE_AMBIGUOUS_FUNCTION),
errmsg("more than one function named \"%s\"", functionName)));
}
/* get function oid from function list's head */
Oid functionOid = functionList->oid;
return functionOid;
}
/*
* FunctionCallGetTupleStore1 calls the given set-returning PGFunction with the given
* argument and returns the ResultSetInfo filled by the called function.
*/
ReturnSetInfo *
FunctionCallGetTupleStore1(PGFunction function, Oid functionId, Datum argument)
{
LOCAL_FCINFO(fcinfo, 1);
FmgrInfo flinfo;
ReturnSetInfo *rsinfo = makeNode(ReturnSetInfo);
EState *estate = CreateExecutorState();
rsinfo->econtext = GetPerTupleExprContext(estate);
rsinfo->allowedModes = SFRM_Materialize;
fmgr_info(functionId, &flinfo);
InitFunctionCallInfoData(*fcinfo, &flinfo, 1, InvalidOid, NULL, (Node *) rsinfo);
fcSetArg(fcinfo, 0, argument);
(*function)(fcinfo);
return rsinfo;
}