LCOV - code coverage report
Current view: top level - src/pl/plpython - plpy_resultobject.c (source / functions) Hit Total Coverage
Test: PostgreSQL 17devel Lines: 78 89 87.6 %
Date: 2024-04-24 11:11:50 Functions: 13 13 100.0 %
Legend: Lines: hit not hit

          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 *arg, 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          46 : PLy_result_init_type(void)
      62             : {
      63          46 :     if (PyType_Ready(&PLy_ResultType) < 0)
      64           0 :         elog(ERROR, "could not initialize PLy_ResultType");
      65          46 : }
      66             : 
      67             : PyObject *
      68         300 : PLy_result_new(void)
      69             : {
      70             :     PLyResultObject *ob;
      71             : 
      72         300 :     if ((ob = PyObject_New(PLyResultObject, &PLy_ResultType)) == NULL)
      73           0 :         return NULL;
      74             : 
      75             :     /* ob->tuples = NULL; */
      76             : 
      77         300 :     Py_INCREF(Py_None);
      78         300 :     ob->status = Py_None;
      79         300 :     ob->nrows = PyLong_FromLong(-1);
      80         300 :     ob->rows = PyList_New(0);
      81         300 :     ob->tupdesc = NULL;
      82         300 :     if (!ob->rows)
      83             :     {
      84           0 :         Py_DECREF(ob);
      85           0 :         return NULL;
      86             :     }
      87             : 
      88         300 :     return (PyObject *) ob;
      89             : }
      90             : 
      91             : static void
      92         298 : PLy_result_dealloc(PyObject *arg)
      93             : {
      94         298 :     PLyResultObject *ob = (PLyResultObject *) arg;
      95             : 
      96         298 :     Py_XDECREF(ob->nrows);
      97         298 :     Py_XDECREF(ob->rows);
      98         298 :     Py_XDECREF(ob->status);
      99         298 :     if (ob->tupdesc)
     100             :     {
     101         118 :         FreeTupleDesc(ob->tupdesc);
     102         118 :         ob->tupdesc = NULL;
     103             :     }
     104             : 
     105         298 :     arg->ob_type->tp_free(arg);
     106         298 : }
     107             : 
     108             : static PyObject *
     109           4 : PLy_result_colnames(PyObject *self, PyObject *unused)
     110             : {
     111           4 :     PLyResultObject *ob = (PLyResultObject *) self;
     112             :     PyObject   *list;
     113             :     int         i;
     114             : 
     115           4 :     if (!ob->tupdesc)
     116             :     {
     117           2 :         PLy_exception_set(PLy_exc_error, "command did not produce a result set");
     118           2 :         return NULL;
     119             :     }
     120             : 
     121           2 :     list = PyList_New(ob->tupdesc->natts);
     122           2 :     if (!list)
     123           0 :         return NULL;
     124           6 :     for (i = 0; i < ob->tupdesc->natts; i++)
     125             :     {
     126           4 :         Form_pg_attribute attr = TupleDescAttr(ob->tupdesc, i);
     127             : 
     128           4 :         PyList_SET_ITEM(list, i, PLyUnicode_FromString(NameStr(attr->attname)));
     129             :     }
     130             : 
     131           2 :     return list;
     132             : }
     133             : 
     134             : static PyObject *
     135           2 : PLy_result_coltypes(PyObject *self, PyObject *unused)
     136             : {
     137           2 :     PLyResultObject *ob = (PLyResultObject *) self;
     138             :     PyObject   *list;
     139             :     int         i;
     140             : 
     141           2 :     if (!ob->tupdesc)
     142             :     {
     143           0 :         PLy_exception_set(PLy_exc_error, "command did not produce a result set");
     144           0 :         return NULL;
     145             :     }
     146             : 
     147           2 :     list = PyList_New(ob->tupdesc->natts);
     148           2 :     if (!list)
     149           0 :         return NULL;
     150           6 :     for (i = 0; i < ob->tupdesc->natts; i++)
     151             :     {
     152           4 :         Form_pg_attribute attr = TupleDescAttr(ob->tupdesc, i);
     153             : 
     154           4 :         PyList_SET_ITEM(list, i, PyLong_FromLong(attr->atttypid));
     155             :     }
     156             : 
     157           2 :     return list;
     158             : }
     159             : 
     160             : static PyObject *
     161           2 : PLy_result_coltypmods(PyObject *self, PyObject *unused)
     162             : {
     163           2 :     PLyResultObject *ob = (PLyResultObject *) self;
     164             :     PyObject   *list;
     165             :     int         i;
     166             : 
     167           2 :     if (!ob->tupdesc)
     168             :     {
     169           0 :         PLy_exception_set(PLy_exc_error, "command did not produce a result set");
     170           0 :         return NULL;
     171             :     }
     172             : 
     173           2 :     list = PyList_New(ob->tupdesc->natts);
     174           2 :     if (!list)
     175           0 :         return NULL;
     176           6 :     for (i = 0; i < ob->tupdesc->natts; i++)
     177             :     {
     178           4 :         Form_pg_attribute attr = TupleDescAttr(ob->tupdesc, i);
     179             : 
     180           4 :         PyList_SET_ITEM(list, i, PyLong_FromLong(attr->atttypmod));
     181             :     }
     182             : 
     183           2 :     return list;
     184             : }
     185             : 
     186             : static PyObject *
     187          14 : PLy_result_nrows(PyObject *self, PyObject *args)
     188             : {
     189          14 :     PLyResultObject *ob = (PLyResultObject *) self;
     190             : 
     191          14 :     Py_INCREF(ob->nrows);
     192          14 :     return ob->nrows;
     193             : }
     194             : 
     195             : static PyObject *
     196           4 : PLy_result_status(PyObject *self, PyObject *args)
     197             : {
     198           4 :     PLyResultObject *ob = (PLyResultObject *) self;
     199             : 
     200           4 :     Py_INCREF(ob->status);
     201           4 :     return ob->status;
     202             : }
     203             : 
     204             : static Py_ssize_t
     205          26 : PLy_result_length(PyObject *arg)
     206             : {
     207          26 :     PLyResultObject *ob = (PLyResultObject *) arg;
     208             : 
     209          26 :     return PyList_Size(ob->rows);
     210             : }
     211             : 
     212             : static PyObject *
     213          56 : PLy_result_item(PyObject *arg, Py_ssize_t idx)
     214             : {
     215             :     PyObject   *rv;
     216          56 :     PLyResultObject *ob = (PLyResultObject *) arg;
     217             : 
     218          56 :     rv = PyList_GetItem(ob->rows, idx);
     219          56 :     if (rv != NULL)
     220          40 :         Py_INCREF(rv);
     221          56 :     return rv;
     222             : }
     223             : 
     224             : static PyObject *
     225           4 : PLy_result_str(PyObject *arg)
     226             : {
     227           4 :     PLyResultObject *ob = (PLyResultObject *) arg;
     228             : 
     229           8 :     return PyUnicode_FromFormat("<%s status=%S nrows=%S rows=%S>",
     230           4 :                                 Py_TYPE(ob)->tp_name,
     231             :                                 ob->status,
     232             :                                 ob->nrows,
     233             :                                 ob->rows);
     234             : }
     235             : 
     236             : static PyObject *
     237          92 : PLy_result_subscript(PyObject *arg, PyObject *item)
     238             : {
     239          92 :     PLyResultObject *ob = (PLyResultObject *) arg;
     240             : 
     241          92 :     return PyObject_GetItem(ob->rows, item);
     242             : }
     243             : 
     244             : static int
     245           4 : PLy_result_ass_subscript(PyObject *arg, PyObject *item, PyObject *value)
     246             : {
     247           4 :     PLyResultObject *ob = (PLyResultObject *) arg;
     248             : 
     249           4 :     return PyObject_SetItem(ob->rows, item, value);
     250             : }

Generated by: LCOV version 1.14