mirror of
https://github.com/postgres/postgres.git
synced 2026-02-12 15:23:16 -05:00
This allows functions with multiple OUT parameters returning both one or multiple records (RECORD or SETOF RECORD). Jan Urbański, reviewed by Hitoshi Harada
336 lines
7.9 KiB
Text
336 lines
7.9 KiB
Text
--
|
|
-- Test returning tuples
|
|
--
|
|
CREATE TABLE table_record (
|
|
first text,
|
|
second int4
|
|
) ;
|
|
CREATE TYPE type_record AS (
|
|
first text,
|
|
second int4
|
|
) ;
|
|
CREATE FUNCTION test_table_record_as(typ text, first text, second integer, retnull boolean) RETURNS table_record AS $$
|
|
if retnull:
|
|
return None
|
|
if typ == 'dict':
|
|
return { 'first': first, 'second': second, 'additionalfield': 'must not cause trouble' }
|
|
elif typ == 'tuple':
|
|
return ( first, second )
|
|
elif typ == 'list':
|
|
return [ first, second ]
|
|
elif typ == 'obj':
|
|
class type_record: pass
|
|
type_record.first = first
|
|
type_record.second = second
|
|
return type_record
|
|
$$ LANGUAGE plpythonu;
|
|
CREATE FUNCTION test_type_record_as(typ text, first text, second integer, retnull boolean) RETURNS type_record AS $$
|
|
if retnull:
|
|
return None
|
|
if typ == 'dict':
|
|
return { 'first': first, 'second': second, 'additionalfield': 'must not cause trouble' }
|
|
elif typ == 'tuple':
|
|
return ( first, second )
|
|
elif typ == 'list':
|
|
return [ first, second ]
|
|
elif typ == 'obj':
|
|
class type_record: pass
|
|
type_record.first = first
|
|
type_record.second = second
|
|
return type_record
|
|
$$ LANGUAGE plpythonu;
|
|
CREATE FUNCTION test_in_out_params(first in text, second out text) AS $$
|
|
return first + '_in_to_out';
|
|
$$ LANGUAGE plpythonu;
|
|
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;
|
|
CREATE FUNCTION test_inout_params(first inout text) AS $$
|
|
return first + '_inout';
|
|
$$ LANGUAGE plpythonu;
|
|
-- Test tuple returning functions
|
|
SELECT * FROM test_table_record_as('dict', null, null, false);
|
|
first | second
|
|
-------+--------
|
|
|
|
|
(1 row)
|
|
|
|
SELECT * FROM test_table_record_as('dict', 'one', null, false);
|
|
first | second
|
|
-------+--------
|
|
one |
|
|
(1 row)
|
|
|
|
SELECT * FROM test_table_record_as('dict', null, 2, false);
|
|
first | second
|
|
-------+--------
|
|
| 2
|
|
(1 row)
|
|
|
|
SELECT * FROM test_table_record_as('dict', 'three', 3, false);
|
|
first | second
|
|
-------+--------
|
|
three | 3
|
|
(1 row)
|
|
|
|
SELECT * FROM test_table_record_as('dict', null, null, true);
|
|
first | second
|
|
-------+--------
|
|
|
|
|
(1 row)
|
|
|
|
SELECT * FROM test_table_record_as('tuple', null, null, false);
|
|
first | second
|
|
-------+--------
|
|
|
|
|
(1 row)
|
|
|
|
SELECT * FROM test_table_record_as('tuple', 'one', null, false);
|
|
first | second
|
|
-------+--------
|
|
one |
|
|
(1 row)
|
|
|
|
SELECT * FROM test_table_record_as('tuple', null, 2, false);
|
|
first | second
|
|
-------+--------
|
|
| 2
|
|
(1 row)
|
|
|
|
SELECT * FROM test_table_record_as('tuple', 'three', 3, false);
|
|
first | second
|
|
-------+--------
|
|
three | 3
|
|
(1 row)
|
|
|
|
SELECT * FROM test_table_record_as('tuple', null, null, true);
|
|
first | second
|
|
-------+--------
|
|
|
|
|
(1 row)
|
|
|
|
SELECT * FROM test_table_record_as('list', null, null, false);
|
|
first | second
|
|
-------+--------
|
|
|
|
|
(1 row)
|
|
|
|
SELECT * FROM test_table_record_as('list', 'one', null, false);
|
|
first | second
|
|
-------+--------
|
|
one |
|
|
(1 row)
|
|
|
|
SELECT * FROM test_table_record_as('list', null, 2, false);
|
|
first | second
|
|
-------+--------
|
|
| 2
|
|
(1 row)
|
|
|
|
SELECT * FROM test_table_record_as('list', 'three', 3, false);
|
|
first | second
|
|
-------+--------
|
|
three | 3
|
|
(1 row)
|
|
|
|
SELECT * FROM test_table_record_as('list', null, null, true);
|
|
first | second
|
|
-------+--------
|
|
|
|
|
(1 row)
|
|
|
|
SELECT * FROM test_table_record_as('obj', null, null, false);
|
|
first | second
|
|
-------+--------
|
|
|
|
|
(1 row)
|
|
|
|
SELECT * FROM test_table_record_as('obj', 'one', null, false);
|
|
first | second
|
|
-------+--------
|
|
one |
|
|
(1 row)
|
|
|
|
SELECT * FROM test_table_record_as('obj', null, 2, false);
|
|
first | second
|
|
-------+--------
|
|
| 2
|
|
(1 row)
|
|
|
|
SELECT * FROM test_table_record_as('obj', 'three', 3, false);
|
|
first | second
|
|
-------+--------
|
|
three | 3
|
|
(1 row)
|
|
|
|
SELECT * FROM test_table_record_as('obj', null, null, true);
|
|
first | second
|
|
-------+--------
|
|
|
|
|
(1 row)
|
|
|
|
SELECT * FROM test_type_record_as('dict', null, null, false);
|
|
first | second
|
|
-------+--------
|
|
|
|
|
(1 row)
|
|
|
|
SELECT * FROM test_type_record_as('dict', 'one', null, false);
|
|
first | second
|
|
-------+--------
|
|
one |
|
|
(1 row)
|
|
|
|
SELECT * FROM test_type_record_as('dict', null, 2, false);
|
|
first | second
|
|
-------+--------
|
|
| 2
|
|
(1 row)
|
|
|
|
SELECT * FROM test_type_record_as('dict', 'three', 3, false);
|
|
first | second
|
|
-------+--------
|
|
three | 3
|
|
(1 row)
|
|
|
|
SELECT * FROM test_type_record_as('dict', null, null, true);
|
|
first | second
|
|
-------+--------
|
|
|
|
|
(1 row)
|
|
|
|
SELECT * FROM test_type_record_as('tuple', null, null, false);
|
|
first | second
|
|
-------+--------
|
|
|
|
|
(1 row)
|
|
|
|
SELECT * FROM test_type_record_as('tuple', 'one', null, false);
|
|
first | second
|
|
-------+--------
|
|
one |
|
|
(1 row)
|
|
|
|
SELECT * FROM test_type_record_as('tuple', null, 2, false);
|
|
first | second
|
|
-------+--------
|
|
| 2
|
|
(1 row)
|
|
|
|
SELECT * FROM test_type_record_as('tuple', 'three', 3, false);
|
|
first | second
|
|
-------+--------
|
|
three | 3
|
|
(1 row)
|
|
|
|
SELECT * FROM test_type_record_as('tuple', null, null, true);
|
|
first | second
|
|
-------+--------
|
|
|
|
|
(1 row)
|
|
|
|
SELECT * FROM test_type_record_as('list', null, null, false);
|
|
first | second
|
|
-------+--------
|
|
|
|
|
(1 row)
|
|
|
|
SELECT * FROM test_type_record_as('list', 'one', null, false);
|
|
first | second
|
|
-------+--------
|
|
one |
|
|
(1 row)
|
|
|
|
SELECT * FROM test_type_record_as('list', null, 2, false);
|
|
first | second
|
|
-------+--------
|
|
| 2
|
|
(1 row)
|
|
|
|
SELECT * FROM test_type_record_as('list', 'three', 3, false);
|
|
first | second
|
|
-------+--------
|
|
three | 3
|
|
(1 row)
|
|
|
|
SELECT * FROM test_type_record_as('list', null, null, true);
|
|
first | second
|
|
-------+--------
|
|
|
|
|
(1 row)
|
|
|
|
SELECT * FROM test_type_record_as('obj', null, null, false);
|
|
first | second
|
|
-------+--------
|
|
|
|
|
(1 row)
|
|
|
|
SELECT * FROM test_type_record_as('obj', 'one', null, false);
|
|
first | second
|
|
-------+--------
|
|
one |
|
|
(1 row)
|
|
|
|
SELECT * FROM test_type_record_as('obj', null, 2, false);
|
|
first | second
|
|
-------+--------
|
|
| 2
|
|
(1 row)
|
|
|
|
SELECT * FROM test_type_record_as('obj', 'three', 3, false);
|
|
first | second
|
|
-------+--------
|
|
three | 3
|
|
(1 row)
|
|
|
|
SELECT * FROM test_type_record_as('obj', null, null, true);
|
|
first | second
|
|
-------+--------
|
|
|
|
|
(1 row)
|
|
|
|
SELECT * FROM test_in_out_params('test_in');
|
|
second
|
|
-------------------
|
|
test_in_in_to_out
|
|
(1 row)
|
|
|
|
SELECT * FROM test_in_out_params_multi('test_in');
|
|
second | third
|
|
----------------------------+----------------------------
|
|
test_in_record_in_to_out_1 | test_in_record_in_to_out_2
|
|
(1 row)
|
|
|
|
SELECT * FROM test_inout_params('test_in');
|
|
first
|
|
---------------
|
|
test_in_inout
|
|
(1 row)
|
|
|
|
-- errors cases
|
|
CREATE FUNCTION test_type_record_error1() RETURNS type_record AS $$
|
|
return { 'first': 'first' }
|
|
$$ LANGUAGE plpythonu;
|
|
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.
|
|
CONTEXT: while creating return value
|
|
PL/Python function "test_type_record_error1"
|
|
CREATE FUNCTION test_type_record_error2() RETURNS type_record AS $$
|
|
return [ 'first' ]
|
|
$$ LANGUAGE plpythonu;
|
|
SELECT * FROM test_type_record_error2();
|
|
ERROR: length of returned sequence did not match number of columns in row
|
|
CONTEXT: while creating return value
|
|
PL/Python function "test_type_record_error2"
|
|
CREATE FUNCTION test_type_record_error3() RETURNS type_record AS $$
|
|
class type_record: pass
|
|
type_record.first = 'first'
|
|
return type_record
|
|
$$ LANGUAGE plpythonu;
|
|
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.
|
|
CONTEXT: while creating return value
|
|
PL/Python function "test_type_record_error3"
|