Re: Determine the name of the calling function - Mailing list pgsql-novice

From Jack Kaufman
Subject Re: Determine the name of the calling function
Date
Msg-id CAM=VM80V2JaPoDpCGzedJ7=5AE4e-oaNeMQaP-sW8FT+5fGyNg@mail.gmail.com
Whole thread Raw
In response to Re: Determine the name of the calling function  (Tom Lane <tgl@sss.pgh.pa.us>)
List 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@sss.pgh.pa.us> wrote:
Jack Kaufman <jack.kaufman@sanmina.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.kaufman@sanmina.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.

pgsql-novice by date:

Previous
From: Keith Ouellette
Date:
Subject: WAL replication question
Next
From: "Kevin Grittner"
Date:
Subject: Re: WAL replication question