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

Generated by: LCOV version 1.13