2 * Python procedure manipulation for plpython
4 * src/pl/plpython/plpy_procedure.c
9 #include "access/htup_details.h"
10 #include "access/transam.h"
12 #include "catalog/pg_proc.h"
13 #include "catalog/pg_type.h"
14 #include "plpy_elog.h"
15 #include "plpy_main.h"
16 #include "plpy_procedure.h"
18 #include "utils/builtins.h"
19 #include "utils/hsearch.h"
20 #include "utils/inval.h"
21 #include "utils/lsyscache.h"
22 #include "utils/memutils.h"
23 #include "utils/syscache.h"
25 static HTAB
*PLy_procedure_cache
= NULL
;
27 static PLyProcedure
*PLy_procedure_create(HeapTuple procTup
, Oid fn_oid
, bool is_trigger
);
28 static bool PLy_procedure_valid(PLyProcedure
*proc
, HeapTuple procTup
);
29 static char *PLy_procedure_munge_source(const char *name
, const char *src
);
33 init_procedure_caches(void)
37 hash_ctl
.keysize
= sizeof(PLyProcedureKey
);
38 hash_ctl
.entrysize
= sizeof(PLyProcedureEntry
);
39 PLy_procedure_cache
= hash_create("PL/Python procedures", 32, &hash_ctl
,
40 HASH_ELEM
| HASH_BLOBS
);
44 * PLy_procedure_name: get the name of the specified procedure.
46 * NB: this returns the SQL name, not the internal Python procedure name
49 PLy_procedure_name(PLyProcedure
*proc
)
52 return "<unknown procedure>";
57 * PLy_procedure_get: returns a cached PLyProcedure, or creates, stores and
58 * returns a new PLyProcedure.
60 * fn_oid is the OID of the function requested
61 * fn_rel is InvalidOid or the relation this function triggers on
62 * is_trigger denotes whether the function is a trigger function
64 * The reason that both fn_rel and is_trigger need to be passed is that when
65 * trigger functions get validated we don't know which relation(s) they'll
66 * be used with, so no sensible fn_rel can be passed.
69 PLy_procedure_get(Oid fn_oid
, Oid fn_rel
, bool is_trigger
)
71 bool use_cache
= !(is_trigger
&& fn_rel
== InvalidOid
);
74 PLyProcedureEntry
*volatile entry
= NULL
;
75 PLyProcedure
*volatile proc
= NULL
;
78 procTup
= SearchSysCache1(PROCOID
, ObjectIdGetDatum(fn_oid
));
79 if (!HeapTupleIsValid(procTup
))
80 elog(ERROR
, "cache lookup failed for function %u", fn_oid
);
83 * Look for the function in the cache, unless we don't have the necessary
84 * information (e.g. during validation). In that case we just don't cache
91 entry
= hash_search(PLy_procedure_cache
, &key
, HASH_ENTER
, &found
);
99 /* Haven't found it, create a new procedure */
100 proc
= PLy_procedure_create(procTup
, fn_oid
, is_trigger
);
104 else if (!PLy_procedure_valid(proc
, procTup
))
106 /* Found it, but it's invalid, free and reuse the cache entry */
109 PLy_procedure_delete(proc
);
110 proc
= PLy_procedure_create(procTup
, fn_oid
, is_trigger
);
113 /* Found it and it's valid, it's fine to use it */
117 /* Do not leave an uninitialized entry in the cache */
119 hash_search(PLy_procedure_cache
, &key
, HASH_REMOVE
, NULL
);
124 ReleaseSysCache(procTup
);
130 * Create a new PLyProcedure structure
132 static PLyProcedure
*
133 PLy_procedure_create(HeapTuple procTup
, Oid fn_oid
, bool is_trigger
)
135 char procName
[NAMEDATALEN
+ 256];
136 Form_pg_proc procStruct
;
137 PLyProcedure
*volatile proc
;
139 MemoryContext oldcxt
;
143 procStruct
= (Form_pg_proc
) GETSTRUCT(procTup
);
144 rv
= snprintf(procName
, sizeof(procName
),
145 "__plpython_procedure_%s_%u",
146 NameStr(procStruct
->proname
),
148 if (rv
>= sizeof(procName
) || rv
< 0)
149 elog(ERROR
, "procedure name would overrun buffer");
151 /* Replace any not-legal-in-Python-names characters with '_' */
152 for (ptr
= procName
; *ptr
; ptr
++)
154 if (!((*ptr
>= 'A' && *ptr
<= 'Z') ||
155 (*ptr
>= 'a' && *ptr
<= 'z') ||
156 (*ptr
>= '0' && *ptr
<= '9')))
160 /* Create long-lived context that all procedure info will live in */
161 cxt
= AllocSetContextCreate(TopMemoryContext
,
162 "PL/Python function",
163 ALLOCSET_DEFAULT_SIZES
);
165 oldcxt
= MemoryContextSwitchTo(cxt
);
167 proc
= (PLyProcedure
*) palloc0(sizeof(PLyProcedure
));
172 Datum protrftypes_datum
;
178 proc
->proname
= pstrdup(NameStr(procStruct
->proname
));
179 MemoryContextSetIdentifier(cxt
, proc
->proname
);
180 proc
->pyname
= pstrdup(procName
);
181 proc
->fn_xmin
= HeapTupleHeaderGetRawXmin(procTup
->t_data
);
182 proc
->fn_tid
= procTup
->t_self
;
183 proc
->fn_readonly
= (procStruct
->provolatile
!= PROVOLATILE_VOLATILE
);
184 proc
->is_setof
= procStruct
->proretset
;
185 proc
->is_procedure
= (procStruct
->prokind
== PROKIND_PROCEDURE
);
187 proc
->argnames
= NULL
;
190 proc
->langid
= procStruct
->prolang
;
191 protrftypes_datum
= SysCacheGetAttr(PROCOID
, procTup
,
192 Anum_pg_proc_protrftypes
,
194 proc
->trftypes
= isnull
? NIL
: oid_array_to_list(protrftypes_datum
);
196 proc
->statics
= NULL
;
197 proc
->globals
= NULL
;
199 proc
->argstack
= NULL
;
202 * get information required for output conversion of the return value,
203 * but only if this isn't a trigger.
207 Oid rettype
= procStruct
->prorettype
;
209 Form_pg_type rvTypeStruct
;
211 rvTypeTup
= SearchSysCache1(TYPEOID
, ObjectIdGetDatum(rettype
));
212 if (!HeapTupleIsValid(rvTypeTup
))
213 elog(ERROR
, "cache lookup failed for type %u", rettype
);
214 rvTypeStruct
= (Form_pg_type
) GETSTRUCT(rvTypeTup
);
216 /* Disallow pseudotype result, except for void or record */
217 if (rvTypeStruct
->typtype
== TYPTYPE_PSEUDO
)
219 if (rettype
== VOIDOID
||
220 rettype
== RECORDOID
)
222 else if (rettype
== TRIGGEROID
|| rettype
== EVENT_TRIGGEROID
)
224 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED
),
225 errmsg("trigger functions can only be called as triggers")));
228 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED
),
229 errmsg("PL/Python functions cannot return type %s",
230 format_type_be(rettype
))));
233 /* set up output function for procedure result */
234 PLy_output_setup_func(&proc
->result
, proc
->mcxt
,
237 ReleaseSysCache(rvTypeTup
);
242 * In a trigger function, we use proc->result and proc->result_in
243 * for converting tuples, but we don't yet have enough info to set
244 * them up. PLy_exec_trigger will deal with it.
246 proc
->result
.typoid
= InvalidOid
;
247 proc
->result_in
.typoid
= InvalidOid
;
251 * Now get information required for input conversion of the
252 * procedure's arguments. Note that we ignore output arguments here.
253 * If the function returns record, those I/O functions will be set up
254 * when the function is first called.
256 if (procStruct
->pronargs
)
264 /* extract argument type info from the pg_proc tuple */
265 total
= get_func_arg_info(procTup
, &types
, &names
, &modes
);
267 /* count number of in+inout args into proc->nargs */
272 /* proc->nargs was initialized to 0 above */
273 for (i
= 0; i
< total
; i
++)
275 if (modes
[i
] != PROARGMODE_OUT
&&
276 modes
[i
] != PROARGMODE_TABLE
)
281 /* Allocate arrays for per-input-argument data */
282 proc
->argnames
= (char **) palloc0(sizeof(char *) * proc
->nargs
);
283 proc
->args
= (PLyDatumToOb
*) palloc0(sizeof(PLyDatumToOb
) * proc
->nargs
);
285 for (i
= pos
= 0; i
< total
; i
++)
287 HeapTuple argTypeTup
;
288 Form_pg_type argTypeStruct
;
291 (modes
[i
] == PROARGMODE_OUT
||
292 modes
[i
] == PROARGMODE_TABLE
))
293 continue; /* skip OUT arguments */
295 Assert(types
[i
] == procStruct
->proargtypes
.values
[pos
]);
297 argTypeTup
= SearchSysCache1(TYPEOID
,
298 ObjectIdGetDatum(types
[i
]));
299 if (!HeapTupleIsValid(argTypeTup
))
300 elog(ERROR
, "cache lookup failed for type %u", types
[i
]);
301 argTypeStruct
= (Form_pg_type
) GETSTRUCT(argTypeTup
);
303 /* disallow pseudotype arguments */
304 if (argTypeStruct
->typtype
== TYPTYPE_PSEUDO
)
306 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED
),
307 errmsg("PL/Python functions cannot accept type %s",
308 format_type_be(types
[i
]))));
310 /* set up I/O function info */
311 PLy_input_setup_func(&proc
->args
[pos
], proc
->mcxt
,
312 types
[i
], -1, /* typmod not known */
315 /* get argument name */
316 proc
->argnames
[pos
] = names
? pstrdup(names
[i
]) : NULL
;
318 ReleaseSysCache(argTypeTup
);
325 * get the text of the function.
327 prosrcdatum
= SysCacheGetAttr(PROCOID
, procTup
,
328 Anum_pg_proc_prosrc
, &isnull
);
330 elog(ERROR
, "null prosrc");
331 procSource
= TextDatumGetCString(prosrcdatum
);
333 PLy_procedure_compile(proc
, procSource
);
339 MemoryContextSwitchTo(oldcxt
);
340 PLy_procedure_delete(proc
);
345 MemoryContextSwitchTo(oldcxt
);
350 * Insert the procedure into the Python interpreter
353 PLy_procedure_compile(PLyProcedure
*proc
, const char *src
)
355 PyObject
*crv
= NULL
;
358 proc
->globals
= PyDict_Copy(PLy_interp_globals
);
361 * SD is private preserved data between calls. GD is global data shared by
364 proc
->statics
= PyDict_New();
366 PLy_elog(ERROR
, NULL
);
367 PyDict_SetItemString(proc
->globals
, "SD", proc
->statics
);
370 * insert the function code into the interpreter
372 msrc
= PLy_procedure_munge_source(proc
->pyname
, src
);
373 /* Save the mangled source for later inclusion in tracebacks */
374 proc
->src
= MemoryContextStrdup(proc
->mcxt
, msrc
);
375 crv
= PyRun_String(msrc
, Py_file_input
, proc
->globals
, NULL
);
381 char call
[NAMEDATALEN
+ 256];
386 * compile a call to the function
388 clen
= snprintf(call
, sizeof(call
), "%s()", proc
->pyname
);
389 if (clen
< 0 || clen
>= sizeof(call
))
390 elog(ERROR
, "string would overflow buffer");
391 proc
->code
= Py_CompileString(call
, "<string>", Py_eval_input
);
392 if (proc
->code
!= NULL
)
397 PLy_elog(ERROR
, "could not compile PL/Python function \"%s\"",
400 PLy_elog(ERROR
, "could not compile anonymous PL/Python code block");
404 PLy_procedure_delete(PLyProcedure
*proc
)
406 Py_XDECREF(proc
->code
);
407 Py_XDECREF(proc
->statics
);
408 Py_XDECREF(proc
->globals
);
409 MemoryContextDelete(proc
->mcxt
);
413 * Decide whether a cached PLyProcedure struct is still valid
416 PLy_procedure_valid(PLyProcedure
*proc
, HeapTuple procTup
)
421 /* If the pg_proc tuple has changed, it's not valid */
422 if (!(proc
->fn_xmin
== HeapTupleHeaderGetRawXmin(procTup
->t_data
) &&
423 ItemPointerEquals(&proc
->fn_tid
, &procTup
->t_self
)))
430 PLy_procedure_munge_source(const char *name
, const char *src
)
439 * room for function source and the def statement
441 mlen
= (strlen(src
) * 2) + strlen(name
) + 16;
444 plen
= snprintf(mrc
, mlen
, "def %s():\n\t", name
);
445 Assert(plen
>= 0 && plen
< mlen
);
452 if (*sp
== '\r' && *(sp
+ 1) == '\n')
455 if (*sp
== '\n' || *sp
== '\r')
468 if (mp
> (mrc
+ mlen
))
469 elog(FATAL
, "buffer overrun in PLy_procedure_munge_source");