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; /*