]> granicus.if.org Git - postgresql/blob - contrib/hstore_plpython/hstore_plpython.c
Separate block sampling functions
[postgresql] / contrib / hstore_plpython / hstore_plpython.c
1 #include "postgres.h"
2 #include "fmgr.h"
3 #include "plpython.h"
4 #include "plpy_typeio.h"
5 #include "hstore.h"
6
7 PG_MODULE_MAGIC;
8
9
10 PG_FUNCTION_INFO_V1(hstore_to_plpython);
11 Datum hstore_to_plpython(PG_FUNCTION_ARGS);
12
13 Datum
14 hstore_to_plpython(PG_FUNCTION_ARGS)
15 {
16         HStore     *in = PG_GETARG_HS(0);
17         int                     i;
18         int                     count = HS_COUNT(in);
19         char       *base = STRPTR(in);
20         HEntry     *entries = ARRPTR(in);
21         PyObject   *dict;
22
23         dict = PyDict_New();
24
25         for (i = 0; i < count; i++)
26         {
27                 PyObject   *key;
28
29                 key = PyString_FromStringAndSize(HS_KEY(entries, base, i), HS_KEYLEN(entries, i));
30                 if (HS_VALISNULL(entries, i))
31                         PyDict_SetItem(dict, key, Py_None);
32                 else
33                 {
34                         PyObject *value;
35
36                         value = PyString_FromStringAndSize(HS_VAL(entries, base,i), HS_VALLEN(entries, i));
37                         PyDict_SetItem(dict, key, value);
38                         Py_XDECREF(value);
39                 }
40                 Py_XDECREF(key);
41         }
42
43         return PointerGetDatum(dict);
44 }
45
46
47 PG_FUNCTION_INFO_V1(plpython_to_hstore);
48 Datum plpython_to_hstore(PG_FUNCTION_ARGS);
49
50 Datum
51 plpython_to_hstore(PG_FUNCTION_ARGS)
52 {
53         PyObject   *dict;
54         volatile PyObject *items_v = NULL;
55         int32           pcount;
56         HStore     *out;
57
58         dict = (PyObject *) PG_GETARG_POINTER(0);
59         if (!PyMapping_Check(dict))
60                 ereport(ERROR,
61                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
62                                  errmsg("not a Python mapping")));
63
64         pcount = PyMapping_Size(dict);
65         items_v = PyMapping_Items(dict);
66
67         PG_TRY();
68         {
69                 int32           buflen;
70                 int32           i;
71                 Pairs      *pairs;
72                 PyObject   *items = (PyObject *) items_v;
73
74                 pairs = palloc(pcount * sizeof(*pairs));
75
76                 for (i = 0; i < pcount; i++)
77                 {
78                         PyObject *tuple;
79                         PyObject *key;
80                         PyObject *value;
81
82                         tuple = PyList_GetItem(items, i);
83                         key = PyTuple_GetItem(tuple, 0);
84                         value = PyTuple_GetItem(tuple, 1);
85
86                         pairs[i].key = PLyObject_AsString(key);
87                         pairs[i].keylen = hstoreCheckKeyLen(strlen(pairs[i].key));
88                         pairs[i].needfree = true;
89
90                         if (value == Py_None)
91                         {
92                                 pairs[i].val = NULL;
93                                 pairs[i].vallen = 0;
94                                 pairs[i].isnull = true;
95                         }
96                         else
97                         {
98                                 pairs[i].val = PLyObject_AsString(value);
99                                 pairs[i].vallen = hstoreCheckValLen(strlen(pairs[i].val));
100                                 pairs[i].isnull = false;
101                         }
102                 }
103                 Py_DECREF(items_v);
104
105                 pcount = hstoreUniquePairs(pairs, pcount, &buflen);
106                 out = hstorePairs(pairs, pcount, buflen);
107         }
108         PG_CATCH();
109         {
110                 Py_DECREF(items_v);
111                 PG_RE_THROW();
112         }
113         PG_END_TRY();
114
115         PG_RETURN_POINTER(out);
116 }