* Construct a PLySavedArgs struct representing the current values of the * procedure's arguments in its globals dict. This can be used to restore * those values when exiting a recursive call level or returning control to a * set-returning function. * * This would not be necessary except for an ancient decision to make args * available via the proc's globals :-( ... but we're stuck with that
| 499 | * available via the proc's globals :-( ... but we're stuck with that now. |
| 500 | */ |
| 501 | static PLySavedArgs * |
| 502 | PLy_function_save_args(PLyProcedure *proc) |
| 503 | { |
| 504 | PLySavedArgs *result; |
| 505 | |
| 506 | /* saved args are always allocated in procedure's context */ |
| 507 | result = (PLySavedArgs *) |
| 508 | MemoryContextAllocZero(proc->mcxt, |
| 509 | offsetof(PLySavedArgs, namedargs) + |
| 510 | proc->nargs * sizeof(PyObject *)); |
| 511 | result->nargs = proc->nargs; |
| 512 | |
| 513 | /* Fetch the "args" list */ |
| 514 | result->args = PyDict_GetItemString(proc->globals, "args"); |
| 515 | Py_XINCREF(result->args); |
| 516 | |
| 517 | /* If it's a trigger, also save "TD" */ |
| 518 | if (proc->is_trigger) |
| 519 | { |
| 520 | result->td = PyDict_GetItemString(proc->globals, "TD"); |
| 521 | Py_XINCREF(result->td); |
| 522 | } |
| 523 | |
| 524 | /* Fetch all the named arguments */ |
| 525 | if (proc->argnames) |
| 526 | { |
| 527 | int i; |
| 528 | |
| 529 | for (i = 0; i < result->nargs; i++) |
| 530 | { |
| 531 | if (proc->argnames[i]) |
| 532 | { |
| 533 | result->namedargs[i] = PyDict_GetItemString(proc->globals, |
| 534 | proc->argnames[i]); |
| 535 | Py_XINCREF(result->namedargs[i]); |
| 536 | } |
| 537 | } |
| 538 | } |
| 539 | |
| 540 | return result; |
| 541 | } |
| 542 | |
| 543 | /* |
| 544 | * Restore procedure's arguments from a PLySavedArgs struct, |
no test coverage detected