LCOV - code coverage report
Current view: top level - src/pl/plpython - plpy_util.c (source / functions) Hit Total Coverage
Test: PostgreSQL 17devel Lines: 23 36 63.9 %
Date: 2024-04-19 08:11:23 Functions: 4 4 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        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           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        4802 :         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       13326 : PLyUnicode_FromStringAndSize(const char *s, Py_ssize_t size)
      98             : {
      99             :     char       *utf8string;
     100             :     PyObject   *o;
     101             : 
     102       13326 :     utf8string = pg_server_to_any(s, size, PG_UTF8);
     103             : 
     104       13326 :     if (utf8string == s)
     105             :     {
     106       13326 :         o = PyUnicode_FromStringAndSize(s, size);
     107             :     }
     108             :     else
     109             :     {
     110           0 :         o = PyUnicode_FromString(utf8string);
     111           0 :         pfree(utf8string);
     112             :     }
     113             : 
     114       13326 :     return o;
     115             : }
     116             : 
     117             : PyObject *
     118       13232 : PLyUnicode_FromString(const char *s)
     119             : {
     120       13232 :     return PLyUnicode_FromStringAndSize(s, strlen(s));
     121             : }

Generated by: LCOV version 1.14