plpython-use-server-encoding-functions-v2.patch
text/x-diff
Filename: plpython-use-server-encoding-functions-v2.patch
Type: text/x-diff
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
Series: patch v2
| File | + | − |
|---|---|---|
| src/pl/plpython/plpy_elog.c | 0 | 0 |
| src/pl/plpython/plpy_util.c | 0 | 0 |
diff --git a/src/pl/plpython/plpy_elog.c b/src/pl/plpython/plpy_elog.c
new file mode 100644
index c375ac0..9944f72
*** a/src/pl/plpython/plpy_elog.c
--- b/src/pl/plpython/plpy_elog.c
*************** static char *get_source_line(const char
*** 28,33 ****
--- 28,41 ----
/*
+ * Guard agains re-entrant calls to PLy_traceback, which can happen if
+ * traceback formatting functions raise Python errors.
+ */
+ #define TRACEBACK_RECURSION_LIMIT 2
+ static int recursion_depth = 0;
+
+
+ /*
* Emit a PG error or notice, together with any available info about
* the current Python error, previously set by PLy_exception_set().
* This should be used to propagate Python errors into PG. If fmt is
*************** static char *get_source_line(const char
*** 38,46 ****
void
PLy_elog(int elevel, const char *fmt,...)
{
! char *xmsg;
! char *tbmsg;
! int tb_depth;
StringInfoData emsg;
PyObject *exc,
*val,
--- 46,54 ----
void
PLy_elog(int elevel, const char *fmt,...)
{
! char *xmsg = NULL;
! char *tbmsg = NULL;
! int tb_depth = 0;
StringInfoData emsg;
PyObject *exc,
*val,
*************** PLy_elog(int elevel, const char *fmt,...
*** 62,68 ****
}
PyErr_Restore(exc, val, tb);
! PLy_traceback(&xmsg, &tbmsg, &tb_depth);
if (fmt)
{
--- 70,90 ----
}
PyErr_Restore(exc, val, tb);
! if (recursion_depth++ <= TRACEBACK_RECURSION_LIMIT)
! {
! PG_TRY();
! {
! PLy_traceback(&xmsg, &tbmsg, &tb_depth);
! }
! PG_CATCH();
! {
! recursion_depth--;
! PG_RE_THROW();
! }
! PG_END_TRY();
! }
!
! recursion_depth--;
if (fmt)
{
diff --git a/src/pl/plpython/plpy_util.c b/src/pl/plpython/plpy_util.c
new file mode 100644
index 4aabafc..94c035e
*** a/src/pl/plpython/plpy_util.c
--- b/src/pl/plpython/plpy_util.c
*************** PLy_free(void *ptr)
*** 61,126 ****
PyObject *
PLyUnicode_Bytes(PyObject *unicode)
{
! PyObject *rv;
! const char *serverenc;
! /*
! * Map PostgreSQL encoding to a Python encoding name.
! */
! switch (GetDatabaseEncoding())
{
! case PG_SQL_ASCII:
! /*
! * Mapping SQL_ASCII to Python's 'ascii' is a bit bogus. Python's
! * 'ascii' means true 7-bit only ASCII, while PostgreSQL's
! * SQL_ASCII means that anything is allowed, and the system doesn't
! * try to interpret the bytes in any way. But not sure what else
! * to do, and we haven't heard any complaints...
! */
! serverenc = "ascii";
! break;
! case PG_WIN1250:
! serverenc = "cp1250";
! break;
! case PG_WIN1251:
! serverenc = "cp1251";
! break;
! case PG_WIN1252:
! serverenc = "cp1252";
! break;
! case PG_WIN1253:
! serverenc = "cp1253";
! break;
! case PG_WIN1254:
! serverenc = "cp1254";
! break;
! case PG_WIN1255:
! serverenc = "cp1255";
! break;
! case PG_WIN1256:
! serverenc = "cp1256";
! break;
! case PG_WIN1257:
! serverenc = "cp1257";
! break;
! case PG_WIN1258:
! serverenc = "cp1258";
! break;
! case PG_WIN866:
! serverenc = "cp866";
! break;
! case PG_WIN874:
! serverenc = "cp874";
! break;
! default:
! /* Other encodings have the same name in Python. */
! serverenc = GetDatabaseEncodingName();
! break;
}
! rv = PyUnicode_AsEncodedString(unicode, serverenc, "strict");
! if (rv == NULL)
! PLy_elog(ERROR, "could not convert Python Unicode object to PostgreSQL server encoding");
return rv;
}
--- 61,106 ----
PyObject *
PLyUnicode_Bytes(PyObject *unicode)
{
! PyObject *bytes, *rv;
! char *utf8string, *encoded;
! /* first encode the Python unicode object with UTF-8 */
! bytes = PyUnicode_AsUTF8String(unicode);
! if (bytes == NULL)
! PLy_elog(ERROR, "could not convert Python Unicode object to bytes");
!
! utf8string = PyBytes_AsString(bytes);
! if (utf8string == NULL) {
! Py_DECREF(bytes);
! PLy_elog(ERROR, "could not extract bytes from encoded string");
! }
!
! /* then convert to server encoding */
! PG_TRY();
{
! encoded = (char *) pg_do_encoding_conversion(
! (unsigned char *) utf8string,
! strlen(utf8string),
! PG_UTF8,
! GetDatabaseEncoding());
! }
! PG_CATCH();
! {
! Py_DECREF(bytes);
! PG_RE_THROW();
}
+ PG_END_TRY();
! /* finally, build a bytes object in the server encoding */
! rv = PyBytes_FromStringAndSize(encoded, strlen(encoded));
!
! /* if pg_do_encoding_conversion allocated memory, free it now */
! if (utf8string != encoded)
! {
! pfree(encoded);
! }
!
! Py_DECREF(bytes);
return rv;
}