* procedural language
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/pl/plpgsql/src/gram.y,v 1.60 2004/08/16 17:52:06 tgl Exp $
+ * $PostgreSQL: pgsql/src/pl/plpgsql/src/gram.y,v 1.61 2004/08/20 22:00:14 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
new = malloc(sizeof(PLpgSQL_exceptions));
memset(new, 0, sizeof(PLpgSQL_exceptions));
- new->exceptions_alloc = 64;
+ new->exceptions_alloc = 16;
new->exceptions_used = 1;
new->exceptions = malloc(sizeof(PLpgSQL_exception *) * new->exceptions_alloc);
new->exceptions[0] = $1;
proc_conditions : proc_conditions K_OR opt_lblname
{
- PLpgSQL_condition *new;
- PLpgSQL_condition *old;
+ PLpgSQL_condition *old;
- new = malloc(sizeof(PLpgSQL_condition));
- memset(new, 0, sizeof(PLpgSQL_condition));
+ for (old = $1; old->next != NULL; old = old->next)
+ /* skip */ ;
+ old->next = plpgsql_parse_err_condition($3);
- new->condname = $3;
- new->next = NULL;
-
- for (old = $1; old->next != NULL; old = old->next)
- /* skip */ ;
- old->next = new;
-
- $$ = $1;
+ $$ = $1;
}
| opt_lblname
{
- PLpgSQL_condition *new;
-
- new = malloc(sizeof(PLpgSQL_condition));
- memset(new, 0, sizeof(PLpgSQL_condition));
-
- new->condname = $1;
- new->next = NULL;
-
- $$ = new;
+ $$ = plpgsql_parse_err_condition($1);
}
;
* procedural language
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.78 2004/07/31 00:45:46 tgl Exp $
+ * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.79 2004/08/20 22:00:14 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
#define FUNCS_PER_USER 128 /* initial table size */
+/* ----------
+ * Lookup table for EXCEPTION condition names
+ * ----------
+ */
+typedef struct {
+ const char *label;
+ int sqlerrstate;
+} ExceptionLabelMap;
+
+static const ExceptionLabelMap exception_label_map[] = {
+#include "plerrcodes.h"
+ { NULL, 0 }
+};
+
/* ----------
* static prototypes
return typ;
}
+/*
+ * plpgsql_parse_err_condition
+ * Generate PLpgSQL_condition entry(s) for an exception condition name
+ *
+ * This has to be able to return a list because there are some duplicate
+ * names in the table of error code names.
+ */
+PLpgSQL_condition *
+plpgsql_parse_err_condition(char *condname)
+{
+ int i;
+ PLpgSQL_condition *new;
+ PLpgSQL_condition *prev;
+
+ /*
+ * XXX Eventually we will want to look for user-defined exception names
+ * here.
+ */
+
+ /*
+ * OTHERS is represented as code 0 (which would map to '00000', but
+ * we have no need to represent that as an exception condition).
+ */
+ if (strcmp(condname, "others") == 0)
+ {
+ new = malloc(sizeof(PLpgSQL_condition));
+ new->sqlerrstate = 0;
+ new->condname = condname;
+ new->next = NULL;
+ return new;
+ }
+
+ prev = NULL;
+ for (i = 0; exception_label_map[i].label != NULL; i++)
+ {
+ if (strcmp(condname, exception_label_map[i].label) == 0)
+ {
+ new = malloc(sizeof(PLpgSQL_condition));
+ new->sqlerrstate = exception_label_map[i].sqlerrstate;
+ new->condname = condname;
+ new->next = prev;
+ prev = new;
+ }
+ }
+
+ if (!prev)
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("unrecognized exception condition \"%s\"",
+ condname)));
+
+ return prev;
+}
/* ----------
* plpgsql_adddatum Add a variable, record or row
* procedural language
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.115 2004/08/13 18:47:56 tgl Exp $
+ * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.116 2004/08/20 22:00:14 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
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
{
for (; cond != NULL; cond = cond->next)
{
- const char *condname = cond->condname;
- int i;
+ int sqlerrstate = cond->sqlerrstate;
/*
* OTHERS matches everything *except* query-canceled;
* if you're foolish enough, you can match that explicitly.
*/
- if (strcmp(condname, "others") == 0)
+ if (sqlerrstate == 0)
{
- if (edata->sqlerrcode == ERRCODE_QUERY_CANCELED)
- return false;
- else
+ if (edata->sqlerrcode != ERRCODE_QUERY_CANCELED)
return true;
}
- for (i = 0; exception_label_map[i].label != NULL; i++)
- {
- if (strcmp(condname, exception_label_map[i].label) == 0)
- {
- int labelerrcode = exception_label_map[i].sqlerrstate;
-
- /* Exact match? */
- if (edata->sqlerrcode == labelerrcode)
- return true;
- /* Category match? */
- if (ERRCODE_IS_CATEGORY(labelerrcode) &&
- ERRCODE_TO_CATEGORY(edata->sqlerrcode) == labelerrcode)
- return true;
- /*
- * You would think we should "break" here, but there are some
- * duplicate names in the table, so keep looking.
- */
- }
- }
- /* Should we raise an error if condname is unrecognized?? */
+ /* Exact match? */
+ else if (edata->sqlerrcode == sqlerrstate)
+ return true;
+ /* Category match? */
+ else if (ERRCODE_IS_CATEGORY(sqlerrstate) &&
+ ERRCODE_TO_CATEGORY(edata->sqlerrcode) == sqlerrstate)
+ return true;
}
return false;
}
* procedural language
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.50 2004/08/01 17:32:22 tgl Exp $
+ * $PostgreSQL: pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.51 2004/08/20 22:00:14 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
typedef struct PLpgSQL_condition
{ /* One EXCEPTION condition name */
- char *condname;
+ int sqlerrstate; /* SQLSTATE code */
+ char *condname; /* condition name (for debugging) */
struct PLpgSQL_condition *next;
} PLpgSQL_condition;
extern PLpgSQL_variable *plpgsql_build_variable(char *refname, int lineno,
PLpgSQL_type *dtype,
bool add2namespace);
+extern PLpgSQL_condition *plpgsql_parse_err_condition(char *condname);
extern void plpgsql_adddatum(PLpgSQL_datum *new);
extern int plpgsql_add_initdatums(int **varnos);
extern void plpgsql_HashTableInit(void);