From 036166f26e00ab3286ef29a6519525d6291fdfd7 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter_e@gmx.net>
Date: Wed, 30 Aug 2017 22:16:50 -0400
Subject: [PATCH] Document and use SPI_result_code_string()

A lot of semi-internal code just prints out numeric SPI error codes,
which is not very helpful.  We already have an API function to convert
the codes to a string, so let's make more use of that.

Reviewed-by: Michael Paquier <michael.paquier@gmail.com>
---
 contrib/spi/refint.c                |  6 ++--
 contrib/spi/timetravel.c            |  2 +-
 doc/src/sgml/spi.sgml               | 53 +++++++++++++++++++++++++++++
 src/backend/utils/adt/ri_triggers.c | 10 +++---
 src/test/regress/regress.c          |  2 +-
 5 files changed, 63 insertions(+), 10 deletions(-)

diff --git a/contrib/spi/refint.c b/contrib/spi/refint.c
index 70def95ac5..2fc894e72a 100644
--- a/contrib/spi/refint.c
+++ b/contrib/spi/refint.c
@@ -182,7 +182,7 @@ check_primary_key(PG_FUNCTION_ARGS)
 		pplan = SPI_prepare(sql, nkeys, argtypes);
 		if (pplan == NULL)
 			/* internal error */
-			elog(ERROR, "check_primary_key: SPI_prepare returned %d", SPI_result);
+			elog(ERROR, "check_primary_key: SPI_prepare returned %s", SPI_result_code_string(SPI_result));
 
 		/*
 		 * Remember that SPI_prepare places plan in current memory context -
@@ -395,7 +395,7 @@ check_foreign_key(PG_FUNCTION_ARGS)
 			/* this shouldn't happen! SPI_ERROR_NOOUTFUNC ? */
 			if (oldval == NULL)
 				/* internal error */
-				elog(ERROR, "check_foreign_key: SPI_getvalue returned %d", SPI_result);
+				elog(ERROR, "check_foreign_key: SPI_getvalue returned %s", SPI_result_code_string(SPI_result));
 			newval = SPI_getvalue(newtuple, tupdesc, fnumber);
 			if (newval == NULL || strcmp(oldval, newval) != 0)
 				isequal = false;
@@ -529,7 +529,7 @@ check_foreign_key(PG_FUNCTION_ARGS)
 			pplan = SPI_prepare(sql, nkeys, argtypes);
 			if (pplan == NULL)
 				/* internal error */
-				elog(ERROR, "check_foreign_key: SPI_prepare returned %d", SPI_result);
+				elog(ERROR, "check_foreign_key: SPI_prepare returned %s", SPI_result_code_string(SPI_result));
 
 			/*
 			 * Remember that SPI_prepare places plan in current memory context
diff --git a/contrib/spi/timetravel.c b/contrib/spi/timetravel.c
index 816cc549ae..00f661e6b6 100644
--- a/contrib/spi/timetravel.c
+++ b/contrib/spi/timetravel.c
@@ -341,7 +341,7 @@ timetravel(PG_FUNCTION_ARGS)
 		/* Prepare plan for query */
 		pplan = SPI_prepare(sql, natts, ctypes);
 		if (pplan == NULL)
-			elog(ERROR, "timetravel (%s): SPI_prepare returned %d", relname, SPI_result);
+			elog(ERROR, "timetravel (%s): SPI_prepare returned %s", relname, SPI_result_code_string(SPI_result));
 
 		/*
 		 * Remember that SPI_prepare places plan in current memory context -
diff --git a/doc/src/sgml/spi.sgml b/doc/src/sgml/spi.sgml
index 31535a307d..3594f9dce1 100644
--- a/doc/src/sgml/spi.sgml
+++ b/doc/src/sgml/spi.sgml
@@ -3546,6 +3546,59 @@ char * SPI_getnspname(Relation <parameter>rel</parameter>)
  </refsect1>
 </refentry>
 
+<refentry id="spi-spi-result-code-string">
+ <indexterm><primary>SPI_result_code_string</primary></indexterm>
+
+ <refmeta>
+  <refentrytitle>SPI_result_code_string</refentrytitle>
+  <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+  <refname>SPI_result_code_string</refname>
+  <refpurpose>return error code as string</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+const char * SPI_result_code_string(int <parameter>code</parameter>);
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+  <title>Description</title>
+
+  <para>
+   <function>SPI_result_code_string</function> returns a string representation
+   of the result code returned by various SPI functions or stored
+   in <varname>SPI_result</varname>.
+  </para>
+ </refsect1>
+
+ <refsect1>
+  <title>Arguments</title>
+
+  <variablelist>
+   <varlistentry>
+    <term><literal>int <parameter>code</parameter></literal></term>
+    <listitem>
+     <para>
+      result code
+     </para>
+    </listitem>
+   </varlistentry>
+  </variablelist>
+ </refsect1>
+
+ <refsect1>
+  <title>Return Value</title>
+
+  <para>
+   A string representation of the result code.
+  </para>
+ </refsect1>
+</refentry>
+
  </sect1>
 
  <sect1 id="spi-memory">
diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c
index b63a7775b7..ba0e3ad87d 100644
--- a/src/backend/utils/adt/ri_triggers.c
+++ b/src/backend/utils/adt/ri_triggers.c
@@ -2435,8 +2435,8 @@ RI_Initial_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel)
 	qplan = SPI_prepare(querybuf.data, 0, NULL);
 
 	if (qplan == NULL)
-		elog(ERROR, "SPI_prepare returned %d for %s",
-			 SPI_result, querybuf.data);
+		elog(ERROR, "SPI_prepare returned %s for %s",
+			 SPI_result_code_string(SPI_result), querybuf.data);
 
 	/*
 	 * Run the plan.  For safety we force a current snapshot to be used. (In
@@ -2453,7 +2453,7 @@ RI_Initial_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel)
 
 	/* Check result */
 	if (spi_result != SPI_OK_SELECT)
-		elog(ERROR, "SPI_execute_snapshot returned %d", spi_result);
+		elog(ERROR, "SPI_execute_snapshot returned %s", SPI_result_code_string(spi_result));
 
 	/* Did we find a tuple violating the constraint? */
 	if (SPI_processed > 0)
@@ -3016,7 +3016,7 @@ ri_PlanCheck(const char *querystr, int nargs, Oid *argtypes,
 	qplan = SPI_prepare(querystr, nargs, argtypes);
 
 	if (qplan == NULL)
-		elog(ERROR, "SPI_prepare returned %d for %s", SPI_result, querystr);
+		elog(ERROR, "SPI_prepare returned %s for %s", SPI_result_code_string(SPI_result), querystr);
 
 	/* Restore UID and security context */
 	SetUserIdAndSecContext(save_userid, save_sec_context);
@@ -3144,7 +3144,7 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo,
 
 	/* Check result */
 	if (spi_result < 0)
-		elog(ERROR, "SPI_execute_snapshot returned %d", spi_result);
+		elog(ERROR, "SPI_execute_snapshot returned %s", SPI_result_code_string(spi_result));
 
 	if (expect_OK >= 0 && spi_result != expect_OK)
 		ereport(ERROR,
diff --git a/src/test/regress/regress.c b/src/test/regress/regress.c
index 0a123f2b39..0e9e46e667 100644
--- a/src/test/regress/regress.c
+++ b/src/test/regress/regress.c
@@ -612,7 +612,7 @@ ttdummy(PG_FUNCTION_ARGS)
 		/* Prepare plan for query */
 		pplan = SPI_prepare(query, natts, ctypes);
 		if (pplan == NULL)
-			elog(ERROR, "ttdummy (%s): SPI_prepare returned %d", relname, SPI_result);
+			elog(ERROR, "ttdummy (%s): SPI_prepare returned %s", relname, SPI_result_code_string(SPI_result));
 
 		if (SPI_keepplan(pplan))
 			elog(ERROR, "ttdummy (%s): SPI_keepplan failed", relname);