Fix recursive RECORD-returning plpython functions.
[pgsql.git] / src / pl / plpython / plpy_util.c
blob22e2a599ad968c302e8b4327a76523227dfadadd
1 /*
2 * utility functions
4 * src/pl/plpython/plpy_util.c
5 */
7 #include "postgres.h"
9 #include "mb/pg_wchar.h"
10 #include "plpy_elog.h"
11 #include "plpy_util.h"
12 #include "plpython.h"
13 #include "utils/memutils.h"
16 * Convert a Python unicode object to a Python string/bytes object in
17 * PostgreSQL server encoding. Reference ownership is passed to the
18 * caller.
20 PyObject *
21 PLyUnicode_Bytes(PyObject *unicode)
23 PyObject *bytes,
24 *rv;
25 char *utf8string,
26 *encoded;
28 /* First encode the Python unicode object with UTF-8. */
29 bytes = PyUnicode_AsUTF8String(unicode);
30 if (bytes == NULL)
31 PLy_elog(ERROR, "could not convert Python Unicode object to bytes");
33 utf8string = PyBytes_AsString(bytes);
34 if (utf8string == NULL)
36 Py_DECREF(bytes);
37 PLy_elog(ERROR, "could not extract bytes from encoded string");
41 * Then convert to server encoding if necessary.
43 * PyUnicode_AsEncodedString could be used to encode the object directly
44 * in the server encoding, but Python doesn't support all the encodings
45 * that PostgreSQL does (EUC_TW and MULE_INTERNAL). UTF-8 is used as an
46 * intermediary in PLyUnicode_FromString as well.
48 if (GetDatabaseEncoding() != PG_UTF8)
50 PG_TRY();
52 encoded = pg_any_to_server(utf8string,
53 strlen(utf8string),
54 PG_UTF8);
56 PG_CATCH();
58 Py_DECREF(bytes);
59 PG_RE_THROW();
61 PG_END_TRY();
63 else
64 encoded = utf8string;
66 /* finally, build a bytes object in the server encoding */
67 rv = PyBytes_FromStringAndSize(encoded, strlen(encoded));
69 /* if pg_any_to_server allocated memory, free it now */
70 if (utf8string != encoded)
71 pfree(encoded);
73 Py_DECREF(bytes);
74 return rv;
78 * Convert a Python unicode object to a C string in PostgreSQL server
79 * encoding. No Python object reference is passed out of this
80 * function. The result is palloc'ed.
82 char *
83 PLyUnicode_AsString(PyObject *unicode)
85 PyObject *o = PLyUnicode_Bytes(unicode);
86 char *rv = pstrdup(PyBytes_AsString(o));
88 Py_XDECREF(o);
89 return rv;
93 * Convert a C string in the PostgreSQL server encoding to a Python
94 * unicode object. Reference ownership is passed to the caller.
96 PyObject *
97 PLyUnicode_FromStringAndSize(const char *s, Py_ssize_t size)
99 char *utf8string;
100 PyObject *o;
102 utf8string = pg_server_to_any(s, size, PG_UTF8);
104 if (utf8string == s)
106 o = PyUnicode_FromStringAndSize(s, size);
108 else
110 o = PyUnicode_FromString(utf8string);
111 pfree(utf8string);
114 return o;
117 PyObject *
118 PLyUnicode_FromString(const char *s)
120 return PLyUnicode_FromStringAndSize(s, strlen(s));