Consistently use "superuser" instead of "super user"
[pgsql.git] / src / pl / plpython / plpy_procedure.c
blob494f109b3232004583dfecf74b4c34614155ebf6
1 /*
2 * Python procedure manipulation for plpython
4 * src/pl/plpython/plpy_procedure.c
5 */
7 #include "postgres.h"
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"
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);
32 void
33 init_procedure_caches(void)
35 HASHCTL hash_ctl;
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
48 char *
49 PLy_procedure_name(PLyProcedure *proc)
51 if (proc == NULL)
52 return "<unknown procedure>";
53 return proc->proname;
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.
68 PLyProcedure *
69 PLy_procedure_get(Oid fn_oid, Oid fn_rel, bool is_trigger)
71 bool use_cache = !(is_trigger && fn_rel == InvalidOid);
72 HeapTuple procTup;
73 PLyProcedureKey key;
74 PLyProcedureEntry *volatile entry = NULL;
75 PLyProcedure *volatile proc = NULL;
76 bool found = false;
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
85 * anything.
87 if (use_cache)
89 key.fn_oid = fn_oid;
90 key.fn_rel = fn_rel;
91 entry = hash_search(PLy_procedure_cache, &key, HASH_ENTER, &found);
92 proc = entry->proc;
95 PG_TRY();
97 if (!found)
99 /* Haven't found it, create a new procedure */
100 proc = PLy_procedure_create(procTup, fn_oid, is_trigger);
101 if (use_cache)
102 entry->proc = proc;
104 else if (!PLy_procedure_valid(proc, procTup))
106 /* Found it, but it's invalid, free and reuse the cache entry */
107 entry->proc = NULL;
108 if (proc)
109 PLy_procedure_delete(proc);
110 proc = PLy_procedure_create(procTup, fn_oid, is_trigger);
111 entry->proc = proc;
113 /* Found it and it's valid, it's fine to use it */
115 PG_CATCH();
117 /* Do not leave an uninitialized entry in the cache */
118 if (use_cache)
119 hash_search(PLy_procedure_cache, &key, HASH_REMOVE, NULL);
120 PG_RE_THROW();
122 PG_END_TRY();
124 ReleaseSysCache(procTup);
126 return proc;
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;
138 MemoryContext cxt;
139 MemoryContext oldcxt;
140 int rv;
141 char *ptr;
143 procStruct = (Form_pg_proc) GETSTRUCT(procTup);
144 rv = snprintf(procName, sizeof(procName),
145 "__plpython_procedure_%s_%u",
146 NameStr(procStruct->proname),
147 fn_oid);
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')))
157 *ptr = '_';
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));
168 proc->mcxt = cxt;
170 PG_TRY();
172 Datum protrftypes_datum;
173 Datum prosrcdatum;
174 bool isnull;
175 char *procSource;
176 int i;
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);
186 proc->src = NULL;
187 proc->argnames = NULL;
188 proc->args = NULL;
189 proc->nargs = 0;
190 proc->langid = procStruct->prolang;
191 protrftypes_datum = SysCacheGetAttr(PROCOID, procTup,
192 Anum_pg_proc_protrftypes,
193 &isnull);
194 proc->trftypes = isnull ? NIL : oid_array_to_list(protrftypes_datum);
195 proc->code = NULL;
196 proc->statics = NULL;
197 proc->globals = NULL;
198 proc->calldepth = 0;
199 proc->argstack = NULL;
202 * get information required for output conversion of the return value,
203 * but only if this isn't a trigger.
205 if (!is_trigger)
207 Oid rettype = procStruct->prorettype;
208 HeapTuple rvTypeTup;
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)
221 /* okay */ ;
222 else if (rettype == TRIGGEROID || rettype == EVENT_TRIGGEROID)
223 ereport(ERROR,
224 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
225 errmsg("trigger functions can only be called as triggers")));
226 else
227 ereport(ERROR,
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,
235 rettype, -1, proc);
237 ReleaseSysCache(rvTypeTup);
239 else
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)
258 Oid *types;
259 char **names,
260 *modes;
261 int pos,
262 total;
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 */
268 if (modes == NULL)
269 proc->nargs = total;
270 else
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)
277 (proc->nargs)++;
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;
290 if (modes &&
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)
305 ereport(ERROR,
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 */
313 proc);
315 /* get argument name */
316 proc->argnames[pos] = names ? pstrdup(names[i]) : NULL;
318 ReleaseSysCache(argTypeTup);
320 pos++;
325 * get the text of the function.
327 prosrcdatum = SysCacheGetAttr(PROCOID, procTup,
328 Anum_pg_proc_prosrc, &isnull);
329 if (isnull)
330 elog(ERROR, "null prosrc");
331 procSource = TextDatumGetCString(prosrcdatum);
333 PLy_procedure_compile(proc, procSource);
335 pfree(procSource);
337 PG_CATCH();
339 MemoryContextSwitchTo(oldcxt);
340 PLy_procedure_delete(proc);
341 PG_RE_THROW();
343 PG_END_TRY();
345 MemoryContextSwitchTo(oldcxt);
346 return proc;
350 * Insert the procedure into the Python interpreter
352 void
353 PLy_procedure_compile(PLyProcedure *proc, const char *src)
355 PyObject *crv = NULL;
356 char *msrc;
358 proc->globals = PyDict_Copy(PLy_interp_globals);
361 * SD is private preserved data between calls. GD is global data shared by
362 * all functions
364 proc->statics = PyDict_New();
365 if (!proc->statics)
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);
376 pfree(msrc);
378 if (crv != NULL)
380 int clen;
381 char call[NAMEDATALEN + 256];
383 Py_DECREF(crv);
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)
393 return;
396 if (proc->proname)
397 PLy_elog(ERROR, "could not compile PL/Python function \"%s\"",
398 proc->proname);
399 else
400 PLy_elog(ERROR, "could not compile anonymous PL/Python code block");
403 void
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
415 static bool
416 PLy_procedure_valid(PLyProcedure *proc, HeapTuple procTup)
418 if (proc == NULL)
419 return false;
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)))
424 return false;
426 return true;
429 static char *
430 PLy_procedure_munge_source(const char *name, const char *src)
432 char *mrc,
433 *mp;
434 const char *sp;
435 size_t mlen;
436 int plen;
439 * room for function source and the def statement
441 mlen = (strlen(src) * 2) + strlen(name) + 16;
443 mrc = palloc(mlen);
444 plen = snprintf(mrc, mlen, "def %s():\n\t", name);
445 Assert(plen >= 0 && plen < mlen);
447 sp = src;
448 mp = mrc + plen;
450 while (*sp != '\0')
452 if (*sp == '\r' && *(sp + 1) == '\n')
453 sp++;
455 if (*sp == '\n' || *sp == '\r')
457 *mp++ = '\n';
458 *mp++ = '\t';
459 sp++;
461 else
462 *mp++ = *sp++;
464 *mp++ = '\n';
465 *mp++ = '\n';
466 *mp = '\0';
468 if (mp > (mrc + mlen))
469 elog(FATAL, "buffer overrun in PLy_procedure_munge_source");
471 return mrc;