Hi
po 3. 4. 2023 v 19:37 odesÃlatel Tom Lane <t...@sss.pgh.pa.us> napsal: > Pavel Stehule <pavel.steh...@gmail.com> writes: > > po 27. 3. 2023 v 5:36 odesÃlatel Kirk Wolak <wol...@gmail.com> napsal: > >> I have marked the item Ready for Commiter... > > > Thank you for doc and for review > > I'm kind of surprised there was any interest in this proposal at all, > TBH, but apparently there is some. Still, I think you over-engineered > it by doing more than the original proposal of making the function OID > available. The other things can be had by casting the OID to regproc > or regprocedure, so I'd be inclined to add just one new keyword not > three. Besides, your implementation is a bit inconsistent: relying > on fn_signature could return a result that is stale or doesn't conform > to the current search_path. > ok There is reduced patch + regress tests Regards Pavel > regards, tom lane >
diff --git a/doc/src/sgml/plpgsql.sgml b/doc/src/sgml/plpgsql.sgml index 7c8a49fe43..4df1b71904 100644 --- a/doc/src/sgml/plpgsql.sgml +++ b/doc/src/sgml/plpgsql.sgml @@ -1639,6 +1639,11 @@ 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_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..ed9d26258b 100644 --- a/src/pl/plpgsql/src/pl_exec.c +++ b/src/pl/plpgsql/src/pl_exec.c @@ -2475,6 +2475,12 @@ exec_stmt_getdiag(PLpgSQL_execstate *estate, PLpgSQL_stmt_getdiag *stmt) } break; + case PLPGSQL_GETDIAG_CURRENT_ROUTINE_OID: + exec_assign_value(estate, var, + ObjectIdGetDatum(estate->func->fn_oid), + false, OIDOID, -1); + 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..4ebf393646 100644 --- a/src/pl/plpgsql/src/pl_funcs.c +++ b/src/pl/plpgsql/src/pl_funcs.c @@ -325,6 +325,8 @@ plpgsql_getdiag_kindname(PLpgSQL_getdiag_kind kind) return "TABLE_NAME"; case PLPGSQL_GETDIAG_SCHEMA_NAME: return "SCHEMA_NAME"; + case PLPGSQL_GETDIAG_CURRENT_ROUTINE_OID: + return "PG_CURRENT_ROUTINE_OID"; } return "unknown"; diff --git a/src/pl/plpgsql/src/pl_gram.y b/src/pl/plpgsql/src/pl_gram.y index edeb72c380..6e81cf774d 100644 --- a/src/pl/plpgsql/src/pl_gram.y +++ b/src/pl/plpgsql/src/pl_gram.y @@ -318,6 +318,7 @@ 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_OID %token <keyword> K_PG_DATATYPE_NAME %token <keyword> K_PG_EXCEPTION_CONTEXT %token <keyword> K_PG_EXCEPTION_DETAIL @@ -1035,6 +1036,7 @@ 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_OID: break; default: elog(ERROR, "unrecognized diagnostic item kind: %d", @@ -1123,6 +1125,9 @@ 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_OID, "pg_current_routine_oid")) + $$ = PLPGSQL_GETDIAG_CURRENT_ROUTINE_OID; else yyerror("unrecognized GET DIAGNOSTICS item"); } @@ -2523,6 +2528,7 @@ unreserved_keyword : | K_OPEN | K_OPTION | K_PERFORM + | K_PG_CURRENT_ROUTINE_OID | 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..b569d75708 100644 --- a/src/pl/plpgsql/src/pl_unreserved_kwlist.h +++ b/src/pl/plpgsql/src/pl_unreserved_kwlist.h @@ -81,6 +81,7 @@ 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_oid", K_PG_CURRENT_ROUTINE_OID) 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..258ce4dec7 100644 --- a/src/pl/plpgsql/src/plpgsql.h +++ b/src/pl/plpgsql/src/plpgsql.h @@ -157,7 +157,8 @@ 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_OID } PLpgSQL_getdiag_kind; /* diff --git a/src/test/regress/expected/plpgsql.out b/src/test/regress/expected/plpgsql.out index 2d26be1a81..56ed4e14bf 100644 --- a/src/test/regress/expected/plpgsql.out +++ b/src/test/regress/expected/plpgsql.out @@ -5798,3 +5798,29 @@ END; $$ LANGUAGE plpgsql; ERROR: "x" is not a scalar variable LINE 3: GET DIAGNOSTICS x = ROW_COUNT; ^ +-- +-- Check pg_current_routine_oid +-- +-- Note: the result cannot be displayed, but we can check so +-- the related value is assigned without errors. +-- +DO $$ +DECLARE + fn_oid oid; +BEGIN + GET DIAGNOSTICS fn_oid = PG_CURRENT_ROUTINE_OID; + RAISE NOTICE 'ok'; +END; +$$; +NOTICE: ok +DO $$ +DECLARE + fn_oid oid; +BEGIN + RAISE EXCEPTION 'error'; +EXCEPTION WHEN others THEN + GET STACKED DIAGNOSTICS fn_oid = PG_CURRENT_ROUTINE_OID; + RAISE NOTICE 'ok'; +END; +$$; +NOTICE: ok diff --git a/src/test/regress/sql/plpgsql.sql b/src/test/regress/sql/plpgsql.sql index 98365e087f..8fb56b93ef 100644 --- a/src/test/regress/sql/plpgsql.sql +++ b/src/test/regress/sql/plpgsql.sql @@ -4731,3 +4731,29 @@ BEGIN GET DIAGNOSTICS x = ROW_COUNT; RETURN; END; $$ LANGUAGE plpgsql; + +-- +-- Check pg_current_routine_oid +-- +-- Note: the result cannot be displayed, but we can check so +-- the related value is assigned without errors. +-- +DO $$ +DECLARE + fn_oid oid; +BEGIN + GET DIAGNOSTICS fn_oid = PG_CURRENT_ROUTINE_OID; + RAISE NOTICE 'ok'; +END; +$$; + +DO $$ +DECLARE + fn_oid oid; +BEGIN + RAISE EXCEPTION 'error'; +EXCEPTION WHEN others THEN + GET STACKED DIAGNOSTICS fn_oid = PG_CURRENT_ROUTINE_OID; + RAISE NOTICE 'ok'; +END; +$$;