-
Notifications
You must be signed in to change notification settings - Fork 881
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Split DDL processing into start and end hooks
The ProcessUtility hook doesn't give any information on applied DDL commands, which makes it hard to implement DDL processing that requires the result of a DDL command on a hypertable (for instance, adding a constraint or index without an explicit name). This change splits the DDL processing over start and end hooks, handling DDL commands before and after regular PostgreSQL processing, respectively. The start DDL hook is still based on the ProcessUtility hook, while the end DDL hook is based on an event trigger that allows getting information on the created/dropped/altered objects.
- Loading branch information
Showing
10 changed files
with
430 additions
and
167 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
#include <postgres.h> | ||
#include <commands/event_trigger.h> | ||
#include <executor/executor.h> | ||
#include <access/htup_details.h> | ||
|
||
#include "event_trigger.h" | ||
|
||
/* Function manager info for the event "pg_event_trigger_ddl_commands", which is | ||
* used to retrieve information on executed DDL commands in an event | ||
* trigger. The function manager info is initialized on extension load. */ | ||
static FmgrInfo ddl_commands_fmgrinfo; | ||
|
||
/* | ||
* Get a list of executed DDL commands in an event trigger. | ||
* | ||
* This function calls the function pg_event_trigger_ddl_commands(), which is | ||
* part of the event trigger API, and retrieves the DDL commands executed in | ||
* relation to the event trigger. It is only valid to call this function from | ||
* within an event trigger. | ||
*/ | ||
List * | ||
event_trigger_ddl_commands(void) | ||
{ | ||
ReturnSetInfo rsinfo; | ||
FunctionCallInfoData fcinfo; | ||
TupleTableSlot *slot; | ||
EState *estate = CreateExecutorState(); | ||
List *objects = NIL; | ||
|
||
InitFunctionCallInfoData(fcinfo, &ddl_commands_fmgrinfo, 1, InvalidOid, NULL, NULL); | ||
MemSet(&rsinfo, 0, sizeof(rsinfo)); | ||
rsinfo.type = T_ReturnSetInfo; | ||
rsinfo.allowedModes = SFRM_Materialize; | ||
rsinfo.econtext = CreateExprContext(estate); | ||
fcinfo.resultinfo = (fmNodePtr) &rsinfo; | ||
|
||
FunctionCallInvoke(&fcinfo); | ||
|
||
slot = MakeSingleTupleTableSlot(rsinfo.setDesc); | ||
|
||
while (tuplestore_gettupleslot(rsinfo.setResult, true, false, slot)) | ||
{ | ||
HeapTuple tuple = ExecFetchSlotTuple(slot); | ||
CollectedCommand *cmd; | ||
Datum values[rsinfo.setDesc->natts]; | ||
bool nulls[rsinfo.setDesc->natts]; | ||
|
||
heap_deform_tuple(tuple, rsinfo.setDesc, values, nulls); | ||
|
||
if (rsinfo.setDesc->natts > 8 && !nulls[8]) | ||
{ | ||
cmd = (CollectedCommand *) DatumGetPointer(values[8]); | ||
objects = lappend(objects, cmd); | ||
} | ||
} | ||
|
||
FreeExprContext(rsinfo.econtext, false); | ||
FreeExecutorState(estate); | ||
ExecDropSingleTupleTableSlot(slot); | ||
|
||
return objects; | ||
} | ||
|
||
void | ||
_event_trigger_init(void) | ||
{ | ||
fmgr_info(fmgr_internal_function("pg_event_trigger_ddl_commands"), | ||
&ddl_commands_fmgrinfo); | ||
} | ||
|
||
void | ||
_event_trigger_fini(void) | ||
{ | ||
/* Nothing to do */ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#ifndef TIMESCALEDB_EVENT_TRIGGER_H | ||
#define TIMESCALEDB_EVENT_TRIGGER_H | ||
|
||
#include <postgres.h> | ||
#include <nodes/pg_list.h> | ||
|
||
extern List *event_trigger_ddl_commands(void); | ||
extern void _event_trigger_init(void); | ||
extern void _event_trigger_fini(void); | ||
|
||
#endif /* TIMESCALEDB_EVENT_TRIGGER_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.