| 259 | #endif /* PY_MAJOR_VERSION < 3 */ |
| 260 | |
| 261 | Datum |
| 262 | plpython_call_handler(PG_FUNCTION_ARGS) |
| 263 | { |
| 264 | bool nonatomic; |
| 265 | Datum retval; |
| 266 | PLyExecutionContext *exec_ctx; |
| 267 | ErrorContextCallback plerrcontext; |
| 268 | |
| 269 | PLy_initialize(); |
| 270 | |
| 271 | nonatomic = fcinfo->context && |
| 272 | IsA(fcinfo->context, CallContext) && |
| 273 | !castNode(CallContext, fcinfo->context)->atomic; |
| 274 | |
| 275 | /* Note: SPI_finish() happens in plpy_exec.c, which is dubious design */ |
| 276 | if (SPI_connect_ext(nonatomic ? SPI_OPT_NONATOMIC : 0) != SPI_OK_CONNECT) |
| 277 | elog(ERROR, "SPI_connect failed"); |
| 278 | |
| 279 | /* |
| 280 | * Push execution context onto stack. It is important that this get |
| 281 | * popped again, so avoid putting anything that could throw error between |
| 282 | * here and the PG_TRY. |
| 283 | */ |
| 284 | exec_ctx = PLy_push_execution_context(!nonatomic); |
| 285 | |
| 286 | PG_TRY(); |
| 287 | { |
| 288 | Oid funcoid = fcinfo->flinfo->fn_oid; |
| 289 | PLyProcedure *proc; |
| 290 | |
| 291 | /* |
| 292 | * Setup error traceback support for ereport(). Note that the PG_TRY |
| 293 | * structure pops this for us again at exit, so we needn't do that |
| 294 | * explicitly, nor do we risk the callback getting called after we've |
| 295 | * destroyed the exec_ctx. |
| 296 | */ |
| 297 | plerrcontext.callback = plpython_error_callback; |
| 298 | plerrcontext.arg = exec_ctx; |
| 299 | plerrcontext.previous = error_context_stack; |
| 300 | error_context_stack = &plerrcontext; |
| 301 | |
| 302 | if (CALLED_AS_TRIGGER(fcinfo)) |
| 303 | { |
| 304 | Relation tgrel = ((TriggerData *) fcinfo->context)->tg_relation; |
| 305 | HeapTuple trv; |
| 306 | |
| 307 | proc = PLy_procedure_get(funcoid, RelationGetRelid(tgrel), true); |
| 308 | exec_ctx->curr_proc = proc; |
| 309 | trv = PLy_exec_trigger(fcinfo, proc); |
| 310 | retval = PointerGetDatum(trv); |
| 311 | } |
| 312 | else |
| 313 | { |
| 314 | proc = PLy_procedure_get(funcoid, InvalidOid, false); |
| 315 | exec_ctx->curr_proc = proc; |
| 316 | retval = PLy_exec_function(fcinfo, proc); |
| 317 | } |
| 318 | } |
no test coverage detected