mirror of
https://github.com/postgres/postgres.git
synced 2025-11-03 09:13:20 +03:00
Modified files for MERGE
This commit is contained in:
@@ -360,8 +360,17 @@ typedef struct JunkFilter
|
||||
AttrNumber *jf_cleanMap;
|
||||
TupleTableSlot *jf_resultSlot;
|
||||
AttrNumber jf_junkAttNo;
|
||||
AttrNumber jf_otherJunkAttNo;
|
||||
} JunkFilter;
|
||||
|
||||
typedef struct MergeState
|
||||
{
|
||||
/* List of MERGE MATCHED action states */
|
||||
List *matchedActionStates;
|
||||
/* List of MERGE NOT MATCHED action states */
|
||||
List *notMatchedActionStates;
|
||||
} MergeState;
|
||||
|
||||
/*
|
||||
* OnConflictSetState
|
||||
*
|
||||
@@ -452,8 +461,38 @@ typedef struct ResultRelInfo
|
||||
|
||||
/* relation descriptor for root partitioned table */
|
||||
Relation ri_PartitionRoot;
|
||||
|
||||
int ri_PartitionLeafIndex;
|
||||
/* for running MERGE on this result relation */
|
||||
MergeState *ri_mergeState;
|
||||
|
||||
/*
|
||||
* While executing MERGE, the target relation is processed twice; once
|
||||
* as a target relation and once to run a join between the target and the
|
||||
* source. We generate two different RTEs for these two purposes, one with
|
||||
* rte->inh set to false and other with rte->inh set to true.
|
||||
*
|
||||
* Since the plan re-evaluated by EvalPlanQual uses the join RTE, we must
|
||||
* install the updated tuple in the scan corresponding to that RTE. The
|
||||
* following member tracks the index of the second RTE for EvalPlanQual
|
||||
* purposes. ri_mergeTargetRTI is non-zero only when MERGE is in-progress.
|
||||
* We use ri_mergeTargetRTI to run EvalPlanQual for MERGE and
|
||||
* ri_RangeTableIndex elsewhere.
|
||||
*/
|
||||
Index ri_mergeTargetRTI;
|
||||
} ResultRelInfo;
|
||||
|
||||
/*
|
||||
* Get the Range table index for EvalPlanQual.
|
||||
*
|
||||
* We use the ri_mergeTargetRTI if set, otherwise use ri_RangeTableIndex.
|
||||
* ri_mergeTargetRTI should really be ever set iff we're running MERGE.
|
||||
*/
|
||||
#define GetEPQRangeTableIndex(r) \
|
||||
(((r)->ri_mergeTargetRTI > 0) \
|
||||
? (r)->ri_mergeTargetRTI \
|
||||
: (r)->ri_RangeTableIndex)
|
||||
|
||||
/* ----------------
|
||||
* EState information
|
||||
*
|
||||
@@ -966,6 +1005,11 @@ typedef struct PlanState
|
||||
if (((PlanState *)(node))->instrument) \
|
||||
((PlanState *)(node))->instrument->nfiltered2 += (delta); \
|
||||
} while(0)
|
||||
#define InstrCountFiltered3(node, delta) \
|
||||
do { \
|
||||
if (((PlanState *)(node))->instrument) \
|
||||
((PlanState *)(node))->instrument->nfiltered3 += (delta); \
|
||||
} while(0)
|
||||
|
||||
/*
|
||||
* EPQState is state for executing an EvalPlanQual recheck on a candidate
|
||||
@@ -1012,6 +1056,20 @@ typedef struct ProjectSetState
|
||||
MemoryContext argcontext; /* context for SRF arguments */
|
||||
} ProjectSetState;
|
||||
|
||||
/* ----------------
|
||||
* MergeActionState information
|
||||
* ----------------
|
||||
*/
|
||||
typedef struct MergeActionState
|
||||
{
|
||||
NodeTag type;
|
||||
bool matched; /* true=MATCHED, false=NOT MATCHED */
|
||||
ExprState *whenqual; /* WHEN AND conditions */
|
||||
CmdType commandType; /* INSERT/UPDATE/DELETE/DO NOTHING */
|
||||
ProjectionInfo *proj; /* tuple projection info */
|
||||
TupleDesc tupDesc; /* tuple descriptor for projection */
|
||||
} MergeActionState;
|
||||
|
||||
/* ----------------
|
||||
* ModifyTableState information
|
||||
* ----------------
|
||||
@@ -1019,7 +1077,7 @@ typedef struct ProjectSetState
|
||||
typedef struct ModifyTableState
|
||||
{
|
||||
PlanState ps; /* its first field is NodeTag */
|
||||
CmdType operation; /* INSERT, UPDATE, or DELETE */
|
||||
CmdType operation; /* INSERT, UPDATE, DELETE or MERGE */
|
||||
bool canSetTag; /* do we set the command tag/es_processed? */
|
||||
bool mt_done; /* are we done? */
|
||||
PlanState **mt_plans; /* subplans (one per target rel) */
|
||||
@@ -1035,6 +1093,8 @@ typedef struct ModifyTableState
|
||||
List *mt_excludedtlist; /* the excluded pseudo relation's tlist */
|
||||
TupleTableSlot *mt_conflproj; /* CONFLICT ... SET ... projection target */
|
||||
|
||||
TupleTableSlot *mt_mergeproj; /* MERGE action projection target */
|
||||
|
||||
/* Tuple-routing support info */
|
||||
struct PartitionTupleRouting *mt_partition_tuple_routing;
|
||||
|
||||
@@ -1046,6 +1106,9 @@ typedef struct ModifyTableState
|
||||
|
||||
/* Per plan map for tuple conversion from child to root */
|
||||
TupleConversionMap **mt_per_subplan_tupconv_maps;
|
||||
|
||||
/* Flags showing which subcommands are present INS/UPD/DEL/DO NOTHING */
|
||||
int mt_merge_subcommands;
|
||||
} ModifyTableState;
|
||||
|
||||
/* ----------------
|
||||
|
||||
@@ -97,6 +97,7 @@ typedef enum NodeTag
|
||||
T_PlanState,
|
||||
T_ResultState,
|
||||
T_ProjectSetState,
|
||||
T_MergeActionState,
|
||||
T_ModifyTableState,
|
||||
T_AppendState,
|
||||
T_MergeAppendState,
|
||||
@@ -308,6 +309,8 @@ typedef enum NodeTag
|
||||
T_InsertStmt,
|
||||
T_DeleteStmt,
|
||||
T_UpdateStmt,
|
||||
T_MergeStmt,
|
||||
T_MergeAction,
|
||||
T_SelectStmt,
|
||||
T_AlterTableStmt,
|
||||
T_AlterTableCmd,
|
||||
@@ -657,7 +660,8 @@ typedef enum CmdType
|
||||
CMD_SELECT, /* select stmt */
|
||||
CMD_UPDATE, /* update stmt */
|
||||
CMD_INSERT, /* insert stmt */
|
||||
CMD_DELETE,
|
||||
CMD_DELETE, /* delete stmt */
|
||||
CMD_MERGE, /* merge stmt */
|
||||
CMD_UTILITY, /* cmds like create, destroy, copy, vacuum,
|
||||
* etc. */
|
||||
CMD_NOTHING /* dummy command for instead nothing rules
|
||||
|
||||
@@ -38,7 +38,7 @@ typedef enum OverridingKind
|
||||
typedef enum QuerySource
|
||||
{
|
||||
QSRC_ORIGINAL, /* original parsetree (explicit query) */
|
||||
QSRC_PARSER, /* added by parse analysis (now unused) */
|
||||
QSRC_PARSER, /* added by parse analysis in MERGE */
|
||||
QSRC_INSTEAD_RULE, /* added by unconditional INSTEAD rule */
|
||||
QSRC_QUAL_INSTEAD_RULE, /* added by conditional INSTEAD rule */
|
||||
QSRC_NON_INSTEAD_RULE /* added by non-INSTEAD rule */
|
||||
@@ -107,7 +107,7 @@ typedef struct Query
|
||||
{
|
||||
NodeTag type;
|
||||
|
||||
CmdType commandType; /* select|insert|update|delete|utility */
|
||||
CmdType commandType; /* select|insert|update|delete|merge|utility */
|
||||
|
||||
QuerySource querySource; /* where did I come from? */
|
||||
|
||||
@@ -118,7 +118,7 @@ typedef struct Query
|
||||
Node *utilityStmt; /* non-null if commandType == CMD_UTILITY */
|
||||
|
||||
int resultRelation; /* rtable index of target relation for
|
||||
* INSERT/UPDATE/DELETE; 0 for SELECT */
|
||||
* INSERT/UPDATE/DELETE/MERGE; 0 for SELECT */
|
||||
|
||||
bool hasAggs; /* has aggregates in tlist or havingQual */
|
||||
bool hasWindowFuncs; /* has window functions in tlist */
|
||||
@@ -169,6 +169,9 @@ typedef struct Query
|
||||
List *withCheckOptions; /* a list of WithCheckOption's, which are
|
||||
* only added during rewrite and therefore
|
||||
* are not written out as part of Query. */
|
||||
int mergeTarget_relation;
|
||||
List *mergeSourceTargetList;
|
||||
List *mergeActionList; /* list of actions for MERGE (only) */
|
||||
|
||||
/*
|
||||
* The following two fields identify the portion of the source text string
|
||||
@@ -1128,7 +1131,9 @@ typedef enum WCOKind
|
||||
WCO_VIEW_CHECK, /* WCO on an auto-updatable view */
|
||||
WCO_RLS_INSERT_CHECK, /* RLS INSERT WITH CHECK policy */
|
||||
WCO_RLS_UPDATE_CHECK, /* RLS UPDATE WITH CHECK policy */
|
||||
WCO_RLS_CONFLICT_CHECK /* RLS ON CONFLICT DO UPDATE USING policy */
|
||||
WCO_RLS_CONFLICT_CHECK, /* RLS ON CONFLICT DO UPDATE USING policy */
|
||||
WCO_RLS_MERGE_UPDATE_CHECK, /* RLS MERGE UPDATE USING policy */
|
||||
WCO_RLS_MERGE_DELETE_CHECK /* RLS MERGE DELETE USING policy */
|
||||
} WCOKind;
|
||||
|
||||
typedef struct WithCheckOption
|
||||
@@ -1503,6 +1508,30 @@ typedef struct UpdateStmt
|
||||
WithClause *withClause; /* WITH clause */
|
||||
} UpdateStmt;
|
||||
|
||||
/* ----------------------
|
||||
* Merge Statement
|
||||
* ----------------------
|
||||
*/
|
||||
typedef struct MergeStmt
|
||||
{
|
||||
NodeTag type;
|
||||
RangeVar *relation; /* target relation to merge into */
|
||||
Node *source_relation; /* source relation */
|
||||
Node *join_condition; /* join condition between source and target */
|
||||
List *mergeActionList; /* list of MergeAction(s) */
|
||||
} MergeStmt;
|
||||
|
||||
typedef struct MergeAction
|
||||
{
|
||||
NodeTag type;
|
||||
bool matched; /* true=MATCHED, false=NOT MATCHED */
|
||||
Node *condition; /* WHEN AND conditions (raw parser) */
|
||||
Node *qual; /* transformed WHEN AND conditions */
|
||||
CmdType commandType; /* INSERT/UPDATE/DELETE/DO NOTHING */
|
||||
Node *stmt; /* T_UpdateStmt etc */
|
||||
List *targetList; /* the target list (of ResTarget) */
|
||||
} MergeAction;
|
||||
|
||||
/* ----------------------
|
||||
* Select Statement
|
||||
*
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "lib/stringinfo.h"
|
||||
#include "nodes/bitmapset.h"
|
||||
#include "nodes/lockoptions.h"
|
||||
#include "nodes/parsenodes.h"
|
||||
#include "nodes/primnodes.h"
|
||||
|
||||
|
||||
@@ -42,7 +43,7 @@ typedef struct PlannedStmt
|
||||
{
|
||||
NodeTag type;
|
||||
|
||||
CmdType commandType; /* select|insert|update|delete|utility */
|
||||
CmdType commandType; /* select|insert|update|delete|merge|utility */
|
||||
|
||||
uint64 queryId; /* query identifier (copied from Query) */
|
||||
|
||||
@@ -216,13 +217,14 @@ typedef struct ProjectSet
|
||||
typedef struct ModifyTable
|
||||
{
|
||||
Plan plan;
|
||||
CmdType operation; /* INSERT, UPDATE, or DELETE */
|
||||
CmdType operation; /* INSERT, UPDATE, DELETE or MERGE */
|
||||
bool canSetTag; /* do we set the command tag/es_processed? */
|
||||
Index nominalRelation; /* Parent RT index for use of EXPLAIN */
|
||||
/* RT indexes of non-leaf tables in a partition tree */
|
||||
List *partitioned_rels;
|
||||
bool partColsUpdated; /* some part key in hierarchy updated */
|
||||
List *resultRelations; /* integer list of RT indexes */
|
||||
Index mergeTargetRelation; /* RT index of the merge target */
|
||||
int resultRelIndex; /* index of first resultRel in plan's list */
|
||||
int rootResultRelIndex; /* index of the partitioned table root */
|
||||
List *plans; /* plan(s) producing source data */
|
||||
@@ -238,6 +240,8 @@ typedef struct ModifyTable
|
||||
Node *onConflictWhere; /* WHERE for ON CONFLICT UPDATE */
|
||||
Index exclRelRTI; /* RTI of the EXCLUDED pseudo relation */
|
||||
List *exclRelTlist; /* tlist of the EXCLUDED pseudo relation */
|
||||
List *mergeSourceTargetList;
|
||||
List *mergeActionList; /* actions for MERGE */
|
||||
} ModifyTable;
|
||||
|
||||
/* ----------------
|
||||
|
||||
@@ -1670,7 +1670,7 @@ typedef struct LockRowsPath
|
||||
} LockRowsPath;
|
||||
|
||||
/*
|
||||
* ModifyTablePath represents performing INSERT/UPDATE/DELETE modifications
|
||||
* ModifyTablePath represents performing INSERT/UPDATE/DELETE/MERGE
|
||||
*
|
||||
* We represent most things that will be in the ModifyTable plan node
|
||||
* literally, except we have child Path(s) not Plan(s). But analysis of the
|
||||
@@ -1679,13 +1679,14 @@ typedef struct LockRowsPath
|
||||
typedef struct ModifyTablePath
|
||||
{
|
||||
Path path;
|
||||
CmdType operation; /* INSERT, UPDATE, or DELETE */
|
||||
CmdType operation; /* INSERT, UPDATE, DELETE or MERGE */
|
||||
bool canSetTag; /* do we set the command tag/es_processed? */
|
||||
Index nominalRelation; /* Parent RT index for use of EXPLAIN */
|
||||
/* RT indexes of non-leaf tables in a partition tree */
|
||||
List *partitioned_rels;
|
||||
bool partColsUpdated; /* some part key in hierarchy updated */
|
||||
List *resultRelations; /* integer list of RT indexes */
|
||||
Index mergeTargetRelation;/* RT index of merge target relation */
|
||||
List *subpaths; /* Path(s) producing source data */
|
||||
List *subroots; /* per-target-table PlannerInfos */
|
||||
List *withCheckOptionLists; /* per-target-table WCO lists */
|
||||
@@ -1693,6 +1694,8 @@ typedef struct ModifyTablePath
|
||||
List *rowMarks; /* PlanRowMarks (non-locking only) */
|
||||
OnConflictExpr *onconflict; /* ON CONFLICT clause, or NULL */
|
||||
int epqParam; /* ID of Param for EvalPlanQual re-eval */
|
||||
List *mergeSourceTargetList;
|
||||
List *mergeActionList; /* actions for MERGE */
|
||||
} ModifyTablePath;
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user