diff --git a/doc/src/sgml/plpgsql.sgml b/doc/src/sgml/plpgsql.sgml
index 7c8a49fe43..19dfe529cf 100644
--- a/doc/src/sgml/plpgsql.sgml
+++ b/doc/src/sgml/plpgsql.sgml
@@ -1639,6 +1639,21 @@ GET DIAGNOSTICS integer_var = ROW_COUNT;
line(s) of text describing the current call stack
(see )
+
+ PG_CURRENT_ROUTINE_SIGNATURE
+ text
+ text describing the current routine with paramater types
+
+
+ PG_CURRENT_ROUTINE_NAME
+ text
+ text name of the function without parenthesis
+
+
+ PG_CURRENT_ROUTINE_OID
+ oid
+ oid of the function currently running
+
diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c
index b0a2cac227..bb2f3ff828 100644
--- a/src/pl/plpgsql/src/pl_exec.c
+++ b/src/pl/plpgsql/src/pl_exec.c
@@ -2475,6 +2475,28 @@ exec_stmt_getdiag(PLpgSQL_execstate *estate, PLpgSQL_stmt_getdiag *stmt)
}
break;
+ case PLPGSQL_GETDIAG_CURRENT_ROUTINE_NAME:
+ {
+ char *funcname;
+
+ funcname = get_func_name(estate->func->fn_oid);
+ exec_assign_c_string(estate, var, funcname);
+ if (funcname)
+ pfree(funcname);
+ }
+ break;
+
+ case PLPGSQL_GETDIAG_CURRENT_ROUTINE_OID:
+ exec_assign_value(estate, var,
+ ObjectIdGetDatum(estate->func->fn_oid),
+ false, OIDOID, -1);
+ break;
+
+ case PLPGSQL_GETDIAG_CURRENT_ROUTINE_SIGNATURE:
+ exec_assign_c_string(estate, var,
+ estate->func->fn_signature);
+ break;
+
default:
elog(ERROR, "unrecognized diagnostic item kind: %d",
diag_item->kind);
diff --git a/src/pl/plpgsql/src/pl_funcs.c b/src/pl/plpgsql/src/pl_funcs.c
index 5a6eadccd5..bdf02f36cc 100644
--- a/src/pl/plpgsql/src/pl_funcs.c
+++ b/src/pl/plpgsql/src/pl_funcs.c
@@ -325,6 +325,12 @@ plpgsql_getdiag_kindname(PLpgSQL_getdiag_kind kind)
return "TABLE_NAME";
case PLPGSQL_GETDIAG_SCHEMA_NAME:
return "SCHEMA_NAME";
+ case PLPGSQL_GETDIAG_CURRENT_ROUTINE_NAME:
+ return "PG_CURRENT_ROUTINE_NAME";
+ case PLPGSQL_GETDIAG_CURRENT_ROUTINE_OID:
+ return "PG_CURRENT_ROUTINE_OID";
+ case PLPGSQL_GETDIAG_CURRENT_ROUTINE_SIGNATURE:
+ return "PG_CURRENT_ROUTINE_SIGNATURE";
}
return "unknown";
diff --git a/src/pl/plpgsql/src/pl_gram.y b/src/pl/plpgsql/src/pl_gram.y
index edeb72c380..9ea21fec3d 100644
--- a/src/pl/plpgsql/src/pl_gram.y
+++ b/src/pl/plpgsql/src/pl_gram.y
@@ -318,6 +318,9 @@ static void check_raise_parameters(PLpgSQL_stmt_raise *stmt);
%token K_OR
%token K_PERFORM
%token K_PG_CONTEXT
+%token K_PG_CURRENT_ROUTINE_NAME
+%token K_PG_CURRENT_ROUTINE_OID
+%token K_PG_CURRENT_ROUTINE_SIGNATURE
%token K_PG_DATATYPE_NAME
%token K_PG_EXCEPTION_CONTEXT
%token K_PG_EXCEPTION_DETAIL
@@ -1035,6 +1038,9 @@ stmt_getdiag : K_GET getdiag_area_opt K_DIAGNOSTICS getdiag_list ';'
break;
/* these fields are allowed in either case */
case PLPGSQL_GETDIAG_CONTEXT:
+ case PLPGSQL_GETDIAG_CURRENT_ROUTINE_NAME:
+ case PLPGSQL_GETDIAG_CURRENT_ROUTINE_OID:
+ case PLPGSQL_GETDIAG_CURRENT_ROUTINE_SIGNATURE:
break;
default:
elog(ERROR, "unrecognized diagnostic item kind: %d",
@@ -1123,6 +1129,15 @@ getdiag_item :
else if (tok_is_keyword(tok, &yylval,
K_RETURNED_SQLSTATE, "returned_sqlstate"))
$$ = PLPGSQL_GETDIAG_RETURNED_SQLSTATE;
+ else if (tok_is_keyword(tok, &yylval,
+ K_PG_CURRENT_ROUTINE_NAME, "pg_current_routine_name"))
+ $$ = PLPGSQL_GETDIAG_CURRENT_ROUTINE_NAME;
+ else if (tok_is_keyword(tok, &yylval,
+ K_PG_CURRENT_ROUTINE_OID, "pg_current_routine_oid"))
+ $$ = PLPGSQL_GETDIAG_CURRENT_ROUTINE_OID;
+ else if (tok_is_keyword(tok, &yylval,
+ K_PG_CURRENT_ROUTINE_SIGNATURE, "pg_current_routine_signature"))
+ $$ = PLPGSQL_GETDIAG_CURRENT_ROUTINE_SIGNATURE;
else
yyerror("unrecognized GET DIAGNOSTICS item");
}
@@ -2523,6 +2538,9 @@ unreserved_keyword :
| K_OPEN
| K_OPTION
| K_PERFORM
+ | K_PG_CURRENT_ROUTINE_NAME
+ | K_PG_CURRENT_ROUTINE_OID
+ | K_PG_CURRENT_ROUTINE_SIGNATURE
| K_PG_CONTEXT
| K_PG_DATATYPE_NAME
| K_PG_EXCEPTION_CONTEXT
diff --git a/src/pl/plpgsql/src/pl_unreserved_kwlist.h b/src/pl/plpgsql/src/pl_unreserved_kwlist.h
index 466bdc7a20..6d5a14eb28 100644
--- a/src/pl/plpgsql/src/pl_unreserved_kwlist.h
+++ b/src/pl/plpgsql/src/pl_unreserved_kwlist.h
@@ -81,6 +81,9 @@ PG_KEYWORD("open", K_OPEN)
PG_KEYWORD("option", K_OPTION)
PG_KEYWORD("perform", K_PERFORM)
PG_KEYWORD("pg_context", K_PG_CONTEXT)
+PG_KEYWORD("pg_current_routine_name", K_PG_CURRENT_ROUTINE_NAME)
+PG_KEYWORD("pg_current_routine_oid", K_PG_CURRENT_ROUTINE_OID)
+PG_KEYWORD("pg_current_routine_signature", K_PG_CURRENT_ROUTINE_SIGNATURE)
PG_KEYWORD("pg_datatype_name", K_PG_DATATYPE_NAME)
PG_KEYWORD("pg_exception_context", K_PG_EXCEPTION_CONTEXT)
PG_KEYWORD("pg_exception_detail", K_PG_EXCEPTION_DETAIL)
diff --git a/src/pl/plpgsql/src/plpgsql.h b/src/pl/plpgsql/src/plpgsql.h
index 355c9f678d..42c094fb48 100644
--- a/src/pl/plpgsql/src/plpgsql.h
+++ b/src/pl/plpgsql/src/plpgsql.h
@@ -157,7 +157,10 @@ typedef enum PLpgSQL_getdiag_kind
PLPGSQL_GETDIAG_DATATYPE_NAME,
PLPGSQL_GETDIAG_MESSAGE_TEXT,
PLPGSQL_GETDIAG_TABLE_NAME,
- PLPGSQL_GETDIAG_SCHEMA_NAME
+ PLPGSQL_GETDIAG_SCHEMA_NAME,
+ PLPGSQL_GETDIAG_CURRENT_ROUTINE_NAME,
+ PLPGSQL_GETDIAG_CURRENT_ROUTINE_OID,
+ PLPGSQL_GETDIAG_CURRENT_ROUTINE_SIGNATURE
} PLpgSQL_getdiag_kind;
/*