1
0
mirror of https://github.com/postgres/postgres.git synced 2025-09-02 04:21:28 +03:00

plpgsql does exceptions.

There are still some things that need refinement; in particular I fear
that the recognized set of error condition names probably has little in
common with what Oracle recognizes.  But it's a start.
This commit is contained in:
Tom Lane
2004-07-31 07:39:21 +00:00
parent b5d2821929
commit beda4814c1
11 changed files with 767 additions and 110 deletions

View File

@@ -4,7 +4,7 @@
* procedural language
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/pl/plpgsql/src/gram.y,v 1.57 2004/07/04 02:49:04 tgl Exp $
* $PostgreSQL: pgsql/src/pl/plpgsql/src/gram.y,v 1.58 2004/07/31 07:39:20 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
@@ -96,6 +96,8 @@ static void check_assignable(PLpgSQL_datum *datum);
PLpgSQL_stmt *stmt;
PLpgSQL_stmts *stmts;
PLpgSQL_stmt_block *program;
PLpgSQL_exception *exception;
PLpgSQL_exceptions *exceptions;
PLpgSQL_nsitem *nsitem;
}
@@ -131,6 +133,9 @@ static void check_assignable(PLpgSQL_datum *datum);
%type <stmt> stmt_dynexecute stmt_getdiag
%type <stmt> stmt_open stmt_fetch stmt_close
%type <exceptions> exception_sect proc_exceptions
%type <exception> proc_exception
%type <intlist> raise_params
%type <ival> raise_level raise_param
%type <str> raise_msg
@@ -240,7 +245,7 @@ opt_semi :
| ';'
;
pl_block : decl_sect K_BEGIN lno proc_sect K_END
pl_block : decl_sect K_BEGIN lno proc_sect exception_sect K_END
{
PLpgSQL_stmt_block *new;
@@ -253,6 +258,7 @@ pl_block : decl_sect K_BEGIN lno proc_sect K_END
new->n_initvars = $1.n_initvars;
new->initvarnos = $1.initvarnos;
new->body = $4;
new->exceptions = $5;
plpgsql_ns_pop();
@@ -588,7 +594,7 @@ proc_stmts : proc_stmts proc_stmt
$1->stmts_alloc *= 2;
$1->stmts = realloc($1->stmts, sizeof(PLpgSQL_stmt *) * $1->stmts_alloc);
}
$1->stmts[$1->stmts_used++] = (struct PLpgSQL_stmt *)$2;
$1->stmts[$1->stmts_used++] = $2;
$$ = $1;
}
@@ -602,7 +608,7 @@ proc_stmts : proc_stmts proc_stmt
new->stmts_alloc = 64;
new->stmts_used = 1;
new->stmts = malloc(sizeof(PLpgSQL_stmt *) * new->stmts_alloc);
new->stmts[0] = (struct PLpgSQL_stmt *)$1;
new->stmts[0] = $1;
$$ = new;
@@ -832,7 +838,7 @@ stmt_else :
new->stmts_alloc = 64;
new->stmts_used = 1;
new->stmts = malloc(sizeof(PLpgSQL_stmt *) * new->stmts_alloc);
new->stmts[0] = (struct PLpgSQL_stmt *)new_if;
new->stmts[0] = (PLpgSQL_stmt *) new_if;
$$ = new;
@@ -1524,6 +1530,54 @@ execsql_start : T_WORD
{ $$ = strdup(yytext); }
;
exception_sect :
{ $$ = NULL; }
| K_EXCEPTION proc_exceptions
{ $$ = $2; }
;
proc_exceptions : proc_exceptions proc_exception
{
if ($1->exceptions_used == $1->exceptions_alloc)
{
$1->exceptions_alloc *= 2;
$1->exceptions = realloc($1->exceptions, sizeof(PLpgSQL_exception *) * $1->exceptions_alloc);
}
$1->exceptions[$1->exceptions_used++] = $2;
$$ = $1;
}
| proc_exception
{
PLpgSQL_exceptions *new;
new = malloc(sizeof(PLpgSQL_exceptions));
memset(new, 0, sizeof(PLpgSQL_exceptions));
new->exceptions_alloc = 64;
new->exceptions_used = 1;
new->exceptions = malloc(sizeof(PLpgSQL_exception *) * new->exceptions_alloc);
new->exceptions[0] = $1;
$$ = new;
}
;
proc_exception : K_WHEN lno opt_lblname K_THEN proc_sect
{
PLpgSQL_exception *new;
new = malloc(sizeof(PLpgSQL_exception));
memset(new, 0, sizeof(PLpgSQL_exception));
new->lineno = $2;
new->label = $3;
new->action = $5;
$$ = new;
}
;
expr_until_semi :
{ $$ = plpgsql_read_expression(';', ";"); }
;

View File

@@ -3,7 +3,7 @@
* procedural language
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.108 2004/07/31 00:45:46 tgl Exp $
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.109 2004/07/31 07:39:20 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
@@ -56,6 +56,16 @@
static const char *const raise_skip_msg = "RAISE";
typedef struct {
const char *label;
int sqlerrstate;
} ExceptionLabelMap;
static const ExceptionLabelMap exception_label_map[] = {
#include "plerrcodes.h"
{ NULL, 0 }
};
/*
* All plpgsql function executions within a single transaction share
* the same executor EState for evaluating "simple" expressions. Each
@@ -784,6 +794,32 @@ copy_rec(PLpgSQL_rec * rec)
}
static bool
exception_matches_label(ErrorData *edata, const char *label)
{
int i;
/*
* OTHERS matches everything *except* query-canceled;
* if you're foolish enough, you can match that explicitly.
*/
if (pg_strcasecmp(label, "OTHERS") == 0)
{
if (edata->sqlerrcode == ERRCODE_QUERY_CANCELED)
return false;
else
return true;
}
for (i = 0; exception_label_map[i].label != NULL; i++)
{
if (pg_strcasecmp(label, exception_label_map[i].label) == 0)
return (edata->sqlerrcode == exception_label_map[i].sqlerrstate);
}
/* Should we raise an error if label is unrecognized?? */
return false;
}
/* ----------
* exec_stmt_block Execute a block of statements
* ----------
@@ -791,7 +827,7 @@ copy_rec(PLpgSQL_rec * rec)
static int
exec_stmt_block(PLpgSQL_execstate * estate, PLpgSQL_stmt_block * block)
{
int rc;
volatile int rc = -1;
int i;
int n;
@@ -859,13 +895,86 @@ exec_stmt_block(PLpgSQL_execstate * estate, PLpgSQL_stmt_block * block)
elog(ERROR, "unrecognized dtype: %d",
estate->datums[n]->dtype);
}
}
/*
* Execute the statements in the block's body
*/
rc = exec_stmts(estate, block->body);
if (block->exceptions)
{
/*
* Execute the statements in the block's body inside a sub-transaction
*/
MemoryContext oldcontext = CurrentMemoryContext;
volatile bool caught = false;
/*
* Start a subtransaction, and re-connect to SPI within it
*/
SPI_push();
BeginInternalSubTransaction(NULL);
/* Want to run statements inside function's memory context */
MemoryContextSwitchTo(oldcontext);
if (SPI_connect() != SPI_OK_CONNECT)
elog(ERROR, "SPI_connect failed");
PG_TRY();
{
rc = exec_stmts(estate, block->body);
}
PG_CATCH();
{
ErrorData *edata;
PLpgSQL_exceptions *exceptions;
int j;
/* Save error info */
MemoryContextSwitchTo(oldcontext);
edata = CopyErrorData();
FlushErrorState();
/* Abort the inner transaction (and inner SPI connection) */
RollbackAndReleaseCurrentSubTransaction();
MemoryContextSwitchTo(oldcontext);
SPI_pop();
/* Look for a matching exception handler */
exceptions = block->exceptions;
for (j = 0; j < exceptions->exceptions_used; j++)
{
PLpgSQL_exception *exception = exceptions->exceptions[j];
if (exception_matches_label(edata, exception->label))
{
rc = exec_stmts(estate, exception->action);
break;
}
}
/* If no match found, re-throw the error */
if (j >= exceptions->exceptions_used)
ReThrowError(edata);
else
FreeErrorData(edata);
caught = true;
}
PG_END_TRY();
/* Commit the inner transaction, return to outer xact context */
if (!caught)
{
if (SPI_finish() != SPI_OK_FINISH)
elog(ERROR, "SPI_finish failed");
ReleaseCurrentSubTransaction();
MemoryContextSwitchTo(oldcontext);
SPI_pop();
}
}
else
{
/*
* Just execute the statements in the block's body
*/
rc = exec_stmts(estate, block->body);
}
/*
* Handle the return code.
@@ -909,7 +1018,7 @@ exec_stmts(PLpgSQL_execstate * estate, PLpgSQL_stmts * stmts)
for (i = 0; i < stmts->stmts_used; i++)
{
rc = exec_stmt(estate, (PLpgSQL_stmt *) (stmts->stmts[i]));
rc = exec_stmt(estate, stmts->stmts[i]);
if (rc != PLPGSQL_RC_OK)
return rc;
}
@@ -1852,7 +1961,8 @@ exec_stmt_raise(PLpgSQL_execstate * estate, PLpgSQL_stmt_raise * stmt)
estate->err_text = raise_skip_msg; /* suppress traceback of raise */
ereport(stmt->elog_level,
(errmsg_internal("%s", plpgsql_dstring_get(&ds))));
((stmt->elog_level >= ERROR) ? errcode(ERRCODE_RAISE_EXCEPTION) : 0,
errmsg_internal("%s", plpgsql_dstring_get(&ds))));
estate->err_text = NULL; /* un-suppress... */

View File

@@ -3,7 +3,7 @@
* procedural language
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_funcs.c,v 1.32 2004/02/21 00:34:53 tgl Exp $
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_funcs.c,v 1.33 2004/07/31 07:39:20 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
@@ -583,6 +583,17 @@ dump_stmt(PLpgSQL_stmt * stmt)
}
}
static void
dump_stmts(PLpgSQL_stmts * stmts)
{
int i;
dump_indent += 2;
for (i = 0; i < stmts->stmts_used; i++)
dump_stmt(stmts->stmts[i]);
dump_indent -= 2;
}
static void
dump_block(PLpgSQL_stmt_block * block)
{
@@ -597,10 +608,19 @@ dump_block(PLpgSQL_stmt_block * block)
dump_ind();
printf("BLOCK <<%s>>\n", name);
dump_indent += 2;
for (i = 0; i < block->body->stmts_used; i++)
dump_stmt((PLpgSQL_stmt *) (block->body->stmts[i]));
dump_indent -= 2;
dump_stmts(block->body);
if (block->exceptions)
{
for (i = 0; i < block->exceptions->exceptions_used; i++)
{
PLpgSQL_exception *exc = block->exceptions->exceptions[i];
dump_ind();
printf(" EXCEPTION WHEN %s THEN\n", exc->label);
dump_stmts(exc->action);
}
}
dump_ind();
printf(" END -- %s\n", name);
@@ -618,25 +638,17 @@ dump_assign(PLpgSQL_stmt_assign * stmt)
static void
dump_if(PLpgSQL_stmt_if * stmt)
{
int i;
dump_ind();
printf("IF ");
dump_expr(stmt->cond);
printf(" THEN\n");
dump_indent += 2;
for (i = 0; i < stmt->true_body->stmts_used; i++)
dump_stmt((PLpgSQL_stmt *) (stmt->true_body->stmts[i]));
dump_indent -= 2;
dump_stmts(stmt->true_body);
dump_ind();
printf(" ELSE\n");
dump_indent += 2;
for (i = 0; i < stmt->false_body->stmts_used; i++)
dump_stmt((PLpgSQL_stmt *) (stmt->false_body->stmts[i]));
dump_indent -= 2;
dump_stmts(stmt->false_body);
dump_ind();
printf(" ENDIF\n");
@@ -645,15 +657,10 @@ dump_if(PLpgSQL_stmt_if * stmt)
static void
dump_loop(PLpgSQL_stmt_loop * stmt)
{
int i;
dump_ind();
printf("LOOP\n");
dump_indent += 2;
for (i = 0; i < stmt->body->stmts_used; i++)
dump_stmt((PLpgSQL_stmt *) (stmt->body->stmts[i]));
dump_indent -= 2;
dump_stmts(stmt->body);
dump_ind();
printf(" ENDLOOP\n");
@@ -662,17 +669,12 @@ dump_loop(PLpgSQL_stmt_loop * stmt)
static void
dump_while(PLpgSQL_stmt_while * stmt)
{
int i;
dump_ind();
printf("WHILE ");
dump_expr(stmt->cond);
printf("\n");
dump_indent += 2;
for (i = 0; i < stmt->body->stmts_used; i++)
dump_stmt((PLpgSQL_stmt *) (stmt->body->stmts[i]));
dump_indent -= 2;
dump_stmts(stmt->body);
dump_ind();
printf(" ENDWHILE\n");
@@ -681,8 +683,6 @@ dump_while(PLpgSQL_stmt_while * stmt)
static void
dump_fori(PLpgSQL_stmt_fori * stmt)
{
int i;
dump_ind();
printf("FORI %s %s\n", stmt->var->refname, (stmt->reverse) ? "REVERSE" : "NORMAL");
@@ -695,11 +695,10 @@ dump_fori(PLpgSQL_stmt_fori * stmt)
printf(" upper = ");
dump_expr(stmt->upper);
printf("\n");
for (i = 0; i < stmt->body->stmts_used; i++)
dump_stmt((PLpgSQL_stmt *) (stmt->body->stmts[i]));
dump_indent -= 2;
dump_stmts(stmt->body);
dump_ind();
printf(" ENDFORI\n");
}
@@ -707,17 +706,12 @@ dump_fori(PLpgSQL_stmt_fori * stmt)
static void
dump_fors(PLpgSQL_stmt_fors * stmt)
{
int i;
dump_ind();
printf("FORS %s ", (stmt->rec != NULL) ? stmt->rec->refname : stmt->row->refname);
dump_expr(stmt->query);
printf("\n");
dump_indent += 2;
for (i = 0; i < stmt->body->stmts_used; i++)
dump_stmt((PLpgSQL_stmt *) (stmt->body->stmts[i]));
dump_indent -= 2;
dump_stmts(stmt->body);
dump_ind();
printf(" ENDFORS\n");
@@ -891,17 +885,12 @@ dump_dynexecute(PLpgSQL_stmt_dynexecute * stmt)
static void
dump_dynfors(PLpgSQL_stmt_dynfors * stmt)
{
int i;
dump_ind();
printf("FORS %s EXECUTE ", (stmt->rec != NULL) ? stmt->rec->refname : stmt->row->refname);
dump_expr(stmt->query);
printf("\n");
dump_indent += 2;
for (i = 0; i < stmt->body->stmts_used; i++)
dump_stmt((PLpgSQL_stmt *) (stmt->body->stmts[i]));
dump_indent -= 2;
dump_stmts(stmt->body);
dump_ind();
printf(" ENDFORS\n");
@@ -1051,4 +1040,5 @@ plpgsql_dumptree(PLpgSQL_function * func)
printf("%3d:", func->action->lineno);
dump_block(func->action);
printf("\nEnd of execution tree of function %s\n\n", func->fn_name);
fflush(stdout);
}

View File

@@ -0,0 +1,203 @@
/*-------------------------------------------------------------------------
*
* plerrcodes.h
* PL/pgSQL error codes (mapping of exception labels to SQLSTATEs)
*
* Eventually this header file should be auto-generated from errcodes.h
* with some sort of sed hackery, but no time for that now. It's likely
* that an exact mapping will not be what's wanted anyhow ...
*
* Copyright (c) 2003, PostgreSQL Global Development Group
*
* $PostgreSQL: pgsql/src/pl/plpgsql/src/plerrcodes.h,v 1.1 2004/07/31 07:39:20 tgl Exp $
*
*-------------------------------------------------------------------------
*/
{ "SUCCESSFUL_COMPLETION", ERRCODE_SUCCESSFUL_COMPLETION },
{ "WARNING", ERRCODE_WARNING },
{ "WARNING_DYNAMIC_RESULT_SETS_RETURNED", ERRCODE_WARNING_DYNAMIC_RESULT_SETS_RETURNED },
{ "WARNING_IMPLICIT_ZERO_BIT_PADDING", ERRCODE_WARNING_IMPLICIT_ZERO_BIT_PADDING },
{ "WARNING_NULL_VALUE_ELIMINATED_IN_SET_FUNCTION", ERRCODE_WARNING_NULL_VALUE_ELIMINATED_IN_SET_FUNCTION },
{ "WARNING_PRIVILEGE_NOT_GRANTED", ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED },
{ "WARNING_PRIVILEGE_NOT_REVOKED", ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED },
{ "WARNING_STRING_DATA_RIGHT_TRUNCATION", ERRCODE_WARNING_STRING_DATA_RIGHT_TRUNCATION },
{ "WARNING_DEPRECATED_FEATURE", ERRCODE_WARNING_DEPRECATED_FEATURE },
{ "NO_DATA", ERRCODE_NO_DATA },
{ "NO_ADDITIONAL_DYNAMIC_RESULT_SETS_RETURNED", ERRCODE_NO_ADDITIONAL_DYNAMIC_RESULT_SETS_RETURNED },
{ "SQL_STATEMENT_NOT_YET_COMPLETE", ERRCODE_SQL_STATEMENT_NOT_YET_COMPLETE },
{ "CONNECTION_EXCEPTION", ERRCODE_CONNECTION_EXCEPTION },
{ "CONNECTION_DOES_NOT_EXIST", ERRCODE_CONNECTION_DOES_NOT_EXIST },
{ "CONNECTION_FAILURE", ERRCODE_CONNECTION_FAILURE },
{ "SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION", ERRCODE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION },
{ "SQLSERVER_REJECTED_ESTABLISHMENT_OF_SQLCONNECTION", ERRCODE_SQLSERVER_REJECTED_ESTABLISHMENT_OF_SQLCONNECTION },
{ "TRANSACTION_RESOLUTION_UNKNOWN", ERRCODE_TRANSACTION_RESOLUTION_UNKNOWN },
{ "PROTOCOL_VIOLATION", ERRCODE_PROTOCOL_VIOLATION },
{ "TRIGGERED_ACTION_EXCEPTION", ERRCODE_TRIGGERED_ACTION_EXCEPTION },
{ "FEATURE_NOT_SUPPORTED", ERRCODE_FEATURE_NOT_SUPPORTED },
{ "INVALID_TRANSACTION_INITIATION", ERRCODE_INVALID_TRANSACTION_INITIATION },
{ "LOCATOR_EXCEPTION", ERRCODE_LOCATOR_EXCEPTION },
{ "L_E_INVALID_SPECIFICATION", ERRCODE_L_E_INVALID_SPECIFICATION },
{ "INVALID_GRANTOR", ERRCODE_INVALID_GRANTOR },
{ "INVALID_GRANT_OPERATION", ERRCODE_INVALID_GRANT_OPERATION },
{ "INVALID_ROLE_SPECIFICATION", ERRCODE_INVALID_ROLE_SPECIFICATION },
{ "CARDINALITY_VIOLATION", ERRCODE_CARDINALITY_VIOLATION },
{ "DATA_EXCEPTION", ERRCODE_DATA_EXCEPTION },
{ "ARRAY_ELEMENT_ERROR", ERRCODE_ARRAY_ELEMENT_ERROR },
{ "ARRAY_SUBSCRIPT_ERROR", ERRCODE_ARRAY_SUBSCRIPT_ERROR },
{ "CHARACTER_NOT_IN_REPERTOIRE", ERRCODE_CHARACTER_NOT_IN_REPERTOIRE },
{ "DATETIME_FIELD_OVERFLOW", ERRCODE_DATETIME_FIELD_OVERFLOW },
{ "DATETIME_VALUE_OUT_OF_RANGE", ERRCODE_DATETIME_VALUE_OUT_OF_RANGE },
{ "DIVISION_BY_ZERO", ERRCODE_DIVISION_BY_ZERO },
{ "ERROR_IN_ASSIGNMENT", ERRCODE_ERROR_IN_ASSIGNMENT },
{ "ESCAPE_CHARACTER_CONFLICT", ERRCODE_ESCAPE_CHARACTER_CONFLICT },
{ "INDICATOR_OVERFLOW", ERRCODE_INDICATOR_OVERFLOW },
{ "INTERVAL_FIELD_OVERFLOW", ERRCODE_INTERVAL_FIELD_OVERFLOW },
{ "INVALID_ARGUMENT_FOR_LOG", ERRCODE_INVALID_ARGUMENT_FOR_LOG },
{ "INVALID_ARGUMENT_FOR_POWER_FUNCTION", ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION },
{ "INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION", ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION },
{ "INVALID_CHARACTER_VALUE_FOR_CAST", ERRCODE_INVALID_CHARACTER_VALUE_FOR_CAST },
{ "INVALID_DATETIME_FORMAT", ERRCODE_INVALID_DATETIME_FORMAT },
{ "INVALID_ESCAPE_CHARACTER", ERRCODE_INVALID_ESCAPE_CHARACTER },
{ "INVALID_ESCAPE_OCTET", ERRCODE_INVALID_ESCAPE_OCTET },
{ "INVALID_ESCAPE_SEQUENCE", ERRCODE_INVALID_ESCAPE_SEQUENCE },
{ "INVALID_INDICATOR_PARAMETER_VALUE", ERRCODE_INVALID_INDICATOR_PARAMETER_VALUE },
{ "INVALID_LIMIT_VALUE", ERRCODE_INVALID_LIMIT_VALUE },
{ "INVALID_PARAMETER_VALUE", ERRCODE_INVALID_PARAMETER_VALUE },
{ "INVALID_REGULAR_EXPRESSION", ERRCODE_INVALID_REGULAR_EXPRESSION },
{ "INVALID_TIME_ZONE_DISPLACEMENT_VALUE", ERRCODE_INVALID_TIME_ZONE_DISPLACEMENT_VALUE },
{ "INVALID_USE_OF_ESCAPE_CHARACTER", ERRCODE_INVALID_USE_OF_ESCAPE_CHARACTER },
{ "MOST_SPECIFIC_TYPE_MISMATCH", ERRCODE_MOST_SPECIFIC_TYPE_MISMATCH },
{ "NULL_VALUE_NOT_ALLOWED", ERRCODE_NULL_VALUE_NOT_ALLOWED },
{ "NULL_VALUE_NO_INDICATOR_PARAMETER", ERRCODE_NULL_VALUE_NO_INDICATOR_PARAMETER },
{ "NUMERIC_VALUE_OUT_OF_RANGE", ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE },
{ "STRING_DATA_LENGTH_MISMATCH", ERRCODE_STRING_DATA_LENGTH_MISMATCH },
{ "STRING_DATA_RIGHT_TRUNCATION", ERRCODE_STRING_DATA_RIGHT_TRUNCATION },
{ "SUBSTRING_ERROR", ERRCODE_SUBSTRING_ERROR },
{ "TRIM_ERROR", ERRCODE_TRIM_ERROR },
{ "UNTERMINATED_C_STRING", ERRCODE_UNTERMINATED_C_STRING },
{ "ZERO_LENGTH_CHARACTER_STRING", ERRCODE_ZERO_LENGTH_CHARACTER_STRING },
{ "FLOATING_POINT_EXCEPTION", ERRCODE_FLOATING_POINT_EXCEPTION },
{ "INVALID_TEXT_REPRESENTATION", ERRCODE_INVALID_TEXT_REPRESENTATION },
{ "INVALID_BINARY_REPRESENTATION", ERRCODE_INVALID_BINARY_REPRESENTATION },
{ "BAD_COPY_FILE_FORMAT", ERRCODE_BAD_COPY_FILE_FORMAT },
{ "UNTRANSLATABLE_CHARACTER", ERRCODE_UNTRANSLATABLE_CHARACTER },
{ "INTEGRITY_CONSTRAINT_VIOLATION", ERRCODE_INTEGRITY_CONSTRAINT_VIOLATION },
{ "RESTRICT_VIOLATION", ERRCODE_RESTRICT_VIOLATION },
{ "NOT_NULL_VIOLATION", ERRCODE_NOT_NULL_VIOLATION },
{ "FOREIGN_KEY_VIOLATION", ERRCODE_FOREIGN_KEY_VIOLATION },
{ "UNIQUE_VIOLATION", ERRCODE_UNIQUE_VIOLATION },
{ "CHECK_VIOLATION", ERRCODE_CHECK_VIOLATION },
{ "INVALID_CURSOR_STATE", ERRCODE_INVALID_CURSOR_STATE },
{ "INVALID_TRANSACTION_STATE", ERRCODE_INVALID_TRANSACTION_STATE },
{ "ACTIVE_SQL_TRANSACTION", ERRCODE_ACTIVE_SQL_TRANSACTION },
{ "BRANCH_TRANSACTION_ALREADY_ACTIVE", ERRCODE_BRANCH_TRANSACTION_ALREADY_ACTIVE },
{ "HELD_CURSOR_REQUIRES_SAME_ISOLATION_LEVEL", ERRCODE_HELD_CURSOR_REQUIRES_SAME_ISOLATION_LEVEL },
{ "INAPPROPRIATE_ACCESS_MODE_FOR_BRANCH_TRANSACTION", ERRCODE_INAPPROPRIATE_ACCESS_MODE_FOR_BRANCH_TRANSACTION },
{ "INAPPROPRIATE_ISOLATION_LEVEL_FOR_BRANCH_TRANSACTION", ERRCODE_INAPPROPRIATE_ISOLATION_LEVEL_FOR_BRANCH_TRANSACTION },
{ "NO_ACTIVE_SQL_TRANSACTION_FOR_BRANCH_TRANSACTION", ERRCODE_NO_ACTIVE_SQL_TRANSACTION_FOR_BRANCH_TRANSACTION },
{ "READ_ONLY_SQL_TRANSACTION", ERRCODE_READ_ONLY_SQL_TRANSACTION },
{ "SCHEMA_AND_DATA_STATEMENT_MIXING_NOT_SUPPORTED", ERRCODE_SCHEMA_AND_DATA_STATEMENT_MIXING_NOT_SUPPORTED },
{ "NO_ACTIVE_SQL_TRANSACTION", ERRCODE_NO_ACTIVE_SQL_TRANSACTION },
{ "IN_FAILED_SQL_TRANSACTION", ERRCODE_IN_FAILED_SQL_TRANSACTION },
{ "INVALID_SQL_STATEMENT_NAME", ERRCODE_INVALID_SQL_STATEMENT_NAME },
{ "TRIGGERED_DATA_CHANGE_VIOLATION", ERRCODE_TRIGGERED_DATA_CHANGE_VIOLATION },
{ "INVALID_AUTHORIZATION_SPECIFICATION", ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION },
{ "DEPENDENT_PRIVILEGE_DESCRIPTORS_STILL_EXIST", ERRCODE_DEPENDENT_PRIVILEGE_DESCRIPTORS_STILL_EXIST },
{ "DEPENDENT_OBJECTS_STILL_EXIST", ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST },
{ "INVALID_TRANSACTION_TERMINATION", ERRCODE_INVALID_TRANSACTION_TERMINATION },
{ "SQL_ROUTINE_EXCEPTION", ERRCODE_SQL_ROUTINE_EXCEPTION },
{ "S_R_E_FUNCTION_EXECUTED_NO_RETURN_STATEMENT", ERRCODE_S_R_E_FUNCTION_EXECUTED_NO_RETURN_STATEMENT },
{ "S_R_E_MODIFYING_SQL_DATA_NOT_PERMITTED", ERRCODE_S_R_E_MODIFYING_SQL_DATA_NOT_PERMITTED },
{ "S_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED", ERRCODE_S_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED },
{ "S_R_E_READING_SQL_DATA_NOT_PERMITTED", ERRCODE_S_R_E_READING_SQL_DATA_NOT_PERMITTED },
{ "INVALID_CURSOR_NAME", ERRCODE_INVALID_CURSOR_NAME },
{ "EXTERNAL_ROUTINE_EXCEPTION", ERRCODE_EXTERNAL_ROUTINE_EXCEPTION },
{ "E_R_E_CONTAINING_SQL_NOT_PERMITTED", ERRCODE_E_R_E_CONTAINING_SQL_NOT_PERMITTED },
{ "E_R_E_MODIFYING_SQL_DATA_NOT_PERMITTED", ERRCODE_E_R_E_MODIFYING_SQL_DATA_NOT_PERMITTED },
{ "E_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED", ERRCODE_E_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED },
{ "E_R_E_READING_SQL_DATA_NOT_PERMITTED", ERRCODE_E_R_E_READING_SQL_DATA_NOT_PERMITTED },
{ "EXTERNAL_ROUTINE_INVOCATION_EXCEPTION", ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION },
{ "E_R_I_E_INVALID_SQLSTATE_RETURNED", ERRCODE_E_R_I_E_INVALID_SQLSTATE_RETURNED },
{ "E_R_I_E_NULL_VALUE_NOT_ALLOWED", ERRCODE_E_R_I_E_NULL_VALUE_NOT_ALLOWED },
{ "E_R_I_E_TRIGGER_PROTOCOL_VIOLATED", ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED },
{ "E_R_I_E_SRF_PROTOCOL_VIOLATED", ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED },
{ "SAVEPOINT_EXCEPTION", ERRCODE_SAVEPOINT_EXCEPTION },
{ "S_E_INVALID_SPECIFICATION", ERRCODE_S_E_INVALID_SPECIFICATION },
{ "INVALID_CATALOG_NAME", ERRCODE_INVALID_CATALOG_NAME },
{ "INVALID_SCHEMA_NAME", ERRCODE_INVALID_SCHEMA_NAME },
{ "TRANSACTION_ROLLBACK", ERRCODE_TRANSACTION_ROLLBACK },
{ "T_R_INTEGRITY_CONSTRAINT_VIOLATION", ERRCODE_T_R_INTEGRITY_CONSTRAINT_VIOLATION },
{ "T_R_SERIALIZATION_FAILURE", ERRCODE_T_R_SERIALIZATION_FAILURE },
{ "T_R_STATEMENT_COMPLETION_UNKNOWN", ERRCODE_T_R_STATEMENT_COMPLETION_UNKNOWN },
{ "T_R_DEADLOCK_DETECTED", ERRCODE_T_R_DEADLOCK_DETECTED },
{ "SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION", ERRCODE_SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION },
{ "SYNTAX_ERROR", ERRCODE_SYNTAX_ERROR },
{ "INSUFFICIENT_PRIVILEGE", ERRCODE_INSUFFICIENT_PRIVILEGE },
{ "CANNOT_COERCE", ERRCODE_CANNOT_COERCE },
{ "GROUPING_ERROR", ERRCODE_GROUPING_ERROR },
{ "INVALID_FOREIGN_KEY", ERRCODE_INVALID_FOREIGN_KEY },
{ "INVALID_NAME", ERRCODE_INVALID_NAME },
{ "NAME_TOO_LONG", ERRCODE_NAME_TOO_LONG },
{ "RESERVED_NAME", ERRCODE_RESERVED_NAME },
{ "DATATYPE_MISMATCH", ERRCODE_DATATYPE_MISMATCH },
{ "INDETERMINATE_DATATYPE", ERRCODE_INDETERMINATE_DATATYPE },
{ "WRONG_OBJECT_TYPE", ERRCODE_WRONG_OBJECT_TYPE },
{ "UNDEFINED_COLUMN", ERRCODE_UNDEFINED_COLUMN },
{ "UNDEFINED_CURSOR", ERRCODE_UNDEFINED_CURSOR },
{ "UNDEFINED_DATABASE", ERRCODE_UNDEFINED_DATABASE },
{ "UNDEFINED_FUNCTION", ERRCODE_UNDEFINED_FUNCTION },
{ "UNDEFINED_PSTATEMENT", ERRCODE_UNDEFINED_PSTATEMENT },
{ "UNDEFINED_SCHEMA", ERRCODE_UNDEFINED_SCHEMA },
{ "UNDEFINED_TABLE", ERRCODE_UNDEFINED_TABLE },
{ "UNDEFINED_PARAMETER", ERRCODE_UNDEFINED_PARAMETER },
{ "UNDEFINED_OBJECT", ERRCODE_UNDEFINED_OBJECT },
{ "DUPLICATE_COLUMN", ERRCODE_DUPLICATE_COLUMN },
{ "DUPLICATE_CURSOR", ERRCODE_DUPLICATE_CURSOR },
{ "DUPLICATE_DATABASE", ERRCODE_DUPLICATE_DATABASE },
{ "DUPLICATE_FUNCTION", ERRCODE_DUPLICATE_FUNCTION },
{ "DUPLICATE_PSTATEMENT", ERRCODE_DUPLICATE_PSTATEMENT },
{ "DUPLICATE_SCHEMA", ERRCODE_DUPLICATE_SCHEMA },
{ "DUPLICATE_TABLE", ERRCODE_DUPLICATE_TABLE },
{ "DUPLICATE_ALIAS", ERRCODE_DUPLICATE_ALIAS },
{ "DUPLICATE_OBJECT", ERRCODE_DUPLICATE_OBJECT },
{ "AMBIGUOUS_COLUMN", ERRCODE_AMBIGUOUS_COLUMN },
{ "AMBIGUOUS_FUNCTION", ERRCODE_AMBIGUOUS_FUNCTION },
{ "AMBIGUOUS_PARAMETER", ERRCODE_AMBIGUOUS_PARAMETER },
{ "AMBIGUOUS_ALIAS", ERRCODE_AMBIGUOUS_ALIAS },
{ "INVALID_COLUMN_REFERENCE", ERRCODE_INVALID_COLUMN_REFERENCE },
{ "INVALID_COLUMN_DEFINITION", ERRCODE_INVALID_COLUMN_DEFINITION },
{ "INVALID_CURSOR_DEFINITION", ERRCODE_INVALID_CURSOR_DEFINITION },
{ "INVALID_DATABASE_DEFINITION", ERRCODE_INVALID_DATABASE_DEFINITION },
{ "INVALID_FUNCTION_DEFINITION", ERRCODE_INVALID_FUNCTION_DEFINITION },
{ "INVALID_PSTATEMENT_DEFINITION", ERRCODE_INVALID_PSTATEMENT_DEFINITION },
{ "INVALID_SCHEMA_DEFINITION", ERRCODE_INVALID_SCHEMA_DEFINITION },
{ "INVALID_TABLE_DEFINITION", ERRCODE_INVALID_TABLE_DEFINITION },
{ "INVALID_OBJECT_DEFINITION", ERRCODE_INVALID_OBJECT_DEFINITION },
{ "WITH_CHECK_OPTION_VIOLATION", ERRCODE_WITH_CHECK_OPTION_VIOLATION },
{ "INSUFFICIENT_RESOURCES", ERRCODE_INSUFFICIENT_RESOURCES },
{ "DISK_FULL", ERRCODE_DISK_FULL },
{ "OUT_OF_MEMORY", ERRCODE_OUT_OF_MEMORY },
{ "TOO_MANY_CONNECTIONS", ERRCODE_TOO_MANY_CONNECTIONS },
{ "PROGRAM_LIMIT_EXCEEDED", ERRCODE_PROGRAM_LIMIT_EXCEEDED },
{ "STATEMENT_TOO_COMPLEX", ERRCODE_STATEMENT_TOO_COMPLEX },
{ "TOO_MANY_COLUMNS", ERRCODE_TOO_MANY_COLUMNS },
{ "TOO_MANY_ARGUMENTS", ERRCODE_TOO_MANY_ARGUMENTS },
{ "OBJECT_NOT_IN_PREREQUISITE_STATE", ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE },
{ "OBJECT_IN_USE", ERRCODE_OBJECT_IN_USE },
{ "CANT_CHANGE_RUNTIME_PARAM", ERRCODE_CANT_CHANGE_RUNTIME_PARAM },
{ "OPERATOR_INTERVENTION", ERRCODE_OPERATOR_INTERVENTION },
{ "QUERY_CANCELED", ERRCODE_QUERY_CANCELED },
{ "ADMIN_SHUTDOWN", ERRCODE_ADMIN_SHUTDOWN },
{ "CRASH_SHUTDOWN", ERRCODE_CRASH_SHUTDOWN },
{ "CANNOT_CONNECT_NOW", ERRCODE_CANNOT_CONNECT_NOW },
{ "IO_ERROR", ERRCODE_IO_ERROR },
{ "UNDEFINED_FILE", ERRCODE_UNDEFINED_FILE },
{ "DUPLICATE_FILE", ERRCODE_DUPLICATE_FILE },
{ "CONFIG_FILE_ERROR", ERRCODE_CONFIG_FILE_ERROR },
{ "LOCK_FILE_EXISTS", ERRCODE_LOCK_FILE_EXISTS },
{ "PLPGSQL_ERROR", ERRCODE_PLPGSQL_ERROR },
{ "RAISE_EXCEPTION", ERRCODE_RAISE_EXCEPTION },
{ "INTERNAL_ERROR", ERRCODE_INTERNAL_ERROR },
{ "DATA_CORRUPTED", ERRCODE_DATA_CORRUPTED },
{ "INDEX_CORRUPTED", ERRCODE_INDEX_CORRUPTED },

View File

@@ -3,7 +3,7 @@
* procedural language
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.47 2004/06/06 00:41:28 tgl Exp $
* $PostgreSQL: pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.48 2004/07/31 07:39:20 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
@@ -307,14 +307,6 @@ typedef struct PLpgSQL_ns
} PLpgSQL_ns;
typedef struct
{ /* List of execution nodes */
int stmts_alloc;
int stmts_used;
struct PLpgSQL_stmt **stmts;
} PLpgSQL_stmts;
typedef struct
{ /* Generic execution node */
int cmd_type;
@@ -322,12 +314,37 @@ typedef struct
} PLpgSQL_stmt;
typedef struct
{ /* List of execution nodes */
int stmts_alloc; /* XXX this oughta just be a List ... */
int stmts_used;
PLpgSQL_stmt **stmts;
} PLpgSQL_stmts;
typedef struct
{ /* One EXCEPTION ... WHEN clause */
int lineno;
char *label;
PLpgSQL_stmts *action;
} PLpgSQL_exception;
typedef struct
{ /* List of WHEN clauses */
int exceptions_alloc; /* XXX this oughta just be a List ... */
int exceptions_used;
PLpgSQL_exception **exceptions;
} PLpgSQL_exceptions;
typedef struct
{ /* Block of statements */
int cmd_type;
int lineno;
char *label;
PLpgSQL_stmts *body;
PLpgSQL_exceptions *exceptions;
int n_initvars;
int *initvarnos;
} PLpgSQL_stmt_block;