mirror of
https://github.com/postgres/postgres.git
synced 2025-06-13 07:41:39 +03:00
Add transforms feature
This provides a mechanism for specifying conversions between SQL data types and procedural languages. As examples, there are transforms for hstore and ltree for PL/Perl and PL/Python. reviews by Pavel Stěhule and Andres Freund
This commit is contained in:
132
contrib/hstore_plpython/expected/hstore_plpython.out
Normal file
132
contrib/hstore_plpython/expected/hstore_plpython.out
Normal file
@ -0,0 +1,132 @@
|
||||
CREATE EXTENSION plpython2u;
|
||||
CREATE EXTENSION hstore_plpython2u;
|
||||
-- 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);
|
||||
INFO: [('aa', 'bb'), ('cc', None)]
|
||||
CONTEXT: PL/Python function "test1"
|
||||
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)
|
||||
plpy.info(sorted(val.items()))
|
||||
return len(val)
|
||||
$$;
|
||||
SELECT test1n('aa=>bb, cc=>NULL'::hstore);
|
||||
INFO: [('aa', 'bb'), ('cc', None)]
|
||||
CONTEXT: PL/Python function "test1n"
|
||||
test1n
|
||||
--------
|
||||
2
|
||||
(1 row)
|
||||
|
||||
-- test hstore[] -> python
|
||||
CREATE FUNCTION test1arr(val hstore[]) RETURNS int
|
||||
LANGUAGE plpythonu
|
||||
TRANSFORM FOR TYPE hstore
|
||||
AS $$
|
||||
plpy.info(repr(val))
|
||||
return len(val)
|
||||
$$;
|
||||
SELECT test1arr(array['aa=>bb, cc=>NULL'::hstore, 'dd=>ee']);
|
||||
INFO: [{'aa': 'bb', 'cc': None}, {'dd': 'ee'}]
|
||||
CONTEXT: PL/Python function "test1arr"
|
||||
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")
|
||||
plpy.info(repr(rv[0]["col1"]))
|
||||
|
||||
val = {'a': 1, 'b': 'boo', 'c': None}
|
||||
plan = plpy.prepare("SELECT $1::text AS col1", ["hstore"])
|
||||
rv = plpy.execute(plan, [val])
|
||||
plpy.info(repr(rv[0]["col1"]))
|
||||
$$;
|
||||
SELECT test3();
|
||||
INFO: {'aa': 'bb', 'cc': None}
|
||||
CONTEXT: PL/Python function "test3"
|
||||
INFO: '"a"=>"1", "b"=>"boo", "c"=>NULL'
|
||||
CONTEXT: PL/Python function "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 $$
|
||||
plpy.info("Trigger row: {'a': %r, 'b': %r}" % (TD["new"]["a"], TD["new"]["b"]))
|
||||
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;
|
||||
INFO: Trigger row: {'a': 1, 'b': {'aa': 'bb', 'cc': None}}
|
||||
CONTEXT: PL/Python function "test4"
|
||||
SELECT * FROM test1;
|
||||
a | b
|
||||
---+---------------------------------
|
||||
1 | "a"=>"1", "b"=>"boo", "c"=>NULL
|
||||
(1 row)
|
||||
|
Reference in New Issue
Block a user