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 : 14 : /* 15 : * Convert a Python unicode object to a Python string/bytes object in 16 : * PostgreSQL server encoding. Reference ownership is passed to the 17 : * caller. 18 : */ 19 : PyObject * 20 4812 : PLyUnicode_Bytes(PyObject *unicode) 21 : { 22 : PyObject *bytes, 23 : *rv; 24 : char *utf8string, 25 : *encoded; 26 : 27 : /* First encode the Python unicode object with UTF-8. */ 28 4812 : bytes = PyUnicode_AsUTF8String(unicode); 29 4812 : if (bytes == NULL) 30 0 : PLy_elog(ERROR, "could not convert Python Unicode object to bytes"); 31 : 32 4812 : utf8string = PyBytes_AsString(bytes); 33 4812 : if (utf8string == NULL) 34 : { 35 0 : Py_DECREF(bytes); 36 0 : PLy_elog(ERROR, "could not extract bytes from encoded string"); 37 : } 38 : 39 : /* 40 : * Then convert to server encoding if necessary. 41 : * 42 : * PyUnicode_AsEncodedString could be used to encode the object directly 43 : * in the server encoding, but Python doesn't support all the encodings 44 : * that PostgreSQL does (EUC_TW and MULE_INTERNAL). UTF-8 is used as an 45 : * intermediary in PLyUnicode_FromString as well. 46 : */ 47 4812 : if (GetDatabaseEncoding() != PG_UTF8) 48 : { 49 0 : PG_TRY(); 50 : { 51 0 : encoded = pg_any_to_server(utf8string, 52 0 : strlen(utf8string), 53 : PG_UTF8); 54 : } 55 0 : PG_CATCH(); 56 : { 57 0 : Py_DECREF(bytes); 58 0 : PG_RE_THROW(); 59 : } 60 0 : PG_END_TRY(); 61 : } 62 : else 63 4812 : encoded = utf8string; 64 : 65 : /* finally, build a bytes object in the server encoding */ 66 4812 : rv = PyBytes_FromStringAndSize(encoded, strlen(encoded)); 67 : 68 : /* if pg_any_to_server allocated memory, free it now */ 69 4812 : if (utf8string != encoded) 70 0 : pfree(encoded); 71 : 72 4812 : Py_DECREF(bytes); 73 4812 : return rv; 74 : } 75 : 76 : /* 77 : * Convert a Python unicode object to a C string in PostgreSQL server 78 : * encoding. No Python object reference is passed out of this 79 : * function. The result is palloc'ed. 80 : */ 81 : char * 82 1650 : PLyUnicode_AsString(PyObject *unicode) 83 : { 84 1650 : PyObject *o = PLyUnicode_Bytes(unicode); 85 1650 : char *rv = pstrdup(PyBytes_AsString(o)); 86 : 87 1650 : Py_XDECREF(o); 88 1650 : return rv; 89 : } 90 : 91 : /* 92 : * Convert a C string in the PostgreSQL server encoding to a Python 93 : * unicode object. Reference ownership is passed to the caller. 94 : */ 95 : PyObject * 96 13464 : PLyUnicode_FromStringAndSize(const char *s, Py_ssize_t size) 97 : { 98 : char *utf8string; 99 : PyObject *o; 100 : 101 13464 : utf8string = pg_server_to_any(s, size, PG_UTF8); 102 : 103 13464 : if (utf8string == s) 104 : { 105 13464 : o = PyUnicode_FromStringAndSize(s, size); 106 : } 107 : else 108 : { 109 0 : o = PyUnicode_FromString(utf8string); 110 0 : pfree(utf8string); 111 : } 112 : 113 13464 : return o; 114 : } 115 : 116 : PyObject * 117 13370 : PLyUnicode_FromString(const char *s) 118 : { 119 13370 : return PLyUnicode_FromStringAndSize(s, strlen(s)); 120 : }