mirror of
https://github.com/postgres/postgres.git
synced 2025-07-27 12:41:57 +03:00
Add a way to get the current function's OID in pl/pgsql.
Invent "GET DIAGNOSTICS oid_variable = PG_ROUTINE_OID". This is useful for avoiding the maintenance nuisances that come with embedding a function's name in its body, as one might do for logging purposes for example. Typically users would cast the result to regproc or regprocedure to get something human-readable, but we won't pre-judge whether that's appropriate. Pavel Stehule, reviewed by Kirk Wolak and myself Discussion: https://postgr.es/m/CAFj8pRA4zMd5pY-B89Gm64bDLRt-L+akOd34aD1j4PEstHHSVQ@mail.gmail.com
This commit is contained in:
@ -1639,6 +1639,11 @@ GET DIAGNOSTICS integer_var = ROW_COUNT;
|
|||||||
<entry>line(s) of text describing the current call stack
|
<entry>line(s) of text describing the current call stack
|
||||||
(see <xref linkend="plpgsql-call-stack"/>)</entry>
|
(see <xref linkend="plpgsql-call-stack"/>)</entry>
|
||||||
</row>
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry><literal>PG_ROUTINE_OID</literal></entry>
|
||||||
|
<entry><type>oid</type></entry>
|
||||||
|
<entry>OID of the current function</entry>
|
||||||
|
</row>
|
||||||
</tbody>
|
</tbody>
|
||||||
</tgroup>
|
</tgroup>
|
||||||
</table>
|
</table>
|
||||||
|
@ -2411,6 +2411,12 @@ exec_stmt_getdiag(PLpgSQL_execstate *estate, PLpgSQL_stmt_getdiag *stmt)
|
|||||||
false, INT8OID, -1);
|
false, INT8OID, -1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PLPGSQL_GETDIAG_ROUTINE_OID:
|
||||||
|
exec_assign_value(estate, var,
|
||||||
|
ObjectIdGetDatum(estate->func->fn_oid),
|
||||||
|
false, OIDOID, -1);
|
||||||
|
break;
|
||||||
|
|
||||||
case PLPGSQL_GETDIAG_ERROR_CONTEXT:
|
case PLPGSQL_GETDIAG_ERROR_CONTEXT:
|
||||||
exec_assign_c_string(estate, var,
|
exec_assign_c_string(estate, var,
|
||||||
estate->cur_error->context);
|
estate->cur_error->context);
|
||||||
|
@ -303,6 +303,8 @@ plpgsql_getdiag_kindname(PLpgSQL_getdiag_kind kind)
|
|||||||
{
|
{
|
||||||
case PLPGSQL_GETDIAG_ROW_COUNT:
|
case PLPGSQL_GETDIAG_ROW_COUNT:
|
||||||
return "ROW_COUNT";
|
return "ROW_COUNT";
|
||||||
|
case PLPGSQL_GETDIAG_ROUTINE_OID:
|
||||||
|
return "PG_ROUTINE_OID";
|
||||||
case PLPGSQL_GETDIAG_CONTEXT:
|
case PLPGSQL_GETDIAG_CONTEXT:
|
||||||
return "PG_CONTEXT";
|
return "PG_CONTEXT";
|
||||||
case PLPGSQL_GETDIAG_ERROR_CONTEXT:
|
case PLPGSQL_GETDIAG_ERROR_CONTEXT:
|
||||||
|
@ -322,6 +322,7 @@ static void check_raise_parameters(PLpgSQL_stmt_raise *stmt);
|
|||||||
%token <keyword> K_PG_EXCEPTION_CONTEXT
|
%token <keyword> K_PG_EXCEPTION_CONTEXT
|
||||||
%token <keyword> K_PG_EXCEPTION_DETAIL
|
%token <keyword> K_PG_EXCEPTION_DETAIL
|
||||||
%token <keyword> K_PG_EXCEPTION_HINT
|
%token <keyword> K_PG_EXCEPTION_HINT
|
||||||
|
%token <keyword> K_PG_ROUTINE_OID
|
||||||
%token <keyword> K_PRINT_STRICT_PARAMS
|
%token <keyword> K_PRINT_STRICT_PARAMS
|
||||||
%token <keyword> K_PRIOR
|
%token <keyword> K_PRIOR
|
||||||
%token <keyword> K_QUERY
|
%token <keyword> K_QUERY
|
||||||
@ -1008,6 +1009,7 @@ stmt_getdiag : K_GET getdiag_area_opt K_DIAGNOSTICS getdiag_list ';'
|
|||||||
{
|
{
|
||||||
/* these fields are disallowed in stacked case */
|
/* these fields are disallowed in stacked case */
|
||||||
case PLPGSQL_GETDIAG_ROW_COUNT:
|
case PLPGSQL_GETDIAG_ROW_COUNT:
|
||||||
|
case PLPGSQL_GETDIAG_ROUTINE_OID:
|
||||||
if (new->is_stacked)
|
if (new->is_stacked)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_SYNTAX_ERROR),
|
(errcode(ERRCODE_SYNTAX_ERROR),
|
||||||
@ -1090,6 +1092,9 @@ getdiag_item :
|
|||||||
if (tok_is_keyword(tok, &yylval,
|
if (tok_is_keyword(tok, &yylval,
|
||||||
K_ROW_COUNT, "row_count"))
|
K_ROW_COUNT, "row_count"))
|
||||||
$$ = PLPGSQL_GETDIAG_ROW_COUNT;
|
$$ = PLPGSQL_GETDIAG_ROW_COUNT;
|
||||||
|
else if (tok_is_keyword(tok, &yylval,
|
||||||
|
K_PG_ROUTINE_OID, "pg_routine_oid"))
|
||||||
|
$$ = PLPGSQL_GETDIAG_ROUTINE_OID;
|
||||||
else if (tok_is_keyword(tok, &yylval,
|
else if (tok_is_keyword(tok, &yylval,
|
||||||
K_PG_CONTEXT, "pg_context"))
|
K_PG_CONTEXT, "pg_context"))
|
||||||
$$ = PLPGSQL_GETDIAG_CONTEXT;
|
$$ = PLPGSQL_GETDIAG_CONTEXT;
|
||||||
@ -2528,6 +2533,7 @@ unreserved_keyword :
|
|||||||
| K_PG_EXCEPTION_CONTEXT
|
| K_PG_EXCEPTION_CONTEXT
|
||||||
| K_PG_EXCEPTION_DETAIL
|
| K_PG_EXCEPTION_DETAIL
|
||||||
| K_PG_EXCEPTION_HINT
|
| K_PG_EXCEPTION_HINT
|
||||||
|
| K_PG_ROUTINE_OID
|
||||||
| K_PRINT_STRICT_PARAMS
|
| K_PRINT_STRICT_PARAMS
|
||||||
| K_PRIOR
|
| K_PRIOR
|
||||||
| K_QUERY
|
| K_QUERY
|
||||||
|
@ -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_context", K_PG_EXCEPTION_CONTEXT)
|
||||||
PG_KEYWORD("pg_exception_detail", K_PG_EXCEPTION_DETAIL)
|
PG_KEYWORD("pg_exception_detail", K_PG_EXCEPTION_DETAIL)
|
||||||
PG_KEYWORD("pg_exception_hint", K_PG_EXCEPTION_HINT)
|
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("print_strict_params", K_PRINT_STRICT_PARAMS)
|
||||||
PG_KEYWORD("prior", K_PRIOR)
|
PG_KEYWORD("prior", K_PRIOR)
|
||||||
PG_KEYWORD("query", K_QUERY)
|
PG_KEYWORD("query", K_QUERY)
|
||||||
|
@ -147,6 +147,7 @@ enum
|
|||||||
typedef enum PLpgSQL_getdiag_kind
|
typedef enum PLpgSQL_getdiag_kind
|
||||||
{
|
{
|
||||||
PLPGSQL_GETDIAG_ROW_COUNT,
|
PLPGSQL_GETDIAG_ROW_COUNT,
|
||||||
|
PLPGSQL_GETDIAG_ROUTINE_OID,
|
||||||
PLPGSQL_GETDIAG_CONTEXT,
|
PLPGSQL_GETDIAG_CONTEXT,
|
||||||
PLPGSQL_GETDIAG_ERROR_CONTEXT,
|
PLPGSQL_GETDIAG_ERROR_CONTEXT,
|
||||||
PLPGSQL_GETDIAG_ERROR_DETAIL,
|
PLPGSQL_GETDIAG_ERROR_DETAIL,
|
||||||
|
@ -5229,7 +5229,7 @@ NOTICE: outer_func() done
|
|||||||
20
|
20
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- repeated call should to work
|
-- repeated call should work
|
||||||
select outer_outer_func(20);
|
select outer_outer_func(20);
|
||||||
NOTICE: calling down into outer_func()
|
NOTICE: calling down into outer_func()
|
||||||
NOTICE: calling down into inner_func()
|
NOTICE: calling down into inner_func()
|
||||||
@ -5311,7 +5311,7 @@ NOTICE: outer_func() done
|
|||||||
20
|
20
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- repeated call should to work
|
-- repeated call should work
|
||||||
select outer_outer_func(20);
|
select outer_outer_func(20);
|
||||||
NOTICE: calling down into outer_func()
|
NOTICE: calling down into outer_func()
|
||||||
NOTICE: calling down into inner_func()
|
NOTICE: calling down into inner_func()
|
||||||
@ -5332,6 +5332,33 @@ NOTICE: outer_func() done
|
|||||||
drop function outer_outer_func(int);
|
drop function outer_outer_func(int);
|
||||||
drop function outer_func(int);
|
drop function outer_func(int);
|
||||||
drop function inner_func(int);
|
drop function inner_func(int);
|
||||||
|
-- Test pg_routine_oid
|
||||||
|
create function current_function(text)
|
||||||
|
returns regprocedure as $$
|
||||||
|
declare
|
||||||
|
fn_oid regprocedure;
|
||||||
|
begin
|
||||||
|
get diagnostics fn_oid = pg_routine_oid;
|
||||||
|
return fn_oid;
|
||||||
|
end;
|
||||||
|
$$ language plpgsql;
|
||||||
|
select current_function('foo');
|
||||||
|
current_function
|
||||||
|
------------------------
|
||||||
|
current_function(text)
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
drop function current_function(text);
|
||||||
|
-- shouldn't fail in DO, even though there's no useful data
|
||||||
|
do $$
|
||||||
|
declare
|
||||||
|
fn_oid oid;
|
||||||
|
begin
|
||||||
|
get diagnostics fn_oid = pg_routine_oid;
|
||||||
|
raise notice 'pg_routine_oid = %', fn_oid;
|
||||||
|
end;
|
||||||
|
$$;
|
||||||
|
NOTICE: pg_routine_oid = 0
|
||||||
--
|
--
|
||||||
-- Test ASSERT
|
-- Test ASSERT
|
||||||
--
|
--
|
||||||
|
@ -4206,7 +4206,7 @@ end;
|
|||||||
$$ language plpgsql;
|
$$ language plpgsql;
|
||||||
|
|
||||||
select outer_outer_func(10);
|
select outer_outer_func(10);
|
||||||
-- repeated call should to work
|
-- repeated call should work
|
||||||
select outer_outer_func(20);
|
select outer_outer_func(20);
|
||||||
|
|
||||||
drop function outer_outer_func(int);
|
drop function outer_outer_func(int);
|
||||||
@ -4261,13 +4261,38 @@ end;
|
|||||||
$$ language plpgsql;
|
$$ language plpgsql;
|
||||||
|
|
||||||
select outer_outer_func(10);
|
select outer_outer_func(10);
|
||||||
-- repeated call should to work
|
-- repeated call should work
|
||||||
select outer_outer_func(20);
|
select outer_outer_func(20);
|
||||||
|
|
||||||
drop function outer_outer_func(int);
|
drop function outer_outer_func(int);
|
||||||
drop function outer_func(int);
|
drop function outer_func(int);
|
||||||
drop function inner_func(int);
|
drop function inner_func(int);
|
||||||
|
|
||||||
|
-- Test pg_routine_oid
|
||||||
|
create function current_function(text)
|
||||||
|
returns regprocedure as $$
|
||||||
|
declare
|
||||||
|
fn_oid regprocedure;
|
||||||
|
begin
|
||||||
|
get diagnostics fn_oid = pg_routine_oid;
|
||||||
|
return fn_oid;
|
||||||
|
end;
|
||||||
|
$$ language plpgsql;
|
||||||
|
|
||||||
|
select current_function('foo');
|
||||||
|
|
||||||
|
drop function current_function(text);
|
||||||
|
|
||||||
|
-- shouldn't fail in DO, even though there's no useful data
|
||||||
|
do $$
|
||||||
|
declare
|
||||||
|
fn_oid oid;
|
||||||
|
begin
|
||||||
|
get diagnostics fn_oid = pg_routine_oid;
|
||||||
|
raise notice 'pg_routine_oid = %', fn_oid;
|
||||||
|
end;
|
||||||
|
$$;
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Test ASSERT
|
-- Test ASSERT
|
||||||
--
|
--
|
||||||
|
Reference in New Issue
Block a user