* Initialize the SQLFunctionCache for a SQL function */
| 677 | * Initialize the SQLFunctionCache for a SQL function |
| 678 | */ |
| 679 | static void |
| 680 | init_sql_fcache(FunctionCallInfo fcinfo, Oid collation, bool lazyEvalOK) |
| 681 | { |
| 682 | FmgrInfo *finfo = fcinfo->flinfo; |
| 683 | Oid foid = finfo->fn_oid; |
| 684 | MemoryContext fcontext; |
| 685 | MemoryContext oldcontext; |
| 686 | Oid rettype; |
| 687 | TupleDesc rettupdesc; |
| 688 | HeapTuple procedureTuple; |
| 689 | Form_pg_proc procedureStruct; |
| 690 | SQLFunctionCachePtr fcache; |
| 691 | List *queryTree_list; |
| 692 | List *resulttlist; |
| 693 | ListCell *lc; |
| 694 | Datum tmp; |
| 695 | bool isNull; |
| 696 | |
| 697 | /* |
| 698 | * Create memory context that holds all the SQLFunctionCache data. It |
| 699 | * must be a child of whatever context holds the FmgrInfo. |
| 700 | */ |
| 701 | fcontext = AllocSetContextCreate(finfo->fn_mcxt, |
| 702 | "SQL function", |
| 703 | ALLOCSET_DEFAULT_SIZES); |
| 704 | |
| 705 | oldcontext = MemoryContextSwitchTo(fcontext); |
| 706 | |
| 707 | /* |
| 708 | * Create the struct proper, link it to fcontext and fn_extra. Once this |
| 709 | * is done, we'll be able to recover the memory after failure, even if the |
| 710 | * FmgrInfo is long-lived. |
| 711 | */ |
| 712 | fcache = (SQLFunctionCachePtr) palloc0(sizeof(SQLFunctionCache)); |
| 713 | fcache->fcontext = fcontext; |
| 714 | finfo->fn_extra = (void *) fcache; |
| 715 | |
| 716 | /* |
| 717 | * get the procedure tuple corresponding to the given function Oid |
| 718 | */ |
| 719 | procedureTuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(foid)); |
| 720 | if (!HeapTupleIsValid(procedureTuple)) |
| 721 | elog(ERROR, "cache lookup failed for function %u", foid); |
| 722 | procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple); |
| 723 | |
| 724 | /* |
| 725 | * copy function name immediately for use by error reporting callback, and |
| 726 | * for use as memory context identifier |
| 727 | */ |
| 728 | fcache->fname = pstrdup(NameStr(procedureStruct->proname)); |
| 729 | MemoryContextSetIdentifier(fcontext, fcache->fname); |
| 730 | |
| 731 | /* |
| 732 | * Resolve any polymorphism, obtaining the actual result type, and the |
| 733 | * corresponding tupdesc if it's a rowtype. |
| 734 | */ |
| 735 | (void) get_call_result_type(fcinfo, &rettype, &rettupdesc); |
| 736 |
no test coverage detected