LCOV - code coverage report
Current view: top level - contrib/hstore_plpython - hstore_plpython.c (source / functions) Hit Total Coverage
Test: PostgreSQL 12beta2 Lines: 61 66 92.4 %
Date: 2019-06-18 07:06:57 Functions: 6 6 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : #include "postgres.h"
       2             : 
       3             : #include "fmgr.h"
       4             : #include "plpython.h"
       5             : #include "plpy_typeio.h"
       6             : #include "hstore/hstore.h"
       7             : 
       8           4 : PG_MODULE_MAGIC;
       9             : 
      10             : extern void _PG_init(void);
      11             : 
      12             : /* Linkage to functions in plpython module */
      13             : typedef char *(*PLyObject_AsString_t) (PyObject *plrv);
      14             : static PLyObject_AsString_t PLyObject_AsString_p;
      15             : #if PY_MAJOR_VERSION >= 3
      16             : typedef PyObject *(*PLyUnicode_FromStringAndSize_t) (const char *s, Py_ssize_t size);
      17             : static PLyUnicode_FromStringAndSize_t PLyUnicode_FromStringAndSize_p;
      18             : #endif
      19             : 
      20             : /* Linkage to functions in hstore module */
      21             : typedef HStore *(*hstoreUpgrade_t) (Datum orig);
      22             : static hstoreUpgrade_t hstoreUpgrade_p;
      23             : typedef int (*hstoreUniquePairs_t) (Pairs *a, int32 l, int32 *buflen);
      24             : static hstoreUniquePairs_t hstoreUniquePairs_p;
      25             : typedef HStore *(*hstorePairs_t) (Pairs *pairs, int32 pcount, int32 buflen);
      26             : static hstorePairs_t hstorePairs_p;
      27             : typedef size_t (*hstoreCheckKeyLen_t) (size_t len);
      28             : static hstoreCheckKeyLen_t hstoreCheckKeyLen_p;
      29             : typedef size_t (*hstoreCheckValLen_t) (size_t len);
      30             : static hstoreCheckValLen_t hstoreCheckValLen_p;
      31             : 
      32             : 
      33             : /*
      34             :  * Module initialize function: fetch function pointers for cross-module calls.
      35             :  */
      36             : void
      37           4 : _PG_init(void)
      38             : {
      39             :     /* Asserts verify that typedefs above match original declarations */
      40             :     AssertVariableIsOfType(&PLyObject_AsString, PLyObject_AsString_t);
      41           4 :     PLyObject_AsString_p = (PLyObject_AsString_t)
      42           4 :         load_external_function("$libdir/" PLPYTHON_LIBNAME, "PLyObject_AsString",
      43             :                                true, NULL);
      44             : #if PY_MAJOR_VERSION >= 3
      45             :     AssertVariableIsOfType(&PLyUnicode_FromStringAndSize, PLyUnicode_FromStringAndSize_t);
      46             :     PLyUnicode_FromStringAndSize_p = (PLyUnicode_FromStringAndSize_t)
      47             :         load_external_function("$libdir/" PLPYTHON_LIBNAME, "PLyUnicode_FromStringAndSize",
      48             :                                true, NULL);
      49             : #endif
      50             :     AssertVariableIsOfType(&hstoreUpgrade, hstoreUpgrade_t);
      51           4 :     hstoreUpgrade_p = (hstoreUpgrade_t)
      52           4 :         load_external_function("$libdir/hstore", "hstoreUpgrade",
      53             :                                true, NULL);
      54             :     AssertVariableIsOfType(&hstoreUniquePairs, hstoreUniquePairs_t);
      55           4 :     hstoreUniquePairs_p = (hstoreUniquePairs_t)
      56           4 :         load_external_function("$libdir/hstore", "hstoreUniquePairs",
      57             :                                true, NULL);
      58             :     AssertVariableIsOfType(&hstorePairs, hstorePairs_t);
      59           4 :     hstorePairs_p = (hstorePairs_t)
      60           4 :         load_external_function("$libdir/hstore", "hstorePairs",
      61             :                                true, NULL);
      62             :     AssertVariableIsOfType(&hstoreCheckKeyLen, hstoreCheckKeyLen_t);
      63           4 :     hstoreCheckKeyLen_p = (hstoreCheckKeyLen_t)
      64           4 :         load_external_function("$libdir/hstore", "hstoreCheckKeyLen",
      65             :                                true, NULL);
      66             :     AssertVariableIsOfType(&hstoreCheckValLen, hstoreCheckValLen_t);
      67           4 :     hstoreCheckValLen_p = (hstoreCheckValLen_t)
      68           4 :         load_external_function("$libdir/hstore", "hstoreCheckValLen",
      69             :                                true, NULL);
      70           4 : }
      71             : 
      72             : 
      73             : /* These defines must be after the module init function */
      74             : #define PLyObject_AsString PLyObject_AsString_p
      75             : #define PLyUnicode_FromStringAndSize PLyUnicode_FromStringAndSize_p
      76             : #define hstoreUpgrade hstoreUpgrade_p
      77             : #define hstoreUniquePairs hstoreUniquePairs_p
      78             : #define hstorePairs hstorePairs_p
      79             : #define hstoreCheckKeyLen hstoreCheckKeyLen_p
      80             : #define hstoreCheckValLen hstoreCheckValLen_p
      81             : 
      82             : 
      83           8 : PG_FUNCTION_INFO_V1(hstore_to_plpython);
      84             : 
      85             : Datum
      86          14 : hstore_to_plpython(PG_FUNCTION_ARGS)
      87             : {
      88          14 :     HStore     *in = PG_GETARG_HSTORE_P(0);
      89             :     int         i;
      90          14 :     int         count = HS_COUNT(in);
      91          14 :     char       *base = STRPTR(in);
      92          14 :     HEntry     *entries = ARRPTR(in);
      93             :     PyObject   *dict;
      94             : 
      95          14 :     dict = PyDict_New();
      96          14 :     if (!dict)
      97           0 :         ereport(ERROR,
      98             :                 (errcode(ERRCODE_OUT_OF_MEMORY),
      99             :                  errmsg("out of memory")));
     100             : 
     101          40 :     for (i = 0; i < count; i++)
     102             :     {
     103             :         PyObject   *key;
     104             : 
     105          52 :         key = PyString_FromStringAndSize(HSTORE_KEY(entries, base, i),
     106          52 :                                          HSTORE_KEYLEN(entries, i));
     107          26 :         if (HSTORE_VALISNULL(entries, i))
     108          12 :             PyDict_SetItem(dict, key, Py_None);
     109             :         else
     110             :         {
     111             :             PyObject   *value;
     112             : 
     113          28 :             value = PyString_FromStringAndSize(HSTORE_VAL(entries, base, i),
     114          28 :                                                HSTORE_VALLEN(entries, i));
     115          14 :             PyDict_SetItem(dict, key, value);
     116          14 :             Py_XDECREF(value);
     117             :         }
     118          26 :         Py_XDECREF(key);
     119             :     }
     120             : 
     121          14 :     return PointerGetDatum(dict);
     122             : }
     123             : 
     124             : 
     125           6 : PG_FUNCTION_INFO_V1(plpython_to_hstore);
     126             : 
     127             : Datum
     128          14 : plpython_to_hstore(PG_FUNCTION_ARGS)
     129             : {
     130             :     PyObject   *dict;
     131             :     PyObject   *volatile items;
     132             :     Py_ssize_t  pcount;
     133             :     HStore     *volatile out;
     134             : 
     135          14 :     dict = (PyObject *) PG_GETARG_POINTER(0);
     136          14 :     if (!PyMapping_Check(dict))
     137           0 :         ereport(ERROR,
     138             :                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
     139             :                  errmsg("not a Python mapping")));
     140             : 
     141          14 :     pcount = PyMapping_Size(dict);
     142          14 :     items = PyMapping_Items(dict);
     143             : 
     144          14 :     PG_TRY();
     145             :     {
     146             :         int32       buflen;
     147             :         Py_ssize_t  i;
     148             :         Pairs      *pairs;
     149             : 
     150          14 :         pairs = palloc(pcount * sizeof(*pairs));
     151             : 
     152          52 :         for (i = 0; i < pcount; i++)
     153             :         {
     154             :             PyObject   *tuple;
     155             :             PyObject   *key;
     156             :             PyObject   *value;
     157             : 
     158          38 :             tuple = PyList_GetItem(items, i);
     159          38 :             key = PyTuple_GetItem(tuple, 0);
     160          38 :             value = PyTuple_GetItem(tuple, 1);
     161             : 
     162          38 :             pairs[i].key = PLyObject_AsString(key);
     163          38 :             pairs[i].keylen = hstoreCheckKeyLen(strlen(pairs[i].key));
     164          38 :             pairs[i].needfree = true;
     165             : 
     166          38 :             if (value == Py_None)
     167             :             {
     168          12 :                 pairs[i].val = NULL;
     169          12 :                 pairs[i].vallen = 0;
     170          12 :                 pairs[i].isnull = true;
     171             :             }
     172             :             else
     173             :             {
     174          26 :                 pairs[i].val = PLyObject_AsString(value);
     175          26 :                 pairs[i].vallen = hstoreCheckValLen(strlen(pairs[i].val));
     176          26 :                 pairs[i].isnull = false;
     177             :             }
     178             :         }
     179             : 
     180          14 :         pcount = hstoreUniquePairs(pairs, pcount, &buflen);
     181          14 :         out = hstorePairs(pairs, pcount, buflen);
     182             :     }
     183           0 :     PG_CATCH();
     184             :     {
     185           0 :         Py_DECREF(items);
     186           0 :         PG_RE_THROW();
     187             :     }
     188          14 :     PG_END_TRY();
     189             : 
     190          14 :     Py_DECREF(items);
     191             : 
     192          14 :     PG_RETURN_POINTER(out);
     193             : }

Generated by: LCOV version 1.13