PostgreSQL Source Code git master
plpy_util.c
Go to the documentation of this file.
1/*
2 * utility functions
3 *
4 * src/pl/plpython/plpy_util.c
5 */
6
7#include "postgres.h"
8
9#include "mb/pg_wchar.h"
10#include "plpy_elog.h"
11#include "plpy_util.h"
12
13/*
14 * Convert a Python unicode object to a Python string/bytes object in
15 * PostgreSQL server encoding. Reference ownership is passed to the
16 * caller.
17 */
18PyObject *
19PLyUnicode_Bytes(PyObject *unicode)
20{
21 PyObject *bytes,
22 *rv;
23 char *utf8string,
24 *encoded;
25
26 /* First encode the Python unicode object with UTF-8. */
27 bytes = PyUnicode_AsUTF8String(unicode);
28 if (bytes == NULL)
29 PLy_elog(ERROR, "could not convert Python Unicode object to bytes");
30
31 utf8string = PyBytes_AsString(bytes);
32 if (utf8string == NULL)
33 {
34 Py_DECREF(bytes);
35 PLy_elog(ERROR, "could not extract bytes from encoded string");
36 }
37
38 /*
39 * Then convert to server encoding if necessary.
40 *
41 * PyUnicode_AsEncodedString could be used to encode the object directly
42 * in the server encoding, but Python doesn't support all the encodings
43 * that PostgreSQL does (EUC_TW and MULE_INTERNAL). UTF-8 is used as an
44 * intermediary in PLyUnicode_FromString as well.
45 */
47 {
48 PG_TRY();
49 {
50 encoded = pg_any_to_server(utf8string,
51 strlen(utf8string),
52 PG_UTF8);
53 }
54 PG_CATCH();
55 {
56 Py_DECREF(bytes);
58 }
59 PG_END_TRY();
60 }
61 else
62 encoded = utf8string;
63
64 /* finally, build a bytes object in the server encoding */
65 rv = PyBytes_FromStringAndSize(encoded, strlen(encoded));
66
67 /* if pg_any_to_server allocated memory, free it now */
68 if (utf8string != encoded)
69 pfree(encoded);
70
71 Py_DECREF(bytes);
72 return rv;
73}
74
75/*
76 * Convert a Python unicode object to a C string in PostgreSQL server
77 * encoding. No Python object reference is passed out of this
78 * function. The result is palloc'ed.
79 */
80char *
81PLyUnicode_AsString(PyObject *unicode)
82{
83 PyObject *o = PLyUnicode_Bytes(unicode);
84 char *rv = pstrdup(PyBytes_AsString(o));
85
86 Py_XDECREF(o);
87 return rv;
88}
89
90/*
91 * Convert a C string in the PostgreSQL server encoding to a Python
92 * unicode object. Reference ownership is passed to the caller.
93 */
94PyObject *
95PLyUnicode_FromStringAndSize(const char *s, Py_ssize_t size)
96{
97 char *utf8string;
98 PyObject *o;
99
100 utf8string = pg_server_to_any(s, size, PG_UTF8);
101
102 if (utf8string == s)
103 {
104 o = PyUnicode_FromStringAndSize(s, size);
105 }
106 else
107 {
108 o = PyUnicode_FromString(utf8string);
109 pfree(utf8string);
110 }
111
112 return o;
113}
114
115PyObject *
117{
118 return PLyUnicode_FromStringAndSize(s, strlen(s));
119}
#define PG_RE_THROW()
Definition: elog.h:404
#define PG_TRY(...)
Definition: elog.h:371
#define PG_END_TRY(...)
Definition: elog.h:396
#define ERROR
Definition: elog.h:39
#define PG_CATCH(...)
Definition: elog.h:381
#define PLy_elog
int GetDatabaseEncoding(void)
Definition: mbutils.c:1261
char * pg_any_to_server(const char *s, int len, int encoding)
Definition: mbutils.c:676
char * pg_server_to_any(const char *s, int len, int encoding)
Definition: mbutils.c:749
char * pstrdup(const char *in)
Definition: mcxt.c:2325
void pfree(void *pointer)
Definition: mcxt.c:2150
@ PG_UTF8
Definition: pg_wchar.h:232
char * PLyUnicode_AsString(PyObject *unicode)
Definition: plpy_util.c:81
PyObject * PLyUnicode_Bytes(PyObject *unicode)
Definition: plpy_util.c:19
PyObject * PLyUnicode_FromStringAndSize(const char *s, Py_ssize_t size)
Definition: plpy_util.c:95
PyObject * PLyUnicode_FromString(const char *s)
Definition: plpy_util.c:116