LCOV - code coverage report
Current view: top level - src/pl/plpython - plpy_util.c (source / functions) Hit Total Coverage
Test: PostgreSQL 14devel Lines: 16 27 59.3 %
Date: 2020-09-25 17:06:10 Functions: 2 2 100.0 %
Legend: Lines: hit not hit

          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          12 : 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          12 :     bytes = PyUnicode_AsUTF8String(unicode);
      30          12 :     if (bytes == NULL)
      31           0 :         PLy_elog(ERROR, "could not convert Python Unicode object to bytes");
      32             : 
      33          12 :     utf8string = PyBytes_AsString(bytes);
      34          12 :     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          12 :     if (GetDatabaseEncoding() != PG_UTF8)
      49             :     {
      50           0 :         PG_TRY();
      51             :         {
      52           0 :             encoded = pg_any_to_server(utf8string,
      53           0 :                                        strlen(utf8string),
      54             :                                        PG_UTF8);
      55             :         }
      56           0 :         PG_CATCH();
      57             :         {
      58           0 :             Py_DECREF(bytes);
      59           0 :             PG_RE_THROW();
      60             :         }
      61           0 :         PG_END_TRY();
      62             :     }
      63             :     else
      64          12 :         encoded = utf8string;
      65             : 
      66             :     /* finally, build a bytes object in the server encoding */
      67          12 :     rv = PyBytes_FromStringAndSize(encoded, strlen(encoded));
      68             : 
      69             :     /* if pg_any_to_server allocated memory, free it now */
      70          12 :     if (utf8string != encoded)
      71           0 :         pfree(encoded);
      72             : 
      73          12 :     Py_DECREF(bytes);
      74          12 :     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             :  * Note that this function is disguised as PyString_AsString() when
      83             :  * using Python 3.  That function returns a pointer into the internal
      84             :  * memory of the argument, which isn't exactly the interface of this
      85             :  * function.  But in either case you get a rather short-lived
      86             :  * reference that you ought to better leave alone.
      87             :  */
      88             : char *
      89           6 : PLyUnicode_AsString(PyObject *unicode)
      90             : {
      91           6 :     PyObject   *o = PLyUnicode_Bytes(unicode);
      92           6 :     char       *rv = pstrdup(PyBytes_AsString(o));
      93             : 
      94           6 :     Py_XDECREF(o);
      95           6 :     return rv;
      96             : }
      97             : 
      98             : #if PY_MAJOR_VERSION >= 3
      99             : /*
     100             :  * Convert a C string in the PostgreSQL server encoding to a Python
     101             :  * unicode object.  Reference ownership is passed to the caller.
     102             :  */
     103             : PyObject *
     104             : PLyUnicode_FromStringAndSize(const char *s, Py_ssize_t size)
     105             : {
     106             :     char       *utf8string;
     107             :     PyObject   *o;
     108             : 
     109             :     utf8string = pg_server_to_any(s, size, PG_UTF8);
     110             : 
     111             :     if (utf8string == s)
     112             :     {
     113             :         o = PyUnicode_FromStringAndSize(s, size);
     114             :     }
     115             :     else
     116             :     {
     117             :         o = PyUnicode_FromString(utf8string);
     118             :         pfree(utf8string);
     119             :     }
     120             : 
     121             :     return o;
     122             : }
     123             : 
     124             : PyObject *
     125             : PLyUnicode_FromString(const char *s)
     126             : {
     127             :     return PLyUnicode_FromStringAndSize(s, strlen(s));
     128             : }
     129             : 
     130             : #endif                          /* PY_MAJOR_VERSION >= 3 */

Generated by: LCOV version 1.13