4 * src/pl/plpython/plpy_resultobject.c
11 #include "plpy_resultobject.h"
12 #include "plpy_elog.h"
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);
29 static char PLy_result_doc[] = {
30 "Results of a PostgreSQL query"
33 static PySequenceMethods PLy_result_as_sequence = {
34 PLy_result_length, /* sq_length */
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 */
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 */
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},
58 static PyTypeObject PLy_ResultType = {
59 PyVarObject_HEAD_INIT(NULL, 0)
60 "PLyResult", /* tp_name */
61 sizeof(PLyResultObject), /* tp_size */
67 PLy_result_dealloc, /* tp_dealloc */
74 &PLy_result_as_sequence, /* tp_as_sequence */
75 &PLy_result_as_mapping, /* tp_as_mapping */
78 &PLy_result_str, /* tp_str */
82 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
83 PLy_result_doc, /* tp_doc */
86 0, /* tp_richcompare */
87 0, /* tp_weaklistoffset */
90 PLy_result_methods, /* tp_tpmethods */
94 PLy_result_init_type(void)
96 if (PyType_Ready(&PLy_ResultType) < 0)
97 elog(ERROR, "could not initialize PLy_ResultType");
105 if ((ob = PyObject_New(PLyResultObject, &PLy_ResultType)) == NULL)
108 /* ob->tuples = NULL; */
111 ob->status = Py_None;
112 ob->nrows = PyInt_FromLong(-1);
113 ob->rows = PyList_New(0);
121 return (PyObject *) ob;
125 PLy_result_dealloc(PyObject *arg)
127 PLyResultObject *ob = (PLyResultObject *) arg;
129 Py_XDECREF(ob->nrows);
130 Py_XDECREF(ob->rows);
131 Py_XDECREF(ob->status);
134 FreeTupleDesc(ob->tupdesc);
138 arg->ob_type->tp_free(arg);
142 PLy_result_colnames(PyObject *self, PyObject *unused)
144 PLyResultObject *ob = (PLyResultObject *) self;
150 PLy_exception_set(PLy_exc_error, "command did not produce a result set");
154 list = PyList_New(ob->tupdesc->natts);
157 for (i = 0; i < ob->tupdesc->natts; i++)
159 Form_pg_attribute attr = TupleDescAttr(ob->tupdesc, i);
161 PyList_SET_ITEM(list, i, PyString_FromString(NameStr(attr->attname)));
168 PLy_result_coltypes(PyObject *self, PyObject *unused)
170 PLyResultObject *ob = (PLyResultObject *) self;
176 PLy_exception_set(PLy_exc_error, "command did not produce a result set");
180 list = PyList_New(ob->tupdesc->natts);
183 for (i = 0; i < ob->tupdesc->natts; i++)
185 Form_pg_attribute attr = TupleDescAttr(ob->tupdesc, i);
187 PyList_SET_ITEM(list, i, PyInt_FromLong(attr->atttypid));
194 PLy_result_coltypmods(PyObject *self, PyObject *unused)
196 PLyResultObject *ob = (PLyResultObject *) self;
202 PLy_exception_set(PLy_exc_error, "command did not produce a result set");
206 list = PyList_New(ob->tupdesc->natts);
209 for (i = 0; i < ob->tupdesc->natts; i++)
211 Form_pg_attribute attr = TupleDescAttr(ob->tupdesc, i);
213 PyList_SET_ITEM(list, i, PyInt_FromLong(attr->atttypmod));
220 PLy_result_nrows(PyObject *self, PyObject *args)
222 PLyResultObject *ob = (PLyResultObject *) self;
224 Py_INCREF(ob->nrows);
229 PLy_result_status(PyObject *self, PyObject *args)
231 PLyResultObject *ob = (PLyResultObject *) self;
233 Py_INCREF(ob->status);
238 PLy_result_length(PyObject *arg)
240 PLyResultObject *ob = (PLyResultObject *) arg;
242 return PyList_Size(ob->rows);
246 PLy_result_item(PyObject *arg, Py_ssize_t idx)
249 PLyResultObject *ob = (PLyResultObject *) arg;
251 rv = PyList_GetItem(ob->rows, idx);
258 PLy_result_slice(PyObject *arg, Py_ssize_t lidx, Py_ssize_t hidx)
260 PLyResultObject *ob = (PLyResultObject *) arg;
262 return PyList_GetSlice(ob->rows, lidx, hidx);
266 PLy_result_ass_slice(PyObject *arg, Py_ssize_t lidx, Py_ssize_t hidx, PyObject *slice)
269 PLyResultObject *ob = (PLyResultObject *) arg;
271 rv = PyList_SetSlice(ob->rows, lidx, hidx, slice);
276 PLy_result_str(PyObject *arg)
278 PLyResultObject *ob = (PLyResultObject *) arg;
280 #if PY_MAJOR_VERSION >= 3
281 return PyUnicode_FromFormat("<%s status=%S nrows=%S rows=%S>",
282 Py_TYPE(ob)->tp_name,
287 return PyString_FromFormat("<%s status=%ld nrows=%ld rows=%s>",
288 ob->ob_type->tp_name,
289 PyInt_AsLong(ob->status),
290 PyInt_AsLong(ob->nrows),
291 PyString_AsString(PyObject_Str(ob->rows)));
296 PLy_result_subscript(PyObject *arg, PyObject *item)
298 PLyResultObject *ob = (PLyResultObject *) arg;
300 return PyObject_GetItem(ob->rows, item);
304 PLy_result_ass_subscript(PyObject *arg, PyObject *item, PyObject *value)
306 PLyResultObject *ob = (PLyResultObject *) arg;
308 return PyObject_SetItem(ob->rows, item, value);