mirror of https://github.com/postgres/postgres
Add some checks on various data types are converted into and out of Python. This is extracted from Caleb Welton's patch for improved bytea support, but much expanded.REL8_5_ALPHA1_BRANCH
parent
cf37d68467
commit
0c738084fb
@ -0,0 +1,378 @@ |
||||
-- |
||||
-- 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" |
||||
@ -0,0 +1,157 @@ |
||||
-- |
||||
-- 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); |
||||
Loading…
Reference in new issue