LCOV - code coverage report
Current view: top level - src/pl/plpython - plpy_util.c (source / functions) Hit Total Coverage
Test: PostgreSQL 18devel Lines: 23 36 63.9 %
Date: 2024-11-21 10:14:43 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             : 
      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             : }

Generated by: LCOV version 1.14