mirror of
https://github.com/postgres/postgres.git
synced 2025-04-22 23:02:54 +03:00
Be more consistent about reporting SPI errors in the various PLs.
Create a shared function to convert a SPI error code into a string (replacing near-duplicate code in several PLs), and use it anywhere that a SPI function call error is reported.
This commit is contained in:
parent
da4a0dab59
commit
ad4d2e9711
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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;
|
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 =================== */
|
/* =================== private functions =================== */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
*
|
*
|
||||||
* spi.h
|
* 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 Oid SPI_getargtypeid(void *plan, int argIndex);
|
||||||
extern int SPI_getargcount(void *plan);
|
extern int SPI_getargcount(void *plan);
|
||||||
extern bool SPI_is_cursor_plan(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 HeapTuple SPI_copytuple(HeapTuple tuple);
|
||||||
extern HeapTupleHeader SPI_returntuple(HeapTuple tuple, TupleDesc tupdesc);
|
extern HeapTupleHeader SPI_returntuple(HeapTuple tuple, TupleDesc tupdesc);
|
||||||
|
@ -9,10 +9,9 @@
|
|||||||
|
|
||||||
#include "spi_internal.h"
|
#include "spi_internal.h"
|
||||||
|
|
||||||
static char* plperl_spi_status_string(int);
|
|
||||||
|
|
||||||
static HV* plperl_spi_execute_fetch_result(SPITupleTable*, int, int );
|
static HV* plperl_spi_execute_fetch_result(SPITupleTable*, int, int );
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
spi_DEBUG(void)
|
spi_DEBUG(void)
|
||||||
{
|
{
|
||||||
@ -93,93 +92,35 @@ plperl_hash_from_tuple(HeapTuple tuple, TupleDesc tupdesc)
|
|||||||
static HV*
|
static HV*
|
||||||
plperl_spi_execute_fetch_result(SPITupleTable *tuptable, int processed, int status)
|
plperl_spi_execute_fetch_result(SPITupleTable *tuptable, int processed, int status)
|
||||||
{
|
{
|
||||||
|
|
||||||
HV *result;
|
HV *result;
|
||||||
AV *rows;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
result = newHV();
|
result = newHV();
|
||||||
rows = newAV();
|
|
||||||
|
|
||||||
if (status == SPI_OK_UTILITY)
|
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("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*)plperl_spi_status_string(status),0), 0);
|
|
||||||
hv_store(result, "processed", strlen("processed"), newSViv(processed), 0);
|
|
||||||
if (processed)
|
if (processed)
|
||||||
{
|
{
|
||||||
|
AV *rows;
|
||||||
HV *row;
|
HV *row;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
rows = newAV();
|
||||||
for (i = 0; i < processed; i++)
|
for (i = 0; i < processed; i++)
|
||||||
{
|
{
|
||||||
row = plperl_hash_from_tuple(tuptable->vals[i], tuptable->tupdesc);
|
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);
|
hv_store(result, "rows", strlen("rows"),
|
||||||
|
newRV_noinc((SV*)rows), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SPI_freetuptable(tuptable);
|
SPI_freetuptable(tuptable);
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
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";
|
|
||||||
}
|
|
||||||
|
|
||||||
return "Unknown or Invalid code";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* procedural language
|
* procedural language
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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.
|
* 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;
|
MemoryContext oldcontext = CurrentMemoryContext;
|
||||||
volatile bool caught = false;
|
volatile bool caught = false;
|
||||||
|
int xrc;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Start a subtransaction, and re-connect to SPI within it
|
* 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);
|
BeginInternalSubTransaction(NULL);
|
||||||
/* Want to run statements inside function's memory context */
|
/* Want to run statements inside function's memory context */
|
||||||
MemoryContextSwitchTo(oldcontext);
|
MemoryContextSwitchTo(oldcontext);
|
||||||
if (SPI_connect() != SPI_OK_CONNECT)
|
if ((xrc = SPI_connect()) != SPI_OK_CONNECT)
|
||||||
elog(ERROR, "SPI_connect failed");
|
elog(ERROR, "SPI_connect failed: %s",
|
||||||
|
SPI_result_code_string(xrc));
|
||||||
|
|
||||||
PG_TRY();
|
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 */
|
/* Commit the inner transaction, return to outer xact context */
|
||||||
if (!caught)
|
if (!caught)
|
||||||
{
|
{
|
||||||
if (SPI_finish() != SPI_OK_FINISH)
|
if ((xrc = SPI_finish()) != SPI_OK_FINISH)
|
||||||
elog(ERROR, "SPI_finish failed");
|
elog(ERROR, "SPI_finish failed: %s",
|
||||||
|
SPI_result_code_string(xrc));
|
||||||
ReleaseCurrentSubTransaction();
|
ReleaseCurrentSubTransaction();
|
||||||
MemoryContextSwitchTo(oldcontext);
|
MemoryContextSwitchTo(oldcontext);
|
||||||
SPI_pop();
|
SPI_pop();
|
||||||
@ -2069,7 +2072,8 @@ exec_prepare_plan(PLpgSQL_execstate * estate,
|
|||||||
*/
|
*/
|
||||||
plan = SPI_prepare(expr->query, expr->nparams, argtypes);
|
plan = SPI_prepare(expr->query, expr->nparams, argtypes);
|
||||||
if (plan == NULL)
|
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);
|
expr->plan = SPI_saveplan(plan);
|
||||||
spi_plan = (_SPI_plan *) expr->plan;
|
spi_plan = (_SPI_plan *) expr->plan;
|
||||||
expr->plan_argtypes = spi_plan->argtypes;
|
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.")));
|
errhint("If you want to discard the results, use PERFORM instead.")));
|
||||||
|
|
||||||
default:
|
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:
|
default:
|
||||||
elog(ERROR, "unexpected error %d in EXECUTE of query \"%s\"",
|
elog(ERROR, "SPI_exec failed executing query \"%s\": %s",
|
||||||
exec_res, querystr);
|
querystr, SPI_result_code_string(exec_res));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2321,11 +2326,12 @@ exec_stmt_dynfors(PLpgSQL_execstate * estate, PLpgSQL_stmt_dynfors * stmt)
|
|||||||
*/
|
*/
|
||||||
plan = SPI_prepare(querystr, 0, NULL);
|
plan = SPI_prepare(querystr, 0, NULL);
|
||||||
if (plan == 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);
|
portal = SPI_cursor_open(NULL, plan, NULL, NULL);
|
||||||
if (portal == NULL)
|
if (portal == NULL)
|
||||||
elog(ERROR, "failed to open implicit cursor for dynamic query \"%s\"",
|
elog(ERROR, "could not open implicit cursor for query \"%s\": %s",
|
||||||
querystr);
|
querystr, SPI_result_code_string(SPI_result));
|
||||||
pfree(querystr);
|
pfree(querystr);
|
||||||
SPI_freeplan(plan);
|
SPI_freeplan(plan);
|
||||||
|
|
||||||
@ -2512,11 +2518,12 @@ exec_stmt_open(PLpgSQL_execstate * estate, PLpgSQL_stmt_open * stmt)
|
|||||||
*/
|
*/
|
||||||
curplan = SPI_prepare(querystr, 0, NULL);
|
curplan = SPI_prepare(querystr, 0, NULL);
|
||||||
if (curplan == NULL)
|
if (curplan == NULL)
|
||||||
elog(ERROR, "SPI_prepare() failed for dynamic query \"%s\"",
|
elog(ERROR, "SPI_prepare failed for \"%s\": %s",
|
||||||
querystr);
|
querystr, SPI_result_code_string(SPI_result));
|
||||||
portal = SPI_cursor_open(curname, curplan, NULL, NULL);
|
portal = SPI_cursor_open(curname, curplan, NULL, NULL);
|
||||||
if (portal == 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);
|
pfree(querystr);
|
||||||
SPI_freeplan(curplan);
|
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);
|
portal = SPI_cursor_open(curname, query->plan, values, nulls);
|
||||||
if (portal == NULL)
|
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(values);
|
||||||
pfree(nulls);
|
pfree(nulls);
|
||||||
@ -3454,8 +3462,8 @@ exec_run_select(PLpgSQL_execstate * estate,
|
|||||||
{
|
{
|
||||||
*portalP = SPI_cursor_open(NULL, expr->plan, values, nulls);
|
*portalP = SPI_cursor_open(NULL, expr->plan, values, nulls);
|
||||||
if (*portalP == NULL)
|
if (*portalP == NULL)
|
||||||
elog(ERROR, "failed to open implicit cursor for \"%s\"",
|
elog(ERROR, "could not open implicit cursor for query \"%s\": %s",
|
||||||
expr->query);
|
expr->query, SPI_result_code_string(SPI_result));
|
||||||
pfree(values);
|
pfree(values);
|
||||||
pfree(nulls);
|
pfree(nulls);
|
||||||
return SPI_OK_CURSOR;
|
return SPI_OK_CURSOR;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* procedural language
|
* procedural language
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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.
|
* This software is copyrighted by Jan Wieck - Hamburg.
|
||||||
*
|
*
|
||||||
@ -102,6 +102,7 @@ plpgsql_call_handler(PG_FUNCTION_ARGS)
|
|||||||
{
|
{
|
||||||
PLpgSQL_function *func;
|
PLpgSQL_function *func;
|
||||||
Datum retval;
|
Datum retval;
|
||||||
|
int rc;
|
||||||
|
|
||||||
/* perform initialization */
|
/* perform initialization */
|
||||||
plpgsql_init_all();
|
plpgsql_init_all();
|
||||||
@ -109,8 +110,8 @@ plpgsql_call_handler(PG_FUNCTION_ARGS)
|
|||||||
/*
|
/*
|
||||||
* Connect to SPI manager
|
* Connect to SPI manager
|
||||||
*/
|
*/
|
||||||
if (SPI_connect() != SPI_OK_CONNECT)
|
if ((rc = SPI_connect()) != SPI_OK_CONNECT)
|
||||||
elog(ERROR, "SPI_connect failed");
|
elog(ERROR, "SPI_connect failed: %s", SPI_result_code_string(rc));
|
||||||
|
|
||||||
/* Find or compile the function */
|
/* Find or compile the function */
|
||||||
func = plpgsql_compile(fcinfo, false);
|
func = plpgsql_compile(fcinfo, false);
|
||||||
@ -128,8 +129,8 @@ plpgsql_call_handler(PG_FUNCTION_ARGS)
|
|||||||
/*
|
/*
|
||||||
* Disconnect from SPI manager
|
* Disconnect from SPI manager
|
||||||
*/
|
*/
|
||||||
if (SPI_finish() != SPI_OK_FINISH)
|
if ((rc = SPI_finish()) != SPI_OK_FINISH)
|
||||||
elog(ERROR, "SPI_finish failed");
|
elog(ERROR, "SPI_finish failed: %s", SPI_result_code_string(rc));
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
@ -211,12 +212,13 @@ plpgsql_validator(PG_FUNCTION_ARGS)
|
|||||||
FunctionCallInfoData fake_fcinfo;
|
FunctionCallInfoData fake_fcinfo;
|
||||||
FmgrInfo flinfo;
|
FmgrInfo flinfo;
|
||||||
TriggerData trigdata;
|
TriggerData trigdata;
|
||||||
|
int rc;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Connect to SPI manager (is this needed for compilation?)
|
* Connect to SPI manager (is this needed for compilation?)
|
||||||
*/
|
*/
|
||||||
if (SPI_connect() != SPI_OK_CONNECT)
|
if ((rc = SPI_connect()) != SPI_OK_CONNECT)
|
||||||
elog(ERROR, "SPI_connect failed");
|
elog(ERROR, "SPI_connect failed: %s", SPI_result_code_string(rc));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set up a fake fcinfo with just enough info to satisfy
|
* Set up a fake fcinfo with just enough info to satisfy
|
||||||
@ -240,8 +242,8 @@ plpgsql_validator(PG_FUNCTION_ARGS)
|
|||||||
/*
|
/*
|
||||||
* Disconnect from SPI manager
|
* Disconnect from SPI manager
|
||||||
*/
|
*/
|
||||||
if (SPI_finish() != SPI_OK_FINISH)
|
if ((rc = SPI_finish()) != SPI_OK_FINISH)
|
||||||
elog(ERROR, "SPI_finish failed");
|
elog(ERROR, "SPI_finish failed: %s", SPI_result_code_string(rc));
|
||||||
}
|
}
|
||||||
|
|
||||||
ReleaseSysCache(tuple);
|
ReleaseSysCache(tuple);
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
* MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
* MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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_prepare(PyObject *, PyObject *);
|
||||||
static PyObject *PLy_spi_execute(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_query(char *query, int limit);
|
||||||
static PyObject *PLy_spi_execute_plan(PyObject *, PyObject *, int);
|
static PyObject *PLy_spi_execute_plan(PyObject *, PyObject *, int);
|
||||||
static PyObject *PLy_spi_execute_fetch_result(SPITupleTable *, int, 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);
|
plan->plan = SPI_prepare(query, plan->nargs, plan->types);
|
||||||
if (plan->plan == NULL)
|
if (plan->plan == NULL)
|
||||||
elog(ERROR, "Unable to prepare plan. SPI_prepare failed -- %s.",
|
elog(ERROR, "SPI_prepare failed: %s",
|
||||||
PLy_spi_error_string(SPI_result));
|
SPI_result_code_string(SPI_result));
|
||||||
|
|
||||||
/* transfer plan from procCxt to topCxt */
|
/* transfer plan from procCxt to topCxt */
|
||||||
tmpplan = plan->plan;
|
tmpplan = plan->plan;
|
||||||
plan->plan = SPI_saveplan(tmpplan);
|
plan->plan = SPI_saveplan(tmpplan);
|
||||||
SPI_freeplan(tmpplan);
|
SPI_freeplan(tmpplan);
|
||||||
if (plan->plan == NULL)
|
if (plan->plan == NULL)
|
||||||
elog(ERROR, "Unable to save plan. SPI_saveplan failed -- %s.",
|
elog(ERROR, "SPI_saveplan failed: %s",
|
||||||
PLy_spi_error_string(SPI_result));
|
SPI_result_code_string(SPI_result));
|
||||||
}
|
}
|
||||||
PG_CATCH();
|
PG_CATCH();
|
||||||
{
|
{
|
||||||
@ -2095,8 +2094,8 @@ PLy_spi_execute_plan(PyObject * ob, PyObject * list, int limit)
|
|||||||
if (rv < 0)
|
if (rv < 0)
|
||||||
{
|
{
|
||||||
PLy_exception_set(PLy_exc_spi_error,
|
PLy_exception_set(PLy_exc_spi_error,
|
||||||
"Unable to execute plan. SPI_execp failed -- %s",
|
"SPI_execp failed: %s",
|
||||||
PLy_spi_error_string(rv));
|
SPI_result_code_string(rv));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2130,8 +2129,8 @@ PLy_spi_execute_query(char *query, int limit)
|
|||||||
if (rv < 0)
|
if (rv < 0)
|
||||||
{
|
{
|
||||||
PLy_exception_set(PLy_exc_spi_error,
|
PLy_exception_set(PLy_exc_spi_error,
|
||||||
"Unable to execute query. SPI_exec failed -- %s",
|
"SPI_exec failed: %s",
|
||||||
PLy_spi_error_string(rv));
|
SPI_result_code_string(rv));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2206,38 +2205,9 @@ PLy_spi_execute_fetch_result(SPITupleTable *tuptable, int rows, int status)
|
|||||||
return (PyObject *) result;
|
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
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
* ENHANCEMENTS, OR MODIFICATIONS.
|
* ENHANCEMENTS, OR MODIFICATIONS.
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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:
|
case SPI_OK_SELECT:
|
||||||
break;
|
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:
|
default:
|
||||||
snprintf(buf, sizeof(buf), "%d", spi_rc);
|
Tcl_AppendResult(interp, "pltcl: SPI_exec failed: ",
|
||||||
Tcl_AppendResult(interp, "pltcl: SPI_exec() failed - ",
|
SPI_result_code_string(spi_rc), NULL);
|
||||||
"unknown RC ", buf, NULL);
|
SPI_freetuptable(SPI_tuptable);
|
||||||
return TCL_ERROR;
|
return TCL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2117,46 +2081,10 @@ pltcl_SPI_execp(ClientData cdata, Tcl_Interp *interp,
|
|||||||
case SPI_OK_SELECT:
|
case SPI_OK_SELECT:
|
||||||
break;
|
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:
|
default:
|
||||||
snprintf(buf, sizeof(buf), "%d", spi_rc);
|
Tcl_AppendResult(interp, "pltcl: SPI_execp failed: ",
|
||||||
Tcl_AppendResult(interp, "pltcl: SPI_exec() failed - ",
|
SPI_result_code_string(spi_rc), NULL);
|
||||||
"unknown RC ", buf, NULL);
|
SPI_freetuptable(SPI_tuptable);
|
||||||
return TCL_ERROR;
|
return TCL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user