On Sun, Mar 26, 2023 at 5:37 PM Kirk Wolak <wol...@gmail.com> wrote:
> On Wed, Feb 8, 2023 at 10:56 AM Kirk Wolak <wol...@gmail.com> wrote: > >> On Wed, Feb 8, 2023 at 3:08 AM Pavel Stehule <pavel.steh...@gmail.com> >> wrote: >> >>> 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: >>>> > >>>> > GET DIAGNOSTICS _oid = PG_ROUTINE_OID; >>>> > RAISE NOTICE '... % ... %', _oid, _oid::regproc::text; >>>> > >>>> > 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 >>> >> >> I agree that the name changed to pg_current_routine_... makes the most >> sense, great call... >> >> +1 >> > > Okay, I reviewed this. I tested it (allocating too small of > varchar's for values, various "signature types"), > and also a performance test... Wow, on my VM, 10,000 Calls in a loop was > 2-4ms... > > The names are clear. Again, I tested with various options, and including > ROW_COUNT, or not. > > This functions PERFECTLY.... Except there are no documentation changes. > Because of that, I set it to Waiting on Author. > Which might be unfair, because I could take a stab at doing the > documentation (but docs are not compiling on my setup yet). > > The documentation changes are simple enough. > If I can get the docs compiled on my rig, I will see if I can make the > changes, and post an updated patch, > that contains both... > > But I don't want to be stepping on toes, or having it look like I am > taking credit. > > Regards - Kirk > Okay, I have modified the documentation and made sure it compiles. They were simple enough changes. I am attaching this updated patch. I have marked the item Ready for Commiter... Thanks for your patience. I now have a workable hacking environment! Regards - Kirk
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; <entry>line(s) of text describing the current call stack (see <xref linkend="plpgsql-call-stack"/>)</entry> </row> + <row> + <entry><literal>PG_CURRENT_ROUTINE_SIGNATURE</literal></entry> + <entry><type>text</type></entry> + <entry>text describing the current routine with paramater types</entry> + </row> + <row> + <entry><literal>PG_CURRENT_ROUTINE_NAME</literal></entry> + <entry><type>text</type></entry> + <entry>text name of the function without parenthesis</entry> + </row> + <row> + <entry><literal>PG_CURRENT_ROUTINE_OID</literal></entry> + <entry><type>oid</type></entry> + <entry>oid of the function currently running</entry> + </row> </tbody> </tgroup> </table> 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 <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; /*