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