]> granicus.if.org Git - postgresql/blob - src/pl/plpython/plpy_resultobject.c
PL/Python: Remove use of simple slicing API
[postgresql] / src / pl / plpython / plpy_resultobject.c
1 /*
2  * the PLyResult class
3  *
4  * src/pl/plpython/plpy_resultobject.c
5  */
6
7 #include "postgres.h"
8
9 #include "plpython.h"
10
11 #include "plpy_resultobject.h"
12 #include "plpy_elog.h"
13
14
15 static void PLy_result_dealloc(PyObject *arg);
16 static PyObject *PLy_result_colnames(PyObject *self, PyObject *unused);
17 static PyObject *PLy_result_coltypes(PyObject *self, PyObject *unused);
18 static PyObject *PLy_result_coltypmods(PyObject *self, PyObject *unused);
19 static PyObject *PLy_result_nrows(PyObject *self, PyObject *args);
20 static PyObject *PLy_result_status(PyObject *self, PyObject *args);
21 static Py_ssize_t PLy_result_length(PyObject *arg);
22 static PyObject *PLy_result_item(PyObject *arg, Py_ssize_t idx);
23 static PyObject *PLy_result_str(PyObject *arg);
24 static PyObject *PLy_result_subscript(PyObject *arg, PyObject *item);
25 static int      PLy_result_ass_subscript(PyObject *self, PyObject *item, PyObject *value);
26
27 static char PLy_result_doc[] = {
28         "Results of a PostgreSQL query"
29 };
30
31 static PySequenceMethods PLy_result_as_sequence = {
32         PLy_result_length,                      /* sq_length */
33         NULL,                                           /* sq_concat */
34         NULL,                                           /* sq_repeat */
35         PLy_result_item,                        /* sq_item */
36         NULL,                                           /* sq_slice */
37         NULL,                                           /* sq_ass_item */
38         NULL,                                           /* sq_ass_slice */
39 };
40
41 static PyMappingMethods PLy_result_as_mapping = {
42         PLy_result_length,                      /* mp_length */
43         PLy_result_subscript,           /* mp_subscript */
44         PLy_result_ass_subscript,       /* mp_ass_subscript */
45 };
46
47 static PyMethodDef PLy_result_methods[] = {
48         {"colnames", PLy_result_colnames, METH_NOARGS, NULL},
49         {"coltypes", PLy_result_coltypes, METH_NOARGS, NULL},
50         {"coltypmods", PLy_result_coltypmods, METH_NOARGS, NULL},
51         {"nrows", PLy_result_nrows, METH_VARARGS, NULL},
52         {"status", PLy_result_status, METH_VARARGS, NULL},
53         {NULL, NULL, 0, NULL}
54 };
55
56 static PyTypeObject PLy_ResultType = {
57         PyVarObject_HEAD_INIT(NULL, 0)
58         "PLyResult",                            /* tp_name */
59         sizeof(PLyResultObject),        /* tp_size */
60         0,                                                      /* tp_itemsize */
61
62         /*
63          * methods
64          */
65         PLy_result_dealloc,                     /* tp_dealloc */
66         0,                                                      /* tp_print */
67         0,                                                      /* tp_getattr */
68         0,                                                      /* tp_setattr */
69         0,                                                      /* tp_compare */
70         0,                                                      /* tp_repr */
71         0,                                                      /* tp_as_number */
72         &PLy_result_as_sequence,        /* tp_as_sequence */
73         &PLy_result_as_mapping,         /* tp_as_mapping */
74         0,                                                      /* tp_hash */
75         0,                                                      /* tp_call */
76         &PLy_result_str,                        /* tp_str */
77         0,                                                      /* tp_getattro */
78         0,                                                      /* tp_setattro */
79         0,                                                      /* tp_as_buffer */
80         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,       /* tp_flags */
81         PLy_result_doc,                         /* tp_doc */
82         0,                                                      /* tp_traverse */
83         0,                                                      /* tp_clear */
84         0,                                                      /* tp_richcompare */
85         0,                                                      /* tp_weaklistoffset */
86         0,                                                      /* tp_iter */
87         0,                                                      /* tp_iternext */
88         PLy_result_methods,                     /* tp_tpmethods */
89 };
90
91 void
92 PLy_result_init_type(void)
93 {
94         if (PyType_Ready(&PLy_ResultType) < 0)
95                 elog(ERROR, "could not initialize PLy_ResultType");
96 }
97
98 PyObject *
99 PLy_result_new(void)
100 {
101         PLyResultObject *ob;
102
103         if ((ob = PyObject_New(PLyResultObject, &PLy_ResultType)) == NULL)
104                 return NULL;
105
106         /* ob->tuples = NULL; */
107
108         Py_INCREF(Py_None);
109         ob->status = Py_None;
110         ob->nrows = PyInt_FromLong(-1);
111         ob->rows = PyList_New(0);
112         ob->tupdesc = NULL;
113         if (!ob->rows)
114         {
115                 Py_DECREF(ob);
116                 return NULL;
117         }
118
119         return (PyObject *) ob;
120 }
121
122 static void
123 PLy_result_dealloc(PyObject *arg)
124 {
125         PLyResultObject *ob = (PLyResultObject *) arg;
126
127         Py_XDECREF(ob->nrows);
128         Py_XDECREF(ob->rows);
129         Py_XDECREF(ob->status);
130         if (ob->tupdesc)
131         {
132                 FreeTupleDesc(ob->tupdesc);
133                 ob->tupdesc = NULL;
134         }
135
136         arg->ob_type->tp_free(arg);
137 }
138
139 static PyObject *
140 PLy_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         {
157                 Form_pg_attribute attr = TupleDescAttr(ob->tupdesc, i);
158
159                 PyList_SET_ITEM(list, i, PyString_FromString(NameStr(attr->attname)));
160         }
161
162         return list;
163 }
164
165 static PyObject *
166 PLy_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         {
183                 Form_pg_attribute attr = TupleDescAttr(ob->tupdesc, i);
184
185                 PyList_SET_ITEM(list, i, PyInt_FromLong(attr->atttypid));
186         }
187
188         return list;
189 }
190
191 static PyObject *
192 PLy_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         {
209                 Form_pg_attribute attr = TupleDescAttr(ob->tupdesc, i);
210
211                 PyList_SET_ITEM(list, i, PyInt_FromLong(attr->atttypmod));
212         }
213
214         return list;
215 }
216
217 static PyObject *
218 PLy_result_nrows(PyObject *self, PyObject *args)
219 {
220         PLyResultObject *ob = (PLyResultObject *) self;
221
222         Py_INCREF(ob->nrows);
223         return ob->nrows;
224 }
225
226 static PyObject *
227 PLy_result_status(PyObject *self, PyObject *args)
228 {
229         PLyResultObject *ob = (PLyResultObject *) self;
230
231         Py_INCREF(ob->status);
232         return ob->status;
233 }
234
235 static Py_ssize_t
236 PLy_result_length(PyObject *arg)
237 {
238         PLyResultObject *ob = (PLyResultObject *) arg;
239
240         return PyList_Size(ob->rows);
241 }
242
243 static PyObject *
244 PLy_result_item(PyObject *arg, Py_ssize_t idx)
245 {
246         PyObject   *rv;
247         PLyResultObject *ob = (PLyResultObject *) arg;
248
249         rv = PyList_GetItem(ob->rows, idx);
250         if (rv != NULL)
251                 Py_INCREF(rv);
252         return rv;
253 }
254
255 static PyObject *
256 PLy_result_str(PyObject *arg)
257 {
258         PLyResultObject *ob = (PLyResultObject *) arg;
259
260 #if PY_MAJOR_VERSION >= 3
261         return PyUnicode_FromFormat("<%s status=%S nrows=%S rows=%S>",
262                                                                 Py_TYPE(ob)->tp_name,
263                                                                 ob->status,
264                                                                 ob->nrows,
265                                                                 ob->rows);
266 #else
267         return PyString_FromFormat("<%s status=%ld nrows=%ld rows=%s>",
268                                                            ob->ob_type->tp_name,
269                                                            PyInt_AsLong(ob->status),
270                                                            PyInt_AsLong(ob->nrows),
271                                                            PyString_AsString(PyObject_Str(ob->rows)));
272 #endif
273 }
274
275 static PyObject *
276 PLy_result_subscript(PyObject *arg, PyObject *item)
277 {
278         PLyResultObject *ob = (PLyResultObject *) arg;
279
280         return PyObject_GetItem(ob->rows, item);
281 }
282
283 static int
284 PLy_result_ass_subscript(PyObject *arg, PyObject *item, PyObject *value)
285 {
286         PLyResultObject *ob = (PLyResultObject *) arg;
287
288         return PyObject_SetItem(ob->rows, item, value);
289 }