PostgreSQL Source Code  git master
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 "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_slice(PyObject *arg, Py_ssize_t lidx, Py_ssize_t hidx);
24 static int PLy_result_ass_slice(PyObject *arg, Py_ssize_t lidx, Py_ssize_t hidx, PyObject *slice);
25 static PyObject *PLy_result_str(PyObject *arg);
26 static PyObject *PLy_result_subscript(PyObject *arg, PyObject *item);
27 static int PLy_result_ass_subscript(PyObject *self, PyObject *item, PyObject *value);
28 
29 static char PLy_result_doc[] = {
30  "Results of a PostgreSQL query"
31 };
32 
33 static PySequenceMethods PLy_result_as_sequence = {
34  PLy_result_length, /* sq_length */
35  NULL, /* sq_concat */
36  NULL, /* sq_repeat */
37  PLy_result_item, /* sq_item */
38  PLy_result_slice, /* sq_slice */
39  NULL, /* sq_ass_item */
40  PLy_result_ass_slice, /* sq_ass_slice */
41 };
42 
43 static PyMappingMethods PLy_result_as_mapping = {
44  PLy_result_length, /* mp_length */
45  PLy_result_subscript, /* mp_subscript */
46  PLy_result_ass_subscript, /* mp_ass_subscript */
47 };
48 
49 static PyMethodDef PLy_result_methods[] = {
50  {"colnames", PLy_result_colnames, METH_NOARGS, NULL},
51  {"coltypes", PLy_result_coltypes, METH_NOARGS, NULL},
52  {"coltypmods", PLy_result_coltypmods, METH_NOARGS, NULL},
53  {"nrows", PLy_result_nrows, METH_VARARGS, NULL},
54  {"status", PLy_result_status, METH_VARARGS, NULL},
55  {NULL, NULL, 0, NULL}
56 };
57 
58 static PyTypeObject PLy_ResultType = {
59  PyVarObject_HEAD_INIT(NULL, 0)
60  "PLyResult", /* tp_name */
61  sizeof(PLyResultObject), /* tp_size */
62  0, /* tp_itemsize */
63 
64  /*
65  * methods
66  */
67  PLy_result_dealloc, /* tp_dealloc */
68  0, /* tp_print */
69  0, /* tp_getattr */
70  0, /* tp_setattr */
71  0, /* tp_compare */
72  0, /* tp_repr */
73  0, /* tp_as_number */
74  &PLy_result_as_sequence, /* tp_as_sequence */
75  &PLy_result_as_mapping, /* tp_as_mapping */
76  0, /* tp_hash */
77  0, /* tp_call */
78  &PLy_result_str, /* tp_str */
79  0, /* tp_getattro */
80  0, /* tp_setattro */
81  0, /* tp_as_buffer */
82  Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
83  PLy_result_doc, /* tp_doc */
84  0, /* tp_traverse */
85  0, /* tp_clear */
86  0, /* tp_richcompare */
87  0, /* tp_weaklistoffset */
88  0, /* tp_iter */
89  0, /* tp_iternext */
90  PLy_result_methods, /* tp_tpmethods */
91 };
92 
93 void
95 {
96  if (PyType_Ready(&PLy_ResultType) < 0)
97  elog(ERROR, "could not initialize PLy_ResultType");
98 }
99 
100 PyObject *
102 {
103  PLyResultObject *ob;
104 
105  if ((ob = PyObject_New(PLyResultObject, &PLy_ResultType)) == NULL)
106  return NULL;
107 
108  /* ob->tuples = NULL; */
109 
110  Py_INCREF(Py_None);
111  ob->status = Py_None;
112  ob->nrows = PyInt_FromLong(-1);
113  ob->rows = PyList_New(0);
114  ob->tupdesc = NULL;
115 
116  return (PyObject *) ob;
117 }
118 
119 static void
121 {
122  PLyResultObject *ob = (PLyResultObject *) arg;
123 
124  Py_XDECREF(ob->nrows);
125  Py_XDECREF(ob->rows);
126  Py_XDECREF(ob->status);
127  if (ob->tupdesc)
128  {
129  FreeTupleDesc(ob->tupdesc);
130  ob->tupdesc = NULL;
131  }
132 
133  arg->ob_type->tp_free(arg);
134 }
135 
136 static PyObject *
137 PLy_result_colnames(PyObject *self, PyObject *unused)
138 {
139  PLyResultObject *ob = (PLyResultObject *) self;
140  PyObject *list;
141  int i;
142 
143  if (!ob->tupdesc)
144  {
145  PLy_exception_set(PLy_exc_error, "command did not produce a result set");
146  return NULL;
147  }
148 
149  list = PyList_New(ob->tupdesc->natts);
150  for (i = 0; i < ob->tupdesc->natts; i++)
151  {
152  Form_pg_attribute attr = TupleDescAttr(ob->tupdesc, i);
153 
154  PyList_SET_ITEM(list, i, PyString_FromString(NameStr(attr->attname)));
155  }
156 
157  return list;
158 }
159 
160 static PyObject *
161 PLy_result_coltypes(PyObject *self, PyObject *unused)
162 {
163  PLyResultObject *ob = (PLyResultObject *) self;
164  PyObject *list;
165  int i;
166 
167  if (!ob->tupdesc)
168  {
169  PLy_exception_set(PLy_exc_error, "command did not produce a result set");
170  return NULL;
171  }
172 
173  list = PyList_New(ob->tupdesc->natts);
174  for (i = 0; i < ob->tupdesc->natts; i++)
175  {
176  Form_pg_attribute attr = TupleDescAttr(ob->tupdesc, i);
177 
178  PyList_SET_ITEM(list, i, PyInt_FromLong(attr->atttypid));
179  }
180 
181  return list;
182 }
183 
184 static PyObject *
185 PLy_result_coltypmods(PyObject *self, PyObject *unused)
186 {
187  PLyResultObject *ob = (PLyResultObject *) self;
188  PyObject *list;
189  int i;
190 
191  if (!ob->tupdesc)
192  {
193  PLy_exception_set(PLy_exc_error, "command did not produce a result set");
194  return NULL;
195  }
196 
197  list = PyList_New(ob->tupdesc->natts);
198  for (i = 0; i < ob->tupdesc->natts; i++)
199  {
200  Form_pg_attribute attr = TupleDescAttr(ob->tupdesc, i);
201 
202  PyList_SET_ITEM(list, i, PyInt_FromLong(attr->atttypmod));
203  }
204 
205  return list;
206 }
207 
208 static PyObject *
209 PLy_result_nrows(PyObject *self, PyObject *args)
210 {
211  PLyResultObject *ob = (PLyResultObject *) self;
212 
213  Py_INCREF(ob->nrows);
214  return ob->nrows;
215 }
216 
217 static PyObject *
218 PLy_result_status(PyObject *self, PyObject *args)
219 {
220  PLyResultObject *ob = (PLyResultObject *) self;
221 
222  Py_INCREF(ob->status);
223  return ob->status;
224 }
225 
226 static Py_ssize_t
228 {
229  PLyResultObject *ob = (PLyResultObject *) arg;
230 
231  return PyList_Size(ob->rows);
232 }
233 
234 static PyObject *
236 {
237  PyObject *rv;
238  PLyResultObject *ob = (PLyResultObject *) arg;
239 
240  rv = PyList_GetItem(ob->rows, idx);
241  if (rv != NULL)
242  Py_INCREF(rv);
243  return rv;
244 }
245 
246 static PyObject *
248 {
249  PLyResultObject *ob = (PLyResultObject *) arg;
250 
251  return PyList_GetSlice(ob->rows, lidx, hidx);
252 }
253 
254 static int
255 PLy_result_ass_slice(PyObject *arg, Py_ssize_t lidx, Py_ssize_t hidx, PyObject *slice)
256 {
257  int rv;
258  PLyResultObject *ob = (PLyResultObject *) arg;
259 
260  rv = PyList_SetSlice(ob->rows, lidx, hidx, slice);
261  return rv;
262 }
263 
264 static PyObject *
265 PLy_result_str(PyObject *arg)
266 {
267  PLyResultObject *ob = (PLyResultObject *) arg;
268 
269 #if PY_MAJOR_VERSION >= 3
270  return PyUnicode_FromFormat("<%s status=%S nrows=%S rows=%S>",
271  Py_TYPE(ob)->tp_name,
272  ob->status,
273  ob->nrows,
274  ob->rows);
275 #else
276  return PyString_FromFormat("<%s status=%ld nrows=%ld rows=%s>",
277  ob->ob_type->tp_name,
278  PyInt_AsLong(ob->status),
279  PyInt_AsLong(ob->nrows),
280  PyString_AsString(PyObject_Str(ob->rows)));
281 #endif
282 }
283 
284 static PyObject *
285 PLy_result_subscript(PyObject *arg, PyObject *item)
286 {
287  PLyResultObject *ob = (PLyResultObject *) arg;
288 
289  return PyObject_GetItem(ob->rows, item);
290 }
291 
292 static int
293 PLy_result_ass_subscript(PyObject *arg, PyObject *item, PyObject *value)
294 {
295  PLyResultObject *ob = (PLyResultObject *) arg;
296 
297  return PyObject_SetItem(ob->rows, item, value);
298 }
static PyObject * PLy_result_status(PyObject *self, PyObject *args)
#define PyVarObject_HEAD_INIT(type, size)
Definition: plpython.h:111
static Py_ssize_t PLy_result_length(PyObject *arg)
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:90
static PyMethodDef PLy_result_methods[]
static PyObject * PLy_result_subscript(PyObject *arg, PyObject *item)
struct PLyResultObject PLyResultObject
PyObject * PLy_exc_error
Definition: plpy_elog.c:19
Datum idx(PG_FUNCTION_ARGS)
Definition: _int_op.c:264
void PLy_exception_set(PyObject *exc, const char *fmt,...)
Definition: plpy_elog.c:500
int natts
Definition: tupdesc.h:79
int Py_ssize_t
Definition: plpython.h:64
static PySequenceMethods PLy_result_as_sequence
#define ERROR
Definition: elog.h:43
static char PLy_result_doc[]
static struct @121 value
static PyTypeObject PLy_ResultType
static PyObject * PLy_result_nrows(PyObject *self, PyObject *args)
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:187
static PyObject * PLy_result_colnames(PyObject *self, PyObject *unused)
static PyObject * PLy_result_coltypes(PyObject *self, PyObject *unused)
static PyObject * PLy_result_item(PyObject *arg, Py_ssize_t idx)
static void PLy_result_dealloc(PyObject *arg)
static int PLy_result_ass_slice(PyObject *arg, Py_ssize_t lidx, Py_ssize_t hidx, PyObject *slice)
static PyObject * PLy_result_coltypmods(PyObject *self, PyObject *unused)
static PyObject * PLy_result_slice(PyObject *arg, Py_ssize_t lidx, Py_ssize_t hidx)
void FreeTupleDesc(TupleDesc tupdesc)
Definition: tupdesc.c:251
void PLy_result_init_type(void)
PyObject * PLy_result_new(void)
int i
#define NameStr(name)
Definition: c.h:547
void * arg
PyObject_HEAD PyObject * nrows
static PyMappingMethods PLy_result_as_mapping
#define elog
Definition: elog.h:219
static PyObject * PLy_result_str(PyObject *arg)
static int PLy_result_ass_subscript(PyObject *self, PyObject *item, PyObject *value)