1 /*-------------------------------------------------------------------------
2  *
3  * postgres_fdw.h
4  *		  Foreign-data wrapper for remote PostgreSQL servers
5  *
6  * Portions Copyright (c) 2012-2020, PostgreSQL Global Development Group
7  *
8  * IDENTIFICATION
9  *		  contrib/postgres_fdw/postgres_fdw.h
10  *
11  *-------------------------------------------------------------------------
12  */
13 #ifndef POSTGRES_FDW_H
14 #define POSTGRES_FDW_H
15 
16 #include "foreign/foreign.h"
17 #include "lib/stringinfo.h"
18 #include "libpq-fe.h"
19 #include "nodes/pathnodes.h"
20 #include "utils/relcache.h"
21 
22 /*
23  * FDW-specific planner information kept in RelOptInfo.fdw_private for a
24  * postgres_fdw foreign table.  For a baserel, this struct is created by
25  * postgresGetForeignRelSize, although some fields are not filled till later.
26  * postgresGetForeignJoinPaths creates it for a joinrel, and
27  * postgresGetForeignUpperPaths creates it for an upperrel.
28  */
29 typedef struct PgFdwRelationInfo
30 {
31 	/*
32 	 * True means that the relation can be pushed down. Always true for simple
33 	 * foreign scan.
34 	 */
35 	bool		pushdown_safe;
36 
37 	/*
38 	 * Restriction clauses, divided into safe and unsafe to pushdown subsets.
39 	 * All entries in these lists should have RestrictInfo wrappers; that
40 	 * improves efficiency of selectivity and cost estimation.
41 	 */
42 	List	   *remote_conds;
43 	List	   *local_conds;
44 
45 	/* Actual remote restriction clauses for scan (sans RestrictInfos) */
46 	List	   *final_remote_exprs;
47 
48 	/* Bitmap of attr numbers we need to fetch from the remote server. */
49 	Bitmapset  *attrs_used;
50 
51 	/* True means that the query_pathkeys is safe to push down */
52 	bool		qp_is_pushdown_safe;
53 
54 	/* Cost and selectivity of local_conds. */
55 	QualCost	local_conds_cost;
56 	Selectivity local_conds_sel;
57 
58 	/* Selectivity of join conditions */
59 	Selectivity joinclause_sel;
60 
61 	/* Estimated size and cost for a scan, join, or grouping/aggregation. */
62 	double		rows;
63 	int			width;
64 	Cost		startup_cost;
65 	Cost		total_cost;
66 
67 	/*
68 	 * Estimated number of rows fetched from the foreign server, and costs
69 	 * excluding costs for transferring those rows from the foreign server.
70 	 * These are only used by estimate_path_cost_size().
71 	 */
72 	double		retrieved_rows;
73 	Cost		rel_startup_cost;
74 	Cost		rel_total_cost;
75 
76 	/* Options extracted from catalogs. */
77 	bool		use_remote_estimate;
78 	Cost		fdw_startup_cost;
79 	Cost		fdw_tuple_cost;
80 	List	   *shippable_extensions;	/* OIDs of whitelisted extensions */
81 
82 	/* Cached catalog information. */
83 	ForeignTable *table;
84 	ForeignServer *server;
85 	UserMapping *user;			/* only set in use_remote_estimate mode */
86 
87 	int			fetch_size;		/* fetch size for this remote table */
88 
89 	/*
90 	 * Name of the relation, for use while EXPLAINing ForeignScan.  It is used
91 	 * for join and upper relations but is set for all relations.  For a base
92 	 * relation, this is really just the RT index as a string; we convert that
93 	 * while producing EXPLAIN output.  For join and upper relations, the name
94 	 * indicates which base foreign tables are included and the join type or
95 	 * aggregation type used.
96 	 */
97 	char	   *relation_name;
98 
99 	/* Join information */
100 	RelOptInfo *outerrel;
101 	RelOptInfo *innerrel;
102 	JoinType	jointype;
103 	/* joinclauses contains only JOIN/ON conditions for an outer join */
104 	List	   *joinclauses;	/* List of RestrictInfo */
105 
106 	/* Upper relation information */
107 	UpperRelationKind stage;
108 
109 	/* Grouping information */
110 	List	   *grouped_tlist;
111 
112 	/* Subquery information */
113 	bool		make_outerrel_subquery; /* do we deparse outerrel as a
114 										 * subquery? */
115 	bool		make_innerrel_subquery; /* do we deparse innerrel as a
116 										 * subquery? */
117 	Relids		lower_subquery_rels;	/* all relids appearing in lower
118 										 * subqueries */
119 
120 	/*
121 	 * Index of the relation.  It is used to create an alias to a subquery
122 	 * representing the relation.
123 	 */
124 	int			relation_index;
125 } PgFdwRelationInfo;
126 
127 /* in postgres_fdw.c */
128 extern int	set_transmission_modes(void);
129 extern void reset_transmission_modes(int nestlevel);
130 
131 /* in connection.c */
132 extern PGconn *GetConnection(UserMapping *user, bool will_prep_stmt);
133 extern void ReleaseConnection(PGconn *conn);
134 extern unsigned int GetCursorNumber(PGconn *conn);
135 extern unsigned int GetPrepStmtNumber(PGconn *conn);
136 extern PGresult *pgfdw_get_result(PGconn *conn, const char *query);
137 extern PGresult *pgfdw_exec_query(PGconn *conn, const char *query);
138 extern void pgfdw_report_error(int elevel, PGresult *res, PGconn *conn,
139 							   bool clear, const char *sql);
140 
141 /* in option.c */
142 extern int	ExtractConnectionOptions(List *defelems,
143 									 const char **keywords,
144 									 const char **values);
145 extern List *ExtractExtensionList(const char *extensionsString,
146 								  bool warnOnMissing);
147 
148 /* in deparse.c */
149 extern void classifyConditions(PlannerInfo *root,
150 							   RelOptInfo *baserel,
151 							   List *input_conds,
152 							   List **remote_conds,
153 							   List **local_conds);
154 extern bool is_foreign_expr(PlannerInfo *root,
155 							RelOptInfo *baserel,
156 							Expr *expr);
157 extern bool is_foreign_param(PlannerInfo *root,
158 							 RelOptInfo *baserel,
159 							 Expr *expr);
160 extern void deparseInsertSql(StringInfo buf, RangeTblEntry *rte,
161 							 Index rtindex, Relation rel,
162 							 List *targetAttrs, bool doNothing,
163 							 List *withCheckOptionList, List *returningList,
164 							 List **retrieved_attrs);
165 extern void deparseUpdateSql(StringInfo buf, RangeTblEntry *rte,
166 							 Index rtindex, Relation rel,
167 							 List *targetAttrs,
168 							 List *withCheckOptionList, List *returningList,
169 							 List **retrieved_attrs);
170 extern void deparseDirectUpdateSql(StringInfo buf, PlannerInfo *root,
171 								   Index rtindex, Relation rel,
172 								   RelOptInfo *foreignrel,
173 								   List *targetlist,
174 								   List *targetAttrs,
175 								   List *remote_conds,
176 								   List **params_list,
177 								   List *returningList,
178 								   List **retrieved_attrs);
179 extern void deparseDeleteSql(StringInfo buf, RangeTblEntry *rte,
180 							 Index rtindex, Relation rel,
181 							 List *returningList,
182 							 List **retrieved_attrs);
183 extern void deparseDirectDeleteSql(StringInfo buf, PlannerInfo *root,
184 								   Index rtindex, Relation rel,
185 								   RelOptInfo *foreignrel,
186 								   List *remote_conds,
187 								   List **params_list,
188 								   List *returningList,
189 								   List **retrieved_attrs);
190 extern void deparseAnalyzeSizeSql(StringInfo buf, Relation rel);
191 extern void deparseAnalyzeSql(StringInfo buf, Relation rel,
192 							  List **retrieved_attrs);
193 extern void deparseStringLiteral(StringInfo buf, const char *val);
194 extern Expr *find_em_expr_for_rel(EquivalenceClass *ec, RelOptInfo *rel);
195 extern Expr *find_em_expr_for_input_target(PlannerInfo *root,
196 										   EquivalenceClass *ec,
197 										   PathTarget *target);
198 extern List *build_tlist_to_deparse(RelOptInfo *foreignrel);
199 extern void deparseSelectStmtForRel(StringInfo buf, PlannerInfo *root,
200 									RelOptInfo *foreignrel, List *tlist,
201 									List *remote_conds, List *pathkeys,
202 									bool has_final_sort, bool has_limit,
203 									bool is_subquery,
204 									List **retrieved_attrs, List **params_list);
205 extern const char *get_jointype_name(JoinType jointype);
206 
207 /* in shippable.c */
208 extern bool is_builtin(Oid objectId);
209 extern bool is_shippable(Oid objectId, Oid classId, PgFdwRelationInfo *fpinfo);
210 
211 #endif							/* POSTGRES_FDW_H */
212