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