LCOV - code coverage report
Current view: top level - src/pl/plpython - plpy_planobject.c (source / functions) Hit Total Coverage
Test: PostgreSQL 18devel Lines: 38 43 88.4 %
Date: 2025-04-01 15:15:16 Functions: 7 7 100.0 %
Legend: Lines: hit not hit

          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             : }

Generated by: LCOV version 1.14