Ășt 4. 4. 2023 v 16:20 odesĂlatel Tom Lane <t...@sss.pgh.pa.us> napsal:
> Pavel Stehule <pavel.steh...@gmail.com> writes: > > There is reduced patch + regress tests > > One more thing: I do not think it's appropriate to allow this in > GET STACKED DIAGNOSTICS. That's about reporting the place where > an error occurred, not the current location. Eventually it might > be interesting to retrieve the OID of the function that contained > the error, but that would be a pretty complicated patch and I am > not sure it's worth it. In the meantime I think we should just > forbid it. > > If we do that, then the confusion you were concerned about upthread > goes away and we could shorten the keyword back down to "pg_routine_oid", > which seems like a good thing for our carpal tunnels. > > Thoughts? > has sense updated patch attached Regards Pavel > > regards, tom lane >
diff --git a/doc/src/sgml/plpgsql.sgml b/doc/src/sgml/plpgsql.sgml index 7c8a49fe43..163ca48f31 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_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..1603ba073d 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_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..1b0c857b7d 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_ROUTINE_OID: + return "PG_ROUTINE_OID"; } return "unknown"; diff --git a/src/pl/plpgsql/src/pl_gram.y b/src/pl/plpgsql/src/pl_gram.y index edeb72c380..bf2c04852b 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_ROUTINE_OID %token <keyword> K_PG_DATATYPE_NAME %token <keyword> K_PG_EXCEPTION_CONTEXT %token <keyword> K_PG_EXCEPTION_DETAIL @@ -1008,6 +1009,7 @@ stmt_getdiag : K_GET getdiag_area_opt K_DIAGNOSTICS getdiag_list ';' { /* these fields are disallowed in stacked case */ case PLPGSQL_GETDIAG_ROW_COUNT: + case PLPGSQL_GETDIAG_ROUTINE_OID: if (new->is_stacked) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), @@ -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_ROUTINE_OID, "pg_routine_oid")) + $$ = PLPGSQL_GETDIAG_ROUTINE_OID; else yyerror("unrecognized GET DIAGNOSTICS item"); } @@ -2523,6 +2528,7 @@ unreserved_keyword : | K_OPEN | K_OPTION | K_PERFORM + | K_PG_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..3e258a6bb9 100644 --- a/src/pl/plpgsql/src/pl_unreserved_kwlist.h +++ b/src/pl/plpgsql/src/pl_unreserved_kwlist.h @@ -85,6 +85,7 @@ 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) PG_KEYWORD("pg_exception_hint", K_PG_EXCEPTION_HINT) +PG_KEYWORD("pg_routine_oid", K_PG_ROUTINE_OID) PG_KEYWORD("print_strict_params", K_PRINT_STRICT_PARAMS) PG_KEYWORD("prior", K_PRIOR) PG_KEYWORD("query", K_QUERY) diff --git a/src/pl/plpgsql/src/plpgsql.h b/src/pl/plpgsql/src/plpgsql.h index 355c9f678d..7e574b8052 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_ROUTINE_OID } PLpgSQL_getdiag_kind; /* diff --git a/src/test/regress/expected/plpgsql.out b/src/test/regress/expected/plpgsql.out index 2d26be1a81..df01788a3a 100644 --- a/src/test/regress/expected/plpgsql.out +++ b/src/test/regress/expected/plpgsql.out @@ -5798,3 +5798,32 @@ 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_ROUTINE_OID; + RAISE NOTICE 'ok'; +END; +$$; +NOTICE: ok +-- should fail, PG_ROUTINE_OID is not allowed in GET STACKED DIAGNOSTICS +DO $$ +DECLARE + fn_oid oid; +BEGIN + RAISE EXCEPTION 'error'; +EXCEPTION WHEN others THEN + GET STACKED DIAGNOSTICS fn_oid = PG_ROUTINE_OID; + RAISE NOTICE 'ok'; +END; +$$; +ERROR: diagnostics item PG_ROUTINE_OID is not allowed in GET STACKED DIAGNOSTICS +LINE 7: GET STACKED DIAGNOSTICS fn_oid = PG_ROUTINE_OID; + ^ diff --git a/src/test/regress/sql/plpgsql.sql b/src/test/regress/sql/plpgsql.sql index 98365e087f..51640d6b37 100644 --- a/src/test/regress/sql/plpgsql.sql +++ b/src/test/regress/sql/plpgsql.sql @@ -4731,3 +4731,30 @@ 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_ROUTINE_OID; + RAISE NOTICE 'ok'; +END; +$$; + +-- should fail, PG_ROUTINE_OID is not allowed in GET STACKED DIAGNOSTICS +DO $$ +DECLARE + fn_oid oid; +BEGIN + RAISE EXCEPTION 'error'; +EXCEPTION WHEN others THEN + GET STACKED DIAGNOSTICS fn_oid = PG_ROUTINE_OID; + RAISE NOTICE 'ok'; +END; +$$;