mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-27 08:39:28 +08:00
b67aaf21e8
Without CASCADE, if an extension has an unfullfilled dependency on another extension, CREATE EXTENSION ERRORs out with "required extension ... is not installed". That is annoying, especially when that dependency is an implementation detail of the extension, rather than something the extension's user can make sense of. In addition to CASCADE this also includes a small set of regression tests around CREATE EXTENSION. Author: Petr Jelinek, editorialized by Michael Paquier, Andres Freund Reviewed-By: Michael Paquier, Andres Freund, Jeff Janes Discussion: 557E0520.3040800@2ndquadrant.com
127 lines
2.9 KiB
Plaintext
127 lines
2.9 KiB
Plaintext
CREATE EXTENSION hstore_plpython2u CASCADE;
|
|
NOTICE: installing required extension "plpython2u"
|
|
-- test hstore -> python
|
|
CREATE FUNCTION test1(val hstore) RETURNS int
|
|
LANGUAGE plpythonu
|
|
TRANSFORM FOR TYPE hstore
|
|
AS $$
|
|
assert isinstance(val, dict)
|
|
i = list(val.items())
|
|
i.sort()
|
|
plpy.info(i)
|
|
return len(val)
|
|
$$;
|
|
SELECT test1('aa=>bb, cc=>NULL'::hstore);
|
|
INFO: [('aa', 'bb'), ('cc', None)]
|
|
test1
|
|
-------
|
|
2
|
|
(1 row)
|
|
|
|
-- 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)
|
|
i = list(val.items())
|
|
i.sort()
|
|
plpy.info(i)
|
|
return len(val)
|
|
$$;
|
|
SELECT test1n('aa=>bb, cc=>NULL'::hstore);
|
|
INFO: [('aa', 'bb'), ('cc', None)]
|
|
test1n
|
|
--------
|
|
2
|
|
(1 row)
|
|
|
|
-- 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']);
|
|
test1arr
|
|
----------
|
|
2
|
|
(1 row)
|
|
|
|
-- test python -> hstore
|
|
CREATE FUNCTION test2() RETURNS hstore
|
|
LANGUAGE plpythonu
|
|
TRANSFORM FOR TYPE hstore
|
|
AS $$
|
|
val = {'a': 1, 'b': 'boo', 'c': None}
|
|
return val
|
|
$$;
|
|
SELECT test2();
|
|
test2
|
|
---------------------------------
|
|
"a"=>"1", "b"=>"boo", "c"=>NULL
|
|
(1 row)
|
|
|
|
-- 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();
|
|
test2arr
|
|
--------------------------------------------------------------
|
|
{"\"a\"=>\"1\", \"b\"=>\"boo\", \"c\"=>NULL","\"d\"=>\"2\""}
|
|
(1 row)
|
|
|
|
-- 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();
|
|
test3
|
|
-------
|
|
|
|
(1 row)
|
|
|
|
-- test trigger
|
|
CREATE TABLE test1 (a int, b hstore);
|
|
INSERT INTO test1 VALUES (1, 'aa=>bb, cc=>NULL');
|
|
SELECT * FROM test1;
|
|
a | b
|
|
---+------------------------
|
|
1 | "aa"=>"bb", "cc"=>NULL
|
|
(1 row)
|
|
|
|
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;
|
|
a | b
|
|
---+---------------------------------
|
|
1 | "a"=>"1", "b"=>"boo", "c"=>NULL
|
|
(1 row)
|
|
|