aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>2012-07-05 22:16:29 +0300
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>2012-07-05 22:32:04 +0300
commit138313ebaa985030d75d429c3b3cb7138e62b10f (patch)
tree0a894fd991890fee743a7099355b157c527c59c7
parentb8aca12d77612007ebde22db14e3971ef664d553 (diff)
downloadpostgresql-138313ebaa985030d75d429c3b3cb7138e62b10f.tar.gz
postgresql-138313ebaa985030d75d429c3b3cb7138e62b10f.zip
Fix mapping of PostgreSQL encodings to Python encodings.
Windows encodings, "win1252" and so forth, are named differently in Python, like "cp1252". Also, if the PyUnicode_AsEncodedString() function call fails for some reason, use a plain ereport(), not a PLy_elog(), to report that error. That avoids recursion and crash, if PLy_elog() tries to call PLyUnicode_Bytes() again. This fixes bug reported by Asif Naeem. Backpatch down to 9.0, before that plpython didn't even try these conversions. Jan UrbaƄski, with minor comment improvements by me.
-rw-r--r--src/pl/plpython/plpython.c69
1 files changed, 62 insertions, 7 deletions
diff --git a/src/pl/plpython/plpython.c b/src/pl/plpython/plpython.c
index 95efd0b42e6..2f67caba6db 100644
--- a/src/pl/plpython/plpython.c
+++ b/src/pl/plpython/plpython.c
@@ -4873,16 +4873,71 @@ PLyUnicode_Bytes(PyObject *unicode)
const char *serverenc;
/*
- * Python understands almost all PostgreSQL encoding names, but it doesn't
- * know SQL_ASCII.
+ * Map PostgreSQL encoding to a Python encoding name.
*/
- if (GetDatabaseEncoding() == PG_SQL_ASCII)
- serverenc = "ascii";
- else
- serverenc = GetDatabaseEncodingName();
+ 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");
+ {
+ /*
+ * Use a plain ereport instead of PLy_elog to avoid recursion, if
+ * the traceback formatting functions try to do unicode to bytes
+ * conversion again.
+ */
+ ereport(ERROR,
+ (errcode(ERRCODE_INTERNAL_ERROR),
+ errmsg("could not convert Python Unicode object to PostgreSQL server encoding")));
+ }
return rv;
}