mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-11-27 07:21:09 +08:00
In hstore_plpython, avoid crashing when return value isn't a mapping.
Python 3 changed the behavior of PyMapping_Check(), breaking the test in plpython_to_hstore() that verifies whether a function result to be transformed is acceptable. A backwards-compatible fix is to first verify that the object doesn't pass PySequence_Check(). Perhaps accidentally, our other uses of PyMapping_Check() already follow uses of PySequence_Check(), so that no other bugs were created by this change. Per bug #17908 from Alexander Lakhin. Back-patch to all supported branches. Dmitry Dolgov and Tom Lane Discussion: https://postgr.es/m/17908-3f19a125d56a11d6@postgresql.org
This commit is contained in:
parent
b95f36f861
commit
de2dfa0538
@ -32,6 +32,17 @@ INFO: [('aa', 'bb'), ('cc', None)]
|
|||||||
2
|
2
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
-- test that a non-mapping result is correctly rejected
|
||||||
|
CREATE FUNCTION test1bad() RETURNS hstore
|
||||||
|
LANGUAGE plpythonu
|
||||||
|
TRANSFORM FOR TYPE hstore
|
||||||
|
AS $$
|
||||||
|
return "foo"
|
||||||
|
$$;
|
||||||
|
SELECT test1bad();
|
||||||
|
ERROR: not a Python mapping
|
||||||
|
CONTEXT: while creating return value
|
||||||
|
PL/Python function "test1bad"
|
||||||
-- test hstore[] -> python
|
-- test hstore[] -> python
|
||||||
CREATE FUNCTION test1arr(val hstore[]) RETURNS int
|
CREATE FUNCTION test1arr(val hstore[]) RETURNS int
|
||||||
LANGUAGE plpythonu
|
LANGUAGE plpythonu
|
||||||
|
@ -133,7 +133,13 @@ plpython_to_hstore(PG_FUNCTION_ARGS)
|
|||||||
HStore *volatile out;
|
HStore *volatile out;
|
||||||
|
|
||||||
dict = (PyObject *) PG_GETARG_POINTER(0);
|
dict = (PyObject *) PG_GETARG_POINTER(0);
|
||||||
if (!PyMapping_Check(dict))
|
|
||||||
|
/*
|
||||||
|
* As of Python 3, PyMapping_Check() is unreliable unless one first checks
|
||||||
|
* that the object isn't a sequence. (Cleaner solutions exist, but not
|
||||||
|
* before Python 3.10, which we're not prepared to require yet.)
|
||||||
|
*/
|
||||||
|
if (PySequence_Check(dict) || !PyMapping_Check(dict))
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
|
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
|
||||||
errmsg("not a Python mapping")));
|
errmsg("not a Python mapping")));
|
||||||
|
@ -27,6 +27,17 @@ $$;
|
|||||||
SELECT test1n('aa=>bb, cc=>NULL'::hstore);
|
SELECT test1n('aa=>bb, cc=>NULL'::hstore);
|
||||||
|
|
||||||
|
|
||||||
|
-- test that a non-mapping result is correctly rejected
|
||||||
|
CREATE FUNCTION test1bad() RETURNS hstore
|
||||||
|
LANGUAGE plpythonu
|
||||||
|
TRANSFORM FOR TYPE hstore
|
||||||
|
AS $$
|
||||||
|
return "foo"
|
||||||
|
$$;
|
||||||
|
|
||||||
|
SELECT test1bad();
|
||||||
|
|
||||||
|
|
||||||
-- test hstore[] -> python
|
-- test hstore[] -> python
|
||||||
CREATE FUNCTION test1arr(val hstore[]) RETURNS int
|
CREATE FUNCTION test1arr(val hstore[]) RETURNS int
|
||||||
LANGUAGE plpythonu
|
LANGUAGE plpythonu
|
||||||
|
Loading…
Reference in New Issue
Block a user