--- /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 plpythonu;
+SELECT * FROM test_type_conversion_bool(true);
+INFO: (True, <type 'bool'>)
+CONTEXT: PL/Python function "test_type_conversion_bool"
+ test_type_conversion_bool
+---------------------------
+ t
+(1 row)
+
+SELECT * FROM test_type_conversion_bool(false);
+INFO: (False, <type 'bool'>)
+CONTEXT: PL/Python function "test_type_conversion_bool"
+ test_type_conversion_bool
+---------------------------
+ f
+(1 row)
+
+SELECT * FROM test_type_conversion_bool(null);
+INFO: (None, <type 'NoneType'>)
+CONTEXT: PL/Python function "test_type_conversion_bool"
+ test_type_conversion_bool
+---------------------------
+
+(1 row)
+
+CREATE FUNCTION test_type_conversion_char(x char) RETURNS char AS $$
+plpy.info(x, type(x))
+return x
+$$ LANGUAGE plpythonu;
+SELECT * FROM test_type_conversion_char('a');
+INFO: ('a', <type 'str'>)
+CONTEXT: PL/Python function "test_type_conversion_char"
+ test_type_conversion_char
+---------------------------
+ a
+(1 row)
+
+SELECT * FROM test_type_conversion_char(null);
+INFO: (None, <type 'NoneType'>)
+CONTEXT: PL/Python function "test_type_conversion_char"
+ 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 plpythonu;
+SELECT * FROM test_type_conversion_int2(100::int2);
+INFO: (100, <type 'int'>)
+CONTEXT: PL/Python function "test_type_conversion_int2"
+ test_type_conversion_int2
+---------------------------
+ 100
+(1 row)
+
+SELECT * FROM test_type_conversion_int2(-100::int2);
+INFO: (-100, <type 'int'>)
+CONTEXT: PL/Python function "test_type_conversion_int2"
+ test_type_conversion_int2
+---------------------------
+ -100
+(1 row)
+
+SELECT * FROM test_type_conversion_int2(null);
+INFO: (None, <type 'NoneType'>)
+CONTEXT: PL/Python function "test_type_conversion_int2"
+ 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 plpythonu;
+SELECT * FROM test_type_conversion_int4(100);
+INFO: (100, <type 'int'>)
+CONTEXT: PL/Python function "test_type_conversion_int4"
+ test_type_conversion_int4
+---------------------------
+ 100
+(1 row)
+
+SELECT * FROM test_type_conversion_int4(-100);
+INFO: (-100, <type 'int'>)
+CONTEXT: PL/Python function "test_type_conversion_int4"
+ test_type_conversion_int4
+---------------------------
+ -100
+(1 row)
+
+SELECT * FROM test_type_conversion_int4(null);
+INFO: (None, <type 'NoneType'>)
+CONTEXT: PL/Python function "test_type_conversion_int4"
+ 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 plpythonu;
+SELECT * FROM test_type_conversion_int8(100);
+INFO: (100L, <type 'long'>)
+CONTEXT: PL/Python function "test_type_conversion_int8"
+ test_type_conversion_int8
+---------------------------
+ 100
+(1 row)
+
+SELECT * FROM test_type_conversion_int8(-100);
+INFO: (-100L, <type 'long'>)
+CONTEXT: PL/Python function "test_type_conversion_int8"
+ test_type_conversion_int8
+---------------------------
+ -100
+(1 row)
+
+SELECT * FROM test_type_conversion_int8(5000000000);
+INFO: (5000000000L, <type 'long'>)
+CONTEXT: PL/Python function "test_type_conversion_int8"
+ test_type_conversion_int8
+---------------------------
+ 5000000000
+(1 row)
+
+SELECT * FROM test_type_conversion_int8(null);
+INFO: (None, <type 'NoneType'>)
+CONTEXT: PL/Python function "test_type_conversion_int8"
+ test_type_conversion_int8
+---------------------------
+
+(1 row)
+
+CREATE FUNCTION test_type_conversion_numeric(x numeric) RETURNS numeric AS $$
+plpy.info(x, type(x))
+return x
+$$ LANGUAGE plpythonu;
+/* The current implementation converts numeric to float. */
+SELECT * FROM test_type_conversion_numeric(100);
+INFO: (100.0, <type 'float'>)
+CONTEXT: PL/Python function "test_type_conversion_numeric"
+ test_type_conversion_numeric
+------------------------------
+ 100.0
+(1 row)
+
+SELECT * FROM test_type_conversion_numeric(-100);
+INFO: (-100.0, <type 'float'>)
+CONTEXT: PL/Python function "test_type_conversion_numeric"
+ test_type_conversion_numeric
+------------------------------
+ -100.0
+(1 row)
+
+SELECT * FROM test_type_conversion_numeric(5000000000.5);
+INFO: (5000000000.5, <type 'float'>)
+CONTEXT: PL/Python function "test_type_conversion_numeric"
+ test_type_conversion_numeric
+------------------------------
+ 5000000000.5
+(1 row)
+
+SELECT * FROM test_type_conversion_numeric(79228162514264337593543950336);
+INFO: (7.9228162514264338e+28, <type 'float'>)
+CONTEXT: PL/Python function "test_type_conversion_numeric"
+ test_type_conversion_numeric
+-------------------------------
+ 79228162514300000000000000000
+(1 row)
+
+SELECT * FROM test_type_conversion_numeric(null);
+INFO: (None, <type 'NoneType'>)
+CONTEXT: PL/Python function "test_type_conversion_numeric"
+ 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 plpythonu;
+SELECT * FROM test_type_conversion_float4(100);
+INFO: (100.0, <type 'float'>)
+CONTEXT: PL/Python function "test_type_conversion_float4"
+ test_type_conversion_float4
+-----------------------------
+ 100
+(1 row)
+
+SELECT * FROM test_type_conversion_float4(-100);
+INFO: (-100.0, <type 'float'>)
+CONTEXT: PL/Python function "test_type_conversion_float4"
+ test_type_conversion_float4
+-----------------------------
+ -100
+(1 row)
+
+SELECT * FROM test_type_conversion_float4(5000.5);
+INFO: (5000.5, <type 'float'>)
+CONTEXT: PL/Python function "test_type_conversion_float4"
+ test_type_conversion_float4
+-----------------------------
+ 5000.5
+(1 row)
+
+SELECT * FROM test_type_conversion_float4(null);
+INFO: (None, <type 'NoneType'>)
+CONTEXT: PL/Python function "test_type_conversion_float4"
+ 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 plpythonu;
+SELECT * FROM test_type_conversion_float8(100);
+INFO: (100.0, <type 'float'>)
+CONTEXT: PL/Python function "test_type_conversion_float8"
+ test_type_conversion_float8
+-----------------------------
+ 100
+(1 row)
+
+SELECT * FROM test_type_conversion_float8(-100);
+INFO: (-100.0, <type 'float'>)
+CONTEXT: PL/Python function "test_type_conversion_float8"
+ test_type_conversion_float8
+-----------------------------
+ -100
+(1 row)
+
+SELECT * FROM test_type_conversion_float8(5000000000.5);
+INFO: (5000000000.5, <type 'float'>)
+CONTEXT: PL/Python function "test_type_conversion_float8"
+ test_type_conversion_float8
+-----------------------------
+ 5000000000.5
+(1 row)
+
+SELECT * FROM test_type_conversion_float8(null);
+INFO: (None, <type 'NoneType'>)
+CONTEXT: PL/Python function "test_type_conversion_float8"
+ test_type_conversion_float8
+-----------------------------
+
+(1 row)
+
+CREATE FUNCTION test_type_conversion_text(x text) RETURNS text AS $$
+plpy.info(x, type(x))
+return x
+$$ LANGUAGE plpythonu;
+SELECT * FROM test_type_conversion_text('hello world');
+INFO: ('hello world', <type 'str'>)
+CONTEXT: PL/Python function "test_type_conversion_text"
+ test_type_conversion_text
+---------------------------
+ hello world
+(1 row)
+
+SELECT * FROM test_type_conversion_text(null);
+INFO: (None, <type 'NoneType'>)
+CONTEXT: PL/Python function "test_type_conversion_text"
+ 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 plpythonu;
+SELECT * FROM test_type_conversion_bytea('hello world');
+INFO: ('\\x68656c6c6f20776f726c64', <type 'str'>)
+CONTEXT: PL/Python function "test_type_conversion_bytea"
+ test_type_conversion_bytea
+----------------------------
+ \x68656c6c6f20776f726c64
+(1 row)
+
+SELECT * FROM test_type_conversion_bytea(null);
+INFO: (None, <type 'NoneType'>)
+CONTEXT: PL/Python function "test_type_conversion_bytea"
+ test_type_conversion_bytea
+----------------------------
+
+(1 row)
+
+CREATE FUNCTION test_type_marshal() RETURNS bytea AS $$
+import marshal
+return marshal.dumps('hello world')
+$$ LANGUAGE plpythonu;
+CREATE FUNCTION test_type_unmarshal(x bytea) RETURNS text AS $$
+import marshal
+try:
+ return marshal.loads(x)
+except ValueError, e:
+ return 'FAILED: ' + str(e)
+$$ LANGUAGE plpythonu;
+/* This will currently fail because the bytea datum is presented to
+ Python as a string in bytea-encoding, which Python doesn't understand. */
+SELECT test_type_unmarshal(x) FROM test_type_marshal() x;
+ test_type_unmarshal
+--------------------------
+ FAILED: bad marshal data
+(1 row)
+
+--
+-- Domains
+--
+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 plpythonu;
+SELECT * FROM test_type_conversion_uint2(100::uint2, 50);
+INFO: (100, <type 'int'>)
+CONTEXT: PL/Python function "test_type_conversion_uint2"
+ test_type_conversion_uint2
+----------------------------
+ 50
+(1 row)
+
+SELECT * FROM test_type_conversion_uint2(100::uint2, -50);
+INFO: (100, <type 'int'>)
+CONTEXT: PL/Python function "test_type_conversion_uint2"
+ERROR: value for domain uint2 violates check constraint "uint2_check"
+CONTEXT: PL/Python function "test_type_conversion_uint2"
+SELECT * FROM test_type_conversion_uint2(null, 1);
+INFO: (None, <type 'NoneType'>)
+CONTEXT: PL/Python function "test_type_conversion_uint2"
+ test_type_conversion_uint2
+----------------------------
+ 1
+(1 row)
+
+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 plpythonu;
+SELECT * FROM test_type_conversion_bytea10('hello wold', 'hello wold');
+INFO: ('\\x68656c6c6f20776f6c64', <type 'str'>)
+CONTEXT: PL/Python function "test_type_conversion_bytea10"
+ 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: ('\\x68656c6c6f20776f7264', <type 'str'>)
+CONTEXT: PL/Python function "test_type_conversion_bytea10"
+ERROR: value for domain bytea10 violates check constraint "bytea10_check"
+CONTEXT: 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: ('\\x68656c6c6f20776f7264', <type 'str'>)
+CONTEXT: PL/Python function "test_type_conversion_bytea10"
+ERROR: value for domain bytea10 violates check constraint "bytea10_check"
+CONTEXT: PL/Python function "test_type_conversion_bytea10"
--- /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 plpythonu;
+
+SELECT * FROM test_type_conversion_bool(true);
+SELECT * FROM test_type_conversion_bool(false);
+SELECT * FROM test_type_conversion_bool(null);
+
+
+CREATE FUNCTION test_type_conversion_char(x char) RETURNS char AS $$
+plpy.info(x, type(x))
+return x
+$$ LANGUAGE plpythonu;
+
+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;
+
+SELECT * FROM test_type_conversion_int2(100::int2);
+SELECT * FROM test_type_conversion_int2(-100::int2);
+SELECT * FROM test_type_conversion_int2(null);
+
+
+CREATE FUNCTION test_type_conversion_int4(x int4) RETURNS int4 AS $$
+plpy.info(x, type(x))
+return x
+$$ LANGUAGE plpythonu;
+
+SELECT * FROM test_type_conversion_int4(100);
+SELECT * FROM test_type_conversion_int4(-100);
+SELECT * FROM test_type_conversion_int4(null);
+
+
+CREATE FUNCTION test_type_conversion_int8(x int8) RETURNS int8 AS $$
+plpy.info(x, type(x))
+return x
+$$ LANGUAGE plpythonu;
+
+SELECT * FROM test_type_conversion_int8(100);
+SELECT * FROM test_type_conversion_int8(-100);
+SELECT * FROM test_type_conversion_int8(5000000000);
+SELECT * FROM test_type_conversion_int8(null);
+
+
+CREATE FUNCTION test_type_conversion_numeric(x numeric) RETURNS numeric AS $$
+plpy.info(x, type(x))
+return x
+$$ LANGUAGE plpythonu;
+
+/* The current implementation converts numeric to float. */
+SELECT * FROM test_type_conversion_numeric(100);
+SELECT * FROM test_type_conversion_numeric(-100);
+SELECT * FROM test_type_conversion_numeric(5000000000.5);
+SELECT * FROM test_type_conversion_numeric(79228162514264337593543950336);
+SELECT * FROM test_type_conversion_numeric(null);
+
+
+CREATE FUNCTION test_type_conversion_float4(x float4) RETURNS float4 AS $$
+plpy.info(x, type(x))
+return x
+$$ LANGUAGE plpythonu;
+
+SELECT * FROM test_type_conversion_float4(100);
+SELECT * FROM test_type_conversion_float4(-100);
+SELECT * FROM test_type_conversion_float4(5000.5);
+SELECT * FROM test_type_conversion_float4(null);
+
+
+CREATE FUNCTION test_type_conversion_float8(x float8) RETURNS float8 AS $$
+plpy.info(x, type(x))
+return x
+$$ LANGUAGE plpythonu;
+
+SELECT * FROM test_type_conversion_float8(100);
+SELECT * FROM test_type_conversion_float8(-100);
+SELECT * FROM test_type_conversion_float8(5000000000.5);
+SELECT * FROM test_type_conversion_float8(null);
+
+
+CREATE FUNCTION test_type_conversion_text(x text) RETURNS text AS $$
+plpy.info(x, type(x))
+return x
+$$ LANGUAGE plpythonu;
+
+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;
+
+SELECT * FROM test_type_conversion_bytea('hello world');
+SELECT * FROM test_type_conversion_bytea(null);
+
+
+CREATE FUNCTION test_type_marshal() RETURNS bytea AS $$
+import marshal
+return marshal.dumps('hello world')
+$$ LANGUAGE plpythonu;
+
+CREATE FUNCTION test_type_unmarshal(x bytea) RETURNS text AS $$
+import marshal
+try:
+ return marshal.loads(x)
+except ValueError, e:
+ return 'FAILED: ' + str(e)
+$$ LANGUAGE plpythonu;
+
+/* This will currently fail because the bytea datum is presented to
+ Python as a string in bytea-encoding, which Python doesn't understand. */
+SELECT test_type_unmarshal(x) FROM test_type_marshal() x;
+
+
+--
+-- Domains
+--
+
+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 plpythonu;
+
+SELECT * FROM test_type_conversion_uint2(100::uint2, 50);
+SELECT * FROM test_type_conversion_uint2(100::uint2, -50);
+SELECT * FROM test_type_conversion_uint2(null, 1);
+
+
+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 plpythonu;
+
+SELECT * FROM test_type_conversion_bytea10('hello wold', 'hello wold');
+SELECT * FROM test_type_conversion_bytea10('hello world', 'hello wold');
+SELECT * FROM test_type_conversion_bytea10('hello word', 'hello world');
+SELECT * FROM test_type_conversion_bytea10(null, 'hello word');
+SELECT * FROM test_type_conversion_bytea10('hello word', null);