PostgreSQL Source Code: src/backend/executor/functions.c File Reference (original) (raw)
Go to the source code of this file.
Data Structures | |
---|---|
struct | DR_sqlfunction |
struct | execution_state |
struct | SQLFunctionHashEntry |
struct | SQLFunctionCache |
Typedefs | |
---|---|
typedef struct execution_state | execution_state |
typedef struct SQLFunctionHashEntry | SQLFunctionHashEntry |
typedef struct SQLFunctionCache | SQLFunctionCache |
typedef SQLFunctionCache * | SQLFunctionCachePtr |
◆ execution_state
◆ SQLFunctionCache
◆ SQLFunctionCachePtr
◆ SQLFunctionHashEntry
◆ ExecStatus
Enumerator |
---|
F_EXEC_START |
F_EXEC_RUN |
F_EXEC_DONE |
Definition at line 62 of file functions.c.
◆ 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
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107 if (queryTreeLists != NIL)
2109 else
2110 queryTreeList = NIL;
2111
2113 rettype, rettupdesc,
2114 prokind, insertDroppedCols);
2115}
static bool check_sql_stmt_retval(List *queryTreeList, Oid rettype, TupleDesc rettupdesc, char prokind, bool insertDroppedCols)
#define llast_node(type, l)
References check_sql_stmt_retval(), llast_node, and NIL.
Referenced by fmgr_sql_validator(), inline_function(), and inline_set_returning_function().
◆ check_sql_fn_statement()
static void check_sql_fn_statement ( List * queryTreeList) | static |
---|
Definition at line 2024 of file functions.c.
2025{
2027
2028 foreach(lc, queryTreeList)
2029 {
2031
2032
2033
2034
2035
2036
2037
2038
2041 {
2043
2046 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2047 errmsg("calling procedures with output arguments is not supported in SQL functions")));
2048 }
2049 }
2050}
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
if(TABLE==NULL||TABLE_index==NULL)
#define IsA(nodeptr, _type_)
#define lfirst_node(type, lc)
References CMD_UTILITY, Query::commandType, ereport, errcode(), errmsg(), ERROR, if(), IsA, lfirst_node, NIL, stmt, and Query::utilityStmt.
Referenced by check_sql_fn_statements(), prepare_next_query(), and sql_postrewrite_callback().
◆ check_sql_fn_statements()
void check_sql_fn_statements | ( | List * | queryTreeLists | ) |
---|
◆ check_sql_stmt_retval()
static bool check_sql_stmt_retval ( List * queryTreeList, Oid rettype, TupleDesc rettupdesc, char prokind, bool insertDroppedCols ) | static |
---|
Definition at line 2122 of file functions.c.
2125{
2126 bool is_tuple_result = false;
2129 List *tlist;
2130 int tlistlen;
2131 bool tlist_is_modifiable;
2132 char fn_typtype;
2134 bool upper_tlist_nontrivial = false;
2136
2137
2138
2139
2140
2141 if (rettype == VOIDOID)
2142 return false;
2143
2144
2145
2146
2147
2148
2150 parse_cell = NULL;
2151 foreach(lc, queryTreeList)
2152 {
2154
2155 if (q->canSetTag)
2156 {
2158 parse_cell = lc;
2159 }
2160 }
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2175 {
2176 tlist = parse->targetList;
2177
2178 tlist_is_modifiable = (parse->setOperations == NULL);
2179 }
2180 else if (parse &&
2185 parse->returningList)
2186 {
2187 tlist = parse->returningList;
2188
2189 tlist_is_modifiable = true;
2190 }
2191 else
2192 {
2193
2195 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
2196 errmsg("return type mismatch in function declared to return %s",
2198 errdetail("Function's final statement must be SELECT or INSERT/UPDATE/DELETE/MERGE RETURNING.")));
2199 return false;
2200 }
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2216
2218
2219 if (fn_typtype == TYPTYPE_BASE ||
2220 fn_typtype == TYPTYPE_DOMAIN ||
2221 fn_typtype == TYPTYPE_ENUM ||
2222 fn_typtype == TYPTYPE_RANGE ||
2223 fn_typtype == TYPTYPE_MULTIRANGE)
2224 {
2225
2226
2227
2228
2230
2231 if (tlistlen != 1)
2233 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
2234 errmsg("return type mismatch in function declared to return %s",
2236 errdetail("Final statement must return exactly one column.")));
2237
2238
2240 Assert(!tle->resjunk);
2241
2243 tlist_is_modifiable,
2244 &upper_tlist,
2245 &upper_tlist_nontrivial))
2247 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
2248 errmsg("return type mismatch in function declared to return %s",
2250 errdetail("Actual return type is %s.",
2252 }
2253 else if (fn_typtype == TYPTYPE_COMPOSITE || rettype == RECORDOID)
2254 {
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266 int tupnatts;
2267 int tuplogcols;
2268 int colindex;
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291 if (tlistlen == 1 && prokind != PROKIND_PROCEDURE)
2292 {
2294
2295 Assert(!tle->resjunk);
2297 tlist_is_modifiable,
2298 &upper_tlist,
2299 &upper_tlist_nontrivial))
2300 {
2301
2302 goto tlist_coercion_finished;
2303 }
2304 }
2305
2306
2307
2308
2309
2310 if (rettupdesc == NULL)
2311 return true;
2312
2313
2314
2315
2316
2317
2318
2319 tupnatts = rettupdesc->natts;
2320 tuplogcols = 0;
2321 colindex = 0;
2322
2323 foreach(lc, tlist)
2324 {
2327
2328
2329 if (tle->resjunk)
2330 continue;
2331
2332 do
2333 {
2334 colindex++;
2335 if (colindex > tupnatts)
2337 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
2338 errmsg("return type mismatch in function declared to return %s",
2340 errdetail("Final statement returns too many columns.")));
2342 if (attr->attisdropped && insertDroppedCols)
2343 {
2344 Expr *null_expr;
2345
2346
2348 -1,
2352 true,
2353 true );
2354 upper_tlist = lappend(upper_tlist,
2357 NULL,
2358 false));
2359 upper_tlist_nontrivial = true;
2360 }
2361 } while (attr->attisdropped);
2362 tuplogcols++;
2363
2365 attr->atttypid, attr->atttypmod,
2366 tlist_is_modifiable,
2367 &upper_tlist,
2368 &upper_tlist_nontrivial))
2370 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
2371 errmsg("return type mismatch in function declared to return %s",
2373 errdetail("Final statement returns %s instead of %s at column %d.",
2376 tuplogcols)));
2377 }
2378
2379
2380 for (colindex++; colindex <= tupnatts; colindex++)
2381 {
2384 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
2385 errmsg("return type mismatch in function declared to return %s",
2387 errdetail("Final statement returns too few columns.")));
2388 if (insertDroppedCols)
2389 {
2390 Expr *null_expr;
2391
2392
2394 -1,
2398 true,
2399 true );
2400 upper_tlist = lappend(upper_tlist,
2403 NULL,
2404 false));
2405 upper_tlist_nontrivial = true;
2406 }
2407 }
2408
2409
2410 is_tuple_result = true;
2411 }
2412 else
2414 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
2415 errmsg("return type %s is not supported for SQL functions",
2417
2418tlist_coercion_finished:
2419
2420
2421
2422
2423
2424
2425
2426 if (upper_tlist_nontrivial)
2427 {
2428 Query *newquery;
2429 List *colnames;
2432
2434
2435
2438 newquery->querySource = parse->querySource;
2439 newquery->canSetTag = true;
2441
2442
2443 colnames = NIL;
2444 foreach(lc, parse->targetList)
2445 {
2447
2448 if (tle->resjunk)
2449 continue;
2450 colnames = lappend(colnames,
2451 makeString(tle->resname ? tle->resname : ""));
2452 }
2453
2454
2458 rte->eref = rte->alias = makeAlias("*SELECT*", colnames);
2459 rte->lateral = false;
2460 rte->inh = false;
2461 rte->inFromCl = true;
2463
2467
2468
2469
2470
2471
2472 newquery->hasRowSecurity = parse->hasRowSecurity;
2473
2474
2475 lfirst(parse_cell) = newquery;
2476 }
2477
2478 return is_tuple_result;
2479}
int errdetail(const char *fmt,...)
int ExecCleanTargetListLength(List *targetlist)
char * format_type_be(Oid type_oid)
static bool coerce_fn_result_column(TargetEntry *src_tle, Oid res_type, int32 res_typmod, bool tlist_is_modifiable, List **upper_tlist, bool *upper_tlist_nontrivial)
Assert(PointerIsAligned(start, uint64))
List * lappend(List *list, void *datum)
char get_typtype(Oid typid)
Alias * makeAlias(const char *aliasname, List *colnames)
FromExpr * makeFromExpr(List *fromlist, Node *quals)
TargetEntry * makeTargetEntry(Expr *expr, AttrNumber resno, char *resname, bool resjunk)
Const * makeConst(Oid consttype, int32 consttypmod, Oid constcollid, int constlen, Datum constvalue, bool constisnull, bool constbyval)
Oid exprType(const Node *expr)
FormData_pg_attribute * Form_pg_attribute
static int list_length(const List *l)
static struct subre * parse(struct vars *v, int stopper, int type, struct state *init, struct state *final)
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
static CompactAttribute * TupleDescCompactAttr(TupleDesc tupdesc, int i)
String * makeString(char *str)
References Assert(), CMD_DELETE, CMD_INSERT, CMD_MERGE, CMD_SELECT, CMD_UPDATE, coerce_fn_result_column(), Query::commandType, ereport, errcode(), errdetail(), errmsg(), ERROR, ExecCleanTargetListLength(), TargetEntry::expr, exprType(), format_type_be(), get_typtype(), RangeTblEntry::inh, InvalidOid, Query::jointree, lappend(), lfirst, lfirst_node, linitial, list_length(), list_make1, makeAlias(), makeConst(), makeFromExpr(), makeNode, makeString(), makeTargetEntry(), TupleDescData::natts, NIL, parse(), Query::rtable, RTE_SUBQUERY, RangeTblEntry::rtekind, RangeTblRef::rtindex, RangeTblEntry::subquery, Query::targetList, TupleDescAttr(), and TupleDescCompactAttr().
Referenced by check_sql_fn_retval(), prepare_next_query(), and sql_postrewrite_callback().
◆ coerce_fn_result_column()
static bool coerce_fn_result_column ( TargetEntry * src_tle, Oid res_type, int32 res_typmod, bool tlist_is_modifiable, List ** upper_tlist, bool * upper_tlist_nontrivial ) | static |
---|
Definition at line 2492 of file functions.c.
2498{
2500 Expr *new_tle_expr;
2501 Node *cast_result;
2502
2503
2504
2505
2506
2507
2508
2509 if (tlist_is_modifiable && src_tle->ressortgroupref == 0)
2510 {
2511
2515 res_type, res_typmod,
2518 -1);
2519 if (cast_result == NULL)
2520 return false;
2522 src_tle->expr = (Expr *) cast_result;
2523
2525 }
2526 else
2527 {
2528
2530
2532 (Node *) var,
2533 var->vartype,
2534 res_type, res_typmod,
2537 -1);
2538 if (cast_result == NULL)
2539 return false;
2541
2542 if (cast_result != (Node *) var)
2543 *upper_tlist_nontrivial = true;
2544 new_tle_expr = (Expr *) cast_result;
2545 }
2548 src_tle->resname, false);
2549 *upper_tlist = lappend(*upper_tlist, new_tle);
2550 return true;
2551}
Var * makeVarFromTargetEntry(int varno, TargetEntry *tle)
Node * coerce_to_target_type(ParseState *pstate, Node *expr, Oid exprtype, Oid targettype, int32 targettypmod, CoercionContext ccontext, CoercionForm cformat, int location)
void assign_expr_collations(ParseState *pstate, Node *expr)
References assign_expr_collations(), COERCE_IMPLICIT_CAST, coerce_to_target_type(), COERCION_ASSIGNMENT, TargetEntry::expr, exprType(), lappend(), list_length(), makeTargetEntry(), makeVarFromTargetEntry(), and TargetEntry::ressortgroupref.
Referenced by check_sql_stmt_retval().
◆ CreateSQLFunctionDestReceiver()
Definition at line 2589 of file functions.c.
2590{
2592
2598
2599
2600
2602}
static void sqlfunction_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
static bool sqlfunction_receive(TupleTableSlot *slot, DestReceiver *self)
static void sqlfunction_destroy(DestReceiver *self)
static void sqlfunction_shutdown(DestReceiver *self)
void * palloc0(Size size)
void(* rStartup)(DestReceiver *self, int operation, TupleDesc typeinfo)
void(* rShutdown)(DestReceiver *self)
bool(* receiveSlot)(TupleTableSlot *slot, DestReceiver *self)
void(* rDestroy)(DestReceiver *self)
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()
Definition at line 1554 of file functions.c.
1555{
1559 bool randomAccess;
1560 bool lazyEvalOK;
1561 bool pushed_snapshot;
1565
1566
1567 if (fcinfo->flinfo->fn_retset)
1568 {
1570
1571
1572
1573
1574
1575
1576
1581 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1582 errmsg("set-valued function called in context that cannot accept a set")));
1585
1587 }
1588 else
1589 {
1590 randomAccess = false;
1591 lazyEvalOK = true;
1592
1593 tscontext = NULL;
1594 }
1595
1596
1597
1598
1600
1601
1604
1605
1606
1607
1609 sqlerrcontext.arg = fcache;
1612
1613
1614
1615
1616
1617 do
1618 {
1619 es = fcache->eslist;
1621 es = es->next;
1622 if (es)
1623 break;
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644 pushed_snapshot = false;
1645 while (es)
1646 {
1647 bool completed;
1648
1650 {
1651
1652
1653
1654
1655
1656
1658 {
1660 if (!pushed_snapshot)
1661 {
1663 pushed_snapshot = true;
1664 }
1665 else
1667 }
1668
1670 }
1672 {
1673
1675 pushed_snapshot = true;
1676 }
1677
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1702 break;
1703
1704
1705
1706
1707 es = es->next;
1708 while (!es)
1709 {
1710
1711
1712
1713
1714
1715
1716 if (pushed_snapshot)
1717 {
1719 pushed_snapshot = false;
1720 }
1721
1723 break;
1724
1725 es = fcache->eslist;
1726 }
1727 }
1728
1729
1730
1731
1732
1734 {
1736
1737 if (es)
1738 {
1739
1740
1741
1742
1744
1748
1750
1751
1752
1753
1755
1756
1757
1758
1759
1761 {
1766 }
1767 }
1769 {
1770
1771
1772
1773
1775
1776 fcinfo->isnull = true;
1777 result = (Datum) 0;
1778
1779
1781 {
1786 }
1787 }
1788 else
1789 {
1790
1791
1792
1793
1794
1795
1796
1797
1798
1802 fcache->tstore = NULL;
1803
1806
1807 fcinfo->isnull = true;
1808 result = (Datum) 0;
1809
1810
1812 {
1817 }
1818 }
1819 }
1820 else
1821 {
1822
1823
1824
1826 {
1827
1831 else
1832 {
1833 fcinfo->isnull = true;
1834 result = (Datum) 0;
1835 }
1836 }
1837 else
1838 {
1839
1841 fcinfo->isnull = true;
1842 result = (Datum) 0;
1843 }
1844 }
1845
1846
1847 if (pushed_snapshot)
1849
1850
1851
1852
1853
1854 if (es == NULL)
1855 fcache->eslist = NULL;
1856
1858
1859 return result;
1860}
ErrorContextCallback * error_context_stack
void UnregisterExprContextCallback(ExprContext *econtext, ExprContextCallbackFunction function, Datum arg)
void RegisterExprContextCallback(ExprContext *econtext, ExprContextCallbackFunction function, Datum arg)
@ SFRM_Materialize_Preferred
@ SFRM_Materialize_Random
static Datum postquel_get_single_result(TupleTableSlot *slot, FunctionCallInfo fcinfo, SQLFunctionCachePtr fcache)
static bool postquel_getnext(execution_state *es, SQLFunctionCachePtr fcache)
static void postquel_start(execution_state *es, SQLFunctionCachePtr fcache)
static bool init_execution_state(SQLFunctionCachePtr fcache)
static void postquel_end(execution_state *es, SQLFunctionCachePtr fcache)
static void sql_exec_error_callback(void *arg)
static void ShutdownSQLFunction(Datum arg)
static SQLFunctionCache * init_sql_fcache(FunctionCallInfo fcinfo, bool lazyEvalOK)
static Datum PointerGetDatum(const void *X)
Snapshot GetTransactionSnapshot(void)
void PushActiveSnapshot(Snapshot snapshot)
void UpdateActiveSnapshotCommandId(void)
void PopActiveSnapshot(void)
struct ErrorContextCallback * previous
void(* callback)(void *arg)
MemoryContext ecxt_per_query_memory
TupleDesc jf_cleanTupType
TupleTableSlot * jf_resultSlot
SetFunctionReturnMode returnMode
Tuplestorestate * setResult
SQLFunctionHashEntry * func
struct execution_state * next
TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)
void CommandCounterIncrement(void)
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().
◆ get_sql_fn_result_tlist()
static List * get_sql_fn_result_tlist ( List * queryTreeList) | static |
---|
◆ init_execution_state()
Definition at line 629 of file functions.c.
630{
634 int nstmts;
636
637
638
639
640 if (fcache->cplan)
641 {
643 fcache->cplan = NULL;
644 }
645 fcache->eslist = NULL;
646
647
648
649
650
651
652
654 {
656 return false;
659 }
660 else
662
666
667
668
669
670
671
672
677 NULL);
678
679
680
681
684 {
685 if (fcache->esarray == NULL)
689 else
693 }
694
695
696
697
699 {
702
703
704
705
706
708 {
710 ((CopyStmt *) stmt->utilityStmt)->filename == NULL)
712 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
713 errmsg("cannot COPY to/from client in an SQL function")));
714
717 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
718
719 errmsg("%s is not allowed in an SQL function",
721 }
722
725 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
726
727 errmsg("%s is not allowed in a non-volatile function",
729
730
732 if (preves)
733 preves->next = newes;
734 else
735 fcache->eslist = newes;
736
737 newes->next = NULL;
739 newes->setsResult = false;
740 newes->lazyEval = false;
742 newes->qd = NULL;
743
744 if (stmt->canSetTag)
745 lasttages = newes;
746
747 preves = newes;
748 }
749
750
751
752
753
755 return true;
756
757
758
759
760
761
762
763
764
765
766
767
768
769
773 {
775 List *resulttlist;
777
778
781 "SQL function junkfilter",
783 else
786
788
789
790
791
792
793
795
796
797
798
799
800
801
802
803
807 slot);
808 else
810
811
812
813
814
815
816
817
818
819
821
822
825
826
828
830 }
831
835 {
836
837
838
839
840
842 }
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
859 {
865 }
866
867 return true;
868}
JunkFilter * ExecInitJunkFilterConversion(List *targetList, TupleDesc cleanTupType, TupleTableSlot *slot)
JunkFilter * ExecInitJunkFilter(List *targetList, TupleTableSlot *slot)
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
TupleTableSlot * MakeSingleTupleTableSlot(TupleDesc tupdesc, const TupleTableSlotOps *tts_ops)
const TupleTableSlotOps TTSOpsMinimalTuple
#define repalloc_array(pointer, type, count)
static void prepare_next_query(SQLFunctionHashEntry *func)
static List * get_sql_fn_result_tlist(List *queryTreeList)
bool type_is_rowtype(Oid typid)
void * MemoryContextAlloc(MemoryContext context, Size size)
void MemoryContextReset(MemoryContext context)
#define AllocSetContextCreate
#define ALLOCSET_SMALL_SIZES
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
#define foreach_current_index(var_or_cell)
static void * list_nth(const List *list, int n)
CachedPlan * GetCachedPlan(CachedPlanSource *plansource, ParamListInfo boundParams, ResourceOwner owner, QueryEnvironment *queryEnv)
void ReleaseCachedPlan(CachedPlan *plan, ResourceOwner owner)
ResourceOwner CurrentResourceOwner
execution_state * esarray
TupleDesc tts_tupleDescriptor
bool CommandIsReadOnly(PlannedStmt *pstmt)
static const char * CreateCommandName(Node *parsetree)
References ALLOCSET_SMALL_SIZES, AllocSetContextCreate, BlessTupleDesc(), CMD_SELECT, CMD_UTILITY, CommandIsReadOnly(), PlannedStmt::commandType, SQLFunctionCache::cowner, SQLFunctionCache::cplan, CreateCommandName(), CurrentResourceOwner, ereport, errcode(), errmsg(), ERROR, SQLFunctionCache::error_query_index, SQLFunctionCache::esarray, SQLFunctionCache::esarray_len, SQLFunctionCache::eslist, ExecInitJunkFilter(), ExecInitJunkFilterConversion(), F_EXEC_START, SQLFunctionCache::fcontext, foreach_current_index, SQLFunctionCache::func, CachedPlan::generation, get_sql_fn_result_tlist(), GetCachedPlan(), PlannedStmt::hasModifyingCTE, IsA, SQLFunctionCache::jf_generation, JunkFilter::jf_resultSlot, JunkFilter::jf_targetList, SQLFunctionCache::jfcontext, SQLFunctionCache::junkFilter, execution_state::lazyEval, SQLFunctionCache::lazyEval, SQLFunctionCache::lazyEvalOK, lfirst_node, list_length(), list_nth(), MakeSingleTupleTableSlot(), MemoryContextAlloc(), MemoryContextReset(), MemoryContextSwitchTo(), execution_state::next, SQLFunctionCache::next_query_index, NIL, SQLFunctionHashEntry::num_queries, SQLFunctionCache::paramLI, SQLFunctionHashEntry::plansource_list, prepare_next_query(), execution_state::qd, CachedPlanSource::query_list, SQLFunctionHashEntry::readonly_func, ReleaseCachedPlan(), repalloc_array, SQLFunctionHashEntry::rettupdesc, SQLFunctionHashEntry::rettype, SQLFunctionHashEntry::returnsSet, SQLFunctionHashEntry::returnsTuple, execution_state::setsResult, execution_state::status, execution_state::stmt, stmt, CachedPlan::stmt_list, TupleTableSlot::tts_tupleDescriptor, TTSOpsMinimalTuple, and type_is_rowtype().
Referenced by fmgr_sql().
◆ init_sql_fcache()
Definition at line 534 of file functions.c.
535{
539
540
541
542
543
544
545
547 if (fcache == NULL)
548 {
556 }
557
558
559
560
561
562
563
564 if (fcache->eslist != NULL)
565 {
567 return fcache;
568 }
569
570
571
572
573
574
575
582 true,
583 false);
584
585
586
587
588
589
590
591 if (func != fcache->func)
592 {
593 if (fcache->func != NULL)
594 {
597 }
598 fcache->func = func;
600
602 }
603
604
605
606
607
609
610
613
614
615 fcache->eslist = NULL;
618
619 return fcache;
620}
CachedFunction * cached_function_compile(FunctionCallInfo fcinfo, CachedFunction *function, CachedFunctionCompileCallback ccallback, CachedFunctionDeleteCallback dcallback, Size cacheEntrySize, bool includeResultType, bool forValidator)
static void sql_delete_callback(CachedFunction *cfunc)
static void sql_compile_callback(FunctionCallInfo fcinfo, HeapTuple procedureTuple, const CachedFunctionHashKey *hashkey, CachedFunction *cfunc, bool forValidator)
static void postquel_sub_params(SQLFunctionCachePtr fcache, FunctionCallInfo fcinfo)
static void RemoveSQLFunctionCache(void *arg)
struct SQLFunctionHashEntry SQLFunctionHashEntry
void * MemoryContextAllocZero(MemoryContext context, Size size)
void MemoryContextRegisterResetCallback(MemoryContext context, MemoryContextCallback *cb)
MemoryContextCallbackFunction func
MemoryContextCallback mcb
References MemoryContextCallback::arg, Assert(), cached_function_compile(), SQLFunctionHashEntry::cfunc, SQLFunctionCache::error_query_index, SQLFunctionCache::eslist, SQLFunctionCache::fcontext, FunctionCallInfoBaseData::flinfo, FmgrInfo::fn_extra, FmgrInfo::fn_mcxt, SQLFunctionCache::func, MemoryContextCallback::func, SQLFunctionCache::junkFilter, SQLFunctionCache::lazyEval, SQLFunctionCache::lazyEvalOK, SQLFunctionCache::mcb, MemoryContextAllocZero(), MemoryContextRegisterResetCallback(), SQLFunctionCache::next_query_index, postquel_sub_params(), RemoveSQLFunctionCache(), sql_compile_callback(), sql_delete_callback(), and CachedFunction::use_count.
Referenced by fmgr_sql().
◆ postquel_end()
Definition at line 1419 of file functions.c.
1420{
1422
1423
1425
1426
1428
1429
1431 {
1434 }
1435
1437
1439 es->qd = NULL;
1440
1442
1443
1447}
void ExecutorEnd(QueryDesc *queryDesc)
void ExecutorFinish(QueryDesc *queryDesc)
void MemoryContextDelete(MemoryContext context)
void FreeQueryDesc(QueryDesc *qdesc)
References CMD_UTILITY, QueryDesc::dest, ExecutorEnd(), ExecutorFinish(), F_EXEC_DONE, FreeQueryDesc(), MemoryContextDelete(), MemoryContextSwitchTo(), QueryDesc::operation, SQLFunctionCache::ownSubcontext, execution_state::qd, _DestReceiver::rDestroy, execution_state::status, and SQLFunctionCache::subcontext.
Referenced by fmgr_sql(), and ShutdownSQLFunction().
◆ postquel_get_single_result()
Definition at line 1514 of file functions.c.
1517{
1519
1520
1521
1522
1523
1524
1525
1527 {
1528
1529 fcinfo->isnull = false;
1531 }
1532 else
1533 {
1534
1535
1536
1537
1539
1540 if (!fcinfo->isnull)
1542 }
1543
1544
1546
1548}
Datum datumCopy(Datum value, bool typByVal, int typLen)
Datum ExecFetchSlotHeapTupleDatum(TupleTableSlot *slot)
static Datum slot_getattr(TupleTableSlot *slot, int attnum, bool *isnull)
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
References datumCopy(), ExecClearTuple(), ExecFetchSlotHeapTupleDatum(), SQLFunctionCache::func, FunctionCallInfoBaseData::isnull, SQLFunctionHashEntry::returnsTuple, slot_getattr(), SQLFunctionHashEntry::typbyval, SQLFunctionHashEntry::typlen, and value.
Referenced by fmgr_sql().
◆ postquel_getnext()
Definition at line 1378 of file functions.c.
1379{
1380 bool result;
1382
1383
1385
1387 {
1390 true,
1395 NULL);
1396 result = true;
1397 }
1398 else
1399 {
1400
1402
1404
1405
1406
1407
1408
1410 }
1411
1413
1414 return result;
1415}
void ExecutorRun(QueryDesc *queryDesc, ScanDirection direction, uint64 count)
PlannedStmt * plannedstmt
QueryEnvironment * queryEnv
void ProcessUtility(PlannedStmt *pstmt, const char *queryString, bool readOnlyTree, ProcessUtilityContext context, ParamListInfo params, QueryEnvironment *queryEnv, DestReceiver *dest, QueryCompletion *qc)
References CMD_UTILITY, QueryDesc::dest, EState::es_processed, QueryDesc::estate, ExecutorRun(), ForwardScanDirection, SQLFunctionCache::func, execution_state::lazyEval, MemoryContextSwitchTo(), QueryDesc::operation, QueryDesc::params, QueryDesc::plannedstmt, PROCESS_UTILITY_QUERY, ProcessUtility(), execution_state::qd, QueryDesc::queryEnv, SQLFunctionHashEntry::src, and SQLFunctionCache::subcontext.
Referenced by fmgr_sql().
◆ postquel_start()
Definition at line 1252 of file functions.c.
1253{
1256
1258
1259
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1274 {
1276 "SQL function execution",
1279 }
1281 {
1282
1283
1284
1285
1286
1287
1288
1289
1291 "SQL function execution",
1294 }
1295 else
1296 {
1299 }
1300
1301
1302
1303
1304
1306 {
1309 {
1313 }
1314 }
1315
1316
1318
1319
1320
1321
1322
1324 {
1326
1328
1331 myState->tstore = fcache->tstore;
1333
1334
1336 }
1337 else
1339
1341 NULL,
1348 0);
1349
1350
1352 {
1353
1354
1355
1356
1357
1358
1359
1360 int eflags;
1361
1364 else
1365 eflags = 0;
1367 elog(ERROR, "ExecutorStart() failed unexpectedly");
1368 }
1369
1371
1373}
DestReceiver * CreateDestReceiver(CommandDest dest)
DestReceiver * None_Receiver
bool ExecutorStart(QueryDesc *queryDesc, int eflags)
#define EXEC_FLAG_SKIP_TRIGGERS
MemoryContext CurrentMemoryContext
#define ALLOCSET_DEFAULT_SIZES
QueryDesc * CreateQueryDesc(PlannedStmt *plannedstmt, CachedPlan *cplan, const char *sourceText, Snapshot snapshot, Snapshot crosscheck_snapshot, DestReceiver *dest, ParamListInfo params, QueryEnvironment *queryEnv, int instrument_options)
bool ActiveSnapshotSet(void)
Snapshot GetActiveSnapshot(void)
Tuplestorestate * tuplestore_begin_heap(bool randomAccess, bool interXact, int maxKBytes)
References ActiveSnapshotSet(), ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, Assert(), CMD_UTILITY, PlannedStmt::commandType, CreateDestReceiver(), CreateQueryDesc(), CurrentMemoryContext, generate_unaccent_rules::dest, DestSQLFunction, elog, ERROR, EXEC_FLAG_SKIP_TRIGGERS, ExecClearTuple(), ExecutorStart(), F_EXEC_RUN, SQLFunctionCache::fcontext, DR_sqlfunction::filter, SQLFunctionCache::func, GetActiveSnapshot(), InvalidSnapshot, JunkFilter::jf_resultSlot, SQLFunctionCache::junkFilter, execution_state::lazyEval, MemoryContextSwitchTo(), _DestReceiver::mydest, None_Receiver, QueryDesc::operation, SQLFunctionCache::ownSubcontext, SQLFunctionCache::paramLI, DR_sqlfunction::pub, execution_state::qd, QueryDesc::queryEnv, SQLFunctionCache::randomAccess, SQLFunctionHashEntry::returnsSet, execution_state::setsResult, SQLFunctionHashEntry::src, execution_state::status, execution_state::stmt, SQLFunctionCache::subcontext, SQLFunctionCache::tscontext, DR_sqlfunction::tstore, SQLFunctionCache::tstore, tuplestore_begin_heap(), and work_mem.
Referenced by fmgr_sql().
◆ postquel_sub_params()
Definition at line 1451 of file functions.c.
1453{
1454 int nargs = fcinfo->nargs;
1455
1456 if (nargs > 0)
1457 {
1461
1462 if (fcache->paramLI == NULL)
1463 {
1464
1466
1469 fcache->paramLI = paramLI;
1471 }
1472 else
1473 {
1474 paramLI = fcache->paramLI;
1476 }
1477
1478 for (int i = 0; i < nargs; i++)
1479 {
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1497 argtyplen[i]);
1498
1500 prm->ptype = argtypes[i];
1501 }
1502 }
1503 else
1505}
#define MakeExpandedObjectReadOnly(d, isnull, typlen)
ParamListInfo makeParamList(int numParams)
NullableDatum args[FLEXIBLE_ARRAY_MEMBER]
ParamExternData params[FLEXIBLE_ARRAY_MEMBER]
SQLFunctionParseInfoPtr pinfo
References FunctionCallInfoBaseData::args, SQLFunctionParseInfo::argtypes, SQLFunctionHashEntry::argtyplen, Assert(), SQLFunctionCache::fcontext, SQLFunctionCache::func, i, ParamExternData::isnull, NullableDatum::isnull, MakeExpandedObjectReadOnly, makeParamList(), MemoryContextSwitchTo(), FunctionCallInfoBaseData::nargs, ParamListInfoData::numParams, PARAM_FLAG_CONST, SQLFunctionCache::paramLI, ParamListInfoData::params, ParamExternData::pflags, SQLFunctionHashEntry::pinfo, ParamExternData::ptype, ParamExternData::value, and NullableDatum::value.
Referenced by init_sql_fcache().
◆ prepare_next_query()
Definition at line 876 of file functions.c.
877{
878 int qindex;
879 bool islast;
881 List *queryTree_list;
883
884
886 Assert(qindex < func->num_queries);
887 islast = (qindex + 1 >= func->num_queries);
888
889
890
891
892
893
894
895
896
897
899 {
900
902
905 func->src,
909 }
910 else
911 {
912
914
917 func->src,
920 func->src,
923 NULL);
924 }
925
926
927
928
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949 if (islast)
954 false);
955
956
957
958
959
961 queryTree_list,
962 NULL,
963 NULL,
964 0,
968 false);
969
970
971
972
973
976 islast ? func : NULL);
977
978
979
980
981
985
986
987
988
989
991
992
993
994
995
996
997 if (islast)
998 {
999 func->source_list = NIL;
1002 }
1003}
static void sql_postrewrite_callback(List *querytree_list, void *arg)
void sql_fn_parser_setup(struct ParseState *pstate, SQLFunctionParseInfoPtr pinfo)
void(* ParserSetupHook)(struct ParseState *pstate, void *arg)
#define CURSOR_OPT_PARALLEL_OK
#define CURSOR_OPT_NO_SCROLL
#define list_nth_node(type, list, n)
void SaveCachedPlan(CachedPlanSource *plansource)
void CompleteCachedPlan(CachedPlanSource *plansource, List *querytree_list, MemoryContext querytree_context, Oid *param_types, int num_params, ParserSetupHook parserSetup, void *parserSetupArg, int cursor_options, bool fixed_result)
CachedPlanSource * CreateCachedPlanForQuery(Query *analyzed_parse_tree, const char *query_string, CommandTag commandTag)
void SetPostRewriteHook(CachedPlanSource *plansource, PostRewriteHook postRewrite, void *postRewriteArg)
CachedPlanSource * CreateCachedPlan(RawStmt *raw_parse_tree, const char *query_string, CommandTag commandTag)
List * pg_analyze_and_rewrite_withcb(RawStmt *parsetree, const char *query_string, ParserSetupHook parserSetup, void *parserSetupArg, QueryEnvironment *queryEnv)
List * pg_rewrite_query(Query *query)
void AcquireRewriteLocks(Query *parsetree, bool forExecute, bool forUpdatePushedDown)
CommandTag CreateCommandTag(Node *parsetree)
References AcquireRewriteLocks(), Assert(), check_sql_fn_statement(), check_sql_stmt_retval(), CompleteCachedPlan(), copyObject, CreateCachedPlan(), CreateCachedPlanForQuery(), CreateCommandTag(), CURSOR_OPT_NO_SCROLL, CURSOR_OPT_PARALLEL_OK, SQLFunctionHashEntry::hcontext, lappend(), list_length(), list_nth_node, MemoryContextDelete(), MemoryContextSwitchTo(), NIL, SQLFunctionHashEntry::num_queries, SQLFunctionHashEntry::pcontext, pg_analyze_and_rewrite_withcb(), pg_rewrite_query(), SQLFunctionHashEntry::pinfo, SQLFunctionHashEntry::plansource_list, SQLFunctionHashEntry::prokind, SQLFunctionHashEntry::raw_source, SQLFunctionHashEntry::rettupdesc, SQLFunctionHashEntry::rettype, SQLFunctionHashEntry::returnsTuple, SaveCachedPlan(), SetPostRewriteHook(), SQLFunctionHashEntry::source_list, sql_fn_parser_setup(), sql_postrewrite_callback(), SQLFunctionHashEntry::src, and RawStmt::stmt.
Referenced by init_execution_state().
◆ prepare_sql_fn_parse_info()
Definition at line 249 of file functions.c.
252{
255 int nargs;
256
258
259
261
262
263 pinfo->collation = inputCollation;
264
265
266
267
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 {
289 (errcode(ERRCODE_DATATYPE_MISMATCH),
290 errmsg("could not determine actual type of argument declared %s",
292 argOidVect[argnum] = argtype;
293 }
294 }
295
296 pinfo->argtypes = argOidVect;
297 }
298
299
300
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);
314
315 proargmodes = SysCacheGetAttr(PROCNAMEARGSNSP, procedureTuple,
316 Anum_pg_proc_proargmodes,
317 &isNull);
318 if (isNull)
319 proargmodes = PointerGetDatum(NULL);
320
323
324
325 if (n_arg_names < nargs)
327 }
328 else
330
331 return pinfo;
332}
Oid get_call_expr_argtype(Node *expr, int argnum)
int get_func_input_arg_names(Datum proargnames, Datum proargmodes, char ***arg_names)
SQLFunctionParseInfo * SQLFunctionParseInfoPtr
static void * GETSTRUCT(const HeapTupleData *tuple)
char * pstrdup(const char *in)
FormData_pg_proc * Form_pg_proc
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
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().
◆ RemoveSQLFunctionCache()
static void RemoveSQLFunctionCache ( void * arg) | static |
---|
◆ ShutdownSQLFunction()
static void ShutdownSQLFunction ( Datum arg) | static |
---|
Definition at line 1939 of file functions.c.
1940{
1943
1944 es = fcache->eslist;
1945 while (es)
1946 {
1947
1949 {
1950
1953
1955
1958 }
1959 es = es->next;
1960 }
1961 fcache->eslist = NULL;
1962
1963
1966 fcache->tstore = NULL;
1967
1968
1969 if (fcache->cplan)
1971 fcache->cplan = NULL;
1972
1973
1975}
SQLFunctionCache * SQLFunctionCachePtr
static Pointer DatumGetPointer(Datum X)
void tuplestore_end(Tuplestorestate *state)
References arg, SQLFunctionCache::cowner, SQLFunctionCache::cplan, DatumGetPointer(), SQLFunctionCache::eslist, F_EXEC_RUN, SQLFunctionCache::func, execution_state::next, PopActiveSnapshot(), postquel_end(), PushActiveSnapshot(), execution_state::qd, SQLFunctionHashEntry::readonly_func, ReleaseCachedPlan(), SQLFunctionCache::shutdown_reg, QueryDesc::snapshot, execution_state::status, SQLFunctionCache::tstore, and tuplestore_end().
Referenced by fmgr_sql().
◆ sql_compile_callback()
Definition at line 1016 of file functions.c.
1021{
1028 Oid rettype;
1031 bool isNull;
1032 List *source_list;
1033
1034
1035
1036
1037
1039 comperrcontext.arg = func;
1042
1043
1044
1045
1046
1048 "SQL function",
1050
1051
1052
1053
1054
1056 "SQL function parse trees",
1059
1060
1061
1062
1063
1065 NameStr(procedureStruct->proname));
1067
1068
1069
1070
1071
1073
1074 func->rettype = rettype;
1075 if (rettupdesc)
1076 {
1080 }
1081
1082
1084
1085
1086 func->returnsSet = procedureStruct->proretset;
1087
1088
1090 (procedureStruct->provolatile != PROVOLATILE_VOLATILE);
1091
1092
1093 func->prokind = procedureStruct->prokind;
1094
1095
1096
1097
1098
1099
1105
1106
1107
1108
1109
1114
1115
1116
1117
1121
1122
1124 procedureTuple,
1125 Anum_pg_proc_prosqlbody,
1126 &isNull);
1127 if (!isNull)
1128 {
1129
1131
1135 else
1138 }
1139 else
1140 {
1141
1144 }
1145
1146
1147
1148
1149
1151
1152
1153
1154
1155
1156
1157
1158 if (func->num_queries == 0 && rettype != VOIDOID)
1160 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
1161 errmsg("return type mismatch in function declared to return %s",
1163 errdetail("Function's final statement must be SELECT or INSERT/UPDATE/DELETE/MERGE RETURNING.")));
1164
1165
1169
1170
1171
1172
1173
1174
1175
1178
1180}
#define TextDatumGetCString(d)
#define PG_GET_COLLATION()
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
static void sql_compile_error_callback(void *arg)
SQLFunctionParseInfoPtr prepare_sql_fn_parse_info(HeapTuple procedureTuple, Node *call_expr, Oid inputCollation)
void get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval)
int16 get_typlen(Oid typid)
char * MemoryContextStrdup(MemoryContext context, const char *string)
void MemoryContextSetParent(MemoryContext context, MemoryContext new_parent)
MemoryContext CacheMemoryContext
void MemoryContextSetIdentifier(MemoryContext context, const char *id)
#define castNode(_type_, nodeptr)
#define linitial_node(type, l)
List * pg_parse_query(const char *query_string)
void * stringToNode(const char *str)
Datum SysCacheGetAttrNotNull(int cacheId, HeapTuple tup, AttrNumber attributeNumber)
References ALLOCSET_SMALL_SIZES, AllocSetContextCreate, ErrorContextCallback::arg, SQLFunctionParseInfo::argtypes, SQLFunctionHashEntry::argtyplen, CacheMemoryContext, ErrorContextCallback::callback, castNode, copyObject, CreateTupleDescCopy(), CurrentMemoryContext, ereport, errcode(), errdetail(), errmsg(), ERROR, error_context_stack, FunctionCallInfoBaseData::flinfo, FmgrInfo::fn_expr, SQLFunctionHashEntry::fname, format_type_be(), get_call_result_type(), get_typlen(), get_typlenbyval(), GETSTRUCT(), SQLFunctionHashEntry::hcontext, i, IsA, linitial_node, list_length(), list_make1, MemoryContextAlloc(), MemoryContextSetIdentifier(), MemoryContextSetParent(), MemoryContextStrdup(), MemoryContextSwitchTo(), NameStr, SQLFunctionParseInfo::nargs, SQLFunctionHashEntry::num_queries, SQLFunctionHashEntry::pcontext, PG_GET_COLLATION, pg_parse_query(), SQLFunctionHashEntry::pinfo, prepare_sql_fn_parse_info(), ErrorContextCallback::previous, SQLFunctionHashEntry::prokind, SQLFunctionHashEntry::raw_source, SQLFunctionHashEntry::readonly_func, SQLFunctionHashEntry::rettupdesc, SQLFunctionHashEntry::rettype, SQLFunctionHashEntry::returnsSet, SQLFunctionHashEntry::source_list, sql_compile_error_callback(), SQLFunctionHashEntry::src, stringToNode(), SysCacheGetAttr(), SysCacheGetAttrNotNull(), TextDatumGetCString, SQLFunctionHashEntry::typbyval, and SQLFunctionHashEntry::typlen.
Referenced by init_sql_fcache().
◆ sql_compile_error_callback()
static void sql_compile_error_callback ( void * arg) | static |
---|
◆ sql_delete_callback()
◆ sql_exec_error_callback()
static void sql_exec_error_callback ( void * arg) | static |
---|
Definition at line 1901 of file functions.c.
1902{
1904 int syntaxerrposition;
1905
1906
1907
1908
1910 if (syntaxerrposition > 0 && fcache->func->src != NULL)
1911 {
1915 }
1916
1917
1918
1919
1920
1922 errcontext("SQL function \"%s\" statement %d",
1924 else
1926}
References arg, errcontext, SQLFunctionCache::error_query_index, errposition(), SQLFunctionHashEntry::fname, SQLFunctionCache::func, geterrposition(), internalerrposition(), internalerrquery(), and SQLFunctionHashEntry::src.
Referenced by fmgr_sql().
◆ sql_fn_make_param()
Definition at line 483 of file functions.c.
485{
487
490 param->paramid = paramno;
492 param->paramtypmod = -1;
495
496
497
498
499
500
502 param->paramcollid = pinfo->collation;
503
504 return (Node *) param;
505}
#define OidIsValid(objectId)
Oid get_typcollation(Oid typid)
References SQLFunctionParseInfo::argtypes, SQLFunctionParseInfo::collation, get_typcollation(), Param::location, makeNode, OidIsValid, PARAM_EXTERN, Param::paramid, Param::paramkind, and Param::paramtype.
Referenced by sql_fn_param_ref(), and sql_fn_resolve_param_name().
◆ sql_fn_param_ref()
◆ sql_fn_parser_setup()
Definition at line 338 of file functions.c.
339{
343
345}
static Node * sql_fn_param_ref(ParseState *pstate, ParamRef *pref)
static Node * sql_fn_post_column_ref(ParseState *pstate, ColumnRef *cref, Node *var)
ParseParamRefHook p_paramref_hook
PreParseColumnRefHook p_pre_columnref_hook
PostParseColumnRefHook p_post_columnref_hook
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().
◆ sql_fn_post_column_ref()
Definition at line 351 of file functions.c.
352{
354 int nnames;
355 Node *field1;
356 Node *subfield = NULL;
357 const char *name1;
358 const char *name2 = NULL;
360
361
362
363
364
365
366 if (var != NULL)
367 return NULL;
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
386
387 if (nnames > 3)
388 return NULL;
389
391 nnames--;
392
394 name1 = strVal(field1);
395 if (nnames > 1)
396 {
398 name2 = strVal(subfield);
399 }
400
401 if (nnames == 3)
402 {
403
404
405
406
407
408 if (strcmp(name1, pinfo->fname) != 0)
409 return NULL;
410
412
415 }
416 else if (nnames == 2 && strcmp(name1, pinfo->fname) == 0)
417 {
418
419
420
421
423
424 if (param)
425 {
426
427 subfield = NULL;
428 }
429 else
430 {
431
433 }
434 }
435 else
436 {
437
439 }
440
441 if (!param)
442 return NULL;
443
444 if (subfield)
445 {
446
447
448
449
450
455 NULL,
456 false,
458 }
459
460 return param;
461}
static Node * sql_fn_resolve_param_name(SQLFunctionParseInfoPtr pinfo, const char *paramname, int location)
Node * ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, Node *last_srf, FuncCall *fn, bool proc_call, int location)
References Assert(), ColumnRef::fields, SQLFunctionParseInfo::fname, if(), IsA, linitial, list_length(), list_make1, llast, ColumnRef::location, lsecond, lthird, ParseState::p_last_srf, ParseState::p_ref_hook_state, ParseFuncOrColumn(), sql_fn_resolve_param_name(), and strVal.
Referenced by sql_fn_parser_setup().
◆ sql_fn_resolve_param_name()
◆ sql_postrewrite_callback()
static void sql_postrewrite_callback ( List * querytree_list, void * arg ) | static |
---|
Definition at line 1219 of file functions.c.
1220{
1221
1222
1223
1224
1225
1227
1228
1229
1230
1231
1232
1233 if (arg != NULL)
1234 {
1236 bool returnsTuple;
1237
1242 false);
1245 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1246 errmsg("cached plan must not change result type")));
1247 }
1248}
References arg, check_sql_fn_statement(), check_sql_stmt_retval(), ereport, errcode(), errmsg(), ERROR, SQLFunctionHashEntry::prokind, SQLFunctionHashEntry::rettupdesc, SQLFunctionHashEntry::rettype, and SQLFunctionHashEntry::returnsTuple.
Referenced by prepare_next_query().
◆ sqlfunction_destroy()
static void sqlfunction_destroy ( DestReceiver * self) | static |
---|
◆ sqlfunction_receive()
◆ sqlfunction_shutdown()
static void sqlfunction_shutdown ( DestReceiver * self) | static |
---|