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 "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[] = {
26  "Results of a PostgreSQL query"
27 };
28 
29 static PySequenceMethods PLy_result_as_sequence = {
30  .sq_length = PLy_result_length,
31  .sq_item = PLy_result_item,
32 };
33 
34 static PyMappingMethods PLy_result_as_mapping = {
35  .mp_length = PLy_result_length,
36  .mp_subscript = PLy_result_subscript,
37  .mp_ass_subscript = PLy_result_ass_subscript,
38 };
39 
40 static PyMethodDef PLy_result_methods[] = {
41  {"colnames", PLy_result_colnames, METH_NOARGS, NULL},
42  {"coltypes", PLy_result_coltypes, METH_NOARGS, NULL},
43  {"coltypmods", PLy_result_coltypmods, METH_NOARGS, NULL},
44  {"nrows", PLy_result_nrows, METH_VARARGS, NULL},
45  {"status", PLy_result_status, METH_VARARGS, NULL},
46  {NULL, NULL, 0, NULL}
47 };
48 
49 static PyTypeObject PLy_ResultType = {
50  PyVarObject_HEAD_INIT(NULL, 0)
51  .tp_name = "PLyResult",
52  .tp_basicsize = sizeof(PLyResultObject),
53  .tp_dealloc = PLy_result_dealloc,
54  .tp_as_sequence = &PLy_result_as_sequence,
55  .tp_as_mapping = &PLy_result_as_mapping,
56  .tp_str = &PLy_result_str,
57  .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
58  .tp_doc = PLy_result_doc,
59  .tp_methods = PLy_result_methods,
60 };
61 
62 void
64 {
65  if (PyType_Ready(&PLy_ResultType) < 0)
66  elog(ERROR, "could not initialize PLy_ResultType");
67 }
68 
69 PyObject *
71 {
72  PLyResultObject *ob;
73 
74  if ((ob = PyObject_New(PLyResultObject, &PLy_ResultType)) == NULL)
75  return NULL;
76 
77  /* ob->tuples = NULL; */
78 
79  Py_INCREF(Py_None);
80  ob->status = Py_None;
81  ob->nrows = PyInt_FromLong(-1);
82  ob->rows = PyList_New(0);
83  ob->tupdesc = NULL;
84  if (!ob->rows)
85  {
86  Py_DECREF(ob);
87  return NULL;
88  }
89 
90  return (PyObject *) ob;
91 }
92 
93 static void
95 {
96  PLyResultObject *ob = (PLyResultObject *) arg;
97 
98  Py_XDECREF(ob->nrows);
99  Py_XDECREF(ob->rows);
100  Py_XDECREF(ob->status);
101  if (ob->tupdesc)
102  {
103  FreeTupleDesc(ob->tupdesc);
104  ob->tupdesc = NULL;
105  }
106 
107  arg->ob_type->tp_free(arg);
108 }
109 
110 static PyObject *
111 PLy_result_colnames(PyObject *self, PyObject *unused)
112 {
113  PLyResultObject *ob = (PLyResultObject *) self;
114  PyObject *list;
115  int i;
116 
117  if (!ob->tupdesc)
118  {
119  PLy_exception_set(PLy_exc_error, "command did not produce a result set");
120  return NULL;
121  }
122 
123  list = PyList_New(ob->tupdesc->natts);
124  if (!list)
125  return NULL;
126  for (i = 0; i < ob->tupdesc->natts; i++)
127  {
128  Form_pg_attribute attr = TupleDescAttr(ob->tupdesc, i);
129 
130  PyList_SET_ITEM(list, i, PyString_FromString(NameStr(attr->attname)));
131  }
132 
133  return list;
134 }
135 
136 static PyObject *
137 PLy_result_coltypes(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  if (!list)
151  return NULL;
152  for (i = 0; i < ob->tupdesc->natts; i++)
153  {
154  Form_pg_attribute attr = TupleDescAttr(ob->tupdesc, i);
155 
156  PyList_SET_ITEM(list, i, PyInt_FromLong(attr->atttypid));
157  }
158 
159  return list;
160 }
161 
162 static PyObject *
163 PLy_result_coltypmods(PyObject *self, PyObject *unused)
164 {
165  PLyResultObject *ob = (PLyResultObject *) self;
166  PyObject *list;
167  int i;
168 
169  if (!ob->tupdesc)
170  {
171  PLy_exception_set(PLy_exc_error, "command did not produce a result set");
172  return NULL;
173  }
174 
175  list = PyList_New(ob->tupdesc->natts);
176  if (!list)
177  return NULL;
178  for (i = 0; i < ob->tupdesc->natts; i++)
179  {
180  Form_pg_attribute attr = TupleDescAttr(ob->tupdesc, i);
181 
182  PyList_SET_ITEM(list, i, PyInt_FromLong(attr->atttypmod));
183  }
184 
185  return list;
186 }
187 
188 static PyObject *
189 PLy_result_nrows(PyObject *self, PyObject *args)
190 {
191  PLyResultObject *ob = (PLyResultObject *) self;
192 
193  Py_INCREF(ob->nrows);
194  return ob->nrows;
195 }
196 
197 static PyObject *
198 PLy_result_status(PyObject *self, PyObject *args)
199 {
200  PLyResultObject *ob = (PLyResultObject *) self;
201 
202  Py_INCREF(ob->status);
203  return ob->status;
204 }
205 
206 static Py_ssize_t
208 {
209  PLyResultObject *ob = (PLyResultObject *) arg;
210 
211  return PyList_Size(ob->rows);
212 }
213 
214 static PyObject *
216 {
217  PyObject *rv;
218  PLyResultObject *ob = (PLyResultObject *) arg;
219 
220  rv = PyList_GetItem(ob->rows, idx);
221  if (rv != NULL)
222  Py_INCREF(rv);
223  return rv;
224 }
225 
226 static PyObject *
227 PLy_result_str(PyObject *arg)
228 {
229  PLyResultObject *ob = (PLyResultObject *) arg;
230 
231 #if PY_MAJOR_VERSION >= 3
232  return PyUnicode_FromFormat("<%s status=%S nrows=%S rows=%S>",
233  Py_TYPE(ob)->tp_name,
234  ob->status,
235  ob->nrows,
236  ob->rows);
237 #else
238  return PyString_FromFormat("<%s status=%ld nrows=%ld rows=%s>",
239  ob->ob_type->tp_name,
240  PyInt_AsLong(ob->status),
241  PyInt_AsLong(ob->nrows),
242  PyString_AsString(PyObject_Str(ob->rows)));
243 #endif
244 }
245 
246 static PyObject *
247 PLy_result_subscript(PyObject *arg, PyObject *item)
248 {
249  PLyResultObject *ob = (PLyResultObject *) arg;
250 
251  return PyObject_GetItem(ob->rows, item);
252 }
253 
254 static int
255 PLy_result_ass_subscript(PyObject *arg, PyObject *item, PyObject *value)
256 {
257  PLyResultObject *ob = (PLyResultObject *) arg;
258 
259  return PyObject_SetItem(ob->rows, item, value);
260 }
static PyObject * PLy_result_status(PyObject *self, PyObject *args)
#define PyVarObject_HEAD_INIT(type, size)
Definition: plpython.h:113
static Py_ssize_t PLy_result_length(PyObject *arg)
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
static PyMethodDef PLy_result_methods[]
static PyObject * PLy_result_subscript(PyObject *arg, PyObject *item)
struct PLyResultObject PLyResultObject
static struct @145 value
PyObject * PLy_exc_error
Definition: plpy_elog.c:15
Datum idx(PG_FUNCTION_ARGS)
Definition: _int_op.c:263
void PLy_exception_set(PyObject *exc, const char *fmt,...)
Definition: plpy_elog.c:487
int Py_ssize_t
Definition: plpython.h:66
static PySequenceMethods PLy_result_as_sequence
#define ERROR
Definition: elog.h:43
static char PLy_result_doc[]
static PyTypeObject PLy_ResultType
static PyObject * PLy_result_nrows(PyObject *self, PyObject *args)
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:200
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 PyObject * PLy_result_coltypmods(PyObject *self, PyObject *unused)
void FreeTupleDesc(TupleDesc tupdesc)
Definition: tupdesc.c:313
void PLy_result_init_type(void)
PyObject * PLy_result_new(void)
#define elog(elevel,...)
Definition: elog.h:228
int i
#define NameStr(name)
Definition: c.h:616
void * arg
PyObject_HEAD PyObject * nrows
static PyMappingMethods PLy_result_as_mapping
static PyObject * PLy_result_str(PyObject *arg)
static int PLy_result_ass_subscript(PyObject *self, PyObject *item, PyObject *value)