mirror of
https://git.postgresql.org/git/postgresql.git
synced 2026-02-08 04:07:33 +08:00
Wrap PL/Python SPI calls into subtransactions
This allows the language-specific try/catch construct to catch and handle exceptions arising from SPI calls, matching the behavior of other PLs. As an additional bonus you no longer get all the ugly "unrecognized error in PLy_spi_execute_query" errors. Jan Urbański, reviewed by Steve Singer
This commit is contained in:
@ -32,8 +32,6 @@ CREATE FUNCTION sql_syntax_error() RETURNS text
|
||||
'plpy.execute("syntax error")'
|
||||
LANGUAGE plpythonu;
|
||||
SELECT sql_syntax_error();
|
||||
WARNING: plpy.SPIError: unrecognized error in PLy_spi_execute_query
|
||||
CONTEXT: PL/Python function "sql_syntax_error"
|
||||
ERROR: plpy.SPIError: syntax error at or near "syntax"
|
||||
LINE 1: syntax error
|
||||
^
|
||||
@ -56,8 +54,6 @@ CREATE FUNCTION exception_index_invalid_nested() RETURNS text
|
||||
return rv[0]'
|
||||
LANGUAGE plpythonu;
|
||||
SELECT exception_index_invalid_nested();
|
||||
WARNING: plpy.SPIError: unrecognized error in PLy_spi_execute_query
|
||||
CONTEXT: PL/Python function "exception_index_invalid_nested"
|
||||
ERROR: plpy.SPIError: function test5(unknown) does not exist
|
||||
LINE 1: SELECT test5('foo')
|
||||
^
|
||||
@ -78,8 +74,6 @@ return None
|
||||
'
|
||||
LANGUAGE plpythonu;
|
||||
SELECT invalid_type_uncaught('rick');
|
||||
WARNING: plpy.SPIError: unrecognized error in PLy_spi_prepare
|
||||
CONTEXT: PL/Python function "invalid_type_uncaught"
|
||||
ERROR: plpy.SPIError: type "test" does not exist
|
||||
CONTEXT: PL/Python function "invalid_type_uncaught"
|
||||
/* for what it's worth catch the exception generated by
|
||||
@ -101,8 +95,6 @@ return None
|
||||
'
|
||||
LANGUAGE plpythonu;
|
||||
SELECT invalid_type_caught('rick');
|
||||
WARNING: plpy.SPIError: unrecognized error in PLy_spi_prepare
|
||||
CONTEXT: PL/Python function "invalid_type_caught"
|
||||
NOTICE: type "test" does not exist
|
||||
CONTEXT: PL/Python function "invalid_type_caught"
|
||||
invalid_type_caught
|
||||
@ -128,8 +120,6 @@ return None
|
||||
'
|
||||
LANGUAGE plpythonu;
|
||||
SELECT invalid_type_reraised('rick');
|
||||
WARNING: plpy.SPIError: unrecognized error in PLy_spi_prepare
|
||||
CONTEXT: PL/Python function "invalid_type_reraised"
|
||||
ERROR: plpy.Error: type "test" does not exist
|
||||
CONTEXT: PL/Python function "invalid_type_reraised"
|
||||
/* no typo no messing about
|
||||
@ -150,3 +140,25 @@ SELECT valid_type('rick');
|
||||
|
||||
(1 row)
|
||||
|
||||
/* manually starting subtransactions - a bad idea
|
||||
*/
|
||||
CREATE FUNCTION manual_subxact() RETURNS void AS $$
|
||||
plpy.execute("savepoint save")
|
||||
plpy.execute("create table foo(x integer)")
|
||||
plpy.execute("rollback to save")
|
||||
$$ LANGUAGE plpythonu;
|
||||
SELECT manual_subxact();
|
||||
ERROR: plpy.SPIError: SPI_execute failed: SPI_ERROR_TRANSACTION
|
||||
CONTEXT: PL/Python function "manual_subxact"
|
||||
/* same for prepared plans
|
||||
*/
|
||||
CREATE FUNCTION manual_subxact_prepared() RETURNS void AS $$
|
||||
save = plpy.prepare("savepoint save")
|
||||
rollback = plpy.prepare("rollback to save")
|
||||
plpy.execute(save)
|
||||
plpy.execute("create table foo(x integer)")
|
||||
plpy.execute(rollback)
|
||||
$$ LANGUAGE plpythonu;
|
||||
SELECT manual_subxact_prepared();
|
||||
ERROR: plpy.SPIError: SPI_execute_plan failed: SPI_ERROR_TRANSACTION
|
||||
CONTEXT: PL/Python function "manual_subxact_prepared"
|
||||
|
||||
Reference in New Issue
Block a user