LCOV - code coverage report
Current view: top level - src/pl/plpython - plpy_planobject.c (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 87.8 % 41 36
Test Date: 2026-02-28 14:14:49 Functions: 100.0 % 7 7
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 "plpy_util.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           23 : PLy_plan_init_type(void)
      57              : {
      58           23 :     PLy_PlanType = (PyTypeObject *) PyType_FromSpec(&PLyPlan_spec);
      59           23 :     if (!PLy_PlanType)
      60            0 :         elog(ERROR, "could not initialize PLy_PlanType");
      61           23 : }
      62              : 
      63              : PyObject *
      64           26 : PLy_plan_new(void)
      65              : {
      66              :     PLyPlanObject *ob;
      67              : 
      68           26 :     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           26 :     ob->plan = NULL;
      76           26 :     ob->nargs = 0;
      77           26 :     ob->types = NULL;
      78           26 :     ob->args = NULL;
      79           26 :     ob->mcxt = NULL;
      80              : 
      81           26 :     return (PyObject *) ob;
      82              : }
      83              : 
      84              : bool
      85           21 : is_PLyPlanObject(PyObject *ob)
      86              : {
      87           21 :     return ob->ob_type == PLy_PlanType;
      88              : }
      89              : 
      90              : static void
      91           22 : PLy_plan_dealloc(PLyPlanObject *self)
      92              : {
      93              : #if PY_VERSION_HEX >= 0x03080000
      94           22 :     PyTypeObject *tp = Py_TYPE(self);
      95              : #endif
      96              : 
      97           22 :     if (self->plan)
      98              :     {
      99           19 :         SPI_freeplan(self->plan);
     100           19 :         self->plan = NULL;
     101              :     }
     102           22 :     if (self->mcxt)
     103              :     {
     104           22 :         MemoryContextDelete(self->mcxt);
     105           22 :         self->mcxt = NULL;
     106              :     }
     107              : 
     108           22 :     PyObject_Free(self);
     109              : #if PY_VERSION_HEX >= 0x03080000
     110              :     /* This was not needed before Python 3.8 (Python issue 35810) */
     111              :     Py_DECREF(tp);
     112              : #endif
     113           22 : }
     114              : 
     115              : 
     116              : static PyObject *
     117            1 : PLy_plan_cursor(PyObject *self, PyObject *args)
     118              : {
     119            1 :     PyObject   *planargs = NULL;
     120              : 
     121            1 :     if (!PyArg_ParseTuple(args, "|O", &planargs))
     122            0 :         return NULL;
     123              : 
     124            1 :     return PLy_cursor_plan(self, planargs);
     125              : }
     126              : 
     127              : 
     128              : static PyObject *
     129            1 : PLy_plan_execute(PyObject *self, PyObject *args)
     130              : {
     131            1 :     PyObject   *list = NULL;
     132            1 :     long        limit = 0;
     133              : 
     134            1 :     if (!PyArg_ParseTuple(args, "|Ol", &list, &limit))
     135            0 :         return NULL;
     136              : 
     137            1 :     return PLy_spi_execute_plan(self, list, limit);
     138              : }
     139              : 
     140              : 
     141              : static PyObject *
     142            2 : PLy_plan_status(PyObject *self, PyObject *args)
     143              : {
     144            2 :     if (PyArg_ParseTuple(args, ":status"))
     145              :     {
     146              :         Py_INCREF(Py_True);
     147            2 :         return Py_True;
     148              :         /* return PyLong_FromLong(self->status); */
     149              :     }
     150            0 :     return NULL;
     151              : }
        

Generated by: LCOV version 2.0-1