MCPcopy Create free account
hub / github.com/apache/cloudberry / plpgsql_compile

Function plpgsql_compile

src/pl/plpgsql/src/pl_comp.c:135–239  ·  view source on GitHub ↗

---------- * plpgsql_compile Make an execution tree for a PL/pgSQL function. * * If forValidator is true, we're only compiling for validation purposes, * and so some checks are skipped. * * Note: it's important for this to fall through quickly if the function * has already been compiled. * ---------- */

Source from the content-addressed store, hash-verified

133 * ----------
134 */
135PLpgSQL_function *
136plpgsql_compile(FunctionCallInfo fcinfo, bool forValidator)
137{
138 Oid funcOid = fcinfo->flinfo->fn_oid;
139 HeapTuple procTup;
140 Form_pg_proc procStruct;
141 PLpgSQL_function *function;
142 PLpgSQL_func_hashkey hashkey;
143 bool function_valid = false;
144 bool hashkey_valid = false;
145
146 /*
147 * Lookup the pg_proc tuple by Oid; we'll need it in any case
148 */
149 procTup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcOid));
150 if (!HeapTupleIsValid(procTup))
151 elog(ERROR, "cache lookup failed for function %u", funcOid);
152 procStruct = (Form_pg_proc) GETSTRUCT(procTup);
153
154 /*
155 * See if there's already a cache entry for the current FmgrInfo. If not,
156 * try to find one in the hash table.
157 */
158 function = (PLpgSQL_function *) fcinfo->flinfo->fn_extra;
159
160recheck:
161 if (!function)
162 {
163 /* Compute hashkey using function signature and actual arg types */
164 compute_function_hashkey(fcinfo, procStruct, &hashkey, forValidator);
165 hashkey_valid = true;
166
167 /* And do the lookup */
168 function = plpgsql_HashTableLookup(&hashkey);
169 }
170
171 if (function)
172 {
173 /* We have a compiled function, but is it still valid? */
174 if (function->fn_xmin == HeapTupleHeaderGetRawXmin(procTup->t_data) &&
175 ItemPointerEquals(&function->fn_tid, &procTup->t_self))
176 function_valid = true;
177 else
178 {
179 /*
180 * Nope, so remove it from hashtable and try to drop associated
181 * storage (if not done already).
182 */
183 delete_function(function);
184
185 /*
186 * If the function isn't in active use then we can overwrite the
187 * func struct with new data, allowing any other existing fn_extra
188 * pointers to make use of the new definition on their next use.
189 * If it is in use then just leave it alone and make a new one.
190 * (The active invocations will run to completion using the
191 * previous definition, and then the cache entry will just be
192 * leaked; doesn't seem worth adding code to clean it up, given

Callers 2

plpgsql_call_handlerFunction · 0.85
plpgsql_validatorFunction · 0.85

Calls 8

SearchSysCache1Function · 0.85
ObjectIdGetDatumFunction · 0.85
compute_function_hashkeyFunction · 0.85
plpgsql_HashTableLookupFunction · 0.85
ItemPointerEqualsFunction · 0.85
delete_functionFunction · 0.85
do_compileFunction · 0.85
ReleaseSysCacheFunction · 0.85

Tested by

no test coverage detected