_PG_init首先使用DefineCustomTypeVariable定義GUC變量,以pgaudit.log為例,auditLog是pgaudit.c中定義的char *指針變量,check_pgaudit_log和assign_pgaudit_log是pgaudit.c中定義的函數。
/* Define GUC variables and install hooks upon module load. */
void _PG_init(void) {
...
/* Define pgaudit.log */
DefineCustomStringVariable(
"pgaudit.log",
"Specifies which classes of statements will be logged by session audit "
"logging. Multiple classes can be provided using a comma-separated "
"list and classes can be subtracted by prefacing the class with a "
"- sign.",
NULL,
&auditLog,
"none",
PGC_SUSET,
GUC_LIST_INPUT | GUC_NOT_IN_SAMPLE,
check_pgaudit_log,
assign_pgaudit_log,
NULL);
....
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI0gTMx81dsQWZ4lmZf1GLlpXazVmcvwFciV2dsQXYtJ3bm9CX9s2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xCMy81dvRWYoNHLwEzX5xCMx8FesU2cfdGLwMzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5SO5YzNyUzYkNTZ2EWO0YGZyYzXwUTN1kDM2IzLcdDMyIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjLyM3Lc9CX6MHc0RHaiojIsJye.png)
将我們定義的鈎子加入PG的鈎子鍊。如下圖就是pgaudit.c中定義的臨時鈎子指針變量,用于儲存PG已經引入的鈎子變量,然後将我們定義的鈎子挂在标準的鈎子上,也就是我們熟悉的單連結清單頭插法。
/* Install our hook functions after saving the existing pointers to preserve the chains. */
next_ExecutorStart_hook = ExecutorStart_hook;
ExecutorStart_hook = pgaudit_ExecutorStart_hook;
next_ExecutorCheckPerms_hook = ExecutorCheckPerms_hook;
ExecutorCheckPerms_hook = pgaudit_ExecutorCheckPerms_hook;
next_ProcessUtility_hook = ProcessUtility_hook;
ProcessUtility_hook = pgaudit_ProcessUtility_hook;
next_object_access_hook = object_access_hook;
object_access_hook = pgaudit_object_access_hook;
/* The following hook functions are required to get rows */
next_ExecutorRun_hook = ExecutorRun_hook;
ExecutorRun_hook = pgaudit_ExecutorRun_hook;
next_ExecutorEnd_hook = ExecutorEnd_hook;
ExecutorEnd_hook = pgaudit_ExecutorEnd_hook;
以pgaudit_ExecutorStart_hook為例,先執行pgaudit_ExecutorStart_hook鈎子函數,最後判斷後續有沒有鈎子需要繼續執行,沒有就執行執行PG标準應該執行的函數。