Line data Source code
1 : /*
2 : * the PLyPlan class
3 : *
4 : * src/pl/plpython/plpy_planobject.c
5 : */
6 :
7 : #include "postgres.h"
8 :
9 : #include "plpy_cursorobject.h"
10 : #include "plpy_planobject.h"
11 : #include "plpy_spi.h"
12 : #include "plpython.h"
13 : #include "utils/memutils.h"
14 :
15 : static void PLy_plan_dealloc(PLyPlanObject *self);
16 : static PyObject *PLy_plan_cursor(PyObject *self, PyObject *args);
17 : static PyObject *PLy_plan_execute(PyObject *self, PyObject *args);
18 : static PyObject *PLy_plan_status(PyObject *self, PyObject *args);
19 :
20 : static char PLy_plan_doc[] = "Store a PostgreSQL plan";
21 :
22 : static PyMethodDef PLy_plan_methods[] = {
23 : {"cursor", PLy_plan_cursor, METH_VARARGS, NULL},
24 : {"execute", PLy_plan_execute, METH_VARARGS, NULL},
25 : {"status", PLy_plan_status, METH_VARARGS, NULL},
26 : {NULL, NULL, 0, NULL}
27 : };
28 :
29 : static PyType_Slot PLyPlan_slots[] =
30 : {
31 : {
32 : Py_tp_dealloc, PLy_plan_dealloc
33 : },
34 : {
35 : Py_tp_doc, (char *) PLy_plan_doc
36 : },
37 : {
38 : Py_tp_methods, PLy_plan_methods
39 : },
40 : {
41 : 0, NULL
42 : }
43 : };
44 :
45 : static PyType_Spec PLyPlan_spec =
46 : {
47 : .name = "PLyPlan",
48 : .basicsize = sizeof(PLyPlanObject),
49 : .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
50 : .slots = PLyPlan_slots,
51 : };
52 :
53 : static PyTypeObject *PLy_PlanType;
54 :
55 : void
56 46 : PLy_plan_init_type(void)
57 : {
58 46 : PLy_PlanType = (PyTypeObject *) PyType_FromSpec(&PLyPlan_spec);
59 46 : if (!PLy_PlanType)
60 0 : elog(ERROR, "could not initialize PLy_PlanType");
61 46 : }
62 :
63 : PyObject *
64 52 : PLy_plan_new(void)
65 : {
66 : PLyPlanObject *ob;
67 :
68 52 : if ((ob = PyObject_New(PLyPlanObject, PLy_PlanType)) == NULL)
69 0 : return NULL;
70 : #if PY_VERSION_HEX < 0x03080000
71 : /* Workaround for Python issue 35810; no longer necessary in Python 3.8 */
72 : Py_INCREF(PLy_PlanType);
73 : #endif
74 :
75 52 : ob->plan = NULL;
76 52 : ob->nargs = 0;
77 52 : ob->types = NULL;
78 52 : ob->args = NULL;
79 52 : ob->mcxt = NULL;
80 :
81 52 : return (PyObject *) ob;
82 : }
83 :
84 : bool
85 42 : is_PLyPlanObject(PyObject *ob)
86 : {
87 42 : return ob->ob_type == PLy_PlanType;
88 : }
89 :
90 : static void
91 44 : PLy_plan_dealloc(PLyPlanObject *self)
92 : {
93 : #if PY_VERSION_HEX >= 0x03080000
94 44 : PyTypeObject *tp = Py_TYPE(self);
95 : #endif
96 :
97 44 : if (self->plan)
98 : {
99 38 : SPI_freeplan(self->plan);
100 38 : self->plan = NULL;
101 : }
102 44 : if (self->mcxt)
103 : {
104 44 : MemoryContextDelete(self->mcxt);
105 44 : self->mcxt = NULL;
106 : }
107 :
108 44 : PyObject_Free(self);
109 : #if PY_VERSION_HEX >= 0x03080000
110 : /* This was not needed before Python 3.8 (Python issue 35810) */
111 44 : Py_DECREF(tp);
112 : #endif
113 44 : }
114 :
115 :
116 : static PyObject *
117 2 : PLy_plan_cursor(PyObject *self, PyObject *args)
118 : {
119 2 : PyObject *planargs = NULL;
120 :
121 2 : if (!PyArg_ParseTuple(args, "|O", &planargs))
122 0 : return NULL;
123 :
124 2 : return PLy_cursor_plan(self, planargs);
125 : }
126 :
127 :
128 : static PyObject *
129 2 : PLy_plan_execute(PyObject *self, PyObject *args)
130 : {
131 2 : PyObject *list = NULL;
132 2 : long limit = 0;
133 :
134 2 : if (!PyArg_ParseTuple(args, "|Ol", &list, &limit))
135 0 : return NULL;
136 :
137 2 : return PLy_spi_execute_plan(self, list, limit);
138 : }
139 :
140 :
141 : static PyObject *
142 4 : PLy_plan_status(PyObject *self, PyObject *args)
143 : {
144 4 : if (PyArg_ParseTuple(args, ":status"))
145 : {
146 4 : Py_INCREF(Py_True);
147 4 : return Py_True;
148 : /* return PyLong_FromLong(self->status); */
149 : }
150 0 : return NULL;
151 : }
|