PostgreSQL Source Code git master
functions.h File Reference
#include "nodes/execnodes.h"
#include "tcop/dest.h"
Include dependency graph for functions.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  SQLFunctionParseInfo
 

Typedefs

typedef struct SQLFunctionParseInfo SQLFunctionParseInfo
 
typedef SQLFunctionParseInfoSQLFunctionParseInfoPtr
 

Functions

Datum fmgr_sql (PG_FUNCTION_ARGS)
 
SQLFunctionParseInfoPtr prepare_sql_fn_parse_info (HeapTuple procedureTuple, Node *call_expr, Oid inputCollation)
 
void sql_fn_parser_setup (struct ParseState *pstate, SQLFunctionParseInfoPtr pinfo)
 
void check_sql_fn_statements (List *queryTreeLists)
 
bool check_sql_fn_retval (List *queryTreeLists, Oid rettype, TupleDesc rettupdesc, char prokind, bool insertDroppedCols)
 
DestReceiverCreateSQLFunctionDestReceiver (void)
 

Typedef Documentation

◆ SQLFunctionParseInfo

◆ SQLFunctionParseInfoPtr

Definition at line 35 of file functions.h.

Function Documentation

◆ check_sql_fn_retval()

bool check_sql_fn_retval ( List queryTreeLists,
Oid  rettype,
TupleDesc  rettupdesc,
char  prokind,
bool  insertDroppedCols 
)

Definition at line 2088 of file functions.c.

2092{
2093 List *queryTreeList;
2094
2095 /*
2096 * We consider only the last sublist of Query nodes, so that only the last
2097 * original statement is a candidate to produce the result. This is a
2098 * change from pre-v18 versions, which would back up to the last statement
2099 * that includes a canSetTag query, thus ignoring any ending statement(s)
2100 * that rewrite to DO INSTEAD NOTHING. That behavior was undocumented and
2101 * there seems no good reason for it, except that it was an artifact of
2102 * the original coding.
2103 *
2104 * If the function body is completely empty, handle that the same as if
2105 * the last query had rewritten to nothing.
2106 */
2107 if (queryTreeLists != NIL)
2108 queryTreeList = llast_node(List, queryTreeLists);
2109 else
2110 queryTreeList = NIL;
2111
2112 return check_sql_stmt_retval(queryTreeList,
2113 rettype, rettupdesc,
2114 prokind, insertDroppedCols);
2115}
static bool check_sql_stmt_retval(List *queryTreeList, Oid rettype, TupleDesc rettupdesc, char prokind, bool insertDroppedCols)
Definition: functions.c:2122
#define NIL
Definition: pg_list.h:68
#define llast_node(type, l)
Definition: pg_list.h:202
Definition: pg_list.h:54

References check_sql_stmt_retval(), llast_node, and NIL.

Referenced by fmgr_sql_validator(), inline_function(), and inline_set_returning_function().

◆ check_sql_fn_statements()

void check_sql_fn_statements ( List queryTreeLists)

Definition at line 2007 of file functions.c.

2008{
2009 ListCell *lc;
2010
2011 /* We are given a list of sublists of Queries */
2012 foreach(lc, queryTreeLists)
2013 {
2014 List *sublist = lfirst_node(List, lc);
2015
2016 check_sql_fn_statement(sublist);
2017 }
2018}
static void check_sql_fn_statement(List *queryTreeList)
Definition: functions.c:2024
#define lfirst_node(type, lc)
Definition: pg_list.h:176

References check_sql_fn_statement(), and lfirst_node.

Referenced by fmgr_sql_validator().

◆ CreateSQLFunctionDestReceiver()

DestReceiver * CreateSQLFunctionDestReceiver ( void  )

Definition at line 2589 of file functions.c.

2590{
2592
2597 self->pub.mydest = DestSQLFunction;
2598
2599 /* private fields will be set by postquel_start */
2600
2601 return (DestReceiver *) self;
2602}
@ DestSQLFunction
Definition: dest.h:96
static void sqlfunction_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
Definition: functions.c:2608
static bool sqlfunction_receive(TupleTableSlot *slot, DestReceiver *self)
Definition: functions.c:2617
static void sqlfunction_destroy(DestReceiver *self)
Definition: functions.c:2664
static void sqlfunction_shutdown(DestReceiver *self)
Definition: functions.c:2655
void * palloc0(Size size)
Definition: mcxt.c:1975
DestReceiver pub
Definition: functions.c:46
void(* rStartup)(DestReceiver *self, int operation, TupleDesc typeinfo)
Definition: dest.h:121
void(* rShutdown)(DestReceiver *self)
Definition: dest.h:124
bool(* receiveSlot)(TupleTableSlot *slot, DestReceiver *self)
Definition: dest.h:118
void(* rDestroy)(DestReceiver *self)
Definition: dest.h:126
CommandDest mydest
Definition: dest.h:128

References DestSQLFunction, _DestReceiver::mydest, palloc0(), DR_sqlfunction::pub, _DestReceiver::rDestroy, _DestReceiver::receiveSlot, _DestReceiver::rShutdown, _DestReceiver::rStartup, sqlfunction_destroy(), sqlfunction_receive(), sqlfunction_shutdown(), and sqlfunction_startup().

Referenced by CreateDestReceiver().

◆ fmgr_sql()

Datum fmgr_sql ( PG_FUNCTION_ARGS  )

Definition at line 1554 of file functions.c.

1555{
1556 SQLFunctionCachePtr fcache;
1557 ErrorContextCallback sqlerrcontext;
1558 MemoryContext tscontext;
1559 bool randomAccess;
1560 bool lazyEvalOK;
1561 bool pushed_snapshot;
1562 execution_state *es;
1563 TupleTableSlot *slot;
1564 Datum result;
1565
1566 /* Check call context */
1567 if (fcinfo->flinfo->fn_retset)
1568 {
1569 ReturnSetInfo *rsi = (ReturnSetInfo *) fcinfo->resultinfo;
1570
1571 /*
1572 * For simplicity, we require callers to support both set eval modes.
1573 * There are cases where we must use one or must use the other, and
1574 * it's not really worthwhile to postpone the check till we know. But
1575 * note we do not require caller to provide an expectedDesc.
1576 */
1577 if (!rsi || !IsA(rsi, ReturnSetInfo) ||
1578 (rsi->allowedModes & SFRM_ValuePerCall) == 0 ||
1579 (rsi->allowedModes & SFRM_Materialize) == 0)
1580 ereport(ERROR,
1581 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1582 errmsg("set-valued function called in context that cannot accept a set")));
1583 randomAccess = rsi->allowedModes & SFRM_Materialize_Random;
1584 lazyEvalOK = !(rsi->allowedModes & SFRM_Materialize_Preferred);
1585 /* tuplestore, if used, must have query lifespan */
1586 tscontext = rsi->econtext->ecxt_per_query_memory;
1587 }
1588 else
1589 {
1590 randomAccess = false;
1591 lazyEvalOK = true;
1592 /* we won't need a tuplestore */
1593 tscontext = NULL;
1594 }
1595
1596 /*
1597 * Initialize fcache if starting a fresh execution.
1598 */
1599 fcache = init_sql_fcache(fcinfo, lazyEvalOK);
1600
1601 /* Remember info that we might need later to construct tuplestore */
1602 fcache->tscontext = tscontext;
1603 fcache->randomAccess = randomAccess;
1604
1605 /*
1606 * Now we can set up error traceback support for ereport()
1607 */
1608 sqlerrcontext.callback = sql_exec_error_callback;
1609 sqlerrcontext.arg = fcache;
1610 sqlerrcontext.previous = error_context_stack;
1611 error_context_stack = &sqlerrcontext;
1612
1613 /*
1614 * Find first unfinished execution_state. If none, advance to the next
1615 * query in function.
1616 */
1617 do
1618 {
1619 es = fcache->eslist;
1620 while (es && es->status == F_EXEC_DONE)
1621 es = es->next;
1622 if (es)
1623 break;
1624 } while (init_execution_state(fcache));
1625
1626 /*
1627 * Execute each command in the function one after another until we either
1628 * run out of commands or get a result row from a lazily-evaluated SELECT.
1629 *
1630 * Notes about snapshot management:
1631 *
1632 * In a read-only function, we just use the surrounding query's snapshot.
1633 *
1634 * In a non-read-only function, we rely on the fact that we'll never
1635 * suspend execution between queries of the function: the only reason to
1636 * suspend execution before completion is if we are returning a row from a
1637 * lazily-evaluated SELECT. So, when first entering this loop, we'll
1638 * either start a new query (and push a fresh snapshot) or re-establish
1639 * the active snapshot from the existing query descriptor. If we need to
1640 * start a new query in a subsequent execution of the loop, either we need
1641 * a fresh snapshot (and pushed_snapshot is false) or the existing
1642 * snapshot is on the active stack and we can just bump its command ID.
1643 */
1644 pushed_snapshot = false;
1645 while (es)
1646 {
1647 bool completed;
1648
1649 if (es->status == F_EXEC_START)
1650 {
1651 /*
1652 * If not read-only, be sure to advance the command counter for
1653 * each command, so that all work to date in this transaction is
1654 * visible. Take a new snapshot if we don't have one yet,
1655 * otherwise just bump the command ID in the existing snapshot.
1656 */
1657 if (!fcache->func->readonly_func)
1658 {
1660 if (!pushed_snapshot)
1661 {
1663 pushed_snapshot = true;
1664 }
1665 else
1667 }
1668
1669 postquel_start(es, fcache);
1670 }
1671 else if (!fcache->func->readonly_func && !pushed_snapshot)
1672 {
1673 /* Re-establish active snapshot when re-entering function */
1675 pushed_snapshot = true;
1676 }
1677
1678 completed = postquel_getnext(es, fcache);
1679
1680 /*
1681 * If we ran the command to completion, we can shut it down now. Any
1682 * row(s) we need to return are safely stashed in the result slot or
1683 * tuplestore, and we want to be sure that, for example, AFTER
1684 * triggers get fired before we return anything. Also, if the
1685 * function doesn't return set, we can shut it down anyway because it
1686 * must be a SELECT and we don't care about fetching any more result
1687 * rows.
1688 */
1689 if (completed || !fcache->func->returnsSet)
1690 postquel_end(es, fcache);
1691
1692 /*
1693 * Break from loop if we didn't shut down (implying we got a
1694 * lazily-evaluated row). Otherwise we'll press on till the whole
1695 * function is done, relying on the tuplestore to keep hold of the
1696 * data to eventually be returned. This is necessary since an
1697 * INSERT/UPDATE/DELETE RETURNING that sets the result might be
1698 * followed by additional rule-inserted commands, and we want to
1699 * finish doing all those commands before we return anything.
1700 */
1701 if (es->status != F_EXEC_DONE)
1702 break;
1703
1704 /*
1705 * Advance to next execution_state, and perhaps next query.
1706 */
1707 es = es->next;
1708 while (!es)
1709 {
1710 /*
1711 * Flush the current snapshot so that we will take a new one for
1712 * the new query list. This ensures that new snaps are taken at
1713 * original-query boundaries, matching the behavior of interactive
1714 * execution.
1715 */
1716 if (pushed_snapshot)
1717 {
1719 pushed_snapshot = false;
1720 }
1721
1722 if (!init_execution_state(fcache))
1723 break; /* end of function */
1724
1725 es = fcache->eslist;
1726 }
1727 }
1728
1729 /*
1730 * The result slot or tuplestore now contains whatever row(s) we are
1731 * supposed to return.
1732 */
1733 if (fcache->func->returnsSet)
1734 {
1735 ReturnSetInfo *rsi = (ReturnSetInfo *) fcinfo->resultinfo;
1736
1737 if (es)
1738 {
1739 /*
1740 * If we stopped short of being done, we must have a lazy-eval
1741 * row.
1742 */
1743 Assert(es->lazyEval);
1744 /* The junkfilter's result slot contains the query result tuple */
1745 Assert(fcache->junkFilter);
1746 slot = fcache->junkFilter->jf_resultSlot;
1747 Assert(!TTS_EMPTY(slot));
1748 /* Extract the result as a datum, and copy out from the slot */
1749 result = postquel_get_single_result(slot, fcinfo, fcache);
1750
1751 /*
1752 * Let caller know we're not finished.
1753 */
1755
1756 /*
1757 * Ensure we will get shut down cleanly if the exprcontext is not
1758 * run to completion.
1759 */
1760 if (!fcache->shutdown_reg)
1761 {
1764 PointerGetDatum(fcache));
1765 fcache->shutdown_reg = true;
1766 }
1767 }
1768 else if (fcache->lazyEval)
1769 {
1770 /*
1771 * We are done with a lazy evaluation. Let caller know we're
1772 * finished.
1773 */
1774 rsi->isDone = ExprEndResult;
1775
1776 fcinfo->isnull = true;
1777 result = (Datum) 0;
1778
1779 /* Deregister shutdown callback, if we made one */
1780 if (fcache->shutdown_reg)
1781 {
1784 PointerGetDatum(fcache));
1785 fcache->shutdown_reg = false;
1786 }
1787 }
1788 else
1789 {
1790 /*
1791 * We are done with a non-lazy evaluation. Return whatever is in
1792 * the tuplestore. (It is now caller's responsibility to free the
1793 * tuplestore when done.)
1794 *
1795 * Note an edge case: we could get here without having made a
1796 * tuplestore if the function is declared to return SETOF VOID.
1797 * ExecMakeTableFunctionResult will cope with null setResult.
1798 */
1799 Assert(fcache->tstore || fcache->func->rettype == VOIDOID);
1801 rsi->setResult = fcache->tstore;
1802 fcache->tstore = NULL;
1803 /* must copy desc because execSRF.c will free it */
1804 if (fcache->junkFilter)
1806
1807 fcinfo->isnull = true;
1808 result = (Datum) 0;
1809
1810 /* Deregister shutdown callback, if we made one */
1811 if (fcache->shutdown_reg)
1812 {
1815 PointerGetDatum(fcache));
1816 fcache->shutdown_reg = false;
1817 }
1818 }
1819 }
1820 else
1821 {
1822 /*
1823 * Non-set function. If we got a row, return it; else return NULL.
1824 */
1825 if (fcache->junkFilter)
1826 {
1827 /* The junkfilter's result slot contains the query result tuple */
1828 slot = fcache->junkFilter->jf_resultSlot;
1829 if (!TTS_EMPTY(slot))
1830 result = postquel_get_single_result(slot, fcinfo, fcache);
1831 else
1832 {
1833 fcinfo->isnull = true;
1834 result = (Datum) 0;
1835 }
1836 }
1837 else
1838 {
1839 /* Should only get here for VOID functions and procedures */
1840 Assert(fcache->func->rettype == VOIDOID);
1841 fcinfo->isnull = true;
1842 result = (Datum) 0;
1843 }
1844 }
1845
1846 /* Pop snapshot if we have pushed one */
1847 if (pushed_snapshot)
1849
1850 /*
1851 * If we've gone through every command in the function, we are done. Reset
1852 * state to start over again on next call.
1853 */
1854 if (es == NULL)
1855 fcache->eslist = NULL;
1856
1857 error_context_stack = sqlerrcontext.previous;
1858
1859 return result;
1860}
ErrorContextCallback * error_context_stack
Definition: elog.c:95
int errcode(int sqlerrcode)
Definition: elog.c:854
int errmsg(const char *fmt,...)
Definition: elog.c:1071
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
void UnregisterExprContextCallback(ExprContext *econtext, ExprContextCallbackFunction function, Datum arg)
Definition: execUtils.c:990
void RegisterExprContextCallback(ExprContext *econtext, ExprContextCallbackFunction function, Datum arg)
Definition: execUtils.c:964
@ ExprMultipleResult
Definition: execnodes.h:323
@ ExprEndResult
Definition: execnodes.h:324
@ SFRM_Materialize_Preferred
Definition: execnodes.h:338
@ SFRM_ValuePerCall
Definition: execnodes.h:335
@ SFRM_Materialize_Random
Definition: execnodes.h:337
@ SFRM_Materialize
Definition: execnodes.h:336
static Datum postquel_get_single_result(TupleTableSlot *slot, FunctionCallInfo fcinfo, SQLFunctionCachePtr fcache)
Definition: functions.c:1514
static bool postquel_getnext(execution_state *es, SQLFunctionCachePtr fcache)
Definition: functions.c:1378
static void postquel_start(execution_state *es, SQLFunctionCachePtr fcache)
Definition: functions.c:1252
static bool init_execution_state(SQLFunctionCachePtr fcache)
Definition: functions.c:629
static void postquel_end(execution_state *es, SQLFunctionCachePtr fcache)
Definition: functions.c:1419
static void sql_exec_error_callback(void *arg)
Definition: functions.c:1901
static void ShutdownSQLFunction(Datum arg)
Definition: functions.c:1939
@ F_EXEC_START
Definition: functions.c:64
@ F_EXEC_DONE
Definition: functions.c:64
static SQLFunctionCache * init_sql_fcache(FunctionCallInfo fcinfo, bool lazyEvalOK)
Definition: functions.c:534
Assert(PointerIsAligned(start, uint64))
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:81
#define IsA(nodeptr, _type_)
Definition: nodes.h:164
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:327
uintptr_t Datum
Definition: postgres.h:69
Snapshot GetTransactionSnapshot(void)
Definition: snapmgr.c:271
void PushActiveSnapshot(Snapshot snapshot)
Definition: snapmgr.c:669
void UpdateActiveSnapshotCommandId(void)
Definition: snapmgr.c:731
void PopActiveSnapshot(void)
Definition: snapmgr.c:762
struct ErrorContextCallback * previous
Definition: elog.h:296
void(* callback)(void *arg)
Definition: elog.h:297
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:275
TupleDesc jf_cleanTupType
Definition: execnodes.h:414
TupleTableSlot * jf_resultSlot
Definition: execnodes.h:416
Snapshot snapshot
Definition: execdesc.h:40
SetFunctionReturnMode returnMode
Definition: execnodes.h:355
ExprContext * econtext
Definition: execnodes.h:351
TupleDesc setDesc
Definition: execnodes.h:359
Tuplestorestate * setResult
Definition: execnodes.h:358
int allowedModes
Definition: execnodes.h:353
ExprDoneCond isDone
Definition: execnodes.h:356
execution_state * eslist
Definition: functions.c:173
SQLFunctionHashEntry * func
Definition: functions.c:143
JunkFilter * junkFilter
Definition: functions.c:156
Tuplestorestate * tstore
Definition: functions.c:153
MemoryContext tscontext
Definition: functions.c:154
ExecStatus status
Definition: functions.c:70
struct execution_state * next
Definition: functions.c:69
QueryDesc * qd
Definition: functions.c:74
TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)
Definition: tupdesc.c:245
#define TTS_EMPTY(slot)
Definition: tuptable.h:96
void CommandCounterIncrement(void)
Definition: xact.c:1100

References ReturnSetInfo::allowedModes, ErrorContextCallback::arg, Assert(), ErrorContextCallback::callback, CommandCounterIncrement(), CreateTupleDescCopy(), ReturnSetInfo::econtext, ExprContext::ecxt_per_query_memory, ereport, errcode(), errmsg(), ERROR, error_context_stack, SQLFunctionCache::eslist, ExprEndResult, ExprMultipleResult, F_EXEC_DONE, F_EXEC_START, SQLFunctionCache::func, GetTransactionSnapshot(), if(), init_execution_state(), init_sql_fcache(), IsA, ReturnSetInfo::isDone, JunkFilter::jf_cleanTupType, JunkFilter::jf_resultSlot, SQLFunctionCache::junkFilter, execution_state::lazyEval, SQLFunctionCache::lazyEval, execution_state::next, PointerGetDatum(), PopActiveSnapshot(), postquel_end(), postquel_get_single_result(), postquel_getnext(), postquel_start(), ErrorContextCallback::previous, PushActiveSnapshot(), execution_state::qd, SQLFunctionCache::randomAccess, SQLFunctionHashEntry::readonly_func, RegisterExprContextCallback(), SQLFunctionHashEntry::rettype, ReturnSetInfo::returnMode, SQLFunctionHashEntry::returnsSet, ReturnSetInfo::setDesc, ReturnSetInfo::setResult, SFRM_Materialize, SFRM_Materialize_Preferred, SFRM_Materialize_Random, SFRM_ValuePerCall, SQLFunctionCache::shutdown_reg, ShutdownSQLFunction(), QueryDesc::snapshot, sql_exec_error_callback(), execution_state::status, SQLFunctionCache::tscontext, SQLFunctionCache::tstore, TTS_EMPTY, UnregisterExprContextCallback(), and UpdateActiveSnapshotCommandId().

Referenced by fmgr_info_cxt_security().

◆ prepare_sql_fn_parse_info()

SQLFunctionParseInfoPtr prepare_sql_fn_parse_info ( HeapTuple  procedureTuple,
Node call_expr,
Oid  inputCollation 
)

Definition at line 249 of file functions.c.

252{
254 Form_pg_proc procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple);
255 int nargs;
256
258
259 /* Function's name (only) can be used to qualify argument names */
260 pinfo->fname = pstrdup(NameStr(procedureStruct->proname));
261
262 /* Save the function's input collation */
263 pinfo->collation = inputCollation;
264
265 /*
266 * Copy input argument types from the pg_proc entry, then resolve any
267 * polymorphic types.
268 */
269 pinfo->nargs = nargs = procedureStruct->pronargs;
270 if (nargs > 0)
271 {
272 Oid *argOidVect;
273 int argnum;
274
275 argOidVect = (Oid *) palloc(nargs * sizeof(Oid));
276 memcpy(argOidVect,
277 procedureStruct->proargtypes.values,
278 nargs * sizeof(Oid));
279
280 for (argnum = 0; argnum < nargs; argnum++)
281 {
282 Oid argtype = argOidVect[argnum];
283
284 if (IsPolymorphicType(argtype))
285 {
286 argtype = get_call_expr_argtype(call_expr, argnum);
287 if (argtype == InvalidOid)
289 (errcode(ERRCODE_DATATYPE_MISMATCH),
290 errmsg("could not determine actual type of argument declared %s",
291 format_type_be(argOidVect[argnum]))));
292 argOidVect[argnum] = argtype;
293 }
294 }
295
296 pinfo->argtypes = argOidVect;
297 }
298
299 /*
300 * Collect names of arguments, too, if any
301 */
302 if (nargs > 0)
303 {
304 Datum proargnames;
305 Datum proargmodes;
306 int n_arg_names;
307 bool isNull;
308
309 proargnames = SysCacheGetAttr(PROCNAMEARGSNSP, procedureTuple,
310 Anum_pg_proc_proargnames,
311 &isNull);
312 if (isNull)
313 proargnames = PointerGetDatum(NULL); /* just to be sure */
314
315 proargmodes = SysCacheGetAttr(PROCNAMEARGSNSP, procedureTuple,
316 Anum_pg_proc_proargmodes,
317 &isNull);
318 if (isNull)
319 proargmodes = PointerGetDatum(NULL); /* just to be sure */
320
321 n_arg_names = get_func_input_arg_names(proargnames, proargmodes,
322 &pinfo->argnames);
323
324 /* Paranoia: ignore the result if too few array entries */
325 if (n_arg_names < nargs)
326 pinfo->argnames = NULL;
327 }
328 else
329 pinfo->argnames = NULL;
330
331 return pinfo;
332}
#define NameStr(name)
Definition: c.h:717
Oid get_call_expr_argtype(Node *expr, int argnum)
Definition: fmgr.c:1929
char * format_type_be(Oid type_oid)
Definition: format_type.c:343
int get_func_input_arg_names(Datum proargnames, Datum proargmodes, char ***arg_names)
Definition: funcapi.c:1522
SQLFunctionParseInfo * SQLFunctionParseInfoPtr
Definition: functions.h:35
static void * GETSTRUCT(const HeapTupleData *tuple)
Definition: htup_details.h:728
char * pstrdup(const char *in)
Definition: mcxt.c:2327
void * palloc(Size size)
Definition: mcxt.c:1945
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:136
#define InvalidOid
Definition: postgres_ext.h:35
unsigned int Oid
Definition: postgres_ext.h:30
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:600

References SQLFunctionParseInfo::argnames, SQLFunctionParseInfo::argtypes, SQLFunctionParseInfo::collation, ereport, errcode(), errmsg(), ERROR, SQLFunctionParseInfo::fname, format_type_be(), get_call_expr_argtype(), get_func_input_arg_names(), GETSTRUCT(), InvalidOid, NameStr, SQLFunctionParseInfo::nargs, palloc(), palloc0(), PointerGetDatum(), pstrdup(), and SysCacheGetAttr().

Referenced by fmgr_sql_validator(), inline_function(), inline_set_returning_function(), and sql_compile_callback().

◆ sql_fn_parser_setup()

void sql_fn_parser_setup ( struct ParseState pstate,
SQLFunctionParseInfoPtr  pinfo 
)

Definition at line 338 of file functions.c.

339{
340 pstate->p_pre_columnref_hook = NULL;
343 /* no need to use p_coerce_param_hook */
344 pstate->p_ref_hook_state = pinfo;
345}
static Node * sql_fn_param_ref(ParseState *pstate, ParamRef *pref)
Definition: functions.c:467
static Node * sql_fn_post_column_ref(ParseState *pstate, ColumnRef *cref, Node *var)
Definition: functions.c:351
void * p_ref_hook_state
Definition: parse_node.h:258
ParseParamRefHook p_paramref_hook
Definition: parse_node.h:256
PreParseColumnRefHook p_pre_columnref_hook
Definition: parse_node.h:254
PostParseColumnRefHook p_post_columnref_hook
Definition: parse_node.h:255

References ParseState::p_paramref_hook, ParseState::p_post_columnref_hook, ParseState::p_pre_columnref_hook, ParseState::p_ref_hook_state, sql_fn_param_ref(), and sql_fn_post_column_ref().

Referenced by fmgr_sql_validator(), inline_function(), inline_set_returning_function(), interpret_AS_clause(), and prepare_next_query().