Header And Logo

PostgreSQL
| The world's most advanced open source database.

Functions | Variables

plpy_subxactobject.c File Reference

#include "postgres.h"
#include "access/xact.h"
#include "executor/spi.h"
#include "plpython.h"
#include "plpy_subxactobject.h"
#include "plpy_elog.h"
Include dependency graph for plpy_subxactobject.c:

Go to the source code of this file.

Functions

static void PLy_subtransaction_dealloc (PyObject *subxact)
static PyObject * PLy_subtransaction_enter (PyObject *self, PyObject *unused)
static PyObject * PLy_subtransaction_exit (PyObject *self, PyObject *args)
void PLy_subtransaction_init_type (void)
PyObject * PLy_subtransaction_new (PyObject *self, PyObject *unused)

Variables

Listexplicit_subtransactions = NIL
static char PLy_subtransaction_doc []
static PyMethodDef PLy_subtransaction_methods []
static PyTypeObject PLy_SubtransactionType

Function Documentation

static void PLy_subtransaction_dealloc ( PyObject *  subxact  )  [static]

Definition at line 101 of file plpy_subxactobject.c.

{
}

static PyObject * PLy_subtransaction_enter ( PyObject *  self,
PyObject *  unused 
) [static]

Definition at line 114 of file plpy_subxactobject.c.

References BeginInternalSubTransaction(), CurrentMemoryContext, CurrentResourceOwner, PLySubtransactionObject::exited, lcons(), MemoryContextSwitchTo(), NULL, PLySubtransactionData::oldcontext, PLySubtransactionData::oldowner, PLy_exception_set(), PLy_malloc(), and PLySubtransactionObject::started.

{
    PLySubtransactionData *subxactdata;
    MemoryContext oldcontext;
    PLySubtransactionObject *subxact = (PLySubtransactionObject *) self;

    if (subxact->started)
    {
        PLy_exception_set(PyExc_ValueError, "this subtransaction has already been entered");
        return NULL;
    }

    if (subxact->exited)
    {
        PLy_exception_set(PyExc_ValueError, "this subtransaction has already been exited");
        return NULL;
    }

    subxact->started = true;
    oldcontext = CurrentMemoryContext;

    subxactdata = PLy_malloc(sizeof(*subxactdata));
    subxactdata->oldcontext = oldcontext;
    subxactdata->oldowner = CurrentResourceOwner;

    BeginInternalSubTransaction(NULL);
    /* Do not want to leave the previous memory context */
    MemoryContextSwitchTo(oldcontext);

    explicit_subtransactions = lcons(subxactdata, explicit_subtransactions);

    Py_INCREF(self);
    return self;
}

static PyObject * PLy_subtransaction_exit ( PyObject *  self,
PyObject *  args 
) [static]

Definition at line 161 of file plpy_subxactobject.c.

References CurrentResourceOwner, PLySubtransactionObject::exited, linitial, list_delete_first(), MemoryContextSwitchTo(), NIL, NULL, PLySubtransactionData::oldcontext, PLySubtransactionData::oldowner, PLy_exception_set(), PLy_free(), ReleaseCurrentSubTransaction(), RollbackAndReleaseCurrentSubTransaction(), SPI_restore_connection(), PLySubtransactionObject::started, and value.

{
    PyObject   *type;
    PyObject   *value;
    PyObject   *traceback;
    PLySubtransactionData *subxactdata;
    PLySubtransactionObject *subxact = (PLySubtransactionObject *) self;

    if (!PyArg_ParseTuple(args, "OOO", &type, &value, &traceback))
        return NULL;

    if (!subxact->started)
    {
        PLy_exception_set(PyExc_ValueError, "this subtransaction has not been entered");
        return NULL;
    }

    if (subxact->exited)
    {
        PLy_exception_set(PyExc_ValueError, "this subtransaction has already been exited");
        return NULL;
    }

    if (explicit_subtransactions == NIL)
    {
        PLy_exception_set(PyExc_ValueError, "there is no subtransaction to exit from");
        return NULL;
    }

    subxact->exited = true;

    if (type != Py_None)
    {
        /* Abort the inner transaction */
        RollbackAndReleaseCurrentSubTransaction();
    }
    else
    {
        ReleaseCurrentSubTransaction();
    }

    subxactdata = (PLySubtransactionData *) linitial(explicit_subtransactions);
    explicit_subtransactions = list_delete_first(explicit_subtransactions);

    MemoryContextSwitchTo(subxactdata->oldcontext);
    CurrentResourceOwner = subxactdata->oldowner;
    PLy_free(subxactdata);

    /*
     * AtEOSubXact_SPI() should not have popped any SPI context, but just in
     * case it did, make sure we remain connected.
     */
    SPI_restore_connection();

    Py_INCREF(Py_None);
    return Py_None;
}

void PLy_subtransaction_init_type ( void   ) 

Definition at line 76 of file plpy_subxactobject.c.

References elog, ERROR, and PLy_SubtransactionType.

Referenced by PLy_init_plpy().

{
    if (PyType_Ready(&PLy_SubtransactionType) < 0)
        elog(ERROR, "could not initialize PLy_SubtransactionType");
}

PyObject* PLy_subtransaction_new ( PyObject *  self,
PyObject *  unused 
)

Definition at line 84 of file plpy_subxactobject.c.

References PLySubtransactionObject::exited, NULL, PLy_SubtransactionType, and PLySubtransactionObject::started.

{
    PLySubtransactionObject *ob;

    ob = PyObject_New(PLySubtransactionObject, &PLy_SubtransactionType);

    if (ob == NULL)
        return NULL;

    ob->started = false;
    ob->exited = false;

    return (PyObject *) ob;
}


Variable Documentation

char PLy_subtransaction_doc[] [static]
Initial value:
 {
    "PostgreSQL subtransaction context manager"
}

Definition at line 26 of file plpy_subxactobject.c.

PyMethodDef PLy_subtransaction_methods[] [static]
Initial value:
 {
    {"__enter__", PLy_subtransaction_enter, METH_VARARGS, NULL},
    {"__exit__", PLy_subtransaction_exit, METH_VARARGS, NULL},
    
    {"enter", PLy_subtransaction_enter, METH_VARARGS, NULL},
    {"exit", PLy_subtransaction_exit, METH_VARARGS, NULL},
    {NULL, NULL, 0, NULL}
}

Definition at line 30 of file plpy_subxactobject.c.

PyTypeObject PLy_SubtransactionType [static]

Definition at line 39 of file plpy_subxactobject.c.

Referenced by PLy_subtransaction_init_type(), and PLy_subtransaction_new().