| /*------------------------------------------------------------------------- |
| * |
| * postgres_fdw.h |
| * Foreign-data wrapper for remote PostgreSQL servers |
| * |
| * Portions Copyright (c) 2012-2023, PostgreSQL Global Development Group |
| * |
| * IDENTIFICATION |
| * contrib/postgres_fdw/postgres_fdw.h |
| * |
| *------------------------------------------------------------------------- |
| */ |
| #ifndef POSTGRES_FDW_H |
| #define POSTGRES_FDW_H |
| |
| #include "foreign/foreign.h" |
| #include "lib/stringinfo.h" |
| #include "nodes/execnodes.h" |
| #include "nodes/pathnodes.h" |
| #include "utils/relcache.h" |
| |
| /* GPDB_13_MERGE_FIXME: Do we still needs this patch? */ |
| /* postgres_fdw is compiled as a backend, it needs the server's |
| * header files such as executor/tuptable.h. It also needs libpq |
| * to connect to a remote postgres database, so it's statically |
| * linked to libpq.a which is compiled as a frontend using |
| * -DFRONTEND. |
| * |
| * But the struct PQconninfoOption's length is different between |
| * backend and frontend, there is no "connofs" field in frontend. |
| * When postgres_fdw calls the function "PQconndefaults" implemented |
| * in libpq.a and uses the returned PQconninfoOption variable, it crashs, |
| * because the PQconninfoOption variable returned by libpq.a doesn't contain |
| * the "connofs" value, but the postgres_fdw thinks it has, so it crashes. |
| * |
| * We define FRONTEND here to include frontend libpq header files. |
| */ |
| #ifdef LIBPQ_FE_H |
| #error "postgres_fdw.h" must be included before "libpq-fe.h" |
| #endif /* LIBPQ_FE_H */ |
| |
| #ifndef FRONTEND |
| #define FRONTEND |
| #include "libpq-fe.h" |
| #undef FRONTEND |
| #else |
| #include "libpq-fe.h" |
| #endif /* FRONTEND */ |
| |
| /* |
| * FDW-specific planner information kept in RelOptInfo.fdw_private for a |
| * postgres_fdw foreign table. For a baserel, this struct is created by |
| * postgresGetForeignRelSize, although some fields are not filled till later. |
| * postgresGetForeignJoinPaths creates it for a joinrel, and |
| * postgresGetForeignUpperPaths creates it for an upperrel. |
| */ |
| typedef struct PgFdwRelationInfo |
| { |
| /* |
| * True means that the relation can be pushed down. Always true for simple |
| * foreign scan. |
| */ |
| bool pushdown_safe; |
| |
| /* |
| * Restriction clauses, divided into safe and unsafe to pushdown subsets. |
| * All entries in these lists should have RestrictInfo wrappers; that |
| * improves efficiency of selectivity and cost estimation. |
| */ |
| List *remote_conds; |
| List *local_conds; |
| |
| /* Actual remote restriction clauses for scan (sans RestrictInfos) */ |
| List *final_remote_exprs; |
| |
| /* Bitmap of attr numbers we need to fetch from the remote server. */ |
| Bitmapset *attrs_used; |
| |
| /* True means that the query_pathkeys is safe to push down */ |
| bool qp_is_pushdown_safe; |
| |
| /* Cost and selectivity of local_conds. */ |
| QualCost local_conds_cost; |
| Selectivity local_conds_sel; |
| |
| /* Selectivity of join conditions */ |
| Selectivity joinclause_sel; |
| |
| /* Estimated size and cost for a scan, join, or grouping/aggregation. */ |
| double rows; |
| int width; |
| Cost startup_cost; |
| Cost total_cost; |
| |
| /* |
| * Estimated number of rows fetched from the foreign server, and costs |
| * excluding costs for transferring those rows from the foreign server. |
| * These are only used by estimate_path_cost_size(). |
| */ |
| double retrieved_rows; |
| Cost rel_startup_cost; |
| Cost rel_total_cost; |
| |
| /* Options extracted from catalogs. */ |
| bool use_remote_estimate; |
| Cost fdw_startup_cost; |
| Cost fdw_tuple_cost; |
| List *shippable_extensions; /* OIDs of shippable extensions */ |
| bool async_capable; |
| |
| /* Cached catalog information. */ |
| ForeignTable *table; |
| ForeignServer *server; |
| UserMapping *user; /* only set in use_remote_estimate mode */ |
| |
| int fetch_size; /* fetch size for this remote table */ |
| |
| /* |
| * Name of the relation, for use while EXPLAINing ForeignScan. It is used |
| * for join and upper relations but is set for all relations. For a base |
| * relation, this is really just the RT index as a string; we convert that |
| * while producing EXPLAIN output. For join and upper relations, the name |
| * indicates which base foreign tables are included and the join type or |
| * aggregation type used. |
| */ |
| char *relation_name; |
| |
| /* Join information */ |
| RelOptInfo *outerrel; |
| RelOptInfo *innerrel; |
| JoinType jointype; |
| /* joinclauses contains only JOIN/ON conditions for an outer join */ |
| List *joinclauses; /* List of RestrictInfo */ |
| |
| /* Upper relation information */ |
| UpperRelationKind stage; |
| |
| /* Grouping information */ |
| List *grouped_tlist; |
| |
| /* Subquery information */ |
| bool make_outerrel_subquery; /* do we deparse outerrel as a |
| * subquery? */ |
| bool make_innerrel_subquery; /* do we deparse innerrel as a |
| * subquery? */ |
| Relids lower_subquery_rels; /* all relids appearing in lower |
| * subqueries */ |
| |
| /* |
| * Index of the relation. It is used to create an alias to a subquery |
| * representing the relation. |
| */ |
| int relation_index; |
| } PgFdwRelationInfo; |
| |
| /* |
| * Extra control information relating to a connection. |
| */ |
| typedef struct PgFdwConnState |
| { |
| AsyncRequest *pendingAreq; /* pending async request */ |
| } PgFdwConnState; |
| |
| /* |
| * Method used by ANALYZE to sample remote rows. |
| */ |
| typedef enum PgFdwSamplingMethod |
| { |
| ANALYZE_SAMPLE_OFF, /* no remote sampling */ |
| ANALYZE_SAMPLE_AUTO, /* choose by server version */ |
| ANALYZE_SAMPLE_RANDOM, /* remote random() */ |
| ANALYZE_SAMPLE_SYSTEM, /* TABLESAMPLE system */ |
| ANALYZE_SAMPLE_BERNOULLI /* TABLESAMPLE bernoulli */ |
| } PgFdwSamplingMethod; |
| |
| /* in postgres_fdw.c */ |
| extern int set_transmission_modes(void); |
| extern void reset_transmission_modes(int nestlevel); |
| extern void process_pending_request(AsyncRequest *areq); |
| |
| /* in connection.c */ |
| extern PGconn *GetConnection(UserMapping *user, bool will_prep_stmt, |
| PgFdwConnState **state); |
| extern void ReleaseConnection(PGconn *conn); |
| extern unsigned int GetCursorNumber(PGconn *conn); |
| extern unsigned int GetPrepStmtNumber(PGconn *conn); |
| extern void do_sql_command(PGconn *conn, const char *sql); |
| extern PGresult *pgfdw_get_result(PGconn *conn, const char *query); |
| extern PGresult *pgfdw_exec_query(PGconn *conn, const char *query, |
| PgFdwConnState *state); |
| extern void pgfdw_report_error(int elevel, PGresult *res, PGconn *conn, |
| bool clear, const char *sql); |
| |
| /* in option.c */ |
| extern int ExtractConnectionOptions(List *defelems, |
| const char **keywords, |
| const char **values); |
| extern List *ExtractExtensionList(const char *extensionsString, |
| bool warnOnMissing); |
| extern char *process_pgfdw_appname(const char *appname); |
| extern char *pgfdw_application_name; |
| |
| /* in deparse.c */ |
| extern void classifyConditions(PlannerInfo *root, |
| RelOptInfo *baserel, |
| List *input_conds, |
| List **remote_conds, |
| List **local_conds); |
| extern bool is_foreign_expr(PlannerInfo *root, |
| RelOptInfo *baserel, |
| Expr *expr); |
| extern bool is_foreign_param(PlannerInfo *root, |
| RelOptInfo *baserel, |
| Expr *expr); |
| extern bool is_foreign_pathkey(PlannerInfo *root, |
| RelOptInfo *baserel, |
| PathKey *pathkey); |
| extern void deparseInsertSql(StringInfo buf, RangeTblEntry *rte, |
| Index rtindex, Relation rel, |
| List *targetAttrs, bool doNothing, |
| List *withCheckOptionList, List *returningList, |
| List **retrieved_attrs, int *values_end_len); |
| extern void rebuildInsertSql(StringInfo buf, Relation rel, |
| char *orig_query, List *target_attrs, |
| int values_end_len, int num_params, |
| int num_rows); |
| extern void deparseUpdateSql(StringInfo buf, RangeTblEntry *rte, |
| Index rtindex, Relation rel, |
| List *targetAttrs, |
| List *withCheckOptionList, List *returningList, |
| List **retrieved_attrs); |
| extern void deparseDirectUpdateSql(StringInfo buf, PlannerInfo *root, |
| Index rtindex, Relation rel, |
| RelOptInfo *foreignrel, |
| List *targetlist, |
| List *targetAttrs, |
| List *remote_conds, |
| List **params_list, |
| List *returningList, |
| List **retrieved_attrs); |
| extern void deparseDeleteSql(StringInfo buf, RangeTblEntry *rte, |
| Index rtindex, Relation rel, |
| List *returningList, |
| List **retrieved_attrs); |
| extern void deparseDirectDeleteSql(StringInfo buf, PlannerInfo *root, |
| Index rtindex, Relation rel, |
| RelOptInfo *foreignrel, |
| List *remote_conds, |
| List **params_list, |
| List *returningList, |
| List **retrieved_attrs); |
| extern void deparseAnalyzeSizeSql(StringInfo buf, Relation rel); |
| extern void deparseAnalyzeInfoSql(StringInfo buf, Relation rel); |
| extern void deparseAnalyzeSql(StringInfo buf, Relation rel, |
| PgFdwSamplingMethod sample_method, |
| double sample_frac, |
| List **retrieved_attrs); |
| extern void deparseTruncateSql(StringInfo buf, |
| List *rels, |
| DropBehavior behavior, |
| bool restart_seqs); |
| extern void deparseStringLiteral(StringInfo buf, const char *val); |
| extern EquivalenceMember *find_em_for_rel(PlannerInfo *root, |
| EquivalenceClass *ec, |
| RelOptInfo *rel); |
| extern EquivalenceMember *find_em_for_rel_target(PlannerInfo *root, |
| EquivalenceClass *ec, |
| RelOptInfo *rel); |
| extern List *build_tlist_to_deparse(RelOptInfo *foreignrel); |
| extern void deparseSelectStmtForRel(StringInfo buf, PlannerInfo *root, |
| RelOptInfo *rel, List *tlist, |
| List *remote_conds, List *pathkeys, |
| bool has_final_sort, bool has_limit, |
| bool is_subquery, |
| List **retrieved_attrs, List **params_list); |
| extern const char *get_jointype_name(JoinType jointype); |
| |
| /* in shippable.c */ |
| extern bool is_builtin(Oid objectId); |
| extern bool is_shippable(Oid objectId, Oid classId, PgFdwRelationInfo *fpinfo); |
| |
| #endif /* POSTGRES_FDW_H */ |