diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c index f2fa0a43163ab5c12fd7b0bd693fa23fe741c575..7840f5f787afc86854c829bf87f414da83455f73 100644 --- a/src/backend/executor/spi.c +++ b/src/backend/executor/spi.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.121 2004/07/27 05:10:51 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.122 2004/07/31 20:55:41 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -989,6 +989,68 @@ SPI_is_cursor_plan(void *plan) return false; } +/* + * SPI_result_code_string --- convert any SPI return code to a string + * + * This is often useful in error messages. Most callers will probably + * only pass negative (error-case) codes, but for generality we recognize + * the success codes too. + */ +const char * +SPI_result_code_string(int code) +{ + static char buf[64]; + + switch (code) + { + case SPI_ERROR_CONNECT: + return "SPI_ERROR_CONNECT"; + case SPI_ERROR_COPY: + return "SPI_ERROR_COPY"; + case SPI_ERROR_OPUNKNOWN: + return "SPI_ERROR_OPUNKNOWN"; + case SPI_ERROR_UNCONNECTED: + return "SPI_ERROR_UNCONNECTED"; + case SPI_ERROR_CURSOR: + return "SPI_ERROR_CURSOR"; + case SPI_ERROR_ARGUMENT: + return "SPI_ERROR_ARGUMENT"; + case SPI_ERROR_PARAM: + return "SPI_ERROR_PARAM"; + case SPI_ERROR_TRANSACTION: + return "SPI_ERROR_TRANSACTION"; + case SPI_ERROR_NOATTRIBUTE: + return "SPI_ERROR_NOATTRIBUTE"; + case SPI_ERROR_NOOUTFUNC: + return "SPI_ERROR_NOOUTFUNC"; + case SPI_ERROR_TYPUNKNOWN: + return "SPI_ERROR_TYPUNKNOWN"; + case SPI_OK_CONNECT: + return "SPI_OK_CONNECT"; + case SPI_OK_FINISH: + return "SPI_OK_FINISH"; + case SPI_OK_FETCH: + return "SPI_OK_FETCH"; + case SPI_OK_UTILITY: + return "SPI_OK_UTILITY"; + case SPI_OK_SELECT: + return "SPI_OK_SELECT"; + case SPI_OK_SELINTO: + return "SPI_OK_SELINTO"; + case SPI_OK_INSERT: + return "SPI_OK_INSERT"; + case SPI_OK_DELETE: + return "SPI_OK_DELETE"; + case SPI_OK_UPDATE: + return "SPI_OK_UPDATE"; + case SPI_OK_CURSOR: + return "SPI_OK_CURSOR"; + } + /* Unrecognized code ... return something useful ... */ + sprintf(buf, "Unrecognized SPI code %d", code); + return buf; +} + /* =================== private functions =================== */ /* diff --git a/src/include/executor/spi.h b/src/include/executor/spi.h index e283b55cecd194a812905c48945058351edaa59f..a946efa64acf609e3e365dcd1d14a0e93066f5e5 100644 --- a/src/include/executor/spi.h +++ b/src/include/executor/spi.h @@ -2,7 +2,7 @@ * * spi.h * - * $PostgreSQL: pgsql/src/include/executor/spi.h,v 1.45 2004/07/01 00:51:41 tgl Exp $ + * $PostgreSQL: pgsql/src/include/executor/spi.h,v 1.46 2004/07/31 20:55:42 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -93,6 +93,7 @@ extern int SPI_freeplan(void *plan); extern Oid SPI_getargtypeid(void *plan, int argIndex); extern int SPI_getargcount(void *plan); extern bool SPI_is_cursor_plan(void *plan); +extern const char *SPI_result_code_string(int code); extern HeapTuple SPI_copytuple(HeapTuple tuple); extern HeapTupleHeader SPI_returntuple(HeapTuple tuple, TupleDesc tupdesc); diff --git a/src/pl/plperl/spi_internal.c b/src/pl/plperl/spi_internal.c index 57d95a10f1c0d533b673be3dcd3ea052652f9ce1..8d17af5b542c5f26ae7a4123d1495ab487141079 100644 --- a/src/pl/plperl/spi_internal.c +++ b/src/pl/plperl/spi_internal.c @@ -9,10 +9,9 @@ #include "spi_internal.h" -static char* plperl_spi_status_string(int); - static HV* plperl_spi_execute_fetch_result(SPITupleTable*, int, int ); + int spi_DEBUG(void) { @@ -93,93 +92,35 @@ plperl_hash_from_tuple(HeapTuple tuple, TupleDesc tupdesc) static HV* plperl_spi_execute_fetch_result(SPITupleTable *tuptable, int processed, int status) { - HV *result; - AV *rows; - int i; result = newHV(); - rows = newAV(); - if (status == SPI_OK_UTILITY) - { - hv_store(result, "status", strlen("status"), newSVpv("SPI_OK_UTILITY",0), 0); - hv_store(result, "processed", strlen("processed"), newSViv(processed), 0); - } - else if (status != SPI_OK_SELECT) - { - hv_store(result, "status", strlen("status"), newSVpv((char*)plperl_spi_status_string(status),0), 0); - hv_store(result, "processed", strlen("processed"), newSViv(processed), 0); - } - else + hv_store(result, "status", strlen("status"), + newSVpv((char*)SPI_result_code_string(status),0), 0); + hv_store(result, "processed", strlen("processed"), + newSViv(processed), 0); + + if (status == SPI_OK_SELECT) { - hv_store(result, "status", strlen("status"), newSVpv((char*)plperl_spi_status_string(status),0), 0); - hv_store(result, "processed", strlen("processed"), newSViv(processed), 0); if (processed) { + AV *rows; HV *row; + int i; + + rows = newAV(); for (i = 0; i < processed; i++) { row = plperl_hash_from_tuple(tuptable->vals[i], tuptable->tupdesc); - av_store(rows, i, newRV_noinc((SV*)row)); + av_store(rows, i, newRV_noinc((SV*)row)); } - hv_store(result, "rows", strlen("rows"), newRV_noinc((SV*)rows), 0); - SPI_freetuptable(tuptable); + hv_store(result, "rows", strlen("rows"), + newRV_noinc((SV*)rows), 0); } } - return result; -} -static char* -plperl_spi_status_string(int status) -{ - switch(status){ - /*errors*/ - case SPI_ERROR_TYPUNKNOWN: - return "SPI_ERROR_TYPUNKNOWN"; - case SPI_ERROR_NOOUTFUNC: - return "SPI_ERROR_NOOUTFUNC"; - case SPI_ERROR_NOATTRIBUTE: - return "SPI_ERROR_NOATTRIBUTE"; - case SPI_ERROR_TRANSACTION: - return "SPI_ERROR_TRANSACTION"; - case SPI_ERROR_PARAM: - return "SPI_ERROR_PARAM"; - case SPI_ERROR_ARGUMENT: - return "SPI_ERROR_ARGUMENT"; - case SPI_ERROR_CURSOR: - return "SPI_ERROR_CURSOR"; - case SPI_ERROR_UNCONNECTED: - return "SPI_ERROR_UNCONNECTED"; - case SPI_ERROR_OPUNKNOWN: - return "SPI_ERROR_OPUNKNOWN"; - case SPI_ERROR_COPY: - return "SPI_ERROR_COPY"; - case SPI_ERROR_CONNECT: - return "SPI_ERROR_CONNECT"; - /*ok*/ - case SPI_OK_CONNECT: - return "SPI_OK_CONNECT"; - case SPI_OK_FINISH: - return "SPI_OK_FINISH"; - case SPI_OK_FETCH: - return "SPI_OK_FETCH"; - case SPI_OK_UTILITY: - return "SPI_OK_UTILITY"; - case SPI_OK_SELECT: - return "SPI_OK_SELECT"; - case SPI_OK_SELINTO: - return "SPI_OK_SELINTO"; - case SPI_OK_INSERT: - return "SPI_OK_INSERT"; - case SPI_OK_DELETE: - return "SPI_OK_DELETE"; - case SPI_OK_UPDATE: - return "SPI_OK_UPDATE"; - case SPI_OK_CURSOR: - return "SPI_OK_CURSOR"; - } + SPI_freetuptable(tuptable); - return "Unknown or Invalid code"; + return result; } - diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c index d8befe4d529cc5ea16eca827631eb2a08c3e7173..0950149a494763ef6d025b433a897b0f12872153 100644 --- a/src/pl/plpgsql/src/pl_exec.c +++ b/src/pl/plpgsql/src/pl_exec.c @@ -3,7 +3,7 @@ * procedural language * * IDENTIFICATION - * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.109 2004/07/31 07:39:20 tgl Exp $ + * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.110 2004/07/31 20:55:44 tgl Exp $ * * This software is copyrighted by Jan Wieck - Hamburg. * @@ -904,6 +904,7 @@ exec_stmt_block(PLpgSQL_execstate * estate, PLpgSQL_stmt_block * block) */ MemoryContext oldcontext = CurrentMemoryContext; volatile bool caught = false; + int xrc; /* * Start a subtransaction, and re-connect to SPI within it @@ -912,8 +913,9 @@ exec_stmt_block(PLpgSQL_execstate * estate, PLpgSQL_stmt_block * block) BeginInternalSubTransaction(NULL); /* Want to run statements inside function's memory context */ MemoryContextSwitchTo(oldcontext); - if (SPI_connect() != SPI_OK_CONNECT) - elog(ERROR, "SPI_connect failed"); + if ((xrc = SPI_connect()) != SPI_OK_CONNECT) + elog(ERROR, "SPI_connect failed: %s", + SPI_result_code_string(xrc)); PG_TRY(); { @@ -961,8 +963,9 @@ exec_stmt_block(PLpgSQL_execstate * estate, PLpgSQL_stmt_block * block) /* Commit the inner transaction, return to outer xact context */ if (!caught) { - if (SPI_finish() != SPI_OK_FINISH) - elog(ERROR, "SPI_finish failed"); + if ((xrc = SPI_finish()) != SPI_OK_FINISH) + elog(ERROR, "SPI_finish failed: %s", + SPI_result_code_string(xrc)); ReleaseCurrentSubTransaction(); MemoryContextSwitchTo(oldcontext); SPI_pop(); @@ -2069,7 +2072,8 @@ exec_prepare_plan(PLpgSQL_execstate * estate, */ plan = SPI_prepare(expr->query, expr->nparams, argtypes); if (plan == NULL) - elog(ERROR, "SPI_prepare() failed on \"%s\"", expr->query); + elog(ERROR, "SPI_prepare failed for \"%s\": %s", + expr->query, SPI_result_code_string(SPI_result)); expr->plan = SPI_saveplan(plan); spi_plan = (_SPI_plan *) expr->plan; expr->plan_argtypes = spi_plan->argtypes; @@ -2151,7 +2155,8 @@ exec_stmt_execsql(PLpgSQL_execstate * estate, errhint("If you want to discard the results, use PERFORM instead."))); default: - elog(ERROR, "error executing query \"%s\"", expr->query); + elog(ERROR, "SPI_execp failed executing query \"%s\": %s", + expr->query, SPI_result_code_string(rc)); } /* @@ -2250,8 +2255,8 @@ exec_stmt_dynexecute(PLpgSQL_execstate * estate, } default: - elog(ERROR, "unexpected error %d in EXECUTE of query \"%s\"", - exec_res, querystr); + elog(ERROR, "SPI_exec failed executing query \"%s\": %s", + querystr, SPI_result_code_string(exec_res)); break; } @@ -2321,11 +2326,12 @@ exec_stmt_dynfors(PLpgSQL_execstate * estate, PLpgSQL_stmt_dynfors * stmt) */ plan = SPI_prepare(querystr, 0, NULL); if (plan == NULL) - elog(ERROR, "SPI_prepare() failed for dynamic query \"%s\"", querystr); + elog(ERROR, "SPI_prepare failed for \"%s\": %s", + querystr, SPI_result_code_string(SPI_result)); portal = SPI_cursor_open(NULL, plan, NULL, NULL); if (portal == NULL) - elog(ERROR, "failed to open implicit cursor for dynamic query \"%s\"", - querystr); + elog(ERROR, "could not open implicit cursor for query \"%s\": %s", + querystr, SPI_result_code_string(SPI_result)); pfree(querystr); SPI_freeplan(plan); @@ -2512,11 +2518,12 @@ exec_stmt_open(PLpgSQL_execstate * estate, PLpgSQL_stmt_open * stmt) */ curplan = SPI_prepare(querystr, 0, NULL); if (curplan == NULL) - elog(ERROR, "SPI_prepare() failed for dynamic query \"%s\"", - querystr); + elog(ERROR, "SPI_prepare failed for \"%s\": %s", + querystr, SPI_result_code_string(SPI_result)); portal = SPI_cursor_open(curname, curplan, NULL, NULL); if (portal == NULL) - elog(ERROR, "failed to open cursor"); + elog(ERROR, "could not open cursor for query \"%s\": %s", + querystr, SPI_result_code_string(SPI_result)); pfree(querystr); SPI_freeplan(curplan); @@ -2609,7 +2616,8 @@ exec_stmt_open(PLpgSQL_execstate * estate, PLpgSQL_stmt_open * stmt) */ portal = SPI_cursor_open(curname, query->plan, values, nulls); if (portal == NULL) - elog(ERROR, "failed to open cursor"); + elog(ERROR, "could not open cursor: %s", + SPI_result_code_string(SPI_result)); pfree(values); pfree(nulls); @@ -3454,8 +3462,8 @@ exec_run_select(PLpgSQL_execstate * estate, { *portalP = SPI_cursor_open(NULL, expr->plan, values, nulls); if (*portalP == NULL) - elog(ERROR, "failed to open implicit cursor for \"%s\"", - expr->query); + elog(ERROR, "could not open implicit cursor for query \"%s\": %s", + expr->query, SPI_result_code_string(SPI_result)); pfree(values); pfree(nulls); return SPI_OK_CURSOR; diff --git a/src/pl/plpgsql/src/pl_handler.c b/src/pl/plpgsql/src/pl_handler.c index f7f08bedd031eacd3baca63838b882609e0fe1ec..5f6a83c11d6c2867490cfb91faa45c66ec27d89e 100644 --- a/src/pl/plpgsql/src/pl_handler.c +++ b/src/pl/plpgsql/src/pl_handler.c @@ -3,7 +3,7 @@ * procedural language * * IDENTIFICATION - * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_handler.c,v 1.21 2004/03/22 03:15:33 momjian Exp $ + * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_handler.c,v 1.22 2004/07/31 20:55:44 tgl Exp $ * * This software is copyrighted by Jan Wieck - Hamburg. * @@ -102,6 +102,7 @@ plpgsql_call_handler(PG_FUNCTION_ARGS) { PLpgSQL_function *func; Datum retval; + int rc; /* perform initialization */ plpgsql_init_all(); @@ -109,8 +110,8 @@ plpgsql_call_handler(PG_FUNCTION_ARGS) /* * Connect to SPI manager */ - if (SPI_connect() != SPI_OK_CONNECT) - elog(ERROR, "SPI_connect failed"); + if ((rc = SPI_connect()) != SPI_OK_CONNECT) + elog(ERROR, "SPI_connect failed: %s", SPI_result_code_string(rc)); /* Find or compile the function */ func = plpgsql_compile(fcinfo, false); @@ -128,8 +129,8 @@ plpgsql_call_handler(PG_FUNCTION_ARGS) /* * Disconnect from SPI manager */ - if (SPI_finish() != SPI_OK_FINISH) - elog(ERROR, "SPI_finish failed"); + if ((rc = SPI_finish()) != SPI_OK_FINISH) + elog(ERROR, "SPI_finish failed: %s", SPI_result_code_string(rc)); return retval; } @@ -211,12 +212,13 @@ plpgsql_validator(PG_FUNCTION_ARGS) FunctionCallInfoData fake_fcinfo; FmgrInfo flinfo; TriggerData trigdata; + int rc; /* * Connect to SPI manager (is this needed for compilation?) */ - if (SPI_connect() != SPI_OK_CONNECT) - elog(ERROR, "SPI_connect failed"); + if ((rc = SPI_connect()) != SPI_OK_CONNECT) + elog(ERROR, "SPI_connect failed: %s", SPI_result_code_string(rc)); /* * Set up a fake fcinfo with just enough info to satisfy @@ -240,8 +242,8 @@ plpgsql_validator(PG_FUNCTION_ARGS) /* * Disconnect from SPI manager */ - if (SPI_finish() != SPI_OK_FINISH) - elog(ERROR, "SPI_finish failed"); + if ((rc = SPI_finish()) != SPI_OK_FINISH) + elog(ERROR, "SPI_finish failed: %s", SPI_result_code_string(rc)); } ReleaseSysCache(tuple); diff --git a/src/pl/plpython/plpython.c b/src/pl/plpython/plpython.c index db938c3395a9d9d665dd3588ca30735fddc30cbc..4d8a0aa87add1b733a8765f68f68410cebc87189 100644 --- a/src/pl/plpython/plpython.c +++ b/src/pl/plpython/plpython.c @@ -29,7 +29,7 @@ * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. * * IDENTIFICATION - * $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.50 2004/07/31 00:45:52 tgl Exp $ + * $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.51 2004/07/31 20:55:45 tgl Exp $ * ********************************************************************* */ @@ -1522,7 +1522,6 @@ static int PLy_result_ass_slice(PyObject *, int, int, PyObject *); static PyObject *PLy_spi_prepare(PyObject *, PyObject *); static PyObject *PLy_spi_execute(PyObject *, PyObject *); -static const char *PLy_spi_error_string(int); static PyObject *PLy_spi_execute_query(char *query, int limit); static PyObject *PLy_spi_execute_plan(PyObject *, PyObject *, int); static PyObject *PLy_spi_execute_fetch_result(SPITupleTable *, int, int); @@ -1911,16 +1910,16 @@ PLy_spi_prepare(PyObject * self, PyObject * args) plan->plan = SPI_prepare(query, plan->nargs, plan->types); if (plan->plan == NULL) - elog(ERROR, "Unable to prepare plan. SPI_prepare failed -- %s.", - PLy_spi_error_string(SPI_result)); + elog(ERROR, "SPI_prepare failed: %s", + SPI_result_code_string(SPI_result)); /* transfer plan from procCxt to topCxt */ tmpplan = plan->plan; plan->plan = SPI_saveplan(tmpplan); SPI_freeplan(tmpplan); if (plan->plan == NULL) - elog(ERROR, "Unable to save plan. SPI_saveplan failed -- %s.", - PLy_spi_error_string(SPI_result)); + elog(ERROR, "SPI_saveplan failed: %s", + SPI_result_code_string(SPI_result)); } PG_CATCH(); { @@ -2095,8 +2094,8 @@ PLy_spi_execute_plan(PyObject * ob, PyObject * list, int limit) if (rv < 0) { PLy_exception_set(PLy_exc_spi_error, - "Unable to execute plan. SPI_execp failed -- %s", - PLy_spi_error_string(rv)); + "SPI_execp failed: %s", + SPI_result_code_string(rv)); return NULL; } @@ -2130,8 +2129,8 @@ PLy_spi_execute_query(char *query, int limit) if (rv < 0) { PLy_exception_set(PLy_exc_spi_error, - "Unable to execute query. SPI_exec failed -- %s", - PLy_spi_error_string(rv)); + "SPI_exec failed: %s", + SPI_result_code_string(rv)); return NULL; } @@ -2206,38 +2205,9 @@ PLy_spi_execute_fetch_result(SPITupleTable *tuptable, int rows, int status) return (PyObject *) result; } -static const char * -PLy_spi_error_string(int code) -{ - switch (code) - { - case SPI_ERROR_TYPUNKNOWN: - return "SPI_ERROR_TYPUNKNOWN"; - case SPI_ERROR_NOOUTFUNC: - return "SPI_ERROR_NOOUTFUNC"; - case SPI_ERROR_NOATTRIBUTE: - return "SPI_ERROR_NOATTRIBUTE"; - case SPI_ERROR_TRANSACTION: - return "SPI_ERROR_TRANSACTION"; - case SPI_ERROR_PARAM: - return "SPI_ERROR_PARAM"; - case SPI_ERROR_ARGUMENT: - return "SPI_ERROR_ARGUMENT"; - case SPI_ERROR_CURSOR: - return "SPI_ERROR_CURSOR"; - case SPI_ERROR_UNCONNECTED: - return "SPI_ERROR_UNCONNECTED"; - case SPI_ERROR_OPUNKNOWN: - return "SPI_ERROR_OPUNKNOWN"; - case SPI_ERROR_COPY: - return "SPI_ERROR_COPY"; - case SPI_ERROR_CONNECT: - return "SPI_ERROR_CONNECT"; - } - return "Unknown or Invalid code"; -} - -/* language handler and interpreter initialization + +/* + * language handler and interpreter initialization */ /* diff --git a/src/pl/tcl/pltcl.c b/src/pl/tcl/pltcl.c index 05c906f30f2b72cfccfd3237f021aad073cfe4d1..134291be4e95d876636b011ca481a78be7b90155 100644 --- a/src/pl/tcl/pltcl.c +++ b/src/pl/tcl/pltcl.c @@ -31,7 +31,7 @@ * ENHANCEMENTS, OR MODIFICATIONS. * * IDENTIFICATION - * $PostgreSQL: pgsql/src/pl/tcl/pltcl.c,v 1.87 2004/07/31 00:45:57 tgl Exp $ + * $PostgreSQL: pgsql/src/pl/tcl/pltcl.c,v 1.88 2004/07/31 20:55:45 tgl Exp $ * **********************************************************************/ @@ -1602,46 +1602,10 @@ pltcl_SPI_exec(ClientData cdata, Tcl_Interp *interp, case SPI_OK_SELECT: break; - case SPI_ERROR_ARGUMENT: - Tcl_SetResult(interp, - "pltcl: SPI_exec() failed - SPI_ERROR_ARGUMENT", - TCL_VOLATILE); - return TCL_ERROR; - - case SPI_ERROR_UNCONNECTED: - Tcl_SetResult(interp, - "pltcl: SPI_exec() failed - SPI_ERROR_UNCONNECTED", - TCL_VOLATILE); - return TCL_ERROR; - - case SPI_ERROR_COPY: - Tcl_SetResult(interp, - "pltcl: SPI_exec() failed - SPI_ERROR_COPY", - TCL_VOLATILE); - return TCL_ERROR; - - case SPI_ERROR_CURSOR: - Tcl_SetResult(interp, - "pltcl: SPI_exec() failed - SPI_ERROR_CURSOR", - TCL_VOLATILE); - return TCL_ERROR; - - case SPI_ERROR_TRANSACTION: - Tcl_SetResult(interp, - "pltcl: SPI_exec() failed - SPI_ERROR_TRANSACTION", - TCL_VOLATILE); - return TCL_ERROR; - - case SPI_ERROR_OPUNKNOWN: - Tcl_SetResult(interp, - "pltcl: SPI_exec() failed - SPI_ERROR_OPUNKNOWN", - TCL_VOLATILE); - return TCL_ERROR; - default: - snprintf(buf, sizeof(buf), "%d", spi_rc); - Tcl_AppendResult(interp, "pltcl: SPI_exec() failed - ", - "unknown RC ", buf, NULL); + Tcl_AppendResult(interp, "pltcl: SPI_exec failed: ", + SPI_result_code_string(spi_rc), NULL); + SPI_freetuptable(SPI_tuptable); return TCL_ERROR; } @@ -2117,46 +2081,10 @@ pltcl_SPI_execp(ClientData cdata, Tcl_Interp *interp, case SPI_OK_SELECT: break; - case SPI_ERROR_ARGUMENT: - Tcl_SetResult(interp, - "pltcl: SPI_exec() failed - SPI_ERROR_ARGUMENT", - TCL_VOLATILE); - return TCL_ERROR; - - case SPI_ERROR_UNCONNECTED: - Tcl_SetResult(interp, - "pltcl: SPI_exec() failed - SPI_ERROR_UNCONNECTED", - TCL_VOLATILE); - return TCL_ERROR; - - case SPI_ERROR_COPY: - Tcl_SetResult(interp, - "pltcl: SPI_exec() failed - SPI_ERROR_COPY", - TCL_VOLATILE); - return TCL_ERROR; - - case SPI_ERROR_CURSOR: - Tcl_SetResult(interp, - "pltcl: SPI_exec() failed - SPI_ERROR_CURSOR", - TCL_VOLATILE); - return TCL_ERROR; - - case SPI_ERROR_TRANSACTION: - Tcl_SetResult(interp, - "pltcl: SPI_exec() failed - SPI_ERROR_TRANSACTION", - TCL_VOLATILE); - return TCL_ERROR; - - case SPI_ERROR_OPUNKNOWN: - Tcl_SetResult(interp, - "pltcl: SPI_exec() failed - SPI_ERROR_OPUNKNOWN", - TCL_VOLATILE); - return TCL_ERROR; - default: - snprintf(buf, sizeof(buf), "%d", spi_rc); - Tcl_AppendResult(interp, "pltcl: SPI_exec() failed - ", - "unknown RC ", buf, NULL); + Tcl_AppendResult(interp, "pltcl: SPI_execp failed: ", + SPI_result_code_string(spi_rc), NULL); + SPI_freetuptable(SPI_tuptable); return TCL_ERROR; }