aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Paquier <michael@paquier.xyz>2023-09-19 08:31:29 +0900
committerMichael Paquier <michael@paquier.xyz>2023-09-19 08:31:29 +0900
commit99d27e55ccac335317aa12a9440a946da915decf (patch)
treebcbec57e82eef5cdd71f37cd71f2be1fea98793f /src
parent1233370791fe12f7d9f7cb8b994cab70012bd961 (diff)
downloadpostgresql-99d27e55ccac335317aa12a9440a946da915decf.tar.gz
postgresql-99d27e55ccac335317aa12a9440a946da915decf.zip
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
Diffstat (limited to 'src')
-rw-r--r--src/pl/plpython/expected/plpython_error.out13
-rw-r--r--src/pl/plpython/expected/plpython_error_0.out13
-rw-r--r--src/pl/plpython/expected/plpython_error_5.out13
-rw-r--r--src/pl/plpython/plpy_elog.c3
-rw-r--r--src/pl/plpython/sql/plpython_error.sql11
5 files changed, 50 insertions, 3 deletions
diff --git a/src/pl/plpython/expected/plpython_error.out b/src/pl/plpython/expected/plpython_error.out
index 4d615b41cc5..94874668bad 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_0.out b/src/pl/plpython/expected/plpython_error_0.out
index 290902b1828..66684d94d86 100644
--- a/src/pl/plpython/expected/plpython_error_0.out
+++ b/src/pl/plpython/expected/plpython_error_0.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 25930f99d78..2576609de6b 100644
--- a/src/pl/plpython/plpy_elog.c
+++ b/src/pl/plpython/plpy_elog.c
@@ -107,9 +107,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 d712eb1078f..3f835051e75 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();