Support for GiST in get_equal_strategy_number()
[pgsql.git] / src / pl / plpython / plpy_main.c
blob8117e20efa23b43d042df4f689235dd664f28a3b
1 /*
2 * PL/Python main entry points
4 * src/pl/plpython/plpy_main.c
5 */
7 #include "postgres.h"
9 #include "access/htup_details.h"
10 #include "catalog/pg_proc.h"
11 #include "catalog/pg_type.h"
12 #include "commands/trigger.h"
13 #include "executor/spi.h"
14 #include "miscadmin.h"
15 #include "plpy_elog.h"
16 #include "plpy_exec.h"
17 #include "plpy_main.h"
18 #include "plpy_plpymodule.h"
19 #include "plpy_procedure.h"
20 #include "plpy_subxactobject.h"
21 #include "plpython.h"
22 #include "utils/guc.h"
23 #include "utils/memutils.h"
24 #include "utils/rel.h"
25 #include "utils/syscache.h"
28 * exported functions
31 PG_MODULE_MAGIC;
33 PG_FUNCTION_INFO_V1(plpython3_validator);
34 PG_FUNCTION_INFO_V1(plpython3_call_handler);
35 PG_FUNCTION_INFO_V1(plpython3_inline_handler);
38 static bool PLy_procedure_is_trigger(Form_pg_proc procStruct);
39 static void plpython_error_callback(void *arg);
40 static void plpython_inline_error_callback(void *arg);
41 static void PLy_init_interp(void);
43 static PLyExecutionContext *PLy_push_execution_context(bool atomic_context);
44 static void PLy_pop_execution_context(void);
46 /* static state for Python library conflict detection */
47 static int *plpython_version_bitmask_ptr = NULL;
48 static int plpython_version_bitmask = 0;
50 /* initialize global variables */
51 PyObject *PLy_interp_globals = NULL;
53 /* this doesn't need to be global; use PLy_current_execution_context() */
54 static PLyExecutionContext *PLy_execution_contexts = NULL;
57 void
58 _PG_init(void)
60 int **bitmask_ptr;
63 * Set up a shared bitmask variable telling which Python version(s) are
64 * loaded into this process's address space. If there's more than one, we
65 * cannot call into libpython for fear of causing crashes. But postpone
66 * the actual failure for later, so that operations like pg_restore can
67 * load more than one plpython library so long as they don't try to do
68 * anything much with the language.
70 * While we only support Python 3 these days, somebody might create an
71 * out-of-tree version adding back support for Python 2. Conflicts with
72 * such an extension should be detected.
74 bitmask_ptr = (int **) find_rendezvous_variable("plpython_version_bitmask");
75 if (!(*bitmask_ptr)) /* am I the first? */
76 *bitmask_ptr = &plpython_version_bitmask;
77 /* Retain pointer to the agreed-on shared variable ... */
78 plpython_version_bitmask_ptr = *bitmask_ptr;
79 /* ... and announce my presence */
80 *plpython_version_bitmask_ptr |= (1 << PY_MAJOR_VERSION);
83 * This should be safe even in the presence of conflicting plpythons, and
84 * it's necessary to do it before possibly throwing a conflict error, or
85 * the error message won't get localized.
87 pg_bindtextdomain(TEXTDOMAIN);
91 * Perform one-time setup of PL/Python, after checking for a conflict
92 * with other versions of Python.
94 static void
95 PLy_initialize(void)
97 static bool inited = false;
100 * Check for multiple Python libraries before actively doing anything with
101 * libpython. This must be repeated on each entry to PL/Python, in case a
102 * conflicting library got loaded since we last looked.
104 * It is attractive to weaken this error from FATAL to ERROR, but there
105 * would be corner cases, so it seems best to be conservative.
107 if (*plpython_version_bitmask_ptr != (1 << PY_MAJOR_VERSION))
108 ereport(FATAL,
109 (errmsg("multiple Python libraries are present in session"),
110 errdetail("Only one Python major version can be used in one session.")));
112 /* The rest should only be done once per session */
113 if (inited)
114 return;
116 PyImport_AppendInittab("plpy", PyInit_plpy);
117 Py_Initialize();
118 PyImport_ImportModule("plpy");
119 PLy_init_interp();
120 PLy_init_plpy();
121 if (PyErr_Occurred())
122 PLy_elog(FATAL, "untrapped error in initialization");
124 init_procedure_caches();
126 explicit_subtransactions = NIL;
128 PLy_execution_contexts = NULL;
130 inited = true;
134 * This should be called only once, from PLy_initialize. Initialize the Python
135 * interpreter and global data.
137 static void
138 PLy_init_interp(void)
140 static PyObject *PLy_interp_safe_globals = NULL;
141 PyObject *mainmod;
143 mainmod = PyImport_AddModule("__main__");
144 if (mainmod == NULL || PyErr_Occurred())
145 PLy_elog(ERROR, "could not import \"__main__\" module");
146 Py_INCREF(mainmod);
147 PLy_interp_globals = PyModule_GetDict(mainmod);
148 PLy_interp_safe_globals = PyDict_New();
149 if (PLy_interp_safe_globals == NULL)
150 PLy_elog(ERROR, NULL);
151 PyDict_SetItemString(PLy_interp_globals, "GD", PLy_interp_safe_globals);
152 Py_DECREF(mainmod);
153 if (PLy_interp_globals == NULL || PyErr_Occurred())
154 PLy_elog(ERROR, "could not initialize globals");
157 Datum
158 plpython3_validator(PG_FUNCTION_ARGS)
160 Oid funcoid = PG_GETARG_OID(0);
161 HeapTuple tuple;
162 Form_pg_proc procStruct;
163 bool is_trigger;
165 if (!CheckFunctionValidatorAccess(fcinfo->flinfo->fn_oid, funcoid))
166 PG_RETURN_VOID();
168 if (!check_function_bodies)
169 PG_RETURN_VOID();
171 /* Do this only after making sure we need to do something */
172 PLy_initialize();
174 /* Get the new function's pg_proc entry */
175 tuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcoid));
176 if (!HeapTupleIsValid(tuple))
177 elog(ERROR, "cache lookup failed for function %u", funcoid);
178 procStruct = (Form_pg_proc) GETSTRUCT(tuple);
180 is_trigger = PLy_procedure_is_trigger(procStruct);
182 ReleaseSysCache(tuple);
184 /* We can't validate triggers against any particular table ... */
185 PLy_procedure_get(funcoid, InvalidOid, is_trigger);
187 PG_RETURN_VOID();
190 Datum
191 plpython3_call_handler(PG_FUNCTION_ARGS)
193 bool nonatomic;
194 Datum retval;
195 PLyExecutionContext *exec_ctx;
196 ErrorContextCallback plerrcontext;
198 PLy_initialize();
200 nonatomic = fcinfo->context &&
201 IsA(fcinfo->context, CallContext) &&
202 !castNode(CallContext, fcinfo->context)->atomic;
204 /* Note: SPI_finish() happens in plpy_exec.c, which is dubious design */
205 SPI_connect_ext(nonatomic ? SPI_OPT_NONATOMIC : 0);
208 * Push execution context onto stack. It is important that this get
209 * popped again, so avoid putting anything that could throw error between
210 * here and the PG_TRY.
212 exec_ctx = PLy_push_execution_context(!nonatomic);
214 PG_TRY();
216 Oid funcoid = fcinfo->flinfo->fn_oid;
217 PLyProcedure *proc;
220 * Setup error traceback support for ereport(). Note that the PG_TRY
221 * structure pops this for us again at exit, so we needn't do that
222 * explicitly, nor do we risk the callback getting called after we've
223 * destroyed the exec_ctx.
225 plerrcontext.callback = plpython_error_callback;
226 plerrcontext.arg = exec_ctx;
227 plerrcontext.previous = error_context_stack;
228 error_context_stack = &plerrcontext;
230 if (CALLED_AS_TRIGGER(fcinfo))
232 Relation tgrel = ((TriggerData *) fcinfo->context)->tg_relation;
233 HeapTuple trv;
235 proc = PLy_procedure_get(funcoid, RelationGetRelid(tgrel), true);
236 exec_ctx->curr_proc = proc;
237 trv = PLy_exec_trigger(fcinfo, proc);
238 retval = PointerGetDatum(trv);
240 else
242 proc = PLy_procedure_get(funcoid, InvalidOid, false);
243 exec_ctx->curr_proc = proc;
244 retval = PLy_exec_function(fcinfo, proc);
247 PG_CATCH();
249 PLy_pop_execution_context();
250 PyErr_Clear();
251 PG_RE_THROW();
253 PG_END_TRY();
255 /* Destroy the execution context */
256 PLy_pop_execution_context();
258 return retval;
261 Datum
262 plpython3_inline_handler(PG_FUNCTION_ARGS)
264 LOCAL_FCINFO(fake_fcinfo, 0);
265 InlineCodeBlock *codeblock = (InlineCodeBlock *) DatumGetPointer(PG_GETARG_DATUM(0));
266 FmgrInfo flinfo;
267 PLyProcedure proc;
268 PLyExecutionContext *exec_ctx;
269 ErrorContextCallback plerrcontext;
271 PLy_initialize();
273 /* Note: SPI_finish() happens in plpy_exec.c, which is dubious design */
274 SPI_connect_ext(codeblock->atomic ? 0 : SPI_OPT_NONATOMIC);
276 MemSet(fcinfo, 0, SizeForFunctionCallInfo(0));
277 MemSet(&flinfo, 0, sizeof(flinfo));
278 fake_fcinfo->flinfo = &flinfo;
279 flinfo.fn_oid = InvalidOid;
280 flinfo.fn_mcxt = CurrentMemoryContext;
282 MemSet(&proc, 0, sizeof(PLyProcedure));
283 proc.mcxt = AllocSetContextCreate(TopMemoryContext,
284 "__plpython_inline_block",
285 ALLOCSET_DEFAULT_SIZES);
286 proc.pyname = MemoryContextStrdup(proc.mcxt, "__plpython_inline_block");
287 proc.langid = codeblock->langOid;
290 * This is currently sufficient to get PLy_exec_function to work, but
291 * someday we might need to be honest and use PLy_output_setup_func.
293 proc.result.typoid = VOIDOID;
296 * Push execution context onto stack. It is important that this get
297 * popped again, so avoid putting anything that could throw error between
298 * here and the PG_TRY.
300 exec_ctx = PLy_push_execution_context(codeblock->atomic);
302 PG_TRY();
305 * Setup error traceback support for ereport().
306 * plpython_inline_error_callback doesn't currently need exec_ctx, but
307 * for consistency with plpython3_call_handler we do it the same way.
309 plerrcontext.callback = plpython_inline_error_callback;
310 plerrcontext.arg = exec_ctx;
311 plerrcontext.previous = error_context_stack;
312 error_context_stack = &plerrcontext;
314 PLy_procedure_compile(&proc, codeblock->source_text);
315 exec_ctx->curr_proc = &proc;
316 PLy_exec_function(fake_fcinfo, &proc);
318 PG_CATCH();
320 PLy_pop_execution_context();
321 PLy_procedure_delete(&proc);
322 PyErr_Clear();
323 PG_RE_THROW();
325 PG_END_TRY();
327 /* Destroy the execution context */
328 PLy_pop_execution_context();
330 /* Now clean up the transient procedure we made */
331 PLy_procedure_delete(&proc);
333 PG_RETURN_VOID();
336 static bool
337 PLy_procedure_is_trigger(Form_pg_proc procStruct)
339 return (procStruct->prorettype == TRIGGEROID);
342 static void
343 plpython_error_callback(void *arg)
345 PLyExecutionContext *exec_ctx = (PLyExecutionContext *) arg;
347 if (exec_ctx->curr_proc)
349 if (exec_ctx->curr_proc->is_procedure)
350 errcontext("PL/Python procedure \"%s\"",
351 PLy_procedure_name(exec_ctx->curr_proc));
352 else
353 errcontext("PL/Python function \"%s\"",
354 PLy_procedure_name(exec_ctx->curr_proc));
358 static void
359 plpython_inline_error_callback(void *arg)
361 errcontext("PL/Python anonymous code block");
364 PLyExecutionContext *
365 PLy_current_execution_context(void)
367 if (PLy_execution_contexts == NULL)
368 elog(ERROR, "no Python function is currently executing");
370 return PLy_execution_contexts;
373 MemoryContext
374 PLy_get_scratch_context(PLyExecutionContext *context)
377 * A scratch context might never be needed in a given plpython procedure,
378 * so allocate it on first request.
380 if (context->scratch_ctx == NULL)
381 context->scratch_ctx =
382 AllocSetContextCreate(TopTransactionContext,
383 "PL/Python scratch context",
384 ALLOCSET_DEFAULT_SIZES);
385 return context->scratch_ctx;
388 static PLyExecutionContext *
389 PLy_push_execution_context(bool atomic_context)
391 PLyExecutionContext *context;
393 /* Pick a memory context similar to what SPI uses. */
394 context = (PLyExecutionContext *)
395 MemoryContextAlloc(atomic_context ? TopTransactionContext : PortalContext,
396 sizeof(PLyExecutionContext));
397 context->curr_proc = NULL;
398 context->scratch_ctx = NULL;
399 context->next = PLy_execution_contexts;
400 PLy_execution_contexts = context;
401 return context;
404 static void
405 PLy_pop_execution_context(void)
407 PLyExecutionContext *context = PLy_execution_contexts;
409 if (context == NULL)
410 elog(ERROR, "no Python function is currently executing");
412 PLy_execution_contexts = context->next;
414 if (context->scratch_ctx)
415 MemoryContextDelete(context->scratch_ctx);
416 pfree(context);