mirror of https://github.com/citusdata/citus.git
99 lines
2.9 KiB
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;
|
|
}
|