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