postgres.git / summary / log / commit / refs

commit    bb65f3c1b25fa7a7e7afe6d4b2fd68c85dd880da
Author:   Michael Paquier <michael@paquier.xyz>
Date:     Mon Sep 18 23:31:26 2023 +0000

    Fix assertion failure with PL/Python exceptions
    
    PLy_elog() was not able to handle correctly cases where a SPI called
    failed, which would fill in a DETAIL string able to trigger an
    assertion.  We may want to improve this infrastructure so as it is able
    to provide any extra detail information provided by an error stack, but
    this is left as a future improvement as it could impact existing error
    stacks and any applications that depend on them.  For now, the assertion
    is removed and a regression test is added to cover the case of a failure
    with a detail string.
    
    This problem exists since 2bd78eb8d51c, so backpatch all the way down
    with tweaks to the regression tests output added where required.
    
    Author: Alexander Lakhin
    Discussion: https://postgr.es/m/18070-ab9c171cbf4ebb0f@postgresql.org
    Backpatch-through: 11


src/pl/plpython/expected/plpython_error.out | 13 +++++++++++++ src/pl/plpython/expected/plpython_error_5.out | 13 +++++++++++++ src/pl/plpython/plpy_elog.c | 3 --- src/pl/plpython/sql/plpython_error.sql | 11 +++++++++++ 4 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/pl/plpython/expected/plpython_error.out b/src/pl/plpython/expected/plpython_error.out index b2f8fe83eb6..0f1bab13b6b 100644 --- a/src/pl/plpython/expected/plpython_error.out +++ b/src/pl/plpython/expected/plpython_error.out @@ -445,3 +445,16 @@ PL/Python function "notice_outerfunc" 1 (1 row) +/* test error logged with an underlying exception that includes a detail + * string (bug #18070). + */ +CREATE FUNCTION python_error_detail() RETURNS SETOF text AS $$ + plan = plpy.prepare("SELECT to_date('xy', 'DD') d") + for row in plpy.cursor(plan): + yield row['d'] +$$ LANGUAGE plpythonu; +SELECT python_error_detail(); +ERROR: error fetching next item from iterator +DETAIL: spiexceptions.InvalidDatetimeFormat: invalid value "xy" for "DD" +CONTEXT: Traceback (most recent call last): +PL/Python function "python_error_detail" diff --git a/src/pl/plpython/expected/plpython_error_5.out b/src/pl/plpython/expected/plpython_error_5.out index bc66ab55340..0e67b5a5751 100644 --- a/src/pl/plpython/expected/plpython_error_5.out +++ b/src/pl/plpython/expected/plpython_error_5.out @@ -445,3 +445,16 @@ PL/Python function "notice_outerfunc" 1 (1 row) +/* test error logged with an underlying exception that includes a detail + * string (bug #18070). + */ +CREATE FUNCTION python_error_detail() RETURNS SETOF text AS $$ + plan = plpy.prepare("SELECT to_date('xy', 'DD') d") + for row in plpy.cursor(plan): + yield row['d'] +$$ LANGUAGE plpythonu; +SELECT python_error_detail(); +ERROR: error fetching next item from iterator +DETAIL: spiexceptions.InvalidDatetimeFormat: invalid value "xy" for "DD" +CONTEXT: Traceback (most recent call last): +PL/Python function "python_error_detail" diff --git a/src/pl/plpython/plpy_elog.c b/src/pl/plpython/plpy_elog.c index 224b8836fba..9b5b3bed2f5 100644 --- a/src/pl/plpython/plpy_elog.c +++ b/src/pl/plpython/plpy_elog.c @@ -103,9 +103,6 @@ PLy_elog_impl(int elevel, const char *fmt,...) } primary = emsg.data; - /* Since we have a format string, we cannot have a SPI detail. */ - Assert(detail == NULL); - /* If there's an exception message, it goes in the detail. */ if (xmsg) detail = xmsg; diff --git a/src/pl/plpython/sql/plpython_error.sql b/src/pl/plpython/sql/plpython_error.sql index 88d6936fd0d..8d86bf7d1e0 100644 --- a/src/pl/plpython/sql/plpython_error.sql +++ b/src/pl/plpython/sql/plpython_error.sql @@ -344,3 +344,14 @@ $$ LANGUAGE plpythonu; \set SHOW_CONTEXT always SELECT notice_outerfunc(); + +/* test error logged with an underlying exception that includes a detail + * string (bug #18070). + */ +CREATE FUNCTION python_error_detail() RETURNS SETOF text AS $$ + plan = plpy.prepare("SELECT to_date('xy', 'DD') d") + for row in plpy.cursor(plan): + yield row['d'] +$$ LANGUAGE plpythonu; + +SELECT python_error_detail(); [parent: 9baabfa38e00]