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'
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"
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
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
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
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();
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"
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"
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"
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"
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"
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
------------------+---------
/**********************************************************************
* 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 $
*
*********************************************************************
*/
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)
{
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;
{
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] =
pfree(modvalues);
pfree(modnulls);
+ error_context_stack = plerrcontext.previous;
+
return rtup;
}
PyObject *volatile plrv = NULL;
PyObject *volatile plrv_so = NULL;
char *plrv_sc;
+ ErrorContextCallback plerrcontext;
PG_TRY();
{
}
}
+ 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
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,
}
PG_END_TRY();
+ error_context_stack = plerrcontext.previous;
+
Py_XDECREF(plargs);
Py_DECREF(plrv);
Py_XDECREF(plrv_so);