#include "utils/memutils.h"
static PyObject *PLy_cursor_query(const char *query);
-static void PLy_cursor_dealloc(PyObject *arg);
+static void PLy_cursor_dealloc(PLyCursorObject *self);
static PyObject *PLy_cursor_iternext(PyObject *self);
static PyObject *PLy_cursor_fetch(PyObject *self, PyObject *args);
static PyObject *PLy_cursor_close(PyObject *self, PyObject *unused);
{NULL, NULL, 0, NULL}
};
-static PyTypeObject PLy_CursorType = {
- PyVarObject_HEAD_INIT(NULL, 0)
- .tp_name = "PLyCursor",
- .tp_basicsize = sizeof(PLyCursorObject),
- .tp_dealloc = PLy_cursor_dealloc,
- .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
- .tp_doc = PLy_cursor_doc,
- .tp_iter = PyObject_SelfIter,
- .tp_iternext = PLy_cursor_iternext,
- .tp_methods = PLy_cursor_methods,
+static PyType_Slot PLyCursor_slots[] =
+{
+ {
+ Py_tp_dealloc, PLy_cursor_dealloc
+ },
+ {
+ Py_tp_doc, (char *) PLy_cursor_doc
+ },
+ {
+ Py_tp_iter, PyObject_SelfIter
+ },
+ {
+ Py_tp_iternext, PLy_cursor_iternext
+ },
+ {
+ Py_tp_methods, PLy_cursor_methods
+ },
+ {
+ 0, NULL
+ }
};
+static PyType_Spec PLyCursor_spec =
+{
+ .name = "PLyCursor",
+ .basicsize = sizeof(PLyCursorObject),
+ .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ .slots = PLyCursor_slots,
+};
+
+static PyTypeObject *PLy_CursorType;
+
void
PLy_cursor_init_type(void)
{
- if (PyType_Ready(&PLy_CursorType) < 0)
+ PLy_CursorType = (PyTypeObject *) PyType_FromSpec(&PLyCursor_spec);
+ if (!PLy_CursorType)
elog(ERROR, "could not initialize PLy_CursorType");
}
volatile MemoryContext oldcontext;
volatile ResourceOwner oldowner;
- if ((cursor = PyObject_New(PLyCursorObject, &PLy_CursorType)) == NULL)
+ if ((cursor = PyObject_New(PLyCursorObject, PLy_CursorType)) == NULL)
return NULL;
+#if PY_VERSION_HEX < 0x03080000
+ /* Workaround for Python issue 35810; no longer necessary in Python 3.8 */
+ Py_INCREF(PLy_CursorType);
+#endif
cursor->portalname = NULL;
cursor->closed = false;
cursor->mcxt = AllocSetContextCreate(TopMemoryContext,
return NULL;
}
- if ((cursor = PyObject_New(PLyCursorObject, &PLy_CursorType)) == NULL)
+ if ((cursor = PyObject_New(PLyCursorObject, PLy_CursorType)) == NULL)
return NULL;
+#if PY_VERSION_HEX < 0x03080000
+ /* Workaround for Python issue 35810; no longer necessary in Python 3.8 */
+ Py_INCREF(PLy_CursorType);
+#endif
cursor->portalname = NULL;
cursor->closed = false;
cursor->mcxt = AllocSetContextCreate(TopMemoryContext,
}
static void
-PLy_cursor_dealloc(PyObject *arg)
+PLy_cursor_dealloc(PLyCursorObject *self)
{
- PLyCursorObject *cursor;
+#if PY_VERSION_HEX >= 0x03080000
+ PyTypeObject *tp = Py_TYPE(self);
+#endif
Portal portal;
- cursor = (PLyCursorObject *) arg;
-
- if (!cursor->closed)
+ if (!self->closed)
{
- portal = GetPortalByName(cursor->portalname);
+ portal = GetPortalByName(self->portalname);
if (PortalIsValid(portal))
{
UnpinPortal(portal);
SPI_cursor_close(portal);
}
- cursor->closed = true;
+ self->closed = true;
}
- if (cursor->mcxt)
+ if (self->mcxt)
{
- MemoryContextDelete(cursor->mcxt);
- cursor->mcxt = NULL;
+ MemoryContextDelete(self->mcxt);
+ self->mcxt = NULL;
}
- arg->ob_type->tp_free(arg);
+
+ PyObject_Free(self);
+#if PY_VERSION_HEX >= 0x03080000
+ /* This was not needed before Python 3.8 (Python issue 35810) */
+ Py_DECREF(tp);
+#endif
}
static PyObject *
#include "plpython.h"
#include "utils/memutils.h"
-static void PLy_plan_dealloc(PyObject *arg);
+static void PLy_plan_dealloc(PLyPlanObject *self);
static PyObject *PLy_plan_cursor(PyObject *self, PyObject *args);
static PyObject *PLy_plan_execute(PyObject *self, PyObject *args);
static PyObject *PLy_plan_status(PyObject *self, PyObject *args);
{NULL, NULL, 0, NULL}
};
-static PyTypeObject PLy_PlanType = {
- PyVarObject_HEAD_INIT(NULL, 0)
- .tp_name = "PLyPlan",
- .tp_basicsize = sizeof(PLyPlanObject),
- .tp_dealloc = PLy_plan_dealloc,
- .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
- .tp_doc = PLy_plan_doc,
- .tp_methods = PLy_plan_methods,
+static PyType_Slot PLyPlan_slots[] =
+{
+ {
+ Py_tp_dealloc, PLy_plan_dealloc
+ },
+ {
+ Py_tp_doc, (char *) PLy_plan_doc
+ },
+ {
+ Py_tp_methods, PLy_plan_methods
+ },
+ {
+ 0, NULL
+ }
};
+static PyType_Spec PLyPlan_spec =
+{
+ .name = "PLyPlan",
+ .basicsize = sizeof(PLyPlanObject),
+ .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ .slots = PLyPlan_slots,
+};
+
+static PyTypeObject *PLy_PlanType;
+
void
PLy_plan_init_type(void)
{
- if (PyType_Ready(&PLy_PlanType) < 0)
+ PLy_PlanType = (PyTypeObject *) PyType_FromSpec(&PLyPlan_spec);
+ if (!PLy_PlanType)
elog(ERROR, "could not initialize PLy_PlanType");
}
{
PLyPlanObject *ob;
- if ((ob = PyObject_New(PLyPlanObject, &PLy_PlanType)) == NULL)
+ if ((ob = PyObject_New(PLyPlanObject, PLy_PlanType)) == NULL)
return NULL;
+#if PY_VERSION_HEX < 0x03080000
+ /* Workaround for Python issue 35810; no longer necessary in Python 3.8 */
+ Py_INCREF(PLy_PlanType);
+#endif
ob->plan = NULL;
ob->nargs = 0;
bool
is_PLyPlanObject(PyObject *ob)
{
- return ob->ob_type == &PLy_PlanType;
+ return ob->ob_type == PLy_PlanType;
}
static void
-PLy_plan_dealloc(PyObject *arg)
+PLy_plan_dealloc(PLyPlanObject *self)
{
- PLyPlanObject *ob = (PLyPlanObject *) arg;
+#if PY_VERSION_HEX >= 0x03080000
+ PyTypeObject *tp = Py_TYPE(self);
+#endif
- if (ob->plan)
+ if (self->plan)
{
- SPI_freeplan(ob->plan);
- ob->plan = NULL;
+ SPI_freeplan(self->plan);
+ self->plan = NULL;
}
- if (ob->mcxt)
+ if (self->mcxt)
{
- MemoryContextDelete(ob->mcxt);
- ob->mcxt = NULL;
+ MemoryContextDelete(self->mcxt);
+ self->mcxt = NULL;
}
- arg->ob_type->tp_free(arg);
+
+ PyObject_Free(self);
+#if PY_VERSION_HEX >= 0x03080000
+ /* This was not needed before Python 3.8 (Python issue 35810) */
+ Py_DECREF(tp);
+#endif
}
{
PyObject *crv = NULL;
char *msrc;
+ PyObject *code0;
proc->globals = PyDict_Copy(PLy_interp_globals);
msrc = PLy_procedure_munge_source(proc->pyname, src);
/* Save the mangled source for later inclusion in tracebacks */
proc->src = MemoryContextStrdup(proc->mcxt, msrc);
- crv = PyRun_String(msrc, Py_file_input, proc->globals, NULL);
+ code0 = Py_CompileString(msrc, "<string>", Py_file_input);
+ if (code0)
+ crv = PyEval_EvalCode(code0, proc->globals, NULL);
pfree(msrc);
if (crv != NULL)
#include "plpy_resultobject.h"
#include "plpython.h"
-static void PLy_result_dealloc(PyObject *arg);
+static void PLy_result_dealloc(PLyResultObject *self);
static PyObject *PLy_result_colnames(PyObject *self, PyObject *unused);
static PyObject *PLy_result_coltypes(PyObject *self, PyObject *unused);
static PyObject *PLy_result_coltypmods(PyObject *self, PyObject *unused);
static char PLy_result_doc[] = "Results of a PostgreSQL query";
-static PySequenceMethods PLy_result_as_sequence = {
- .sq_length = PLy_result_length,
- .sq_item = PLy_result_item,
-};
-
-static PyMappingMethods PLy_result_as_mapping = {
- .mp_length = PLy_result_length,
- .mp_subscript = PLy_result_subscript,
- .mp_ass_subscript = PLy_result_ass_subscript,
-};
-
static PyMethodDef PLy_result_methods[] = {
{"colnames", PLy_result_colnames, METH_NOARGS, NULL},
{"coltypes", PLy_result_coltypes, METH_NOARGS, NULL},
{NULL, NULL, 0, NULL}
};
-static PyTypeObject PLy_ResultType = {
- PyVarObject_HEAD_INIT(NULL, 0)
- .tp_name = "PLyResult",
- .tp_basicsize = sizeof(PLyResultObject),
- .tp_dealloc = PLy_result_dealloc,
- .tp_as_sequence = &PLy_result_as_sequence,
- .tp_as_mapping = &PLy_result_as_mapping,
- .tp_str = &PLy_result_str,
- .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
- .tp_doc = PLy_result_doc,
- .tp_methods = PLy_result_methods,
+static PyType_Slot PLyResult_slots[] =
+{
+ {
+ Py_tp_dealloc, PLy_result_dealloc
+ },
+ {
+ Py_sq_length, PLy_result_length
+ },
+ {
+ Py_sq_item, PLy_result_item
+ },
+ {
+ Py_mp_length, PLy_result_length
+ },
+ {
+ Py_mp_subscript, PLy_result_subscript
+ },
+ {
+ Py_mp_ass_subscript, PLy_result_ass_subscript
+ },
+ {
+ Py_tp_str, PLy_result_str
+ },
+ {
+ Py_tp_doc, (char *) PLy_result_doc
+ },
+ {
+ Py_tp_methods, PLy_result_methods
+ },
+ {
+ 0, NULL
+ }
+};
+
+static PyType_Spec PLyResult_spec =
+{
+ .name = "PLyResult",
+ .basicsize = sizeof(PLyResultObject),
+ .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ .slots = PLyResult_slots,
};
+static PyTypeObject *PLy_ResultType;
+
void
PLy_result_init_type(void)
{
- if (PyType_Ready(&PLy_ResultType) < 0)
+ PLy_ResultType = (PyTypeObject *) PyType_FromSpec(&PLyResult_spec);
+ if (!PLy_ResultType)
elog(ERROR, "could not initialize PLy_ResultType");
}
{
PLyResultObject *ob;
- if ((ob = PyObject_New(PLyResultObject, &PLy_ResultType)) == NULL)
+ if ((ob = PyObject_New(PLyResultObject, PLy_ResultType)) == NULL)
return NULL;
+#if PY_VERSION_HEX < 0x03080000
+ /* Workaround for Python issue 35810; no longer necessary in Python 3.8 */
+ Py_INCREF(PLy_ResultType);
+#endif
/* ob->tuples = NULL; */
}
static void
-PLy_result_dealloc(PyObject *arg)
+PLy_result_dealloc(PLyResultObject *self)
{
- PLyResultObject *ob = (PLyResultObject *) arg;
-
- Py_XDECREF(ob->nrows);
- Py_XDECREF(ob->rows);
- Py_XDECREF(ob->status);
- if (ob->tupdesc)
+#if PY_VERSION_HEX >= 0x03080000
+ PyTypeObject *tp = Py_TYPE(self);
+#endif
+
+ Py_XDECREF(self->nrows);
+ Py_XDECREF(self->rows);
+ Py_XDECREF(self->status);
+ if (self->tupdesc)
{
- FreeTupleDesc(ob->tupdesc);
- ob->tupdesc = NULL;
+ FreeTupleDesc(self->tupdesc);
+ self->tupdesc = NULL;
}
- arg->ob_type->tp_free(arg);
+ PyObject_Free(self);
+#if PY_VERSION_HEX >= 0x03080000
+ /* This was not needed before Python 3.8 (Python issue 35810) */
+ Py_DECREF(tp);
+#endif
}
static PyObject *
{
Form_pg_attribute attr = TupleDescAttr(ob->tupdesc, i);
- PyList_SET_ITEM(list, i, PLyUnicode_FromString(NameStr(attr->attname)));
+ PyList_SetItem(list, i, PLyUnicode_FromString(NameStr(attr->attname)));
}
return list;
{
Form_pg_attribute attr = TupleDescAttr(ob->tupdesc, i);
- PyList_SET_ITEM(list, i, PyLong_FromLong(attr->atttypid));
+ PyList_SetItem(list, i, PyLong_FromLong(attr->atttypid));
}
return list;
{
Form_pg_attribute attr = TupleDescAttr(ob->tupdesc, i);
- PyList_SET_ITEM(list, i, PyLong_FromLong(attr->atttypmod));
+ PyList_SetItem(list, i, PyLong_FromLong(attr->atttypmod));
}
return list;
PLyResultObject *ob = (PLyResultObject *) arg;
return PyUnicode_FromFormat("<%s status=%S nrows=%S rows=%S>",
- Py_TYPE(ob)->tp_name,
+ "PLyResult",
ob->status,
ob->nrows,
ob->rows);
List *explicit_subtransactions = NIL;
-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);
{NULL, NULL, 0, NULL}
};
-static PyTypeObject PLy_SubtransactionType = {
- PyVarObject_HEAD_INIT(NULL, 0)
- .tp_name = "PLySubtransaction",
- .tp_basicsize = sizeof(PLySubtransactionObject),
- .tp_dealloc = PLy_subtransaction_dealloc,
- .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
- .tp_doc = PLy_subtransaction_doc,
- .tp_methods = PLy_subtransaction_methods,
+static PyType_Slot PLySubtransaction_slots[] =
+{
+ {
+ Py_tp_doc, (char *) PLy_subtransaction_doc
+ },
+ {
+ Py_tp_methods, PLy_subtransaction_methods
+ },
+ {
+ 0, NULL
+ }
};
+static PyType_Spec PLySubtransaction_spec =
+{
+ .name = "PLySubtransaction",
+ .basicsize = sizeof(PLySubtransactionObject),
+ .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ .slots = PLySubtransaction_slots,
+};
+
+static PyTypeObject *PLy_SubtransactionType;
+
void
PLy_subtransaction_init_type(void)
{
- if (PyType_Ready(&PLy_SubtransactionType) < 0)
+ PLy_SubtransactionType = (PyTypeObject *) PyType_FromSpec(&PLySubtransaction_spec);
+ if (!PLy_SubtransactionType)
elog(ERROR, "could not initialize PLy_SubtransactionType");
}
{
PLySubtransactionObject *ob;
- ob = PyObject_New(PLySubtransactionObject, &PLy_SubtransactionType);
-
+ ob = PyObject_New(PLySubtransactionObject, PLy_SubtransactionType);
if (ob == NULL)
return NULL;
+#if PY_VERSION_HEX < 0x03080000
+ /* Workaround for Python issue 35810; no longer necessary in Python 3.8 */
+ Py_INCREF(PLy_SubtransactionType);
+#endif
ob->started = false;
ob->exited = false;
return (PyObject *) ob;
}
-/* Python requires a dealloc function to be defined */
-static void
-PLy_subtransaction_dealloc(PyObject *subxact)
-{
-}
-
/*
* subxact.__enter__() or subxact.enter()
*
sublist = PLyList_FromArray_recurse(elm, dims, ndim, dim + 1,
dataptr_p, bitmap_p, bitmask_p);
- PyList_SET_ITEM(list, i, sublist);
+ PyList_SetItem(list, i, sublist);
}
}
else
if (bitmap && (*bitmap & bitmask) == 0)
{
Py_INCREF(Py_None);
- PyList_SET_ITEM(list, i, Py_None);
+ PyList_SetItem(list, i, Py_None);
}
else
{
Datum itemvalue;
itemvalue = fetch_att(dataptr, elm->typbyval, elm->typlen);
- PyList_SET_ITEM(list, i, elm->func(elm, itemvalue));
+ PyList_SetItem(list, i, elm->func(elm, itemvalue));
dataptr = att_addlength_pointer(dataptr, elm->typlen, dataptr);
dataptr = (char *) att_align_nominal(dataptr, elm->typalign);
}