Give a more specific error message for "you can't do that" error cases
authorTom Lane
Fri, 13 Aug 2004 18:47:56 +0000 (18:47 +0000)
committerTom Lane
Fri, 13 Aug 2004 18:47:56 +0000 (18:47 +0000)
in plpgsql, particularly trying to begin/end/rollback a transaction.

src/pl/plpgsql/src/pl_exec.c

index 3e6d3f77b5a8630548e99f38ce7ce71355355302..47a505a8d3433fe21337b637bb453dbe7213630a 100644 (file)
@@ -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));