| 544 | } |
| 545 | |
| 546 | PyObject * |
| 547 | PLy_rollback(PyObject *self, PyObject *args) |
| 548 | { |
| 549 | MemoryContext oldcontext = CurrentMemoryContext; |
| 550 | PLyExecutionContext *exec_ctx = PLy_current_execution_context(); |
| 551 | |
| 552 | PG_TRY(); |
| 553 | { |
| 554 | SPI_rollback(); |
| 555 | |
| 556 | /* was cleared at transaction end, reset pointer */ |
| 557 | exec_ctx->scratch_ctx = NULL; |
| 558 | } |
| 559 | PG_CATCH(); |
| 560 | { |
| 561 | ErrorData *edata; |
| 562 | PLyExceptionEntry *entry; |
| 563 | PyObject *exc; |
| 564 | |
| 565 | /* Save error info */ |
| 566 | MemoryContextSwitchTo(oldcontext); |
| 567 | edata = CopyErrorData(); |
| 568 | FlushErrorState(); |
| 569 | |
| 570 | /* was cleared at transaction end, reset pointer */ |
| 571 | exec_ctx->scratch_ctx = NULL; |
| 572 | |
| 573 | /* Look up the correct exception */ |
| 574 | entry = hash_search(PLy_spi_exceptions, &(edata->sqlerrcode), |
| 575 | HASH_FIND, NULL); |
| 576 | |
| 577 | /* |
| 578 | * This could be a custom error code, if that's the case fallback to |
| 579 | * SPIError |
| 580 | */ |
| 581 | exc = entry ? entry->exc : PLy_exc_spi_error; |
| 582 | /* Make Python raise the exception */ |
| 583 | PLy_spi_exception_set(exc, edata); |
| 584 | FreeErrorData(edata); |
| 585 | |
| 586 | return NULL; |
| 587 | } |
| 588 | PG_END_TRY(); |
| 589 | |
| 590 | Py_RETURN_NONE; |
| 591 | } |
| 592 | |
| 593 | /* |
| 594 | * Utilities for running SPI functions in subtransactions. |
nothing calls this directly
no test coverage detected