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 : 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 : */ 18 : PyObject * 19 4818 : PLyUnicode_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 4818 : bytes = PyUnicode_AsUTF8String(unicode); 28 4818 : if (bytes == NULL) 29 0 : PLy_elog(ERROR, "could not convert Python Unicode object to bytes"); 30 : 31 4818 : utf8string = PyBytes_AsString(bytes); 32 4818 : if (utf8string == NULL) 33 : { 34 0 : Py_DECREF(bytes); 35 0 : 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 : */ 46 4818 : if (GetDatabaseEncoding() != PG_UTF8) 47 : { 48 0 : PG_TRY(); 49 : { 50 0 : encoded = pg_any_to_server(utf8string, 51 0 : strlen(utf8string), 52 : PG_UTF8); 53 : } 54 0 : PG_CATCH(); 55 : { 56 0 : Py_DECREF(bytes); 57 0 : PG_RE_THROW(); 58 : } 59 0 : PG_END_TRY(); 60 : } 61 : else 62 4818 : encoded = utf8string; 63 : 64 : /* finally, build a bytes object in the server encoding */ 65 4818 : rv = PyBytes_FromStringAndSize(encoded, strlen(encoded)); 66 : 67 : /* if pg_any_to_server allocated memory, free it now */ 68 4818 : if (utf8string != encoded) 69 0 : pfree(encoded); 70 : 71 4818 : Py_DECREF(bytes); 72 4818 : 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 : */ 80 : char * 81 1650 : PLyUnicode_AsString(PyObject *unicode) 82 : { 83 1650 : PyObject *o = PLyUnicode_Bytes(unicode); 84 1650 : char *rv = pstrdup(PyBytes_AsString(o)); 85 : 86 1650 : Py_XDECREF(o); 87 1650 : 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 : */ 94 : PyObject * 95 13470 : PLyUnicode_FromStringAndSize(const char *s, Py_ssize_t size) 96 : { 97 : char *utf8string; 98 : PyObject *o; 99 : 100 13470 : utf8string = pg_server_to_any(s, size, PG_UTF8); 101 : 102 13470 : if (utf8string == s) 103 : { 104 13470 : o = PyUnicode_FromStringAndSize(s, size); 105 : } 106 : else 107 : { 108 0 : o = PyUnicode_FromString(utf8string); 109 0 : pfree(utf8string); 110 : } 111 : 112 13470 : return o; 113 : } 114 : 115 : PyObject * 116 13376 : PLyUnicode_FromString(const char *s) 117 : { 118 13376 : return PLyUnicode_FromStringAndSize(s, strlen(s)); 119 : }