--
-- 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(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"
