37 memset(&hash_ctl, 0,
sizeof(hash_ctl));
40 PLy_procedure_cache =
hash_create(
"PL/Python procedures", 32, &hash_ctl,
53 return "<unknown procedure>";
72 bool use_cache = !(is_trigger && fn_rel ==
InvalidOid);
81 elog(
ERROR,
"cache lookup failed for function %u", fn_oid);
145 rv =
snprintf(procName,
sizeof(procName),
146 "__plpython_procedure_%s_%u",
149 if (rv >=
sizeof(procName) || rv < 0)
150 elog(
ERROR,
"procedure name would overrun buffer");
153 for (ptr = procName; *ptr; ptr++)
155 if (!((*ptr >=
'A' && *ptr <=
'Z') ||
156 (*ptr >=
'a' && *ptr <=
'z') ||
157 (*ptr >=
'0' && *ptr <=
'9')))
163 "PL/Python function",
173 Datum protrftypes_datum;
184 proc->
fn_readonly = (procStruct->provolatile != PROVOLATILE_VOLATILE);
185 proc->
is_setof = procStruct->proretset;
186 proc->
is_procedure = (procStruct->prokind == PROKIND_PROCEDURE);
191 proc->
langid = procStruct->prolang;
193 Anum_pg_proc_protrftypes,
208 Oid rettype = procStruct->prorettype;
214 elog(
ERROR,
"cache lookup failed for type %u", rettype);
218 if (rvTypeStruct->typtype == TYPTYPE_PSEUDO)
220 if (rettype == VOIDOID ||
221 rettype == RECORDOID)
223 else if (rettype == TRIGGEROID || rettype == EVTTRIGGEROID)
225 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
226 errmsg(
"trigger functions can only be called as triggers")));
229 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
230 errmsg(
"PL/Python functions cannot return type %s",
257 if (procStruct->pronargs)
274 for (i = 0; i < total; i++)
276 if (modes[i] != PROARGMODE_OUT &&
277 modes[i] != PROARGMODE_TABLE)
286 for (i = pos = 0; i < total; i++)
292 (modes[i] == PROARGMODE_OUT ||
293 modes[i] == PROARGMODE_TABLE))
296 Assert(types[i] == procStruct->proargtypes.values[pos]);
301 elog(
ERROR,
"cache lookup failed for type %u", types[i]);
305 if (argTypeStruct->typtype == TYPTYPE_PSEUDO)
307 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
308 errmsg(
"PL/Python functions cannot accept type %s",
329 Anum_pg_proc_prosrc, &isnull);
356 PyObject *crv = NULL;
376 crv = PyRun_String(msrc, Py_file_input, proc->
globals, NULL);
390 if (clen < 0 || clen >=
sizeof(call))
391 elog(
ERROR,
"string would overflow buffer");
392 proc->
code = Py_CompileString(call,
"<string>", Py_eval_input);
393 if (proc->
code != NULL)
398 PLy_elog(
ERROR,
"could not compile PL/Python function \"%s\"",
401 PLy_elog(
ERROR,
"could not compile anonymous PL/Python code block");
407 Py_XDECREF(proc->
code);
442 mlen = (strlen(src) * 2) + strlen(name) + 16;
445 plen =
snprintf(mrc, mlen,
"def %s():\n\t", name);
446 Assert(plen >= 0 && plen < mlen);
453 if (*sp ==
'\r' && *(sp + 1) ==
'\n')
456 if (*sp ==
'\n' || *sp ==
'\r')
469 if (mp > (mrc + mlen))
470 elog(
FATAL,
"buffer overrun in PLy_procedure_munge_source");
void MemoryContextDelete(MemoryContext context)
#define AllocSetContextCreate
static char * PLy_procedure_munge_source(const char *name, const char *src)
char * pstrdup(const char *in)
void init_procedure_caches(void)
int get_func_arg_info(HeapTuple procTup, Oid **p_argtypes, char ***p_argnames, char **p_argmodes)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
void PLy_procedure_delete(PLyProcedure *proc)
int errcode(int sqlerrcode)
void PLy_procedure_compile(PLyProcedure *proc, const char *src)
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
List * oid_array_to_list(Datum datum)
PLyProcedure * PLy_procedure_get(Oid fn_oid, Oid fn_rel, bool is_trigger)
void pfree(void *pointer)
char * PLy_procedure_name(PLyProcedure *proc)
#define ObjectIdGetDatum(X)
struct PLyProcedureEntry PLyProcedureEntry
#define ALLOCSET_DEFAULT_SIZES
PyObject * PLy_interp_globals
void PLy_input_setup_func(PLyDatumToOb *arg, MemoryContext arg_mcxt, Oid typeOid, int32 typmod, PLyProcedure *proc)
#define ereport(elevel, rest)
MemoryContext TopMemoryContext
static bool PLy_procedure_valid(PLyProcedure *proc, HeapTuple procTup)
HeapTuple SearchSysCache1(int cacheId, Datum key1)
#define TextDatumGetCString(d)
void * palloc0(Size size)
HTAB * hash_create(const char *tabname, long nelem, HASHCTL *info, int flags)
void ReleaseSysCache(HeapTuple tuple)
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
FormData_pg_proc * Form_pg_proc
static PLyProcedure * PLy_procedure_create(HeapTuple procTup, Oid fn_oid, bool is_trigger)
#define HeapTupleIsValid(tuple)
#define Assert(condition)
FormData_pg_type * Form_pg_type
void MemoryContextSetIdentifier(MemoryContext context, const char *id)
#define HeapTupleHeaderGetRawXmin(tup)
struct PLyProcedureKey PLyProcedureKey
bool ItemPointerEquals(ItemPointer pointer1, ItemPointer pointer2)
static HTAB * PLy_procedure_cache
void PLy_output_setup_func(PLyObToDatum *arg, MemoryContext arg_mcxt, Oid typeOid, int32 typmod, PLyProcedure *proc)
int errmsg(const char *fmt,...)
char * MemoryContextStrdup(MemoryContext context, const char *string)