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[] = "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
62 {
63  if (PyType_Ready(&PLy_ResultType) < 0)
64  elog(ERROR, "could not initialize PLy_ResultType");
65 }
66 
67 PyObject *
69 {
70  PLyResultObject *ob;
71 
72  if ((ob = PyObject_New(PLyResultObject, &PLy_ResultType)) == NULL)
73  return NULL;
74 
75  /* ob->tuples = NULL; */
76 
77  Py_INCREF(Py_None);
78  ob->status = Py_None;
79  ob->nrows = PyInt_FromLong(-1);
80  ob->rows = PyList_New(0);
81  ob->tupdesc = NULL;
82  if (!ob->rows)
83  {
84  Py_DECREF(ob);
85  return NULL;
86  }
87 
88  return (PyObject *) ob;
89 }
90 
91 static void
93 {
94  PLyResultObject *ob = (PLyResultObject *) arg;
95 
96  Py_XDECREF(ob->nrows);
97  Py_XDECREF(ob->rows);
98  Py_XDECREF(ob->status);
99  if (ob->tupdesc)
100  {
101  FreeTupleDesc(ob->tupdesc);
102  ob->tupdesc = NULL;
103  }
104 
105  arg->ob_type->tp_free(arg);
106 }
107 
108 static PyObject *
109 PLy_result_colnames(PyObject *self, PyObject *unused)
110 {
111  PLyResultObject *ob = (PLyResultObject *) self;
112  PyObject *list;
113  int i;
114 
115  if (!ob->tupdesc)
116  {
117  PLy_exception_set(PLy_exc_error, "command did not produce a result set");
118  return NULL;
119  }
120 
121  list = PyList_New(ob->tupdesc->natts);
122  if (!list)
123  return NULL;
124  for (i = 0; i < ob->tupdesc->natts; i++)
125  {
126  Form_pg_attribute attr = TupleDescAttr(ob->tupdesc, i);
127 
128  PyList_SET_ITEM(list, i, PyString_FromString(NameStr(attr->attname)));
129  }
130 
131  return list;
132 }
133 
134 static PyObject *
135 PLy_result_coltypes(PyObject *self, PyObject *unused)
136 {
137  PLyResultObject *ob = (PLyResultObject *) self;
138  PyObject *list;
139  int i;
140 
141  if (!ob->tupdesc)
142  {
143  PLy_exception_set(PLy_exc_error, "command did not produce a result set");
144  return NULL;
145  }
146 
147  list = PyList_New(ob->tupdesc->natts);
148  if (!list)
149  return NULL;
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, PyInt_FromLong(attr->atttypid));
155  }
156 
157  return list;
158 }
159 
160 static PyObject *
161 PLy_result_coltypmods(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  if (!list)
175  return NULL;
176  for (i = 0; i < ob->tupdesc->natts; i++)
177  {
178  Form_pg_attribute attr = TupleDescAttr(ob->tupdesc, i);
179 
180  PyList_SET_ITEM(list, i, PyInt_FromLong(attr->atttypmod));
181  }
182 
183  return list;
184 }
185 
186 static PyObject *
187 PLy_result_nrows(PyObject *self, PyObject *args)
188 {
189  PLyResultObject *ob = (PLyResultObject *) self;
190 
191  Py_INCREF(ob->nrows);
192  return ob->nrows;
193 }
194 
195 static PyObject *
196 PLy_result_status(PyObject *self, PyObject *args)
197 {
198  PLyResultObject *ob = (PLyResultObject *) self;
199 
200  Py_INCREF(ob->status);
201  return ob->status;
202 }
203 
204 static Py_ssize_t
206 {
207  PLyResultObject *ob = (PLyResultObject *) arg;
208 
209  return PyList_Size(ob->rows);
210 }
211 
212 static PyObject *
213 PLy_result_item(PyObject *arg, Py_ssize_t idx)
214 {
215  PyObject *rv;
216  PLyResultObject *ob = (PLyResultObject *) arg;
217 
218  rv = PyList_GetItem(ob->rows, idx);
219  if (rv != NULL)
220  Py_INCREF(rv);
221  return rv;
222 }
223 
224 static PyObject *
225 PLy_result_str(PyObject *arg)
226 {
227  PLyResultObject *ob = (PLyResultObject *) arg;
228 
229 #if PY_MAJOR_VERSION >= 3
230  return PyUnicode_FromFormat("<%s status=%S nrows=%S rows=%S>",
231  Py_TYPE(ob)->tp_name,
232  ob->status,
233  ob->nrows,
234  ob->rows);
235 #else
236  return PyString_FromFormat("<%s status=%ld nrows=%ld rows=%s>",
237  ob->ob_type->tp_name,
238  PyInt_AsLong(ob->status),
239  PyInt_AsLong(ob->nrows),
240  PyString_AsString(PyObject_Str(ob->rows)));
241 #endif
242 }
243 
244 static PyObject *
245 PLy_result_subscript(PyObject *arg, PyObject *item)
246 {
247  PLyResultObject *ob = (PLyResultObject *) arg;
248 
249  return PyObject_GetItem(ob->rows, item);
250 }
251 
252 static int
253 PLy_result_ass_subscript(PyObject *arg, PyObject *item, PyObject *value)
254 {
255  PLyResultObject *ob = (PLyResultObject *) arg;
256 
257  return PyObject_SetItem(ob->rows, item, value);
258 }
static PyObject * PLy_result_status(PyObject *self, PyObject *args)
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
PyObject * PLy_exc_error
Definition: plpy_elog.c:15
Datum idx(PG_FUNCTION_ARGS)
Definition: _int_op.c:259
void PLy_exception_set(PyObject *exc, const char *fmt,...)
Definition: plpy_elog.c:479
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:193
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 struct @143 value
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:214
int i
#define NameStr(name)
Definition: c.h:615
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)