Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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 2087 of file functions.c.

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

2007{
2008 ListCell *lc;
2009
2010 /* We are given a list of sublists of Queries */
2011 foreach(lc, queryTreeLists)
2012 {
2013 List *sublist = lfirst_node(List, lc);
2014
2015 check_sql_fn_statement(sublist);
2016 }
2017}
static void check_sql_fn_statement(List *queryTreeList)
Definition: functions.c:2023
#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 2588 of file functions.c.

2589{
2591
2596 self->pub.mydest = DestSQLFunction;
2597
2598 /* private fields will be set by postquel_start */
2599
2600 return (DestReceiver *) self;
2601}
@ DestSQLFunction
Definition: dest.h:96
static void sqlfunction_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
Definition: functions.c:2607
static bool sqlfunction_receive(TupleTableSlot *slot, DestReceiver *self)
Definition: functions.c:2616
static void sqlfunction_destroy(DestReceiver *self)
Definition: functions.c:2663
static void sqlfunction_shutdown(DestReceiver *self)
Definition: functions.c:2654
void * palloc0(Size size)
Definition: mcxt.c:1351
DestReceiver pub
Definition: functions.c:47
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 1553 of file functions.c.

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

253{
255 Form_pg_proc procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple);
256 int nargs;
257
259
260 /* Function's name (only) can be used to qualify argument names */
261 pinfo->fname = pstrdup(NameStr(procedureStruct->proname));
262
263 /* Save the function's input collation */
264 pinfo->collation = inputCollation;
265
266 /*
267 * Copy input argument types from the pg_proc entry, then resolve any
268 * polymorphic types.
269 */
270 pinfo->nargs = nargs = procedureStruct->pronargs;
271 if (nargs > 0)
272 {
273 Oid *argOidVect;
274 int argnum;
275
276 argOidVect = (Oid *) palloc(nargs * sizeof(Oid));
277 memcpy(argOidVect,
278 procedureStruct->proargtypes.values,
279 nargs * sizeof(Oid));
280
281 for (argnum = 0; argnum < nargs; argnum++)
282 {
283 Oid argtype = argOidVect[argnum];
284
285 if (IsPolymorphicType(argtype))
286 {
287 argtype = get_call_expr_argtype(call_expr, argnum);
288 if (argtype == InvalidOid)
290 (errcode(ERRCODE_DATATYPE_MISMATCH),
291 errmsg("could not determine actual type of argument declared %s",
292 format_type_be(argOidVect[argnum]))));
293 argOidVect[argnum] = argtype;
294 }
295 }
296
297 pinfo->argtypes = argOidVect;
298 }
299
300 /*
301 * Collect names of arguments, too, if any
302 */
303 if (nargs > 0)
304 {
305 Datum proargnames;
306 Datum proargmodes;
307 int n_arg_names;
308 bool isNull;
309
310 proargnames = SysCacheGetAttr(PROCNAMEARGSNSP, procedureTuple,
311 Anum_pg_proc_proargnames,
312 &isNull);
313 if (isNull)
314 proargnames = PointerGetDatum(NULL); /* just to be sure */
315
316 proargmodes = SysCacheGetAttr(PROCNAMEARGSNSP, procedureTuple,
317 Anum_pg_proc_proargmodes,
318 &isNull);
319 if (isNull)
320 proargmodes = PointerGetDatum(NULL); /* just to be sure */
321
322 n_arg_names = get_func_input_arg_names(proargnames, proargmodes,
323 &pinfo->argnames);
324
325 /* Paranoia: ignore the result if too few array entries */
326 if (n_arg_names < nargs)
327 pinfo->argnames = NULL;
328 }
329 else
330 pinfo->argnames = NULL;
331
332 return pinfo;
333}
#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:1703
void * palloc(Size size)
Definition: mcxt.c:1321
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 339 of file functions.c.

340{
341 pstate->p_pre_columnref_hook = NULL;
344 /* no need to use p_coerce_param_hook */
345 pstate->p_ref_hook_state = pinfo;
346}
static Node * sql_fn_param_ref(ParseState *pstate, ParamRef *pref)
Definition: functions.c:468
static Node * sql_fn_post_column_ref(ParseState *pstate, ColumnRef *cref, Node *var)
Definition: functions.c:352
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().