| 436 | /* helper functions for Python code execution */ |
| 437 | |
| 438 | static PyObject * |
| 439 | PLy_function_build_args(FunctionCallInfo fcinfo, PLyProcedure *proc) |
| 440 | { |
| 441 | PyObject *volatile arg = NULL; |
| 442 | PyObject *args; |
| 443 | int i; |
| 444 | |
| 445 | /* |
| 446 | * Make any Py*_New() calls before the PG_TRY block so that we can quickly |
| 447 | * return NULL on failure. We can't return within the PG_TRY block, else |
| 448 | * we'd miss unwinding the exception stack. |
| 449 | */ |
| 450 | args = PyList_New(proc->nargs); |
| 451 | if (!args) |
| 452 | return NULL; |
| 453 | |
| 454 | PG_TRY(); |
| 455 | { |
| 456 | for (i = 0; i < proc->nargs; i++) |
| 457 | { |
| 458 | PLyDatumToOb *arginfo = &proc->args[i]; |
| 459 | |
| 460 | if (fcinfo->args[i].isnull) |
| 461 | arg = NULL; |
| 462 | else |
| 463 | arg = PLy_input_convert(arginfo, fcinfo->args[i].value); |
| 464 | |
| 465 | if (arg == NULL) |
| 466 | { |
| 467 | Py_INCREF(Py_None); |
| 468 | arg = Py_None; |
| 469 | } |
| 470 | |
| 471 | if (PyList_SetItem(args, i, arg) == -1) |
| 472 | PLy_elog(ERROR, "PyList_SetItem() failed, while setting up arguments"); |
| 473 | |
| 474 | if (proc->argnames && proc->argnames[i] && |
| 475 | PyDict_SetItemString(proc->globals, proc->argnames[i], arg) == -1) |
| 476 | PLy_elog(ERROR, "PyDict_SetItemString() failed, while setting up arguments"); |
| 477 | arg = NULL; |
| 478 | } |
| 479 | } |
| 480 | PG_CATCH(); |
| 481 | { |
| 482 | Py_XDECREF(arg); |
| 483 | Py_XDECREF(args); |
| 484 | |
| 485 | PG_RE_THROW(); |
| 486 | } |
| 487 | PG_END_TRY(); |
| 488 | |
| 489 | return args; |
| 490 | } |
| 491 | |
| 492 | /* |
| 493 | * Construct a PLySavedArgs struct representing the current values of the |
no test coverage detected