LCOV - code coverage report
Current view: top level - src/pl/plpython - plpy_util.c (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 66.7 % 33 22
Test Date: 2026-03-10 06:14:44 Functions: 100.0 % 4 4
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              : 
      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         2419 : 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         2419 :     bytes = PyUnicode_AsUTF8String(unicode);
      28         2419 :     if (bytes == NULL)
      29            0 :         PLy_elog(ERROR, "could not convert Python Unicode object to bytes");
      30              : 
      31         2419 :     utf8string = PyBytes_AsString(bytes);
      32         2419 :     if (utf8string == NULL)
      33              :     {
      34              :         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         2419 :     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              :             Py_DECREF(bytes);
      57            0 :             PG_RE_THROW();
      58              :         }
      59            0 :         PG_END_TRY();
      60              :     }
      61              :     else
      62         2419 :         encoded = utf8string;
      63              : 
      64              :     /* finally, build a bytes object in the server encoding */
      65         2419 :     rv = PyBytes_FromStringAndSize(encoded, strlen(encoded));
      66              : 
      67              :     /* if pg_any_to_server allocated memory, free it now */
      68         2419 :     if (utf8string != encoded)
      69            0 :         pfree(encoded);
      70              : 
      71              :     Py_DECREF(bytes);
      72         2419 :     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          835 : PLyUnicode_AsString(PyObject *unicode)
      82              : {
      83          835 :     PyObject   *o = PLyUnicode_Bytes(unicode);
      84          835 :     char       *rv = pstrdup(PyBytes_AsString(o));
      85              : 
      86          835 :     Py_XDECREF(o);
      87          835 :     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         6755 : PLyUnicode_FromStringAndSize(const char *s, Py_ssize_t size)
      96              : {
      97              :     char       *utf8string;
      98              :     PyObject   *o;
      99              : 
     100         6755 :     utf8string = pg_server_to_any(s, size, PG_UTF8);
     101              : 
     102         6755 :     if (utf8string == s)
     103              :     {
     104         6755 :         o = PyUnicode_FromStringAndSize(s, size);
     105              :     }
     106              :     else
     107              :     {
     108            0 :         o = PyUnicode_FromString(utf8string);
     109            0 :         pfree(utf8string);
     110              :     }
     111              : 
     112         6755 :     return o;
     113              : }
     114              : 
     115              : PyObject *
     116         6708 : PLyUnicode_FromString(const char *s)
     117              : {
     118         6708 :     return PLyUnicode_FromStringAndSize(s, strlen(s));
     119              : }
        

Generated by: LCOV version 2.0-1