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