From bf08e6550b113d109ce02cafad9c8d6bbfa53577 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Fri, 13 Aug 2004 18:47:56 +0000 Subject: [PATCH] Give a more specific error message for "you can't do that" error cases in plpgsql, particularly trying to begin/end/rollback a transaction. --- src/pl/plpgsql/src/pl_exec.c | 43 +++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c index 3e6d3f77b5..47a505a8d3 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.114 2004/08/02 17:03:45 tgl Exp $ + * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.115 2004/08/13 18:47:56 tgl Exp $ * * This software is copyrighted by Jan Wieck - Hamburg. * @@ -2090,8 +2090,29 @@ exec_prepare_plan(PLpgSQL_execstate * estate, */ plan = SPI_prepare(expr->query, expr->nparams, argtypes); if (plan == NULL) - elog(ERROR, "SPI_prepare failed for \"%s\": %s", - expr->query, SPI_result_code_string(SPI_result)); + { + /* Some SPI errors deserve specific error messages */ + switch (SPI_result) + { + case SPI_ERROR_COPY: + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot COPY to/from client in PL/pgSQL"))); + case SPI_ERROR_CURSOR: + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot manipulate cursors directly in PL/pgSQL"), + errhint("Use PL/pgSQL's cursor features instead."))); + case SPI_ERROR_TRANSACTION: + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot begin/end transactions in PL/pgSQL"), + errhint("Use a BEGIN block with an EXCEPTION clause instead."))); + default: + 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; @@ -2272,6 +2293,22 @@ exec_stmt_dynexecute(PLpgSQL_execstate * estate, break; } + /* Some SPI errors deserve specific error messages */ + case SPI_ERROR_COPY: + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot COPY to/from client in PL/pgSQL"))); + case SPI_ERROR_CURSOR: + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot manipulate cursors directly in PL/pgSQL"), + errhint("Use PL/pgSQL's cursor features instead."))); + case SPI_ERROR_TRANSACTION: + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot begin/end transactions in PL/pgSQL"), + errhint("Use a BEGIN block with an EXCEPTION clause instead."))); + default: elog(ERROR, "SPI_exec failed executing query \"%s\": %s", querystr, SPI_result_code_string(exec_res));