Обсуждение: help with fmgr

Поиск
Список
Период
Сортировка

help with fmgr

От
Luca Ferrari
Дата:
Hi all,
I'm trying to understand how fmgr works, and I've written a very
simple module that checks if functions f_test, f_test2 (defined by
myself in SQL) or hashtext (internal) needs fmgr, and in the case
print out a message when the fmgr is invoked.
I've two main doubts:
- is fmgr working for non PL functions? Because I cannot see messages
starting when an internal function is invoked;
- how can I lookup a function so that I can test for the needing of
fmgr based on function prototype (name and args) instead of the rough
Oid hard coded?

Here's the code:

#include "postgres.h"
#include "miscadmin.h"
#include "fmgr.h"

#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif

void _PG_init(void);
void _PG_fini(void);

static fmgr_hook_type       original_fmgr_hook       = NULL;
static needs_fmgr_hook_type original_needs_fmgr_hook = NULL;


static void catch_fmgr (FmgrHookEventType event,
                                         FmgrInfo *flinfo, Datum *arg)
{
  elog( INFO, "Check for function invocation OID = %d @ event = %d",
flinfo->fn_oid, event );


  if ( original_fmgr_hook && original_fmgr_hook != fmgr_hook )
    original_fmgr_hook( event, flinfo, arg );

}

static bool
needs_fmgr_hook_catch( Oid functionOid )
{
  elog( INFO, "needs_fmgr_hook_catch %d", functionOid );
  return functionOid == 132532 || functionOid == 132533 || functionOid
== 400; // 400 = hashtext
}



void _PG_init(void)
{
  original_fmgr_hook       = fmgr_hook;
  original_needs_fmgr_hook = needs_fmgr_hook;
  fmgr_hook                = catch_fmgr;
  needs_fmgr_hook          = needs_fmgr_hook_catch;
}


void _PG_fini(void)
{
  fmgr_hook       = original_fmgr_hook;
  needs_fmgr_hook = original_needs_fmgr_hook;
}


and this is the result:


testdb=> select f_test();
INFO:  needs_fmgr_hook_catch 132532
INFO:  needs_fmgr_hook_catch 132532
INFO:  Check for function invocation OID = 132532 @ event = 0
INFO:  Check for function invocation OID = 132532 @ event = 1
 f_test
--------
 hello
(1 row)

testdb=> select hashtext( 'foo' );
  hashtext
------------
 1955559433
(1 row)


Thanks,
Luca



Re: help with fmgr

От
Tom Lane
Дата:
Luca Ferrari <fluca1978@gmail.com> writes:
> I've two main doubts:
> - is fmgr working for non PL functions? Because I cannot see messages
> starting when an internal function is invoked;

Built-in functions do not support fmgr_hook; see the order of tests
in fmgr_info_cxt_security().  I'd be loath to change that, for both
performance and risk-of-circularity reasons.

Note that built-in is not the same as internal --- you could potentially
make a new internal-language pg_proc entry pointing at some existing
built-in function, and then calls using that could get hooked.

            regards, tom lane