aboutsummaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
Diffstat (limited to 'src/include')
-rw-r--r--src/include/foreign/fdwapi.h69
-rw-r--r--src/include/nodes/execnodes.h7
-rw-r--r--src/include/nodes/plannodes.h38
-rw-r--r--src/include/optimizer/planmain.h3
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);