PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
plpy_resultobject.c
Go to the documentation of this file.
1/*
2 * the PLyResult class
3 *
4 * src/pl/plpython/plpy_resultobject.c
5 */
6
7#include "postgres.h"
8
9#include "plpy_elog.h"
10#include "plpy_resultobject.h"
11#include "plpython.h"
12
13static void PLy_result_dealloc(PLyResultObject *self);
14static PyObject *PLy_result_colnames(PyObject *self, PyObject *unused);
15static PyObject *PLy_result_coltypes(PyObject *self, PyObject *unused);
16static PyObject *PLy_result_coltypmods(PyObject *self, PyObject *unused);
17static PyObject *PLy_result_nrows(PyObject *self, PyObject *args);
18static PyObject *PLy_result_status(PyObject *self, PyObject *args);
19static Py_ssize_t PLy_result_length(PyObject *arg);
20static PyObject *PLy_result_item(PyObject *arg, Py_ssize_t idx);
21static PyObject *PLy_result_str(PyObject *arg);
22static PyObject *PLy_result_subscript(PyObject *arg, PyObject *item);
23static int PLy_result_ass_subscript(PyObject *arg, PyObject *item, PyObject *value);
24
25static char PLy_result_doc[] = "Results of a PostgreSQL query";
26
27static PyMethodDef PLy_result_methods[] = {
28 {"colnames", PLy_result_colnames, METH_NOARGS, NULL},
29 {"coltypes", PLy_result_coltypes, METH_NOARGS, NULL},
30 {"coltypmods", PLy_result_coltypmods, METH_NOARGS, NULL},
31 {"nrows", PLy_result_nrows, METH_VARARGS, NULL},
32 {"status", PLy_result_status, METH_VARARGS, NULL},
33 {NULL, NULL, 0, NULL}
34};
35
36static PyType_Slot PLyResult_slots[] =
37{
38 {
39 Py_tp_dealloc, PLy_result_dealloc
40 },
41 {
42 Py_sq_length, PLy_result_length
43 },
44 {
45 Py_sq_item, PLy_result_item
46 },
47 {
48 Py_mp_length, PLy_result_length
49 },
50 {
51 Py_mp_subscript, PLy_result_subscript
52 },
53 {
54 Py_mp_ass_subscript, PLy_result_ass_subscript
55 },
56 {
57 Py_tp_str, PLy_result_str
58 },
59 {
60 Py_tp_doc, (char *) PLy_result_doc
61 },
62 {
63 Py_tp_methods, PLy_result_methods
64 },
65 {
66 0, NULL
67 }
68};
69
70static PyType_Spec PLyResult_spec =
71{
72 .name = "PLyResult",
73 .basicsize = sizeof(PLyResultObject),
74 .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
75 .slots = PLyResult_slots,
76};
77
78static PyTypeObject *PLy_ResultType;
79
80void
82{
83 PLy_ResultType = (PyTypeObject *) PyType_FromSpec(&PLyResult_spec);
84 if (!PLy_ResultType)
85 elog(ERROR, "could not initialize PLy_ResultType");
86}
87
88PyObject *
90{
92
93 if ((ob = PyObject_New(PLyResultObject, PLy_ResultType)) == NULL)
94 return NULL;
95#if PY_VERSION_HEX < 0x03080000
96 /* Workaround for Python issue 35810; no longer necessary in Python 3.8 */
97 Py_INCREF(PLy_ResultType);
98#endif
99
100 /* ob->tuples = NULL; */
101
102 Py_INCREF(Py_None);
103 ob->status = Py_None;
104 ob->nrows = PyLong_FromLong(-1);
105 ob->rows = PyList_New(0);
106 ob->tupdesc = NULL;
107 if (!ob->rows)
108 {
109 Py_DECREF(ob);
110 return NULL;
111 }
112
113 return (PyObject *) ob;
114}
115
116static void
118{
119#if PY_VERSION_HEX >= 0x03080000
120 PyTypeObject *tp = Py_TYPE(self);
121#endif
122
123 Py_XDECREF(self->nrows);
124 Py_XDECREF(self->rows);
125 Py_XDECREF(self->status);
126 if (self->tupdesc)
127 {
128 FreeTupleDesc(self->tupdesc);
129 self->tupdesc = NULL;
130 }
131
132 PyObject_Free(self);
133#if PY_VERSION_HEX >= 0x03080000
134 /* This was not needed before Python 3.8 (Python issue 35810) */
135 Py_DECREF(tp);
136#endif
137}
138
139static PyObject *
140PLy_result_colnames(PyObject *self, PyObject *unused)
141{
142 PLyResultObject *ob = (PLyResultObject *) self;
143 PyObject *list;
144 int i;
145
146 if (!ob->tupdesc)
147 {
148 PLy_exception_set(PLy_exc_error, "command did not produce a result set");
149 return NULL;
150 }
151
152 list = PyList_New(ob->tupdesc->natts);
153 if (!list)
154 return NULL;
155 for (i = 0; i < ob->tupdesc->natts; i++)
156 {
158
159 PyList_SetItem(list, i, PLyUnicode_FromString(NameStr(attr->attname)));
160 }
161
162 return list;
163}
164
165static PyObject *
166PLy_result_coltypes(PyObject *self, PyObject *unused)
167{
168 PLyResultObject *ob = (PLyResultObject *) self;
169 PyObject *list;
170 int i;
171
172 if (!ob->tupdesc)
173 {
174 PLy_exception_set(PLy_exc_error, "command did not produce a result set");
175 return NULL;
176 }
177
178 list = PyList_New(ob->tupdesc->natts);
179 if (!list)
180 return NULL;
181 for (i = 0; i < ob->tupdesc->natts; i++)
182 {
184
185 PyList_SetItem(list, i, PyLong_FromLong(attr->atttypid));
186 }
187
188 return list;
189}
190
191static PyObject *
192PLy_result_coltypmods(PyObject *self, PyObject *unused)
193{
194 PLyResultObject *ob = (PLyResultObject *) self;
195 PyObject *list;
196 int i;
197
198 if (!ob->tupdesc)
199 {
200 PLy_exception_set(PLy_exc_error, "command did not produce a result set");
201 return NULL;
202 }
203
204 list = PyList_New(ob->tupdesc->natts);
205 if (!list)
206 return NULL;
207 for (i = 0; i < ob->tupdesc->natts; i++)
208 {
210
211 PyList_SetItem(list, i, PyLong_FromLong(attr->atttypmod));
212 }
213
214 return list;
215}
216
217static PyObject *
218PLy_result_nrows(PyObject *self, PyObject *args)
219{
220 PLyResultObject *ob = (PLyResultObject *) self;
221
222 Py_INCREF(ob->nrows);
223 return ob->nrows;
224}
225
226static PyObject *
227PLy_result_status(PyObject *self, PyObject *args)
228{
229 PLyResultObject *ob = (PLyResultObject *) self;
230
231 Py_INCREF(ob->status);
232 return ob->status;
233}
234
235static Py_ssize_t
237{
239
240 return PyList_Size(ob->rows);
241}
242
243static PyObject *
244PLy_result_item(PyObject *arg, Py_ssize_t idx)
245{
246 PyObject *rv;
248
249 rv = PyList_GetItem(ob->rows, idx);
250 if (rv != NULL)
251 Py_INCREF(rv);
252 return rv;
253}
254
255static PyObject *
257{
259
260 return PyUnicode_FromFormat("<%s status=%S nrows=%S rows=%S>",
261 "PLyResult",
262 ob->status,
263 ob->nrows,
264 ob->rows);
265}
266
267static PyObject *
268PLy_result_subscript(PyObject *arg, PyObject *item)
269{
271
272 return PyObject_GetItem(ob->rows, item);
273}
274
275static int
276PLy_result_ass_subscript(PyObject *arg, PyObject *item, PyObject *value)
277{
279
280 return PyObject_SetItem(ob->rows, item, value);
281}
Datum idx(PG_FUNCTION_ARGS)
Definition: _int_op.c:262
#define NameStr(name)
Definition: c.h:717
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
static struct @165 value
int i
Definition: isn.c:77
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:200
void * arg
PyObject * PLy_exc_error
Definition: plpy_elog.c:15
void PLy_exception_set(PyObject *exc, const char *fmt,...)
Definition: plpy_elog.c:472
static PyType_Spec PLyResult_spec
static PyObject * PLy_result_str(PyObject *arg)
static PyObject * PLy_result_item(PyObject *arg, Py_ssize_t idx)
static PyObject * PLy_result_nrows(PyObject *self, PyObject *args)
static void PLy_result_dealloc(PLyResultObject *self)
static PyType_Slot PLyResult_slots[]
void PLy_result_init_type(void)
static PyTypeObject * PLy_ResultType
static PyObject * PLy_result_coltypmods(PyObject *self, PyObject *unused)
PyObject * PLy_result_new(void)
static char PLy_result_doc[]
static PyObject * PLy_result_status(PyObject *self, PyObject *args)
static PyObject * PLy_result_subscript(PyObject *arg, PyObject *item)
static Py_ssize_t PLy_result_length(PyObject *arg)
static PyObject * PLy_result_coltypes(PyObject *self, PyObject *unused)
static PyObject * PLy_result_colnames(PyObject *self, PyObject *unused)
static PyMethodDef PLy_result_methods[]
static int PLy_result_ass_subscript(PyObject *arg, PyObject *item, PyObject *value)
struct PLyResultObject PLyResultObject
PyObject * PLyUnicode_FromString(const char *s)
Definition: plpy_util.c:117
PyObject_HEAD PyObject * nrows
void FreeTupleDesc(TupleDesc tupdesc)
Definition: tupdesc.c:479
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
Definition: tupdesc.h:154