summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/pl/plpython/expected/plpython_record.out9
-rw-r--r--src/pl/plpython/expected/plpython_trigger.out12
-rw-r--r--src/pl/plpython/expected/plpython_types.out9
-rw-r--r--src/pl/plpython/expected/plpython_unicode.out10
-rw-r--r--src/pl/plpython/expected/plpython_unicode_2.out10
-rw-r--r--src/pl/plpython/expected/plpython_unicode_3.out10
-rw-r--r--src/pl/plpython/expected/plpython_void.out3
-rw-r--r--src/pl/plpython/plpython.c34
8 files changed, 71 insertions, 26 deletions
diff --git a/src/pl/plpython/expected/plpython_record.out b/src/pl/plpython/expected/plpython_record.out
index 9e4645d56cb..c8c4f9d5a3c 100644
--- a/src/pl/plpython/expected/plpython_record.out
+++ b/src/pl/plpython/expected/plpython_record.out
@@ -313,13 +313,15 @@ $$ 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: PL/Python function "test_type_record_error1"
+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: PL/Python function "test_type_record_error2"
+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'
@@ -328,4 +330,5 @@ $$ 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: PL/Python function "test_type_record_error3"
+CONTEXT: while creating return value
+PL/Python function "test_type_record_error3"
diff --git a/src/pl/plpython/expected/plpython_trigger.out b/src/pl/plpython/expected/plpython_trigger.out
index b60796dab5b..6be1c9dd0c1 100644
--- a/src/pl/plpython/expected/plpython_trigger.out
+++ b/src/pl/plpython/expected/plpython_trigger.out
@@ -353,7 +353,8 @@ BEFORE UPDATE ON trigger_test
FOR EACH ROW EXECUTE PROCEDURE stupid4();
UPDATE trigger_test SET v = 'null' WHERE i = 0;
ERROR: TD["new"] deleted, cannot modify row
-CONTEXT: PL/Python function "stupid4"
+CONTEXT: while modifying trigger row
+PL/Python function "stupid4"
DROP TRIGGER stupid_trigger4 ON trigger_test;
-- TD not a dictionary
CREATE FUNCTION stupid5() RETURNS trigger
@@ -366,7 +367,8 @@ BEFORE UPDATE ON trigger_test
FOR EACH ROW EXECUTE PROCEDURE stupid5();
UPDATE trigger_test SET v = 'null' WHERE i = 0;
ERROR: TD["new"] is not a dictionary
-CONTEXT: PL/Python function "stupid5"
+CONTEXT: while modifying trigger row
+PL/Python function "stupid5"
DROP TRIGGER stupid_trigger5 ON trigger_test;
-- TD not having string keys
CREATE FUNCTION stupid6() RETURNS trigger
@@ -379,7 +381,8 @@ BEFORE UPDATE ON trigger_test
FOR EACH ROW EXECUTE PROCEDURE stupid6();
UPDATE trigger_test SET v = 'null' WHERE i = 0;
ERROR: TD["new"] dictionary key at ordinal position 0 is not a string
-CONTEXT: PL/Python function "stupid6"
+CONTEXT: while modifying trigger row
+PL/Python function "stupid6"
DROP TRIGGER stupid_trigger6 ON trigger_test;
-- TD keys not corresponding to row columns
CREATE FUNCTION stupid7() RETURNS trigger
@@ -392,7 +395,8 @@ BEFORE UPDATE ON trigger_test
FOR EACH ROW EXECUTE PROCEDURE stupid7();
UPDATE trigger_test SET v = 'null' WHERE i = 0;
ERROR: key "a" found in TD["new"] does not exist as a column in the triggering row
-CONTEXT: PL/Python function "stupid7"
+CONTEXT: while modifying trigger row
+PL/Python function "stupid7"
DROP TRIGGER stupid_trigger7 ON trigger_test;
-- calling a trigger function directly
SELECT stupid7();
diff --git a/src/pl/plpython/expected/plpython_types.out b/src/pl/plpython/expected/plpython_types.out
index 476f32974be..19b3c9e47a1 100644
--- a/src/pl/plpython/expected/plpython_types.out
+++ b/src/pl/plpython/expected/plpython_types.out
@@ -332,7 +332,8 @@ SELECT * FROM test_type_conversion_uint2(100::uint2, -50);
INFO: (100, <type 'int'>)
CONTEXT: PL/Python function "test_type_conversion_uint2"
ERROR: value for domain uint2 violates check constraint "uint2_check"
-CONTEXT: PL/Python function "test_type_conversion_uint2"
+CONTEXT: while creating return value
+PL/Python function "test_type_conversion_uint2"
SELECT * FROM test_type_conversion_uint2(null, 1);
INFO: (None, <type 'NoneType'>)
CONTEXT: PL/Python function "test_type_conversion_uint2"
@@ -360,11 +361,13 @@ SELECT * FROM test_type_conversion_bytea10('hello word', 'hello world');
INFO: ('\\x68656c6c6f20776f7264', <type 'str'>)
CONTEXT: PL/Python function "test_type_conversion_bytea10"
ERROR: value for domain bytea10 violates check constraint "bytea10_check"
-CONTEXT: PL/Python function "test_type_conversion_bytea10"
+CONTEXT: while creating return value
+PL/Python function "test_type_conversion_bytea10"
SELECT * FROM test_type_conversion_bytea10(null, 'hello word');
ERROR: value for domain bytea10 violates check constraint "bytea10_check"
SELECT * FROM test_type_conversion_bytea10('hello word', null);
INFO: ('\\x68656c6c6f20776f7264', <type 'str'>)
CONTEXT: PL/Python function "test_type_conversion_bytea10"
ERROR: value for domain bytea10 violates check constraint "bytea10_check"
-CONTEXT: PL/Python function "test_type_conversion_bytea10"
+CONTEXT: while creating return value
+PL/Python function "test_type_conversion_bytea10"
diff --git a/src/pl/plpython/expected/plpython_unicode.out b/src/pl/plpython/expected/plpython_unicode.out
index ce19eb980c2..d3b6fd1db73 100644
--- a/src/pl/plpython/expected/plpython_unicode.out
+++ b/src/pl/plpython/expected/plpython_unicode.out
@@ -24,13 +24,15 @@ rv = plpy.execute(plan, u"\\x80", 1)
return rv[0]["testvalue1"]
' LANGUAGE plpythonu;
SELECT unicode_return_error();
-ERROR: PL/Python: could not create string representation of Python object, while creating return value
+ERROR: PL/Python: could not create string representation of Python object
DETAIL: <type 'exceptions.UnicodeEncodeError'>: 'ascii' codec can't encode character u'\x80' in position 0: ordinal not in range(128)
-CONTEXT: PL/Python function "unicode_return_error"
+CONTEXT: while creating return value
+PL/Python function "unicode_return_error"
INSERT INTO unicode_test (testvalue) VALUES ('test');
-ERROR: PL/Python: could not compute string representation of Python object, while modifying trigger row
+ERROR: PL/Python: could not create string representation of Python object
DETAIL: <type 'exceptions.UnicodeEncodeError'>: 'ascii' codec can't encode character u'\x80' in position 0: ordinal not in range(128)
-CONTEXT: PL/Python function "unicode_trigger_error"
+CONTEXT: while modifying trigger row
+PL/Python function "unicode_trigger_error"
SELECT unicode_plan_error1();
WARNING: PL/Python: <class 'plpy.Error'>: unrecognized error in PLy_spi_execute_plan
CONTEXT: PL/Python function "unicode_plan_error1"
diff --git a/src/pl/plpython/expected/plpython_unicode_2.out b/src/pl/plpython/expected/plpython_unicode_2.out
index 9280fe7dde9..1f393fbef33 100644
--- a/src/pl/plpython/expected/plpython_unicode_2.out
+++ b/src/pl/plpython/expected/plpython_unicode_2.out
@@ -24,13 +24,15 @@ rv = plpy.execute(plan, u"\\x80", 1)
return rv[0]["testvalue1"]
' LANGUAGE plpythonu;
SELECT unicode_return_error();
-ERROR: PL/Python: could not create string representation of Python object, while creating return value
+ERROR: PL/Python: could not create string representation of Python object
DETAIL: exceptions.UnicodeError: ASCII encoding error: ordinal not in range(128)
-CONTEXT: PL/Python function "unicode_return_error"
+CONTEXT: while creating return value
+PL/Python function "unicode_return_error"
INSERT INTO unicode_test (testvalue) VALUES ('test');
-ERROR: PL/Python: could not compute string representation of Python object, while modifying trigger row
+ERROR: PL/Python: could not create string representation of Python object
DETAIL: exceptions.UnicodeError: ASCII encoding error: ordinal not in range(128)
-CONTEXT: PL/Python function "unicode_trigger_error"
+CONTEXT: while modifying trigger row
+PL/Python function "unicode_trigger_error"
SELECT unicode_plan_error1();
WARNING: PL/Python: plpy.Error: unrecognized error in PLy_spi_execute_plan
CONTEXT: PL/Python function "unicode_plan_error1"
diff --git a/src/pl/plpython/expected/plpython_unicode_3.out b/src/pl/plpython/expected/plpython_unicode_3.out
index f058e2b0988..620f9f57906 100644
--- a/src/pl/plpython/expected/plpython_unicode_3.out
+++ b/src/pl/plpython/expected/plpython_unicode_3.out
@@ -24,13 +24,15 @@ rv = plpy.execute(plan, u"\\x80", 1)
return rv[0]["testvalue1"]
' LANGUAGE plpythonu;
SELECT unicode_return_error();
-ERROR: PL/Python: could not create string representation of Python object, while creating return value
+ERROR: PL/Python: could not create string representation of Python object
DETAIL: exceptions.UnicodeEncodeError: 'ascii' codec can't encode character u'\x80' in position 0: ordinal not in range(128)
-CONTEXT: PL/Python function "unicode_return_error"
+CONTEXT: while creating return value
+PL/Python function "unicode_return_error"
INSERT INTO unicode_test (testvalue) VALUES ('test');
-ERROR: PL/Python: could not compute string representation of Python object, while modifying trigger row
+ERROR: PL/Python: could not create string representation of Python object
DETAIL: exceptions.UnicodeEncodeError: 'ascii' codec can't encode character u'\x80' in position 0: ordinal not in range(128)
-CONTEXT: PL/Python function "unicode_trigger_error"
+CONTEXT: while modifying trigger row
+PL/Python function "unicode_trigger_error"
SELECT unicode_plan_error1();
WARNING: PL/Python: plpy.Error: unrecognized error in PLy_spi_execute_plan
CONTEXT: PL/Python function "unicode_plan_error1"
diff --git a/src/pl/plpython/expected/plpython_void.out b/src/pl/plpython/expected/plpython_void.out
index d067de06c06..1080d12d6b2 100644
--- a/src/pl/plpython/expected/plpython_void.out
+++ b/src/pl/plpython/expected/plpython_void.out
@@ -20,7 +20,8 @@ SELECT test_void_func1(), test_void_func1() IS NULL AS "is null";
SELECT test_void_func2(); -- should fail
ERROR: PL/Python function with return type "void" did not return None
-CONTEXT: PL/Python function "test_void_func2"
+CONTEXT: while creating return value
+PL/Python function "test_void_func2"
SELECT test_return_none(), test_return_none() IS NULL AS "is null";
test_return_none | is null
------------------+---------
diff --git a/src/pl/plpython/plpython.c b/src/pl/plpython/plpython.c
index eec0288e493..4aba4ba95ad 100644
--- a/src/pl/plpython/plpython.c
+++ b/src/pl/plpython/plpython.c
@@ -1,7 +1,7 @@
/**********************************************************************
* plpython.c - python as a procedural language for PostgreSQL
*
- * $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.126 2009/08/25 08:14:42 petere Exp $
+ * $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.127 2009/08/25 12:44:59 petere Exp $
*
*********************************************************************
*/
@@ -339,6 +339,20 @@ plpython_error_callback(void *arg)
errcontext("PL/Python function \"%s\"", PLy_procedure_name(PLy_curr_procedure));
}
+static void
+plpython_trigger_error_callback(void *arg)
+{
+ if (PLy_curr_procedure)
+ errcontext("while modifying trigger row");
+}
+
+static void
+plpython_return_error_callback(void *arg)
+{
+ if (PLy_curr_procedure)
+ errcontext("while creating return value");
+}
+
Datum
plpython_call_handler(PG_FUNCTION_ARGS)
{
@@ -506,6 +520,11 @@ PLy_modify_tuple(PLyProcedure *proc, PyObject *pltd, TriggerData *tdata,
Datum *volatile modvalues;
char *volatile modnulls;
TupleDesc tupdesc;
+ ErrorContextCallback plerrcontext;
+
+ plerrcontext.callback = plpython_trigger_error_callback;
+ plerrcontext.previous = error_context_stack;
+ error_context_stack = &plerrcontext;
plntup = plkeys = platt = plval = plstr = NULL;
modattrs = NULL;
@@ -563,7 +582,7 @@ PLy_modify_tuple(PLyProcedure *proc, PyObject *pltd, TriggerData *tdata,
{
plstr = PyObject_Str(plval);
if (!plstr)
- PLy_elog(ERROR, "could not compute string representation of Python object, while modifying trigger row");
+ PLy_elog(ERROR, "could not create string representation of Python object");
src = PyString_AsString(plstr);
modvalues[i] =
@@ -620,6 +639,8 @@ PLy_modify_tuple(PLyProcedure *proc, PyObject *pltd, TriggerData *tdata,
pfree(modvalues);
pfree(modnulls);
+ error_context_stack = plerrcontext.previous;
+
return rtup;
}
@@ -811,6 +832,7 @@ PLy_function_handler(FunctionCallInfo fcinfo, PLyProcedure *proc)
PyObject *volatile plrv = NULL;
PyObject *volatile plrv_so = NULL;
char *plrv_sc;
+ ErrorContextCallback plerrcontext;
PG_TRY();
{
@@ -901,6 +923,10 @@ PLy_function_handler(FunctionCallInfo fcinfo, PLyProcedure *proc)
}
}
+ plerrcontext.callback = plpython_return_error_callback;
+ plerrcontext.previous = error_context_stack;
+ error_context_stack = &plerrcontext;
+
/*
* If the function is declared to return void, the Python return value
* must be None. For void-returning functions, we also treat a None
@@ -959,7 +985,7 @@ PLy_function_handler(FunctionCallInfo fcinfo, PLyProcedure *proc)
fcinfo->isnull = false;
plrv_so = PyObject_Str(plrv);
if (!plrv_so)
- PLy_elog(ERROR, "could not create string representation of Python object, while creating return value");
+ PLy_elog(ERROR, "could not create string representation of Python object");
plrv_sc = PyString_AsString(plrv_so);
rv = InputFunctionCall(&proc->result.out.d.typfunc,
plrv_sc,
@@ -977,6 +1003,8 @@ PLy_function_handler(FunctionCallInfo fcinfo, PLyProcedure *proc)
}
PG_END_TRY();
+ error_context_stack = plerrcontext.previous;
+
Py_XDECREF(plargs);
Py_DECREF(plrv);
Py_XDECREF(plrv_so);