Ășt 4. 4. 2023 v 16:20 odesĂlatel Tom Lane <[email protected]> napsal:
> Pavel Stehule <[email protected]> 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;
+$$;