mirror of
https://github.com/postgres/postgres.git
synced 2026-01-13 12:22:55 +03:00
Extract the "while creating return value" and "while modifying trigger row" parts of some error messages into another layer of error context. This will simplify the upcoming patch to improve data type support, but it can stand on its own.
335 lines
7.8 KiB
Plaintext
335 lines
7.8 KiB
Plaintext
--
|
|
-- 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;
|
|
-- this doesn't work yet :-(
|
|
CREATE FUNCTION test_in_out_params_multi(first in text,
|
|
second out text, third out text) AS $$
|
|
return first + '_record_in_to_out';
|
|
$$ 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)
|
|
|
|
-- this doesn't work yet :-(
|
|
SELECT * FROM test_in_out_params_multi('test_in');
|
|
ERROR: PL/Python functions cannot return type record
|
|
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"
|