mirror of
https://github.com/postgres/postgres.git
synced 2025-07-27 12:41:57 +03:00
Add GET DIAGNOSTICS ... PG_CONTEXT in PL/PgSQL
This adds the ability to get the call stack as a string from within a PL/PgSQL function, which can be handy for logging to a table, or to include in a useful message to an end-user. Pavel Stehule, reviewed by Rushabh Lathia and rather heavily whacked around by Stephen Frost.
This commit is contained in:
@ -1599,6 +1599,16 @@ exec_stmt_getdiag(PLpgSQL_execstate *estate, PLpgSQL_stmt_getdiag *stmt)
|
||||
estate->cur_error->schema_name);
|
||||
break;
|
||||
|
||||
case PLPGSQL_GETDIAG_CONTEXT:
|
||||
{
|
||||
char *contextstackstr = GetErrorContextStack();
|
||||
|
||||
exec_assign_c_string(estate, var, contextstackstr);
|
||||
|
||||
pfree(contextstackstr);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
elog(ERROR, "unrecognized diagnostic item kind: %d",
|
||||
diag_item->kind);
|
||||
|
@ -277,6 +277,8 @@ plpgsql_getdiag_kindname(int kind)
|
||||
return "ROW_COUNT";
|
||||
case PLPGSQL_GETDIAG_RESULT_OID:
|
||||
return "RESULT_OID";
|
||||
case PLPGSQL_GETDIAG_CONTEXT:
|
||||
return "PG_CONTEXT";
|
||||
case PLPGSQL_GETDIAG_ERROR_CONTEXT:
|
||||
return "PG_EXCEPTION_CONTEXT";
|
||||
case PLPGSQL_GETDIAG_ERROR_DETAIL:
|
||||
|
@ -303,6 +303,7 @@ static List *read_raise_options(void);
|
||||
%token <keyword> K_OPTION
|
||||
%token <keyword> K_OR
|
||||
%token <keyword> K_PERFORM
|
||||
%token <keyword> K_PG_CONTEXT
|
||||
%token <keyword> K_PG_DATATYPE_NAME
|
||||
%token <keyword> K_PG_EXCEPTION_CONTEXT
|
||||
%token <keyword> K_PG_EXCEPTION_DETAIL
|
||||
@ -894,6 +895,7 @@ stmt_getdiag : K_GET getdiag_area_opt K_DIAGNOSTICS getdiag_list ';'
|
||||
/* these fields are disallowed in stacked case */
|
||||
case PLPGSQL_GETDIAG_ROW_COUNT:
|
||||
case PLPGSQL_GETDIAG_RESULT_OID:
|
||||
case PLPGSQL_GETDIAG_CONTEXT:
|
||||
if (new->is_stacked)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_SYNTAX_ERROR),
|
||||
@ -976,6 +978,9 @@ getdiag_item :
|
||||
else if (tok_is_keyword(tok, &yylval,
|
||||
K_RESULT_OID, "result_oid"))
|
||||
$$ = PLPGSQL_GETDIAG_RESULT_OID;
|
||||
else if (tok_is_keyword(tok, &yylval,
|
||||
K_PG_CONTEXT, "pg_context"))
|
||||
$$ = PLPGSQL_GETDIAG_CONTEXT;
|
||||
else if (tok_is_keyword(tok, &yylval,
|
||||
K_PG_EXCEPTION_DETAIL, "pg_exception_detail"))
|
||||
$$ = PLPGSQL_GETDIAG_ERROR_DETAIL;
|
||||
@ -2287,6 +2292,7 @@ unreserved_keyword :
|
||||
| K_NO
|
||||
| K_NOTICE
|
||||
| K_OPTION
|
||||
| K_PG_CONTEXT
|
||||
| K_PG_DATATYPE_NAME
|
||||
| K_PG_EXCEPTION_CONTEXT
|
||||
| K_PG_EXCEPTION_DETAIL
|
||||
|
@ -135,6 +135,7 @@ static const ScanKeyword unreserved_keywords[] = {
|
||||
PG_KEYWORD("no", K_NO, UNRESERVED_KEYWORD)
|
||||
PG_KEYWORD("notice", K_NOTICE, UNRESERVED_KEYWORD)
|
||||
PG_KEYWORD("option", K_OPTION, UNRESERVED_KEYWORD)
|
||||
PG_KEYWORD("pg_context", K_PG_CONTEXT, 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)
|
||||
|
@ -124,6 +124,7 @@ enum
|
||||
{
|
||||
PLPGSQL_GETDIAG_ROW_COUNT,
|
||||
PLPGSQL_GETDIAG_RESULT_OID,
|
||||
PLPGSQL_GETDIAG_CONTEXT,
|
||||
PLPGSQL_GETDIAG_ERROR_CONTEXT,
|
||||
PLPGSQL_GETDIAG_ERROR_DETAIL,
|
||||
PLPGSQL_GETDIAG_ERROR_HINT,
|
||||
|
Reference in New Issue
Block a user