1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-17 06:41:09 +03:00

Fix transition tables for partition/inheritance.

We disallow row-level triggers with transition tables on child tables.
Transition tables for triggers on the parent table contain only those
columns present in the parent.  (We can't mix tuple formats in a
single transition table.)

Patch by Thomas Munro

Discussion: https://postgr.es/m/CA%2BTgmoZzTBBAsEUh4MazAN7ga%3D8SsMC-Knp-6cetts9yNZUCcg%40mail.gmail.com
This commit is contained in:
Andrew Gierth
2017-06-28 18:55:03 +01:00
parent 99255d73c0
commit 501ed02cf6
13 changed files with 1143 additions and 110 deletions

View File

@ -41,6 +41,39 @@ typedef struct TriggerData
Tuplestorestate *tg_newtable;
} TriggerData;
/*
* Meta-data to control the capture of old and new tuples into transition
* tables from child tables.
*/
typedef struct TransitionCaptureState
{
/*
* Is there at least one trigger specifying each transition relation on
* the relation explicitly named in the DML statement or COPY command?
*/
bool tcs_delete_old_table;
bool tcs_update_old_table;
bool tcs_update_new_table;
bool tcs_insert_new_table;
/*
* For UPDATE and DELETE, AfterTriggerSaveEvent may need to convert the
* new and old tuples from a child table's format to the format of the
* relation named in a query so that it is compatible with the transition
* tuplestores.
*/
TupleConversionMap *tcs_map;
/*
* For INSERT and COPY, it would be wasteful to convert tuples from child
* format to parent format after they have already been converted in the
* opposite direction during routing. In that case we bypass conversion
* and allow the inserting code (copy.c and nodeModifyTable.c) to provide
* the original tuple directly.
*/
HeapTuple tcs_original_insert_tuple;
} TransitionCaptureState;
/*
* TriggerEvent bit flags
*
@ -127,6 +160,9 @@ extern void RelationBuildTriggers(Relation relation);
extern TriggerDesc *CopyTriggerDesc(TriggerDesc *trigdesc);
extern const char *FindTriggerIncompatibleWithInheritance(TriggerDesc *trigdesc);
extern TransitionCaptureState *MakeTransitionCaptureState(TriggerDesc *trigdesc);
extern void FreeTriggerDesc(TriggerDesc *trigdesc);
extern void ExecBSInsertTriggers(EState *estate,
@ -139,7 +175,8 @@ extern TupleTableSlot *ExecBRInsertTriggers(EState *estate,
extern void ExecARInsertTriggers(EState *estate,
ResultRelInfo *relinfo,
HeapTuple trigtuple,
List *recheckIndexes);
List *recheckIndexes,
TransitionCaptureState *transition_capture);
extern TupleTableSlot *ExecIRInsertTriggers(EState *estate,
ResultRelInfo *relinfo,
TupleTableSlot *slot);
@ -155,7 +192,8 @@ extern bool ExecBRDeleteTriggers(EState *estate,
extern void ExecARDeleteTriggers(EState *estate,
ResultRelInfo *relinfo,
ItemPointer tupleid,
HeapTuple fdw_trigtuple);
HeapTuple fdw_trigtuple,
TransitionCaptureState *transition_capture);
extern bool ExecIRDeleteTriggers(EState *estate,
ResultRelInfo *relinfo,
HeapTuple trigtuple);
@ -174,7 +212,8 @@ extern void ExecARUpdateTriggers(EState *estate,
ItemPointer tupleid,
HeapTuple fdw_trigtuple,
HeapTuple newtuple,
List *recheckIndexes);
List *recheckIndexes,
TransitionCaptureState *transition_capture);
extern TupleTableSlot *ExecIRUpdateTriggers(EState *estate,
ResultRelInfo *relinfo,
HeapTuple trigtuple,