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