Age Owner 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 *self, 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
4130 peter_e 61 CBC 23 : PLy_result_init_type(void)
62 : {
63 23 : if (PyType_Ready(&PLy_ResultType) < 0)
4130 peter_e 64 UBC 0 : elog(ERROR, "could not initialize PLy_ResultType");
4130 peter_e 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)
4130 peter_e 73 UBC 0 : return NULL;
74 :
75 : /* ob->tuples = NULL; */
76 :
4130 peter_e 77 CBC 150 : Py_INCREF(Py_None);
78 150 : ob->status = Py_None;
398 andres 79 150 : ob->nrows = PyLong_FromLong(-1);
4130 peter_e 80 150 : ob->rows = PyList_New(0);
4087 81 150 : ob->tupdesc = NULL;
1986 82 150 : if (!ob->rows)
83 : {
1986 peter_e 84 UBC 0 : Py_DECREF(ob);
85 0 : return NULL;
86 : }
87 :
4130 peter_e 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);
4087 99 149 : if (ob->tupdesc)
100 : {
101 59 : FreeTupleDesc(ob->tupdesc);
102 59 : ob->tupdesc = NULL;
103 : }
104 :
4130 105 149 : arg->ob_type->tp_free(arg);
106 149 : }
107 :
108 : static PyObject *
4087 109 2 : PLy_result_colnames(PyObject *self, PyObject *unused)
110 : {
111 2 : PLyResultObject *ob = (PLyResultObject *) self;
112 : PyObject *list;
113 : int i;
114 :
4011 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 :
4087 121 1 : list = PyList_New(ob->tupdesc->natts);
1986 122 1 : if (!list)
1986 peter_e 123 UBC 0 : return NULL;
4087 peter_e 124 CBC 3 : for (i = 0; i < ob->tupdesc->natts; i++)
125 : {
2058 andres 126 2 : Form_pg_attribute attr = TupleDescAttr(ob->tupdesc, i);
127 :
398 128 2 : PyList_SET_ITEM(list, i, PLyUnicode_FromString(NameStr(attr->attname)));
129 : }
130 :
4087 peter_e 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 :
4011 141 1 : if (!ob->tupdesc)
142 : {
4011 peter_e 143 UBC 0 : PLy_exception_set(PLy_exc_error, "command did not produce a result set");
144 0 : return NULL;
145 : }
146 :
4087 peter_e 147 CBC 1 : list = PyList_New(ob->tupdesc->natts);
1986 148 1 : if (!list)
1986 peter_e 149 UBC 0 : return NULL;
4087 peter_e 150 CBC 3 : for (i = 0; i < ob->tupdesc->natts; i++)
151 : {
2058 andres 152 2 : Form_pg_attribute attr = TupleDescAttr(ob->tupdesc, i);
153 :
398 154 2 : PyList_SET_ITEM(list, i, PyLong_FromLong(attr->atttypid));
155 : }
156 :
4087 peter_e 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 :
4011 167 1 : if (!ob->tupdesc)
168 : {
4011 peter_e 169 UBC 0 : PLy_exception_set(PLy_exc_error, "command did not produce a result set");
170 0 : return NULL;
171 : }
172 :
4087 peter_e 173 CBC 1 : list = PyList_New(ob->tupdesc->natts);
1986 174 1 : if (!list)
1986 peter_e 175 UBC 0 : return NULL;
4087 peter_e 176 CBC 3 : for (i = 0; i < ob->tupdesc->natts; i++)
177 : {
2058 andres 178 2 : Form_pg_attribute attr = TupleDescAttr(ob->tupdesc, i);
179 :
398 180 2 : PyList_SET_ITEM(list, i, PyLong_FromLong(attr->atttypmod));
181 : }
182 :
4087 peter_e 183 1 : return list;
184 : }
185 :
186 : static PyObject *
4130 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 *
3717 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 *
3986 237 46 : PLy_result_subscript(PyObject *arg, PyObject *item)
238 : {
3955 bruce 239 46 : PLyResultObject *ob = (PLyResultObject *) arg;
240 :
3986 peter_e 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 : {
3955 bruce 247 2 : PLyResultObject *ob = (PLyResultObject *) arg;
248 :
3986 peter_e 249 2 : return PyObject_SetItem(ob->rows, item, value);
250 : }
|