# Generated subdirectories
-/expected/python3/
/log/
/results/
-/sql/python3/
/tmp_check/
DATA = hstore_plpython3u--1.0.sql
REGRESS = hstore_plpython
-REGRESS_PLPYTHON3_MANGLE := $(REGRESS)
PG_CPPFLAGS = $(python_includespec) -DPLPYTHON_LIBNAME='"plpython$(python_majorversion)"'
endif
REGRESS_OPTS += --load-extension=hstore
-ifeq ($(python_majorversion),2)
-REGRESS_OPTS += --load-extension=plpythonu --load-extension=hstore_plpythonu
-endif
EXTRA_INSTALL += contrib/hstore
-
-include $(top_srcdir)/src/pl/plpython/regress-python3-mangle.mk
-CREATE EXTENSION hstore_plpython2u CASCADE;
-NOTICE: installing required extension "plpython2u"
+CREATE EXTENSION hstore_plpython3u CASCADE;
+NOTICE: installing required extension "plpython3u"
-- test hstore -> python
CREATE FUNCTION test1(val hstore) RETURNS int
-LANGUAGE plpythonu
+LANGUAGE plpython3u
TRANSFORM FOR TYPE hstore
AS $$
assert isinstance(val, dict)
-- the same with the versioned language name
CREATE FUNCTION test1n(val hstore) RETURNS int
-LANGUAGE plpython2u
+LANGUAGE plpython3u
TRANSFORM FOR TYPE hstore
AS $$
assert isinstance(val, dict)
-- test hstore[] -> python
CREATE FUNCTION test1arr(val hstore[]) RETURNS int
-LANGUAGE plpythonu
+LANGUAGE plpython3u
TRANSFORM FOR TYPE hstore
AS $$
assert(val == [{'aa': 'bb', 'cc': None}, {'dd': 'ee'}])
-- test python -> hstore
CREATE FUNCTION test2(a int, b text) RETURNS hstore
-LANGUAGE plpythonu
+LANGUAGE plpython3u
TRANSFORM FOR TYPE hstore
AS $$
val = {'a': a, 'b': b, 'c': None}
CREATE OR REPLACE FUNCTION public.test2(a integer, b text)
RETURNS hstore
TRANSFORM FOR TYPE hstore
- LANGUAGE plpythonu
+ LANGUAGE plpython3u
AS $function$
val = {'a': a, 'b': b, 'c': None}
return val
$function$
-- test python -> hstore[]
CREATE FUNCTION test2arr() RETURNS hstore[]
-LANGUAGE plpythonu
+LANGUAGE plpython3u
TRANSFORM FOR TYPE hstore
AS $$
val = [{'a': 1, 'b': 'boo', 'c': None}, {'d': 2}]
-- test python -> domain over hstore
CREATE DOMAIN hstore_foo AS hstore CHECK(VALUE ? 'foo');
CREATE FUNCTION test2dom(fn text) RETURNS hstore_foo
-LANGUAGE plpythonu
+LANGUAGE plpython3u
TRANSFORM FOR TYPE hstore
AS $$
return {'a': 1, fn: 'boo', 'c': None}
PL/Python function "test2dom"
-- test as part of prepare/execute
CREATE FUNCTION test3() RETURNS void
-LANGUAGE plpythonu
+LANGUAGE plpython3u
TRANSFORM FOR TYPE hstore
AS $$
rv = plpy.execute("SELECT 'aa=>bb, cc=>NULL'::hstore AS col1")
(1 row)
CREATE FUNCTION test4() RETURNS trigger
-LANGUAGE plpythonu
+LANGUAGE plpython3u
TRANSFORM FOR TYPE hstore
AS $$
assert(TD["new"] == {'a': 1, 'b': {'aa': 'bb', 'cc': None}})
-CREATE EXTENSION hstore_plpython2u CASCADE;
+CREATE EXTENSION hstore_plpython3u CASCADE;
-- test hstore -> python
CREATE FUNCTION test1(val hstore) RETURNS int
-LANGUAGE plpythonu
+LANGUAGE plpython3u
TRANSFORM FOR TYPE hstore
AS $$
assert isinstance(val, dict)
-- the same with the versioned language name
CREATE FUNCTION test1n(val hstore) RETURNS int
-LANGUAGE plpython2u
+LANGUAGE plpython3u
TRANSFORM FOR TYPE hstore
AS $$
assert isinstance(val, dict)
-- test hstore[] -> python
CREATE FUNCTION test1arr(val hstore[]) RETURNS int
-LANGUAGE plpythonu
+LANGUAGE plpython3u
TRANSFORM FOR TYPE hstore
AS $$
assert(val == [{'aa': 'bb', 'cc': None}, {'dd': 'ee'}])
-- test python -> hstore
CREATE FUNCTION test2(a int, b text) RETURNS hstore
-LANGUAGE plpythonu
+LANGUAGE plpython3u
TRANSFORM FOR TYPE hstore
AS $$
val = {'a': a, 'b': b, 'c': None}
-- test python -> hstore[]
CREATE FUNCTION test2arr() RETURNS hstore[]
-LANGUAGE plpythonu
+LANGUAGE plpython3u
TRANSFORM FOR TYPE hstore
AS $$
val = [{'a': 1, 'b': 'boo', 'c': None}, {'d': 2}]
CREATE DOMAIN hstore_foo AS hstore CHECK(VALUE ? 'foo');
CREATE FUNCTION test2dom(fn text) RETURNS hstore_foo
-LANGUAGE plpythonu
+LANGUAGE plpython3u
TRANSFORM FOR TYPE hstore
AS $$
return {'a': 1, fn: 'boo', 'c': None}
-- test as part of prepare/execute
CREATE FUNCTION test3() RETURNS void
-LANGUAGE plpythonu
+LANGUAGE plpython3u
TRANSFORM FOR TYPE hstore
AS $$
rv = plpy.execute("SELECT 'aa=>bb, cc=>NULL'::hstore AS col1")
SELECT * FROM test1;
CREATE FUNCTION test4() RETURNS trigger
-LANGUAGE plpythonu
+LANGUAGE plpython3u
TRANSFORM FOR TYPE hstore
AS $$
assert(TD["new"] == {'a': 1, 'b': {'aa': 'bb', 'cc': None}})
# Generated subdirectories
-/expected/python3/
/log/
/results/
-/sql/python3/
/tmp_check/
DATA = jsonb_plpython3u--1.0.sql
REGRESS = jsonb_plpython
-REGRESS_PLPYTHON3_MANGLE := $(REGRESS)
ifdef USE_PGXS
PG_CONFIG = pg_config
rpathdir = $(python_libdir)
SHLIB_LINK += $(python_libspec) $(python_additional_libs)
endif
-
-ifeq ($(python_majorversion),2)
-REGRESS_OPTS += --load-extension=plpythonu --load-extension=jsonb_plpythonu
-endif
-
-include $(top_srcdir)/src/pl/plpython/regress-python3-mangle.mk
-CREATE EXTENSION jsonb_plpython2u CASCADE;
-NOTICE: installing required extension "plpython2u"
+CREATE EXTENSION jsonb_plpython3u CASCADE;
+NOTICE: installing required extension "plpython3u"
-- test jsonb -> python dict
CREATE FUNCTION test1(val jsonb) RETURNS int
-LANGUAGE plpythonu
+LANGUAGE plpython3u
TRANSFORM FOR TYPE jsonb
AS $$
assert isinstance(val, dict)
-- test jsonb -> python dict
-- complex dict with dicts as value
CREATE FUNCTION test1complex(val jsonb) RETURNS int
-LANGUAGE plpython2u
+LANGUAGE plpython3u
TRANSFORM FOR TYPE jsonb
AS $$
assert isinstance(val, dict)
-- test jsonb[] -> python dict
-- dict with array as value
CREATE FUNCTION test1arr(val jsonb) RETURNS int
-LANGUAGE plpythonu
+LANGUAGE plpython3u
TRANSFORM FOR TYPE jsonb
AS $$
assert isinstance(val, dict)
-- test jsonb[] -> python list
-- simple list
CREATE FUNCTION test2arr(val jsonb) RETURNS int
-LANGUAGE plpythonu
+LANGUAGE plpython3u
TRANSFORM FOR TYPE jsonb
AS $$
assert isinstance(val, list)
-- test jsonb[] -> python list
-- array of dicts
CREATE FUNCTION test3arr(val jsonb) RETURNS int
-LANGUAGE plpythonu
+LANGUAGE plpython3u
TRANSFORM FOR TYPE jsonb
AS $$
assert isinstance(val, list)
-- test jsonb int -> python int
CREATE FUNCTION test1int(val jsonb) RETURNS int
-LANGUAGE plpythonu
+LANGUAGE plpython3u
TRANSFORM FOR TYPE jsonb
AS $$
assert(val == 1)
-- test jsonb string -> python string
CREATE FUNCTION test1string(val jsonb) RETURNS text
-LANGUAGE plpythonu
+LANGUAGE plpython3u
TRANSFORM FOR TYPE jsonb
AS $$
assert(val == "a")
-- test jsonb null -> python None
CREATE FUNCTION test1null(val jsonb) RETURNS int
-LANGUAGE plpythonu
+LANGUAGE plpython3u
TRANSFORM FOR TYPE jsonb
AS $$
assert(val == None)
-- test python -> jsonb
CREATE FUNCTION roundtrip(val jsonb) RETURNS jsonb
-LANGUAGE plpythonu
+LANGUAGE plpython3u
TRANSFORM FOR TYPE jsonb
as $$
return val
-- complex numbers -> jsonb
CREATE FUNCTION testComplexNumbers() RETURNS jsonb
-LANGUAGE plpythonu
+LANGUAGE plpython3u
TRANSFORM FOR TYPE jsonb
AS $$
x = 1 + 2j
PL/Python function "testcomplexnumbers"
-- range -> jsonb
CREATE FUNCTION testRange() RETURNS jsonb
-LANGUAGE plpythonu
+LANGUAGE plpython3u
TRANSFORM FOR TYPE jsonb
AS $$
x = range(3)
-- 0xff -> jsonb
CREATE FUNCTION testDecimal() RETURNS jsonb
-LANGUAGE plpythonu
+LANGUAGE plpython3u
TRANSFORM FOR TYPE jsonb
AS $$
x = 0xff
-- tuple -> jsonb
CREATE FUNCTION testTuple() RETURNS jsonb
-LANGUAGE plpythonu
+LANGUAGE plpython3u
TRANSFORM FOR TYPE jsonb
AS $$
x = (1, 'String', None)
-- interesting dict -> jsonb
CREATE FUNCTION test_dict1() RETURNS jsonb
-LANGUAGE plpythonu
+LANGUAGE plpython3u
TRANSFORM FOR TYPE jsonb
AS $$
x = {"a": 1, None: 2, 33: 3}
-CREATE EXTENSION jsonb_plpython2u CASCADE;
+CREATE EXTENSION jsonb_plpython3u CASCADE;
-- test jsonb -> python dict
CREATE FUNCTION test1(val jsonb) RETURNS int
-LANGUAGE plpythonu
+LANGUAGE plpython3u
TRANSFORM FOR TYPE jsonb
AS $$
assert isinstance(val, dict)
-- test jsonb -> python dict
-- complex dict with dicts as value
CREATE FUNCTION test1complex(val jsonb) RETURNS int
-LANGUAGE plpython2u
+LANGUAGE plpython3u
TRANSFORM FOR TYPE jsonb
AS $$
assert isinstance(val, dict)
-- test jsonb[] -> python dict
-- dict with array as value
CREATE FUNCTION test1arr(val jsonb) RETURNS int
-LANGUAGE plpythonu
+LANGUAGE plpython3u
TRANSFORM FOR TYPE jsonb
AS $$
assert isinstance(val, dict)
-- test jsonb[] -> python list
-- simple list
CREATE FUNCTION test2arr(val jsonb) RETURNS int
-LANGUAGE plpythonu
+LANGUAGE plpython3u
TRANSFORM FOR TYPE jsonb
AS $$
assert isinstance(val, list)
-- test jsonb[] -> python list
-- array of dicts
CREATE FUNCTION test3arr(val jsonb) RETURNS int
-LANGUAGE plpythonu
+LANGUAGE plpython3u
TRANSFORM FOR TYPE jsonb
AS $$
assert isinstance(val, list)
-- test jsonb int -> python int
CREATE FUNCTION test1int(val jsonb) RETURNS int
-LANGUAGE plpythonu
+LANGUAGE plpython3u
TRANSFORM FOR TYPE jsonb
AS $$
assert(val == 1)
-- test jsonb string -> python string
CREATE FUNCTION test1string(val jsonb) RETURNS text
-LANGUAGE plpythonu
+LANGUAGE plpython3u
TRANSFORM FOR TYPE jsonb
AS $$
assert(val == "a")
-- test jsonb null -> python None
CREATE FUNCTION test1null(val jsonb) RETURNS int
-LANGUAGE plpythonu
+LANGUAGE plpython3u
TRANSFORM FOR TYPE jsonb
AS $$
assert(val == None)
-- test python -> jsonb
CREATE FUNCTION roundtrip(val jsonb) RETURNS jsonb
-LANGUAGE plpythonu
+LANGUAGE plpython3u
TRANSFORM FOR TYPE jsonb
as $$
return val
-- complex numbers -> jsonb
CREATE FUNCTION testComplexNumbers() RETURNS jsonb
-LANGUAGE plpythonu
+LANGUAGE plpython3u
TRANSFORM FOR TYPE jsonb
AS $$
x = 1 + 2j
-- range -> jsonb
CREATE FUNCTION testRange() RETURNS jsonb
-LANGUAGE plpythonu
+LANGUAGE plpython3u
TRANSFORM FOR TYPE jsonb
AS $$
x = range(3)
-- 0xff -> jsonb
CREATE FUNCTION testDecimal() RETURNS jsonb
-LANGUAGE plpythonu
+LANGUAGE plpython3u
TRANSFORM FOR TYPE jsonb
AS $$
x = 0xff
-- tuple -> jsonb
CREATE FUNCTION testTuple() RETURNS jsonb
-LANGUAGE plpythonu
+LANGUAGE plpython3u
TRANSFORM FOR TYPE jsonb
AS $$
x = (1, 'String', None)
-- interesting dict -> jsonb
CREATE FUNCTION test_dict1() RETURNS jsonb
-LANGUAGE plpythonu
+LANGUAGE plpython3u
TRANSFORM FOR TYPE jsonb
AS $$
x = {"a": 1, None: 2, 33: 3}
# Generated subdirectories
-/expected/python3/
/log/
/results/
-/sql/python3/
/tmp_check/
DATA = ltree_plpython3u--1.0.sql
REGRESS = ltree_plpython
-REGRESS_PLPYTHON3_MANGLE := $(REGRESS)
PG_CPPFLAGS = $(python_includespec) -DPLPYTHON_LIBNAME='"plpython$(python_majorversion)"'
endif
REGRESS_OPTS += --load-extension=ltree
-ifeq ($(python_majorversion),2)
-REGRESS_OPTS += --load-extension=plpythonu --load-extension=ltree_plpythonu
-endif
EXTRA_INSTALL += contrib/ltree
-
-include $(top_srcdir)/src/pl/plpython/regress-python3-mangle.mk
-CREATE EXTENSION ltree_plpython2u CASCADE;
-NOTICE: installing required extension "plpython2u"
+CREATE EXTENSION ltree_plpython3u CASCADE;
+NOTICE: installing required extension "plpython3u"
CREATE FUNCTION test1(val ltree) RETURNS int
-LANGUAGE plpythonu
+LANGUAGE plpython3u
TRANSFORM FOR TYPE ltree
AS $$
plpy.info(repr(val))
(1 row)
CREATE FUNCTION test1n(val ltree) RETURNS int
-LANGUAGE plpython2u
+LANGUAGE plpython3u
TRANSFORM FOR TYPE ltree
AS $$
plpy.info(repr(val))
(1 row)
CREATE FUNCTION test2() RETURNS ltree
-LANGUAGE plpythonu
+LANGUAGE plpython3u
TRANSFORM FOR TYPE ltree
AS $$
return ['foo', 'bar', 'baz']
-CREATE EXTENSION ltree_plpython2u CASCADE;
+CREATE EXTENSION ltree_plpython3u CASCADE;
CREATE FUNCTION test1(val ltree) RETURNS int
-LANGUAGE plpythonu
+LANGUAGE plpython3u
TRANSFORM FOR TYPE ltree
AS $$
plpy.info(repr(val))
CREATE FUNCTION test1n(val ltree) RETURNS int
-LANGUAGE plpython2u
+LANGUAGE plpython3u
TRANSFORM FOR TYPE ltree
AS $$
plpy.info(repr(val))
CREATE FUNCTION test2() RETURNS ltree
-LANGUAGE plpythonu
+LANGUAGE plpython3u
TRANSFORM FOR TYPE ltree
AS $$
return ['foo', 'bar', 'baz']
/spiexceptions.h
# Generated subdirectories
-/expected/python3/
/log/
/results/
-/sql/python3/
/tmp_check/
plpy_util.o
DATA = $(NAME)u.control $(NAME)u--1.0.sql
-ifeq ($(python_majorversion),2)
-DATA += plpythonu.control plpythonu--1.0.sql
-endif
# header files to install - it's not clear which of these might be needed
# so install them all.
SHLIB_LINK = $(python_libspec) $(python_additional_libs) $(filter -lintl,$(LIBS))
REGRESS_OPTS = --dbname=$(PL_TESTDB)
-# Only load plpythonu with Python 2. The test files themselves load
-# the versioned language plpython(2|3)u.
-ifeq ($(python_majorversion),2)
-REGRESS_OPTS += --load-extension=plpythonu
-endif
REGRESS = \
plpython_schema \
plpython_transaction \
plpython_drop
-REGRESS_PLPYTHON3_MANGLE := $(REGRESS)
-
include $(top_srcdir)/src/Makefile.shlib
all: all-lib
install-data: installdirs
$(INSTALL_DATA) $(addprefix $(srcdir)/, $(DATA)) '$(DESTDIR)$(datadir)/extension/'
$(INSTALL_DATA) $(addprefix $(srcdir)/, $(INCS)) '$(DESTDIR)$(includedir_server)'
- $(INSTALL_DATA) $(srcdir)/regress-python3-mangle.mk '$(DESTDIR)$(pgxsdir)/src/pl/plpython'
uninstall-data:
rm -f $(addprefix '$(DESTDIR)$(datadir)/extension'/, $(notdir $(DATA)))
.PHONY: install-data uninstall-data
-include $(srcdir)/regress-python3-mangle.mk
-
-
check: submake-pg-regress
$(pg_regress_check) $(REGRESS_OPTS) $(REGRESS)
-- Tests for procedures / CALL syntax
--
CREATE PROCEDURE test_proc1()
-LANGUAGE plpythonu
+LANGUAGE plpython3u
AS $$
pass
$$;
CALL test_proc1();
-- error: can't return non-None
CREATE PROCEDURE test_proc2()
-LANGUAGE plpythonu
+LANGUAGE plpython3u
AS $$
return 5
$$;
CONTEXT: PL/Python procedure "test_proc2"
CREATE TABLE test1 (a int);
CREATE PROCEDURE test_proc3(x int)
-LANGUAGE plpythonu
+LANGUAGE plpython3u
AS $$
plpy.execute("INSERT INTO test1 VALUES (%s)" % x)
$$;
-- output arguments
CREATE PROCEDURE test_proc5(INOUT a text)
-LANGUAGE plpythonu
+LANGUAGE plpython3u
AS $$
return [a + '+' + a]
$$;
(1 row)
CREATE PROCEDURE test_proc6(a int, INOUT b int, INOUT c int)
-LANGUAGE plpythonu
+LANGUAGE plpython3u
AS $$
return (b * a, c * a)
$$;
-- OUT parameters
CREATE PROCEDURE test_proc9(IN a int, OUT b int)
-LANGUAGE plpythonu
+LANGUAGE plpython3u
AS $$
plpy.notice("a: %s" % (a))
return (a * 2,)
CREATE FUNCTION multiout_simple(OUT i integer, OUT j integer) AS $$
return (1, 2)
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT multiout_simple();
multiout_simple
-----------------
CREATE FUNCTION multiout_simple_setof(n integer = 1, OUT integer, OUT integer) RETURNS SETOF record AS $$
return [(1, 2)] * n
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT multiout_simple_setof();
multiout_simple_setof
-----------------------
return type_record
elif typ == 'str':
return "('%s',%r)" % (first, second)
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM multiout_record_as('dict', 'foo', 1, 'f');
first | second
-------+--------
power = 2 ** i
length = plpy.execute("select length('%d')" % power)[0]['length']
yield power, length
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM multiout_setof(3);
power_of_2 | length
------------+--------
return [{'x': 4, 'y' :'four'},
{'x': 7, 'y' :'seven'},
{'x': 0, 'y' :'zero'}]
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM multiout_return_table();
x | y
---+-------
yield [[1], 'a']
yield [[1,2], 'b']
yield [[1,2,3], None]
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM multiout_array();
column1 | column2
---------+---------
CREATE FUNCTION singleout_composite(OUT type_record) AS $$
return {'first': 1, 'second': 2}
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION multiout_composite(OUT type_record) RETURNS SETOF type_record AS $$
return [{'first': 1, 'second': 2},
{'first': 3, 'second': 4 }]
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM singleout_composite();
first | second
-------+--------
-- composite OUT parameters in functions returning RECORD not supported yet
CREATE FUNCTION multiout_composite(INOUT n integer, OUT type_record) AS $$
return (n, (n * 2, n * 3))
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION multiout_table_type_setof(typ text, returnnull boolean, INOUT n integer, OUT table_record) RETURNS SETOF record AS $$
if returnnull:
d = None
d = "(%r,%r)" % (n * 2, n * 3)
for i in range(n):
yield (i, d)
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM multiout_composite(2);
n | column2
---+---------
CREATE FUNCTION changing_test(OUT n integer, OUT changing) RETURNS SETOF record AS $$
return [(1, {'i': 1, 'j': 2}),
(1, (3, 4))]
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM changing_test();
n | column2
---+---------
yield {'tab': [('first', 1), ('second', 2)],
'typ': [{'first': 'third', 'second': 3},
{'first': 'fourth', 'second': 4}]}
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM composite_types_table();
tab | typ
----------------------------+----------------------------
-- check what happens if the output record descriptor changes
CREATE FUNCTION return_record(t text) RETURNS record AS $$
return {'t': t, 'val': 10}
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM return_record('abc') AS r(t text, val integer);
t | val
-----+-----
CREATE FUNCTION return_record_2(t text) RETURNS record AS $$
return {'v1':1,'v2':2,t:3}
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM return_record_2('v3') AS (v3 int, v2 int, v1 int);
v3 | v2 | v1
----+----+----
-- multi-dimensional array of composite types.
CREATE FUNCTION composite_type_as_list() RETURNS type_record[] AS $$
return [[('first', 1), ('second', 1)], [('first', 2), ('second', 2)], [('first', 3), ('second', 3)]];
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM composite_type_as_list();
composite_type_as_list
------------------------------------------------------------------------------------
-- on the issue.
CREATE FUNCTION composite_type_as_list_broken() RETURNS type_record[] AS $$
return [['first', 1]];
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM composite_type_as_list_broken();
ERROR: malformed record literal: "first"
DETAIL: Missing left parenthesis.
-DO $$ plpy.notice("This is plpythonu.") $$ LANGUAGE plpythonu;
-NOTICE: This is plpythonu.
-DO $$ plpy.notice("This is plpython2u.") $$ LANGUAGE plpython2u;
-NOTICE: This is plpython2u.
-DO $$ raise Exception("error test") $$ LANGUAGE plpythonu;
+DO $$ plpy.notice("This is plpython3u.") $$ LANGUAGE plpython3u;
+NOTICE: This is plpython3u.
+DO $$ raise Exception("error test") $$ LANGUAGE plpython3u;
ERROR: Exception: error test
CONTEXT: Traceback (most recent call last):
PL/Python anonymous code block, line 1, in <module>
-- For paranoia's sake, don't leave an untrusted language sitting around
--
SET client_min_messages = WARNING;
-DROP EXTENSION plpythonu CASCADE;
-DROP EXTENSION IF EXISTS plpython2u CASCADE;
+DROP EXTENSION plpython3u CASCADE;
plpy.notice('notice', detail='some detail')
plpy.warning('warning', detail='some detail')
plpy.error('stop on error', detail='some detail', hint='some hint')
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT elog_test();
INFO: info
DETAIL: some detail
PL/Python function "elog_test", line 18, in <module>
plpy.error('stop on error', detail='some detail', hint='some hint')
PL/Python function "elog_test"
-DO $$ plpy.info('other types', detail=(10, 20)) $$ LANGUAGE plpythonu;
+DO $$ plpy.info('other types', detail=(10, 20)) $$ LANGUAGE plpython3u;
INFO: other types
DETAIL: (10, 20)
DO $$
import time;
from datetime import date
plpy.info('other types', detail=date(2016, 2, 26))
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
INFO: other types
DETAIL: 2016-02-26
DO $$
basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
plpy.info('other types', detail=basket)
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
INFO: other types
DETAIL: ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
-- should fail
-DO $$ plpy.info('wrong sqlstate', sqlstate='54444A') $$ LANGUAGE plpythonu;
+DO $$ plpy.info('wrong sqlstate', sqlstate='54444A') $$ LANGUAGE plpython3u;
ERROR: ValueError: invalid SQLSTATE code
CONTEXT: Traceback (most recent call last):
PL/Python anonymous code block, line 1, in <module>
plpy.info('wrong sqlstate', sqlstate='54444A')
PL/Python anonymous code block
-DO $$ plpy.info('unsupported argument', blabla='fooboo') $$ LANGUAGE plpythonu;
+DO $$ plpy.info('unsupported argument', blabla='fooboo') $$ LANGUAGE plpython3u;
ERROR: TypeError: 'blabla' is an invalid keyword argument for this function
CONTEXT: Traceback (most recent call last):
PL/Python anonymous code block, line 1, in <module>
plpy.info('unsupported argument', blabla='fooboo')
PL/Python anonymous code block
-DO $$ plpy.info('first message', message='second message') $$ LANGUAGE plpythonu;
+DO $$ plpy.info('first message', message='second message') $$ LANGUAGE plpython3u;
ERROR: TypeError: argument 'message' given by name and position
CONTEXT: Traceback (most recent call last):
PL/Python anonymous code block, line 1, in <module>
plpy.info('first message', message='second message')
PL/Python anonymous code block
-DO $$ plpy.info('first message', 'second message', message='third message') $$ LANGUAGE plpythonu;
+DO $$ plpy.info('first message', 'second message', message='third message') $$ LANGUAGE plpython3u;
ERROR: TypeError: argument 'message' given by name and position
CONTEXT: Traceback (most recent call last):
PL/Python anonymous code block, line 1, in <module>
}
# ignore None values
plpy.error(**dict((k, v) for k, v in iter(kwargs.items()) if v))
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT raise_exception('hello', 'world');
ERROR: plpy.Error: hello
DETAIL: world
$$;
NOTICE: handled exception
DETAIL: message:(plpy.Error: message text), detail:(detail text), hint: (hint text), sqlstate: (XX555), schema_name:(schema text), table_name:(table text), column_name:(column text), datatype_name:(datatype text), constraint_name:(constraint text)
--- The displayed context is different between Python2 and Python3,
--- but that's not important for this test.
-\set SHOW_CONTEXT never
DO $$
try:
plpy.execute("select raise_exception(_message => 'my message', _sqlstate => 'XX987', _hint => 'some hint', _table_name => 'users_tab', _datatype_name => 'user_type')")
except Exception as e:
plpy.info(e.spidata)
raise e
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
INFO: (119577128, None, 'some hint', None, 0, None, 'users_tab', None, 'user_type', None)
ERROR: plpy.SPIError: plpy.Error: my message
HINT: some hint
+CONTEXT: Traceback (most recent call last):
+ PL/Python anonymous code block, line 6, in <module>
+ raise e
+ PL/Python anonymous code block, line 3, in __plpython_inline_block
+ plpy.execute("select raise_exception(_message => 'my message', _sqlstate => 'XX987', _hint => 'some hint', _table_name => 'users_tab', _datatype_name => 'user_type')")
+PL/Python anonymous code block
DO $$
try:
plpy.error(message = 'my message', sqlstate = 'XX987', hint = 'some hint', table_name = 'users_tab', datatype_name = 'user_type')
except Exception as e:
plpy.info('sqlstate: %s, hint: %s, table_name: %s, datatype_name: %s' % (e.sqlstate, e.hint, e.table_name, e.datatype_name))
raise e
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
INFO: sqlstate: XX987, hint: some hint, table_name: users_tab, datatype_name: user_type
ERROR: plpy.Error: my message
HINT: some hint
+CONTEXT: Traceback (most recent call last):
+ PL/Python anonymous code block, line 6, in <module>
+ raise e
+ PL/Python anonymous code block, line 3, in __plpython_inline_block
+ plpy.error(message = 'my message', sqlstate = 'XX987', hint = 'some hint', table_name = 'users_tab', datatype_name = 'user_type')
+PL/Python anonymous code block
CREATE FUNCTION python_syntax_error() RETURNS text
AS
'.syntaxerror'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
ERROR: could not compile PL/Python function "python_syntax_error"
DETAIL: SyntaxError: invalid syntax (<string>, line 2)
/* With check_function_bodies = false the function should get defined
CREATE FUNCTION python_syntax_error() RETURNS text
AS
'.syntaxerror'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
SELECT python_syntax_error();
ERROR: could not compile PL/Python function "python_syntax_error"
DETAIL: SyntaxError: invalid syntax (<string>, line 2)
CREATE FUNCTION sql_syntax_error() RETURNS text
AS
'plpy.execute("syntax error")'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
SELECT sql_syntax_error();
ERROR: spiexceptions.SyntaxError: syntax error at or near "syntax"
LINE 1: syntax error
CREATE FUNCTION exception_index_invalid(text) RETURNS text
AS
'return args[1]'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
SELECT exception_index_invalid('test');
ERROR: IndexError: list index out of range
CONTEXT: Traceback (most recent call last):
AS
'rv = plpy.execute("SELECT test5(''foo'')")
return rv[0]'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
SELECT exception_index_invalid_nested();
ERROR: spiexceptions.UndefinedFunction: function test5(unknown) does not exist
LINE 1: SELECT test5('foo')
return rv[0]["fname"]
return None
'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
SELECT invalid_type_uncaught('rick');
ERROR: spiexceptions.UndefinedObject: type "test" does not exist
CONTEXT: Traceback (most recent call last):
return rv[0]["fname"]
return None
'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
SELECT invalid_type_caught('rick');
NOTICE: type "test" does not exist
invalid_type_caught
return rv[0]["fname"]
return None
'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
SELECT invalid_type_reraised('rick');
ERROR: plpy.Error: type "test" does not exist
CONTEXT: Traceback (most recent call last):
return rv[0]["fname"]
return None
'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
SELECT valid_type('rick');
valid_type
------------
fun3()
return "not reached"
'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
SELECT nested_error();
ERROR: plpy.Error: boom
CONTEXT: Traceback (most recent call last):
fun3()
return "not reached"
'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
SELECT nested_error_raise();
ERROR: plpy.Error: boom
CONTEXT: Traceback (most recent call last):
fun3()
return "you''ve been warned"
'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
SELECT nested_warning();
WARNING: boom
nested_warning
CREATE FUNCTION toplevel_attribute_error() RETURNS void AS
$$
plpy.nonexistent
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT toplevel_attribute_error();
-ERROR: AttributeError: 'module' object has no attribute 'nonexistent'
+ERROR: AttributeError: module 'plpy' has no attribute 'nonexistent'
CONTEXT: Traceback (most recent call last):
PL/Python function "toplevel_attribute_error", line 2, in <module>
plpy.nonexistent
plpy.execute("select sql_error()")
first()
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE OR REPLACE FUNCTION sql_error() RETURNS void AS $$
begin
select 1/0;
$$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION sql_from_python_error() RETURNS void AS $$
plpy.execute("select sql_error()")
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT python_traceback();
ERROR: spiexceptions.DivisionByZero: division by zero
CONTEXT: Traceback (most recent call last):
plpy.notice("Violated the NOT NULL constraint, sqlstate %s" % e.sqlstate)
except spiexceptions.UniqueViolation as e:
plpy.notice("Violated the UNIQUE constraint, sqlstate %s" % e.sqlstate)
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT specific_exception(2);
specific_exception
--------------------
CREATE FUNCTION python_unique_violation() RETURNS void AS $$
plpy.execute("insert into specific values (1)")
plpy.execute("insert into specific values (1)")
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION catch_python_unique_violation() RETURNS text AS $$
begin
begin
plpy.execute("savepoint save")
plpy.execute("create table foo(x integer)")
plpy.execute("rollback to save")
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT manual_subxact();
ERROR: plpy.SPIError: SPI_execute failed: SPI_ERROR_TRANSACTION
CONTEXT: Traceback (most recent call last):
plpy.execute(save)
plpy.execute("create table foo(x integer)")
plpy.execute(rollback)
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT manual_subxact_prepared();
ERROR: plpy.SPIError: SPI_execute_plan failed: SPI_ERROR_TRANSACTION
CONTEXT: Traceback (most recent call last):
*/
CREATE FUNCTION plpy_raise_spiexception() RETURNS void AS $$
raise plpy.spiexceptions.DivisionByZero()
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
DO $$
BEGIN
SELECT plpy_raise_spiexception();
exc = plpy.spiexceptions.DivisionByZero()
exc.sqlstate = 'SILLY'
raise exc
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
DO $$
BEGIN
SELECT plpy_raise_spiexception_override();
/* test the context stack trace for nested execution levels
*/
CREATE FUNCTION notice_innerfunc() RETURNS int AS $$
-plpy.execute("DO LANGUAGE plpythonu $x$ plpy.notice('inside DO') $x$")
+plpy.execute("DO LANGUAGE plpython3u $x$ plpy.notice('inside DO') $x$")
return 1
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION notice_outerfunc() RETURNS int AS $$
plpy.execute("SELECT notice_innerfunc()")
return 1
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
\set SHOW_CONTEXT always
SELECT notice_outerfunc();
NOTICE: inside DO
CONTEXT: PL/Python anonymous code block
-SQL statement "DO LANGUAGE plpythonu $x$ plpy.notice('inside DO') $x$"
+SQL statement "DO LANGUAGE plpython3u $x$ plpy.notice('inside DO') $x$"
PL/Python function "notice_innerfunc"
SQL statement "SELECT notice_innerfunc()"
PL/Python function "notice_outerfunc"
+++ /dev/null
--- test error handling, i forgot to restore Warn_restart in
--- the trigger handler once. the errors and subsequent core dump were
--- interesting.
-/* Flat out Python syntax error
- */
-CREATE FUNCTION python_syntax_error() RETURNS text
- AS
-'.syntaxerror'
- LANGUAGE plpython3u;
-ERROR: could not compile PL/Python function "python_syntax_error"
-DETAIL: SyntaxError: invalid syntax (<string>, line 2)
-/* With check_function_bodies = false the function should get defined
- * and the error reported when called
- */
-SET check_function_bodies = false;
-CREATE FUNCTION python_syntax_error() RETURNS text
- AS
-'.syntaxerror'
- LANGUAGE plpython3u;
-SELECT python_syntax_error();
-ERROR: could not compile PL/Python function "python_syntax_error"
-DETAIL: SyntaxError: invalid syntax (<string>, line 2)
-/* Run the function twice to check if the hashtable entry gets cleaned up */
-SELECT python_syntax_error();
-ERROR: could not compile PL/Python function "python_syntax_error"
-DETAIL: SyntaxError: invalid syntax (<string>, line 2)
-RESET check_function_bodies;
-/* Flat out syntax error
- */
-CREATE FUNCTION sql_syntax_error() RETURNS text
- AS
-'plpy.execute("syntax error")'
- LANGUAGE plpython3u;
-SELECT sql_syntax_error();
-ERROR: spiexceptions.SyntaxError: syntax error at or near "syntax"
-LINE 1: syntax error
- ^
-QUERY: syntax error
-CONTEXT: Traceback (most recent call last):
- PL/Python function "sql_syntax_error", line 1, in <module>
- plpy.execute("syntax error")
-PL/Python function "sql_syntax_error"
-/* check the handling of uncaught python exceptions
- */
-CREATE FUNCTION exception_index_invalid(text) RETURNS text
- AS
-'return args[1]'
- LANGUAGE plpython3u;
-SELECT exception_index_invalid('test');
-ERROR: IndexError: list index out of range
-CONTEXT: Traceback (most recent call last):
- PL/Python function "exception_index_invalid", line 1, in <module>
- return args[1]
-PL/Python function "exception_index_invalid"
-/* check handling of nested exceptions
- */
-CREATE FUNCTION exception_index_invalid_nested() RETURNS text
- AS
-'rv = plpy.execute("SELECT test5(''foo'')")
-return rv[0]'
- LANGUAGE plpython3u;
-SELECT exception_index_invalid_nested();
-ERROR: spiexceptions.UndefinedFunction: function test5(unknown) does not exist
-LINE 1: SELECT test5('foo')
- ^
-HINT: No function matches the given name and argument types. You might need to add explicit type casts.
-QUERY: SELECT test5('foo')
-CONTEXT: Traceback (most recent call last):
- PL/Python function "exception_index_invalid_nested", line 1, in <module>
- rv = plpy.execute("SELECT test5('foo')")
-PL/Python function "exception_index_invalid_nested"
-/* a typo
- */
-CREATE FUNCTION invalid_type_uncaught(a text) RETURNS text
- AS
-'if "plan" not in SD:
- q = "SELECT fname FROM users WHERE lname = $1"
- SD["plan"] = plpy.prepare(q, [ "test" ])
-rv = plpy.execute(SD["plan"], [ a ])
-if len(rv):
- return rv[0]["fname"]
-return None
-'
- LANGUAGE plpython3u;
-SELECT invalid_type_uncaught('rick');
-ERROR: spiexceptions.UndefinedObject: type "test" does not exist
-CONTEXT: Traceback (most recent call last):
- PL/Python function "invalid_type_uncaught", line 3, in <module>
- SD["plan"] = plpy.prepare(q, [ "test" ])
-PL/Python function "invalid_type_uncaught"
-/* for what it's worth catch the exception generated by
- * the typo, and return None
- */
-CREATE FUNCTION invalid_type_caught(a text) RETURNS text
- AS
-'if "plan" not in SD:
- q = "SELECT fname FROM users WHERE lname = $1"
- try:
- SD["plan"] = plpy.prepare(q, [ "test" ])
- except plpy.SPIError as ex:
- plpy.notice(str(ex))
- return None
-rv = plpy.execute(SD["plan"], [ a ])
-if len(rv):
- return rv[0]["fname"]
-return None
-'
- LANGUAGE plpython3u;
-SELECT invalid_type_caught('rick');
-NOTICE: type "test" does not exist
- invalid_type_caught
----------------------
-
-(1 row)
-
-/* for what it's worth catch the exception generated by
- * the typo, and reraise it as a plain error
- */
-CREATE FUNCTION invalid_type_reraised(a text) RETURNS text
- AS
-'if "plan" not in SD:
- q = "SELECT fname FROM users WHERE lname = $1"
- try:
- SD["plan"] = plpy.prepare(q, [ "test" ])
- except plpy.SPIError as ex:
- plpy.error(str(ex))
-rv = plpy.execute(SD["plan"], [ a ])
-if len(rv):
- return rv[0]["fname"]
-return None
-'
- LANGUAGE plpython3u;
-SELECT invalid_type_reraised('rick');
-ERROR: plpy.Error: type "test" does not exist
-CONTEXT: Traceback (most recent call last):
- PL/Python function "invalid_type_reraised", line 6, in <module>
- plpy.error(str(ex))
-PL/Python function "invalid_type_reraised"
-/* no typo no messing about
- */
-CREATE FUNCTION valid_type(a text) RETURNS text
- AS
-'if "plan" not in SD:
- SD["plan"] = plpy.prepare("SELECT fname FROM users WHERE lname = $1", [ "text" ])
-rv = plpy.execute(SD["plan"], [ a ])
-if len(rv):
- return rv[0]["fname"]
-return None
-'
- LANGUAGE plpython3u;
-SELECT valid_type('rick');
- valid_type
-------------
-
-(1 row)
-
-/* error in nested functions to get a traceback
-*/
-CREATE FUNCTION nested_error() RETURNS text
- AS
-'def fun1():
- plpy.error("boom")
-
-def fun2():
- fun1()
-
-def fun3():
- fun2()
-
-fun3()
-return "not reached"
-'
- LANGUAGE plpython3u;
-SELECT nested_error();
-ERROR: plpy.Error: boom
-CONTEXT: Traceback (most recent call last):
- PL/Python function "nested_error", line 10, in <module>
- fun3()
- PL/Python function "nested_error", line 8, in fun3
- fun2()
- PL/Python function "nested_error", line 5, in fun2
- fun1()
- PL/Python function "nested_error", line 2, in fun1
- plpy.error("boom")
-PL/Python function "nested_error"
-/* raising plpy.Error is just like calling plpy.error
-*/
-CREATE FUNCTION nested_error_raise() RETURNS text
- AS
-'def fun1():
- raise plpy.Error("boom")
-
-def fun2():
- fun1()
-
-def fun3():
- fun2()
-
-fun3()
-return "not reached"
-'
- LANGUAGE plpython3u;
-SELECT nested_error_raise();
-ERROR: plpy.Error: boom
-CONTEXT: Traceback (most recent call last):
- PL/Python function "nested_error_raise", line 10, in <module>
- fun3()
- PL/Python function "nested_error_raise", line 8, in fun3
- fun2()
- PL/Python function "nested_error_raise", line 5, in fun2
- fun1()
- PL/Python function "nested_error_raise", line 2, in fun1
- raise plpy.Error("boom")
-PL/Python function "nested_error_raise"
-/* using plpy.warning should not produce a traceback
-*/
-CREATE FUNCTION nested_warning() RETURNS text
- AS
-'def fun1():
- plpy.warning("boom")
-
-def fun2():
- fun1()
-
-def fun3():
- fun2()
-
-fun3()
-return "you''ve been warned"
-'
- LANGUAGE plpython3u;
-SELECT nested_warning();
-WARNING: boom
- nested_warning
---------------------
- you've been warned
-(1 row)
-
-/* AttributeError at toplevel used to give segfaults with the traceback
-*/
-CREATE FUNCTION toplevel_attribute_error() RETURNS void AS
-$$
-plpy.nonexistent
-$$ LANGUAGE plpython3u;
-SELECT toplevel_attribute_error();
-ERROR: AttributeError: module 'plpy' has no attribute 'nonexistent'
-CONTEXT: Traceback (most recent call last):
- PL/Python function "toplevel_attribute_error", line 2, in <module>
- plpy.nonexistent
-PL/Python function "toplevel_attribute_error"
-/* Calling PL/Python functions from SQL and vice versa should not lose context.
- */
-CREATE OR REPLACE FUNCTION python_traceback() RETURNS void AS $$
-def first():
- second()
-
-def second():
- third()
-
-def third():
- plpy.execute("select sql_error()")
-
-first()
-$$ LANGUAGE plpython3u;
-CREATE OR REPLACE FUNCTION sql_error() RETURNS void AS $$
-begin
- select 1/0;
-end
-$$ LANGUAGE plpgsql;
-CREATE OR REPLACE FUNCTION python_from_sql_error() RETURNS void AS $$
-begin
- select python_traceback();
-end
-$$ LANGUAGE plpgsql;
-CREATE OR REPLACE FUNCTION sql_from_python_error() RETURNS void AS $$
-plpy.execute("select sql_error()")
-$$ LANGUAGE plpython3u;
-SELECT python_traceback();
-ERROR: spiexceptions.DivisionByZero: division by zero
-CONTEXT: Traceback (most recent call last):
- PL/Python function "python_traceback", line 11, in <module>
- first()
- PL/Python function "python_traceback", line 3, in first
- second()
- PL/Python function "python_traceback", line 6, in second
- third()
- PL/Python function "python_traceback", line 9, in third
- plpy.execute("select sql_error()")
-PL/Python function "python_traceback"
-SELECT sql_error();
-ERROR: division by zero
-CONTEXT: SQL statement "select 1/0"
-PL/pgSQL function sql_error() line 3 at SQL statement
-SELECT python_from_sql_error();
-ERROR: spiexceptions.DivisionByZero: division by zero
-CONTEXT: Traceback (most recent call last):
- PL/Python function "python_traceback", line 11, in <module>
- first()
- PL/Python function "python_traceback", line 3, in first
- second()
- PL/Python function "python_traceback", line 6, in second
- third()
- PL/Python function "python_traceback", line 9, in third
- plpy.execute("select sql_error()")
-PL/Python function "python_traceback"
-SQL statement "select python_traceback()"
-PL/pgSQL function python_from_sql_error() line 3 at SQL statement
-SELECT sql_from_python_error();
-ERROR: spiexceptions.DivisionByZero: division by zero
-CONTEXT: Traceback (most recent call last):
- PL/Python function "sql_from_python_error", line 2, in <module>
- plpy.execute("select sql_error()")
-PL/Python function "sql_from_python_error"
-/* check catching specific types of exceptions
- */
-CREATE TABLE specific (
- i integer PRIMARY KEY
-);
-CREATE FUNCTION specific_exception(i integer) RETURNS void AS
-$$
-from plpy import spiexceptions
-try:
- plpy.execute("insert into specific values (%s)" % (i or "NULL"));
-except spiexceptions.NotNullViolation as e:
- plpy.notice("Violated the NOT NULL constraint, sqlstate %s" % e.sqlstate)
-except spiexceptions.UniqueViolation as e:
- plpy.notice("Violated the UNIQUE constraint, sqlstate %s" % e.sqlstate)
-$$ LANGUAGE plpython3u;
-SELECT specific_exception(2);
- specific_exception
---------------------
-
-(1 row)
-
-SELECT specific_exception(NULL);
-NOTICE: Violated the NOT NULL constraint, sqlstate 23502
- specific_exception
---------------------
-
-(1 row)
-
-SELECT specific_exception(2);
-NOTICE: Violated the UNIQUE constraint, sqlstate 23505
- specific_exception
---------------------
-
-(1 row)
-
-/* SPI errors in PL/Python functions should preserve the SQLSTATE value
- */
-CREATE FUNCTION python_unique_violation() RETURNS void AS $$
-plpy.execute("insert into specific values (1)")
-plpy.execute("insert into specific values (1)")
-$$ LANGUAGE plpython3u;
-CREATE FUNCTION catch_python_unique_violation() RETURNS text AS $$
-begin
- begin
- perform python_unique_violation();
- exception when unique_violation then
- return 'ok';
- end;
- return 'not reached';
-end;
-$$ language plpgsql;
-SELECT catch_python_unique_violation();
- catch_python_unique_violation
--------------------------------
- ok
-(1 row)
-
-/* manually starting subtransactions - a bad idea
- */
-CREATE FUNCTION manual_subxact() RETURNS void AS $$
-plpy.execute("savepoint save")
-plpy.execute("create table foo(x integer)")
-plpy.execute("rollback to save")
-$$ LANGUAGE plpython3u;
-SELECT manual_subxact();
-ERROR: plpy.SPIError: SPI_execute failed: SPI_ERROR_TRANSACTION
-CONTEXT: Traceback (most recent call last):
- PL/Python function "manual_subxact", line 2, in <module>
- plpy.execute("savepoint save")
-PL/Python function "manual_subxact"
-/* same for prepared plans
- */
-CREATE FUNCTION manual_subxact_prepared() RETURNS void AS $$
-save = plpy.prepare("savepoint save")
-rollback = plpy.prepare("rollback to save")
-plpy.execute(save)
-plpy.execute("create table foo(x integer)")
-plpy.execute(rollback)
-$$ LANGUAGE plpython3u;
-SELECT manual_subxact_prepared();
-ERROR: plpy.SPIError: SPI_execute_plan failed: SPI_ERROR_TRANSACTION
-CONTEXT: Traceback (most recent call last):
- PL/Python function "manual_subxact_prepared", line 4, in <module>
- plpy.execute(save)
-PL/Python function "manual_subxact_prepared"
-/* raising plpy.spiexception.* from python code should preserve sqlstate
- */
-CREATE FUNCTION plpy_raise_spiexception() RETURNS void AS $$
-raise plpy.spiexceptions.DivisionByZero()
-$$ LANGUAGE plpython3u;
-DO $$
-BEGIN
- SELECT plpy_raise_spiexception();
-EXCEPTION WHEN division_by_zero THEN
- -- NOOP
-END
-$$ LANGUAGE plpgsql;
-/* setting a custom sqlstate should be handled
- */
-CREATE FUNCTION plpy_raise_spiexception_override() RETURNS void AS $$
-exc = plpy.spiexceptions.DivisionByZero()
-exc.sqlstate = 'SILLY'
-raise exc
-$$ LANGUAGE plpython3u;
-DO $$
-BEGIN
- SELECT plpy_raise_spiexception_override();
-EXCEPTION WHEN SQLSTATE 'SILLY' THEN
- -- NOOP
-END
-$$ LANGUAGE plpgsql;
-/* test the context stack trace for nested execution levels
- */
-CREATE FUNCTION notice_innerfunc() RETURNS int AS $$
-plpy.execute("DO LANGUAGE plpythonu $x$ plpy.notice('inside DO') $x$")
-return 1
-$$ LANGUAGE plpythonu;
-CREATE FUNCTION notice_outerfunc() RETURNS int AS $$
-plpy.execute("SELECT notice_innerfunc()")
-return 1
-$$ LANGUAGE plpythonu;
-\set SHOW_CONTEXT always
-SELECT notice_outerfunc();
-NOTICE: inside DO
-CONTEXT: PL/Python anonymous code block
-SQL statement "DO LANGUAGE plpythonu $x$ plpy.notice('inside DO') $x$"
-PL/Python function "notice_innerfunc"
-SQL statement "SELECT notice_innerfunc()"
-PL/Python function "notice_outerfunc"
- notice_outerfunc
-------------------
- 1
-(1 row)
-
if "global_test" not in GD:
GD["global_test"] = "set by global_test_one"
return "SD: " + SD["global_test"] + ", GD: " + GD["global_test"]'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
CREATE FUNCTION global_test_two() returns text
AS
'if "global_test" not in SD:
if "global_test" not in GD:
GD["global_test"] = "set by global_test_two"
return "SD: " + SD["global_test"] + ", GD: " + GD["global_test"]'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
CREATE FUNCTION static_test() returns int4
AS
'if "call" in SD:
SD["call"] = 1
return SD["call"]
'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
SELECT static_test();
static_test
-------------
except ImportError:
return "failed as expected"
return "succeeded, that wasn''t supposed to happen"'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
CREATE FUNCTION import_succeed() returns text
AS
'try:
plpy.notice("import failed -- %s" % str(ex))
return "failed, that wasn''t supposed to happen"
return "succeeded, as expected"'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
CREATE FUNCTION import_test_one(p text) RETURNS text
AS
'try:
import sha
digest = sha.new(p)
return digest.hexdigest()'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
CREATE FUNCTION import_test_two(u users) RETURNS text
AS
'plain = u["fname"] + u["lname"]
import sha
digest = sha.new(plain);
return "sha hash of " + plain + " is " + digest.hexdigest()'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
-- import python modules
--
SELECT import_fail();
--
CREATE OR REPLACE FUNCTION newline_lf() RETURNS integer AS
E'x = 100\ny = 23\nreturn x + y\n'
-LANGUAGE plpythonu;
+LANGUAGE plpython3u;
CREATE OR REPLACE FUNCTION newline_cr() RETURNS integer AS
E'x = 100\ry = 23\rreturn x + y\r'
-LANGUAGE plpythonu;
+LANGUAGE plpython3u;
CREATE OR REPLACE FUNCTION newline_crlf() RETURNS integer AS
E'x = 100\r\ny = 23\r\nreturn x + y\r\n'
-LANGUAGE plpythonu;
+LANGUAGE plpython3u;
SELECT newline_lf();
newline_lf
------------
--
CREATE FUNCTION test_param_names0(integer, integer) RETURNS int AS $$
return args[0] + args[1]
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION test_param_names1(a0 integer, a1 text) RETURNS boolean AS $$
assert a0 == args[0]
assert a1 == args[1]
return True
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION test_param_names2(u users) RETURNS text AS $$
assert u == args[0]
if isinstance(u, dict):
else:
s = str(u)
return s
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
-- use deliberately wrong parameter names
CREATE FUNCTION test_param_names3(a0 integer) RETURNS boolean AS $$
try:
except NameError as e:
assert e.args[0].find("a1") > -1
return True
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT test_param_names0(2,7);
test_param_names0
-------------------
return plpy.quote_ident(t)
else:
raise plpy.Error("unrecognized quote type %s" % how)
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT quote(t, 'literal') FROM (VALUES
('abc'),
('a''bc'),
type_record.first = first
type_record.second = second
return type_record
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION test_type_record_as(typ text, first text, second integer, retnull boolean) RETURNS type_record AS $$
if retnull:
return None
return type_record
elif typ == 'str':
return "('%s',%r)" % (first, second)
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION test_in_out_params(first in text, second out text) AS $$
return first + '_in_to_out';
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION test_in_out_params_multi(first in text,
second out text, third out text) AS $$
return (first + '_record_in_to_out_1', first + '_record_in_to_out_2');
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION test_inout_params(first inout text) AS $$
return first + '_inout';
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
-- Test tuple returning functions
SELECT * FROM test_table_record_as('dict', null, null, false);
first | second
-- errors cases
CREATE FUNCTION test_type_record_error1() RETURNS type_record AS $$
return { 'first': 'first' }
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_record_error1();
ERROR: key "second" not found in mapping
HINT: To return null in a column, add the value None to the mapping with the key named after the column.
PL/Python function "test_type_record_error1"
CREATE FUNCTION test_type_record_error2() RETURNS type_record AS $$
return [ 'first' ]
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_record_error2();
ERROR: length of returned sequence did not match number of columns in row
CONTEXT: while creating return value
class type_record: pass
type_record.first = 'first'
return type_record
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_record_error3();
ERROR: attribute "second" does not exist in Python object
HINT: To return null in a column, let the returned object have an attribute named after column with value None.
PL/Python function "test_type_record_error3"
CREATE FUNCTION test_type_record_error4() RETURNS type_record AS $$
return 'foo'
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_record_error4();
ERROR: malformed record literal: "foo"
DETAIL: Missing left parenthesis.
--
CREATE FUNCTION test_setof_error() RETURNS SETOF text AS $$
return 37
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT test_setof_error();
ERROR: returned object cannot be iterated
DETAIL: PL/Python set-returning functions must return an iterable object.
CONTEXT: PL/Python function "test_setof_error"
CREATE FUNCTION test_setof_as_list(count integer, content text) RETURNS SETOF text AS $$
return [ content ]*count
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION test_setof_as_tuple(count integer, content text) RETURNS SETOF text AS $$
t = ()
for i in range(count):
t += ( content, )
return t
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION test_setof_as_iterator(count integer, content text) RETURNS SETOF text AS $$
class producer:
def __init__ (self, icount, icontent):
self.icount = icount
def __iter__ (self):
return self
- def next (self):
+ def __next__ (self):
if self.icount == 0:
raise StopIteration
self.icount -= 1
return self.icontent
return producer(count, content)
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION test_setof_spi_in_iterator() RETURNS SETOF text AS
$$
for s in ('Hello', 'Brave', 'New', 'World'):
yield s
plpy.execute('select 2')
$$
-LANGUAGE plpythonu;
+LANGUAGE plpython3u;
-- Test set returning functions
SELECT test_setof_as_list(0, 'list');
test_setof_as_list
while x <= lim:
yield x
x = x + 1
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT ugly(1, 5);
ugly
------
RETURNS SETOF users
AS $$
return plpy.execute("SELECT * FROM users ORDER BY username")
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT get_user_records();
get_user_records
----------------------
RETURNS TABLE(fname text, lname text, username text, userid int)
AS $$
return plpy.execute("SELECT * FROM users ORDER BY username")
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT get_user_records2();
get_user_records2
----------------------
'q = "SELECT nested_call_two(''%s'')" % a
r = plpy.execute(q)
return r[0]'
- LANGUAGE plpythonu ;
+ LANGUAGE plpython3u ;
CREATE FUNCTION nested_call_two(a text) RETURNS text
AS
'q = "SELECT nested_call_three(''%s'')" % a
r = plpy.execute(q)
return r[0]'
- LANGUAGE plpythonu ;
+ LANGUAGE plpython3u ;
CREATE FUNCTION nested_call_three(a text) RETURNS text
AS
'return a'
- LANGUAGE plpythonu ;
+ LANGUAGE plpython3u ;
-- some spi stuff
CREATE FUNCTION spi_prepared_plan_test_one(a text) RETURNS text
AS
plpy.error(str(ex))
return None
'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
CREATE FUNCTION spi_prepared_plan_test_two(a text) RETURNS text
AS
'if "myplan" not in SD:
plpy.error(str(ex))
return None
'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
CREATE FUNCTION spi_prepared_plan_test_nested(a text) RETURNS text
AS
'if "myplan" not in SD:
plpy.error(str(ex))
return None
'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
CREATE FUNCTION join_sequences(s sequences) RETURNS text
AS
'if not s["multipart"]:
seq = seq + r["sequence"]
return seq
'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
CREATE FUNCTION spi_recursive_sum(a int) RETURNS int
AS
'r = 0
r = plpy.execute("SELECT spi_recursive_sum(%d) as a" % (a-1))[0]["a"]
return a + r
'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
--
-- spi and nested calls
--
return result.nrows()
else:
return None
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT result_metadata_test($$SELECT 1 AS foo, '11'::text AS bar UNION SELECT 2, '22'$$);
INFO: True
INFO: ['foo', 'bar']
AS $$
result = plpy.execute(cmd)
return result.nrows()
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT result_nrows_test($$SELECT 1$$);
result_nrows_test
-------------------
AS $$
result = plpy.execute(cmd)
return len(result)
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT result_len_test($$SELECT 1$$);
result_len_test
-----------------
result[:2] = [{'c': 10}, {'c': 100}]
plpy.info([item['c'] for item in result[:]])
-# raises TypeError, but the message differs on Python 2.6, so silence it
+# raises TypeError, catch so further tests could be added
try:
plpy.info(result['foo'])
except TypeError:
else:
assert False, "TypeError not raised"
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT result_subscript_test();
INFO: 2
INFO: 4
plpy.info(result[:])
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT result_empty_test();
INFO: []
result_empty_test
plan = plpy.prepare(cmd)
result = plpy.execute(plan)
return str(result)
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT result_str_test($$SELECT 1 AS foo UNION SELECT 2$$);
result_str_test
------------------------------------------------------------
if row['lname'] == 'doe':
does += 1
return does
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION double_cursor_close() RETURNS int AS $$
res = plpy.cursor("select fname, lname from users")
res.close()
res.close()
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION cursor_fetch() RETURNS int AS $$
res = plpy.cursor("select fname, lname from users")
assert len(res.fetch(3)) == 3
pass
else:
assert False, "StopIteration not raised"
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION cursor_mix_next_and_fetch() RETURNS int AS $$
res = plpy.cursor("select fname, lname from users order by fname")
assert len(res.fetch(2)) == 2
assert item['fname'] == 'rick'
assert len(res.fetch(2)) == 1
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION fetch_after_close() RETURNS int AS $$
res = plpy.cursor("select fname, lname from users")
res.close()
pass
else:
assert False, "ValueError not raised"
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION next_after_close() RETURNS int AS $$
res = plpy.cursor("select fname, lname from users")
res.close()
pass
else:
assert False, "ValueError not raised"
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION cursor_fetch_next_empty() RETURNS int AS $$
res = plpy.cursor("select fname, lname from users where false")
assert len(res.fetch(1)) == 0
pass
else:
assert False, "StopIteration not raised"
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION cursor_plan() RETURNS SETOF text AS $$
plan = plpy.prepare(
"select fname, lname from users where fname like $1 || '%' order by fname",
yield row['fname']
for row in plan.cursor(["j"]):
yield row['fname']
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION cursor_plan_wrong_args() RETURNS SETOF text AS $$
plan = plpy.prepare("select fname, lname from users where fname like $1 || '%'",
["text"])
c = plpy.cursor(plan, ["a", "b"])
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE TYPE test_composite_type AS (
a1 int,
a2 varchar
plan = plpy.prepare("select $1 as c1", ["test_composite_type"])
res = plpy.execute(plan, [{"a1": 3, "a2": "label"}])
return res[0]["c1"]
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT simple_cursor_test();
simple_cursor_test
--------------------
plpy.execute("INSERT INTO subtransaction_tbl VALUES ('oops')")
elif what_error == "Python":
raise Exception("Python exception")
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT subtransaction_ctx_test();
subtransaction_ctx_test
-------------------------
raise
plpy.notice("Swallowed %s(%r)" % (e.__class__.__name__, e.args[0]))
return "ok"
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT subtransaction_nested_test();
ERROR: spiexceptions.SyntaxError: syntax error at or near "error"
LINE 1: error
plpy.execute("INSERT INTO subtransaction_tbl VALUES (2)")
plpy.execute("SELECT subtransaction_nested_test('t')")
return "ok"
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT subtransaction_deeply_nested_test();
NOTICE: Swallowed SyntaxError('syntax error at or near "error"')
subtransaction_deeply_nested_test
CREATE FUNCTION subtransaction_exit_without_enter() RETURNS void
AS $$
plpy.subtransaction().__exit__(None, None, None)
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION subtransaction_enter_without_exit() RETURNS void
AS $$
plpy.subtransaction().__enter__()
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION subtransaction_exit_twice() RETURNS void
AS $$
plpy.subtransaction().__enter__()
plpy.subtransaction().__exit__(None, None, None)
plpy.subtransaction().__exit__(None, None, None)
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION subtransaction_enter_twice() RETURNS void
AS $$
plpy.subtransaction().__enter__()
plpy.subtransaction().__enter__()
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION subtransaction_exit_same_subtransaction_twice() RETURNS void
AS $$
s = plpy.subtransaction()
s.__enter__()
s.__exit__(None, None, None)
s.__exit__(None, None, None)
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION subtransaction_enter_same_subtransaction_twice() RETURNS void
AS $$
s = plpy.subtransaction()
s.__enter__()
s.__enter__()
s.__exit__(None, None, None)
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
-- No warnings here, as the subtransaction gets indeed closed
CREATE FUNCTION subtransaction_enter_subtransaction_in_with() RETURNS void
AS $$
with plpy.subtransaction() as s:
s.__enter__()
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION subtransaction_exit_subtransaction_in_with() RETURNS void
AS $$
try:
s.__exit__(None, None, None)
except ValueError as e:
raise ValueError(e)
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT subtransaction_exit_without_enter();
ERROR: ValueError: this subtransaction has not been entered
CONTEXT: Traceback (most recent call last):
plpy.execute(p, ["wrong"])
except plpy.SPIError:
plpy.warning("Caught a SPI error")
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT subtransaction_mix_explicit_and_implicit();
WARNING: Caught a SPI error from an explicit subtransaction
WARNING: Caught a SPI error
s = plpy.subtransaction()
s.enter()
s.exit(None, None, None)
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT subtransaction_alternative_names();
subtransaction_alternative_names
----------------------------------
plpy.execute("INSERT INTO subtransaction_tbl VALUES ('a')")
except plpy.SPIError:
plpy.notice("caught")
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT try_catch_inside_subtransaction();
NOTICE: caught
try_catch_inside_subtransaction
plpy.execute("INSERT INTO subtransaction_tbl VALUES (1)")
except plpy.SPIError:
plpy.notice("caught")
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT pk_violation_inside_subtransaction();
NOTICE: caught
pk_violation_inside_subtransaction
cur.fetch(10)
fetched = cur.fetch(10);
return int(fetched[5]["i"])
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION cursor_aborted_subxact() RETURNS int AS $$
try:
with plpy.subtransaction():
fetched = cur.fetch(10)
return int(fetched[5]["i"])
return 0 # not reached
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION cursor_plan_aborted_subxact() RETURNS int AS $$
try:
with plpy.subtransaction():
fetched = cur.fetch(5)
return fetched[2]["i"]
return 0 # not reached
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION cursor_close_aborted_subxact() RETURNS boolean AS $$
try:
with plpy.subtransaction():
cur.close()
return True
return False # not reached
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT cursor_in_subxact();
cursor_in_subxact
-------------------
-- first some tests of basic functionality
-CREATE EXTENSION plpython2u;
+CREATE EXTENSION plpython3u;
-- really stupid function just to get the module loaded
-CREATE FUNCTION stupid() RETURNS text AS 'return "zarkon"' LANGUAGE plpythonu;
+CREATE FUNCTION stupid() RETURNS text AS 'return "zarkon"' LANGUAGE plpython3u;
select stupid();
stupid
--------
(1 row)
-- check 2/3 versioning
-CREATE FUNCTION stupidn() RETURNS text AS 'return "zarkon"' LANGUAGE plpython2u;
+CREATE FUNCTION stupidn() RETURNS text AS 'return "zarkon"' LANGUAGE plpython3u;
select stupidn();
stupidn
---------
out.append("%s: %s" % (key, u[key]))
words = a1 + " " + a2 + " => {" + ", ".join(out) + "}"
return words'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
select "Argument test #1"(users, fname, lname) from users where lname = 'doe' order by 1;
Argument test #1
-----------------------------------------------------------------------
contents = list(filter(lambda x: not x.startswith("__"), dir(plpy)))
contents.sort()
return contents
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
select module_contents();
module_contents
-----------------
plpy.notice('notice')
plpy.warning('warning')
plpy.error('error')
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT elog_test_basic();
INFO: info
INFO: 37
CREATE TABLE test1 (a int, b text);
CREATE PROCEDURE transaction_test1()
-LANGUAGE plpythonu
+LANGUAGE plpython3u
AS $$
for i in range(0, 10):
plpy.execute("INSERT INTO test1 (a) VALUES (%d)" % i)
TRUNCATE test1;
DO
-LANGUAGE plpythonu
+LANGUAGE plpython3u
$$
for i in range(0, 10):
plpy.execute("INSERT INTO test1 (a) VALUES (%d)" % i)
TRUNCATE test1;
-- not allowed in a function
CREATE FUNCTION transaction_test2() RETURNS int
-LANGUAGE plpythonu
+LANGUAGE plpython3u
AS $$
for i in range(0, 10):
plpy.execute("INSERT INTO test1 (a) VALUES (%d)" % i)
-- also not allowed if procedure is called from a function
CREATE FUNCTION transaction_test3() RETURNS int
-LANGUAGE plpythonu
+LANGUAGE plpython3u
AS $$
plpy.execute("CALL transaction_test1()")
return 1
-- DO block inside function
CREATE FUNCTION transaction_test4() RETURNS int
-LANGUAGE plpythonu
+LANGUAGE plpython3u
AS $$
-plpy.execute("DO LANGUAGE plpythonu $x$ plpy.commit() $x$")
+plpy.execute("DO LANGUAGE plpython3u $x$ plpy.commit() $x$")
return 1
$$;
SELECT transaction_test4();
ERROR: spiexceptions.InvalidTransactionTermination: spiexceptions.InvalidTransactionTermination: invalid transaction termination
CONTEXT: Traceback (most recent call last):
PL/Python function "transaction_test4", line 2, in <module>
- plpy.execute("DO LANGUAGE plpythonu $x$ plpy.commit() $x$")
+ plpy.execute("DO LANGUAGE plpython3u $x$ plpy.commit() $x$")
PL/Python function "transaction_test4"
-- commit inside subtransaction (prohibited)
-DO LANGUAGE plpythonu $$
+DO LANGUAGE plpython3u $$
s = plpy.subtransaction()
s.enter()
plpy.commit()
CREATE TABLE test2 (x int);
INSERT INTO test2 VALUES (0), (1), (2), (3), (4);
TRUNCATE test1;
-DO LANGUAGE plpythonu $$
+DO LANGUAGE plpython3u $$
for row in plpy.cursor("SELECT * FROM test2 ORDER BY x"):
plpy.execute("INSERT INTO test1 (a) VALUES (%s)" % row['x'])
plpy.commit()
-- error in cursor loop with commit
TRUNCATE test1;
-DO LANGUAGE plpythonu $$
+DO LANGUAGE plpython3u $$
for row in plpy.cursor("SELECT * FROM test2 ORDER BY x"):
plpy.execute("INSERT INTO test1 (a) VALUES (12/(%s-2))" % row['x'])
plpy.commit()
-- rollback inside cursor loop
TRUNCATE test1;
-DO LANGUAGE plpythonu $$
+DO LANGUAGE plpython3u $$
for row in plpy.cursor("SELECT * FROM test2 ORDER BY x"):
plpy.execute("INSERT INTO test1 (a) VALUES (%s)" % row['x'])
plpy.rollback()
-- first commit then rollback inside cursor loop
TRUNCATE test1;
-DO LANGUAGE plpythonu $$
+DO LANGUAGE plpython3u $$
for row in plpy.cursor("SELECT * FROM test2 ORDER BY x"):
plpy.execute("INSERT INTO test1 (a) VALUES (%s)" % row['x'])
if row['x'] % 2 == 0:
-- check handling of an error during COMMIT
CREATE TABLE testpk (id int PRIMARY KEY);
CREATE TABLE testfk(f1 int REFERENCES testpk DEFERRABLE INITIALLY DEFERRED);
-DO LANGUAGE plpythonu $$
+DO LANGUAGE plpython3u $$
# this insert will fail during commit:
plpy.execute("INSERT INTO testfk VALUES (0)")
plpy.commit()
----
(0 rows)
-DO LANGUAGE plpythonu $$
+DO LANGUAGE plpython3u $$
# this insert will fail during commit:
plpy.execute("INSERT INTO testfk VALUES (0)")
try:
TD["new"]["fname"] = TD["args"][0]
rv = "MODIFY"
return rv'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
CREATE FUNCTION users_update() returns trigger
AS
'if TD["event"] == "UPDATE":
if TD["old"]["fname"] != TD["new"]["fname"] and TD["old"]["fname"] == TD["args"][0]:
return "SKIP"
return None'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
CREATE FUNCTION users_delete() RETURNS trigger
AS
'if TD["old"]["fname"] == TD["args"][0]:
return "SKIP"
return None'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
CREATE TRIGGER users_insert_trig BEFORE INSERT ON users FOR EACH ROW
EXECUTE PROCEDURE users_insert ('willem');
CREATE TRIGGER users_update_trig BEFORE UPDATE ON users FOR EACH ROW
i int,
j int GENERATED ALWAYS AS (i * 2) STORED
);
-CREATE FUNCTION trigger_data() RETURNS trigger LANGUAGE plpythonu AS $$
+CREATE FUNCTION trigger_data() RETURNS trigger LANGUAGE plpython3u AS $$
if 'relid' in TD:
TD['relid'] = "bogus:12345"
CREATE FUNCTION stupid1() RETURNS trigger
AS $$
return 37
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE TRIGGER stupid_trigger1
BEFORE INSERT ON trigger_test
FOR EACH ROW EXECUTE PROCEDURE stupid1();
CREATE FUNCTION stupid2() RETURNS trigger
AS $$
return "MODIFY"
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE TRIGGER stupid_trigger2
BEFORE DELETE ON trigger_test
FOR EACH ROW EXECUTE PROCEDURE stupid2();
CREATE FUNCTION stupid3() RETURNS trigger
AS $$
return "foo"
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE TRIGGER stupid_trigger3
BEFORE UPDATE ON trigger_test
FOR EACH ROW EXECUTE PROCEDURE stupid3();
-- Unicode variant
CREATE FUNCTION stupid3u() RETURNS trigger
AS $$
- return u"foo"
-$$ LANGUAGE plpythonu;
+ return "foo"
+$$ LANGUAGE plpython3u;
CREATE TRIGGER stupid_trigger3
BEFORE UPDATE ON trigger_test
FOR EACH ROW EXECUTE PROCEDURE stupid3u();
AS $$
del TD["new"]
return "MODIFY";
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE TRIGGER stupid_trigger4
BEFORE UPDATE ON trigger_test
FOR EACH ROW EXECUTE PROCEDURE stupid4();
AS $$
TD["new"] = ['foo', 'bar']
return "MODIFY";
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE TRIGGER stupid_trigger5
BEFORE UPDATE ON trigger_test
FOR EACH ROW EXECUTE PROCEDURE stupid5();
AS $$
TD["new"] = {1: 'foo', 2: 'bar'}
return "MODIFY";
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE TRIGGER stupid_trigger6
BEFORE UPDATE ON trigger_test
FOR EACH ROW EXECUTE PROCEDURE stupid6();
AS $$
TD["new"] = {'v': 'foo', 'a': 'bar'}
return "MODIFY";
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE TRIGGER stupid_trigger7
BEFORE UPDATE ON trigger_test
FOR EACH ROW EXECUTE PROCEDURE stupid7();
-- Unicode variant
CREATE FUNCTION stupid7u() RETURNS trigger
AS $$
- TD["new"] = {u'v': 'foo', u'a': 'bar'}
+ TD["new"] = {'v': 'foo', 'a': 'bar'}
return "MODIFY"
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE TRIGGER stupid_trigger7
BEFORE UPDATE ON trigger_test
FOR EACH ROW EXECUTE PROCEDURE stupid7u();
AS $$
TD["new"]['v'] = None
return "MODIFY"
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE TRIGGER test_null_trigger
BEFORE UPDATE ON trigger_test
FOR EACH ROW EXECUTE PROCEDURE test_null();
CREATE FUNCTION set_modif_time() RETURNS trigger AS $$
TD['new']['modif_time'] = '2010-10-13 21:57:28.930486'
return 'MODIFY'
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE TABLE pb (a TEXT, modif_time TIMESTAMP(0) WITHOUT TIME ZONE);
CREATE TRIGGER set_modif_time BEFORE UPDATE ON pb
FOR EACH ROW EXECUTE PROCEDURE set_modif_time();
TD['new']['f1'] = (3, False)
TD['new']['f2'] = {'k': 7, 'l': 'yes', 'ignored': 10}
return 'MODIFY'
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE TRIGGER composite_trigger BEFORE INSERT ON composite_trigger_test
FOR EACH ROW EXECUTE PROCEDURE composite_trigger_f();
INSERT INTO composite_trigger_test VALUES (NULL, NULL);
CREATE TABLE composite_trigger_noop_test (f1 comp1, f2 comp2);
CREATE FUNCTION composite_trigger_noop_f() RETURNS trigger AS $$
return 'MODIFY'
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE TRIGGER composite_trigger_noop BEFORE INSERT ON composite_trigger_noop_test
FOR EACH ROW EXECUTE PROCEDURE composite_trigger_noop_f();
INSERT INTO composite_trigger_noop_test VALUES (NULL, NULL);
CREATE TABLE composite_trigger_nested_test(c comp3);
CREATE FUNCTION composite_trigger_nested_f() RETURNS trigger AS $$
return 'MODIFY'
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE TRIGGER composite_trigger_nested BEFORE INSERT ON composite_trigger_nested_test
FOR EACH ROW EXECUTE PROCEDURE composite_trigger_nested_f();
INSERT INTO composite_trigger_nested_test VALUES (NULL);
(3 rows)
-- check that using a function as a trigger over two tables works correctly
-CREATE FUNCTION trig1234() RETURNS trigger LANGUAGE plpythonu AS $$
+CREATE FUNCTION trig1234() RETURNS trigger LANGUAGE plpython3u AS $$
TD["new"]["data"] = '1234'
return 'MODIFY'
$$;
-- check that SQL run in trigger code can see transition tables
CREATE TABLE transition_table_test (id int, name text);
INSERT INTO transition_table_test VALUES (1, 'a');
-CREATE FUNCTION transition_table_test_f() RETURNS trigger LANGUAGE plpythonu AS
+CREATE FUNCTION transition_table_test_f() RETURNS trigger LANGUAGE plpython3u AS
$$
rv = plpy.execute("SELECT * FROM old_table")
assert(rv.nrows() == 1)
DROP FUNCTION transition_table_test_f();
-- dealing with generated columns
CREATE FUNCTION generated_test_func1() RETURNS trigger
-LANGUAGE plpythonu
+LANGUAGE plpython3u
AS $$
TD['new']['j'] = 5 # not allowed
return 'MODIFY'
CREATE FUNCTION test_type_conversion_bool(x bool) RETURNS bool AS $$
plpy.info(x, type(x))
return x
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_bool(true);
-INFO: (True, <type 'bool'>)
+INFO: (True, <class 'bool'>)
test_type_conversion_bool
---------------------------
t
(1 row)
SELECT * FROM test_type_conversion_bool(false);
-INFO: (False, <type 'bool'>)
+INFO: (False, <class 'bool'>)
test_type_conversion_bool
---------------------------
f
(1 row)
SELECT * FROM test_type_conversion_bool(null);
-INFO: (None, <type 'NoneType'>)
+INFO: (None, <class 'NoneType'>)
test_type_conversion_bool
---------------------------
ret = [0]
plpy.info(ret, not not ret)
return ret
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_bool_other(0);
INFO: (0, False)
test_type_conversion_bool_other
CREATE FUNCTION test_type_conversion_char(x char) RETURNS char AS $$
plpy.info(x, type(x))
return x
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_char('a');
-INFO: ('a', <type 'str'>)
+INFO: ('a', <class 'str'>)
test_type_conversion_char
---------------------------
a
(1 row)
SELECT * FROM test_type_conversion_char(null);
-INFO: (None, <type 'NoneType'>)
+INFO: (None, <class 'NoneType'>)
test_type_conversion_char
---------------------------
CREATE FUNCTION test_type_conversion_int2(x int2) RETURNS int2 AS $$
plpy.info(x, type(x))
return x
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_int2(100::int2);
-INFO: (100, <type 'int'>)
+INFO: (100, <class 'int'>)
test_type_conversion_int2
---------------------------
100
(1 row)
SELECT * FROM test_type_conversion_int2(-100::int2);
-INFO: (-100, <type 'int'>)
+INFO: (-100, <class 'int'>)
test_type_conversion_int2
---------------------------
-100
(1 row)
SELECT * FROM test_type_conversion_int2(null);
-INFO: (None, <type 'NoneType'>)
+INFO: (None, <class 'NoneType'>)
test_type_conversion_int2
---------------------------
CREATE FUNCTION test_type_conversion_int4(x int4) RETURNS int4 AS $$
plpy.info(x, type(x))
return x
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_int4(100);
-INFO: (100, <type 'int'>)
+INFO: (100, <class 'int'>)
test_type_conversion_int4
---------------------------
100
(1 row)
SELECT * FROM test_type_conversion_int4(-100);
-INFO: (-100, <type 'int'>)
+INFO: (-100, <class 'int'>)
test_type_conversion_int4
---------------------------
-100
(1 row)
SELECT * FROM test_type_conversion_int4(null);
-INFO: (None, <type 'NoneType'>)
+INFO: (None, <class 'NoneType'>)
test_type_conversion_int4
---------------------------
CREATE FUNCTION test_type_conversion_int8(x int8) RETURNS int8 AS $$
plpy.info(x, type(x))
return x
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_int8(100);
-INFO: (100L, <type 'long'>)
+INFO: (100, <class 'int'>)
test_type_conversion_int8
---------------------------
100
(1 row)
SELECT * FROM test_type_conversion_int8(-100);
-INFO: (-100L, <type 'long'>)
+INFO: (-100, <class 'int'>)
test_type_conversion_int8
---------------------------
-100
(1 row)
SELECT * FROM test_type_conversion_int8(5000000000);
-INFO: (5000000000L, <type 'long'>)
+INFO: (5000000000, <class 'int'>)
test_type_conversion_int8
---------------------------
5000000000
(1 row)
SELECT * FROM test_type_conversion_int8(null);
-INFO: (None, <type 'NoneType'>)
+INFO: (None, <class 'NoneType'>)
test_type_conversion_int8
---------------------------
# between decimal and cdecimal
plpy.info(str(x), x.__class__.__name__)
return x
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_numeric(100);
INFO: ('100', 'Decimal')
test_type_conversion_numeric
CREATE FUNCTION test_type_conversion_float4(x float4) RETURNS float4 AS $$
plpy.info(x, type(x))
return x
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_float4(100);
-INFO: (100.0, <type 'float'>)
+INFO: (100.0, <class 'float'>)
test_type_conversion_float4
-----------------------------
100
(1 row)
SELECT * FROM test_type_conversion_float4(-100);
-INFO: (-100.0, <type 'float'>)
+INFO: (-100.0, <class 'float'>)
test_type_conversion_float4
-----------------------------
-100
(1 row)
SELECT * FROM test_type_conversion_float4(5000.5);
-INFO: (5000.5, <type 'float'>)
+INFO: (5000.5, <class 'float'>)
test_type_conversion_float4
-----------------------------
5000.5
(1 row)
SELECT * FROM test_type_conversion_float4(null);
-INFO: (None, <type 'NoneType'>)
+INFO: (None, <class 'NoneType'>)
test_type_conversion_float4
-----------------------------
CREATE FUNCTION test_type_conversion_float8(x float8) RETURNS float8 AS $$
plpy.info(x, type(x))
return x
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_float8(100);
-INFO: (100.0, <type 'float'>)
+INFO: (100.0, <class 'float'>)
test_type_conversion_float8
-----------------------------
100
(1 row)
SELECT * FROM test_type_conversion_float8(-100);
-INFO: (-100.0, <type 'float'>)
+INFO: (-100.0, <class 'float'>)
test_type_conversion_float8
-----------------------------
-100
(1 row)
SELECT * FROM test_type_conversion_float8(5000000000.5);
-INFO: (5000000000.5, <type 'float'>)
+INFO: (5000000000.5, <class 'float'>)
test_type_conversion_float8
-----------------------------
5000000000.5
(1 row)
SELECT * FROM test_type_conversion_float8(null);
-INFO: (None, <type 'NoneType'>)
+INFO: (None, <class 'NoneType'>)
test_type_conversion_float8
-----------------------------
(1 row)
SELECT * FROM test_type_conversion_float8(100100100.654321);
-INFO: (100100100.654321, <type 'float'>)
+INFO: (100100100.654321, <class 'float'>)
test_type_conversion_float8
-----------------------------
100100100.654321
CREATE FUNCTION test_type_conversion_oid(x oid) RETURNS oid AS $$
plpy.info(x, type(x))
return x
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_oid(100);
-INFO: (100L, <type 'long'>)
+INFO: (100, <class 'int'>)
test_type_conversion_oid
--------------------------
100
(1 row)
SELECT * FROM test_type_conversion_oid(2147483649);
-INFO: (2147483649L, <type 'long'>)
+INFO: (2147483649, <class 'int'>)
test_type_conversion_oid
--------------------------
2147483649
(1 row)
SELECT * FROM test_type_conversion_oid(null);
-INFO: (None, <type 'NoneType'>)
+INFO: (None, <class 'NoneType'>)
test_type_conversion_oid
--------------------------
CREATE FUNCTION test_type_conversion_text(x text) RETURNS text AS $$
plpy.info(x, type(x))
return x
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_text('hello world');
-INFO: ('hello world', <type 'str'>)
+INFO: ('hello world', <class 'str'>)
test_type_conversion_text
---------------------------
hello world
(1 row)
SELECT * FROM test_type_conversion_text(null);
-INFO: (None, <type 'NoneType'>)
+INFO: (None, <class 'NoneType'>)
test_type_conversion_text
---------------------------
CREATE FUNCTION test_type_conversion_bytea(x bytea) RETURNS bytea AS $$
plpy.info(x, type(x))
return x
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_bytea('hello world');
-INFO: ('hello world', <type 'str'>)
+INFO: (b'hello world', <class 'bytes'>)
test_type_conversion_bytea
----------------------------
\x68656c6c6f20776f726c64
(1 row)
SELECT * FROM test_type_conversion_bytea(E'null\\000byte');
-INFO: ('null\x00byte', <type 'str'>)
+INFO: (b'null\x00byte', <class 'bytes'>)
test_type_conversion_bytea
----------------------------
\x6e756c6c0062797465
(1 row)
SELECT * FROM test_type_conversion_bytea(null);
-INFO: (None, <type 'NoneType'>)
+INFO: (None, <class 'NoneType'>)
test_type_conversion_bytea
----------------------------
CREATE FUNCTION test_type_marshal() RETURNS bytea AS $$
import marshal
return marshal.dumps('hello world')
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION test_type_unmarshal(x bytea) RETURNS text AS $$
import marshal
try:
return marshal.loads(x)
except ValueError as e:
return 'FAILED: ' + str(e)
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT test_type_unmarshal(x) FROM test_type_marshal() x;
test_type_unmarshal
---------------------
CREATE DOMAIN booltrue AS bool CHECK (VALUE IS TRUE OR VALUE IS NULL);
CREATE FUNCTION test_type_conversion_booltrue(x booltrue, y bool) RETURNS booltrue AS $$
return y
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_booltrue(true, true);
test_type_conversion_booltrue
-------------------------------
CREATE FUNCTION test_type_conversion_uint2(x uint2, y int) RETURNS uint2 AS $$
plpy.info(x, type(x))
return y
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_uint2(100::uint2, 50);
-INFO: (100, <type 'int'>)
+INFO: (100, <class 'int'>)
test_type_conversion_uint2
----------------------------
50
(1 row)
SELECT * FROM test_type_conversion_uint2(100::uint2, -50);
-INFO: (100, <type 'int'>)
+INFO: (100, <class 'int'>)
ERROR: value for domain uint2 violates check constraint "uint2_check"
CONTEXT: while creating return value
PL/Python function "test_type_conversion_uint2"
SELECT * FROM test_type_conversion_uint2(null, 1);
-INFO: (None, <type 'NoneType'>)
+INFO: (None, <class 'NoneType'>)
test_type_conversion_uint2
----------------------------
1
CREATE DOMAIN nnint AS int CHECK (VALUE IS NOT NULL);
CREATE FUNCTION test_type_conversion_nnint(x nnint, y int) RETURNS nnint AS $$
return y
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_nnint(10, 20);
test_type_conversion_nnint
----------------------------
CREATE FUNCTION test_type_conversion_bytea10(x bytea10, y bytea) RETURNS bytea10 AS $$
plpy.info(x, type(x))
return y
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_bytea10('hello wold', 'hello wold');
-INFO: ('hello wold', <type 'str'>)
+INFO: (b'hello wold', <class 'bytes'>)
test_type_conversion_bytea10
------------------------------
\x68656c6c6f20776f6c64
SELECT * FROM test_type_conversion_bytea10('hello world', 'hello wold');
ERROR: value for domain bytea10 violates check constraint "bytea10_check"
SELECT * FROM test_type_conversion_bytea10('hello word', 'hello world');
-INFO: ('hello word', <type 'str'>)
+INFO: (b'hello word', <class 'bytes'>)
ERROR: value for domain bytea10 violates check constraint "bytea10_check"
CONTEXT: while creating return value
PL/Python function "test_type_conversion_bytea10"
SELECT * FROM test_type_conversion_bytea10(null, 'hello word');
ERROR: value for domain bytea10 violates check constraint "bytea10_check"
SELECT * FROM test_type_conversion_bytea10('hello word', null);
-INFO: ('hello word', <type 'str'>)
+INFO: (b'hello word', <class 'bytes'>)
ERROR: value for domain bytea10 violates check constraint "bytea10_check"
CONTEXT: while creating return value
PL/Python function "test_type_conversion_bytea10"
CREATE FUNCTION test_type_conversion_array_int4(x int4[]) RETURNS int4[] AS $$
plpy.info(x, type(x))
return x
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_array_int4(ARRAY[0, 100]);
-INFO: ([0, 100], <type 'list'>)
+INFO: ([0, 100], <class 'list'>)
test_type_conversion_array_int4
---------------------------------
{0,100}
(1 row)
SELECT * FROM test_type_conversion_array_int4(ARRAY[0,-100,55]);
-INFO: ([0, -100, 55], <type 'list'>)
+INFO: ([0, -100, 55], <class 'list'>)
test_type_conversion_array_int4
---------------------------------
{0,-100,55}
(1 row)
SELECT * FROM test_type_conversion_array_int4(ARRAY[NULL,1]);
-INFO: ([None, 1], <type 'list'>)
+INFO: ([None, 1], <class 'list'>)
test_type_conversion_array_int4
---------------------------------
{NULL,1}
(1 row)
SELECT * FROM test_type_conversion_array_int4(ARRAY[]::integer[]);
-INFO: ([], <type 'list'>)
+INFO: ([], <class 'list'>)
test_type_conversion_array_int4
---------------------------------
{}
(1 row)
SELECT * FROM test_type_conversion_array_int4(NULL);
-INFO: (None, <type 'NoneType'>)
+INFO: (None, <class 'NoneType'>)
test_type_conversion_array_int4
---------------------------------
(1 row)
SELECT * FROM test_type_conversion_array_int4(ARRAY[[1,2,3],[4,5,6]]);
-INFO: ([[1, 2, 3], [4, 5, 6]], <type 'list'>)
+INFO: ([[1, 2, 3], [4, 5, 6]], <class 'list'>)
test_type_conversion_array_int4
---------------------------------
{{1,2,3},{4,5,6}}
(1 row)
SELECT * FROM test_type_conversion_array_int4(ARRAY[[[1,2,NULL],[NULL,5,6]],[[NULL,8,9],[10,11,12]]]);
-INFO: ([[[1, 2, None], [None, 5, 6]], [[None, 8, 9], [10, 11, 12]]], <type 'list'>)
+INFO: ([[[1, 2, None], [None, 5, 6]], [[None, 8, 9], [10, 11, 12]]], <class 'list'>)
test_type_conversion_array_int4
---------------------------------------------------
{{{1,2,NULL},{NULL,5,6}},{{NULL,8,9},{10,11,12}}}
(1 row)
SELECT * FROM test_type_conversion_array_int4('[2:4]={1,2,3}');
-INFO: ([1, 2, 3], <type 'list'>)
+INFO: ([1, 2, 3], <class 'list'>)
test_type_conversion_array_int4
---------------------------------
{1,2,3}
CREATE FUNCTION test_type_conversion_array_int8(x int8[]) RETURNS int8[] AS $$
plpy.info(x, type(x))
return x
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_array_int8(ARRAY[[[1,2,NULL],[NULL,5,6]],[[NULL,8,9],[10,11,12]]]::int8[]);
-INFO: ([[[1L, 2L, None], [None, 5L, 6L]], [[None, 8L, 9L], [10L, 11L, 12L]]], <type 'list'>)
+INFO: ([[[1, 2, None], [None, 5, 6]], [[None, 8, 9], [10, 11, 12]]], <class 'list'>)
test_type_conversion_array_int8
---------------------------------------------------
{{{1,2,NULL},{NULL,5,6}},{{NULL,8,9},{10,11,12}}}
CREATE FUNCTION test_type_conversion_array_date(x date[]) RETURNS date[] AS $$
plpy.info(x, type(x))
return x
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_array_date(ARRAY[[['2016-09-21','2016-09-22',NULL],[NULL,'2016-10-21','2016-10-22']],
[[NULL,'2016-11-21','2016-10-21'],['2015-09-21','2015-09-22','2014-09-21']]]::date[]);
-INFO: ([[['09-21-2016', '09-22-2016', None], [None, '10-21-2016', '10-22-2016']], [[None, '11-21-2016', '10-21-2016'], ['09-21-2015', '09-22-2015', '09-21-2014']]], <type 'list'>)
+INFO: ([[['09-21-2016', '09-22-2016', None], [None, '10-21-2016', '10-22-2016']], [[None, '11-21-2016', '10-21-2016'], ['09-21-2015', '09-22-2015', '09-21-2014']]], <class 'list'>)
test_type_conversion_array_date
---------------------------------------------------------------------------------------------------------------------------------
{{{09-21-2016,09-22-2016,NULL},{NULL,10-21-2016,10-22-2016}},{{NULL,11-21-2016,10-21-2016},{09-21-2015,09-22-2015,09-21-2014}}}
CREATE FUNCTION test_type_conversion_array_timestamp(x timestamp[]) RETURNS timestamp[] AS $$
plpy.info(x, type(x))
return x
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_array_timestamp(ARRAY[[['2016-09-21 15:34:24.078792-04','2016-10-22 11:34:24.078795-04',NULL],
[NULL,'2016-10-21 11:34:25.078792-04','2016-10-21 11:34:24.098792-04']],
[[NULL,'2016-01-21 11:34:24.078792-04','2016-11-21 11:34:24.108792-04'],
['2015-09-21 11:34:24.079792-04','2014-09-21 11:34:24.078792-04','2013-09-21 11:34:24.078792-04']]]::timestamp[]);
-INFO: ([[['Wed Sep 21 15:34:24.078792 2016', 'Sat Oct 22 11:34:24.078795 2016', None], [None, 'Fri Oct 21 11:34:25.078792 2016', 'Fri Oct 21 11:34:24.098792 2016']], [[None, 'Thu Jan 21 11:34:24.078792 2016', 'Mon Nov 21 11:34:24.108792 2016'], ['Mon Sep 21 11:34:24.079792 2015', 'Sun Sep 21 11:34:24.078792 2014', 'Sat Sep 21 11:34:24.078792 2013']]], <type 'list'>)
+INFO: ([[['Wed Sep 21 15:34:24.078792 2016', 'Sat Oct 22 11:34:24.078795 2016', None], [None, 'Fri Oct 21 11:34:25.078792 2016', 'Fri Oct 21 11:34:24.098792 2016']], [[None, 'Thu Jan 21 11:34:24.078792 2016', 'Mon Nov 21 11:34:24.108792 2016'], ['Mon Sep 21 11:34:24.079792 2015', 'Sun Sep 21 11:34:24.078792 2014', 'Sat Sep 21 11:34:24.078792 2013']]], <class 'list'>)
test_type_conversion_array_timestamp
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
{{{"Wed Sep 21 15:34:24.078792 2016","Sat Oct 22 11:34:24.078795 2016",NULL},{NULL,"Fri Oct 21 11:34:25.078792 2016","Fri Oct 21 11:34:24.098792 2016"}},{{NULL,"Thu Jan 21 11:34:24.078792 2016","Mon Nov 21 11:34:24.108792 2016"},{"Mon Sep 21 11:34:24.079792 2015","Sun Sep 21 11:34:24.078792 2014","Sat Sep 21 11:34:24.078792 2013"}}}
m = [[[[x for x in range(h)] for y in range(i)] for z in range(j)] for w in range(k)]
plpy.info(m, type(m))
return m
-$BODY$ LANGUAGE plpythonu;
+$BODY$ LANGUAGE plpython3u;
select pyreturnmultidemint4(8,5,3,2);
-INFO: ([[[[0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7]], [[0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7]], [[0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7]]], [[[0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7]], [[0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7]], [[0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7]]]], <type 'list'>)
+INFO: ([[[[0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7]], [[0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7]], [[0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7]]], [[[0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7]], [[0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7]], [[0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7]]]], <class 'list'>)
pyreturnmultidemint4
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
{{{{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7}},{{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7}},{{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7}}},{{{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7}},{{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7}},{{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7}}}}
m = [[[[x for x in range(h)] for y in range(i)] for z in range(j)] for w in range(k)]
plpy.info(m, type(m))
return m
-$BODY$ LANGUAGE plpythonu;
+$BODY$ LANGUAGE plpython3u;
select pyreturnmultidemint8(5,5,3,2);
-INFO: ([[[[0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4]], [[0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4]], [[0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4]]], [[[0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4]], [[0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4]], [[0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4]]]], <type 'list'>)
+INFO: ([[[[0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4]], [[0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4]], [[0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4]]], [[[0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4]], [[0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4]], [[0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4]]]], <class 'list'>)
pyreturnmultidemint8
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
{{{{0,1,2,3,4},{0,1,2,3,4},{0,1,2,3,4},{0,1,2,3,4},{0,1,2,3,4}},{{0,1,2,3,4},{0,1,2,3,4},{0,1,2,3,4},{0,1,2,3,4},{0,1,2,3,4}},{{0,1,2,3,4},{0,1,2,3,4},{0,1,2,3,4},{0,1,2,3,4},{0,1,2,3,4}}},{{{0,1,2,3,4},{0,1,2,3,4},{0,1,2,3,4},{0,1,2,3,4},{0,1,2,3,4}},{{0,1,2,3,4},{0,1,2,3,4},{0,1,2,3,4},{0,1,2,3,4},{0,1,2,3,4}},{{0,1,2,3,4},{0,1,2,3,4},{0,1,2,3,4},{0,1,2,3,4},{0,1,2,3,4}}}}
m = [[[[x for x in range(h)] for y in range(i)] for z in range(j)] for w in range(k)]
plpy.info(m, type(m))
return m
-$BODY$ LANGUAGE plpythonu;
+$BODY$ LANGUAGE plpython3u;
select pyreturnmultidemfloat4(6,5,3,2);
-INFO: ([[[[0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5]], [[0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5]], [[0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5]]], [[[0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5]], [[0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5]], [[0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5]]]], <type 'list'>)
+INFO: ([[[[0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5]], [[0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5]], [[0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5]]], [[[0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5]], [[0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5]], [[0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5]]]], <class 'list'>)
pyreturnmultidemfloat4
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
{{{{0,1,2,3,4,5},{0,1,2,3,4,5},{0,1,2,3,4,5},{0,1,2,3,4,5},{0,1,2,3,4,5}},{{0,1,2,3,4,5},{0,1,2,3,4,5},{0,1,2,3,4,5},{0,1,2,3,4,5},{0,1,2,3,4,5}},{{0,1,2,3,4,5},{0,1,2,3,4,5},{0,1,2,3,4,5},{0,1,2,3,4,5},{0,1,2,3,4,5}}},{{{0,1,2,3,4,5},{0,1,2,3,4,5},{0,1,2,3,4,5},{0,1,2,3,4,5},{0,1,2,3,4,5}},{{0,1,2,3,4,5},{0,1,2,3,4,5},{0,1,2,3,4,5},{0,1,2,3,4,5},{0,1,2,3,4,5}},{{0,1,2,3,4,5},{0,1,2,3,4,5},{0,1,2,3,4,5},{0,1,2,3,4,5},{0,1,2,3,4,5}}}}
m = [[[[x for x in range(h)] for y in range(i)] for z in range(j)] for w in range(k)]
plpy.info(m, type(m))
return m
-$BODY$ LANGUAGE plpythonu;
+$BODY$ LANGUAGE plpython3u;
select pyreturnmultidemfloat8(7,5,3,2);
-INFO: ([[[[0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6]], [[0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6]], [[0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6]]], [[[0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6]], [[0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6]], [[0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6]]]], <type 'list'>)
+INFO: ([[[[0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6]], [[0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6]], [[0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6]]], [[[0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6]], [[0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6]], [[0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6]]]], <class 'list'>)
pyreturnmultidemfloat8
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
{{{{0,1,2,3,4,5,6},{0,1,2,3,4,5,6},{0,1,2,3,4,5,6},{0,1,2,3,4,5,6},{0,1,2,3,4,5,6}},{{0,1,2,3,4,5,6},{0,1,2,3,4,5,6},{0,1,2,3,4,5,6},{0,1,2,3,4,5,6},{0,1,2,3,4,5,6}},{{0,1,2,3,4,5,6},{0,1,2,3,4,5,6},{0,1,2,3,4,5,6},{0,1,2,3,4,5,6},{0,1,2,3,4,5,6}}},{{{0,1,2,3,4,5,6},{0,1,2,3,4,5,6},{0,1,2,3,4,5,6},{0,1,2,3,4,5,6},{0,1,2,3,4,5,6}},{{0,1,2,3,4,5,6},{0,1,2,3,4,5,6},{0,1,2,3,4,5,6},{0,1,2,3,4,5,6},{0,1,2,3,4,5,6}},{{0,1,2,3,4,5,6},{0,1,2,3,4,5,6},{0,1,2,3,4,5,6},{0,1,2,3,4,5,6},{0,1,2,3,4,5,6}}}}
CREATE FUNCTION test_type_conversion_array_text(x text[]) RETURNS text[] AS $$
plpy.info(x, type(x))
return x
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_array_text(ARRAY['foo', 'bar']);
-INFO: (['foo', 'bar'], <type 'list'>)
+INFO: (['foo', 'bar'], <class 'list'>)
test_type_conversion_array_text
---------------------------------
{foo,bar}
(1 row)
SELECT * FROM test_type_conversion_array_text(ARRAY[['foo', 'bar'],['foo2', 'bar2']]);
-INFO: ([['foo', 'bar'], ['foo2', 'bar2']], <type 'list'>)
+INFO: ([['foo', 'bar'], ['foo2', 'bar2']], <class 'list'>)
test_type_conversion_array_text
---------------------------------
{{foo,bar},{foo2,bar2}}
CREATE FUNCTION test_type_conversion_array_bytea(x bytea[]) RETURNS bytea[] AS $$
plpy.info(x, type(x))
return x
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_array_bytea(ARRAY[E'\\xdeadbeef'::bytea, NULL]);
-INFO: (['\xde\xad\xbe\xef', None], <type 'list'>)
+INFO: ([b'\xde\xad\xbe\xef', None], <class 'list'>)
test_type_conversion_array_bytea
----------------------------------
{"\\xdeadbeef",NULL}
CREATE FUNCTION test_type_conversion_array_mixed1() RETURNS text[] AS $$
return [123, 'abc']
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_array_mixed1();
test_type_conversion_array_mixed1
-----------------------------------
CREATE FUNCTION test_type_conversion_array_mixed2() RETURNS int[] AS $$
return [123, 'abc']
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_array_mixed2();
ERROR: invalid input syntax for type integer: "abc"
CONTEXT: while creating return value
PL/Python function "test_type_conversion_array_mixed2"
CREATE FUNCTION test_type_conversion_mdarray_malformed() RETURNS int[] AS $$
return [[1,2,3],[4,5]]
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_mdarray_malformed();
ERROR: wrong length of inner sequence: has length 2, but 3 was expected
DETAIL: To construct a multidimensional array, the inner sequences must all have the same length.
PL/Python function "test_type_conversion_mdarray_malformed"
CREATE FUNCTION test_type_conversion_mdarray_toodeep() RETURNS int[] AS $$
return [[[[[[[1]]]]]]]
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_mdarray_toodeep();
ERROR: number of array dimensions exceeds the maximum allowed (6)
CONTEXT: while creating return value
PL/Python function "test_type_conversion_mdarray_toodeep"
CREATE FUNCTION test_type_conversion_array_record() RETURNS type_record[] AS $$
return [{'first': 'one', 'second': 42}, {'first': 'two', 'second': 11}]
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_array_record();
test_type_conversion_array_record
-----------------------------------
CREATE FUNCTION test_type_conversion_array_string() RETURNS text[] AS $$
return 'abc'
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_array_string();
test_type_conversion_array_string
-----------------------------------
CREATE FUNCTION test_type_conversion_array_tuple() RETURNS text[] AS $$
return ('abc', 'def')
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_array_tuple();
test_type_conversion_array_tuple
----------------------------------
CREATE FUNCTION test_type_conversion_array_error() RETURNS int[] AS $$
return 5
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_array_error();
ERROR: return value of function with array return type is not a Python sequence
CONTEXT: while creating return value
CREATE FUNCTION test_type_conversion_array_domain(x ordered_pair_domain) RETURNS ordered_pair_domain AS $$
plpy.info(x, type(x))
return x
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_array_domain(ARRAY[0, 100]::ordered_pair_domain);
-INFO: ([0, 100], <type 'list'>)
+INFO: ([0, 100], <class 'list'>)
test_type_conversion_array_domain
-----------------------------------
{0,100}
(1 row)
SELECT * FROM test_type_conversion_array_domain(NULL::ordered_pair_domain);
-INFO: (None, <type 'NoneType'>)
+INFO: (None, <class 'NoneType'>)
test_type_conversion_array_domain
-----------------------------------
CREATE FUNCTION test_type_conversion_array_domain_check_violation() RETURNS ordered_pair_domain AS $$
return [2,1]
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_array_domain_check_violation();
ERROR: value for domain ordered_pair_domain violates check constraint "ordered_pair_domain_check"
CONTEXT: while creating return value
CREATE FUNCTION test_read_uint2_array(x uint2[]) RETURNS uint2 AS $$
plpy.info(x, type(x))
return x[0]
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
select test_read_uint2_array(array[1::uint2]);
-INFO: ([1], <type 'list'>)
+INFO: ([1], <class 'list'>)
test_read_uint2_array
-----------------------
1
CREATE FUNCTION test_build_uint2_array(x int2) RETURNS uint2[] AS $$
return [x, x]
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
select test_build_uint2_array(1::int2);
test_build_uint2_array
------------------------
CREATE FUNCTION test_type_conversion_domain_array(x integer[])
RETURNS ordered_pair_domain[] AS $$
return [x, x]
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
select test_type_conversion_domain_array(array[2,4]);
ERROR: return value of function with array return type is not a Python sequence
CONTEXT: while creating return value
RETURNS integer AS $$
plpy.info(x, type(x))
return x[1]
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
select test_type_conversion_domain_array2(array[2,4]);
-INFO: ([2, 4], <type 'list'>)
+INFO: ([2, 4], <class 'list'>)
test_type_conversion_domain_array2
------------------------------------
4
RETURNS ordered_pair_domain AS $$
plpy.info(x, type(x))
return x[0]
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
select test_type_conversion_array_domain_array(array[array[2,4]::ordered_pair_domain]);
-INFO: ([[2, 4]], <type 'list'>)
+INFO: ([[2, 4]], <class 'list'>)
test_type_conversion_array_domain_array
-----------------------------------------
{2,4}
INSERT INTO employee VALUES ('John', 100, 10), ('Mary', 200, 10);
CREATE OR REPLACE FUNCTION test_composite_table_input(e employee) RETURNS integer AS $$
return e['basesalary'] + e['bonus']
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT name, test_composite_table_input(employee.*) FROM employee;
name | test_composite_table_input
------+----------------------------
);
CREATE OR REPLACE FUNCTION test_composite_type_input(p named_pair) RETURNS integer AS $$
return sum(p.values())
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT test_composite_type_input(row(1, 2));
test_composite_type_input
---------------------------
CREATE TYPE nnint_container AS (f1 int, f2 nnint);
CREATE FUNCTION nnint_test(x int, y int) RETURNS nnint_container AS $$
return {'f1': x, 'f2': y}
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT nnint_test(null, 3);
nnint_test
------------
CREATE DOMAIN ordered_named_pair AS named_pair_2 CHECK((VALUE).i <= (VALUE).j);
CREATE FUNCTION read_ordered_named_pair(p ordered_named_pair) RETURNS integer AS $$
return p['i'] + p['j']
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT read_ordered_named_pair(row(1, 2));
read_ordered_named_pair
-------------------------
ERROR: value for domain ordered_named_pair violates check constraint "ordered_named_pair_check"
CREATE FUNCTION build_ordered_named_pair(i int, j int) RETURNS ordered_named_pair AS $$
return {'i': i, 'j': j}
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT build_ordered_named_pair(1,2);
build_ordered_named_pair
--------------------------
PL/Python function "build_ordered_named_pair"
CREATE FUNCTION build_ordered_named_pairs(i int, j int) RETURNS ordered_named_pair[] AS $$
return [{'i': i, 'j': j}, {'i': i, 'j': j+1}]
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT build_ordered_named_pairs(1,2);
build_ordered_named_pairs
---------------------------
-- Prepared statements
--
CREATE OR REPLACE FUNCTION test_prep_bool_input() RETURNS int
-LANGUAGE plpythonu
+LANGUAGE plpython3u
AS $$
plan = plpy.prepare("SELECT CASE WHEN $1 THEN 1 ELSE 0 END AS val", ['boolean'])
rv = plpy.execute(plan, ['fa'], 5) # 'fa' is true in Python
(1 row)
CREATE OR REPLACE FUNCTION test_prep_bool_output() RETURNS bool
-LANGUAGE plpythonu
+LANGUAGE plpython3u
AS $$
plan = plpy.prepare("SELECT $1 = 1 AS val", ['int'])
rv = plpy.execute(plan, [0], 5)
(1 row)
CREATE OR REPLACE FUNCTION test_prep_bytea_input(bb bytea) RETURNS int
-LANGUAGE plpythonu
+LANGUAGE plpython3u
AS $$
plan = plpy.prepare("SELECT octet_length($1) AS val", ['bytea'])
rv = plpy.execute(plan, [bb], 5)
(1 row)
CREATE OR REPLACE FUNCTION test_prep_bytea_output() RETURNS bytea
-LANGUAGE plpythonu
+LANGUAGE plpython3u
AS $$
plan = plpy.prepare("SELECT decode('aa00bb', 'hex') AS val")
rv = plpy.execute(plan, [], 5)
return rv[0]['val']
$$;
SELECT test_prep_bytea_output();
-INFO: {'val': '\xaa\x00\xbb'}
+INFO: {'val': b'\xaa\x00\xbb'}
test_prep_bytea_output
------------------------
\xaa00bb
+++ /dev/null
---
--- Test data type behavior
---
---
--- Base/common types
---
-CREATE FUNCTION test_type_conversion_bool(x bool) RETURNS bool AS $$
-plpy.info(x, type(x))
-return x
-$$ LANGUAGE plpython3u;
-SELECT * FROM test_type_conversion_bool(true);
-INFO: (True, <class 'bool'>)
- test_type_conversion_bool
----------------------------
- t
-(1 row)
-
-SELECT * FROM test_type_conversion_bool(false);
-INFO: (False, <class 'bool'>)
- test_type_conversion_bool
----------------------------
- f
-(1 row)
-
-SELECT * FROM test_type_conversion_bool(null);
-INFO: (None, <class 'NoneType'>)
- test_type_conversion_bool
----------------------------
-
-(1 row)
-
--- test various other ways to express Booleans in Python
-CREATE FUNCTION test_type_conversion_bool_other(n int) RETURNS bool AS $$
-# numbers
-if n == 0:
- ret = 0
-elif n == 1:
- ret = 5
-# strings
-elif n == 2:
- ret = ''
-elif n == 3:
- ret = 'fa' # true in Python, false in PostgreSQL
-# containers
-elif n == 4:
- ret = []
-elif n == 5:
- ret = [0]
-plpy.info(ret, not not ret)
-return ret
-$$ LANGUAGE plpython3u;
-SELECT * FROM test_type_conversion_bool_other(0);
-INFO: (0, False)
- test_type_conversion_bool_other
----------------------------------
- f
-(1 row)
-
-SELECT * FROM test_type_conversion_bool_other(1);
-INFO: (5, True)
- test_type_conversion_bool_other
----------------------------------
- t
-(1 row)
-
-SELECT * FROM test_type_conversion_bool_other(2);
-INFO: ('', False)
- test_type_conversion_bool_other
----------------------------------
- f
-(1 row)
-
-SELECT * FROM test_type_conversion_bool_other(3);
-INFO: ('fa', True)
- test_type_conversion_bool_other
----------------------------------
- t
-(1 row)
-
-SELECT * FROM test_type_conversion_bool_other(4);
-INFO: ([], False)
- test_type_conversion_bool_other
----------------------------------
- f
-(1 row)
-
-SELECT * FROM test_type_conversion_bool_other(5);
-INFO: ([0], True)
- test_type_conversion_bool_other
----------------------------------
- t
-(1 row)
-
-CREATE FUNCTION test_type_conversion_char(x char) RETURNS char AS $$
-plpy.info(x, type(x))
-return x
-$$ LANGUAGE plpython3u;
-SELECT * FROM test_type_conversion_char('a');
-INFO: ('a', <class 'str'>)
- test_type_conversion_char
----------------------------
- a
-(1 row)
-
-SELECT * FROM test_type_conversion_char(null);
-INFO: (None, <class 'NoneType'>)
- test_type_conversion_char
----------------------------
-
-(1 row)
-
-CREATE FUNCTION test_type_conversion_int2(x int2) RETURNS int2 AS $$
-plpy.info(x, type(x))
-return x
-$$ LANGUAGE plpython3u;
-SELECT * FROM test_type_conversion_int2(100::int2);
-INFO: (100, <class 'int'>)
- test_type_conversion_int2
----------------------------
- 100
-(1 row)
-
-SELECT * FROM test_type_conversion_int2(-100::int2);
-INFO: (-100, <class 'int'>)
- test_type_conversion_int2
----------------------------
- -100
-(1 row)
-
-SELECT * FROM test_type_conversion_int2(null);
-INFO: (None, <class 'NoneType'>)
- test_type_conversion_int2
----------------------------
-
-(1 row)
-
-CREATE FUNCTION test_type_conversion_int4(x int4) RETURNS int4 AS $$
-plpy.info(x, type(x))
-return x
-$$ LANGUAGE plpython3u;
-SELECT * FROM test_type_conversion_int4(100);
-INFO: (100, <class 'int'>)
- test_type_conversion_int4
----------------------------
- 100
-(1 row)
-
-SELECT * FROM test_type_conversion_int4(-100);
-INFO: (-100, <class 'int'>)
- test_type_conversion_int4
----------------------------
- -100
-(1 row)
-
-SELECT * FROM test_type_conversion_int4(null);
-INFO: (None, <class 'NoneType'>)
- test_type_conversion_int4
----------------------------
-
-(1 row)
-
-CREATE FUNCTION test_type_conversion_int8(x int8) RETURNS int8 AS $$
-plpy.info(x, type(x))
-return x
-$$ LANGUAGE plpython3u;
-SELECT * FROM test_type_conversion_int8(100);
-INFO: (100, <class 'int'>)
- test_type_conversion_int8
----------------------------
- 100
-(1 row)
-
-SELECT * FROM test_type_conversion_int8(-100);
-INFO: (-100, <class 'int'>)
- test_type_conversion_int8
----------------------------
- -100
-(1 row)
-
-SELECT * FROM test_type_conversion_int8(5000000000);
-INFO: (5000000000, <class 'int'>)
- test_type_conversion_int8
----------------------------
- 5000000000
-(1 row)
-
-SELECT * FROM test_type_conversion_int8(null);
-INFO: (None, <class 'NoneType'>)
- test_type_conversion_int8
----------------------------
-
-(1 row)
-
-CREATE FUNCTION test_type_conversion_numeric(x numeric) RETURNS numeric AS $$
-# print just the class name, not the type, to avoid differences
-# between decimal and cdecimal
-plpy.info(str(x), x.__class__.__name__)
-return x
-$$ LANGUAGE plpython3u;
-SELECT * FROM test_type_conversion_numeric(100);
-INFO: ('100', 'Decimal')
- test_type_conversion_numeric
-------------------------------
- 100
-(1 row)
-
-SELECT * FROM test_type_conversion_numeric(-100);
-INFO: ('-100', 'Decimal')
- test_type_conversion_numeric
-------------------------------
- -100
-(1 row)
-
-SELECT * FROM test_type_conversion_numeric(100.0);
-INFO: ('100.0', 'Decimal')
- test_type_conversion_numeric
-------------------------------
- 100.0
-(1 row)
-
-SELECT * FROM test_type_conversion_numeric(100.00);
-INFO: ('100.00', 'Decimal')
- test_type_conversion_numeric
-------------------------------
- 100.00
-(1 row)
-
-SELECT * FROM test_type_conversion_numeric(5000000000.5);
-INFO: ('5000000000.5', 'Decimal')
- test_type_conversion_numeric
-------------------------------
- 5000000000.5
-(1 row)
-
-SELECT * FROM test_type_conversion_numeric(1234567890.0987654321);
-INFO: ('1234567890.0987654321', 'Decimal')
- test_type_conversion_numeric
-------------------------------
- 1234567890.0987654321
-(1 row)
-
-SELECT * FROM test_type_conversion_numeric(-1234567890.0987654321);
-INFO: ('-1234567890.0987654321', 'Decimal')
- test_type_conversion_numeric
-------------------------------
- -1234567890.0987654321
-(1 row)
-
-SELECT * FROM test_type_conversion_numeric(null);
-INFO: ('None', 'NoneType')
- test_type_conversion_numeric
-------------------------------
-
-(1 row)
-
-CREATE FUNCTION test_type_conversion_float4(x float4) RETURNS float4 AS $$
-plpy.info(x, type(x))
-return x
-$$ LANGUAGE plpython3u;
-SELECT * FROM test_type_conversion_float4(100);
-INFO: (100.0, <class 'float'>)
- test_type_conversion_float4
------------------------------
- 100
-(1 row)
-
-SELECT * FROM test_type_conversion_float4(-100);
-INFO: (-100.0, <class 'float'>)
- test_type_conversion_float4
------------------------------
- -100
-(1 row)
-
-SELECT * FROM test_type_conversion_float4(5000.5);
-INFO: (5000.5, <class 'float'>)
- test_type_conversion_float4
------------------------------
- 5000.5
-(1 row)
-
-SELECT * FROM test_type_conversion_float4(null);
-INFO: (None, <class 'NoneType'>)
- test_type_conversion_float4
------------------------------
-
-(1 row)
-
-CREATE FUNCTION test_type_conversion_float8(x float8) RETURNS float8 AS $$
-plpy.info(x, type(x))
-return x
-$$ LANGUAGE plpython3u;
-SELECT * FROM test_type_conversion_float8(100);
-INFO: (100.0, <class 'float'>)
- test_type_conversion_float8
------------------------------
- 100
-(1 row)
-
-SELECT * FROM test_type_conversion_float8(-100);
-INFO: (-100.0, <class 'float'>)
- test_type_conversion_float8
------------------------------
- -100
-(1 row)
-
-SELECT * FROM test_type_conversion_float8(5000000000.5);
-INFO: (5000000000.5, <class 'float'>)
- test_type_conversion_float8
------------------------------
- 5000000000.5
-(1 row)
-
-SELECT * FROM test_type_conversion_float8(null);
-INFO: (None, <class 'NoneType'>)
- test_type_conversion_float8
------------------------------
-
-(1 row)
-
-SELECT * FROM test_type_conversion_float8(100100100.654321);
-INFO: (100100100.654321, <class 'float'>)
- test_type_conversion_float8
------------------------------
- 100100100.654321
-(1 row)
-
-CREATE FUNCTION test_type_conversion_oid(x oid) RETURNS oid AS $$
-plpy.info(x, type(x))
-return x
-$$ LANGUAGE plpython3u;
-SELECT * FROM test_type_conversion_oid(100);
-INFO: (100, <class 'int'>)
- test_type_conversion_oid
---------------------------
- 100
-(1 row)
-
-SELECT * FROM test_type_conversion_oid(2147483649);
-INFO: (2147483649, <class 'int'>)
- test_type_conversion_oid
---------------------------
- 2147483649
-(1 row)
-
-SELECT * FROM test_type_conversion_oid(null);
-INFO: (None, <class 'NoneType'>)
- test_type_conversion_oid
---------------------------
-
-(1 row)
-
-CREATE FUNCTION test_type_conversion_text(x text) RETURNS text AS $$
-plpy.info(x, type(x))
-return x
-$$ LANGUAGE plpython3u;
-SELECT * FROM test_type_conversion_text('hello world');
-INFO: ('hello world', <class 'str'>)
- test_type_conversion_text
----------------------------
- hello world
-(1 row)
-
-SELECT * FROM test_type_conversion_text(null);
-INFO: (None, <class 'NoneType'>)
- test_type_conversion_text
----------------------------
-
-(1 row)
-
-CREATE FUNCTION test_type_conversion_bytea(x bytea) RETURNS bytea AS $$
-plpy.info(x, type(x))
-return x
-$$ LANGUAGE plpython3u;
-SELECT * FROM test_type_conversion_bytea('hello world');
-INFO: (b'hello world', <class 'bytes'>)
- test_type_conversion_bytea
-----------------------------
- \x68656c6c6f20776f726c64
-(1 row)
-
-SELECT * FROM test_type_conversion_bytea(E'null\\000byte');
-INFO: (b'null\x00byte', <class 'bytes'>)
- test_type_conversion_bytea
-----------------------------
- \x6e756c6c0062797465
-(1 row)
-
-SELECT * FROM test_type_conversion_bytea(null);
-INFO: (None, <class 'NoneType'>)
- test_type_conversion_bytea
-----------------------------
-
-(1 row)
-
-CREATE FUNCTION test_type_marshal() RETURNS bytea AS $$
-import marshal
-return marshal.dumps('hello world')
-$$ LANGUAGE plpython3u;
-CREATE FUNCTION test_type_unmarshal(x bytea) RETURNS text AS $$
-import marshal
-try:
- return marshal.loads(x)
-except ValueError as e:
- return 'FAILED: ' + str(e)
-$$ LANGUAGE plpython3u;
-SELECT test_type_unmarshal(x) FROM test_type_marshal() x;
- test_type_unmarshal
----------------------
- hello world
-(1 row)
-
---
--- Domains
---
-CREATE DOMAIN booltrue AS bool CHECK (VALUE IS TRUE OR VALUE IS NULL);
-CREATE FUNCTION test_type_conversion_booltrue(x booltrue, y bool) RETURNS booltrue AS $$
-return y
-$$ LANGUAGE plpython3u;
-SELECT * FROM test_type_conversion_booltrue(true, true);
- test_type_conversion_booltrue
--------------------------------
- t
-(1 row)
-
-SELECT * FROM test_type_conversion_booltrue(false, true);
-ERROR: value for domain booltrue violates check constraint "booltrue_check"
-SELECT * FROM test_type_conversion_booltrue(true, false);
-ERROR: value for domain booltrue violates check constraint "booltrue_check"
-CONTEXT: while creating return value
-PL/Python function "test_type_conversion_booltrue"
-CREATE DOMAIN uint2 AS int2 CHECK (VALUE >= 0);
-CREATE FUNCTION test_type_conversion_uint2(x uint2, y int) RETURNS uint2 AS $$
-plpy.info(x, type(x))
-return y
-$$ LANGUAGE plpython3u;
-SELECT * FROM test_type_conversion_uint2(100::uint2, 50);
-INFO: (100, <class 'int'>)
- test_type_conversion_uint2
-----------------------------
- 50
-(1 row)
-
-SELECT * FROM test_type_conversion_uint2(100::uint2, -50);
-INFO: (100, <class 'int'>)
-ERROR: value for domain uint2 violates check constraint "uint2_check"
-CONTEXT: while creating return value
-PL/Python function "test_type_conversion_uint2"
-SELECT * FROM test_type_conversion_uint2(null, 1);
-INFO: (None, <class 'NoneType'>)
- test_type_conversion_uint2
-----------------------------
- 1
-(1 row)
-
-CREATE DOMAIN nnint AS int CHECK (VALUE IS NOT NULL);
-CREATE FUNCTION test_type_conversion_nnint(x nnint, y int) RETURNS nnint AS $$
-return y
-$$ LANGUAGE plpython3u;
-SELECT * FROM test_type_conversion_nnint(10, 20);
- test_type_conversion_nnint
-----------------------------
- 20
-(1 row)
-
-SELECT * FROM test_type_conversion_nnint(null, 20);
-ERROR: value for domain nnint violates check constraint "nnint_check"
-SELECT * FROM test_type_conversion_nnint(10, null);
-ERROR: value for domain nnint violates check constraint "nnint_check"
-CONTEXT: while creating return value
-PL/Python function "test_type_conversion_nnint"
-CREATE DOMAIN bytea10 AS bytea CHECK (octet_length(VALUE) = 10 AND VALUE IS NOT NULL);
-CREATE FUNCTION test_type_conversion_bytea10(x bytea10, y bytea) RETURNS bytea10 AS $$
-plpy.info(x, type(x))
-return y
-$$ LANGUAGE plpython3u;
-SELECT * FROM test_type_conversion_bytea10('hello wold', 'hello wold');
-INFO: (b'hello wold', <class 'bytes'>)
- test_type_conversion_bytea10
-------------------------------
- \x68656c6c6f20776f6c64
-(1 row)
-
-SELECT * FROM test_type_conversion_bytea10('hello world', 'hello wold');
-ERROR: value for domain bytea10 violates check constraint "bytea10_check"
-SELECT * FROM test_type_conversion_bytea10('hello word', 'hello world');
-INFO: (b'hello word', <class 'bytes'>)
-ERROR: value for domain bytea10 violates check constraint "bytea10_check"
-CONTEXT: while creating return value
-PL/Python function "test_type_conversion_bytea10"
-SELECT * FROM test_type_conversion_bytea10(null, 'hello word');
-ERROR: value for domain bytea10 violates check constraint "bytea10_check"
-SELECT * FROM test_type_conversion_bytea10('hello word', null);
-INFO: (b'hello word', <class 'bytes'>)
-ERROR: value for domain bytea10 violates check constraint "bytea10_check"
-CONTEXT: while creating return value
-PL/Python function "test_type_conversion_bytea10"
---
--- Arrays
---
-CREATE FUNCTION test_type_conversion_array_int4(x int4[]) RETURNS int4[] AS $$
-plpy.info(x, type(x))
-return x
-$$ LANGUAGE plpython3u;
-SELECT * FROM test_type_conversion_array_int4(ARRAY[0, 100]);
-INFO: ([0, 100], <class 'list'>)
- test_type_conversion_array_int4
----------------------------------
- {0,100}
-(1 row)
-
-SELECT * FROM test_type_conversion_array_int4(ARRAY[0,-100,55]);
-INFO: ([0, -100, 55], <class 'list'>)
- test_type_conversion_array_int4
----------------------------------
- {0,-100,55}
-(1 row)
-
-SELECT * FROM test_type_conversion_array_int4(ARRAY[NULL,1]);
-INFO: ([None, 1], <class 'list'>)
- test_type_conversion_array_int4
----------------------------------
- {NULL,1}
-(1 row)
-
-SELECT * FROM test_type_conversion_array_int4(ARRAY[]::integer[]);
-INFO: ([], <class 'list'>)
- test_type_conversion_array_int4
----------------------------------
- {}
-(1 row)
-
-SELECT * FROM test_type_conversion_array_int4(NULL);
-INFO: (None, <class 'NoneType'>)
- test_type_conversion_array_int4
----------------------------------
-
-(1 row)
-
-SELECT * FROM test_type_conversion_array_int4(ARRAY[[1,2,3],[4,5,6]]);
-INFO: ([[1, 2, 3], [4, 5, 6]], <class 'list'>)
- test_type_conversion_array_int4
----------------------------------
- {{1,2,3},{4,5,6}}
-(1 row)
-
-SELECT * FROM test_type_conversion_array_int4(ARRAY[[[1,2,NULL],[NULL,5,6]],[[NULL,8,9],[10,11,12]]]);
-INFO: ([[[1, 2, None], [None, 5, 6]], [[None, 8, 9], [10, 11, 12]]], <class 'list'>)
- test_type_conversion_array_int4
----------------------------------------------------
- {{{1,2,NULL},{NULL,5,6}},{{NULL,8,9},{10,11,12}}}
-(1 row)
-
-SELECT * FROM test_type_conversion_array_int4('[2:4]={1,2,3}');
-INFO: ([1, 2, 3], <class 'list'>)
- test_type_conversion_array_int4
----------------------------------
- {1,2,3}
-(1 row)
-
-CREATE FUNCTION test_type_conversion_array_int8(x int8[]) RETURNS int8[] AS $$
-plpy.info(x, type(x))
-return x
-$$ LANGUAGE plpython3u;
-SELECT * FROM test_type_conversion_array_int8(ARRAY[[[1,2,NULL],[NULL,5,6]],[[NULL,8,9],[10,11,12]]]::int8[]);
-INFO: ([[[1, 2, None], [None, 5, 6]], [[None, 8, 9], [10, 11, 12]]], <class 'list'>)
- test_type_conversion_array_int8
----------------------------------------------------
- {{{1,2,NULL},{NULL,5,6}},{{NULL,8,9},{10,11,12}}}
-(1 row)
-
-CREATE FUNCTION test_type_conversion_array_date(x date[]) RETURNS date[] AS $$
-plpy.info(x, type(x))
-return x
-$$ LANGUAGE plpython3u;
-SELECT * FROM test_type_conversion_array_date(ARRAY[[['2016-09-21','2016-09-22',NULL],[NULL,'2016-10-21','2016-10-22']],
- [[NULL,'2016-11-21','2016-10-21'],['2015-09-21','2015-09-22','2014-09-21']]]::date[]);
-INFO: ([[['09-21-2016', '09-22-2016', None], [None, '10-21-2016', '10-22-2016']], [[None, '11-21-2016', '10-21-2016'], ['09-21-2015', '09-22-2015', '09-21-2014']]], <class 'list'>)
- test_type_conversion_array_date
----------------------------------------------------------------------------------------------------------------------------------
- {{{09-21-2016,09-22-2016,NULL},{NULL,10-21-2016,10-22-2016}},{{NULL,11-21-2016,10-21-2016},{09-21-2015,09-22-2015,09-21-2014}}}
-(1 row)
-
-CREATE FUNCTION test_type_conversion_array_timestamp(x timestamp[]) RETURNS timestamp[] AS $$
-plpy.info(x, type(x))
-return x
-$$ LANGUAGE plpython3u;
-SELECT * FROM test_type_conversion_array_timestamp(ARRAY[[['2016-09-21 15:34:24.078792-04','2016-10-22 11:34:24.078795-04',NULL],
- [NULL,'2016-10-21 11:34:25.078792-04','2016-10-21 11:34:24.098792-04']],
- [[NULL,'2016-01-21 11:34:24.078792-04','2016-11-21 11:34:24.108792-04'],
- ['2015-09-21 11:34:24.079792-04','2014-09-21 11:34:24.078792-04','2013-09-21 11:34:24.078792-04']]]::timestamp[]);
-INFO: ([[['Wed Sep 21 15:34:24.078792 2016', 'Sat Oct 22 11:34:24.078795 2016', None], [None, 'Fri Oct 21 11:34:25.078792 2016', 'Fri Oct 21 11:34:24.098792 2016']], [[None, 'Thu Jan 21 11:34:24.078792 2016', 'Mon Nov 21 11:34:24.108792 2016'], ['Mon Sep 21 11:34:24.079792 2015', 'Sun Sep 21 11:34:24.078792 2014', 'Sat Sep 21 11:34:24.078792 2013']]], <class 'list'>)
- test_type_conversion_array_timestamp
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- {{{"Wed Sep 21 15:34:24.078792 2016","Sat Oct 22 11:34:24.078795 2016",NULL},{NULL,"Fri Oct 21 11:34:25.078792 2016","Fri Oct 21 11:34:24.098792 2016"}},{{NULL,"Thu Jan 21 11:34:24.078792 2016","Mon Nov 21 11:34:24.108792 2016"},{"Mon Sep 21 11:34:24.079792 2015","Sun Sep 21 11:34:24.078792 2014","Sat Sep 21 11:34:24.078792 2013"}}}
-(1 row)
-
-CREATE OR REPLACE FUNCTION pyreturnmultidemint4(h int4, i int4, j int4, k int4 ) RETURNS int4[] AS $BODY$
-m = [[[[x for x in range(h)] for y in range(i)] for z in range(j)] for w in range(k)]
-plpy.info(m, type(m))
-return m
-$BODY$ LANGUAGE plpython3u;
-select pyreturnmultidemint4(8,5,3,2);
-INFO: ([[[[0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7]], [[0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7]], [[0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7]]], [[[0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7]], [[0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7]], [[0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7]]]], <class 'list'>)
- pyreturnmultidemint4
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- {{{{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7}},{{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7}},{{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7}}},{{{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7}},{{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7}},{{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7},{0,1,2,3,4,5,6,7}}}}
-(1 row)
-
-CREATE OR REPLACE FUNCTION pyreturnmultidemint8(h int4, i int4, j int4, k int4 ) RETURNS int8[] AS $BODY$
-m = [[[[x for x in range(h)] for y in range(i)] for z in range(j)] for w in range(k)]
-plpy.info(m, type(m))
-return m
-$BODY$ LANGUAGE plpython3u;
-select pyreturnmultidemint8(5,5,3,2);
-INFO: ([[[[0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4]], [[0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4]], [[0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4]]], [[[0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4]], [[0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4]], [[0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4]]]], <class 'list'>)
- pyreturnmultidemint8
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- {{{{0,1,2,3,4},{0,1,2,3,4},{0,1,2,3,4},{0,1,2,3,4},{0,1,2,3,4}},{{0,1,2,3,4},{0,1,2,3,4},{0,1,2,3,4},{0,1,2,3,4},{0,1,2,3,4}},{{0,1,2,3,4},{0,1,2,3,4},{0,1,2,3,4},{0,1,2,3,4},{0,1,2,3,4}}},{{{0,1,2,3,4},{0,1,2,3,4},{0,1,2,3,4},{0,1,2,3,4},{0,1,2,3,4}},{{0,1,2,3,4},{0,1,2,3,4},{0,1,2,3,4},{0,1,2,3,4},{0,1,2,3,4}},{{0,1,2,3,4},{0,1,2,3,4},{0,1,2,3,4},{0,1,2,3,4},{0,1,2,3,4}}}}
-(1 row)
-
-CREATE OR REPLACE FUNCTION pyreturnmultidemfloat4(h int4, i int4, j int4, k int4 ) RETURNS float4[] AS $BODY$
-m = [[[[x for x in range(h)] for y in range(i)] for z in range(j)] for w in range(k)]
-plpy.info(m, type(m))
-return m
-$BODY$ LANGUAGE plpython3u;
-select pyreturnmultidemfloat4(6,5,3,2);
-INFO: ([[[[0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5]], [[0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5]], [[0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5]]], [[[0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5]], [[0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5]], [[0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5]]]], <class 'list'>)
- pyreturnmultidemfloat4
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- {{{{0,1,2,3,4,5},{0,1,2,3,4,5},{0,1,2,3,4,5},{0,1,2,3,4,5},{0,1,2,3,4,5}},{{0,1,2,3,4,5},{0,1,2,3,4,5},{0,1,2,3,4,5},{0,1,2,3,4,5},{0,1,2,3,4,5}},{{0,1,2,3,4,5},{0,1,2,3,4,5},{0,1,2,3,4,5},{0,1,2,3,4,5},{0,1,2,3,4,5}}},{{{0,1,2,3,4,5},{0,1,2,3,4,5},{0,1,2,3,4,5},{0,1,2,3,4,5},{0,1,2,3,4,5}},{{0,1,2,3,4,5},{0,1,2,3,4,5},{0,1,2,3,4,5},{0,1,2,3,4,5},{0,1,2,3,4,5}},{{0,1,2,3,4,5},{0,1,2,3,4,5},{0,1,2,3,4,5},{0,1,2,3,4,5},{0,1,2,3,4,5}}}}
-(1 row)
-
-CREATE OR REPLACE FUNCTION pyreturnmultidemfloat8(h int4, i int4, j int4, k int4 ) RETURNS float8[] AS $BODY$
-m = [[[[x for x in range(h)] for y in range(i)] for z in range(j)] for w in range(k)]
-plpy.info(m, type(m))
-return m
-$BODY$ LANGUAGE plpython3u;
-select pyreturnmultidemfloat8(7,5,3,2);
-INFO: ([[[[0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6]], [[0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6]], [[0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6]]], [[[0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6]], [[0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6]], [[0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6]]]], <class 'list'>)
- pyreturnmultidemfloat8
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- {{{{0,1,2,3,4,5,6},{0,1,2,3,4,5,6},{0,1,2,3,4,5,6},{0,1,2,3,4,5,6},{0,1,2,3,4,5,6}},{{0,1,2,3,4,5,6},{0,1,2,3,4,5,6},{0,1,2,3,4,5,6},{0,1,2,3,4,5,6},{0,1,2,3,4,5,6}},{{0,1,2,3,4,5,6},{0,1,2,3,4,5,6},{0,1,2,3,4,5,6},{0,1,2,3,4,5,6},{0,1,2,3,4,5,6}}},{{{0,1,2,3,4,5,6},{0,1,2,3,4,5,6},{0,1,2,3,4,5,6},{0,1,2,3,4,5,6},{0,1,2,3,4,5,6}},{{0,1,2,3,4,5,6},{0,1,2,3,4,5,6},{0,1,2,3,4,5,6},{0,1,2,3,4,5,6},{0,1,2,3,4,5,6}},{{0,1,2,3,4,5,6},{0,1,2,3,4,5,6},{0,1,2,3,4,5,6},{0,1,2,3,4,5,6},{0,1,2,3,4,5,6}}}}
-(1 row)
-
-CREATE FUNCTION test_type_conversion_array_text(x text[]) RETURNS text[] AS $$
-plpy.info(x, type(x))
-return x
-$$ LANGUAGE plpython3u;
-SELECT * FROM test_type_conversion_array_text(ARRAY['foo', 'bar']);
-INFO: (['foo', 'bar'], <class 'list'>)
- test_type_conversion_array_text
----------------------------------
- {foo,bar}
-(1 row)
-
-SELECT * FROM test_type_conversion_array_text(ARRAY[['foo', 'bar'],['foo2', 'bar2']]);
-INFO: ([['foo', 'bar'], ['foo2', 'bar2']], <class 'list'>)
- test_type_conversion_array_text
----------------------------------
- {{foo,bar},{foo2,bar2}}
-(1 row)
-
-CREATE FUNCTION test_type_conversion_array_bytea(x bytea[]) RETURNS bytea[] AS $$
-plpy.info(x, type(x))
-return x
-$$ LANGUAGE plpython3u;
-SELECT * FROM test_type_conversion_array_bytea(ARRAY[E'\\xdeadbeef'::bytea, NULL]);
-INFO: ([b'\xde\xad\xbe\xef', None], <class 'list'>)
- test_type_conversion_array_bytea
-----------------------------------
- {"\\xdeadbeef",NULL}
-(1 row)
-
-CREATE FUNCTION test_type_conversion_array_mixed1() RETURNS text[] AS $$
-return [123, 'abc']
-$$ LANGUAGE plpython3u;
-SELECT * FROM test_type_conversion_array_mixed1();
- test_type_conversion_array_mixed1
------------------------------------
- {123,abc}
-(1 row)
-
-CREATE FUNCTION test_type_conversion_array_mixed2() RETURNS int[] AS $$
-return [123, 'abc']
-$$ LANGUAGE plpython3u;
-SELECT * FROM test_type_conversion_array_mixed2();
-ERROR: invalid input syntax for type integer: "abc"
-CONTEXT: while creating return value
-PL/Python function "test_type_conversion_array_mixed2"
-CREATE FUNCTION test_type_conversion_mdarray_malformed() RETURNS int[] AS $$
-return [[1,2,3],[4,5]]
-$$ LANGUAGE plpython3u;
-SELECT * FROM test_type_conversion_mdarray_malformed();
-ERROR: wrong length of inner sequence: has length 2, but 3 was expected
-DETAIL: To construct a multidimensional array, the inner sequences must all have the same length.
-CONTEXT: while creating return value
-PL/Python function "test_type_conversion_mdarray_malformed"
-CREATE FUNCTION test_type_conversion_mdarray_toodeep() RETURNS int[] AS $$
-return [[[[[[[1]]]]]]]
-$$ LANGUAGE plpython3u;
-SELECT * FROM test_type_conversion_mdarray_toodeep();
-ERROR: number of array dimensions exceeds the maximum allowed (6)
-CONTEXT: while creating return value
-PL/Python function "test_type_conversion_mdarray_toodeep"
-CREATE FUNCTION test_type_conversion_array_record() RETURNS type_record[] AS $$
-return [{'first': 'one', 'second': 42}, {'first': 'two', 'second': 11}]
-$$ LANGUAGE plpython3u;
-SELECT * FROM test_type_conversion_array_record();
- test_type_conversion_array_record
------------------------------------
- {"(one,42)","(two,11)"}
-(1 row)
-
-CREATE FUNCTION test_type_conversion_array_string() RETURNS text[] AS $$
-return 'abc'
-$$ LANGUAGE plpython3u;
-SELECT * FROM test_type_conversion_array_string();
- test_type_conversion_array_string
------------------------------------
- {a,b,c}
-(1 row)
-
-CREATE FUNCTION test_type_conversion_array_tuple() RETURNS text[] AS $$
-return ('abc', 'def')
-$$ LANGUAGE plpython3u;
-SELECT * FROM test_type_conversion_array_tuple();
- test_type_conversion_array_tuple
-----------------------------------
- {abc,def}
-(1 row)
-
-CREATE FUNCTION test_type_conversion_array_error() RETURNS int[] AS $$
-return 5
-$$ LANGUAGE plpython3u;
-SELECT * FROM test_type_conversion_array_error();
-ERROR: return value of function with array return type is not a Python sequence
-CONTEXT: while creating return value
-PL/Python function "test_type_conversion_array_error"
---
--- Domains over arrays
---
-CREATE DOMAIN ordered_pair_domain AS integer[] CHECK (array_length(VALUE,1)=2 AND VALUE[1] < VALUE[2]);
-CREATE FUNCTION test_type_conversion_array_domain(x ordered_pair_domain) RETURNS ordered_pair_domain AS $$
-plpy.info(x, type(x))
-return x
-$$ LANGUAGE plpython3u;
-SELECT * FROM test_type_conversion_array_domain(ARRAY[0, 100]::ordered_pair_domain);
-INFO: ([0, 100], <class 'list'>)
- test_type_conversion_array_domain
------------------------------------
- {0,100}
-(1 row)
-
-SELECT * FROM test_type_conversion_array_domain(NULL::ordered_pair_domain);
-INFO: (None, <class 'NoneType'>)
- test_type_conversion_array_domain
------------------------------------
-
-(1 row)
-
-CREATE FUNCTION test_type_conversion_array_domain_check_violation() RETURNS ordered_pair_domain AS $$
-return [2,1]
-$$ LANGUAGE plpython3u;
-SELECT * FROM test_type_conversion_array_domain_check_violation();
-ERROR: value for domain ordered_pair_domain violates check constraint "ordered_pair_domain_check"
-CONTEXT: while creating return value
-PL/Python function "test_type_conversion_array_domain_check_violation"
---
--- Arrays of domains
---
-CREATE FUNCTION test_read_uint2_array(x uint2[]) RETURNS uint2 AS $$
-plpy.info(x, type(x))
-return x[0]
-$$ LANGUAGE plpythonu;
-select test_read_uint2_array(array[1::uint2]);
-INFO: ([1], <class 'list'>)
- test_read_uint2_array
------------------------
- 1
-(1 row)
-
-CREATE FUNCTION test_build_uint2_array(x int2) RETURNS uint2[] AS $$
-return [x, x]
-$$ LANGUAGE plpythonu;
-select test_build_uint2_array(1::int2);
- test_build_uint2_array
-------------------------
- {1,1}
-(1 row)
-
-select test_build_uint2_array(-1::int2); -- fail
-ERROR: value for domain uint2 violates check constraint "uint2_check"
-CONTEXT: while creating return value
-PL/Python function "test_build_uint2_array"
---
--- ideally this would work, but for now it doesn't, because the return value
--- is [[2,4], [2,4]] which our conversion code thinks should become a 2-D
--- integer array, not an array of arrays.
---
-CREATE FUNCTION test_type_conversion_domain_array(x integer[])
- RETURNS ordered_pair_domain[] AS $$
-return [x, x]
-$$ LANGUAGE plpythonu;
-select test_type_conversion_domain_array(array[2,4]);
-ERROR: return value of function with array return type is not a Python sequence
-CONTEXT: while creating return value
-PL/Python function "test_type_conversion_domain_array"
-select test_type_conversion_domain_array(array[4,2]); -- fail
-ERROR: return value of function with array return type is not a Python sequence
-CONTEXT: while creating return value
-PL/Python function "test_type_conversion_domain_array"
-CREATE FUNCTION test_type_conversion_domain_array2(x ordered_pair_domain)
- RETURNS integer AS $$
-plpy.info(x, type(x))
-return x[1]
-$$ LANGUAGE plpythonu;
-select test_type_conversion_domain_array2(array[2,4]);
-INFO: ([2, 4], <class 'list'>)
- test_type_conversion_domain_array2
-------------------------------------
- 4
-(1 row)
-
-select test_type_conversion_domain_array2(array[4,2]); -- fail
-ERROR: value for domain ordered_pair_domain violates check constraint "ordered_pair_domain_check"
-CREATE FUNCTION test_type_conversion_array_domain_array(x ordered_pair_domain[])
- RETURNS ordered_pair_domain AS $$
-plpy.info(x, type(x))
-return x[0]
-$$ LANGUAGE plpythonu;
-select test_type_conversion_array_domain_array(array[array[2,4]::ordered_pair_domain]);
-INFO: ([[2, 4]], <class 'list'>)
- test_type_conversion_array_domain_array
------------------------------------------
- {2,4}
-(1 row)
-
----
---- Composite types
----
-CREATE TABLE employee (
- name text,
- basesalary integer,
- bonus integer
-);
-INSERT INTO employee VALUES ('John', 100, 10), ('Mary', 200, 10);
-CREATE OR REPLACE FUNCTION test_composite_table_input(e employee) RETURNS integer AS $$
-return e['basesalary'] + e['bonus']
-$$ LANGUAGE plpython3u;
-SELECT name, test_composite_table_input(employee.*) FROM employee;
- name | test_composite_table_input
-------+----------------------------
- John | 110
- Mary | 210
-(2 rows)
-
-ALTER TABLE employee DROP bonus;
-SELECT name, test_composite_table_input(employee.*) FROM employee;
-ERROR: KeyError: 'bonus'
-CONTEXT: Traceback (most recent call last):
- PL/Python function "test_composite_table_input", line 2, in <module>
- return e['basesalary'] + e['bonus']
-PL/Python function "test_composite_table_input"
-ALTER TABLE employee ADD bonus integer;
-UPDATE employee SET bonus = 10;
-SELECT name, test_composite_table_input(employee.*) FROM employee;
- name | test_composite_table_input
-------+----------------------------
- John | 110
- Mary | 210
-(2 rows)
-
-CREATE TYPE named_pair AS (
- i integer,
- j integer
-);
-CREATE OR REPLACE FUNCTION test_composite_type_input(p named_pair) RETURNS integer AS $$
-return sum(p.values())
-$$ LANGUAGE plpython3u;
-SELECT test_composite_type_input(row(1, 2));
- test_composite_type_input
----------------------------
- 3
-(1 row)
-
-ALTER TYPE named_pair RENAME TO named_pair_2;
-SELECT test_composite_type_input(row(1, 2));
- test_composite_type_input
----------------------------
- 3
-(1 row)
-
---
--- Domains within composite
---
-CREATE TYPE nnint_container AS (f1 int, f2 nnint);
-CREATE FUNCTION nnint_test(x int, y int) RETURNS nnint_container AS $$
-return {'f1': x, 'f2': y}
-$$ LANGUAGE plpythonu;
-SELECT nnint_test(null, 3);
- nnint_test
-------------
- (,3)
-(1 row)
-
-SELECT nnint_test(3, null); -- fail
-ERROR: value for domain nnint violates check constraint "nnint_check"
-CONTEXT: while creating return value
-PL/Python function "nnint_test"
---
--- Domains of composite
---
-CREATE DOMAIN ordered_named_pair AS named_pair_2 CHECK((VALUE).i <= (VALUE).j);
-CREATE FUNCTION read_ordered_named_pair(p ordered_named_pair) RETURNS integer AS $$
-return p['i'] + p['j']
-$$ LANGUAGE plpythonu;
-SELECT read_ordered_named_pair(row(1, 2));
- read_ordered_named_pair
--------------------------
- 3
-(1 row)
-
-SELECT read_ordered_named_pair(row(2, 1)); -- fail
-ERROR: value for domain ordered_named_pair violates check constraint "ordered_named_pair_check"
-CREATE FUNCTION build_ordered_named_pair(i int, j int) RETURNS ordered_named_pair AS $$
-return {'i': i, 'j': j}
-$$ LANGUAGE plpythonu;
-SELECT build_ordered_named_pair(1,2);
- build_ordered_named_pair
---------------------------
- (1,2)
-(1 row)
-
-SELECT build_ordered_named_pair(2,1); -- fail
-ERROR: value for domain ordered_named_pair violates check constraint "ordered_named_pair_check"
-CONTEXT: while creating return value
-PL/Python function "build_ordered_named_pair"
-CREATE FUNCTION build_ordered_named_pairs(i int, j int) RETURNS ordered_named_pair[] AS $$
-return [{'i': i, 'j': j}, {'i': i, 'j': j+1}]
-$$ LANGUAGE plpythonu;
-SELECT build_ordered_named_pairs(1,2);
- build_ordered_named_pairs
----------------------------
- {"(1,2)","(1,3)"}
-(1 row)
-
-SELECT build_ordered_named_pairs(2,1); -- fail
-ERROR: value for domain ordered_named_pair violates check constraint "ordered_named_pair_check"
-CONTEXT: while creating return value
-PL/Python function "build_ordered_named_pairs"
---
--- Prepared statements
---
-CREATE OR REPLACE FUNCTION test_prep_bool_input() RETURNS int
-LANGUAGE plpython3u
-AS $$
-plan = plpy.prepare("SELECT CASE WHEN $1 THEN 1 ELSE 0 END AS val", ['boolean'])
-rv = plpy.execute(plan, ['fa'], 5) # 'fa' is true in Python
-return rv[0]['val']
-$$;
-SELECT test_prep_bool_input(); -- 1
- test_prep_bool_input
-----------------------
- 1
-(1 row)
-
-CREATE OR REPLACE FUNCTION test_prep_bool_output() RETURNS bool
-LANGUAGE plpython3u
-AS $$
-plan = plpy.prepare("SELECT $1 = 1 AS val", ['int'])
-rv = plpy.execute(plan, [0], 5)
-plpy.info(rv[0])
-return rv[0]['val']
-$$;
-SELECT test_prep_bool_output(); -- false
-INFO: {'val': False}
- test_prep_bool_output
------------------------
- f
-(1 row)
-
-CREATE OR REPLACE FUNCTION test_prep_bytea_input(bb bytea) RETURNS int
-LANGUAGE plpython3u
-AS $$
-plan = plpy.prepare("SELECT octet_length($1) AS val", ['bytea'])
-rv = plpy.execute(plan, [bb], 5)
-return rv[0]['val']
-$$;
-SELECT test_prep_bytea_input(E'a\\000b'); -- 3 (embedded null formerly truncated value)
- test_prep_bytea_input
------------------------
- 3
-(1 row)
-
-CREATE OR REPLACE FUNCTION test_prep_bytea_output() RETURNS bytea
-LANGUAGE plpython3u
-AS $$
-plan = plpy.prepare("SELECT decode('aa00bb', 'hex') AS val")
-rv = plpy.execute(plan, [], 5)
-plpy.info(rv[0])
-return rv[0]['val']
-$$;
-SELECT test_prep_bytea_output();
-INFO: {'val': b'\xaa\x00\xbb'}
- test_prep_bytea_output
-------------------------
- \xaa00bb
-(1 row)
-
testvalue text NOT NULL
);
CREATE FUNCTION unicode_return() RETURNS text AS E'
-return u"\\xA0"
-' LANGUAGE plpythonu;
+return "\\xA0"
+' LANGUAGE plpython3u;
CREATE FUNCTION unicode_trigger() RETURNS trigger AS E'
-TD["new"]["testvalue"] = u"\\xA0"
+TD["new"]["testvalue"] = "\\xA0"
return "MODIFY"
-' LANGUAGE plpythonu;
+' LANGUAGE plpython3u;
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"\\xA0"], 1)
+rv = plpy.execute(plan, ["\\xA0"], 1)
return rv[0]["testvalue"]
-' LANGUAGE plpythonu;
+' LANGUAGE plpython3u;
CREATE FUNCTION unicode_plan2() RETURNS text AS E'
-plan = plpy.prepare("SELECT $1 || $2 AS testvalue", ["text", u"text"])
+plan = plpy.prepare("SELECT $1 || $2 AS testvalue", ["text", "text"])
rv = plpy.execute(plan, ["foo", "bar"], 1)
return rv[0]["testvalue"]
-' LANGUAGE plpythonu;
+' LANGUAGE plpython3u;
SELECT unicode_return();
unicode_return
----------------
--
CREATE FUNCTION test_void_func1() RETURNS void AS $$
x = 10
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
-- illegal: can't return non-None value in void-returning func
CREATE FUNCTION test_void_func2() RETURNS void AS $$
return 10
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION test_return_none() RETURNS int AS $$
None
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
-- Tests for functions returning void
SELECT test_void_func1(), test_void_func1() IS NULL AS "is null";
test_void_func1 | is null
+++ /dev/null
-ifeq ($(python_majorversion),3)
-# Adjust regression tests for Python 3 compatibility
-#
-# Mention those regression test files that need to be mangled in the
-# variable REGRESS_PLPYTHON3_MANGLE. They will be copied to a
-# subdirectory python3/ and have their Python syntax and other bits
-# adjusted to work with Python 3.
-
-# Note that the order of the tests needs to be preserved in this
-# expression.
-REGRESS := $(foreach test,$(REGRESS),$(if $(filter $(test),$(REGRESS_PLPYTHON3_MANGLE)),python3/$(test),$(test)))
-
-.PHONY: pgregress-python3-mangle
-pgregress-python3-mangle:
- $(MKDIR_P) sql/python3 expected/python3 results/python3
- for file in $(patsubst %,$(srcdir)/sql/%.sql,$(REGRESS_PLPYTHON3_MANGLE)) $(patsubst %,$(srcdir)/expected/%*.out,$(REGRESS_PLPYTHON3_MANGLE)); do \
- sed \
- -e "s/<type 'exceptions\.\([[:alpha:]]*\)'>/<class '\1'>/g" \
- -e "s/<type 'long'>/<class 'int'>/g" \
- -e "s/\([0-9][0-9]*\)L/\1/g" \
- -e 's/\([ [{]\)u"/\1"/g' \
- -e "s/\([ [{]\)u'/\1'/g" \
- -e "s/def next/def __next__/g" \
- -e "s/LANGUAGE plpythonu/LANGUAGE plpython3u/g" \
- -e "s/LANGUAGE plpython2u/LANGUAGE plpython3u/g" \
- -e "s/EXTENSION plpythonu/EXTENSION plpython3u/g" \
- -e "s/EXTENSION plpython2u/EXTENSION plpython3u/g" \
- -e "s/EXTENSION \([^ ]*\)_plpythonu/EXTENSION \1_plpython3u/g" \
- -e "s/EXTENSION \([^ ]*\)_plpython2u/EXTENSION \1_plpython3u/g" \
- -e 's/installing required extension "plpython2u"/installing required extension "plpython3u"/g' \
- $$file >`echo $$file | sed 's,^.*/\([^/][^/]*/\)\([^/][^/]*\)$$,\1python3/\2,'` || exit; \
- done
-
-check installcheck: pgregress-python3-mangle
-
-pg_regress_clean_files += sql/python3/ expected/python3/ results/python3/
-
-endif # Python 3
--
CREATE PROCEDURE test_proc1()
-LANGUAGE plpythonu
+LANGUAGE plpython3u
AS $$
pass
$$;
-- error: can't return non-None
CREATE PROCEDURE test_proc2()
-LANGUAGE plpythonu
+LANGUAGE plpython3u
AS $$
return 5
$$;
CREATE TABLE test1 (a int);
CREATE PROCEDURE test_proc3(x int)
-LANGUAGE plpythonu
+LANGUAGE plpython3u
AS $$
plpy.execute("INSERT INTO test1 VALUES (%s)" % x)
$$;
-- output arguments
CREATE PROCEDURE test_proc5(INOUT a text)
-LANGUAGE plpythonu
+LANGUAGE plpython3u
AS $$
return [a + '+' + a]
$$;
CREATE PROCEDURE test_proc6(a int, INOUT b int, INOUT c int)
-LANGUAGE plpythonu
+LANGUAGE plpython3u
AS $$
return (b * a, c * a)
$$;
-- OUT parameters
CREATE PROCEDURE test_proc9(IN a int, OUT b int)
-LANGUAGE plpythonu
+LANGUAGE plpython3u
AS $$
plpy.notice("a: %s" % (a))
return (a * 2,)
CREATE FUNCTION multiout_simple(OUT i integer, OUT j integer) AS $$
return (1, 2)
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT multiout_simple();
SELECT * FROM multiout_simple();
CREATE FUNCTION multiout_simple_setof(n integer = 1, OUT integer, OUT integer) RETURNS SETOF record AS $$
return [(1, 2)] * n
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT multiout_simple_setof();
SELECT * FROM multiout_simple_setof();
return type_record
elif typ == 'str':
return "('%s',%r)" % (first, second)
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM multiout_record_as('dict', 'foo', 1, 'f');
SELECT multiout_record_as('dict', 'foo', 1, 'f');
power = 2 ** i
length = plpy.execute("select length('%d')" % power)[0]['length']
yield power, length
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM multiout_setof(3);
SELECT multiout_setof(5);
return [{'x': 4, 'y' :'four'},
{'x': 7, 'y' :'seven'},
{'x': 0, 'y' :'zero'}]
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM multiout_return_table();
yield [[1], 'a']
yield [[1,2], 'b']
yield [[1,2,3], None]
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM multiout_array();
CREATE FUNCTION singleout_composite(OUT type_record) AS $$
return {'first': 1, 'second': 2}
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION multiout_composite(OUT type_record) RETURNS SETOF type_record AS $$
return [{'first': 1, 'second': 2},
{'first': 3, 'second': 4 }]
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM singleout_composite();
SELECT * FROM multiout_composite();
-- composite OUT parameters in functions returning RECORD not supported yet
CREATE FUNCTION multiout_composite(INOUT n integer, OUT type_record) AS $$
return (n, (n * 2, n * 3))
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION multiout_table_type_setof(typ text, returnnull boolean, INOUT n integer, OUT table_record) RETURNS SETOF record AS $$
if returnnull:
d = "(%r,%r)" % (n * 2, n * 3)
for i in range(n):
yield (i, d)
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM multiout_composite(2);
SELECT * FROM multiout_table_type_setof('dict', 'f', 3);
CREATE FUNCTION changing_test(OUT n integer, OUT changing) RETURNS SETOF record AS $$
return [(1, {'i': 1, 'j': 2}),
(1, (3, 4))]
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM changing_test();
ALTER TABLE changing DROP COLUMN j;
yield {'tab': [('first', 1), ('second', 2)],
'typ': [{'first': 'third', 'second': 3},
{'first': 'fourth', 'second': 4}]}
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM composite_types_table();
-- check what happens if the output record descriptor changes
CREATE FUNCTION return_record(t text) RETURNS record AS $$
return {'t': t, 'val': 10}
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM return_record('abc') AS r(t text, val integer);
SELECT * FROM return_record('abc') AS r(t text, val bigint);
CREATE FUNCTION return_record_2(t text) RETURNS record AS $$
return {'v1':1,'v2':2,t:3}
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM return_record_2('v3') AS (v3 int, v2 int, v1 int);
SELECT * FROM return_record_2('v3') AS (v2 int, v3 int, v1 int);
-- multi-dimensional array of composite types.
CREATE FUNCTION composite_type_as_list() RETURNS type_record[] AS $$
return [[('first', 1), ('second', 1)], [('first', 2), ('second', 2)], [('first', 3), ('second', 3)]];
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM composite_type_as_list();
-- Starting with PostgreSQL 10, a composite type in an array cannot be
-- on the issue.
CREATE FUNCTION composite_type_as_list_broken() RETURNS type_record[] AS $$
return [['first', 1]];
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM composite_type_as_list_broken();
-DO $$ plpy.notice("This is plpythonu.") $$ LANGUAGE plpythonu;
+DO $$ plpy.notice("This is plpython3u.") $$ LANGUAGE plpython3u;
-DO $$ plpy.notice("This is plpython2u.") $$ LANGUAGE plpython2u;
-
-DO $$ raise Exception("error test") $$ LANGUAGE plpythonu;
+DO $$ raise Exception("error test") $$ LANGUAGE plpython3u;
--
SET client_min_messages = WARNING;
-DROP EXTENSION plpythonu CASCADE;
-
-DROP EXTENSION IF EXISTS plpython2u CASCADE;
+DROP EXTENSION plpython3u CASCADE;
plpy.notice('notice', detail='some detail')
plpy.warning('warning', detail='some detail')
plpy.error('stop on error', detail='some detail', hint='some hint')
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT elog_test();
-DO $$ plpy.info('other types', detail=(10, 20)) $$ LANGUAGE plpythonu;
+DO $$ plpy.info('other types', detail=(10, 20)) $$ LANGUAGE plpython3u;
DO $$
import time;
from datetime import date
plpy.info('other types', detail=date(2016, 2, 26))
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
DO $$
basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
plpy.info('other types', detail=basket)
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
-- should fail
-DO $$ plpy.info('wrong sqlstate', sqlstate='54444A') $$ LANGUAGE plpythonu;
-DO $$ plpy.info('unsupported argument', blabla='fooboo') $$ LANGUAGE plpythonu;
-DO $$ plpy.info('first message', message='second message') $$ LANGUAGE plpythonu;
-DO $$ plpy.info('first message', 'second message', message='third message') $$ LANGUAGE plpythonu;
+DO $$ plpy.info('wrong sqlstate', sqlstate='54444A') $$ LANGUAGE plpython3u;
+DO $$ plpy.info('unsupported argument', blabla='fooboo') $$ LANGUAGE plpython3u;
+DO $$ plpy.info('first message', message='second message') $$ LANGUAGE plpython3u;
+DO $$ plpy.info('first message', 'second message', message='third message') $$ LANGUAGE plpython3u;
-- raise exception in python, handle exception in plgsql
CREATE OR REPLACE FUNCTION raise_exception(_message text, _detail text DEFAULT NULL, _hint text DEFAULT NULL,
}
# ignore None values
plpy.error(**dict((k, v) for k, v in iter(kwargs.items()) if v))
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT raise_exception('hello', 'world');
SELECT raise_exception('message text', 'detail text', _sqlstate => 'YY333');
END;
$$;
--- The displayed context is different between Python2 and Python3,
--- but that's not important for this test.
-\set SHOW_CONTEXT never
-
DO $$
try:
plpy.execute("select raise_exception(_message => 'my message', _sqlstate => 'XX987', _hint => 'some hint', _table_name => 'users_tab', _datatype_name => 'user_type')")
except Exception as e:
plpy.info(e.spidata)
raise e
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
DO $$
try:
except Exception as e:
plpy.info('sqlstate: %s, hint: %s, table_name: %s, datatype_name: %s' % (e.sqlstate, e.hint, e.table_name, e.datatype_name))
raise e
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION python_syntax_error() RETURNS text
AS
'.syntaxerror'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
/* With check_function_bodies = false the function should get defined
* and the error reported when called
CREATE FUNCTION python_syntax_error() RETURNS text
AS
'.syntaxerror'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
SELECT python_syntax_error();
/* Run the function twice to check if the hashtable entry gets cleaned up */
CREATE FUNCTION sql_syntax_error() RETURNS text
AS
'plpy.execute("syntax error")'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
SELECT sql_syntax_error();
CREATE FUNCTION exception_index_invalid(text) RETURNS text
AS
'return args[1]'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
SELECT exception_index_invalid('test');
AS
'rv = plpy.execute("SELECT test5(''foo'')")
return rv[0]'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
SELECT exception_index_invalid_nested();
return rv[0]["fname"]
return None
'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
SELECT invalid_type_uncaught('rick');
return rv[0]["fname"]
return None
'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
SELECT invalid_type_caught('rick');
return rv[0]["fname"]
return None
'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
SELECT invalid_type_reraised('rick');
return rv[0]["fname"]
return None
'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
SELECT valid_type('rick');
fun3()
return "not reached"
'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
SELECT nested_error();
fun3()
return "not reached"
'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
SELECT nested_error_raise();
fun3()
return "you''ve been warned"
'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
SELECT nested_warning();
CREATE FUNCTION toplevel_attribute_error() RETURNS void AS
$$
plpy.nonexistent
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT toplevel_attribute_error();
plpy.execute("select sql_error()")
first()
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE OR REPLACE FUNCTION sql_error() RETURNS void AS $$
begin
CREATE OR REPLACE FUNCTION sql_from_python_error() RETURNS void AS $$
plpy.execute("select sql_error()")
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT python_traceback();
SELECT sql_error();
plpy.notice("Violated the NOT NULL constraint, sqlstate %s" % e.sqlstate)
except spiexceptions.UniqueViolation as e:
plpy.notice("Violated the UNIQUE constraint, sqlstate %s" % e.sqlstate)
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT specific_exception(2);
SELECT specific_exception(NULL);
CREATE FUNCTION python_unique_violation() RETURNS void AS $$
plpy.execute("insert into specific values (1)")
plpy.execute("insert into specific values (1)")
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION catch_python_unique_violation() RETURNS text AS $$
begin
plpy.execute("savepoint save")
plpy.execute("create table foo(x integer)")
plpy.execute("rollback to save")
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT manual_subxact();
plpy.execute(save)
plpy.execute("create table foo(x integer)")
plpy.execute(rollback)
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT manual_subxact_prepared();
*/
CREATE FUNCTION plpy_raise_spiexception() RETURNS void AS $$
raise plpy.spiexceptions.DivisionByZero()
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
DO $$
BEGIN
exc = plpy.spiexceptions.DivisionByZero()
exc.sqlstate = 'SILLY'
raise exc
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
DO $$
BEGIN
/* test the context stack trace for nested execution levels
*/
CREATE FUNCTION notice_innerfunc() RETURNS int AS $$
-plpy.execute("DO LANGUAGE plpythonu $x$ plpy.notice('inside DO') $x$")
+plpy.execute("DO LANGUAGE plpython3u $x$ plpy.notice('inside DO') $x$")
return 1
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION notice_outerfunc() RETURNS int AS $$
plpy.execute("SELECT notice_innerfunc()")
return 1
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
\set SHOW_CONTEXT always
if "global_test" not in GD:
GD["global_test"] = "set by global_test_one"
return "SD: " + SD["global_test"] + ", GD: " + GD["global_test"]'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
CREATE FUNCTION global_test_two() returns text
AS
if "global_test" not in GD:
GD["global_test"] = "set by global_test_two"
return "SD: " + SD["global_test"] + ", GD: " + GD["global_test"]'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
CREATE FUNCTION static_test() returns int4
SD["call"] = 1
return SD["call"]
'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
SELECT static_test();
except ImportError:
return "failed as expected"
return "succeeded, that wasn''t supposed to happen"'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
CREATE FUNCTION import_succeed() returns text
plpy.notice("import failed -- %s" % str(ex))
return "failed, that wasn''t supposed to happen"
return "succeeded, as expected"'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
CREATE FUNCTION import_test_one(p text) RETURNS text
AS
import sha
digest = sha.new(p)
return digest.hexdigest()'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
CREATE FUNCTION import_test_two(u users) RETURNS text
AS
import sha
digest = sha.new(plain);
return "sha hash of " + plain + " is " + digest.hexdigest()'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
-- import python modules
CREATE OR REPLACE FUNCTION newline_lf() RETURNS integer AS
E'x = 100\ny = 23\nreturn x + y\n'
-LANGUAGE plpythonu;
+LANGUAGE plpython3u;
CREATE OR REPLACE FUNCTION newline_cr() RETURNS integer AS
E'x = 100\ry = 23\rreturn x + y\r'
-LANGUAGE plpythonu;
+LANGUAGE plpython3u;
CREATE OR REPLACE FUNCTION newline_crlf() RETURNS integer AS
E'x = 100\r\ny = 23\r\nreturn x + y\r\n'
-LANGUAGE plpythonu;
+LANGUAGE plpython3u;
SELECT newline_lf();
CREATE FUNCTION test_param_names0(integer, integer) RETURNS int AS $$
return args[0] + args[1]
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION test_param_names1(a0 integer, a1 text) RETURNS boolean AS $$
assert a0 == args[0]
assert a1 == args[1]
return True
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION test_param_names2(u users) RETURNS text AS $$
assert u == args[0]
else:
s = str(u)
return s
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
-- use deliberately wrong parameter names
CREATE FUNCTION test_param_names3(a0 integer) RETURNS boolean AS $$
except NameError as e:
assert e.args[0].find("a1") > -1
return True
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT test_param_names0(2,7);
return plpy.quote_ident(t)
else:
raise plpy.Error("unrecognized quote type %s" % how)
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT quote(t, 'literal') FROM (VALUES
('abc'),
type_record.first = first
type_record.second = second
return type_record
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION test_type_record_as(typ text, first text, second integer, retnull boolean) RETURNS type_record AS $$
if retnull:
return type_record
elif typ == 'str':
return "('%s',%r)" % (first, second)
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION test_in_out_params(first in text, second out text) AS $$
return first + '_in_to_out';
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION test_in_out_params_multi(first in text,
second out text, third out text) AS $$
return (first + '_record_in_to_out_1', first + '_record_in_to_out_2');
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION test_inout_params(first inout text) AS $$
return first + '_inout';
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
-- Test tuple returning functions
CREATE FUNCTION test_type_record_error1() RETURNS type_record AS $$
return { 'first': 'first' }
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_record_error1();
CREATE FUNCTION test_type_record_error2() RETURNS type_record AS $$
return [ 'first' ]
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_record_error2();
class type_record: pass
type_record.first = 'first'
return type_record
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_record_error3();
CREATE FUNCTION test_type_record_error4() RETURNS type_record AS $$
return 'foo'
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_record_error4();
CREATE FUNCTION test_setof_error() RETURNS SETOF text AS $$
return 37
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT test_setof_error();
CREATE FUNCTION test_setof_as_list(count integer, content text) RETURNS SETOF text AS $$
return [ content ]*count
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION test_setof_as_tuple(count integer, content text) RETURNS SETOF text AS $$
t = ()
for i in range(count):
t += ( content, )
return t
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION test_setof_as_iterator(count integer, content text) RETURNS SETOF text AS $$
class producer:
self.icount = icount
def __iter__ (self):
return self
- def next (self):
+ def __next__ (self):
if self.icount == 0:
raise StopIteration
self.icount -= 1
return self.icontent
return producer(count, content)
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION test_setof_spi_in_iterator() RETURNS SETOF text AS
$$
yield s
plpy.execute('select 2')
$$
-LANGUAGE plpythonu;
+LANGUAGE plpython3u;
-- Test set returning functions
while x <= lim:
yield x
x = x + 1
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT ugly(1, 5);
RETURNS SETOF users
AS $$
return plpy.execute("SELECT * FROM users ORDER BY username")
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT get_user_records();
SELECT * FROM get_user_records();
RETURNS TABLE(fname text, lname text, username text, userid int)
AS $$
return plpy.execute("SELECT * FROM users ORDER BY username")
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT get_user_records2();
SELECT * FROM get_user_records2();
'q = "SELECT nested_call_two(''%s'')" % a
r = plpy.execute(q)
return r[0]'
- LANGUAGE plpythonu ;
+ LANGUAGE plpython3u ;
CREATE FUNCTION nested_call_two(a text) RETURNS text
AS
'q = "SELECT nested_call_three(''%s'')" % a
r = plpy.execute(q)
return r[0]'
- LANGUAGE plpythonu ;
+ LANGUAGE plpython3u ;
CREATE FUNCTION nested_call_three(a text) RETURNS text
AS
'return a'
- LANGUAGE plpythonu ;
+ LANGUAGE plpython3u ;
-- some spi stuff
plpy.error(str(ex))
return None
'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
CREATE FUNCTION spi_prepared_plan_test_two(a text) RETURNS text
AS
plpy.error(str(ex))
return None
'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
CREATE FUNCTION spi_prepared_plan_test_nested(a text) RETURNS text
AS
plpy.error(str(ex))
return None
'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
CREATE FUNCTION join_sequences(s sequences) RETURNS text
AS
seq = seq + r["sequence"]
return seq
'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
CREATE FUNCTION spi_recursive_sum(a int) RETURNS int
AS
r = plpy.execute("SELECT spi_recursive_sum(%d) as a" % (a-1))[0]["a"]
return a + r
'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
--
-- spi and nested calls
return result.nrows()
else:
return None
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT result_metadata_test($$SELECT 1 AS foo, '11'::text AS bar UNION SELECT 2, '22'$$);
SELECT result_metadata_test($$CREATE TEMPORARY TABLE foo1 (a int, b text)$$);
AS $$
result = plpy.execute(cmd)
return result.nrows()
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT result_nrows_test($$SELECT 1$$);
SELECT result_nrows_test($$CREATE TEMPORARY TABLE foo2 (a int, b text)$$);
AS $$
result = plpy.execute(cmd)
return len(result)
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT result_len_test($$SELECT 1$$);
SELECT result_len_test($$CREATE TEMPORARY TABLE foo3 (a int, b text)$$);
result[:2] = [{'c': 10}, {'c': 100}]
plpy.info([item['c'] for item in result[:]])
-# raises TypeError, but the message differs on Python 2.6, so silence it
+# raises TypeError, catch so further tests could be added
try:
plpy.info(result['foo'])
except TypeError:
else:
assert False, "TypeError not raised"
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT result_subscript_test();
plpy.info(result[:])
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT result_empty_test();
plan = plpy.prepare(cmd)
result = plpy.execute(plan)
return str(result)
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT result_str_test($$SELECT 1 AS foo UNION SELECT 2$$);
SELECT result_str_test($$CREATE TEMPORARY TABLE foo1 (a int, b text)$$);
if row['lname'] == 'doe':
does += 1
return does
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION double_cursor_close() RETURNS int AS $$
res = plpy.cursor("select fname, lname from users")
res.close()
res.close()
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION cursor_fetch() RETURNS int AS $$
res = plpy.cursor("select fname, lname from users")
pass
else:
assert False, "StopIteration not raised"
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION cursor_mix_next_and_fetch() RETURNS int AS $$
res = plpy.cursor("select fname, lname from users order by fname")
assert item['fname'] == 'rick'
assert len(res.fetch(2)) == 1
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION fetch_after_close() RETURNS int AS $$
res = plpy.cursor("select fname, lname from users")
pass
else:
assert False, "ValueError not raised"
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION next_after_close() RETURNS int AS $$
res = plpy.cursor("select fname, lname from users")
pass
else:
assert False, "ValueError not raised"
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION cursor_fetch_next_empty() RETURNS int AS $$
res = plpy.cursor("select fname, lname from users where false")
pass
else:
assert False, "StopIteration not raised"
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION cursor_plan() RETURNS SETOF text AS $$
plan = plpy.prepare(
yield row['fname']
for row in plan.cursor(["j"]):
yield row['fname']
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION cursor_plan_wrong_args() RETURNS SETOF text AS $$
plan = plpy.prepare("select fname, lname from users where fname like $1 || '%'",
["text"])
c = plpy.cursor(plan, ["a", "b"])
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE TYPE test_composite_type AS (
a1 int,
plan = plpy.prepare("select $1 as c1", ["test_composite_type"])
res = plpy.execute(plan, [{"a1": 3, "a2": "label"}])
return res[0]["c1"]
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT simple_cursor_test();
SELECT double_cursor_close();
plpy.execute("INSERT INTO subtransaction_tbl VALUES ('oops')")
elif what_error == "Python":
raise Exception("Python exception")
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT subtransaction_ctx_test();
SELECT * FROM subtransaction_tbl;
raise
plpy.notice("Swallowed %s(%r)" % (e.__class__.__name__, e.args[0]))
return "ok"
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT subtransaction_nested_test();
SELECT * FROM subtransaction_tbl;
plpy.execute("INSERT INTO subtransaction_tbl VALUES (2)")
plpy.execute("SELECT subtransaction_nested_test('t')")
return "ok"
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT subtransaction_deeply_nested_test();
SELECT * FROM subtransaction_tbl;
CREATE FUNCTION subtransaction_exit_without_enter() RETURNS void
AS $$
plpy.subtransaction().__exit__(None, None, None)
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION subtransaction_enter_without_exit() RETURNS void
AS $$
plpy.subtransaction().__enter__()
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION subtransaction_exit_twice() RETURNS void
AS $$
plpy.subtransaction().__enter__()
plpy.subtransaction().__exit__(None, None, None)
plpy.subtransaction().__exit__(None, None, None)
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION subtransaction_enter_twice() RETURNS void
AS $$
plpy.subtransaction().__enter__()
plpy.subtransaction().__enter__()
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION subtransaction_exit_same_subtransaction_twice() RETURNS void
AS $$
s.__enter__()
s.__exit__(None, None, None)
s.__exit__(None, None, None)
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION subtransaction_enter_same_subtransaction_twice() RETURNS void
AS $$
s.__enter__()
s.__enter__()
s.__exit__(None, None, None)
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
-- No warnings here, as the subtransaction gets indeed closed
CREATE FUNCTION subtransaction_enter_subtransaction_in_with() RETURNS void
AS $$
with plpy.subtransaction() as s:
s.__enter__()
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION subtransaction_exit_subtransaction_in_with() RETURNS void
AS $$
s.__exit__(None, None, None)
except ValueError as e:
raise ValueError(e)
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT subtransaction_exit_without_enter();
SELECT subtransaction_enter_without_exit();
plpy.execute(p, ["wrong"])
except plpy.SPIError:
plpy.warning("Caught a SPI error")
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT subtransaction_mix_explicit_and_implicit();
SELECT * FROM subtransaction_tbl;
s = plpy.subtransaction()
s.enter()
s.exit(None, None, None)
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT subtransaction_alternative_names();
plpy.execute("INSERT INTO subtransaction_tbl VALUES ('a')")
except plpy.SPIError:
plpy.notice("caught")
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT try_catch_inside_subtransaction();
SELECT * FROM subtransaction_tbl;
plpy.execute("INSERT INTO subtransaction_tbl VALUES (1)")
except plpy.SPIError:
plpy.notice("caught")
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT pk_violation_inside_subtransaction();
SELECT * FROM subtransaction_tbl;
cur.fetch(10)
fetched = cur.fetch(10);
return int(fetched[5]["i"])
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION cursor_aborted_subxact() RETURNS int AS $$
try:
fetched = cur.fetch(10)
return int(fetched[5]["i"])
return 0 # not reached
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION cursor_plan_aborted_subxact() RETURNS int AS $$
try:
fetched = cur.fetch(5)
return fetched[2]["i"]
return 0 # not reached
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION cursor_close_aborted_subxact() RETURNS boolean AS $$
try:
cur.close()
return True
return False # not reached
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT cursor_in_subxact();
SELECT cursor_aborted_subxact();
-- first some tests of basic functionality
-CREATE EXTENSION plpython2u;
+CREATE EXTENSION plpython3u;
-- really stupid function just to get the module loaded
-CREATE FUNCTION stupid() RETURNS text AS 'return "zarkon"' LANGUAGE plpythonu;
+CREATE FUNCTION stupid() RETURNS text AS 'return "zarkon"' LANGUAGE plpython3u;
select stupid();
-- check 2/3 versioning
-CREATE FUNCTION stupidn() RETURNS text AS 'return "zarkon"' LANGUAGE plpython2u;
+CREATE FUNCTION stupidn() RETURNS text AS 'return "zarkon"' LANGUAGE plpython3u;
select stupidn();
out.append("%s: %s" % (key, u[key]))
words = a1 + " " + a2 + " => {" + ", ".join(out) + "}"
return words'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
select "Argument test #1"(users, fname, lname) from users where lname = 'doe' order by 1;
contents = list(filter(lambda x: not x.startswith("__"), dir(plpy)))
contents.sort()
return contents
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
select module_contents();
plpy.notice('notice')
plpy.warning('warning')
plpy.error('error')
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT elog_test_basic();
CREATE PROCEDURE transaction_test1()
-LANGUAGE plpythonu
+LANGUAGE plpython3u
AS $$
for i in range(0, 10):
plpy.execute("INSERT INTO test1 (a) VALUES (%d)" % i)
TRUNCATE test1;
DO
-LANGUAGE plpythonu
+LANGUAGE plpython3u
$$
for i in range(0, 10):
plpy.execute("INSERT INTO test1 (a) VALUES (%d)" % i)
-- not allowed in a function
CREATE FUNCTION transaction_test2() RETURNS int
-LANGUAGE plpythonu
+LANGUAGE plpython3u
AS $$
for i in range(0, 10):
plpy.execute("INSERT INTO test1 (a) VALUES (%d)" % i)
-- also not allowed if procedure is called from a function
CREATE FUNCTION transaction_test3() RETURNS int
-LANGUAGE plpythonu
+LANGUAGE plpython3u
AS $$
plpy.execute("CALL transaction_test1()")
return 1
-- DO block inside function
CREATE FUNCTION transaction_test4() RETURNS int
-LANGUAGE plpythonu
+LANGUAGE plpython3u
AS $$
-plpy.execute("DO LANGUAGE plpythonu $x$ plpy.commit() $x$")
+plpy.execute("DO LANGUAGE plpython3u $x$ plpy.commit() $x$")
return 1
$$;
-- commit inside subtransaction (prohibited)
-DO LANGUAGE plpythonu $$
+DO LANGUAGE plpython3u $$
s = plpy.subtransaction()
s.enter()
plpy.commit()
TRUNCATE test1;
-DO LANGUAGE plpythonu $$
+DO LANGUAGE plpython3u $$
for row in plpy.cursor("SELECT * FROM test2 ORDER BY x"):
plpy.execute("INSERT INTO test1 (a) VALUES (%s)" % row['x'])
plpy.commit()
-- error in cursor loop with commit
TRUNCATE test1;
-DO LANGUAGE plpythonu $$
+DO LANGUAGE plpython3u $$
for row in plpy.cursor("SELECT * FROM test2 ORDER BY x"):
plpy.execute("INSERT INTO test1 (a) VALUES (12/(%s-2))" % row['x'])
plpy.commit()
-- rollback inside cursor loop
TRUNCATE test1;
-DO LANGUAGE plpythonu $$
+DO LANGUAGE plpython3u $$
for row in plpy.cursor("SELECT * FROM test2 ORDER BY x"):
plpy.execute("INSERT INTO test1 (a) VALUES (%s)" % row['x'])
plpy.rollback()
-- first commit then rollback inside cursor loop
TRUNCATE test1;
-DO LANGUAGE plpythonu $$
+DO LANGUAGE plpython3u $$
for row in plpy.cursor("SELECT * FROM test2 ORDER BY x"):
plpy.execute("INSERT INTO test1 (a) VALUES (%s)" % row['x'])
if row['x'] % 2 == 0:
CREATE TABLE testpk (id int PRIMARY KEY);
CREATE TABLE testfk(f1 int REFERENCES testpk DEFERRABLE INITIALLY DEFERRED);
-DO LANGUAGE plpythonu $$
+DO LANGUAGE plpython3u $$
# this insert will fail during commit:
plpy.execute("INSERT INTO testfk VALUES (0)")
plpy.commit()
SELECT * FROM testpk;
SELECT * FROM testfk;
-DO LANGUAGE plpythonu $$
+DO LANGUAGE plpython3u $$
# this insert will fail during commit:
plpy.execute("INSERT INTO testfk VALUES (0)")
try:
TD["new"]["fname"] = TD["args"][0]
rv = "MODIFY"
return rv'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
CREATE FUNCTION users_update() returns trigger
if TD["old"]["fname"] != TD["new"]["fname"] and TD["old"]["fname"] == TD["args"][0]:
return "SKIP"
return None'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
CREATE FUNCTION users_delete() RETURNS trigger
'if TD["old"]["fname"] == TD["args"][0]:
return "SKIP"
return None'
- LANGUAGE plpythonu;
+ LANGUAGE plpython3u;
CREATE TRIGGER users_insert_trig BEFORE INSERT ON users FOR EACH ROW
j int GENERATED ALWAYS AS (i * 2) STORED
);
-CREATE FUNCTION trigger_data() RETURNS trigger LANGUAGE plpythonu AS $$
+CREATE FUNCTION trigger_data() RETURNS trigger LANGUAGE plpython3u AS $$
if 'relid' in TD:
TD['relid'] = "bogus:12345"
CREATE FUNCTION stupid1() RETURNS trigger
AS $$
return 37
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE TRIGGER stupid_trigger1
BEFORE INSERT ON trigger_test
CREATE FUNCTION stupid2() RETURNS trigger
AS $$
return "MODIFY"
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE TRIGGER stupid_trigger2
BEFORE DELETE ON trigger_test
CREATE FUNCTION stupid3() RETURNS trigger
AS $$
return "foo"
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE TRIGGER stupid_trigger3
BEFORE UPDATE ON trigger_test
CREATE FUNCTION stupid3u() RETURNS trigger
AS $$
- return u"foo"
-$$ LANGUAGE plpythonu;
+ return "foo"
+$$ LANGUAGE plpython3u;
CREATE TRIGGER stupid_trigger3
BEFORE UPDATE ON trigger_test
AS $$
del TD["new"]
return "MODIFY";
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE TRIGGER stupid_trigger4
BEFORE UPDATE ON trigger_test
AS $$
TD["new"] = ['foo', 'bar']
return "MODIFY";
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE TRIGGER stupid_trigger5
BEFORE UPDATE ON trigger_test
AS $$
TD["new"] = {1: 'foo', 2: 'bar'}
return "MODIFY";
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE TRIGGER stupid_trigger6
BEFORE UPDATE ON trigger_test
AS $$
TD["new"] = {'v': 'foo', 'a': 'bar'}
return "MODIFY";
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE TRIGGER stupid_trigger7
BEFORE UPDATE ON trigger_test
CREATE FUNCTION stupid7u() RETURNS trigger
AS $$
- TD["new"] = {u'v': 'foo', u'a': 'bar'}
+ TD["new"] = {'v': 'foo', 'a': 'bar'}
return "MODIFY"
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE TRIGGER stupid_trigger7
BEFORE UPDATE ON trigger_test
AS $$
TD["new"]['v'] = None
return "MODIFY"
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE TRIGGER test_null_trigger
BEFORE UPDATE ON trigger_test
CREATE FUNCTION set_modif_time() RETURNS trigger AS $$
TD['new']['modif_time'] = '2010-10-13 21:57:28.930486'
return 'MODIFY'
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE TABLE pb (a TEXT, modif_time TIMESTAMP(0) WITHOUT TIME ZONE);
TD['new']['f1'] = (3, False)
TD['new']['f2'] = {'k': 7, 'l': 'yes', 'ignored': 10}
return 'MODIFY'
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE TRIGGER composite_trigger BEFORE INSERT ON composite_trigger_test
FOR EACH ROW EXECUTE PROCEDURE composite_trigger_f();
CREATE FUNCTION composite_trigger_noop_f() RETURNS trigger AS $$
return 'MODIFY'
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE TRIGGER composite_trigger_noop BEFORE INSERT ON composite_trigger_noop_test
FOR EACH ROW EXECUTE PROCEDURE composite_trigger_noop_f();
CREATE FUNCTION composite_trigger_nested_f() RETURNS trigger AS $$
return 'MODIFY'
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE TRIGGER composite_trigger_nested BEFORE INSERT ON composite_trigger_nested_test
FOR EACH ROW EXECUTE PROCEDURE composite_trigger_nested_f();
SELECT * FROM composite_trigger_nested_test;
-- check that using a function as a trigger over two tables works correctly
-CREATE FUNCTION trig1234() RETURNS trigger LANGUAGE plpythonu AS $$
+CREATE FUNCTION trig1234() RETURNS trigger LANGUAGE plpython3u AS $$
TD["new"]["data"] = '1234'
return 'MODIFY'
$$;
CREATE TABLE transition_table_test (id int, name text);
INSERT INTO transition_table_test VALUES (1, 'a');
-CREATE FUNCTION transition_table_test_f() RETURNS trigger LANGUAGE plpythonu AS
+CREATE FUNCTION transition_table_test_f() RETURNS trigger LANGUAGE plpython3u AS
$$
rv = plpy.execute("SELECT * FROM old_table")
assert(rv.nrows() == 1)
-- dealing with generated columns
CREATE FUNCTION generated_test_func1() RETURNS trigger
-LANGUAGE plpythonu
+LANGUAGE plpython3u
AS $$
TD['new']['j'] = 5 # not allowed
return 'MODIFY'
CREATE FUNCTION test_type_conversion_bool(x bool) RETURNS bool AS $$
plpy.info(x, type(x))
return x
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_bool(true);
SELECT * FROM test_type_conversion_bool(false);
ret = [0]
plpy.info(ret, not not ret)
return ret
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_bool_other(0);
SELECT * FROM test_type_conversion_bool_other(1);
CREATE FUNCTION test_type_conversion_char(x char) RETURNS char AS $$
plpy.info(x, type(x))
return x
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_char('a');
SELECT * FROM test_type_conversion_char(null);
CREATE FUNCTION test_type_conversion_int2(x int2) RETURNS int2 AS $$
plpy.info(x, type(x))
return x
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_int2(100::int2);
SELECT * FROM test_type_conversion_int2(-100::int2);
CREATE FUNCTION test_type_conversion_int4(x int4) RETURNS int4 AS $$
plpy.info(x, type(x))
return x
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_int4(100);
SELECT * FROM test_type_conversion_int4(-100);
CREATE FUNCTION test_type_conversion_int8(x int8) RETURNS int8 AS $$
plpy.info(x, type(x))
return x
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_int8(100);
SELECT * FROM test_type_conversion_int8(-100);
# between decimal and cdecimal
plpy.info(str(x), x.__class__.__name__)
return x
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_numeric(100);
SELECT * FROM test_type_conversion_numeric(-100);
CREATE FUNCTION test_type_conversion_float4(x float4) RETURNS float4 AS $$
plpy.info(x, type(x))
return x
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_float4(100);
SELECT * FROM test_type_conversion_float4(-100);
CREATE FUNCTION test_type_conversion_float8(x float8) RETURNS float8 AS $$
plpy.info(x, type(x))
return x
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_float8(100);
SELECT * FROM test_type_conversion_float8(-100);
CREATE FUNCTION test_type_conversion_oid(x oid) RETURNS oid AS $$
plpy.info(x, type(x))
return x
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_oid(100);
SELECT * FROM test_type_conversion_oid(2147483649);
CREATE FUNCTION test_type_conversion_text(x text) RETURNS text AS $$
plpy.info(x, type(x))
return x
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_text('hello world');
SELECT * FROM test_type_conversion_text(null);
CREATE FUNCTION test_type_conversion_bytea(x bytea) RETURNS bytea AS $$
plpy.info(x, type(x))
return x
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_bytea('hello world');
SELECT * FROM test_type_conversion_bytea(E'null\\000byte');
CREATE FUNCTION test_type_marshal() RETURNS bytea AS $$
import marshal
return marshal.dumps('hello world')
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION test_type_unmarshal(x bytea) RETURNS text AS $$
import marshal
return marshal.loads(x)
except ValueError as e:
return 'FAILED: ' + str(e)
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT test_type_unmarshal(x) FROM test_type_marshal() x;
CREATE FUNCTION test_type_conversion_booltrue(x booltrue, y bool) RETURNS booltrue AS $$
return y
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_booltrue(true, true);
SELECT * FROM test_type_conversion_booltrue(false, true);
CREATE FUNCTION test_type_conversion_uint2(x uint2, y int) RETURNS uint2 AS $$
plpy.info(x, type(x))
return y
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_uint2(100::uint2, 50);
SELECT * FROM test_type_conversion_uint2(100::uint2, -50);
CREATE FUNCTION test_type_conversion_nnint(x nnint, y int) RETURNS nnint AS $$
return y
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_nnint(10, 20);
SELECT * FROM test_type_conversion_nnint(null, 20);
CREATE FUNCTION test_type_conversion_bytea10(x bytea10, y bytea) RETURNS bytea10 AS $$
plpy.info(x, type(x))
return y
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_bytea10('hello wold', 'hello wold');
SELECT * FROM test_type_conversion_bytea10('hello world', 'hello wold');
CREATE FUNCTION test_type_conversion_array_int4(x int4[]) RETURNS int4[] AS $$
plpy.info(x, type(x))
return x
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_array_int4(ARRAY[0, 100]);
SELECT * FROM test_type_conversion_array_int4(ARRAY[0,-100,55]);
CREATE FUNCTION test_type_conversion_array_int8(x int8[]) RETURNS int8[] AS $$
plpy.info(x, type(x))
return x
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_array_int8(ARRAY[[[1,2,NULL],[NULL,5,6]],[[NULL,8,9],[10,11,12]]]::int8[]);
CREATE FUNCTION test_type_conversion_array_date(x date[]) RETURNS date[] AS $$
plpy.info(x, type(x))
return x
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_array_date(ARRAY[[['2016-09-21','2016-09-22',NULL],[NULL,'2016-10-21','2016-10-22']],
[[NULL,'2016-11-21','2016-10-21'],['2015-09-21','2015-09-22','2014-09-21']]]::date[]);
CREATE FUNCTION test_type_conversion_array_timestamp(x timestamp[]) RETURNS timestamp[] AS $$
plpy.info(x, type(x))
return x
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_array_timestamp(ARRAY[[['2016-09-21 15:34:24.078792-04','2016-10-22 11:34:24.078795-04',NULL],
[NULL,'2016-10-21 11:34:25.078792-04','2016-10-21 11:34:24.098792-04']],
m = [[[[x for x in range(h)] for y in range(i)] for z in range(j)] for w in range(k)]
plpy.info(m, type(m))
return m
-$BODY$ LANGUAGE plpythonu;
+$BODY$ LANGUAGE plpython3u;
select pyreturnmultidemint4(8,5,3,2);
m = [[[[x for x in range(h)] for y in range(i)] for z in range(j)] for w in range(k)]
plpy.info(m, type(m))
return m
-$BODY$ LANGUAGE plpythonu;
+$BODY$ LANGUAGE plpython3u;
select pyreturnmultidemint8(5,5,3,2);
m = [[[[x for x in range(h)] for y in range(i)] for z in range(j)] for w in range(k)]
plpy.info(m, type(m))
return m
-$BODY$ LANGUAGE plpythonu;
+$BODY$ LANGUAGE plpython3u;
select pyreturnmultidemfloat4(6,5,3,2);
m = [[[[x for x in range(h)] for y in range(i)] for z in range(j)] for w in range(k)]
plpy.info(m, type(m))
return m
-$BODY$ LANGUAGE plpythonu;
+$BODY$ LANGUAGE plpython3u;
select pyreturnmultidemfloat8(7,5,3,2);
CREATE FUNCTION test_type_conversion_array_text(x text[]) RETURNS text[] AS $$
plpy.info(x, type(x))
return x
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_array_text(ARRAY['foo', 'bar']);
SELECT * FROM test_type_conversion_array_text(ARRAY[['foo', 'bar'],['foo2', 'bar2']]);
CREATE FUNCTION test_type_conversion_array_bytea(x bytea[]) RETURNS bytea[] AS $$
plpy.info(x, type(x))
return x
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_array_bytea(ARRAY[E'\\xdeadbeef'::bytea, NULL]);
CREATE FUNCTION test_type_conversion_array_mixed1() RETURNS text[] AS $$
return [123, 'abc']
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_array_mixed1();
CREATE FUNCTION test_type_conversion_array_mixed2() RETURNS int[] AS $$
return [123, 'abc']
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_array_mixed2();
CREATE FUNCTION test_type_conversion_mdarray_malformed() RETURNS int[] AS $$
return [[1,2,3],[4,5]]
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_mdarray_malformed();
CREATE FUNCTION test_type_conversion_mdarray_toodeep() RETURNS int[] AS $$
return [[[[[[[1]]]]]]]
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_mdarray_toodeep();
CREATE FUNCTION test_type_conversion_array_record() RETURNS type_record[] AS $$
return [{'first': 'one', 'second': 42}, {'first': 'two', 'second': 11}]
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_array_record();
CREATE FUNCTION test_type_conversion_array_string() RETURNS text[] AS $$
return 'abc'
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_array_string();
CREATE FUNCTION test_type_conversion_array_tuple() RETURNS text[] AS $$
return ('abc', 'def')
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_array_tuple();
CREATE FUNCTION test_type_conversion_array_error() RETURNS int[] AS $$
return 5
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_array_error();
CREATE FUNCTION test_type_conversion_array_domain(x ordered_pair_domain) RETURNS ordered_pair_domain AS $$
plpy.info(x, type(x))
return x
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_array_domain(ARRAY[0, 100]::ordered_pair_domain);
SELECT * FROM test_type_conversion_array_domain(NULL::ordered_pair_domain);
CREATE FUNCTION test_type_conversion_array_domain_check_violation() RETURNS ordered_pair_domain AS $$
return [2,1]
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT * FROM test_type_conversion_array_domain_check_violation();
CREATE FUNCTION test_read_uint2_array(x uint2[]) RETURNS uint2 AS $$
plpy.info(x, type(x))
return x[0]
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
select test_read_uint2_array(array[1::uint2]);
CREATE FUNCTION test_build_uint2_array(x int2) RETURNS uint2[] AS $$
return [x, x]
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
select test_build_uint2_array(1::int2);
select test_build_uint2_array(-1::int2); -- fail
CREATE FUNCTION test_type_conversion_domain_array(x integer[])
RETURNS ordered_pair_domain[] AS $$
return [x, x]
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
select test_type_conversion_domain_array(array[2,4]);
select test_type_conversion_domain_array(array[4,2]); -- fail
RETURNS integer AS $$
plpy.info(x, type(x))
return x[1]
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
select test_type_conversion_domain_array2(array[2,4]);
select test_type_conversion_domain_array2(array[4,2]); -- fail
RETURNS ordered_pair_domain AS $$
plpy.info(x, type(x))
return x[0]
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
select test_type_conversion_array_domain_array(array[array[2,4]::ordered_pair_domain]);
CREATE OR REPLACE FUNCTION test_composite_table_input(e employee) RETURNS integer AS $$
return e['basesalary'] + e['bonus']
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT name, test_composite_table_input(employee.*) FROM employee;
CREATE OR REPLACE FUNCTION test_composite_type_input(p named_pair) RETURNS integer AS $$
return sum(p.values())
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT test_composite_type_input(row(1, 2));
CREATE FUNCTION nnint_test(x int, y int) RETURNS nnint_container AS $$
return {'f1': x, 'f2': y}
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT nnint_test(null, 3);
SELECT nnint_test(3, null); -- fail
CREATE FUNCTION read_ordered_named_pair(p ordered_named_pair) RETURNS integer AS $$
return p['i'] + p['j']
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT read_ordered_named_pair(row(1, 2));
SELECT read_ordered_named_pair(row(2, 1)); -- fail
CREATE FUNCTION build_ordered_named_pair(i int, j int) RETURNS ordered_named_pair AS $$
return {'i': i, 'j': j}
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT build_ordered_named_pair(1,2);
SELECT build_ordered_named_pair(2,1); -- fail
CREATE FUNCTION build_ordered_named_pairs(i int, j int) RETURNS ordered_named_pair[] AS $$
return [{'i': i, 'j': j}, {'i': i, 'j': j+1}]
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
SELECT build_ordered_named_pairs(1,2);
SELECT build_ordered_named_pairs(2,1); -- fail
--
CREATE OR REPLACE FUNCTION test_prep_bool_input() RETURNS int
-LANGUAGE plpythonu
+LANGUAGE plpython3u
AS $$
plan = plpy.prepare("SELECT CASE WHEN $1 THEN 1 ELSE 0 END AS val", ['boolean'])
rv = plpy.execute(plan, ['fa'], 5) # 'fa' is true in Python
CREATE OR REPLACE FUNCTION test_prep_bool_output() RETURNS bool
-LANGUAGE plpythonu
+LANGUAGE plpython3u
AS $$
plan = plpy.prepare("SELECT $1 = 1 AS val", ['int'])
rv = plpy.execute(plan, [0], 5)
CREATE OR REPLACE FUNCTION test_prep_bytea_input(bb bytea) RETURNS int
-LANGUAGE plpythonu
+LANGUAGE plpython3u
AS $$
plan = plpy.prepare("SELECT octet_length($1) AS val", ['bytea'])
rv = plpy.execute(plan, [bb], 5)
CREATE OR REPLACE FUNCTION test_prep_bytea_output() RETURNS bytea
-LANGUAGE plpythonu
+LANGUAGE plpython3u
AS $$
plan = plpy.prepare("SELECT decode('aa00bb', 'hex') AS val")
rv = plpy.execute(plan, [], 5)
);
CREATE FUNCTION unicode_return() RETURNS text AS E'
-return u"\\xA0"
-' LANGUAGE plpythonu;
+return "\\xA0"
+' LANGUAGE plpython3u;
CREATE FUNCTION unicode_trigger() RETURNS trigger AS E'
-TD["new"]["testvalue"] = u"\\xA0"
+TD["new"]["testvalue"] = "\\xA0"
return "MODIFY"
-' LANGUAGE plpythonu;
+' LANGUAGE plpython3u;
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"\\xA0"], 1)
+rv = plpy.execute(plan, ["\\xA0"], 1)
return rv[0]["testvalue"]
-' LANGUAGE plpythonu;
+' LANGUAGE plpython3u;
CREATE FUNCTION unicode_plan2() RETURNS text AS E'
-plan = plpy.prepare("SELECT $1 || $2 AS testvalue", ["text", u"text"])
+plan = plpy.prepare("SELECT $1 || $2 AS testvalue", ["text", "text"])
rv = plpy.execute(plan, ["foo", "bar"], 1)
return rv[0]["testvalue"]
-' LANGUAGE plpythonu;
+' LANGUAGE plpython3u;
SELECT unicode_return();
CREATE FUNCTION test_void_func1() RETURNS void AS $$
x = 10
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
-- illegal: can't return non-None value in void-returning func
CREATE FUNCTION test_void_func2() RETURNS void AS $$
return 10
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
CREATE FUNCTION test_return_none() RETURNS int AS $$
None
-$$ LANGUAGE plpythonu;
+$$ LANGUAGE plpython3u;
-- Tests for functions returning void
return;
}
-sub mangle_plpython3
-{
- my $tests = shift;
- mkdir "results" unless -d "results";
- mkdir "sql/python3";
- mkdir "results/python3";
- mkdir "expected/python3";
-
- foreach my $test (@$tests)
- {
- local $/ = undef;
- foreach my $dir ('sql', 'expected')
- {
- my $extension = ($dir eq 'sql' ? 'sql' : 'out');
-
- my @files =
- glob("$dir/$test.$extension $dir/${test}_[0-9].$extension");
- foreach my $file (@files)
- {
- open(my $handle, '<', $file)
- || die "test file $file not found";
- my $contents = <$handle>;
- close($handle);
- do
- {
- s/<type 'exceptions\.([[:alpha:]]*)'>/<class '$1'>/g;
- s/<type 'long'>/<class 'int'>/g;
- s/([0-9][0-9]*)L/$1/g;
- s/([ [{])u"/$1"/g;
- s/([ [{])u'/$1'/g;
- s/def next/def __next__/g;
- s/LANGUAGE plpython2?u/LANGUAGE plpython3u/g;
- s/EXTENSION (\S*?)plpython2?u/EXTENSION $1plpython3u/g;
- s/installing required extension "plpython2u"/installing required extension "plpython3u"/g;
- }
- for ($contents);
- my $base = basename $file;
- open($handle, '>', "$dir/python3/$base")
- || die "opening python 3 file for $file";
- print $handle $contents;
- close($handle);
- }
- }
- }
- do { s!^!python3/!; }
- foreach (@$tests);
- return @$tests;
-}
-
sub plcheck
{
chdir "$topdir/src/pl";
if ($lang eq 'plpython')
{
next
- unless -d "$topdir/$Config/plpython2"
- || -d "$topdir/$Config/plpython3";
+ unless -d "$topdir/$Config/plpython3";
$lang = 'plpythonu';
}
else
my @lang_args = ("--load-extension=$lang");
chdir $dir;
my @tests = fetchTests();
- @tests = mangle_plpython3(\@tests)
- if $lang eq 'plpythonu' && -d "$topdir/$Config/plpython3";
if ($lang eq 'plperl')
{
my @opts = fetchRegressOpts();
- # Special processing for python transform modules, see their respective
- # Makefiles for more details regarding Python-version specific
- # dependencies.
- if ($module =~ /_plpython$/)
- {
- die "Python not enabled in configuration"
- if !defined($config->{python});
-
- @opts = grep { $_ !~ /plpythonu/ } @opts;
-
- if (-d "$topdir/$Config/plpython2")
- {
- push @opts, "--load-extension=plpythonu";
- push @opts, '--load-extension=' . $module . 'u';
- }
- else
- {
- # must be python 3
- @tests = mangle_plpython3(\@tests);
- }
- }
-
print "============================================================\n";
print "Checking $module\n";
my @args = (