LCOV - differential code coverage report
Current view: top level - src/pl/plpython - plpy_resultobject.c (source / functions) Coverage Total Hit UBC CBC
Current: Differential Code Coverage HEAD vs 15 Lines: 87.6 % 89 78 11 78
Current Date: 2023-04-08 15:15:32 Functions: 100.0 % 13 13 13
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

           TLA  Line data    Source code
       1                 : /*
       2                 :  * the PLyResult class
       3                 :  *
       4                 :  * src/pl/plpython/plpy_resultobject.c
       5                 :  */
       6                 : 
       7                 : #include "postgres.h"
       8                 : 
       9                 : #include "plpy_elog.h"
      10                 : #include "plpy_resultobject.h"
      11                 : #include "plpython.h"
      12                 : 
      13                 : static void PLy_result_dealloc(PyObject *arg);
      14                 : static PyObject *PLy_result_colnames(PyObject *self, PyObject *unused);
      15                 : static PyObject *PLy_result_coltypes(PyObject *self, PyObject *unused);
      16                 : static PyObject *PLy_result_coltypmods(PyObject *self, PyObject *unused);
      17                 : static PyObject *PLy_result_nrows(PyObject *self, PyObject *args);
      18                 : static PyObject *PLy_result_status(PyObject *self, PyObject *args);
      19                 : static Py_ssize_t PLy_result_length(PyObject *arg);
      20                 : static PyObject *PLy_result_item(PyObject *arg, Py_ssize_t idx);
      21                 : static PyObject *PLy_result_str(PyObject *arg);
      22                 : static PyObject *PLy_result_subscript(PyObject *arg, PyObject *item);
      23                 : static int  PLy_result_ass_subscript(PyObject *self, PyObject *item, PyObject *value);
      24                 : 
      25                 : static char PLy_result_doc[] = "Results of a PostgreSQL query";
      26                 : 
      27                 : static PySequenceMethods PLy_result_as_sequence = {
      28                 :     .sq_length = PLy_result_length,
      29                 :     .sq_item = PLy_result_item,
      30                 : };
      31                 : 
      32                 : static PyMappingMethods PLy_result_as_mapping = {
      33                 :     .mp_length = PLy_result_length,
      34                 :     .mp_subscript = PLy_result_subscript,
      35                 :     .mp_ass_subscript = PLy_result_ass_subscript,
      36                 : };
      37                 : 
      38                 : static PyMethodDef PLy_result_methods[] = {
      39                 :     {"colnames", PLy_result_colnames, METH_NOARGS, NULL},
      40                 :     {"coltypes", PLy_result_coltypes, METH_NOARGS, NULL},
      41                 :     {"coltypmods", PLy_result_coltypmods, METH_NOARGS, NULL},
      42                 :     {"nrows", PLy_result_nrows, METH_VARARGS, NULL},
      43                 :     {"status", PLy_result_status, METH_VARARGS, NULL},
      44                 :     {NULL, NULL, 0, NULL}
      45                 : };
      46                 : 
      47                 : static PyTypeObject PLy_ResultType = {
      48                 :     PyVarObject_HEAD_INIT(NULL, 0)
      49                 :     .tp_name = "PLyResult",
      50                 :     .tp_basicsize = sizeof(PLyResultObject),
      51                 :     .tp_dealloc = PLy_result_dealloc,
      52                 :     .tp_as_sequence = &PLy_result_as_sequence,
      53                 :     .tp_as_mapping = &PLy_result_as_mapping,
      54                 :     .tp_str = &PLy_result_str,
      55                 :     .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
      56                 :     .tp_doc = PLy_result_doc,
      57                 :     .tp_methods = PLy_result_methods,
      58                 : };
      59                 : 
      60                 : void
      61 CBC          23 : PLy_result_init_type(void)
      62                 : {
      63              23 :     if (PyType_Ready(&PLy_ResultType) < 0)
      64 UBC           0 :         elog(ERROR, "could not initialize PLy_ResultType");
      65 CBC          23 : }
      66                 : 
      67                 : PyObject *
      68             150 : PLy_result_new(void)
      69                 : {
      70                 :     PLyResultObject *ob;
      71                 : 
      72             150 :     if ((ob = PyObject_New(PLyResultObject, &PLy_ResultType)) == NULL)
      73 UBC           0 :         return NULL;
      74                 : 
      75                 :     /* ob->tuples = NULL; */
      76                 : 
      77 CBC         150 :     Py_INCREF(Py_None);
      78             150 :     ob->status = Py_None;
      79             150 :     ob->nrows = PyLong_FromLong(-1);
      80             150 :     ob->rows = PyList_New(0);
      81             150 :     ob->tupdesc = NULL;
      82             150 :     if (!ob->rows)
      83                 :     {
      84 UBC           0 :         Py_DECREF(ob);
      85               0 :         return NULL;
      86                 :     }
      87                 : 
      88 CBC         150 :     return (PyObject *) ob;
      89                 : }
      90                 : 
      91                 : static void
      92             149 : PLy_result_dealloc(PyObject *arg)
      93                 : {
      94             149 :     PLyResultObject *ob = (PLyResultObject *) arg;
      95                 : 
      96             149 :     Py_XDECREF(ob->nrows);
      97             149 :     Py_XDECREF(ob->rows);
      98             149 :     Py_XDECREF(ob->status);
      99             149 :     if (ob->tupdesc)
     100                 :     {
     101              59 :         FreeTupleDesc(ob->tupdesc);
     102              59 :         ob->tupdesc = NULL;
     103                 :     }
     104                 : 
     105             149 :     arg->ob_type->tp_free(arg);
     106             149 : }
     107                 : 
     108                 : static PyObject *
     109               2 : PLy_result_colnames(PyObject *self, PyObject *unused)
     110                 : {
     111               2 :     PLyResultObject *ob = (PLyResultObject *) self;
     112                 :     PyObject   *list;
     113                 :     int         i;
     114                 : 
     115               2 :     if (!ob->tupdesc)
     116                 :     {
     117               1 :         PLy_exception_set(PLy_exc_error, "command did not produce a result set");
     118               1 :         return NULL;
     119                 :     }
     120                 : 
     121               1 :     list = PyList_New(ob->tupdesc->natts);
     122               1 :     if (!list)
     123 UBC           0 :         return NULL;
     124 CBC           3 :     for (i = 0; i < ob->tupdesc->natts; i++)
     125                 :     {
     126               2 :         Form_pg_attribute attr = TupleDescAttr(ob->tupdesc, i);
     127                 : 
     128               2 :         PyList_SET_ITEM(list, i, PLyUnicode_FromString(NameStr(attr->attname)));
     129                 :     }
     130                 : 
     131               1 :     return list;
     132                 : }
     133                 : 
     134                 : static PyObject *
     135               1 : PLy_result_coltypes(PyObject *self, PyObject *unused)
     136                 : {
     137               1 :     PLyResultObject *ob = (PLyResultObject *) self;
     138                 :     PyObject   *list;
     139                 :     int         i;
     140                 : 
     141               1 :     if (!ob->tupdesc)
     142                 :     {
     143 UBC           0 :         PLy_exception_set(PLy_exc_error, "command did not produce a result set");
     144               0 :         return NULL;
     145                 :     }
     146                 : 
     147 CBC           1 :     list = PyList_New(ob->tupdesc->natts);
     148               1 :     if (!list)
     149 UBC           0 :         return NULL;
     150 CBC           3 :     for (i = 0; i < ob->tupdesc->natts; i++)
     151                 :     {
     152               2 :         Form_pg_attribute attr = TupleDescAttr(ob->tupdesc, i);
     153                 : 
     154               2 :         PyList_SET_ITEM(list, i, PyLong_FromLong(attr->atttypid));
     155                 :     }
     156                 : 
     157               1 :     return list;
     158                 : }
     159                 : 
     160                 : static PyObject *
     161               1 : PLy_result_coltypmods(PyObject *self, PyObject *unused)
     162                 : {
     163               1 :     PLyResultObject *ob = (PLyResultObject *) self;
     164                 :     PyObject   *list;
     165                 :     int         i;
     166                 : 
     167               1 :     if (!ob->tupdesc)
     168                 :     {
     169 UBC           0 :         PLy_exception_set(PLy_exc_error, "command did not produce a result set");
     170               0 :         return NULL;
     171                 :     }
     172                 : 
     173 CBC           1 :     list = PyList_New(ob->tupdesc->natts);
     174               1 :     if (!list)
     175 UBC           0 :         return NULL;
     176 CBC           3 :     for (i = 0; i < ob->tupdesc->natts; i++)
     177                 :     {
     178               2 :         Form_pg_attribute attr = TupleDescAttr(ob->tupdesc, i);
     179                 : 
     180               2 :         PyList_SET_ITEM(list, i, PyLong_FromLong(attr->atttypmod));
     181                 :     }
     182                 : 
     183               1 :     return list;
     184                 : }
     185                 : 
     186                 : static PyObject *
     187               7 : PLy_result_nrows(PyObject *self, PyObject *args)
     188                 : {
     189               7 :     PLyResultObject *ob = (PLyResultObject *) self;
     190                 : 
     191               7 :     Py_INCREF(ob->nrows);
     192               7 :     return ob->nrows;
     193                 : }
     194                 : 
     195                 : static PyObject *
     196               2 : PLy_result_status(PyObject *self, PyObject *args)
     197                 : {
     198               2 :     PLyResultObject *ob = (PLyResultObject *) self;
     199                 : 
     200               2 :     Py_INCREF(ob->status);
     201               2 :     return ob->status;
     202                 : }
     203                 : 
     204                 : static Py_ssize_t
     205              13 : PLy_result_length(PyObject *arg)
     206                 : {
     207              13 :     PLyResultObject *ob = (PLyResultObject *) arg;
     208                 : 
     209              13 :     return PyList_Size(ob->rows);
     210                 : }
     211                 : 
     212                 : static PyObject *
     213              28 : PLy_result_item(PyObject *arg, Py_ssize_t idx)
     214                 : {
     215                 :     PyObject   *rv;
     216              28 :     PLyResultObject *ob = (PLyResultObject *) arg;
     217                 : 
     218              28 :     rv = PyList_GetItem(ob->rows, idx);
     219              28 :     if (rv != NULL)
     220              20 :         Py_INCREF(rv);
     221              28 :     return rv;
     222                 : }
     223                 : 
     224                 : static PyObject *
     225               2 : PLy_result_str(PyObject *arg)
     226                 : {
     227               2 :     PLyResultObject *ob = (PLyResultObject *) arg;
     228                 : 
     229               2 :     return PyUnicode_FromFormat("<%s status=%S nrows=%S rows=%S>",
     230               2 :                                 Py_TYPE(ob)->tp_name,
     231                 :                                 ob->status,
     232                 :                                 ob->nrows,
     233                 :                                 ob->rows);
     234                 : }
     235                 : 
     236                 : static PyObject *
     237              46 : PLy_result_subscript(PyObject *arg, PyObject *item)
     238                 : {
     239              46 :     PLyResultObject *ob = (PLyResultObject *) arg;
     240                 : 
     241              46 :     return PyObject_GetItem(ob->rows, item);
     242                 : }
     243                 : 
     244                 : static int
     245               2 : PLy_result_ass_subscript(PyObject *arg, PyObject *item, PyObject *value)
     246                 : {
     247               2 :     PLyResultObject *ob = (PLyResultObject *) arg;
     248                 : 
     249               2 :     return PyObject_SetItem(ob->rows, item, value);
     250                 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a