Line data Source code
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 : #include "plpython.h" 13 : #include "utils/memutils.h" 14 : 15 : /* 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. 19 : */ 20 : PyObject * 21 4802 : PLyUnicode_Bytes(PyObject *unicode) 22 : { 23 : PyObject *bytes, 24 : *rv; 25 : char *utf8string, 26 : *encoded; 27 : 28 : /* First encode the Python unicode object with UTF-8. */ 29 4802 : bytes = PyUnicode_AsUTF8String(unicode); 30 4802 : if (bytes == NULL) 31 0 : PLy_elog(ERROR, "could not convert Python Unicode object to bytes"); 32 : 33 4802 : utf8string = PyBytes_AsString(bytes); 34 4802 : if (utf8string == NULL) 35 : { 36 0 : Py_DECREF(bytes); 37 0 : PLy_elog(ERROR, "could not extract bytes from encoded string"); 38 : } 39 : 40 : /* 41 : * Then convert to server encoding if necessary. 42 : * 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. 47 : */ 48 4802 : if (GetDatabaseEncoding() != PG_UTF8) 49 : { 50 4802 : PG_TRY(); 51 : { 52 4802 : encoded = pg_any_to_server(utf8string, 53 4802 : strlen(utf8string), 54 : PG_UTF8); 55 : } 56 0 : PG_CATCH(); 57 : { 58 0 : Py_DECREF(bytes); 59 0 : PG_RE_THROW(); 60 : } 61 4802 : PG_END_TRY(); 62 : } 63 : else 64 0 : encoded = utf8string; 65 : 66 : /* finally, build a bytes object in the server encoding */ 67 4802 : rv = PyBytes_FromStringAndSize(encoded, strlen(encoded)); 68 : 69 : /* if pg_any_to_server allocated memory, free it now */ 70 4802 : if (utf8string != encoded) 71 0 : pfree(encoded); 72 : 73 4802 : Py_DECREF(bytes); 74 4802 : return rv; 75 : } 76 : 77 : /* 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. 81 : */ 82 : char * 83 1644 : PLyUnicode_AsString(PyObject *unicode) 84 : { 85 1644 : PyObject *o = PLyUnicode_Bytes(unicode); 86 1644 : char *rv = pstrdup(PyBytes_AsString(o)); 87 : 88 1644 : Py_XDECREF(o); 89 1644 : return rv; 90 : } 91 : 92 : /* 93 : * Convert a C string in the PostgreSQL server encoding to a Python 94 : * unicode object. Reference ownership is passed to the caller. 95 : */ 96 : PyObject * 97 13280 : PLyUnicode_FromStringAndSize(const char *s, Py_ssize_t size) 98 : { 99 : char *utf8string; 100 : PyObject *o; 101 : 102 13280 : utf8string = pg_server_to_any(s, size, PG_UTF8); 103 : 104 13280 : if (utf8string == s) 105 : { 106 13280 : o = PyUnicode_FromStringAndSize(s, size); 107 : } 108 : else 109 : { 110 0 : o = PyUnicode_FromString(utf8string); 111 0 : pfree(utf8string); 112 : } 113 : 114 13280 : return o; 115 : } 116 : 117 : PyObject * 118 13186 : PLyUnicode_FromString(const char *s) 119 : { 120 13186 : return PLyUnicode_FromStringAndSize(s, strlen(s)); 121 : }