postgresql/contrib/hstore_plpython/sql/hstore_plpython.sql
Richard Guo 309dc4526d Use plpythonu in plpython tests added by commit 0b7719f74
Commit 0b7719f74 added regression tests that spell the language name
as plpython3u.  That works on the master branch, but on v14 the
plpython tests must use the unversioned name plpythonu: the plpython3u
extension is built only in Python 3 builds, and for those builds
regress-python3-mangle.mk rewrites plpythonu to plpython3u in the test
files.  In a Python 2 build the new tests instead failed with
"language \"plpython3u\" does not exist".

Spell the language as plpythonu in the new tests, matching every other
plpython test in this branch, so they work in both Python 2 and Python
3 builds.  This is needed only in v14; later branches no longer
support Python 2 and have dropped the mangling step.

Per buildfarm member hippopotamus.
2026-06-29 14:21:15 +09:00

195 lines
3.8 KiB
PL/PgSQL

CREATE EXTENSION hstore_plpython2u CASCADE;
-- test hstore -> python
CREATE FUNCTION test1(val hstore) RETURNS int
LANGUAGE plpythonu
TRANSFORM FOR TYPE hstore
AS $$
assert isinstance(val, dict)
plpy.info(sorted(val.items()))
return len(val)
$$;
SELECT test1('aa=>bb, cc=>NULL'::hstore);
-- the same with the versioned language name
CREATE FUNCTION test1n(val hstore) RETURNS int
LANGUAGE plpython2u
TRANSFORM FOR TYPE hstore
AS $$
assert isinstance(val, dict)
plpy.info(sorted(val.items()))
return len(val)
$$;
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();
-- A mapping whose items() raises should be reported as an error, not crash
-- the backend
CREATE FUNCTION test1broken() RETURNS hstore
LANGUAGE plpythonu
TRANSFORM FOR TYPE hstore
AS $$
class C(dict):
def items(self):
raise ValueError('items failed')
d = C()
d['x'] = 1
return d
$$;
SELECT test1broken();
-- Likewise for a mapping whose items() does not return key/value pairs
CREATE FUNCTION test1malformed() RETURNS hstore
LANGUAGE plpythonu
TRANSFORM FOR TYPE hstore
AS $$
class C(dict):
def items(self):
return [42]
d = C()
d['x'] = 1
return d
$$;
SELECT test1malformed();
-- Likewise for a mapping whose items() yields fewer pairs than its length
CREATE FUNCTION test1short() RETURNS hstore
LANGUAGE plpythonu
TRANSFORM FOR TYPE hstore
AS $$
class C(dict):
def items(self):
return []
d = C()
d['x'] = 1
return d
$$;
SELECT test1short();
-- Likewise for a mapping whose __len__() raises
CREATE FUNCTION test1brokenlen() RETURNS hstore
LANGUAGE plpythonu
TRANSFORM FOR TYPE hstore
AS $$
class C(dict):
def __len__(self):
raise ValueError('len failed')
d = C()
d['x'] = 1
return d
$$;
SELECT test1brokenlen();
-- test hstore[] -> python
CREATE FUNCTION test1arr(val hstore[]) RETURNS int
LANGUAGE plpythonu
TRANSFORM FOR TYPE hstore
AS $$
assert(val == [{'aa': 'bb', 'cc': None}, {'dd': 'ee'}])
return len(val)
$$;
SELECT test1arr(array['aa=>bb, cc=>NULL'::hstore, 'dd=>ee']);
-- test python -> hstore
CREATE FUNCTION test2(a int, b text) RETURNS hstore
LANGUAGE plpythonu
TRANSFORM FOR TYPE hstore
AS $$
val = {'a': a, 'b': b, 'c': None}
return val
$$;
SELECT test2(1, 'boo');
--- test ruleutils
\sf test2
-- test python -> hstore[]
CREATE FUNCTION test2arr() RETURNS hstore[]
LANGUAGE plpythonu
TRANSFORM FOR TYPE hstore
AS $$
val = [{'a': 1, 'b': 'boo', 'c': None}, {'d': 2}]
return val
$$;
SELECT test2arr();
-- test python -> domain over hstore
CREATE DOMAIN hstore_foo AS hstore CHECK(VALUE ? 'foo');
CREATE FUNCTION test2dom(fn text) RETURNS hstore_foo
LANGUAGE plpythonu
TRANSFORM FOR TYPE hstore
AS $$
return {'a': 1, fn: 'boo', 'c': None}
$$;
SELECT test2dom('foo');
SELECT test2dom('bar'); -- fail
-- test as part of prepare/execute
CREATE FUNCTION test3() RETURNS void
LANGUAGE plpythonu
TRANSFORM FOR TYPE hstore
AS $$
rv = plpy.execute("SELECT 'aa=>bb, cc=>NULL'::hstore AS col1")
assert(rv[0]["col1"] == {'aa': 'bb', 'cc': None})
val = {'a': 1, 'b': 'boo', 'c': None}
plan = plpy.prepare("SELECT $1::text AS col1", ["hstore"])
rv = plpy.execute(plan, [val])
assert(rv[0]["col1"] == '"a"=>"1", "b"=>"boo", "c"=>NULL')
$$;
SELECT test3();
-- test trigger
CREATE TABLE test1 (a int, b hstore);
INSERT INTO test1 VALUES (1, 'aa=>bb, cc=>NULL');
SELECT * FROM test1;
CREATE FUNCTION test4() RETURNS trigger
LANGUAGE plpythonu
TRANSFORM FOR TYPE hstore
AS $$
assert(TD["new"] == {'a': 1, 'b': {'aa': 'bb', 'cc': None}})
if TD["new"]["a"] == 1:
TD["new"]["b"] = {'a': 1, 'b': 'boo', 'c': None}
return "MODIFY"
$$;
CREATE TRIGGER test4 BEFORE UPDATE ON test1 FOR EACH ROW EXECUTE PROCEDURE test4();
UPDATE test1 SET a = a;
SELECT * FROM test1;