<term><symbol>PG_DIAG_TABLE_NAME</></term>
<listitem>
<para>
- If the error was associated with a specific table, the name of
- the table. (When this field is present, the schema name field
- provides the name of the table's schema.)
+ If the error was associated with a specific table, the name of the
+ table. (Refer to the schema name field for the name of the
+ table's schema.)
</para>
</listitem>
</varlistentry>
<term><symbol>PG_DIAG_COLUMN_NAME</></term>
<listitem>
<para>
- If the error was associated with a specific table column, the
- name of the column. (When this field is present, the schema
- and table name fields identify the table.)
+ If the error was associated with a specific table column, the name
+ of the column. (Refer to the schema and table name fields to
+ identify the table.)
</para>
</listitem>
</varlistentry>
<term><symbol>PG_DIAG_DATATYPE_NAME</></term>
<listitem>
<para>
- If the error was associated with a specific data type, the name
- of the data type. (When this field is present, the schema name
- field provides the name of the data type's schema.)
+ If the error was associated with a specific data type, the name of
+ the data type. (Refer to the schema name field for the name of
+ the data type's schema.)
</para>
</listitem>
</varlistentry>
<term><symbol>PG_DIAG_CONSTRAINT_NAME</></term>
<listitem>
<para>
- If the error was associated with a specific constraint,
- the name of the constraint. The table or domain that the
- constraint belongs to is reported using the fields listed
- above. (For this purpose, indexes are treated as constraints,
- even if they weren't created with constraint syntax.)
+ If the error was associated with a specific constraint, the name
+ of the constraint. Refer to fields listed above for the
+ associated table or domain. (For this purpose, indexes are
+ treated as constraints, even if they weren't created with
+ constraint syntax.)
</para>
</listitem>
</varlistentry>
<note>
<para>
- The fields for schema name, table name, column name, data type
- name, and constraint name are supplied only for a limited number
- of error types; see <xref linkend="errcodes-appendix">.
+ The fields for schema name, table name, column name, data type name,
+ and constraint name are supplied only for a limited number of error
+ types; see <xref linkend="errcodes-appendix">. Do not assume that
+ the presence of any of these fields guarantees the presence of
+ another field. Core error sources observe the interrelationships
+ noted above, but user-defined functions may use these fields in other
+ ways. In the same vein, do not assume that these fields denote
+ contemporary objects in the current database.
</para>
</note>
<entry>text</entry>
<entry>the SQLSTATE error code of the exception</entry>
</row>
+ <row>
+ <entry><literal>COLUMN_NAME</literal></entry>
+ <entry>text</entry>
+ <entry>the name of column related to exception</entry>
+ </row>
+ <row>
+ <entry><literal>CONSTRAINT_NAME</literal></entry>
+ <entry>text</entry>
+ <entry>the name of constraint related to exception</entry>
+ </row>
+ <row>
+ <entry><literal>PG_DATATYPE_NAME</literal></entry>
+ <entry>text</entry>
+ <entry>the name of datatype related to exception</entry>
+ </row>
<row>
<entry><literal>MESSAGE_TEXT</literal></entry>
<entry>text</entry>
<entry>the text of the exception's primary message</entry>
</row>
+ <row>
+ <entry><literal>TABLE_NAME</literal></entry>
+ <entry>text</entry>
+ <entry>the name of table related to exception</entry>
+ </row>
+ <row>
+ <entry><literal>SCHEMA_NAME</literal></entry>
+ <entry>text</entry>
+ <entry>the name of schema related to exception</entry>
+ </row>
<row>
<entry><literal>PG_EXCEPTION_DETAIL</literal></entry>
<entry>text</entry>
five-character SQLSTATE code.</para>
</listitem>
</varlistentry>
+
+ <varlistentry>
+ <term><literal>COLUMN</literal></term>
+ <term><literal>CONSTRAINT</literal></term>
+ <term><literal>DATATYPE</literal></term>
+ <term><literal>TABLE</literal></term>
+ <term><literal>SCHEMA</literal></term>
+ <listitem>
+ <para>Supplies the name of a related object.</para>
+ </listitem>
+ </varlistentry>
</variablelist>
</para>
<listitem>
<para>
Table name: if the error was associated with a specific table, the
- name of the table. (When this field is present, the schema name field
- provides the name of the table's schema.)
+ name of the table. (Refer to the schema name field for the name of
+ the table's schema.)
</para>
</listitem>
</varlistentry>
<listitem>
<para>
Column name: if the error was associated with a specific table column,
- the name of the column. (When this field is present, the schema and
- table name fields identify the table.)
+ the name of the column. (Refer to the schema and table name fields to
+ identify the table.)
</para>
</listitem>
</varlistentry>
<listitem>
<para>
Data type name: if the error was associated with a specific data type,
- the name of the data type. (When this field is present, the schema
- name field provides the name of the data type's schema.)
+ the name of the data type. (Refer to the schema name field for the
+ name of the data type's schema.)
</para>
</listitem>
</varlistentry>
<listitem>
<para>
Constraint name: if the error was associated with a specific
- constraint, the name of the constraint. The table or domain that the
- constraint belongs to is reported using the fields listed above. (For
- this purpose, indexes are treated as constraints, even if they weren't
- created with constraint syntax.)
+ constraint, the name of the constraint. Refer to fields listed above
+ for the associated table or domain. (For this purpose, indexes are
+ treated as constraints, even if they weren't created with constraint
+ syntax.)
</para>
</listitem>
</varlistentry>
<para>
The fields for schema name, table name, column name, data type name, and
constraint name are supplied only for a limited number of error types;
- see <xref linkend="errcodes-appendix">.
+ see <xref linkend="errcodes-appendix">. Frontends should not assume that
+ the presence of any of these fields guarantees the presence of another
+ field. Core error sources observe the interrelationships noted above, but
+ user-defined functions may use these fields in other ways. In the same
+ vein, clients should not assume that these fields denote contemporary
+ objects in the current database.
</para>
</note>
unpack_sql_state(estate->cur_error->sqlerrcode));
break;
+ case PLPGSQL_GETDIAG_COLUMN_NAME:
+ exec_assign_c_string(estate, var,
+ estate->cur_error->column_name);
+ break;
+
+ case PLPGSQL_GETDIAG_CONSTRAINT_NAME:
+ exec_assign_c_string(estate, var,
+ estate->cur_error->constraint_name);
+ break;
+
+ case PLPGSQL_GETDIAG_DATATYPE_NAME:
+ exec_assign_c_string(estate, var,
+ estate->cur_error->datatype_name);
+ break;
+
case PLPGSQL_GETDIAG_MESSAGE_TEXT:
exec_assign_c_string(estate, var,
estate->cur_error->message);
break;
+ case PLPGSQL_GETDIAG_TABLE_NAME:
+ exec_assign_c_string(estate, var,
+ estate->cur_error->table_name);
+ break;
+
+ case PLPGSQL_GETDIAG_SCHEMA_NAME:
+ exec_assign_c_string(estate, var,
+ estate->cur_error->schema_name);
+ break;
+
default:
elog(ERROR, "unrecognized diagnostic item kind: %d",
diag_item->kind);
estate->rettupdesc = rsi->expectedDesc;
}
+#define SET_RAISE_OPTION_TEXT(opt, name) \
+do { \
+ if (opt) \
+ ereport(ERROR, \
+ (errcode(ERRCODE_SYNTAX_ERROR), \
+ errmsg("RAISE option already specified: %s", \
+ name))); \
+ opt = pstrdup(extval); \
+} while (0)
+
/* ----------
* exec_stmt_raise Build a message and throw it with elog()
* ----------
char *err_message = NULL;
char *err_detail = NULL;
char *err_hint = NULL;
+ char *err_column = NULL;
+ char *err_constraint = NULL;
+ char *err_datatype = NULL;
+ char *err_table = NULL;
+ char *err_schema = NULL;
ListCell *lc;
/* RAISE with no parameters: re-throw current exception */
condname = pstrdup(extval);
break;
case PLPGSQL_RAISEOPTION_MESSAGE:
- if (err_message)
- ereport(ERROR,
- (errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("RAISE option already specified: %s",
- "MESSAGE")));
- err_message = pstrdup(extval);
+ SET_RAISE_OPTION_TEXT(err_message, "MESSAGE");
break;
case PLPGSQL_RAISEOPTION_DETAIL:
- if (err_detail)
- ereport(ERROR,
- (errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("RAISE option already specified: %s",
- "DETAIL")));
- err_detail = pstrdup(extval);
+ SET_RAISE_OPTION_TEXT(err_detail, "DETAIL");
break;
case PLPGSQL_RAISEOPTION_HINT:
- if (err_hint)
- ereport(ERROR,
- (errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("RAISE option already specified: %s",
- "HINT")));
- err_hint = pstrdup(extval);
+ SET_RAISE_OPTION_TEXT(err_hint, "HINT");
+ break;
+ case PLPGSQL_RAISEOPTION_COLUMN:
+ SET_RAISE_OPTION_TEXT(err_column, "COLUMN");
+ break;
+ case PLPGSQL_RAISEOPTION_CONSTRAINT:
+ SET_RAISE_OPTION_TEXT(err_constraint, "CONSTRAINT");
+ break;
+ case PLPGSQL_RAISEOPTION_DATATYPE:
+ SET_RAISE_OPTION_TEXT(err_datatype, "DATATYPE");
+ break;
+ case PLPGSQL_RAISEOPTION_TABLE:
+ SET_RAISE_OPTION_TEXT(err_table, "TABLE");
+ break;
+ case PLPGSQL_RAISEOPTION_SCHEMA:
+ SET_RAISE_OPTION_TEXT(err_schema, "SCHEMA");
break;
default:
elog(ERROR, "unrecognized raise option: %d", opt->opt_type);
(err_code ? errcode(err_code) : 0,
errmsg_internal("%s", err_message),
(err_detail != NULL) ? errdetail_internal("%s", err_detail) : 0,
- (err_hint != NULL) ? errhint("%s", err_hint) : 0));
+ (err_hint != NULL) ? errhint("%s", err_hint) : 0,
+ (err_column != NULL) ?
+ err_generic_string(PG_DIAG_COLUMN_NAME, err_column) : 0,
+ (err_constraint != NULL) ?
+ err_generic_string(PG_DIAG_CONSTRAINT_NAME, err_constraint) : 0,
+ (err_datatype != NULL) ?
+ err_generic_string(PG_DIAG_DATATYPE_NAME, err_datatype) : 0,
+ (err_table != NULL) ?
+ err_generic_string(PG_DIAG_TABLE_NAME, err_table) : 0,
+ (err_schema != NULL) ?
+ err_generic_string(PG_DIAG_SCHEMA_NAME, err_schema) : 0));
estate->err_text = NULL; /* un-suppress... */
pfree(err_detail);
if (err_hint != NULL)
pfree(err_hint);
+ if (err_column != NULL)
+ pfree(err_column);
+ if (err_constraint != NULL)
+ pfree(err_constraint);
+ if (err_datatype != NULL)
+ pfree(err_datatype);
+ if (err_table != NULL)
+ pfree(err_table);
+ if (err_schema != NULL)
+ pfree(err_schema);
return PLPGSQL_RC_OK;
}
return "PG_EXCEPTION_HINT";
case PLPGSQL_GETDIAG_RETURNED_SQLSTATE:
return "RETURNED_SQLSTATE";
+ case PLPGSQL_GETDIAG_COLUMN_NAME:
+ return "COLUMN_NAME";
+ case PLPGSQL_GETDIAG_CONSTRAINT_NAME:
+ return "CONSTRAINT_NAME";
+ case PLPGSQL_GETDIAG_DATATYPE_NAME:
+ return "PG_DATATYPE_NAME";
case PLPGSQL_GETDIAG_MESSAGE_TEXT:
return "MESSAGE_TEXT";
+ case PLPGSQL_GETDIAG_TABLE_NAME:
+ return "TABLE_NAME";
+ case PLPGSQL_GETDIAG_SCHEMA_NAME:
+ return "SCHEMA_NAME";
}
return "unknown";
case PLPGSQL_RAISEOPTION_HINT:
printf(" HINT = ");
break;
+ case PLPGSQL_RAISEOPTION_COLUMN:
+ printf(" COLUMN = ");
+ break;
+ case PLPGSQL_RAISEOPTION_CONSTRAINT:
+ printf(" CONSTRAINT = ");
+ break;
+ case PLPGSQL_RAISEOPTION_DATATYPE:
+ printf(" DATATYPE = ");
+ break;
+ case PLPGSQL_RAISEOPTION_TABLE:
+ printf(" TABLE = ");
+ break;
+ case PLPGSQL_RAISEOPTION_SCHEMA:
+ printf(" SCHEMA = ");
+ break;
}
dump_expr(opt->expr);
printf("\n");
%token <keyword> K_CASE
%token <keyword> K_CLOSE
%token <keyword> K_COLLATE
+%token <keyword> K_COLUMN
+%token <keyword> K_COLUMN_NAME
%token <keyword> K_CONSTANT
+%token <keyword> K_CONSTRAINT
+%token <keyword> K_CONSTRAINT_NAME
%token <keyword> K_CONTINUE
%token <keyword> K_CURRENT
%token <keyword> K_CURSOR
+%token <keyword> K_DATATYPE
%token <keyword> K_DEBUG
%token <keyword> K_DECLARE
%token <keyword> K_DEFAULT
%token <keyword> K_OPTION
%token <keyword> K_OR
%token <keyword> K_PERFORM
+%token <keyword> K_PG_DATATYPE_NAME
%token <keyword> K_PG_EXCEPTION_CONTEXT
%token <keyword> K_PG_EXCEPTION_DETAIL
%token <keyword> K_PG_EXCEPTION_HINT
%token <keyword> K_REVERSE
%token <keyword> K_ROWTYPE
%token <keyword> K_ROW_COUNT
+%token <keyword> K_SCHEMA
+%token <keyword> K_SCHEMA_NAME
%token <keyword> K_SCROLL
%token <keyword> K_SLICE
%token <keyword> K_SQLSTATE
%token <keyword> K_STACKED
%token <keyword> K_STRICT
+%token <keyword> K_TABLE
+%token <keyword> K_TABLE_NAME
%token <keyword> K_THEN
%token <keyword> K_TO
%token <keyword> K_TYPE
case PLPGSQL_GETDIAG_ERROR_DETAIL:
case PLPGSQL_GETDIAG_ERROR_HINT:
case PLPGSQL_GETDIAG_RETURNED_SQLSTATE:
+ case PLPGSQL_GETDIAG_COLUMN_NAME:
+ case PLPGSQL_GETDIAG_CONSTRAINT_NAME:
+ case PLPGSQL_GETDIAG_DATATYPE_NAME:
case PLPGSQL_GETDIAG_MESSAGE_TEXT:
+ case PLPGSQL_GETDIAG_TABLE_NAME:
+ case PLPGSQL_GETDIAG_SCHEMA_NAME:
if (!new->is_stacked)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
else if (tok_is_keyword(tok, &yylval,
K_PG_EXCEPTION_CONTEXT, "pg_exception_context"))
$$ = PLPGSQL_GETDIAG_ERROR_CONTEXT;
+ else if (tok_is_keyword(tok, &yylval,
+ K_COLUMN_NAME, "column_name"))
+ $$ = PLPGSQL_GETDIAG_COLUMN_NAME;
+ else if (tok_is_keyword(tok, &yylval,
+ K_CONSTRAINT_NAME, "constraint_name"))
+ $$ = PLPGSQL_GETDIAG_CONSTRAINT_NAME;
+ else if (tok_is_keyword(tok, &yylval,
+ K_PG_DATATYPE_NAME, "pg_datatype_name"))
+ $$ = PLPGSQL_GETDIAG_DATATYPE_NAME;
else if (tok_is_keyword(tok, &yylval,
K_MESSAGE_TEXT, "message_text"))
$$ = PLPGSQL_GETDIAG_MESSAGE_TEXT;
+ else if (tok_is_keyword(tok, &yylval,
+ K_TABLE_NAME, "table_name"))
+ $$ = PLPGSQL_GETDIAG_TABLE_NAME;
+ else if (tok_is_keyword(tok, &yylval,
+ K_SCHEMA_NAME, "schema_name"))
+ $$ = PLPGSQL_GETDIAG_SCHEMA_NAME;
else if (tok_is_keyword(tok, &yylval,
K_RETURNED_SQLSTATE, "returned_sqlstate"))
$$ = PLPGSQL_GETDIAG_RETURNED_SQLSTATE;
| K_ALIAS
| K_ARRAY
| K_BACKWARD
+ | K_COLUMN
+ | K_COLUMN_NAME
| K_CONSTANT
+ | K_CONSTRAINT
+ | K_CONSTRAINT_NAME
| K_CURRENT
| K_CURSOR
+ | K_DATATYPE
| K_DEBUG
| K_DETAIL
| K_DUMP
| K_NO
| K_NOTICE
| K_OPTION
+ | K_PG_DATATYPE_NAME
| K_PG_EXCEPTION_CONTEXT
| K_PG_EXCEPTION_DETAIL
| K_PG_EXCEPTION_HINT
| K_REVERSE
| K_ROW_COUNT
| K_ROWTYPE
+ | K_SCHEMA
+ | K_SCHEMA_NAME
| K_SCROLL
| K_SLICE
| K_SQLSTATE
| K_STACKED
+ | K_TABLE
+ | K_TABLE_NAME
| K_TYPE
| K_USE_COLUMN
| K_USE_VARIABLE
else if (tok_is_keyword(tok, &yylval,
K_HINT, "hint"))
opt->opt_type = PLPGSQL_RAISEOPTION_HINT;
+ else if (tok_is_keyword(tok, &yylval,
+ K_COLUMN, "column"))
+ opt->opt_type = PLPGSQL_RAISEOPTION_COLUMN;
+ else if (tok_is_keyword(tok, &yylval,
+ K_CONSTRAINT, "constraint"))
+ opt->opt_type = PLPGSQL_RAISEOPTION_CONSTRAINT;
+ else if (tok_is_keyword(tok, &yylval,
+ K_DATATYPE, "datatype"))
+ opt->opt_type = PLPGSQL_RAISEOPTION_DATATYPE;
+ else if (tok_is_keyword(tok, &yylval,
+ K_TABLE, "table"))
+ opt->opt_type = PLPGSQL_RAISEOPTION_TABLE;
+ else if (tok_is_keyword(tok, &yylval,
+ K_SCHEMA, "schema"))
+ opt->opt_type = PLPGSQL_RAISEOPTION_SCHEMA;
else
yyerror("unrecognized RAISE statement option");
PG_KEYWORD("alias", K_ALIAS, UNRESERVED_KEYWORD)
PG_KEYWORD("array", K_ARRAY, UNRESERVED_KEYWORD)
PG_KEYWORD("backward", K_BACKWARD, UNRESERVED_KEYWORD)
+ PG_KEYWORD("column", K_COLUMN, UNRESERVED_KEYWORD)
+ PG_KEYWORD("column_name", K_COLUMN_NAME, UNRESERVED_KEYWORD)
PG_KEYWORD("constant", K_CONSTANT, UNRESERVED_KEYWORD)
+ PG_KEYWORD("constraint", K_CONSTRAINT, UNRESERVED_KEYWORD)
+ PG_KEYWORD("constraint_name", K_CONSTRAINT_NAME, UNRESERVED_KEYWORD)
PG_KEYWORD("current", K_CURRENT, UNRESERVED_KEYWORD)
PG_KEYWORD("cursor", K_CURSOR, UNRESERVED_KEYWORD)
+ PG_KEYWORD("datatype", K_DATATYPE, UNRESERVED_KEYWORD)
PG_KEYWORD("debug", K_DEBUG, UNRESERVED_KEYWORD)
PG_KEYWORD("detail", K_DETAIL, UNRESERVED_KEYWORD)
PG_KEYWORD("dump", K_DUMP, UNRESERVED_KEYWORD)
PG_KEYWORD("no", K_NO, UNRESERVED_KEYWORD)
PG_KEYWORD("notice", K_NOTICE, UNRESERVED_KEYWORD)
PG_KEYWORD("option", K_OPTION, UNRESERVED_KEYWORD)
+ PG_KEYWORD("pg_datatype_name", K_PG_DATATYPE_NAME, UNRESERVED_KEYWORD)
PG_KEYWORD("pg_exception_context", K_PG_EXCEPTION_CONTEXT, UNRESERVED_KEYWORD)
PG_KEYWORD("pg_exception_detail", K_PG_EXCEPTION_DETAIL, UNRESERVED_KEYWORD)
PG_KEYWORD("pg_exception_hint", K_PG_EXCEPTION_HINT, UNRESERVED_KEYWORD)
PG_KEYWORD("reverse", K_REVERSE, UNRESERVED_KEYWORD)
PG_KEYWORD("row_count", K_ROW_COUNT, UNRESERVED_KEYWORD)
PG_KEYWORD("rowtype", K_ROWTYPE, UNRESERVED_KEYWORD)
+ PG_KEYWORD("schema", K_SCHEMA, UNRESERVED_KEYWORD)
+ PG_KEYWORD("schema_name", K_SCHEMA_NAME, UNRESERVED_KEYWORD)
PG_KEYWORD("scroll", K_SCROLL, UNRESERVED_KEYWORD)
PG_KEYWORD("slice", K_SLICE, UNRESERVED_KEYWORD)
PG_KEYWORD("sqlstate", K_SQLSTATE, UNRESERVED_KEYWORD)
PG_KEYWORD("stacked", K_STACKED, UNRESERVED_KEYWORD)
+ PG_KEYWORD("table", K_TABLE, UNRESERVED_KEYWORD)
+ PG_KEYWORD("table_name", K_TABLE_NAME, UNRESERVED_KEYWORD)
PG_KEYWORD("type", K_TYPE, UNRESERVED_KEYWORD)
PG_KEYWORD("use_column", K_USE_COLUMN, UNRESERVED_KEYWORD)
PG_KEYWORD("use_variable", K_USE_VARIABLE, UNRESERVED_KEYWORD)
PLPGSQL_GETDIAG_ERROR_DETAIL,
PLPGSQL_GETDIAG_ERROR_HINT,
PLPGSQL_GETDIAG_RETURNED_SQLSTATE,
- PLPGSQL_GETDIAG_MESSAGE_TEXT
+ PLPGSQL_GETDIAG_COLUMN_NAME,
+ PLPGSQL_GETDIAG_CONSTRAINT_NAME,
+ PLPGSQL_GETDIAG_DATATYPE_NAME,
+ PLPGSQL_GETDIAG_MESSAGE_TEXT,
+ PLPGSQL_GETDIAG_TABLE_NAME,
+ PLPGSQL_GETDIAG_SCHEMA_NAME
};
/* --------
PLPGSQL_RAISEOPTION_ERRCODE,
PLPGSQL_RAISEOPTION_MESSAGE,
PLPGSQL_RAISEOPTION_DETAIL,
- PLPGSQL_RAISEOPTION_HINT
+ PLPGSQL_RAISEOPTION_HINT,
+ PLPGSQL_RAISEOPTION_COLUMN,
+ PLPGSQL_RAISEOPTION_CONSTRAINT,
+ PLPGSQL_RAISEOPTION_DATATYPE,
+ PLPGSQL_RAISEOPTION_TABLE,
+ PLPGSQL_RAISEOPTION_SCHEMA
};
/* --------
NOTICE: 22012
ERROR: substitute message
drop function raise_test();
+-- test passing column_name, constraint_name, datatype_name, table_name
+-- and schema_name error fields
+create or replace function stacked_diagnostics_test() returns void as $$
+declare _column_name text;
+ _constraint_name text;
+ _datatype_name text;
+ _table_name text;
+ _schema_name text;
+begin
+ raise exception using
+ column = '>>some column name<<',
+ constraint = '>>some constraint name<<',
+ datatype = '>>some datatype name<<',
+ table = '>>some table name<<',
+ schema = '>>some schema name<<';
+exception when others then
+ get stacked diagnostics
+ _column_name = column_name,
+ _constraint_name = constraint_name,
+ _datatype_name = pg_datatype_name,
+ _table_name = table_name,
+ _schema_name = schema_name;
+ raise notice 'column %, constraint %, type %, table %, schema %',
+ _column_name, _constraint_name, _datatype_name, _table_name, _schema_name;
+end;
+$$ language plpgsql;
+select stacked_diagnostics_test();
+NOTICE: column >>some column name<<, constraint >>some constraint name<<, type >>some datatype name<<, table >>some table name<<, schema >>some schema name<<
+ stacked_diagnostics_test
+--------------------------
+
+(1 row)
+
+drop function stacked_diagnostics_test();
-- test CASE statement
create or replace function case_test(bigint) returns text as $$
declare a int = 10;
drop function raise_test();
+-- test passing column_name, constraint_name, datatype_name, table_name
+-- and schema_name error fields
+
+create or replace function stacked_diagnostics_test() returns void as $$
+declare _column_name text;
+ _constraint_name text;
+ _datatype_name text;
+ _table_name text;
+ _schema_name text;
+begin
+ raise exception using
+ column = '>>some column name<<',
+ constraint = '>>some constraint name<<',
+ datatype = '>>some datatype name<<',
+ table = '>>some table name<<',
+ schema = '>>some schema name<<';
+exception when others then
+ get stacked diagnostics
+ _column_name = column_name,
+ _constraint_name = constraint_name,
+ _datatype_name = pg_datatype_name,
+ _table_name = table_name,
+ _schema_name = schema_name;
+ raise notice 'column %, constraint %, type %, table %, schema %',
+ _column_name, _constraint_name, _datatype_name, _table_name, _schema_name;
+end;
+$$ language plpgsql;
+
+select stacked_diagnostics_test();
+
+drop function stacked_diagnostics_test();
+
-- test CASE statement
create or replace function case_test(bigint) returns text as $$