diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 13:44:03 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 13:44:03 +0000 |
commit | 293913568e6a7a86fd1479e1cff8e2ecb58d6568 (patch) | |
tree | fc3b469a3ec5ab71b36ea97cc7aaddb838423a0c /src/pl/plpython/plpy_resultobject.c | |
parent | Initial commit. (diff) | |
download | postgresql-16-293913568e6a7a86fd1479e1cff8e2ecb58d6568.tar.xz postgresql-16-293913568e6a7a86fd1479e1cff8e2ecb58d6568.zip |
Adding upstream version 16.2.upstream/16.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/pl/plpython/plpy_resultobject.c')
-rw-r--r-- | src/pl/plpython/plpy_resultobject.c | 250 |
1 files changed, 250 insertions, 0 deletions
diff --git a/src/pl/plpython/plpy_resultobject.c b/src/pl/plpython/plpy_resultobject.c new file mode 100644 index 0000000..95acce6 --- /dev/null +++ b/src/pl/plpython/plpy_resultobject.c @@ -0,0 +1,250 @@ +/* + * the PLyResult class + * + * src/pl/plpython/plpy_resultobject.c + */ + +#include "postgres.h" + +#include "plpy_elog.h" +#include "plpy_resultobject.h" +#include "plpython.h" + +static void PLy_result_dealloc(PyObject *arg); +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 PyObject *PLy_result_nrows(PyObject *self, PyObject *args); +static PyObject *PLy_result_status(PyObject *self, PyObject *args); +static Py_ssize_t PLy_result_length(PyObject *arg); +static PyObject *PLy_result_item(PyObject *arg, Py_ssize_t idx); +static PyObject *PLy_result_str(PyObject *arg); +static PyObject *PLy_result_subscript(PyObject *arg, PyObject *item); +static int PLy_result_ass_subscript(PyObject *arg, PyObject *item, PyObject *value); + +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}, + {"coltypmods", PLy_result_coltypmods, METH_NOARGS, NULL}, + {"nrows", PLy_result_nrows, METH_VARARGS, NULL}, + {"status", PLy_result_status, METH_VARARGS, 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, +}; + +void +PLy_result_init_type(void) +{ + if (PyType_Ready(&PLy_ResultType) < 0) + elog(ERROR, "could not initialize PLy_ResultType"); +} + +PyObject * +PLy_result_new(void) +{ + PLyResultObject *ob; + + if ((ob = PyObject_New(PLyResultObject, &PLy_ResultType)) == NULL) + return NULL; + + /* ob->tuples = NULL; */ + + Py_INCREF(Py_None); + ob->status = Py_None; + ob->nrows = PyLong_FromLong(-1); + ob->rows = PyList_New(0); + ob->tupdesc = NULL; + if (!ob->rows) + { + Py_DECREF(ob); + return NULL; + } + + return (PyObject *) ob; +} + +static void +PLy_result_dealloc(PyObject *arg) +{ + PLyResultObject *ob = (PLyResultObject *) arg; + + Py_XDECREF(ob->nrows); + Py_XDECREF(ob->rows); + Py_XDECREF(ob->status); + if (ob->tupdesc) + { + FreeTupleDesc(ob->tupdesc); + ob->tupdesc = NULL; + } + + arg->ob_type->tp_free(arg); +} + +static PyObject * +PLy_result_colnames(PyObject *self, PyObject *unused) +{ + PLyResultObject *ob = (PLyResultObject *) self; + PyObject *list; + int i; + + if (!ob->tupdesc) + { + PLy_exception_set(PLy_exc_error, "command did not produce a result set"); + return NULL; + } + + list = PyList_New(ob->tupdesc->natts); + if (!list) + return NULL; + for (i = 0; i < ob->tupdesc->natts; i++) + { + Form_pg_attribute attr = TupleDescAttr(ob->tupdesc, i); + + PyList_SET_ITEM(list, i, PLyUnicode_FromString(NameStr(attr->attname))); + } + + return list; +} + +static PyObject * +PLy_result_coltypes(PyObject *self, PyObject *unused) +{ + PLyResultObject *ob = (PLyResultObject *) self; + PyObject *list; + int i; + + if (!ob->tupdesc) + { + PLy_exception_set(PLy_exc_error, "command did not produce a result set"); + return NULL; + } + + list = PyList_New(ob->tupdesc->natts); + if (!list) + return NULL; + for (i = 0; i < ob->tupdesc->natts; i++) + { + Form_pg_attribute attr = TupleDescAttr(ob->tupdesc, i); + + PyList_SET_ITEM(list, i, PyLong_FromLong(attr->atttypid)); + } + + return list; +} + +static PyObject * +PLy_result_coltypmods(PyObject *self, PyObject *unused) +{ + PLyResultObject *ob = (PLyResultObject *) self; + PyObject *list; + int i; + + if (!ob->tupdesc) + { + PLy_exception_set(PLy_exc_error, "command did not produce a result set"); + return NULL; + } + + list = PyList_New(ob->tupdesc->natts); + if (!list) + return NULL; + for (i = 0; i < ob->tupdesc->natts; i++) + { + Form_pg_attribute attr = TupleDescAttr(ob->tupdesc, i); + + PyList_SET_ITEM(list, i, PyLong_FromLong(attr->atttypmod)); + } + + return list; +} + +static PyObject * +PLy_result_nrows(PyObject *self, PyObject *args) +{ + PLyResultObject *ob = (PLyResultObject *) self; + + Py_INCREF(ob->nrows); + return ob->nrows; +} + +static PyObject * +PLy_result_status(PyObject *self, PyObject *args) +{ + PLyResultObject *ob = (PLyResultObject *) self; + + Py_INCREF(ob->status); + return ob->status; +} + +static Py_ssize_t +PLy_result_length(PyObject *arg) +{ + PLyResultObject *ob = (PLyResultObject *) arg; + + return PyList_Size(ob->rows); +} + +static PyObject * +PLy_result_item(PyObject *arg, Py_ssize_t idx) +{ + PyObject *rv; + PLyResultObject *ob = (PLyResultObject *) arg; + + rv = PyList_GetItem(ob->rows, idx); + if (rv != NULL) + Py_INCREF(rv); + return rv; +} + +static PyObject * +PLy_result_str(PyObject *arg) +{ + PLyResultObject *ob = (PLyResultObject *) arg; + + return PyUnicode_FromFormat("<%s status=%S nrows=%S rows=%S>", + Py_TYPE(ob)->tp_name, + ob->status, + ob->nrows, + ob->rows); +} + +static PyObject * +PLy_result_subscript(PyObject *arg, PyObject *item) +{ + PLyResultObject *ob = (PLyResultObject *) arg; + + return PyObject_GetItem(ob->rows, item); +} + +static int +PLy_result_ass_subscript(PyObject *arg, PyObject *item, PyObject *value) +{ + PLyResultObject *ob = (PLyResultObject *) arg; + + return PyObject_SetItem(ob->rows, item, value); +} |