1 /*
2 * the PLyPlan class
3 *
4 * src/pl/plpython/plpy_planobject.c
5 */
6
7 #include "postgres.h"
8
9 #include "plpython.h"
10
11 #include "plpy_planobject.h"
12
13 #include "plpy_cursorobject.h"
14 #include "plpy_elog.h"
15 #include "plpy_spi.h"
16 #include "utils/memutils.h"
17
18
19 static void PLy_plan_dealloc(PyObject *arg);
20 static PyObject *PLy_plan_cursor(PyObject *self, PyObject *args);
21 static PyObject *PLy_plan_execute(PyObject *self, PyObject *args);
22 static PyObject *PLy_plan_status(PyObject *self, PyObject *args);
23
24 static char PLy_plan_doc[] = {
25 "Store a PostgreSQL plan"
26 };
27
28 static PyMethodDef PLy_plan_methods[] = {
29 {"cursor", PLy_plan_cursor, METH_VARARGS, NULL},
30 {"execute", PLy_plan_execute, METH_VARARGS, NULL},
31 {"status", PLy_plan_status, METH_VARARGS, NULL},
32 {NULL, NULL, 0, NULL}
33 };
34
35 static PyTypeObject PLy_PlanType = {
36 PyVarObject_HEAD_INIT(NULL, 0)
37 "PLyPlan", /* tp_name */
38 sizeof(PLyPlanObject), /* tp_size */
39 0, /* tp_itemsize */
40
41 /*
42 * methods
43 */
44 PLy_plan_dealloc, /* tp_dealloc */
45 0, /* tp_print */
46 0, /* tp_getattr */
47 0, /* tp_setattr */
48 0, /* tp_compare */
49 0, /* tp_repr */
50 0, /* tp_as_number */
51 0, /* tp_as_sequence */
52 0, /* tp_as_mapping */
53 0, /* tp_hash */
54 0, /* tp_call */
55 0, /* tp_str */
56 0, /* tp_getattro */
57 0, /* tp_setattro */
58 0, /* tp_as_buffer */
59 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
60 PLy_plan_doc, /* tp_doc */
61 0, /* tp_traverse */
62 0, /* tp_clear */
63 0, /* tp_richcompare */
64 0, /* tp_weaklistoffset */
65 0, /* tp_iter */
66 0, /* tp_iternext */
67 PLy_plan_methods, /* tp_tpmethods */
68 };
69
70 void
PLy_plan_init_type(void)71 PLy_plan_init_type(void)
72 {
73 if (PyType_Ready(&PLy_PlanType) < 0)
74 elog(ERROR, "could not initialize PLy_PlanType");
75 }
76
77 PyObject *
PLy_plan_new(void)78 PLy_plan_new(void)
79 {
80 PLyPlanObject *ob;
81
82 if ((ob = PyObject_New(PLyPlanObject, &PLy_PlanType)) == NULL)
83 return NULL;
84
85 ob->plan = NULL;
86 ob->nargs = 0;
87 ob->types = NULL;
88 ob->values = NULL;
89 ob->args = NULL;
90 ob->mcxt = NULL;
91
92 return (PyObject *) ob;
93 }
94
95 bool
is_PLyPlanObject(PyObject * ob)96 is_PLyPlanObject(PyObject *ob)
97 {
98 return ob->ob_type == &PLy_PlanType;
99 }
100
101 static void
PLy_plan_dealloc(PyObject * arg)102 PLy_plan_dealloc(PyObject *arg)
103 {
104 PLyPlanObject *ob = (PLyPlanObject *) arg;
105
106 if (ob->plan)
107 {
108 SPI_freeplan(ob->plan);
109 ob->plan = NULL;
110 }
111 if (ob->mcxt)
112 {
113 MemoryContextDelete(ob->mcxt);
114 ob->mcxt = NULL;
115 }
116 arg->ob_type->tp_free(arg);
117 }
118
119
120 static PyObject *
PLy_plan_cursor(PyObject * self,PyObject * args)121 PLy_plan_cursor(PyObject *self, PyObject *args)
122 {
123 PyObject *planargs = NULL;
124
125 if (!PyArg_ParseTuple(args, "|O", &planargs))
126 return NULL;
127
128 return PLy_cursor_plan(self, planargs);
129 }
130
131
132 static PyObject *
PLy_plan_execute(PyObject * self,PyObject * args)133 PLy_plan_execute(PyObject *self, PyObject *args)
134 {
135 PyObject *list = NULL;
136 long limit = 0;
137
138 if (!PyArg_ParseTuple(args, "|Ol", &list, &limit))
139 return NULL;
140
141 return PLy_spi_execute_plan(self, list, limit);
142 }
143
144
145 static PyObject *
PLy_plan_status(PyObject * self,PyObject * args)146 PLy_plan_status(PyObject *self, PyObject *args)
147 {
148 if (PyArg_ParseTuple(args, ":status"))
149 {
150 Py_INCREF(Py_True);
151 return Py_True;
152 /* return PyInt_FromLong(self->status); */
153 }
154 return NULL;
155 }
156