Age Owner Branch data TLA Line data Source code
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 : :
13 : : static void PLy_result_dealloc(PyObject *arg);
14 : : static PyObject *PLy_result_colnames(PyObject *self, PyObject *unused);
15 : : static PyObject *PLy_result_coltypes(PyObject *self, PyObject *unused);
16 : : static PyObject *PLy_result_coltypmods(PyObject *self, PyObject *unused);
17 : : static PyObject *PLy_result_nrows(PyObject *self, PyObject *args);
18 : : static PyObject *PLy_result_status(PyObject *self, PyObject *args);
19 : : static Py_ssize_t PLy_result_length(PyObject *arg);
20 : : static PyObject *PLy_result_item(PyObject *arg, Py_ssize_t idx);
21 : : static PyObject *PLy_result_str(PyObject *arg);
22 : : static PyObject *PLy_result_subscript(PyObject *arg, PyObject *item);
23 : : static int PLy_result_ass_subscript(PyObject *arg, PyObject *item, PyObject *value);
24 : :
25 : : static char PLy_result_doc[] = "Results of a PostgreSQL query";
26 : :
27 : : static PySequenceMethods PLy_result_as_sequence = {
28 : : .sq_length = PLy_result_length,
29 : : .sq_item = PLy_result_item,
30 : : };
31 : :
32 : : static PyMappingMethods PLy_result_as_mapping = {
33 : : .mp_length = PLy_result_length,
34 : : .mp_subscript = PLy_result_subscript,
35 : : .mp_ass_subscript = PLy_result_ass_subscript,
36 : : };
37 : :
38 : : static PyMethodDef PLy_result_methods[] = {
39 : : {"colnames", PLy_result_colnames, METH_NOARGS, NULL},
40 : : {"coltypes", PLy_result_coltypes, METH_NOARGS, NULL},
41 : : {"coltypmods", PLy_result_coltypmods, METH_NOARGS, NULL},
42 : : {"nrows", PLy_result_nrows, METH_VARARGS, NULL},
43 : : {"status", PLy_result_status, METH_VARARGS, NULL},
44 : : {NULL, NULL, 0, NULL}
45 : : };
46 : :
47 : : static PyTypeObject PLy_ResultType = {
48 : : PyVarObject_HEAD_INIT(NULL, 0)
49 : : .tp_name = "PLyResult",
50 : : .tp_basicsize = sizeof(PLyResultObject),
51 : : .tp_dealloc = PLy_result_dealloc,
52 : : .tp_as_sequence = &PLy_result_as_sequence,
53 : : .tp_as_mapping = &PLy_result_as_mapping,
54 : : .tp_str = &PLy_result_str,
55 : : .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
56 : : .tp_doc = PLy_result_doc,
57 : : .tp_methods = PLy_result_methods,
58 : : };
59 : :
60 : : void
4501 peter_e@gmx.net 61 :CBC 23 : PLy_result_init_type(void)
62 : : {
63 [ - + ]: 23 : if (PyType_Ready(&PLy_ResultType) < 0)
4501 peter_e@gmx.net 64 [ # # ]:UBC 0 : elog(ERROR, "could not initialize PLy_ResultType");
4501 peter_e@gmx.net 65 :CBC 23 : }
66 : :
67 : : PyObject *
68 : 150 : PLy_result_new(void)
69 : : {
70 : : PLyResultObject *ob;
71 : :
72 [ - + ]: 150 : if ((ob = PyObject_New(PLyResultObject, &PLy_ResultType)) == NULL)
4501 peter_e@gmx.net 73 :UBC 0 : return NULL;
74 : :
75 : : /* ob->tuples = NULL; */
76 : :
4501 peter_e@gmx.net 77 :CBC 150 : Py_INCREF(Py_None);
78 : 150 : ob->status = Py_None;
769 andres@anarazel.de 79 : 150 : ob->nrows = PyLong_FromLong(-1);
4501 peter_e@gmx.net 80 : 150 : ob->rows = PyList_New(0);
4458 81 : 150 : ob->tupdesc = NULL;
2357 82 [ - + ]: 150 : if (!ob->rows)
83 : : {
2357 peter_e@gmx.net 84 :UBC 0 : Py_DECREF(ob);
85 : 0 : return NULL;
86 : : }
87 : :
4501 peter_e@gmx.net 88 :CBC 150 : return (PyObject *) ob;
89 : : }
90 : :
91 : : static void
92 : 149 : PLy_result_dealloc(PyObject *arg)
93 : : {
94 : 149 : PLyResultObject *ob = (PLyResultObject *) arg;
95 : :
96 : 149 : Py_XDECREF(ob->nrows);
97 : 149 : Py_XDECREF(ob->rows);
98 : 149 : Py_XDECREF(ob->status);
4458 99 [ + + ]: 149 : if (ob->tupdesc)
100 : : {
101 : 59 : FreeTupleDesc(ob->tupdesc);
102 : 59 : ob->tupdesc = NULL;
103 : : }
104 : :
4501 105 : 149 : arg->ob_type->tp_free(arg);
106 : 149 : }
107 : :
108 : : static PyObject *
4458 109 : 2 : PLy_result_colnames(PyObject *self, PyObject *unused)
110 : : {
111 : 2 : PLyResultObject *ob = (PLyResultObject *) self;
112 : : PyObject *list;
113 : : int i;
114 : :
4382 115 [ + + ]: 2 : if (!ob->tupdesc)
116 : : {
117 : 1 : PLy_exception_set(PLy_exc_error, "command did not produce a result set");
118 : 1 : return NULL;
119 : : }
120 : :
4458 121 : 1 : list = PyList_New(ob->tupdesc->natts);
2357 122 [ - + ]: 1 : if (!list)
2357 peter_e@gmx.net 123 :UBC 0 : return NULL;
4458 peter_e@gmx.net 124 [ + + ]:CBC 3 : for (i = 0; i < ob->tupdesc->natts; i++)
125 : : {
2429 andres@anarazel.de 126 : 2 : Form_pg_attribute attr = TupleDescAttr(ob->tupdesc, i);
127 : :
769 128 : 2 : PyList_SET_ITEM(list, i, PLyUnicode_FromString(NameStr(attr->attname)));
129 : : }
130 : :
4458 peter_e@gmx.net 131 : 1 : return list;
132 : : }
133 : :
134 : : static PyObject *
135 : 1 : PLy_result_coltypes(PyObject *self, PyObject *unused)
136 : : {
137 : 1 : PLyResultObject *ob = (PLyResultObject *) self;
138 : : PyObject *list;
139 : : int i;
140 : :
4382 141 [ - + ]: 1 : if (!ob->tupdesc)
142 : : {
4382 peter_e@gmx.net 143 :UBC 0 : PLy_exception_set(PLy_exc_error, "command did not produce a result set");
144 : 0 : return NULL;
145 : : }
146 : :
4458 peter_e@gmx.net 147 :CBC 1 : list = PyList_New(ob->tupdesc->natts);
2357 148 [ - + ]: 1 : if (!list)
2357 peter_e@gmx.net 149 :UBC 0 : return NULL;
4458 peter_e@gmx.net 150 [ + + ]:CBC 3 : for (i = 0; i < ob->tupdesc->natts; i++)
151 : : {
2429 andres@anarazel.de 152 : 2 : Form_pg_attribute attr = TupleDescAttr(ob->tupdesc, i);
153 : :
769 154 : 2 : PyList_SET_ITEM(list, i, PyLong_FromLong(attr->atttypid));
155 : : }
156 : :
4458 peter_e@gmx.net 157 : 1 : return list;
158 : : }
159 : :
160 : : static PyObject *
161 : 1 : PLy_result_coltypmods(PyObject *self, PyObject *unused)
162 : : {
163 : 1 : PLyResultObject *ob = (PLyResultObject *) self;
164 : : PyObject *list;
165 : : int i;
166 : :
4382 167 [ - + ]: 1 : if (!ob->tupdesc)
168 : : {
4382 peter_e@gmx.net 169 :UBC 0 : PLy_exception_set(PLy_exc_error, "command did not produce a result set");
170 : 0 : return NULL;
171 : : }
172 : :
4458 peter_e@gmx.net 173 :CBC 1 : list = PyList_New(ob->tupdesc->natts);
2357 174 [ - + ]: 1 : if (!list)
2357 peter_e@gmx.net 175 :UBC 0 : return NULL;
4458 peter_e@gmx.net 176 [ + + ]:CBC 3 : for (i = 0; i < ob->tupdesc->natts; i++)
177 : : {
2429 andres@anarazel.de 178 : 2 : Form_pg_attribute attr = TupleDescAttr(ob->tupdesc, i);
179 : :
769 180 : 2 : PyList_SET_ITEM(list, i, PyLong_FromLong(attr->atttypmod));
181 : : }
182 : :
4458 peter_e@gmx.net 183 : 1 : return list;
184 : : }
185 : :
186 : : static PyObject *
4501 187 : 7 : PLy_result_nrows(PyObject *self, PyObject *args)
188 : : {
189 : 7 : PLyResultObject *ob = (PLyResultObject *) self;
190 : :
191 : 7 : Py_INCREF(ob->nrows);
192 : 7 : return ob->nrows;
193 : : }
194 : :
195 : : static PyObject *
196 : 2 : PLy_result_status(PyObject *self, PyObject *args)
197 : : {
198 : 2 : PLyResultObject *ob = (PLyResultObject *) self;
199 : :
200 : 2 : Py_INCREF(ob->status);
201 : 2 : return ob->status;
202 : : }
203 : :
204 : : static Py_ssize_t
205 : 13 : PLy_result_length(PyObject *arg)
206 : : {
207 : 13 : PLyResultObject *ob = (PLyResultObject *) arg;
208 : :
209 : 13 : return PyList_Size(ob->rows);
210 : : }
211 : :
212 : : static PyObject *
213 : 28 : PLy_result_item(PyObject *arg, Py_ssize_t idx)
214 : : {
215 : : PyObject *rv;
216 : 28 : PLyResultObject *ob = (PLyResultObject *) arg;
217 : :
218 : 28 : rv = PyList_GetItem(ob->rows, idx);
219 [ + + ]: 28 : if (rv != NULL)
220 : 20 : Py_INCREF(rv);
221 : 28 : return rv;
222 : : }
223 : :
224 : : static PyObject *
4088 225 : 2 : PLy_result_str(PyObject *arg)
226 : : {
227 : 2 : PLyResultObject *ob = (PLyResultObject *) arg;
228 : :
229 : 2 : return PyUnicode_FromFormat("<%s status=%S nrows=%S rows=%S>",
230 : 2 : Py_TYPE(ob)->tp_name,
231 : : ob->status,
232 : : ob->nrows,
233 : : ob->rows);
234 : : }
235 : :
236 : : static PyObject *
4357 237 : 46 : PLy_result_subscript(PyObject *arg, PyObject *item)
238 : : {
4326 bruce@momjian.us 239 : 46 : PLyResultObject *ob = (PLyResultObject *) arg;
240 : :
4357 peter_e@gmx.net 241 : 46 : return PyObject_GetItem(ob->rows, item);
242 : : }
243 : :
244 : : static int
245 : 2 : PLy_result_ass_subscript(PyObject *arg, PyObject *item, PyObject *value)
246 : : {
4326 bruce@momjian.us 247 : 2 : PLyResultObject *ob = (PLyResultObject *) arg;
248 : :
4357 peter_e@gmx.net 249 : 2 : return PyObject_SetItem(ob->rows, item, value);
250 : : }
|