diff --git a/src/pl/plpython/expected/plpython_unicode_2.out b/src/pl/plpython/expected/plpython_unicode_2.out
index d6bd823db8ca2d895b099f694d73327084d087de..1113bc7696418be7ec5cae51d9145a508c4c69c4 100644
--- a/src/pl/plpython/expected/plpython_unicode_2.out
+++ b/src/pl/plpython/expected/plpython_unicode_2.out
@@ -41,7 +41,7 @@ SELECT * FROM unicode_test;
 SELECT unicode_plan1();
 WARNING:  PL/Python: plpy.Error: unrecognized error in PLy_spi_execute_plan
 CONTEXT:  PL/Python function "unicode_plan1"
-ERROR:  PL/Python: could not convert Python Unicode object to PostgreSQL server encoding
+ERROR:  PL/Python: plpy.SPIError: PL/Python: could not convert Python Unicode object to PostgreSQL server encoding
 DETAIL:  UnicodeError: ASCII encoding error: ordinal not in range(128)
 CONTEXT:  PL/Python function "unicode_plan1"
 SELECT unicode_plan2();
diff --git a/src/pl/plpython/expected/plpython_unicode_3.out b/src/pl/plpython/expected/plpython_unicode_3.out
index 05f3e306fab156692d87fec982ca071525079991..2b5f3b13050343cffb3315ba8df55ff2df874385 100644
--- a/src/pl/plpython/expected/plpython_unicode_3.out
+++ b/src/pl/plpython/expected/plpython_unicode_3.out
@@ -42,6 +42,7 @@ SELECT unicode_plan1();
 WARNING:  PL/Python: plpy.Error: unrecognized error in PLy_spi_execute_plan
 CONTEXT:  PL/Python function "unicode_plan1"
 ERROR:  PL/Python: plpy.SPIError: PL/Python: could not convert Python Unicode object to PostgreSQL server encoding
+DETAIL:  UnicodeEncodeError: 'ascii' codec can't encode character u'\x80' in position 0: ordinal not in range(128)
 CONTEXT:  PL/Python function "unicode_plan1"
 SELECT unicode_plan2();
  unicode_plan2 
diff --git a/src/pl/plpython/plpython.c b/src/pl/plpython/plpython.c
index 0b75fe6136f902fd535132375de32315ccf4a384..6bcb4cc049b21818908e31692749efb02f55cfc9 100644
--- a/src/pl/plpython/plpython.c
+++ b/src/pl/plpython/plpython.c
@@ -294,7 +294,7 @@ static char *PLy_procedure_name(PLyProcedure *);
 static void
 PLy_elog(int, const char *,...)
 __attribute__((format(printf, 2, 3)));
-static void PLy_get_spi_error_data(PyObject *exc, char **hint, char **query, int *position);
+static void PLy_get_spi_error_data(PyObject *exc, char **detail, char **hint, char **query, int *position);
 static char *PLy_traceback(int *);
 
 static void *PLy_malloc(size_t);
@@ -3551,7 +3551,7 @@ PLy_spi_exception_set(ErrorData *edata)
 	if (!spierror)
 		goto failure;
 
-	spidata = Py_BuildValue("(zzi)", edata->hint,
+	spidata = Py_BuildValue("(zzzi)", edata->detail, edata->hint,
 							edata->internalquery, edata->internalpos);
 	if (!spidata)
 		goto failure;
@@ -3586,13 +3586,14 @@ PLy_elog(int elevel, const char *fmt,...)
 	int			xlevel;
 	StringInfoData emsg;
 	PyObject	*exc, *val, *tb;
+	char		*detail = NULL;
 	char		*hint = NULL;
 	char		*query = NULL;
 	int			position = 0;
 
 	PyErr_Fetch(&exc, &val, &tb);
 	if (exc != NULL && PyErr_GivenExceptionMatches(val, PLy_exc_spi_error))
-		PLy_get_spi_error_data(val, &hint, &query, &position);
+		PLy_get_spi_error_data(val, &detail, &hint, &query, &position);
 	PyErr_Restore(exc, val, tb);
 
 	xmsg = PLy_traceback(&xlevel);
@@ -3626,6 +3627,7 @@ PLy_elog(int elevel, const char *fmt,...)
 		else
 			ereport(elevel,
 					(errmsg("PL/Python: %s", xmsg),
+					 (detail) ? errdetail("%s", detail) : 0,
 					 (hint) ? errhint("%s", hint) : 0,
 					 (query) ? internalerrquery(query) : 0,
 					 (position) ? internalerrposition(position) : 0));
@@ -3650,7 +3652,7 @@ PLy_elog(int elevel, const char *fmt,...)
  * Extract the error data from a SPIError
  */
 static void
-PLy_get_spi_error_data(PyObject *exc, char **hint, char **query, int *position)
+PLy_get_spi_error_data(PyObject *exc, char **detail, char **hint, char **query, int *position)
 {
 	PyObject	*spidata = NULL;
 
@@ -3658,7 +3660,7 @@ PLy_get_spi_error_data(PyObject *exc, char **hint, char **query, int *position)
 	if (!spidata)
 		goto cleanup;
 
-	if (!PyArg_ParseTuple(spidata, "zzi", hint, query, position))
+	if (!PyArg_ParseTuple(spidata, "zzzi", detail, hint, query, position))
 		goto cleanup;
 
 cleanup: