mirror of https://github.com/postgres/postgres
We used to convert the unicode object directly to a string in the server encoding by calling Python's PyUnicode_AsEncodedString function. In other words, we used Python's routines to do the encoding. However, that has a few problems. First of all, it required keeping a mapping table of Python encoding names and PostgreSQL encodings. But the real killer was that Python doesn't support EUC_TW and MULE_INTERNAL encodings at all. Instead, convert the Python unicode object to UTF-8, and use PostgreSQL's encoding conversion functions to convert from UTF-8 to server encoding. We were already doing the same in the other direction in PLyUnicode_FromString, so this is more consistent, too. Note: This makes SQL_ASCII to behave more leniently. We used to map SQL_ASCII to Python's 'ascii', which on Python means strict 7-bit ASCII only, so you got an error if the python string contained anything but pure ASCII. You no longer get an error; you get the UTF-8 representation of the string instead. Backpatch to 9.0, where these conversions were introduced. Jan UrbańskiREL9_1_STABLE
parent
c9c95202b0
commit
3159599390
@ -1,54 +0,0 @@ |
|||||||
-- |
|
||||||
-- Unicode handling |
|
||||||
-- |
|
||||||
SET client_encoding TO UTF8; |
|
||||||
CREATE TABLE unicode_test ( |
|
||||||
testvalue text NOT NULL |
|
||||||
); |
|
||||||
CREATE FUNCTION unicode_return() RETURNS text AS E' |
|
||||||
return u"\\x80" |
|
||||||
' LANGUAGE plpythonu; |
|
||||||
CREATE FUNCTION unicode_trigger() RETURNS trigger AS E' |
|
||||||
TD["new"]["testvalue"] = u"\\x80" |
|
||||||
return "MODIFY" |
|
||||||
' LANGUAGE plpythonu; |
|
||||||
CREATE TRIGGER unicode_test_bi BEFORE INSERT ON unicode_test |
|
||||||
FOR EACH ROW EXECUTE PROCEDURE unicode_trigger(); |
|
||||||
CREATE FUNCTION unicode_plan1() RETURNS text AS E' |
|
||||||
plan = plpy.prepare("SELECT $1 AS testvalue", ["text"]) |
|
||||||
rv = plpy.execute(plan, [u"\\x80"], 1) |
|
||||||
return rv[0]["testvalue"] |
|
||||||
' LANGUAGE plpythonu; |
|
||||||
CREATE FUNCTION unicode_plan2() RETURNS text AS E' |
|
||||||
plan = plpy.prepare("SELECT $1 || $2 AS testvalue", ["text", u"text"]) |
|
||||||
rv = plpy.execute(plan, ["foo", "bar"], 1) |
|
||||||
return rv[0]["testvalue"] |
|
||||||
' LANGUAGE plpythonu; |
|
||||||
SELECT unicode_return(); |
|
||||||
ERROR: could not convert Python Unicode object to PostgreSQL server encoding |
|
||||||
DETAIL: UnicodeEncodeError: 'ascii' codec can't encode character u'\x80' in position 0: ordinal not in range(128) |
|
||||||
CONTEXT: while creating return value |
|
||||||
PL/Python function "unicode_return" |
|
||||||
INSERT INTO unicode_test (testvalue) VALUES ('test'); |
|
||||||
ERROR: could not convert Python Unicode object to PostgreSQL server encoding |
|
||||||
DETAIL: UnicodeEncodeError: 'ascii' codec can't encode character u'\x80' in position 0: ordinal not in range(128) |
|
||||||
CONTEXT: while modifying trigger row |
|
||||||
PL/Python function "unicode_trigger" |
|
||||||
SELECT * FROM unicode_test; |
|
||||||
testvalue |
|
||||||
----------- |
|
||||||
(0 rows) |
|
||||||
|
|
||||||
SELECT unicode_plan1(); |
|
||||||
ERROR: spiexceptions.InternalError: could not convert Python Unicode object to PostgreSQL server encoding |
|
||||||
DETAIL: UnicodeEncodeError: 'ascii' codec can't encode character u'\x80' in position 0: ordinal not in range(128) |
|
||||||
CONTEXT: Traceback (most recent call last): |
|
||||||
PL/Python function "unicode_plan1", line 3, in <module> |
|
||||||
rv = plpy.execute(plan, [u"\x80"], 1) |
|
||||||
PL/Python function "unicode_plan1" |
|
||||||
SELECT unicode_plan2(); |
|
||||||
unicode_plan2 |
|
||||||
--------------- |
|
||||||
foobar |
|
||||||
(1 row) |
|
||||||
|
|
||||||
Loading…
Reference in new issue