1
0
mirror of https://github.com/postgres/postgres.git synced 2025-04-24 10:47:04 +03:00

Revert "Prepare for Python "Limited API" in PL/Python"

This reverts commit c47e8df815c1c45f4e4fc90d5817d67ab088279f.

That commit makes the plpython tests crash with Python 3.6.* and
3.7.*.  It will need further investigation and testing, so revert for
now.
This commit is contained in:
Peter Eisentraut 2025-02-26 21:58:38 +01:00
parent 945a9e3832
commit f734c9fc3a
6 changed files with 105 additions and 177 deletions

View File

@ -20,7 +20,7 @@
#include "utils/memutils.h" #include "utils/memutils.h"
static PyObject *PLy_cursor_query(const char *query); static PyObject *PLy_cursor_query(const char *query);
static void PLy_cursor_dealloc(PLyCursorObject *self); static void PLy_cursor_dealloc(PyObject *arg);
static PyObject *PLy_cursor_iternext(PyObject *self); static PyObject *PLy_cursor_iternext(PyObject *self);
static PyObject *PLy_cursor_fetch(PyObject *self, PyObject *args); static PyObject *PLy_cursor_fetch(PyObject *self, PyObject *args);
static PyObject *PLy_cursor_close(PyObject *self, PyObject *unused); static PyObject *PLy_cursor_close(PyObject *self, PyObject *unused);
@ -33,43 +33,22 @@ static PyMethodDef PLy_cursor_methods[] = {
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
static PyType_Slot PLyCursor_slots[] = static PyTypeObject PLy_CursorType = {
{ PyVarObject_HEAD_INIT(NULL, 0)
{ .tp_name = "PLyCursor",
Py_tp_dealloc, PLy_cursor_dealloc .tp_basicsize = sizeof(PLyCursorObject),
}, .tp_dealloc = PLy_cursor_dealloc,
{ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
Py_tp_doc, (char *) PLy_cursor_doc .tp_doc = PLy_cursor_doc,
}, .tp_iter = PyObject_SelfIter,
{ .tp_iternext = PLy_cursor_iternext,
Py_tp_iter, PyObject_SelfIter .tp_methods = PLy_cursor_methods,
},
{
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 void
PLy_cursor_init_type(void) PLy_cursor_init_type(void)
{ {
PLy_CursorType = (PyTypeObject *) PyType_FromSpec(&PLyCursor_spec); if (PyType_Ready(&PLy_CursorType) < 0)
if (!PLy_CursorType)
elog(ERROR, "could not initialize PLy_CursorType"); elog(ERROR, "could not initialize PLy_CursorType");
} }
@ -101,7 +80,7 @@ PLy_cursor_query(const char *query)
volatile MemoryContext oldcontext; volatile MemoryContext oldcontext;
volatile ResourceOwner oldowner; volatile ResourceOwner oldowner;
if ((cursor = PyObject_New(PLyCursorObject, PLy_CursorType)) == NULL) if ((cursor = PyObject_New(PLyCursorObject, &PLy_CursorType)) == NULL)
return NULL; return NULL;
cursor->portalname = NULL; cursor->portalname = NULL;
cursor->closed = false; cursor->closed = false;
@ -198,7 +177,7 @@ PLy_cursor_plan(PyObject *ob, PyObject *args)
return NULL; return NULL;
} }
if ((cursor = PyObject_New(PLyCursorObject, PLy_CursorType)) == NULL) if ((cursor = PyObject_New(PLyCursorObject, &PLy_CursorType)) == NULL)
return NULL; return NULL;
cursor->portalname = NULL; cursor->portalname = NULL;
cursor->closed = false; cursor->closed = false;
@ -293,30 +272,30 @@ PLy_cursor_plan(PyObject *ob, PyObject *args)
} }
static void static void
PLy_cursor_dealloc(PLyCursorObject *self) PLy_cursor_dealloc(PyObject *arg)
{ {
PyTypeObject *tp = Py_TYPE(self); PLyCursorObject *cursor;
Portal portal; Portal portal;
if (!self->closed) cursor = (PLyCursorObject *) arg;
if (!cursor->closed)
{ {
portal = GetPortalByName(self->portalname); portal = GetPortalByName(cursor->portalname);
if (PortalIsValid(portal)) if (PortalIsValid(portal))
{ {
UnpinPortal(portal); UnpinPortal(portal);
SPI_cursor_close(portal); SPI_cursor_close(portal);
} }
self->closed = true; cursor->closed = true;
} }
if (self->mcxt) if (cursor->mcxt)
{ {
MemoryContextDelete(self->mcxt); MemoryContextDelete(cursor->mcxt);
self->mcxt = NULL; cursor->mcxt = NULL;
} }
arg->ob_type->tp_free(arg);
PyObject_Free(self);
Py_DECREF(tp);
} }
static PyObject * static PyObject *

View File

@ -12,7 +12,7 @@
#include "plpython.h" #include "plpython.h"
#include "utils/memutils.h" #include "utils/memutils.h"
static void PLy_plan_dealloc(PLyPlanObject *self); static void PLy_plan_dealloc(PyObject *arg);
static PyObject *PLy_plan_cursor(PyObject *self, PyObject *args); static PyObject *PLy_plan_cursor(PyObject *self, PyObject *args);
static PyObject *PLy_plan_execute(PyObject *self, PyObject *args); static PyObject *PLy_plan_execute(PyObject *self, PyObject *args);
static PyObject *PLy_plan_status(PyObject *self, PyObject *args); static PyObject *PLy_plan_status(PyObject *self, PyObject *args);
@ -26,37 +26,20 @@ static PyMethodDef PLy_plan_methods[] = {
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
static PyType_Slot PLyPlan_slots[] = static PyTypeObject PLy_PlanType = {
{ PyVarObject_HEAD_INIT(NULL, 0)
{ .tp_name = "PLyPlan",
Py_tp_dealloc, PLy_plan_dealloc .tp_basicsize = sizeof(PLyPlanObject),
}, .tp_dealloc = PLy_plan_dealloc,
{ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
Py_tp_doc, (char *) PLy_plan_doc .tp_doc = PLy_plan_doc,
}, .tp_methods = PLy_plan_methods,
{
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 void
PLy_plan_init_type(void) PLy_plan_init_type(void)
{ {
PLy_PlanType = (PyTypeObject *) PyType_FromSpec(&PLyPlan_spec); if (PyType_Ready(&PLy_PlanType) < 0)
if (!PLy_PlanType)
elog(ERROR, "could not initialize PLy_PlanType"); elog(ERROR, "could not initialize PLy_PlanType");
} }
@ -65,7 +48,7 @@ PLy_plan_new(void)
{ {
PLyPlanObject *ob; PLyPlanObject *ob;
if ((ob = PyObject_New(PLyPlanObject, PLy_PlanType)) == NULL) if ((ob = PyObject_New(PLyPlanObject, &PLy_PlanType)) == NULL)
return NULL; return NULL;
ob->plan = NULL; ob->plan = NULL;
@ -80,27 +63,25 @@ PLy_plan_new(void)
bool bool
is_PLyPlanObject(PyObject *ob) is_PLyPlanObject(PyObject *ob)
{ {
return ob->ob_type == PLy_PlanType; return ob->ob_type == &PLy_PlanType;
} }
static void static void
PLy_plan_dealloc(PLyPlanObject *self) PLy_plan_dealloc(PyObject *arg)
{ {
PyTypeObject *tp = Py_TYPE(self); PLyPlanObject *ob = (PLyPlanObject *) arg;
if (self->plan) if (ob->plan)
{ {
SPI_freeplan(self->plan); SPI_freeplan(ob->plan);
self->plan = NULL; ob->plan = NULL;
} }
if (self->mcxt) if (ob->mcxt)
{ {
MemoryContextDelete(self->mcxt); MemoryContextDelete(ob->mcxt);
self->mcxt = NULL; ob->mcxt = NULL;
} }
arg->ob_type->tp_free(arg);
PyObject_Free(self);
Py_DECREF(tp);
} }

View File

@ -350,7 +350,6 @@ PLy_procedure_compile(PLyProcedure *proc, const char *src)
{ {
PyObject *crv = NULL; PyObject *crv = NULL;
char *msrc; char *msrc;
PyObject *code0;
proc->globals = PyDict_Copy(PLy_interp_globals); proc->globals = PyDict_Copy(PLy_interp_globals);
@ -369,9 +368,7 @@ PLy_procedure_compile(PLyProcedure *proc, const char *src)
msrc = PLy_procedure_munge_source(proc->pyname, src); msrc = PLy_procedure_munge_source(proc->pyname, src);
/* Save the mangled source for later inclusion in tracebacks */ /* Save the mangled source for later inclusion in tracebacks */
proc->src = MemoryContextStrdup(proc->mcxt, msrc); proc->src = MemoryContextStrdup(proc->mcxt, msrc);
code0 = Py_CompileString(msrc, "<string>", Py_file_input); crv = PyRun_String(msrc, Py_file_input, proc->globals, NULL);
if (code0)
crv = PyEval_EvalCode(code0, proc->globals, NULL);
pfree(msrc); pfree(msrc);
if (crv != NULL) if (crv != NULL)

View File

@ -10,7 +10,7 @@
#include "plpy_resultobject.h" #include "plpy_resultobject.h"
#include "plpython.h" #include "plpython.h"
static void PLy_result_dealloc(PLyResultObject *self); static void PLy_result_dealloc(PyObject *arg);
static PyObject *PLy_result_colnames(PyObject *self, PyObject *unused); static PyObject *PLy_result_colnames(PyObject *self, PyObject *unused);
static PyObject *PLy_result_coltypes(PyObject *self, PyObject *unused); static PyObject *PLy_result_coltypes(PyObject *self, PyObject *unused);
static PyObject *PLy_result_coltypmods(PyObject *self, PyObject *unused); static PyObject *PLy_result_coltypmods(PyObject *self, PyObject *unused);
@ -24,6 +24,17 @@ static int PLy_result_ass_subscript(PyObject *arg, PyObject *item, PyObject *val
static char PLy_result_doc[] = "Results of a PostgreSQL query"; 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[] = { static PyMethodDef PLy_result_methods[] = {
{"colnames", PLy_result_colnames, METH_NOARGS, NULL}, {"colnames", PLy_result_colnames, METH_NOARGS, NULL},
{"coltypes", PLy_result_coltypes, METH_NOARGS, NULL}, {"coltypes", PLy_result_coltypes, METH_NOARGS, NULL},
@ -33,55 +44,23 @@ static PyMethodDef PLy_result_methods[] = {
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
static PyType_Slot PLyResult_slots[] = static PyTypeObject PLy_ResultType = {
{ PyVarObject_HEAD_INIT(NULL, 0)
{ .tp_name = "PLyResult",
Py_tp_dealloc, PLy_result_dealloc .tp_basicsize = sizeof(PLyResultObject),
}, .tp_dealloc = PLy_result_dealloc,
{ .tp_as_sequence = &PLy_result_as_sequence,
Py_sq_length, PLy_result_length .tp_as_mapping = &PLy_result_as_mapping,
}, .tp_str = &PLy_result_str,
{ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
Py_sq_item, PLy_result_item .tp_doc = PLy_result_doc,
}, .tp_methods = PLy_result_methods,
{
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 void
PLy_result_init_type(void) PLy_result_init_type(void)
{ {
PLy_ResultType = (PyTypeObject *) PyType_FromSpec(&PLyResult_spec); if (PyType_Ready(&PLy_ResultType) < 0)
if (!PLy_ResultType)
elog(ERROR, "could not initialize PLy_ResultType"); elog(ERROR, "could not initialize PLy_ResultType");
} }
@ -90,7 +69,7 @@ PLy_result_new(void)
{ {
PLyResultObject *ob; PLyResultObject *ob;
if ((ob = PyObject_New(PLyResultObject, PLy_ResultType)) == NULL) if ((ob = PyObject_New(PLyResultObject, &PLy_ResultType)) == NULL)
return NULL; return NULL;
/* ob->tuples = NULL; */ /* ob->tuples = NULL; */
@ -110,21 +89,20 @@ PLy_result_new(void)
} }
static void static void
PLy_result_dealloc(PLyResultObject *self) PLy_result_dealloc(PyObject *arg)
{ {
PyTypeObject *tp = Py_TYPE(self); PLyResultObject *ob = (PLyResultObject *) arg;
Py_XDECREF(self->nrows); Py_XDECREF(ob->nrows);
Py_XDECREF(self->rows); Py_XDECREF(ob->rows);
Py_XDECREF(self->status); Py_XDECREF(ob->status);
if (self->tupdesc) if (ob->tupdesc)
{ {
FreeTupleDesc(self->tupdesc); FreeTupleDesc(ob->tupdesc);
self->tupdesc = NULL; ob->tupdesc = NULL;
} }
PyObject_Free(self); arg->ob_type->tp_free(arg);
Py_DECREF(tp);
} }
static PyObject * static PyObject *
@ -147,7 +125,7 @@ PLy_result_colnames(PyObject *self, PyObject *unused)
{ {
Form_pg_attribute attr = TupleDescAttr(ob->tupdesc, i); Form_pg_attribute attr = TupleDescAttr(ob->tupdesc, i);
PyList_SetItem(list, i, PLyUnicode_FromString(NameStr(attr->attname))); PyList_SET_ITEM(list, i, PLyUnicode_FromString(NameStr(attr->attname)));
} }
return list; return list;
@ -173,7 +151,7 @@ PLy_result_coltypes(PyObject *self, PyObject *unused)
{ {
Form_pg_attribute attr = TupleDescAttr(ob->tupdesc, i); Form_pg_attribute attr = TupleDescAttr(ob->tupdesc, i);
PyList_SetItem(list, i, PyLong_FromLong(attr->atttypid)); PyList_SET_ITEM(list, i, PyLong_FromLong(attr->atttypid));
} }
return list; return list;
@ -199,7 +177,7 @@ PLy_result_coltypmods(PyObject *self, PyObject *unused)
{ {
Form_pg_attribute attr = TupleDescAttr(ob->tupdesc, i); Form_pg_attribute attr = TupleDescAttr(ob->tupdesc, i);
PyList_SetItem(list, i, PyLong_FromLong(attr->atttypmod)); PyList_SET_ITEM(list, i, PyLong_FromLong(attr->atttypmod));
} }
return list; return list;
@ -249,7 +227,7 @@ PLy_result_str(PyObject *arg)
PLyResultObject *ob = (PLyResultObject *) arg; PLyResultObject *ob = (PLyResultObject *) arg;
return PyUnicode_FromFormat("<%s status=%S nrows=%S rows=%S>", return PyUnicode_FromFormat("<%s status=%S nrows=%S rows=%S>",
"PLyResult", Py_TYPE(ob)->tp_name,
ob->status, ob->status,
ob->nrows, ob->nrows,
ob->rows); ob->rows);

View File

@ -15,6 +15,7 @@
List *explicit_subtransactions = NIL; List *explicit_subtransactions = NIL;
static void PLy_subtransaction_dealloc(PyObject *subxact);
static PyObject *PLy_subtransaction_enter(PyObject *self, PyObject *unused); static PyObject *PLy_subtransaction_enter(PyObject *self, PyObject *unused);
static PyObject *PLy_subtransaction_exit(PyObject *self, PyObject *args); static PyObject *PLy_subtransaction_exit(PyObject *self, PyObject *args);
@ -30,35 +31,21 @@ static PyMethodDef PLy_subtransaction_methods[] = {
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
static PyType_Slot PLySubtransaction_slots[] = static PyTypeObject PLy_SubtransactionType = {
{ PyVarObject_HEAD_INIT(NULL, 0)
{ .tp_name = "PLySubtransaction",
Py_tp_doc, (char *) PLy_subtransaction_doc .tp_basicsize = sizeof(PLySubtransactionObject),
}, .tp_dealloc = PLy_subtransaction_dealloc,
{ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
Py_tp_methods, PLy_subtransaction_methods .tp_doc = PLy_subtransaction_doc,
}, .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 void
PLy_subtransaction_init_type(void) PLy_subtransaction_init_type(void)
{ {
PLy_SubtransactionType = (PyTypeObject *) PyType_FromSpec(&PLySubtransaction_spec); if (PyType_Ready(&PLy_SubtransactionType) < 0)
if (!PLy_SubtransactionType)
elog(ERROR, "could not initialize PLy_SubtransactionType"); elog(ERROR, "could not initialize PLy_SubtransactionType");
} }
@ -68,7 +55,7 @@ PLy_subtransaction_new(PyObject *self, PyObject *unused)
{ {
PLySubtransactionObject *ob; PLySubtransactionObject *ob;
ob = PyObject_New(PLySubtransactionObject, PLy_SubtransactionType); ob = PyObject_New(PLySubtransactionObject, &PLy_SubtransactionType);
if (ob == NULL) if (ob == NULL)
return NULL; return NULL;
@ -79,6 +66,12 @@ PLy_subtransaction_new(PyObject *self, PyObject *unused)
return (PyObject *) ob; return (PyObject *) ob;
} }
/* Python requires a dealloc function to be defined */
static void
PLy_subtransaction_dealloc(PyObject *subxact)
{
}
/* /*
* subxact.__enter__() or subxact.enter() * subxact.__enter__() or subxact.enter()
* *

View File

@ -723,7 +723,7 @@ PLyList_FromArray_recurse(PLyDatumToOb *elm, int *dims, int ndim, int dim,
sublist = PLyList_FromArray_recurse(elm, dims, ndim, dim + 1, sublist = PLyList_FromArray_recurse(elm, dims, ndim, dim + 1,
dataptr_p, bitmap_p, bitmask_p); dataptr_p, bitmap_p, bitmask_p);
PyList_SetItem(list, i, sublist); PyList_SET_ITEM(list, i, sublist);
} }
} }
else else
@ -742,14 +742,14 @@ PLyList_FromArray_recurse(PLyDatumToOb *elm, int *dims, int ndim, int dim,
if (bitmap && (*bitmap & bitmask) == 0) if (bitmap && (*bitmap & bitmask) == 0)
{ {
Py_INCREF(Py_None); Py_INCREF(Py_None);
PyList_SetItem(list, i, Py_None); PyList_SET_ITEM(list, i, Py_None);
} }
else else
{ {
Datum itemvalue; Datum itemvalue;
itemvalue = fetch_att(dataptr, elm->typbyval, elm->typlen); itemvalue = fetch_att(dataptr, elm->typbyval, elm->typlen);
PyList_SetItem(list, i, elm->func(elm, itemvalue)); PyList_SET_ITEM(list, i, elm->func(elm, itemvalue));
dataptr = att_addlength_pointer(dataptr, elm->typlen, dataptr); dataptr = att_addlength_pointer(dataptr, elm->typlen, dataptr);
dataptr = (char *) att_align_nominal(dataptr, elm->typalign); dataptr = (char *) att_align_nominal(dataptr, elm->typalign);
} }