151 int paramno,
int location);
153 const char *paramname,
int location);
204 pinfo->
nargs = nargs = procedureStruct->pronargs;
212 procedureStruct->proargtypes.values,
213 nargs *
sizeof(
Oid));
215 for (argnum = 0; argnum < nargs; argnum++)
217 Oid argtype = argOidVect[argnum];
224 (
errcode(ERRCODE_DATATYPE_MISMATCH),
225 errmsg(
"could not determine actual type of argument declared %s",
227 argOidVect[argnum] = argtype;
260 if (n_arg_names < nargs)
293 const char *name2 =
NULL;
345 if (strcmp(name1, pinfo->
fname) != 0)
353 else if (nnames == 2 && strcmp(name1, pinfo->
fname) == 0)
405 int paramno = pref->
number;
408 if (paramno <= 0 || paramno > pinfo->
nargs)
419 int paramno,
int location)
439 return (
Node *) param;
449 const char *paramname,
int location)
456 for (i = 0; i < pinfo->
nargs; i++)
480 foreach(lc1, queryTree_list)
506 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
508 errmsg(
"%s is not allowed in a SQL function",
513 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
515 errmsg(
"%s is not allowed in a non-volatile function",
524 preves->
next = newes;
541 eslist =
lappend(eslist, firstes);
590 List *raw_parsetree_list;
591 List *queryTree_list;
592 List *flat_query_list;
623 elog(
ERROR,
"cache lookup failed for function %u", foid);
635 rettype = procedureStruct->prorettype;
642 (
errcode(ERRCODE_DATATYPE_MISMATCH),
643 errmsg(
"could not determine actual result type for function declared to return type %s",
653 fcache->
returnsSet = procedureStruct->proretset;
676 elog(
ERROR,
"null prosrc for function %u", foid);
696 queryTree_list =
NIL;
697 flat_query_list =
NIL;
698 foreach(lc, raw_parsetree_list)
701 List *queryTree_sublist;
707 queryTree_list =
lappend(queryTree_list, queryTree_sublist);
856 uint64 count = (es->
lazyEval) ? 1 : 0;
895 int nargs = fcinfo->
nargs;
922 for (i = 0; i < nargs; i++)
993 bool pushed_snapshot;
1004 sqlerrcontext.
arg = fcinfo->flinfo;
1009 if (fcinfo->flinfo->fn_retset)
1023 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1024 errmsg(
"set-valued function called in context that cannot accept a set")));
1030 randomAccess =
false;
1046 fcinfo->flinfo->fn_extra =
NULL;
1074 foreach(eslc, eslist)
1120 pushed_snapshot =
false;
1136 if (!pushed_snapshot)
1139 pushed_snapshot =
true;
1151 pushed_snapshot =
true;
1197 if (pushed_snapshot)
1200 pushed_snapshot =
false;
1223 elog(
ERROR,
"failed to fetch lazy-eval tuple");
1226 fcache, oldcontext);
1260 fcinfo->isnull =
true;
1286 fcinfo->isnull =
true;
1310 fcache, oldcontext);
1313 fcinfo->isnull =
true;
1321 fcinfo->isnull =
true;
1330 if (pushed_snapshot)
1366 int syntaxerrposition;
1379 if (syntaxerrposition > 0 && fcache->
src !=
NULL)
1408 errcontext(
"SQL function \"%s\" statement %d",
1409 fcache->
fname, query_num);
1528 bool *modifyTargetList,
1541 if (modifyTargetList)
1542 *modifyTargetList =
false;
1552 foreach(lc, queryTreeList)
1592 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
1593 errmsg(
"return type mismatch in function declared to return %s",
1595 errdetail(
"Function's final statement must be SELECT or INSERT/UPDATE/DELETE RETURNING.")));
1629 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
1630 errmsg(
"return type mismatch in function declared to return %s",
1632 errdetail(
"Final statement must return exactly one column.")));
1641 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
1642 errmsg(
"return type mismatch in function declared to return %s",
1646 if (modifyTargetList && restype != rettype)
1655 *modifyTargetList =
true;
1692 if (modifyTargetList && restype != rettype)
1701 *modifyTargetList =
true;
1729 tupnatts = tupdesc->
natts;
1744 if (modifyTargetList)
1745 junkattrs =
lappend(junkattrs, tle);
1752 if (colindex > tupnatts)
1754 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
1755 errmsg(
"return type mismatch in function declared to return %s",
1757 errdetail(
"Final statement returns too many columns.")));
1758 attr = tupdesc->
attrs[colindex - 1];
1759 if (attr->attisdropped && modifyTargetList)
1778 *modifyTargetList =
true;
1780 }
while (attr->attisdropped);
1784 atttype = attr->atttypid;
1787 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
1788 errmsg(
"return type mismatch in function declared to return %s",
1790 errdetail(
"Final statement returns %s instead of %s at column %d.",
1794 if (modifyTargetList)
1796 if (tletype != atttype)
1805 *modifyTargetList =
true;
1807 tle->
resno = colindex;
1808 newtlist =
lappend(newtlist, tle);
1813 for (colindex++; colindex <= tupnatts; colindex++)
1815 if (!tupdesc->
attrs[colindex - 1]->attisdropped)
1817 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
1818 errmsg(
"return type mismatch in function declared to return %s",
1820 errdetail(
"Final statement returns too few columns.")));
1821 if (modifyTargetList)
1840 *modifyTargetList =
true;
1844 if (modifyTargetList)
1847 foreach(lc, junkattrs)
1851 tle->
resno = colindex++;
1868 (
errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
1869 errmsg(
"return type %s is not supported for SQL functions",
bool SubTransactionIsActive(SubTransactionId subxid)
ParamExternData params[FLEXIBLE_ARRAY_MEMBER]
void tuplestore_puttupleslot(Tuplestorestate *state, TupleTableSlot *slot)
TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)
void(* rDestroy)(DestReceiver *self)
void UpdateActiveSnapshotCommandId(void)
#define IsA(nodeptr, _type_)
void MemoryContextDelete(MemoryContext context)
void PreventCommandIfParallelMode(const char *cmdname)
static void sqlfunction_destroy(DestReceiver *self)
void FreeQueryDesc(QueryDesc *qdesc)
#define TYPTYPE_COMPOSITE
void UnregisterExprContextCallback(ExprContext *econtext, ExprContextCallbackFunction function, Datum arg)
#define PointerGetDatum(X)
char * pstrdup(const char *in)
JunkFilter * ExecInitJunkFilterConversion(List *targetList, TupleDesc cleanTupType, TupleTableSlot *slot)
void sql_fn_parser_setup(struct ParseState *pstate, SQLFunctionParseInfoPtr pinfo)
struct SQLFunctionParseInfo * SQLFunctionParseInfoPtr
void ExecutorStart(QueryDesc *queryDesc, int eflags)
Form_pg_attribute * attrs
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
#define Anum_pg_proc_prosrc
Snapshot GetActiveSnapshot(void)
List * pg_analyze_and_rewrite_params(Node *parsetree, const char *query_string, ParserSetupHook parserSetup, void *parserSetupArg)
struct execution_state execution_state
List * list_copy(const List *oldlist)
void ExecutorRun(QueryDesc *queryDesc, ScanDirection direction, uint64 count)
int errcode(int sqlerrcode)
TupleTableSlot * jf_resultSlot
bool check_sql_fn_retval(Oid func_id, Oid rettype, List *queryTreeList, bool *modifyTargetList, JunkFilter **junkFilter)
char get_typtype(Oid typid)
static void sqlfunction_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
bool CommandIsReadOnly(Node *parsetree)
Oid get_call_expr_argtype(Node *expr, int argnum)
static void postquel_start(execution_state *es, SQLFunctionCachePtr fcache)
List * list_concat(List *list1, List *list2)
static Node * sql_fn_resolve_param_name(SQLFunctionParseInfoPtr pinfo, const char *paramname, int location)
void PopActiveSnapshot(void)
Node * ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, FuncCall *fn, int location)
QueryDesc * CreateQueryDesc(PlannedStmt *plannedstmt, const char *sourceText, Snapshot snapshot, Snapshot crosscheck_snapshot, DestReceiver *dest, ParamListInfo params, int instrument_options)
ParserSetupHook parserSetup
struct ParamListInfoData * ParamListInfo
Const * makeConst(Oid consttype, int32 consttypmod, Oid constcollid, int constlen, Datum constvalue, bool constisnull, bool constbyval)
DestReceiver * None_Receiver
struct ErrorContextCallback * previous
Snapshot GetTransactionSnapshot(void)
#define OidIsValid(objectId)
#define PG_GET_COLLATION()
#define ALLOCSET_DEFAULT_MINSIZE
#define SearchSysCache1(cacheId, key1)
PostParseColumnRefHook p_post_columnref_hook
ErrorContextCallback * error_context_stack
void ExecutorEnd(QueryDesc *queryDesc)
ParamFetchHook paramFetch
void pfree(void *pointer)
bool IsInParallelMode(void)
#define ObjectIdGetDatum(X)
#define IsPolymorphicType(typid)
static void sql_exec_error_callback(void *arg)
List * pg_parse_query(const char *query_string)
void tuplestore_clear(Tuplestorestate *state)
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
static void postquel_end(execution_state *es)
ParseParamRefHook p_paramref_hook
void PushActiveSnapshot(Snapshot snap)
struct SQLFunctionParseInfo SQLFunctionParseInfo
RelabelType * makeRelabelType(Expr *arg, Oid rtype, int32 rtypmod, Oid rcollid, CoercionForm rformat)
TupleDesc jf_cleanTupType
DestReceiver * CreateDestReceiver(CommandDest dest)
JunkFilter * ExecInitJunkFilter(List *targetList, bool hasoid, TupleTableSlot *slot)
int errdetail(const char *fmt,...)
static Node * sql_fn_post_column_ref(ParseState *pstate, ColumnRef *cref, Node *var)
static void ShutdownSQLFunction(Datum arg)
FormData_pg_attribute * Form_pg_attribute
void(* ParserSetupHook)(struct ParseState *pstate, void *arg)
bool ActiveSnapshotSet(void)
static List * init_execution_state(List *queryTree_list, SQLFunctionCachePtr fcache, bool lazyEvalOK)
struct Bitmapset * paramMask
#define Anum_pg_proc_proargmodes
bool argnull[FUNC_MAX_ARGS]
MemoryContext CurrentMemoryContext
uint32 LocalTransactionId
Datum fmgr_sql(PG_FUNCTION_ARGS)
bool type_is_rowtype(Oid typid)
#define ereport(elevel, rest)
TargetEntry * makeTargetEntry(Expr *expr, AttrNumber resno, char *resname, bool resjunk)
#define AssertArg(condition)
Datum datumCopy(Datum value, bool typByVal, int typLen)
const char * CreateCommandTag(Node *parsetree)
void ExecutorFinish(QueryDesc *queryDesc)
int ExecCleanTargetListLength(List *targetlist)
SQLFunctionParseInfoPtr pinfo
bool IsBinaryCoercible(Oid srctype, Oid targettype)
struct ParamExternData ParamExternData
#define PROVOLATILE_VOLATILE
List * lappend(List *list, void *datum)
TypeFuncClass get_func_result_type(Oid functionId, Oid *resultTypeId, TupleDesc *resultTupleDesc)
#define Anum_pg_proc_proargnames
DestReceiver * CreateSQLFunctionDestReceiver(void)
TupleDesc tts_tupleDescriptor
Tuplestorestate * tuplestore_begin_heap(bool randomAccess, bool interXact, int maxKBytes)
int get_func_input_arg_names(Datum proargnames, Datum proargmodes, char ***arg_names)
#define TextDatumGetCString(d)
MemoryContext AllocSetContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
void * palloc0(Size size)
TupleTableSlot * ExecFilterJunk(JunkFilter *junkfilter, TupleTableSlot *slot)
void CommandCounterIncrement(void)
static void sqlfunction_receive(TupleTableSlot *slot, DestReceiver *self)
Oid get_fn_expr_rettype(FmgrInfo *flinfo)
void ReleaseSysCache(HeapTuple tuple)
static void sqlfunction_shutdown(DestReceiver *self)
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
FormData_pg_proc * Form_pg_proc
Oid get_typcollation(Oid typid)
int internalerrquery(const char *query)
SetFunctionReturnMode returnMode
static Datum postquel_get_single_result(TupleTableSlot *slot, FunctionCallInfo fcinfo, SQLFunctionCachePtr fcache, MemoryContext resultcontext)
bool tuplestore_gettupleslot(Tuplestorestate *state, bool forward, bool copy, TupleTableSlot *slot)
#define HeapTupleIsValid(tuple)
#define Assert(condition)
void RegisterExprContextCallback(ExprContext *econtext, ExprContextCallbackFunction function, Datum arg)
SubTransactionId GetCurrentSubTransactionId(void)
Oid exprType(const Node *expr)
static int list_length(const List *l)
void tuplestore_end(Tuplestorestate *state)
void get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval)
static Node * sql_fn_param_ref(ParseState *pstate, ParamRef *pref)
#define EXEC_FLAG_SKIP_TRIGGERS
Tuplestorestate * setResult
#define DatumGetPointer(X)
#define CURSOR_OPT_PARALLEL_OK
SQLFunctionCache * SQLFunctionCachePtr
void(* callback)(void *arg)
int errmsg(const char *fmt,...)
#define ALLOCSET_DEFAULT_INITSIZE
Datum slot_getattr(TupleTableSlot *slot, int attnum, bool *isnull)
static Node * sql_fn_make_param(SQLFunctionParseInfoPtr pinfo, int paramno, int location)
#define ALLOCSET_DEFAULT_MAXSIZE
PreParseColumnRefHook p_pre_columnref_hook
QueryDesc * CreateUtilityQueryDesc(Node *utilitystmt, const char *sourceText, Snapshot snapshot, DestReceiver *dest, ParamListInfo params)
SQLFunctionParseInfoPtr prepare_sql_fn_parse_info(HeapTuple procedureTuple, Node *call_expr, Oid inputCollation)
PlannedStmt * plannedstmt
Datum ExecFetchSlotTupleDatum(TupleTableSlot *slot)
struct execution_state * next
static bool postquel_getnext(execution_state *es, SQLFunctionCachePtr fcache)
static void postquel_sub_params(SQLFunctionCachePtr fcache, FunctionCallInfo fcinfo)
#define offsetof(type, field)
int errposition(int cursorpos)
static void init_sql_fcache(FmgrInfo *finfo, Oid collation, bool lazyEvalOK)
static struct subre * parse(struct vars *, int, int, struct state *, struct state *)
void ProcessUtility(Node *parsetree, const char *queryString, ProcessUtilityContext context, ParamListInfo params, DestReceiver *dest, char *completionTag)
int internalerrposition(int cursorpos)
PlannedStmt * pg_plan_query(Query *querytree, int cursorOptions, ParamListInfo boundParams)