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