diff options
Diffstat (limited to 'src/include')
-rw-r--r-- | src/include/foreign/fdwapi.h | 69 | ||||
-rw-r--r-- | src/include/nodes/execnodes.h | 7 | ||||
-rw-r--r-- | src/include/nodes/plannodes.h | 38 | ||||
-rw-r--r-- | src/include/optimizer/planmain.h | 3 |
4 files changed, 97 insertions, 20 deletions
diff --git a/src/include/foreign/fdwapi.h b/src/include/foreign/fdwapi.h index 562d5412df7..485eee320f8 100644 --- a/src/include/foreign/fdwapi.h +++ b/src/include/foreign/fdwapi.h @@ -38,9 +38,6 @@ typedef ForeignScan *(*GetForeignPlan_function) (PlannerInfo *root, List *tlist, List *scan_clauses); -typedef void (*ExplainForeignScan_function) (ForeignScanState *node, - struct ExplainState *es); - typedef void (*BeginForeignScan_function) (ForeignScanState *node, int eflags); @@ -50,6 +47,48 @@ typedef void (*ReScanForeignScan_function) (ForeignScanState *node); typedef void (*EndForeignScan_function) (ForeignScanState *node); +typedef void (*AddForeignUpdateTargets_function) (Query *parsetree, + RangeTblEntry *target_rte, + Relation target_relation); + +typedef List *(*PlanForeignModify_function) (PlannerInfo *root, + ModifyTable *plan, + Index resultRelation, + int subplan_index); + +typedef void (*BeginForeignModify_function) (ModifyTableState *mtstate, + ResultRelInfo *rinfo, + List *fdw_private, + int subplan_index, + int eflags); + +typedef TupleTableSlot *(*ExecForeignInsert_function) (EState *estate, + ResultRelInfo *rinfo, + TupleTableSlot *slot, + TupleTableSlot *planSlot); + +typedef TupleTableSlot *(*ExecForeignUpdate_function) (EState *estate, + ResultRelInfo *rinfo, + TupleTableSlot *slot, + TupleTableSlot *planSlot); + +typedef TupleTableSlot *(*ExecForeignDelete_function) (EState *estate, + ResultRelInfo *rinfo, + TupleTableSlot *slot, + TupleTableSlot *planSlot); + +typedef void (*EndForeignModify_function) (EState *estate, + ResultRelInfo *rinfo); + +typedef void (*ExplainForeignScan_function) (ForeignScanState *node, + struct ExplainState *es); + +typedef void (*ExplainForeignModify_function) (ModifyTableState *mtstate, + ResultRelInfo *rinfo, + List *fdw_private, + int subplan_index, + struct ExplainState *es); + typedef int (*AcquireSampleRowsFunc) (Relation relation, int elevel, HeapTuple *rows, int targrows, double *totalrows, @@ -73,22 +112,34 @@ typedef struct FdwRoutine { NodeTag type; - /* - * These functions are required. - */ + /* Functions for scanning foreign tables */ GetForeignRelSize_function GetForeignRelSize; GetForeignPaths_function GetForeignPaths; GetForeignPlan_function GetForeignPlan; - ExplainForeignScan_function ExplainForeignScan; BeginForeignScan_function BeginForeignScan; IterateForeignScan_function IterateForeignScan; ReScanForeignScan_function ReScanForeignScan; EndForeignScan_function EndForeignScan; /* - * These functions are optional. Set the pointer to NULL for any that are - * not provided. + * Remaining functions are optional. Set the pointer to NULL for any that + * are not provided. */ + + /* Functions for updating foreign tables */ + AddForeignUpdateTargets_function AddForeignUpdateTargets; + PlanForeignModify_function PlanForeignModify; + BeginForeignModify_function BeginForeignModify; + ExecForeignInsert_function ExecForeignInsert; + ExecForeignUpdate_function ExecForeignUpdate; + ExecForeignDelete_function ExecForeignDelete; + EndForeignModify_function EndForeignModify; + + /* Support functions for EXPLAIN */ + ExplainForeignScan_function ExplainForeignScan; + ExplainForeignModify_function ExplainForeignModify; + + /* Support functions for ANALYZE */ AnalyzeForeignTable_function AnalyzeForeignTable; } FdwRoutine; diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h index 76e8cdb1ad8..4f77016652d 100644 --- a/src/include/nodes/execnodes.h +++ b/src/include/nodes/execnodes.h @@ -270,7 +270,8 @@ typedef struct ProjectionInfo * resultSlot: tuple slot used to hold cleaned tuple. * junkAttNo: not used by junkfilter code. Can be used by caller * to remember the attno of a specific junk attribute - * (execMain.c stores the "ctid" attno here). + * (nodeModifyTable.c keeps the "ctid" or "wholerow" + * attno here). * ---------------- */ typedef struct JunkFilter @@ -300,6 +301,8 @@ typedef struct JunkFilter * TrigFunctions cached lookup info for trigger functions * TrigWhenExprs array of trigger WHEN expr states * TrigInstrument optional runtime measurements for triggers + * FdwRoutine FDW callback functions, if foreign table + * FdwState available to save private state of FDW * ConstraintExprs array of constraint-checking expr states * junkFilter for removing junk attributes from tuples * projectReturning for computing a RETURNING list @@ -317,6 +320,8 @@ typedef struct ResultRelInfo FmgrInfo *ri_TrigFunctions; List **ri_TrigWhenExprs; Instrumentation *ri_TrigInstrument; + struct FdwRoutine *ri_FdwRoutine; + void *ri_FdwState; List **ri_ConstraintExprs; JunkFilter *ri_junkFilter; ProjectionInfo *ri_projectReturning; diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h index 0b8b1076bbf..841701ed98a 100644 --- a/src/include/nodes/plannodes.h +++ b/src/include/nodes/plannodes.h @@ -173,6 +173,7 @@ typedef struct ModifyTable int resultRelIndex; /* index of first resultRel in plan's list */ List *plans; /* plan(s) producing source data */ List *returningLists; /* per-target-table RETURNING tlists */ + List *fdwPrivLists; /* per-target-table FDW private data lists */ List *rowMarks; /* PlanRowMarks (non-locking only) */ int epqParam; /* ID of Param for EvalPlanQual re-eval */ } ModifyTable; @@ -752,13 +753,32 @@ typedef struct Limit * RowMarkType - * enums for types of row-marking operations * - * When doing UPDATE, DELETE, or SELECT FOR [KEY] UPDATE/SHARE, we have to uniquely + * The first four of these values represent different lock strengths that + * we can take on tuples according to SELECT FOR [KEY] UPDATE/SHARE requests. + * We only support these on regular tables. For foreign tables, any locking + * that might be done for these requests must happen during the initial row + * fetch; there is no mechanism for going back to lock a row later (and thus + * no need for EvalPlanQual machinery during updates of foreign tables). + * This means that the semantics will be a bit different than for a local + * table; in particular we are likely to lock more rows than would be locked + * locally, since remote rows will be locked even if they then fail + * locally-checked restriction or join quals. However, the alternative of + * doing a separate remote query to lock each selected row is extremely + * unappealing, so let's do it like this for now. + * + * When doing UPDATE, DELETE, or SELECT FOR UPDATE/SHARE, we have to uniquely * identify all the source rows, not only those from the target relations, so * that we can perform EvalPlanQual rechecking at need. For plain tables we - * can just fetch the TID, the same as for a target relation. Otherwise (for - * example for VALUES or FUNCTION scans) we have to copy the whole row value. - * The latter is pretty inefficient but fortunately the case is not - * performance-critical in practice. + * can just fetch the TID, much as for a target relation; this case is + * represented by ROW_MARK_REFERENCE. Otherwise (for example for VALUES or + * FUNCTION scans) we have to copy the whole row value. ROW_MARK_COPY is + * pretty inefficient, since most of the time we'll never need the data; but + * fortunately the case is not performance-critical in practice. Note that + * we use ROW_MARK_COPY for non-target foreign tables, even if the FDW has a + * concept of rowid and so could theoretically support some form of + * ROW_MARK_REFERENCE. Although copying the whole row value is inefficient, + * it's probably still faster than doing a second remote fetch, so it doesn't + * seem worth the extra complexity to permit ROW_MARK_REFERENCE. */ typedef enum RowMarkType { @@ -776,10 +796,10 @@ typedef enum RowMarkType * PlanRowMark - * plan-time representation of FOR [KEY] UPDATE/SHARE clauses * - * When doing UPDATE, DELETE, or SELECT FOR [KEY] UPDATE/SHARE, we create a separate + * When doing UPDATE, DELETE, or SELECT FOR UPDATE/SHARE, we create a separate * PlanRowMark node for each non-target relation in the query. Relations that - * are not specified as FOR [KEY] UPDATE/SHARE are marked ROW_MARK_REFERENCE (if - * real tables) or ROW_MARK_COPY (if not). + * are not specified as FOR UPDATE/SHARE are marked ROW_MARK_REFERENCE (if + * regular tables) or ROW_MARK_COPY (if not). * * Initially all PlanRowMarks have rti == prti and isParent == false. * When the planner discovers that a relation is the root of an inheritance @@ -791,7 +811,7 @@ typedef enum RowMarkType * * The planner also adds resjunk output columns to the plan that carry * information sufficient to identify the locked or fetched rows. For - * tables (markType != ROW_MARK_COPY), these columns are named + * regular tables (markType != ROW_MARK_COPY), these columns are named * tableoid%u OID of table * ctid%u TID of row * The tableoid column is only present for an inheritance hierarchy. diff --git a/src/include/optimizer/planmain.h b/src/include/optimizer/planmain.h index 2f9fcd575a6..16d685846e8 100644 --- a/src/include/optimizer/planmain.h +++ b/src/include/optimizer/planmain.h @@ -79,7 +79,8 @@ extern SetOp *make_setop(SetOpCmd cmd, SetOpStrategy strategy, Plan *lefttree, long numGroups, double outputRows); extern Result *make_result(PlannerInfo *root, List *tlist, Node *resconstantqual, Plan *subplan); -extern ModifyTable *make_modifytable(CmdType operation, bool canSetTag, +extern ModifyTable *make_modifytable(PlannerInfo *root, + CmdType operation, bool canSetTag, List *resultRelations, List *subplans, List *returningLists, List *rowMarks, int epqParam); extern bool is_projection_capable_plan(Plan *plan); |