avoid_catalog_lookup.patch
application/octet-stream
Filename: avoid_catalog_lookup.patch
Type: application/octet-stream
Part: 0
Message:
Re: review: FDW API
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
| File | + | − |
|---|---|---|
| src/backend/foreign/foreign.c | 0 | 24 |
| src/backend/nodes/outfuncs.c | 1 | 0 |
| src/backend/optimizer/path/allpaths.c | 1 | 1 |
| src/backend/optimizer/util/plancat.c | 7 | 0 |
| src/backend/optimizer/util/relnode.c | 2 | 0 |
| src/include/foreign/foreign.h | 0 | 1 |
| src/include/nodes/relation.h | 1 | 0 |
diff --git a/src/backend/foreign/foreign.c b/src/backend/foreign/foreign.c
index 1fdd925..2e9f3f1 100644
--- a/src/backend/foreign/foreign.c
+++ b/src/backend/foreign/foreign.c
@@ -362,30 +362,6 @@ GetFdwRoutineByRelId(Oid relid)
/*
- * Determine the relation is a foreign table.
- */
-bool
-IsForeignTable(Oid relid)
-{
- HeapTuple tuple;
- Form_pg_class classForm;
- char relkind;
-
- tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
- if (!HeapTupleIsValid(tuple))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_TABLE),
- errmsg("relation with OID %u does not exist", relid)));
- classForm = (Form_pg_class) GETSTRUCT(tuple);
- relkind = classForm->relkind;
- ReleaseSysCache(tuple);
-
- return (relkind == RELKIND_FOREIGN_TABLE);
-}
-
-
-
-/*
* deflist_to_tuplestore - Helper function to convert DefElem list to
* tuplestore usable in SRF.
*/
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index 6fc6825..b8e4c1f 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -1676,6 +1676,7 @@ _outRelOptInfo(StringInfo str, RelOptInfo *node)
WRITE_NODE_FIELD(subplan);
WRITE_NODE_FIELD(subrtable);
WRITE_NODE_FIELD(subrowmark);
+ WRITE_BOOL_FIELD(is_foreign_table);
WRITE_NODE_FIELD(baserestrictinfo);
WRITE_NODE_FIELD(joininfo);
WRITE_BOOL_FIELD(has_eclass_joins);
diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c
index ae2e134..780e64c 100644
--- a/src/backend/optimizer/path/allpaths.c
+++ b/src/backend/optimizer/path/allpaths.c
@@ -256,7 +256,7 @@ set_plain_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
* least one dimension of cost or sortedness.
*/
- if (IsForeignTable(rte->relid))
+ if (rel->is_foreign_table)
{
/* only foreign scan path is applyable to foreign table */
add_path(rel, create_foreignscan_path(root, rel));
diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c
index 1d60af8..f86bc5f 100644
--- a/src/backend/optimizer/util/plancat.c
+++ b/src/backend/optimizer/util/plancat.c
@@ -339,6 +339,13 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
rel->indexlist = indexinfos;
+ /*
+ * We should remember whether the relation is a foreign table or not to
+ * avoid catalog lookup in the phase of path generation.
+ */
+ if (relation->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
+ rel->is_foreign_table = true;
+
heap_close(relation, NoLock);
/*
diff --git a/src/backend/optimizer/util/relnode.c b/src/backend/optimizer/util/relnode.c
index b7a5845..7c2a39d 100644
--- a/src/backend/optimizer/util/relnode.c
+++ b/src/backend/optimizer/util/relnode.c
@@ -85,6 +85,7 @@ build_simple_rel(PlannerInfo *root, int relid, RelOptKind reloptkind)
rel->subplan = NULL;
rel->subrtable = NIL;
rel->subrowmark = NIL;
+ rel->is_foreign_table = false;
rel->baserestrictinfo = NIL;
rel->baserestrictcost.startup = 0;
rel->baserestrictcost.per_tuple = 0;
@@ -339,6 +340,7 @@ build_join_rel(PlannerInfo *root,
joinrel->subplan = NULL;
joinrel->subrtable = NIL;
joinrel->subrowmark = NIL;
+ joinrel->is_foreign_table = false;
joinrel->baserestrictinfo = NIL;
joinrel->baserestrictcost.startup = 0;
joinrel->baserestrictcost.per_tuple = 0;
diff --git a/src/include/foreign/foreign.h b/src/include/foreign/foreign.h
index fe299b3..b0cb37c 100644
--- a/src/include/foreign/foreign.h
+++ b/src/include/foreign/foreign.h
@@ -79,6 +79,5 @@ extern Oid GetForeignDataWrapperOidByName(const char *name, bool missing_ok);
extern ForeignTable *GetForeignTable(Oid relid);
extern FdwRoutine *GetFdwRoutineByRelId(Oid relid);
extern FdwRoutine *GetFdwRoutine(Oid fdwhandler);
-extern bool IsForeignTable(Oid relid);
#endif /* FOREIGN_H */
diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h
index 133a2bd..5abbb07 100644
--- a/src/include/nodes/relation.h
+++ b/src/include/nodes/relation.h
@@ -395,6 +395,7 @@ typedef struct RelOptInfo
struct Plan *subplan; /* if subquery */
List *subrtable; /* if subquery */
List *subrowmark; /* if subquery */
+ bool is_foreign_table; /* T means relation is a foreign table */
/* used by various scans and joins: */
List *baserestrictinfo; /* RestrictInfo structures (if base