Line data Source code
1 : /*
2 : * Python procedure manipulation for plpython
3 : *
4 : * src/pl/plpython/plpy_procedure.c
5 : */
6 :
7 : #include "postgres.h"
8 :
9 : #include "access/htup_details.h"
10 : #include "catalog/pg_proc.h"
11 : #include "catalog/pg_type.h"
12 : #include "funcapi.h"
13 : #include "plpy_elog.h"
14 : #include "plpy_main.h"
15 : #include "plpy_procedure.h"
16 : #include "plpy_util.h"
17 : #include "utils/builtins.h"
18 : #include "utils/hsearch.h"
19 : #include "utils/memutils.h"
20 : #include "utils/syscache.h"
21 :
22 : static HTAB *PLy_procedure_cache = NULL;
23 :
24 : static PLyProcedure *PLy_procedure_create(HeapTuple procTup, Oid fn_oid, PLyTrigType is_trigger);
25 : static bool PLy_procedure_valid(PLyProcedure *proc, HeapTuple procTup);
26 : static char *PLy_procedure_munge_source(const char *name, const char *src);
27 :
28 :
29 : void
30 46 : init_procedure_caches(void)
31 : {
32 : HASHCTL hash_ctl;
33 :
34 46 : hash_ctl.keysize = sizeof(PLyProcedureKey);
35 46 : hash_ctl.entrysize = sizeof(PLyProcedureEntry);
36 46 : PLy_procedure_cache = hash_create("PL/Python procedures", 32, &hash_ctl,
37 : HASH_ELEM | HASH_BLOBS);
38 46 : }
39 :
40 : /*
41 : * PLy_procedure_name: get the name of the specified procedure.
42 : *
43 : * NB: this returns the SQL name, not the internal Python procedure name
44 : */
45 : char *
46 1062 : PLy_procedure_name(PLyProcedure *proc)
47 : {
48 1062 : if (proc == NULL)
49 0 : return "<unknown procedure>";
50 1062 : return proc->proname;
51 : }
52 :
53 : /*
54 : * PLy_procedure_get: returns a cached PLyProcedure, or creates, stores and
55 : * returns a new PLyProcedure.
56 : *
57 : * fn_oid is the OID of the function requested
58 : * fn_rel is InvalidOid or the relation this function triggers on
59 : * is_trigger denotes whether the function is a trigger function
60 : *
61 : * The reason that both fn_rel and is_trigger need to be passed is that when
62 : * trigger functions get validated we don't know which relation(s) they'll
63 : * be used with, so no sensible fn_rel can be passed.
64 : */
65 : PLyProcedure *
66 1902 : PLy_procedure_get(Oid fn_oid, Oid fn_rel, PLyTrigType is_trigger)
67 : {
68 : bool use_cache;
69 : HeapTuple procTup;
70 : PLyProcedureKey key;
71 1902 : PLyProcedureEntry *volatile entry = NULL;
72 1902 : PLyProcedure *volatile proc = NULL;
73 1902 : bool found = false;
74 :
75 1902 : if (is_trigger == PLPY_TRIGGER && fn_rel == InvalidOid)
76 48 : use_cache = false;
77 : else
78 1854 : use_cache = true;
79 :
80 1902 : procTup = SearchSysCache1(PROCOID, ObjectIdGetDatum(fn_oid));
81 1902 : if (!HeapTupleIsValid(procTup))
82 0 : elog(ERROR, "cache lookup failed for function %u", fn_oid);
83 :
84 : /*
85 : * Look for the function in the cache, unless we don't have the necessary
86 : * information (e.g. during validation). In that case we just don't cache
87 : * anything.
88 : */
89 1902 : if (use_cache)
90 : {
91 1854 : key.fn_oid = fn_oid;
92 1854 : key.fn_rel = fn_rel;
93 1854 : entry = hash_search(PLy_procedure_cache, &key, HASH_ENTER, &found);
94 1854 : proc = entry->proc;
95 : }
96 :
97 1902 : PG_TRY();
98 : {
99 1902 : if (!found)
100 : {
101 : /* Haven't found it, create a new procedure */
102 548 : proc = PLy_procedure_create(procTup, fn_oid, is_trigger);
103 540 : if (use_cache)
104 492 : entry->proc = proc;
105 : }
106 1354 : else if (!PLy_procedure_valid(proc, procTup))
107 : {
108 : /* Found it, but it's invalid, free and reuse the cache entry */
109 10 : entry->proc = NULL;
110 10 : if (proc)
111 10 : PLy_procedure_delete(proc);
112 10 : proc = PLy_procedure_create(procTup, fn_oid, is_trigger);
113 10 : entry->proc = proc;
114 : }
115 : /* Found it and it's valid, it's fine to use it */
116 : }
117 8 : PG_CATCH();
118 : {
119 : /* Do not leave an uninitialized entry in the cache */
120 8 : if (use_cache)
121 8 : hash_search(PLy_procedure_cache, &key, HASH_REMOVE, NULL);
122 8 : PG_RE_THROW();
123 : }
124 1894 : PG_END_TRY();
125 :
126 1894 : ReleaseSysCache(procTup);
127 :
128 1894 : return proc;
129 : }
130 :
131 : /*
132 : * Create a new PLyProcedure structure
133 : */
134 : static PLyProcedure *
135 558 : PLy_procedure_create(HeapTuple procTup, Oid fn_oid, PLyTrigType is_trigger)
136 : {
137 : char procName[NAMEDATALEN + 256];
138 : Form_pg_proc procStruct;
139 : PLyProcedure *volatile proc;
140 : MemoryContext cxt;
141 : MemoryContext oldcxt;
142 : int rv;
143 : char *ptr;
144 :
145 558 : procStruct = (Form_pg_proc) GETSTRUCT(procTup);
146 1116 : rv = snprintf(procName, sizeof(procName),
147 : "__plpython_procedure_%s_%u",
148 558 : NameStr(procStruct->proname),
149 : fn_oid);
150 558 : if (rv >= sizeof(procName) || rv < 0)
151 0 : elog(ERROR, "procedure name would overrun buffer");
152 :
153 : /* Replace any not-legal-in-Python-names characters with '_' */
154 26134 : for (ptr = procName; *ptr; ptr++)
155 : {
156 25576 : if (!((*ptr >= 'A' && *ptr <= 'Z') ||
157 25574 : (*ptr >= 'a' && *ptr <= 'z') ||
158 6854 : (*ptr >= '0' && *ptr <= '9')))
159 3860 : *ptr = '_';
160 : }
161 :
162 : /* Create long-lived context that all procedure info will live in */
163 558 : cxt = AllocSetContextCreate(TopMemoryContext,
164 : "PL/Python function",
165 : ALLOCSET_DEFAULT_SIZES);
166 :
167 558 : oldcxt = MemoryContextSwitchTo(cxt);
168 :
169 558 : proc = (PLyProcedure *) palloc0(sizeof(PLyProcedure));
170 558 : proc->mcxt = cxt;
171 :
172 558 : PG_TRY();
173 : {
174 : Datum protrftypes_datum;
175 : Datum prosrcdatum;
176 : bool isnull;
177 : char *procSource;
178 : int i;
179 :
180 558 : proc->proname = pstrdup(NameStr(procStruct->proname));
181 558 : MemoryContextSetIdentifier(cxt, proc->proname);
182 558 : proc->pyname = pstrdup(procName);
183 558 : proc->fn_xmin = HeapTupleHeaderGetRawXmin(procTup->t_data);
184 558 : proc->fn_tid = procTup->t_self;
185 558 : proc->fn_readonly = (procStruct->provolatile != PROVOLATILE_VOLATILE);
186 558 : proc->is_setof = procStruct->proretset;
187 558 : proc->is_procedure = (procStruct->prokind == PROKIND_PROCEDURE);
188 558 : proc->is_trigger = is_trigger;
189 558 : proc->src = NULL;
190 558 : proc->argnames = NULL;
191 558 : proc->args = NULL;
192 558 : proc->nargs = 0;
193 558 : proc->langid = procStruct->prolang;
194 558 : protrftypes_datum = SysCacheGetAttr(PROCOID, procTup,
195 : Anum_pg_proc_protrftypes,
196 : &isnull);
197 558 : proc->trftypes = isnull ? NIL : oid_array_to_list(protrftypes_datum);
198 558 : proc->code = NULL;
199 558 : proc->statics = NULL;
200 558 : proc->globals = NULL;
201 558 : proc->calldepth = 0;
202 558 : proc->argstack = NULL;
203 :
204 : /*
205 : * get information required for output conversion of the return value,
206 : * but only if this isn't a trigger.
207 : */
208 558 : if (is_trigger == PLPY_NOT_TRIGGER)
209 : {
210 456 : Oid rettype = procStruct->prorettype;
211 : HeapTuple rvTypeTup;
212 : Form_pg_type rvTypeStruct;
213 :
214 456 : rvTypeTup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(rettype));
215 456 : if (!HeapTupleIsValid(rvTypeTup))
216 0 : elog(ERROR, "cache lookup failed for type %u", rettype);
217 456 : rvTypeStruct = (Form_pg_type) GETSTRUCT(rvTypeTup);
218 :
219 : /* Disallow pseudotype result, except for void or record */
220 456 : if (rvTypeStruct->typtype == TYPTYPE_PSEUDO)
221 : {
222 104 : if (rettype == VOIDOID ||
223 : rettype == RECORDOID)
224 : /* okay */ ;
225 2 : else if (rettype == TRIGGEROID || rettype == EVENT_TRIGGEROID)
226 2 : ereport(ERROR,
227 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
228 : errmsg("trigger functions can only be called as triggers")));
229 : else
230 0 : ereport(ERROR,
231 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
232 : errmsg("PL/Python functions cannot return type %s",
233 : format_type_be(rettype))));
234 : }
235 :
236 : /* set up output function for procedure result */
237 454 : PLy_output_setup_func(&proc->result, proc->mcxt,
238 : rettype, -1, proc);
239 :
240 454 : ReleaseSysCache(rvTypeTup);
241 : }
242 : else
243 : {
244 : /*
245 : * In a trigger function, we use proc->result and proc->result_in
246 : * for converting tuples, but we don't yet have enough info to set
247 : * them up. PLy_exec_trigger will deal with it.
248 : */
249 102 : proc->result.typoid = InvalidOid;
250 102 : proc->result_in.typoid = InvalidOid;
251 : }
252 :
253 : /*
254 : * Now get information required for input conversion of the
255 : * procedure's arguments. Note that we ignore output arguments here.
256 : * If the function returns record, those I/O functions will be set up
257 : * when the function is first called.
258 : */
259 556 : if (procStruct->pronargs)
260 : {
261 : Oid *types;
262 : char **names,
263 : *modes;
264 : int pos,
265 : total;
266 :
267 : /* extract argument type info from the pg_proc tuple */
268 214 : total = get_func_arg_info(procTup, &types, &names, &modes);
269 :
270 : /* count number of in+inout args into proc->nargs */
271 214 : if (modes == NULL)
272 192 : proc->nargs = total;
273 : else
274 : {
275 : /* proc->nargs was initialized to 0 above */
276 82 : for (i = 0; i < total; i++)
277 : {
278 60 : if (modes[i] != PROARGMODE_OUT &&
279 36 : modes[i] != PROARGMODE_TABLE)
280 36 : (proc->nargs)++;
281 : }
282 : }
283 :
284 : /* Allocate arrays for per-input-argument data */
285 214 : proc->argnames = (char **) palloc0(sizeof(char *) * proc->nargs);
286 214 : proc->args = (PLyDatumToOb *) palloc0(sizeof(PLyDatumToOb) * proc->nargs);
287 :
288 554 : for (i = pos = 0; i < total; i++)
289 : {
290 : HeapTuple argTypeTup;
291 : Form_pg_type argTypeStruct;
292 :
293 340 : if (modes &&
294 60 : (modes[i] == PROARGMODE_OUT ||
295 36 : modes[i] == PROARGMODE_TABLE))
296 24 : continue; /* skip OUT arguments */
297 :
298 : Assert(types[i] == procStruct->proargtypes.values[pos]);
299 :
300 316 : argTypeTup = SearchSysCache1(TYPEOID,
301 316 : ObjectIdGetDatum(types[i]));
302 316 : if (!HeapTupleIsValid(argTypeTup))
303 0 : elog(ERROR, "cache lookup failed for type %u", types[i]);
304 316 : argTypeStruct = (Form_pg_type) GETSTRUCT(argTypeTup);
305 :
306 : /* disallow pseudotype arguments */
307 316 : if (argTypeStruct->typtype == TYPTYPE_PSEUDO)
308 0 : ereport(ERROR,
309 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
310 : errmsg("PL/Python functions cannot accept type %s",
311 : format_type_be(types[i]))));
312 :
313 : /* set up I/O function info */
314 316 : PLy_input_setup_func(&proc->args[pos], proc->mcxt,
315 316 : types[i], -1, /* typmod not known */
316 : proc);
317 :
318 : /* get argument name */
319 316 : proc->argnames[pos] = names ? pstrdup(names[i]) : NULL;
320 :
321 316 : ReleaseSysCache(argTypeTup);
322 :
323 316 : pos++;
324 : }
325 : }
326 :
327 : /*
328 : * get the text of the function.
329 : */
330 556 : prosrcdatum = SysCacheGetAttrNotNull(PROCOID, procTup,
331 : Anum_pg_proc_prosrc);
332 556 : procSource = TextDatumGetCString(prosrcdatum);
333 :
334 556 : PLy_procedure_compile(proc, procSource);
335 :
336 550 : pfree(procSource);
337 : }
338 8 : PG_CATCH();
339 : {
340 8 : MemoryContextSwitchTo(oldcxt);
341 8 : PLy_procedure_delete(proc);
342 8 : PG_RE_THROW();
343 : }
344 550 : PG_END_TRY();
345 :
346 550 : MemoryContextSwitchTo(oldcxt);
347 550 : return proc;
348 : }
349 :
350 : /*
351 : * Insert the procedure into the Python interpreter
352 : */
353 : void
354 598 : PLy_procedure_compile(PLyProcedure *proc, const char *src)
355 : {
356 598 : PyObject *crv = NULL;
357 : char *msrc;
358 : PyObject *code0;
359 :
360 598 : proc->globals = PyDict_Copy(PLy_interp_globals);
361 :
362 : /*
363 : * SD is private preserved data between calls. GD is global data shared by
364 : * all functions
365 : */
366 598 : proc->statics = PyDict_New();
367 598 : if (!proc->statics)
368 0 : PLy_elog(ERROR, NULL);
369 598 : PyDict_SetItemString(proc->globals, "SD", proc->statics);
370 :
371 : /*
372 : * insert the function code into the interpreter
373 : */
374 598 : msrc = PLy_procedure_munge_source(proc->pyname, src);
375 : /* Save the mangled source for later inclusion in tracebacks */
376 598 : proc->src = MemoryContextStrdup(proc->mcxt, msrc);
377 598 : code0 = Py_CompileString(msrc, "<string>", Py_file_input);
378 598 : if (code0)
379 592 : crv = PyEval_EvalCode(code0, proc->globals, NULL);
380 598 : pfree(msrc);
381 :
382 598 : if (crv != NULL)
383 : {
384 : int clen;
385 : char call[NAMEDATALEN + 256];
386 :
387 592 : Py_DECREF(crv);
388 :
389 : /*
390 : * compile a call to the function
391 : */
392 592 : clen = snprintf(call, sizeof(call), "%s()", proc->pyname);
393 592 : if (clen < 0 || clen >= sizeof(call))
394 0 : elog(ERROR, "string would overflow buffer");
395 592 : proc->code = Py_CompileString(call, "<string>", Py_eval_input);
396 592 : if (proc->code != NULL)
397 592 : return;
398 : }
399 :
400 6 : if (proc->proname)
401 6 : PLy_elog(ERROR, "could not compile PL/Python function \"%s\"",
402 : proc->proname);
403 : else
404 0 : PLy_elog(ERROR, "could not compile anonymous PL/Python code block");
405 : }
406 :
407 : void
408 60 : PLy_procedure_delete(PLyProcedure *proc)
409 : {
410 60 : Py_XDECREF(proc->code);
411 60 : Py_XDECREF(proc->statics);
412 60 : Py_XDECREF(proc->globals);
413 60 : MemoryContextDelete(proc->mcxt);
414 60 : }
415 :
416 : /*
417 : * Decide whether a cached PLyProcedure struct is still valid
418 : */
419 : static bool
420 1354 : PLy_procedure_valid(PLyProcedure *proc, HeapTuple procTup)
421 : {
422 1354 : if (proc == NULL)
423 0 : return false;
424 :
425 : /* If the pg_proc tuple has changed, it's not valid */
426 2698 : if (!(proc->fn_xmin == HeapTupleHeaderGetRawXmin(procTup->t_data) &&
427 1344 : ItemPointerEquals(&proc->fn_tid, &procTup->t_self)))
428 10 : return false;
429 :
430 1344 : return true;
431 : }
432 :
433 : static char *
434 598 : PLy_procedure_munge_source(const char *name, const char *src)
435 : {
436 : char *mrc,
437 : *mp;
438 : const char *sp;
439 : size_t mlen;
440 : int plen;
441 :
442 : /*
443 : * room for function source and the def statement
444 : */
445 598 : mlen = (strlen(src) * 2) + strlen(name) + 16;
446 :
447 598 : mrc = palloc(mlen);
448 598 : plen = snprintf(mrc, mlen, "def %s():\n\t", name);
449 : Assert(plen >= 0 && plen < mlen);
450 :
451 598 : sp = src;
452 598 : mp = mrc + plen;
453 :
454 64362 : while (*sp != '\0')
455 : {
456 63764 : if (*sp == '\r' && *(sp + 1) == '\n')
457 6 : sp++;
458 :
459 63764 : if (*sp == '\n' || *sp == '\r')
460 : {
461 2692 : *mp++ = '\n';
462 2692 : *mp++ = '\t';
463 2692 : sp++;
464 : }
465 : else
466 61072 : *mp++ = *sp++;
467 : }
468 598 : *mp++ = '\n';
469 598 : *mp++ = '\n';
470 598 : *mp = '\0';
471 :
472 598 : if (mp > (mrc + mlen))
473 0 : elog(FATAL, "buffer overrun in PLy_procedure_munge_source");
474 :
475 598 : return mrc;
476 : }
|