hi


st 8. 2. 2023 v 7:33 odesílatel Julien Rouhaud <rjuju...@gmail.com> napsal:

> On Tue, Feb 07, 2023 at 08:48:22PM +0100, Pavel Stehule wrote:
> >
> > I have a question about the possibility of simply getting the name of the
> > currently executed function. The reason for this request is
> simplification
> > of writing debug messages.
> >
> > GET DIAGNOSTICS _oid = PG_ROUTINE_OID;
> > RAISE NOTICE '... % ... %', _oid, _oid::regproc::text;
> >
> > The advantage of this dynamic access to function name is always valid
> value
> > not sensitive to some renaming or moving between schemas.
> >
> > I am able to separate a name from context, but it can be harder to write
> > this separation really robustly. It can be very easy to enhance the GET
> > DIAGNOSTICS statement to return the oid of currently executed function.
> >
> > Do you think it can be useful feature?
>
> +1, it would have been quite handy in a few of my projects.
>

it can looks like that

create or replace function foo(a int)
returns int as $$
declare s text; n text; o oid;
begin
  get diagnostics s = pg_current_routine_signature,
                  n = pg_current_routine_name,
                  o = pg_current_routine_oid;
  raise notice 'sign:%,  name:%,  oid:%', s, n, o;
  return a;
end;
$$ language plpgsql;
CREATE FUNCTION
(2023-02-08 09:04:03) postgres=# select foo(10);
NOTICE:  sign:foo(integer),  name:foo,  oid:16392
┌─────┐
│ foo │
╞═════╡
│  10 │
└─────┘
(1 row)

The name - pg_routine_oid can be confusing, because there is not clean if
it is oid of currently executed routine or routine from top of exception

Regards

Pavel
diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c
index 70a002a0f6..908022a88a 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 <keyword>	K_OR
 %token <keyword>	K_PERFORM
 %token <keyword>	K_PG_CONTEXT
+%token <keyword>	K_PG_CURRENT_ROUTINE_NAME
+%token <keyword>	K_PG_CURRENT_ROUTINE_OID
+%token <keyword>	K_PG_CURRENT_ROUTINE_SIGNATURE
 %token <keyword>	K_PG_DATATYPE_NAME
 %token <keyword>	K_PG_EXCEPTION_CONTEXT
 %token <keyword>	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;
 
 /*

Reply via email to