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 63 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 2116 of file functions.c.
2120{
2121 List *queryTreeList;
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135 if (queryTreeLists != NIL)
2137 else
2138 queryTreeList = NIL;
2139
2141 rettype, rettupdesc,
2142 prokind, insertDroppedCols);
2143}
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_sql_function_in_from().
◆ check_sql_fn_statement()
| static void check_sql_fn_statement ( List * queryTreeList) | static |
|---|
Definition at line 2052 of file functions.c.
2053{
2055
2056 foreach(lc, queryTreeList)
2057 {
2059
2060
2061
2062
2063
2064
2065
2066
2069 {
2071
2074 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2075 errmsg("calling procedures with output arguments is not supported in SQL functions")));
2076 }
2077 }
2078}
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 2150 of file functions.c.
2153{
2154 bool is_tuple_result = false;
2157 List *tlist;
2158 int tlistlen;
2159 bool tlist_is_modifiable;
2160 char fn_typtype;
2162 bool upper_tlist_nontrivial = false;
2164
2165
2166
2167
2168
2169 if (rettype == VOIDOID)
2170 return false;
2171
2172
2173
2174
2175
2176
2178 parse_cell = NULL;
2179 foreach(lc, queryTreeList)
2180 {
2182
2183 if (q->canSetTag)
2184 {
2186 parse_cell = lc;
2187 }
2188 }
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2203 {
2204 tlist = parse->targetList;
2205
2206 tlist_is_modifiable = (parse->setOperations == NULL);
2207 }
2208 else if (parse &&
2213 parse->returningList)
2214 {
2215 tlist = parse->returningList;
2216
2217 tlist_is_modifiable = true;
2218 }
2219 else
2220 {
2221
2223 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
2224 errmsg("return type mismatch in function declared to return %s",
2226 errdetail("Function's final statement must be SELECT or INSERT/UPDATE/DELETE/MERGE RETURNING.")));
2227 return false;
2228 }
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2244
2246
2247 if (fn_typtype == TYPTYPE_BASE ||
2248 fn_typtype == TYPTYPE_DOMAIN ||
2249 fn_typtype == TYPTYPE_ENUM ||
2250 fn_typtype == TYPTYPE_RANGE ||
2251 fn_typtype == TYPTYPE_MULTIRANGE)
2252 {
2253
2254
2255
2256
2258
2259 if (tlistlen != 1)
2261 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
2262 errmsg("return type mismatch in function declared to return %s",
2264 errdetail("Final statement must return exactly one column.")));
2265
2266
2268 Assert(!tle->resjunk);
2269
2271 tlist_is_modifiable,
2272 &upper_tlist,
2273 &upper_tlist_nontrivial))
2275 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
2276 errmsg("return type mismatch in function declared to return %s",
2278 errdetail("Actual return type is %s.",
2280 }
2281 else if (fn_typtype == TYPTYPE_COMPOSITE || rettype == RECORDOID)
2282 {
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294 int tupnatts;
2295 int tuplogcols;
2296 int colindex;
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319 if (tlistlen == 1 && prokind != PROKIND_PROCEDURE)
2320 {
2322
2323 Assert(!tle->resjunk);
2325 tlist_is_modifiable,
2326 &upper_tlist,
2327 &upper_tlist_nontrivial))
2328 {
2329
2330 goto tlist_coercion_finished;
2331 }
2332 }
2333
2334
2335
2336
2337
2338 if (rettupdesc == NULL)
2339 return true;
2340
2341
2342
2343
2344
2345
2346
2347 tupnatts = rettupdesc->natts;
2348 tuplogcols = 0;
2349 colindex = 0;
2350
2351 foreach(lc, tlist)
2352 {
2355
2356
2357 if (tle->resjunk)
2358 continue;
2359
2360 do
2361 {
2362 colindex++;
2363 if (colindex > tupnatts)
2365 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
2366 errmsg("return type mismatch in function declared to return %s",
2368 errdetail("Final statement returns too many columns.")));
2370 if (attr->attisdropped && insertDroppedCols)
2371 {
2372 Expr *null_expr;
2373
2374
2376 -1,
2380 true,
2381 true );
2382 upper_tlist = lappend(upper_tlist,
2385 NULL,
2386 false));
2387 upper_tlist_nontrivial = true;
2388 }
2389 } while (attr->attisdropped);
2390 tuplogcols++;
2391
2393 attr->atttypid, attr->atttypmod,
2394 tlist_is_modifiable,
2395 &upper_tlist,
2396 &upper_tlist_nontrivial))
2398 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
2399 errmsg("return type mismatch in function declared to return %s",
2401 errdetail("Final statement returns %s instead of %s at column %d.",
2404 tuplogcols)));
2405 }
2406
2407
2408 for (colindex++; colindex <= tupnatts; colindex++)
2409 {
2412 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
2413 errmsg("return type mismatch in function declared to return %s",
2415 errdetail("Final statement returns too few columns.")));
2416 if (insertDroppedCols)
2417 {
2418 Expr *null_expr;
2419
2420
2422 -1,
2426 true,
2427 true );
2428 upper_tlist = lappend(upper_tlist,
2431 NULL,
2432 false));
2433 upper_tlist_nontrivial = true;
2434 }
2435 }
2436
2437
2438 is_tuple_result = true;
2439 }
2440 else
2442 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
2443 errmsg("return type %s is not supported for SQL functions",
2445
2446tlist_coercion_finished:
2447
2448
2449
2450
2451
2452
2453
2454 if (upper_tlist_nontrivial)
2455 {
2456 Query *newquery;
2457 List *colnames;
2460
2462
2463
2466 newquery->querySource = parse->querySource;
2467 newquery->canSetTag = true;
2469
2470
2471 colnames = NIL;
2472 foreach(lc, parse->targetList)
2473 {
2475
2476 if (tle->resjunk)
2477 continue;
2478 colnames = lappend(colnames,
2479 makeString(tle->resname ? tle->resname : ""));
2480 }
2481
2482
2486 rte->eref = makeAlias("unnamed_subquery", colnames);
2487 rte->lateral = false;
2488 rte->inh = false;
2489 rte->inFromCl = true;
2491
2495
2496
2497
2498
2499
2500 newquery->hasRowSecurity = parse->hasRowSecurity;
2501
2502
2503 lfirst(parse_cell) = newquery;
2504 }
2505
2506 return is_tuple_result;
2507}
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 2520 of file functions.c.
2526{
2528 Expr *new_tle_expr;
2529 Node *cast_result;
2530
2531
2532
2533
2534
2535
2536
2537 if (tlist_is_modifiable && src_tle->ressortgroupref == 0)
2538 {
2539
2543 res_type, res_typmod,
2546 -1);
2547 if (cast_result == NULL)
2548 return false;
2550 src_tle->expr = (Expr *) cast_result;
2551
2553 }
2554 else
2555 {
2556
2558
2560 (Node *) var,
2561 var->vartype,
2562 res_type, res_typmod,
2565 -1);
2566 if (cast_result == NULL)
2567 return false;
2569
2570 if (cast_result != (Node *) var)
2571 *upper_tlist_nontrivial = true;
2572 new_tle_expr = (Expr *) cast_result;
2573 }
2576 src_tle->resname, false);
2577 *upper_tlist = lappend(*upper_tlist, new_tle);
2578 return true;
2579}
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 2617 of file functions.c.
2618{
2620
2626
2627
2628
2630}
#define palloc0_object(type)
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(* 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_object, 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 1576 of file functions.c.
1577{
1581 bool randomAccess;
1582 bool lazyEvalOK;
1583 bool pushed_snapshot;
1587
1588
1589 if (fcinfo->flinfo->fn_retset)
1590 {
1592
1593
1594
1595
1596
1597
1598
1603 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1604 errmsg("set-valued function called in context that cannot accept a set")));
1607
1609 }
1610 else
1611 {
1612 randomAccess = false;
1613 lazyEvalOK = true;
1614
1615 tscontext = NULL;
1616 }
1617
1618
1619
1620
1622
1623
1624 fcache->active = true;
1625
1626
1629
1630
1631
1632
1634 sqlerrcontext.arg = fcache;
1637
1638
1639
1640
1641
1642 do
1643 {
1644 es = fcache->eslist;
1646 es = es->next;
1647 if (es)
1648 break;
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669 pushed_snapshot = false;
1670 while (es)
1671 {
1672 bool completed;
1673
1675 {
1676
1677
1678
1679
1680
1681
1683 {
1685 if (!pushed_snapshot)
1686 {
1688 pushed_snapshot = true;
1689 }
1690 else
1692 }
1693
1695 }
1697 {
1698
1700 pushed_snapshot = true;
1701 }
1702
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1727 break;
1728
1729
1730
1731
1732 es = es->next;
1733 while (!es)
1734 {
1735
1736
1737
1738
1739
1740
1741 if (pushed_snapshot)
1742 {
1744 pushed_snapshot = false;
1745 }
1746
1748 break;
1749
1750 es = fcache->eslist;
1751 }
1752 }
1753
1754
1755
1756
1757
1759 {
1761
1762 if (es)
1763 {
1764
1765
1766
1767
1769
1773
1775
1776
1777
1778
1780
1781
1782
1783
1784
1786 {
1791 }
1792 }
1794 {
1795
1796
1797
1798
1800
1801 fcinfo->isnull = true;
1802 result = (Datum) 0;
1803
1804
1806 {
1811 }
1812 }
1813 else
1814 {
1815
1816
1817
1818
1819
1820
1821
1822
1823
1827 fcache->tstore = NULL;
1828
1831
1832 fcinfo->isnull = true;
1833 result = (Datum) 0;
1834
1835
1837 {
1842 }
1843 }
1844 }
1845 else
1846 {
1847
1848
1849
1851 {
1852
1856 else
1857 {
1858 fcinfo->isnull = true;
1859 result = (Datum) 0;
1860 }
1861 }
1862 else
1863 {
1864
1866 fcinfo->isnull = true;
1867 result = (Datum) 0;
1868 }
1869 }
1870
1871
1872 if (pushed_snapshot)
1874
1875
1876
1877
1878
1879 if (es == NULL)
1880 fcache->eslist = NULL;
1881
1882
1883 fcache->active = false;
1884
1886
1887 return result;
1888}
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 SQLFunctionCache::active, 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 653 of file functions.c.
654{
658 int nstmts;
660
661
662
663
664 if (fcache->cplan)
665 {
667 fcache->cplan = NULL;
668 }
669 fcache->eslist = NULL;
670
671
672
673
674
675
676
678 {
680 return false;
683 }
684 else
686
690
691
692
693
694
695
696
701 NULL);
702
703
704
705
708 {
709 if (fcache->esarray == NULL)
713 else
717 }
718
719
720
721
723 {
726
727
728
729
730
732 {
734 ((CopyStmt *) stmt->utilityStmt)->filename == NULL)
736 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
737 errmsg("cannot COPY to/from client in an SQL function")));
738
741 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
742
743 errmsg("%s is not allowed in an SQL function",
745 }
746
749 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
750
751 errmsg("%s is not allowed in a non-volatile function",
753
754
756 if (preves)
757 preves->next = newes;
758 else
759 fcache->eslist = newes;
760
761 newes->next = NULL;
763 newes->setsResult = false;
764 newes->lazyEval = false;
766 newes->qd = NULL;
767
768 if (stmt->canSetTag)
769 lasttages = newes;
770
771 preves = newes;
772 }
773
774
775
776
777
779 return true;
780
781
782
783
784
785
786
787
788
789
790
791
792
793
797 {
799 List *resulttlist;
801
802
805 "SQL function junkfilter",
807 else
810
812
813
814
815
816
817
819
820
821
822
823
824
825
826
827
831 slot);
832 else
834
835
836
837
838
839
840
841
842
843
845
846
849
850
852
854 }
855
859 {
860
861
862
863
864
866 }
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
883 {
889 }
890
891 return true;
892}
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 536 of file functions.c.
537{
541
542
543
544
545
546
547
549 if (fcache == NULL)
550 {
558 }
559
560
561
562
563
564
565
567 {
568
569
570
571
572
573
574
575 fcache->cplan = NULL;
576 fcache->eslist = NULL;
577 fcache->tstore = NULL;
579 fcache->active = false;
580 }
581
582
583
584
585
586
587
588 if (fcache->eslist != NULL)
589 {
591 return fcache;
592 }
593
594
595
596
597
598
599
606 true,
607 false);
608
609
610
611
612
613
614
615 if (func != fcache->func)
616 {
617 if (fcache->func != NULL)
618 {
621 }
622 fcache->func = func;
624
626 }
627
628
629
630
631
633
634
637
638
639 fcache->eslist = NULL;
642
643 return fcache;
644}
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 SQLFunctionCache::active, MemoryContextCallback::arg, Assert(), cached_function_compile(), SQLFunctionHashEntry::cfunc, SQLFunctionCache::cplan, 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(), SQLFunctionCache::shutdown_reg, sql_compile_callback(), sql_delete_callback(), SQLFunctionCache::tstore, and CachedFunction::use_count.
Referenced by fmgr_sql().
◆ postquel_end()
Definition at line 1441 of file functions.c.
1442{
1444
1445
1447
1448
1450
1451
1453 {
1456 }
1457
1459
1461 es->qd = NULL;
1462
1464
1465
1469}
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 1536 of file functions.c.
1539{
1541
1542
1543
1544
1545
1546
1547
1549 {
1550
1551 fcinfo->isnull = false;
1553 }
1554 else
1555 {
1556
1557
1558
1559
1561
1562 if (!fcinfo->isnull)
1564 }
1565
1566
1568
1570}
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 1400 of file functions.c.
1401{
1402 bool result;
1404
1405
1407
1409 {
1412 true,
1417 NULL);
1418 result = true;
1419 }
1420 else
1421 {
1422
1424
1426
1427
1428
1429
1430
1432 }
1433
1435
1436 return result;
1437}
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 1276 of file functions.c.
1277{
1280
1282
1283
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1298 {
1300 "SQL function execution",
1303 }
1305 {
1306
1307
1308
1309
1310
1311
1312
1313
1315 "SQL function execution",
1318 }
1319 else
1320 {
1323 }
1324
1325
1326
1327
1328
1330 {
1333 {
1337 }
1338 }
1339
1340
1342
1343
1344
1345
1346
1348 {
1350
1352
1355 myState->tstore = fcache->tstore;
1357
1358
1360 }
1361 else
1363
1371 0);
1372
1373
1375 {
1376
1377
1378
1379
1380
1381
1382
1383 int eflags;
1384
1387 else
1388 eflags = 0;
1390 }
1391
1393
1395}
DestReceiver * CreateDestReceiver(CommandDest dest)
DestReceiver * None_Receiver
void ExecutorStart(QueryDesc *queryDesc, int eflags)
#define EXEC_FLAG_SKIP_TRIGGERS
MemoryContext CurrentMemoryContext
#define ALLOCSET_DEFAULT_SIZES
QueryDesc * CreateQueryDesc(PlannedStmt *plannedstmt, 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, 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 1473 of file functions.c.
1475{
1476 int nargs = fcinfo->nargs;
1477
1478 if (nargs > 0)
1479 {
1483
1484 if (fcache->paramLI == NULL)
1485 {
1486
1488
1491 fcache->paramLI = paramLI;
1493 }
1494 else
1495 {
1496 paramLI = fcache->paramLI;
1498 }
1499
1500 for (int i = 0; i < nargs; i++)
1501 {
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1519 argtyplen[i]);
1520
1522 prm->ptype = argtypes[i];
1523 }
1524 }
1525 else
1527}
#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 900 of file functions.c.
901{
902 int qindex;
903 bool islast;
905 List *queryTree_list;
907
908
910 Assert(qindex < func->num_queries);
911 islast = (qindex + 1 >= func->num_queries);
912
913
914
915
916
917
918
919
920
921
923 {
924
926
929 func->src,
933 }
934 else
935 {
936
938
941 func->src,
944 func->src,
947 NULL);
948 }
949
950
951
952
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973 if (islast)
978 false);
979
980
981
982
983
985 queryTree_list,
986 NULL,
987 NULL,
988 0,
992 false);
993
994
995
996
997
1000 islast ? func : NULL);
1001
1002
1003
1004
1005
1009
1010
1011
1012
1013
1015
1016
1017
1018
1019
1020
1021 if (islast)
1022 {
1023 func->source_list = NIL;
1026 }
1027}
static void sql_postrewrite_callback(List *querytree_list, void *arg)
void sql_fn_parser_setup(struct ParseState *pstate, SQLFunctionParseInfoPtr pinfo)
void(* ParserSetupHook)(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 251 of file functions.c.
254{
257 int nargs;
258
260
261
263
264
265 pinfo->collation = inputCollation;
266
267
268
269
270
271 pinfo->nargs = nargs = procedureStruct->pronargs;
272 if (nargs > 0)
273 {
274 Oid *argOidVect;
275 int argnum;
276
277 argOidVect = (Oid *) palloc(nargs * sizeof(Oid));
278 memcpy(argOidVect,
279 procedureStruct->proargtypes.values,
280 nargs * sizeof(Oid));
281
282 for (argnum = 0; argnum < nargs; argnum++)
283 {
284 Oid argtype = argOidVect[argnum];
285
286 if (IsPolymorphicType(argtype))
287 {
291 (errcode(ERRCODE_DATATYPE_MISMATCH),
292 errmsg("could not determine actual type of argument declared %s",
294 argOidVect[argnum] = argtype;
295 }
296 }
297
298 pinfo->argtypes = argOidVect;
299 }
300
301
302
303
304 if (nargs > 0)
305 {
306 Datum proargnames;
307 Datum proargmodes;
308 int n_arg_names;
309 bool isNull;
310
311 proargnames = SysCacheGetAttr(PROCNAMEARGSNSP, procedureTuple,
312 Anum_pg_proc_proargnames,
313 &isNull);
314 if (isNull)
315 proargnames = PointerGetDatum(NULL);
316
317 proargmodes = SysCacheGetAttr(PROCNAMEARGSNSP, procedureTuple,
318 Anum_pg_proc_proargmodes,
319 &isNull);
320 if (isNull)
321 proargmodes = PointerGetDatum(NULL);
322
325
326
327 if (n_arg_names < nargs)
329 }
330 else
332
333 return pinfo;
334}
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_object, PointerGetDatum(), pstrdup(), and SysCacheGetAttr().
Referenced by fmgr_sql_validator(), inline_function(), inline_sql_function_in_from(), sql_compile_callback(), and test_inline_in_from_support_func().
◆ RemoveSQLFunctionCache()
| static void RemoveSQLFunctionCache ( void * arg) | static |
|---|
◆ ShutdownSQLFunction()
| static void ShutdownSQLFunction ( Datum arg) | static |
|---|
Definition at line 1967 of file functions.c.
1968{
1971
1972 es = fcache->eslist;
1973 while (es)
1974 {
1975
1977 {
1978
1981
1983
1986 }
1987 es = es->next;
1988 }
1989 fcache->eslist = NULL;
1990
1991
1994 fcache->tstore = NULL;
1995
1996
1997 if (fcache->cplan)
1999 fcache->cplan = NULL;
2000
2001
2003}
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 1040 of file functions.c.
1045{
1052 Oid rettype;
1055 bool isNull;
1056 List *source_list;
1057
1058
1059
1060
1061
1063 comperrcontext.arg = func;
1066
1067
1068
1069
1070
1072 "SQL function",
1074
1075
1076
1077
1078
1080 "SQL function parse trees",
1083
1084
1085
1086
1087
1089 NameStr(procedureStruct->proname));
1091
1092
1093
1094
1095
1097
1098 func->rettype = rettype;
1099 if (rettupdesc)
1100 {
1104 }
1105
1106
1108
1109
1110 func->returnsSet = procedureStruct->proretset;
1111
1112
1114 (procedureStruct->provolatile != PROVOLATILE_VOLATILE);
1115
1116
1117 func->prokind = procedureStruct->prokind;
1118
1119
1120
1121
1122
1123
1129
1130
1131
1132
1133
1138
1139
1140
1141
1145
1146
1148 procedureTuple,
1149 Anum_pg_proc_prosqlbody,
1150 &isNull);
1151 if (!isNull)
1152 {
1153
1155
1159 else
1162 }
1163 else
1164 {
1165
1168 }
1169
1170
1171
1172
1173
1175
1176
1177
1178
1179
1180
1181
1182 if (func->num_queries == 0 && rettype != VOIDOID)
1184 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
1185 errmsg("return type mismatch in function declared to return %s",
1187 errdetail("Function's final statement must be SELECT or INSERT/UPDATE/DELETE/MERGE RETURNING.")));
1188
1189
1193
1194
1195
1196
1197
1198
1199
1202
1204}
#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 1929 of file functions.c.
1930{
1932 int syntaxerrposition;
1933
1934
1935
1936
1938 if (syntaxerrposition > 0 && fcache->func->src != NULL)
1939 {
1943 }
1944
1945
1946
1947
1948
1950 errcontext("SQL function \"%s\" statement %d",
1952 else
1954}
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 485 of file functions.c.
487{
489
492 param->paramid = paramno;
497
498
499
500
501
502
505
506 return (Node *) param;
507}
#define OidIsValid(objectId)
Oid get_typcollation(Oid typid)
References SQLFunctionParseInfo::argtypes, SQLFunctionParseInfo::collation, get_typcollation(), Param::location, makeNode, OidIsValid, PARAM_EXTERN, Param::paramcollid, Param::paramid, Param::paramkind, Param::paramtype, and Param::paramtypmod.
Referenced by sql_fn_param_ref(), and sql_fn_resolve_param_name().
◆ sql_fn_param_ref()
◆ sql_fn_parser_setup()
Definition at line 340 of file functions.c.
341{
345
347}
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_sql_function_in_from(), interpret_AS_clause(), prepare_next_query(), and test_inline_in_from_support_func().
◆ sql_fn_post_column_ref()
Definition at line 353 of file functions.c.
354{
356 int nnames;
357 Node *field1;
358 Node *subfield = NULL;
359 const char *name1;
360 const char *name2 = NULL;
362
363
364
365
366
367
368 if (var != NULL)
369 return NULL;
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
388
389 if (nnames > 3)
390 return NULL;
391
393 nnames--;
394
396 name1 = strVal(field1);
397 if (nnames > 1)
398 {
400 name2 = strVal(subfield);
401 }
402
403 if (nnames == 3)
404 {
405
406
407
408
409
410 if (strcmp(name1, pinfo->fname) != 0)
411 return NULL;
412
414
417 }
418 else if (nnames == 2 && strcmp(name1, pinfo->fname) == 0)
419 {
420
421
422
423
425
426 if (param)
427 {
428
429 subfield = NULL;
430 }
431 else
432 {
433
435 }
436 }
437 else
438 {
439
441 }
442
443 if (!param)
444 return NULL;
445
446 if (subfield)
447 {
448
449
450
451
452
457 NULL,
458 false,
460 }
461
462 return param;
463}
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 1243 of file functions.c.
1244{
1245
1246
1247
1248
1249
1251
1252
1253
1254
1255
1256
1257 if (arg != NULL)
1258 {
1260 bool returnsTuple;
1261
1266 false);
1269 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1270 errmsg("cached plan must not change result type")));
1271 }
1272}
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 |
|---|