Re: Determine the name of the calling function

From: Jack Kaufman <jack(dot)kaufman(at)sanmina(dot)com>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: pgsql-novice(at)postgresql(dot)org
Subject: Re: Determine the name of the calling function
Date: 2013-01-21 19:43:04
Message-ID: CAM=VM80V2JaPoDpCGzedJ7=5AE4e-oaNeMQaP-sW8FT+5fGyNg@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-novice

Tom, thank you again for your help in solving the "calling function"
problem that I posted last week. I now have a solution I think our shop
can live with, that is, if a better one is not found. The simplest way to
explain the actual solution is to just post the code, which I have done
below. Thank you, again. Jack

- - - - - - - - - - - - -
--drop function test_get_function_name_top ();
create or replace function test_get_function_name_top () returns text AS $$
begin
return test_get_function_name ();
end;
$$ language plpgsql;

--drop function test_get_function_name ();
create or replace function test_get_function_name ()
returns text as $$
declare
function_name text;
begin
-- do some stuff
-- now need name of calling function (

/* begin - call function name function */
declare
temp_var integer;
exception_context text;
begin
temp_var := 1/0;
exception
when division_by_zero then
get stacked diagnostics exception_context = PG_EXCEPTION_CONTEXT;
function_name := get_function_name (exception_context);
end;
/* end - call function name function */

-- use function name
-- do more stuff

return function_name;

end;
$$ language plpgsql;

--drop function get_function_name (exception_context text);
create or replace function get_function_name (exception_context text)
returns text as $$
declare
function_name_loc integer;
begin
function_name_loc = strpos(exception_context, 'PL/pgSQL function') + 18;
exception_context = substr(exception_context, function_name_loc);
function_name_loc = strpos(exception_context, 'PL/pgSQL function') + 18;

if function_name_loc = 18 then
return 'unknown';
end if;

exception_context = substr(exception_context, function_name_loc);
return substr(exception_context, 1, strpos(exception_context, '(') - 1);

/* Use the "get_function_name" function to determine the name of the
calling function.

To return the name of the calling function, place the following block of
code in the main
function, such that it will be executed before the name of calling
function is required:

declare
temp_var integer;
exception_context text;
begin
temp_var := 1/0;
exception
when division_by_zero then
get stacked diagnostics exception_context = PG_EXCEPTION_CONTEXT;
function_name := get_function_name (function_level,
exception_context);
end;

Also, define the variable "function_name" as "text" in the main
function's "declare" section.
Note that the function "get_function_name" must be executed within the
exception block.

Following the execution of the exception block, the variable
"function_name" will contain
the name of the calling function. If the main function was not called by
another function,
then the variable "function_name" will contain the value "unknown".
*/

end;
$$ language plpgsql;

select * from test_get_function_name_top ();

On Fri, Jan 18, 2013 at 5:38 PM, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> wrote:

> Jack Kaufman <jack(dot)kaufman(at)sanmina(dot)com> writes:
> > The output from PG_EXCEPTION_CONTEXT looks parseable, with line 1
> > containing the current function, and line 2, the calling function. The
> > lines are variable length but the LF or CR should be identifiable. Add
> in
> > the fact of the variable number of lines you got from
> > PG_EXCEPTION_CONTEXT--where line 1 become 2, and line 2 becomes 3--and
> the
> > project is a pain but doable.
>
> Cool. FYI, I intend to see about fixing the bug --- IMO there should
> not be a dependency on the number of executions here, and probably the
> form with the extra context line is preferable.
>
> Another thing that you should be aware of before plunging into this is
> that GET STACKED DIAGNOSTICS is new as of 9.2; if you're hoping that
> this code might be back-portable onto older PG versions, you'd better
> not depend on it.
>
> regards, tom lane
>

--
Jack Kaufman
MDS Application Devl (US)
Sanmina-SCI Corporation - Owego site
Email: jack(dot)kaufman(at)sanmina(dot)com
Skype: jack_kaufman_sanm
607-723-0507

CONFIDENTIALITY
This e-mail message and any attachments thereto, is intended only for use by the addressee(s) named herein and may contain legally privileged and/or confidential information. If you are not the intended recipient of this e-mail message, you are hereby notified that any dissemination, distribution or copying of this e-mail message, and any attachments thereto, is strictly prohibited. If you have received this e-mail message in error, please immediately notify the sender and permanently delete the original and any copies of this email and any prints thereof.
ABSENT AN EXPRESS STATEMENT TO THE CONTRARY HEREINABOVE, THIS E-MAIL IS NOT INTENDED AS A SUBSTITUTE FOR A WRITING. Notwithstanding the Uniform Electronic Transactions Act or the applicability of any other law of similar substance and effect, absent an express statement to the contrary hereinabove, this e-mail message its contents, and any attachments hereto are not intended to represent an offer or acceptance to enter into a contract and are not otherwise intended to bind the sender, Sanmina Corporation (or any of its subsidiaries), or any other person or entity.

In response to

Browse pgsql-novice by date

  From Date Subject
Next Message Kevin Grittner 2013-01-21 21:07:54 Re: WAL replication question
Previous Message Keith Ouellette 2013-01-21 13:54:45 WAL replication question