Difference between revisions of "Todo:HooksAndTracePoints"

From PostgreSQL wiki
Jump to: navigation, search
(Created page with "# TODO: Hooks, callbacks and trace points This TODO/wishlist sub-section is intended for all users and developers to edit to add their own thoughts on desired extension point...")
 
Line 1: Line 1:
# TODO: Hooks, callbacks and trace points
+
= TODO: Hooks, callbacks and trace points =
  
 
This TODO/wishlist sub-section is intended for all users and developers to edit to add their own thoughts on desired extension points within the core PostgreSQL codebase.
 
This TODO/wishlist sub-section is intended for all users and developers to edit to add their own thoughts on desired extension points within the core PostgreSQL codebase.
  
 +
== Definitions with existing examples ===
  
# Definitions
+
=== Hook ===
 
 
## Hook
 
  
 
A "hook" is a global variable of pointer-to-function type. PostgreSQL calls the hook function *instead of* a standard postgres function if the variable is set at the relevant point in execution of some core routine. The hook variable is usually set by extension code to run new code before and/or after existing core code, usually from `shared_preload_libraries` or `session_preload_libraries`.
 
A "hook" is a global variable of pointer-to-function type. PostgreSQL calls the hook function *instead of* a standard postgres function if the variable is set at the relevant point in execution of some core routine. The hook variable is usually set by extension code to run new code before and/or after existing core code, usually from `shared_preload_libraries` or `session_preload_libraries`.
Line 16: Line 15:
 
An example is the `ProcessUtility_hook` which is used to intercept and wrap, or entirely suppress, utility commands. A utility command is any "non plannable" SQL command, anything other than `SELECT`/`INSERT`/`UPDATE`/`DELETE`. An real example can be found in `contrib/pg_stat_statements/pg_stat_statements.c`, but a trivial demo is:
 
An example is the `ProcessUtility_hook` which is used to intercept and wrap, or entirely suppress, utility commands. A utility command is any "non plannable" SQL command, anything other than `SELECT`/`INSERT`/`UPDATE`/`DELETE`. An real example can be found in `contrib/pg_stat_statements/pg_stat_statements.c`, but a trivial demo is:
  
```
+
<div class="toccolours mw-collapsible" style="width:100%; overflow:auto;">
 +
<br/>
 +
<syntaxhighlight lang="C" line='line'>
 +
 
 
static ProcessUtility_hook_type next_ProcessUtility_hook;
 
static ProcessUtility_hook_type next_ProcessUtility_hook;
  
Line 52: Line 54:
 
   ProcessUtility_hook = demo_ProcessUtility_hook;
 
   ProcessUtility_hook = demo_ProcessUtility_hook;
 
}
 
}
 
+
</syntaxhighlight>
```
+
</div>

Revision as of 03:36, 6 August 2019

TODO: Hooks, callbacks and trace points

This TODO/wishlist sub-section is intended for all users and developers to edit to add their own thoughts on desired extension points within the core PostgreSQL codebase.

Definitions with existing examples =

Hook

A "hook" is a global variable of pointer-to-function type. PostgreSQL calls the hook function *instead of* a standard postgres function if the variable is set at the relevant point in execution of some core routine. The hook variable is usually set by extension code to run new code before and/or after existing core code, usually from `shared_preload_libraries` or `session_preload_libraries`.

If the hook variable was already set when an extension loads the extension must remember the previous hook value and call it; otherwise it generally calls the original core PostgreSQL routine.

See separate article on entry points for extending PostgreSQL for list of existing hooks.

An example is the `ProcessUtility_hook` which is used to intercept and wrap, or entirely suppress, utility commands. A utility command is any "non plannable" SQL command, anything other than `SELECT`/`INSERT`/`UPDATE`/`DELETE`. An real example can be found in `contrib/pg_stat_statements/pg_stat_statements.c`, but a trivial demo is:


 1 static ProcessUtility_hook_type next_ProcessUtility_hook;
 2 
 3 static void
 4 demo_ProcessUtility_hook(PlannedStmt *pstmt,
 5                                           const char *queryString, ProcessUtilityContext context,
 6                                           ParamListInfo params,
 7                                           QueryEnvironment *queryEnv,
 8                                           DestReceiver *dest, char *completionTag)
 9 {
10   /* Do something silly to show how the hook can work */
11   if (IsA(parsetree, TransactionStmt))
12   {
13     TransactionStmt *stmt = (TransactionStatement)parsetree;
14     if (stmt->kind == TRANS_STMT_PREPARE && !is_superuser())
15         ereport(ERROR,
16                 (errmsg("MyDemoExtension prohibits non-superusers from using PREPARE TRANSACTION")));
17   }
18 
19   /* Call next hook if registered, or original postgres stmt */
20   if (next_ProcessUtility_hook)
21     next_ProcessUtility_hook(pstmt, queryString, context, params, queryEnv, dest, completionTag);
22   else
23     standard_ProcessUtility_hook(pstmt, queryString, context, params, queryEnv, dest, completionTag);
24 
25   if (completionTag)
26     ereport(LOG,
27             (errmsg("MyDemoExtension allowed utility statement %s to run", completionTag)));
28 }
29 
30 void
31 _PG_init(void)
32 {
33   next_ProcessUtility_hook = ProcessUtility_hook;
34   ProcessUtility_hook = demo_ProcessUtility_hook;
35 }