summaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
authorTom Lane2015-03-22 17:53:11 +0000
committerTom Lane2015-03-22 17:53:21 +0000
commitcb1ca4d800621dcae67ca6c799006de99fa4f0a5 (patch)
tree6f69242bd93e64f1529e846433c7d92dc1a2a59d /src/include
parent8ac356cde312693aa79f6b2fe7c46b8ed6108787 (diff)
Allow foreign tables to participate in inheritance.
Foreign tables can now be inheritance children, or parents. Much of the system was already ready for this, but we had to fix a few things of course, mostly in the area of planner and executor handling of row locks. As side effects of this, allow foreign tables to have NOT VALID CHECK constraints (and hence to accept ALTER ... VALIDATE CONSTRAINT), and to accept ALTER SET STORAGE and ALTER SET WITH/WITHOUT OIDS. Continuing to disallow these things would've required bizarre and inconsistent special cases in inheritance behavior. Since foreign tables don't enforce CHECK constraints anyway, a NOT VALID one is a complete no-op, but that doesn't mean we shouldn't allow it. And it's possible that some FDWs might have use for SET STORAGE or SET WITH OIDS, though doubtless they will be no-ops for most. An additional change in support of this is that when a ModifyTable node has multiple target tables, they will all now be explicitly identified in EXPLAIN output, for example: Update on pt1 (cost=0.00..321.05 rows=3541 width=46) Update on pt1 Foreign Update on ft1 Foreign Update on ft2 Update on child3 -> Seq Scan on pt1 (cost=0.00..0.00 rows=1 width=46) -> Foreign Scan on ft1 (cost=100.00..148.03 rows=1170 width=46) -> Foreign Scan on ft2 (cost=100.00..148.03 rows=1170 width=46) -> Seq Scan on child3 (cost=0.00..25.00 rows=1200 width=46) This was done mainly to provide an unambiguous place to attach "Remote SQL" fields, but it is useful for inherited updates even when no foreign tables are involved. Shigeru Hanada and Etsuro Fujita, reviewed by Ashutosh Bapat and Kyotaro Horiguchi, some additional hacking by me
Diffstat (limited to 'src/include')
-rw-r--r--src/include/nodes/execnodes.h11
-rw-r--r--src/include/optimizer/planner.h3
2 files changed, 10 insertions, 4 deletions
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index 59b17f3c993..ac75f86fef7 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -414,17 +414,20 @@ typedef struct EState
* ExecRowMark -
* runtime representation of FOR [KEY] UPDATE/SHARE clauses
*
- * When doing UPDATE, DELETE, or SELECT FOR [KEY] UPDATE/SHARE, we should have an
+ * When doing UPDATE, DELETE, or SELECT FOR [KEY] UPDATE/SHARE, we will have an
* ExecRowMark for each non-target relation in the query (except inheritance
- * parent RTEs, which can be ignored at runtime). See PlanRowMark for details
- * about most of the fields. In addition to fields directly derived from
- * PlanRowMark, we store curCtid, which is used by the WHERE CURRENT OF code.
+ * parent RTEs, which can be ignored at runtime). Virtual relations such as
+ * subqueries-in-FROM will have an ExecRowMark with relation == NULL. See
+ * PlanRowMark for details about most of the fields. In addition to fields
+ * directly derived from PlanRowMark, we store curCtid, which is used by the
+ * WHERE CURRENT OF code.
*
* EState->es_rowMarks is a list of these structs.
*/
typedef struct ExecRowMark
{
Relation relation; /* opened and suitably locked relation */
+ Oid relid; /* its OID (or InvalidOid, if subquery) */
Index rti; /* its range table index */
Index prti; /* parent range table index, if child */
Index rowmarkId; /* unique identifier for resjunk columns */
diff --git a/src/include/optimizer/planner.h b/src/include/optimizer/planner.h
index cd62aec08f1..b10a5040f5b 100644
--- a/src/include/optimizer/planner.h
+++ b/src/include/optimizer/planner.h
@@ -40,6 +40,9 @@ extern void add_tlist_costs_to_plan(PlannerInfo *root, Plan *plan,
extern bool is_dummy_plan(Plan *plan);
+extern RowMarkType select_rowmark_type(RangeTblEntry *rte,
+ LockClauseStrength strength);
+
extern Expr *expression_planner(Expr *expr);
extern Expr *preprocess_phv_expression(PlannerInfo *root, Expr *expr);