PostgreSQL Source Code  git master
postgres_fdw.h File Reference
#include "foreign/foreign.h"
#include "lib/stringinfo.h"
#include "libpq-fe.h"
#include "nodes/execnodes.h"
#include "nodes/pathnodes.h"
#include "utils/relcache.h"
Include dependency graph for postgres_fdw.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  PgFdwRelationInfo
 
struct  PgFdwConnState
 

Typedefs

typedef struct PgFdwRelationInfo PgFdwRelationInfo
 
typedef struct PgFdwConnState PgFdwConnState
 
typedef enum PgFdwSamplingMethod PgFdwSamplingMethod
 

Enumerations

enum  PgFdwSamplingMethod {
  ANALYZE_SAMPLE_OFF , ANALYZE_SAMPLE_AUTO , ANALYZE_SAMPLE_RANDOM , ANALYZE_SAMPLE_SYSTEM ,
  ANALYZE_SAMPLE_BERNOULLI
}
 

Functions

int set_transmission_modes (void)
 
void reset_transmission_modes (int nestlevel)
 
void process_pending_request (AsyncRequest *areq)
 
PGconnGetConnection (UserMapping *user, bool will_prep_stmt, PgFdwConnState **state)
 
void ReleaseConnection (PGconn *conn)
 
unsigned int GetCursorNumber (PGconn *conn)
 
unsigned int GetPrepStmtNumber (PGconn *conn)
 
void do_sql_command (PGconn *conn, const char *sql)
 
PGresultpgfdw_get_result (PGconn *conn)
 
PGresultpgfdw_exec_query (PGconn *conn, const char *query, PgFdwConnState *state)
 
void pgfdw_report_error (int elevel, PGresult *res, PGconn *conn, bool clear, const char *sql)
 
int ExtractConnectionOptions (List *defelems, const char **keywords, const char **values)
 
ListExtractExtensionList (const char *extensionsString, bool warnOnMissing)
 
char * process_pgfdw_appname (const char *appname)
 
void classifyConditions (PlannerInfo *root, RelOptInfo *baserel, List *input_conds, List **remote_conds, List **local_conds)
 
bool is_foreign_expr (PlannerInfo *root, RelOptInfo *baserel, Expr *expr)
 
bool is_foreign_param (PlannerInfo *root, RelOptInfo *baserel, Expr *expr)
 
bool is_foreign_pathkey (PlannerInfo *root, RelOptInfo *baserel, PathKey *pathkey)
 
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)
 
void rebuildInsertSql (StringInfo buf, Relation rel, char *orig_query, List *target_attrs, int values_end_len, int num_params, int num_rows)
 
void deparseUpdateSql (StringInfo buf, RangeTblEntry *rte, Index rtindex, Relation rel, List *targetAttrs, List *withCheckOptionList, List *returningList, List **retrieved_attrs)
 
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)
 
void deparseDeleteSql (StringInfo buf, RangeTblEntry *rte, Index rtindex, Relation rel, List *returningList, List **retrieved_attrs)
 
void deparseDirectDeleteSql (StringInfo buf, PlannerInfo *root, Index rtindex, Relation rel, RelOptInfo *foreignrel, List *remote_conds, List **params_list, List *returningList, List **retrieved_attrs)
 
void deparseAnalyzeSizeSql (StringInfo buf, Relation rel)
 
void deparseAnalyzeInfoSql (StringInfo buf, Relation rel)
 
void deparseAnalyzeSql (StringInfo buf, Relation rel, PgFdwSamplingMethod sample_method, double sample_frac, List **retrieved_attrs)
 
void deparseTruncateSql (StringInfo buf, List *rels, DropBehavior behavior, bool restart_seqs)
 
void deparseStringLiteral (StringInfo buf, const char *val)
 
EquivalenceMemberfind_em_for_rel (PlannerInfo *root, EquivalenceClass *ec, RelOptInfo *rel)
 
EquivalenceMemberfind_em_for_rel_target (PlannerInfo *root, EquivalenceClass *ec, RelOptInfo *rel)
 
Listbuild_tlist_to_deparse (RelOptInfo *foreignrel)
 
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)
 
const char * get_jointype_name (JoinType jointype)
 
bool is_builtin (Oid objectId)
 
bool is_shippable (Oid objectId, Oid classId, PgFdwRelationInfo *fpinfo)
 

Variables

char * pgfdw_application_name
 

Typedef Documentation

◆ PgFdwConnState

◆ PgFdwRelationInfo

◆ PgFdwSamplingMethod

Enumeration Type Documentation

◆ PgFdwSamplingMethod

Enumerator
ANALYZE_SAMPLE_OFF 
ANALYZE_SAMPLE_AUTO 
ANALYZE_SAMPLE_RANDOM 
ANALYZE_SAMPLE_SYSTEM 
ANALYZE_SAMPLE_BERNOULLI 

Definition at line 144 of file postgres_fdw.h.

145 {
146  ANALYZE_SAMPLE_OFF, /* no remote sampling */
147  ANALYZE_SAMPLE_AUTO, /* choose by server version */
148  ANALYZE_SAMPLE_RANDOM, /* remote random() */
149  ANALYZE_SAMPLE_SYSTEM, /* TABLESAMPLE system */
150  ANALYZE_SAMPLE_BERNOULLI, /* TABLESAMPLE bernoulli */
PgFdwSamplingMethod
Definition: postgres_fdw.h:145
@ ANALYZE_SAMPLE_AUTO
Definition: postgres_fdw.h:147
@ ANALYZE_SAMPLE_OFF
Definition: postgres_fdw.h:146
@ ANALYZE_SAMPLE_BERNOULLI
Definition: postgres_fdw.h:150
@ ANALYZE_SAMPLE_SYSTEM
Definition: postgres_fdw.h:149
@ ANALYZE_SAMPLE_RANDOM
Definition: postgres_fdw.h:148

Function Documentation

◆ build_tlist_to_deparse()

List* build_tlist_to_deparse ( RelOptInfo foreignrel)

Definition at line 1176 of file deparse.c.

1177 {
1178  List *tlist = NIL;
1179  PgFdwRelationInfo *fpinfo = (PgFdwRelationInfo *) foreignrel->fdw_private;
1180  ListCell *lc;
1181 
1182  /*
1183  * For an upper relation, we have already built the target list while
1184  * checking shippability, so just return that.
1185  */
1186  if (IS_UPPER_REL(foreignrel))
1187  return fpinfo->grouped_tlist;
1188 
1189  /*
1190  * We require columns specified in foreignrel->reltarget->exprs and those
1191  * required for evaluating the local conditions.
1192  */
1193  tlist = add_to_flat_tlist(tlist,
1194  pull_var_clause((Node *) foreignrel->reltarget->exprs,
1196  foreach(lc, fpinfo->local_conds)
1197  {
1198  RestrictInfo *rinfo = lfirst_node(RestrictInfo, lc);
1199 
1200  tlist = add_to_flat_tlist(tlist,
1201  pull_var_clause((Node *) rinfo->clause,
1203  }
1204 
1205  return tlist;
1206 }
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:77
#define PVC_RECURSE_PLACEHOLDERS
Definition: optimizer.h:191
#define IS_UPPER_REL(rel)
Definition: pathnodes.h:839
#define lfirst_node(type, lc)
Definition: pg_list.h:176
#define NIL
Definition: pg_list.h:68
Definition: pg_list.h:54
Definition: nodes.h:129
List * exprs
Definition: pathnodes.h:1522
struct PathTarget * reltarget
Definition: pathnodes.h:883
Expr * clause
Definition: pathnodes.h:2552
List * add_to_flat_tlist(List *tlist, List *exprs)
Definition: tlist.c:132
List * pull_var_clause(Node *node, int flags)
Definition: var.c:607

References add_to_flat_tlist(), RestrictInfo::clause, PathTarget::exprs, PgFdwRelationInfo::grouped_tlist, if(), IS_UPPER_REL, lfirst_node, PgFdwRelationInfo::local_conds, NIL, pull_var_clause(), PVC_RECURSE_PLACEHOLDERS, and RelOptInfo::reltarget.

Referenced by estimate_path_cost_size(), and postgresGetForeignPlan().

◆ classifyConditions()

void classifyConditions ( PlannerInfo root,
RelOptInfo baserel,
List input_conds,
List **  remote_conds,
List **  local_conds 
)

Definition at line 218 of file deparse.c.

223 {
224  ListCell *lc;
225 
226  *remote_conds = NIL;
227  *local_conds = NIL;
228 
229  foreach(lc, input_conds)
230  {
232 
233  if (is_foreign_expr(root, baserel, ri->clause))
234  *remote_conds = lappend(*remote_conds, ri);
235  else
236  *local_conds = lappend(*local_conds, ri);
237  }
238 }
bool is_foreign_expr(PlannerInfo *root, RelOptInfo *baserel, Expr *expr)
Definition: deparse.c:244
List * lappend(List *list, void *datum)
Definition: list.c:339
tree ctl root
Definition: radixtree.h:1880

References RestrictInfo::clause, is_foreign_expr(), lappend(), lfirst_node, NIL, and root.

Referenced by estimate_path_cost_size(), and postgresGetForeignRelSize().

◆ deparseAnalyzeInfoSql()

void deparseAnalyzeInfoSql ( StringInfo  buf,
Relation  rel 
)

Definition at line 2521 of file deparse.c.

2522 {
2524 
2525  /* We'll need the remote relation name as a literal. */
2527  deparseRelation(&relname, rel);
2528 
2529  appendStringInfoString(buf, "SELECT reltuples, relkind FROM pg_catalog.pg_class WHERE oid = ");
2531  appendStringInfoString(buf, "::pg_catalog.regclass");
2532 }
void deparseStringLiteral(StringInfo buf, const char *val)
Definition: deparse.c:2849
static void deparseRelation(StringInfo buf, Relation rel)
Definition: deparse.c:2809
NameData relname
Definition: pg_class.h:38
static char * buf
Definition: pg_test_fsync.c:73
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:182
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
char data[NAMEDATALEN]
Definition: c.h:742

References appendStringInfoString(), buf, nameData::data, deparseRelation(), deparseStringLiteral(), initStringInfo(), and relname.

Referenced by postgresGetAnalyzeInfoForForeignTable().

◆ deparseAnalyzeSizeSql()

void deparseAnalyzeSizeSql ( StringInfo  buf,
Relation  rel 
)

Definition at line 2499 of file deparse.c.

2500 {
2502 
2503  /* We'll need the remote relation name as a literal. */
2505  deparseRelation(&relname, rel);
2506 
2507  appendStringInfoString(buf, "SELECT pg_catalog.pg_relation_size(");
2509  appendStringInfo(buf, "::pg_catalog.regclass) / %d", BLCKSZ);
2510 }
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:97

References appendStringInfo(), appendStringInfoString(), buf, nameData::data, deparseRelation(), deparseStringLiteral(), initStringInfo(), and relname.

Referenced by postgresAnalyzeForeignTable().

◆ deparseAnalyzeSql()

void deparseAnalyzeSql ( StringInfo  buf,
Relation  rel,
PgFdwSamplingMethod  sample_method,
double  sample_frac,
List **  retrieved_attrs 
)

Definition at line 2561 of file deparse.c.

2564 {
2565  Oid relid = RelationGetRelid(rel);
2566  TupleDesc tupdesc = RelationGetDescr(rel);
2567  int i;
2568  char *colname;
2569  List *options;
2570  ListCell *lc;
2571  bool first = true;
2572 
2573  *retrieved_attrs = NIL;
2574 
2575  appendStringInfoString(buf, "SELECT ");
2576  for (i = 0; i < tupdesc->natts; i++)
2577  {
2578  /* Ignore dropped columns. */
2579  if (TupleDescAttr(tupdesc, i)->attisdropped)
2580  continue;
2581 
2582  if (!first)
2583  appendStringInfoString(buf, ", ");
2584  first = false;
2585 
2586  /* Use attribute name or column_name option. */
2587  colname = NameStr(TupleDescAttr(tupdesc, i)->attname);
2588  options = GetForeignColumnOptions(relid, i + 1);
2589 
2590  foreach(lc, options)
2591  {
2592  DefElem *def = (DefElem *) lfirst(lc);
2593 
2594  if (strcmp(def->defname, "column_name") == 0)
2595  {
2596  colname = defGetString(def);
2597  break;
2598  }
2599  }
2600 
2602 
2603  *retrieved_attrs = lappend_int(*retrieved_attrs, i + 1);
2604  }
2605 
2606  /* Don't generate bad syntax for zero-column relation. */
2607  if (first)
2608  appendStringInfoString(buf, "NULL");
2609 
2610  /*
2611  * Construct FROM clause, and perhaps WHERE clause too, depending on the
2612  * selected sampling method.
2613  */
2614  appendStringInfoString(buf, " FROM ");
2615  deparseRelation(buf, rel);
2616 
2617  switch (sample_method)
2618  {
2619  case ANALYZE_SAMPLE_OFF:
2620  /* nothing to do here */
2621  break;
2622 
2623  case ANALYZE_SAMPLE_RANDOM:
2624  appendStringInfo(buf, " WHERE pg_catalog.random() < %f", sample_frac);
2625  break;
2626 
2627  case ANALYZE_SAMPLE_SYSTEM:
2628  appendStringInfo(buf, " TABLESAMPLE SYSTEM(%f)", (100.0 * sample_frac));
2629  break;
2630 
2632  appendStringInfo(buf, " TABLESAMPLE BERNOULLI(%f)", (100.0 * sample_frac));
2633  break;
2634 
2635  case ANALYZE_SAMPLE_AUTO:
2636  /* should have been resolved into actual method */
2637  elog(ERROR, "unexpected sampling method");
2638  break;
2639  }
2640 }
#define NameStr(name)
Definition: c.h:746
char * defGetString(DefElem *def)
Definition: define.c:48
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:224
List * GetForeignColumnOptions(Oid relid, AttrNumber attnum)
Definition: foreign.c:291
int i
Definition: isn.c:73
List * lappend_int(List *list, int datum)
Definition: list.c:357
NameData attname
Definition: pg_attribute.h:41
#define lfirst(lc)
Definition: pg_list.h:172
static char ** options
unsigned int Oid
Definition: postgres_ext.h:31
#define RelationGetRelid(relation)
Definition: rel.h:505
#define RelationGetDescr(relation)
Definition: rel.h:531
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:12623
char * defname
Definition: parsenodes.h:815
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92

References ANALYZE_SAMPLE_AUTO, ANALYZE_SAMPLE_BERNOULLI, ANALYZE_SAMPLE_OFF, ANALYZE_SAMPLE_RANDOM, ANALYZE_SAMPLE_SYSTEM, appendStringInfo(), appendStringInfoString(), attname, buf, defGetString(), DefElem::defname, deparseRelation(), elog, ERROR, GetForeignColumnOptions(), i, lappend_int(), lfirst, NameStr, TupleDescData::natts, NIL, options, quote_identifier(), RelationGetDescr, RelationGetRelid, and TupleDescAttr.

Referenced by postgresAcquireSampleRowsFunc().

◆ deparseDeleteSql()

void deparseDeleteSql ( StringInfo  buf,
RangeTblEntry rte,
Index  rtindex,
Relation  rel,
List returningList,
List **  retrieved_attrs 
)

Definition at line 2362 of file deparse.c.

2366 {
2367  appendStringInfoString(buf, "DELETE FROM ");
2368  deparseRelation(buf, rel);
2369  appendStringInfoString(buf, " WHERE ctid = $1");
2370 
2371  deparseReturningList(buf, rte, rtindex, rel,
2372  rel->trigdesc && rel->trigdesc->trig_delete_after_row,
2373  NIL, returningList, retrieved_attrs);
2374 }
static void deparseReturningList(StringInfo buf, RangeTblEntry *rte, Index rtindex, Relation rel, bool trig_after_row, List *withCheckOptionList, List *returningList, List **retrieved_attrs)
Definition: deparse.c:2442
TriggerDesc * trigdesc
Definition: rel.h:117
bool trig_delete_after_row
Definition: reltrigger.h:67

References appendStringInfoString(), buf, deparseRelation(), deparseReturningList(), NIL, TriggerDesc::trig_delete_after_row, and RelationData::trigdesc.

Referenced by postgresPlanForeignModify().

◆ deparseDirectDeleteSql()

void deparseDirectDeleteSql ( StringInfo  buf,
PlannerInfo root,
Index  rtindex,
Relation  rel,
RelOptInfo foreignrel,
List remote_conds,
List **  params_list,
List returningList,
List **  retrieved_attrs 
)

Definition at line 2391 of file deparse.c.

2398 {
2400  List *additional_conds = NIL;
2401 
2402  /* Set up context struct for recursion */
2403  context.root = root;
2404  context.foreignrel = foreignrel;
2405  context.scanrel = foreignrel;
2406  context.buf = buf;
2407  context.params_list = params_list;
2408 
2409  appendStringInfoString(buf, "DELETE FROM ");
2410  deparseRelation(buf, rel);
2411  if (foreignrel->reloptkind == RELOPT_JOINREL)
2412  appendStringInfo(buf, " %s%d", REL_ALIAS_PREFIX, rtindex);
2413 
2414  if (foreignrel->reloptkind == RELOPT_JOINREL)
2415  {
2416  List *ignore_conds = NIL;
2417 
2418  appendStringInfoString(buf, " USING ");
2419  deparseFromExprForRel(buf, root, foreignrel, true, rtindex,
2420  &ignore_conds, &additional_conds, params_list);
2421  remote_conds = list_concat(remote_conds, ignore_conds);
2422  }
2423 
2424  appendWhereClause(remote_conds, additional_conds, &context);
2425 
2426  if (additional_conds != NIL)
2427  list_free_deep(additional_conds);
2428 
2429  if (foreignrel->reloptkind == RELOPT_JOINREL)
2430  deparseExplicitTargetList(returningList, true, retrieved_attrs,
2431  &context);
2432  else
2434  rtindex, rel, false,
2435  NIL, returningList, retrieved_attrs);
2436 }
#define REL_ALIAS_PREFIX
Definition: deparse.c:110
static void deparseExplicitTargetList(List *tlist, bool is_returning, List **retrieved_attrs, deparse_expr_cxt *context)
Definition: deparse.c:1681
static void deparseFromExprForRel(StringInfo buf, PlannerInfo *root, RelOptInfo *foreignrel, bool use_alias, Index ignore_rel, List **ignore_conds, List **additional_conds, List **params_list)
Definition: deparse.c:1761
static void appendWhereClause(List *exprs, List *additional_conds, deparse_expr_cxt *context)
Definition: deparse.c:1608
List * list_concat(List *list1, const List *list2)
Definition: list.c:561
void list_free_deep(List *list)
Definition: list.c:1560
#define planner_rt_fetch(rti, root)
Definition: pathnodes.h:560
@ RELOPT_JOINREL
Definition: pathnodes.h:818
tree context
Definition: radixtree.h:1829
RelOptKind reloptkind
Definition: pathnodes.h:855

References appendStringInfo(), appendStringInfoString(), appendWhereClause(), buf, context, deparseExplicitTargetList(), deparseFromExprForRel(), deparseRelation(), deparseReturningList(), list_concat(), list_free_deep(), NIL, planner_rt_fetch, REL_ALIAS_PREFIX, RELOPT_JOINREL, RelOptInfo::reloptkind, and root.

Referenced by postgresPlanDirectModify().

◆ deparseDirectUpdateSql()

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 
)

Definition at line 2276 of file deparse.c.

2285 {
2287  int nestlevel;
2288  bool first;
2289  RangeTblEntry *rte = planner_rt_fetch(rtindex, root);
2290  ListCell *lc,
2291  *lc2;
2292  List *additional_conds = NIL;
2293 
2294  /* Set up context struct for recursion */
2295  context.root = root;
2296  context.foreignrel = foreignrel;
2297  context.scanrel = foreignrel;
2298  context.buf = buf;
2299  context.params_list = params_list;
2300 
2301  appendStringInfoString(buf, "UPDATE ");
2302  deparseRelation(buf, rel);
2303  if (foreignrel->reloptkind == RELOPT_JOINREL)
2304  appendStringInfo(buf, " %s%d", REL_ALIAS_PREFIX, rtindex);
2305  appendStringInfoString(buf, " SET ");
2306 
2307  /* Make sure any constants in the exprs are printed portably */
2308  nestlevel = set_transmission_modes();
2309 
2310  first = true;
2311  forboth(lc, targetlist, lc2, targetAttrs)
2312  {
2313  TargetEntry *tle = lfirst_node(TargetEntry, lc);
2314  int attnum = lfirst_int(lc2);
2315 
2316  /* update's new-value expressions shouldn't be resjunk */
2317  Assert(!tle->resjunk);
2318 
2319  if (!first)
2320  appendStringInfoString(buf, ", ");
2321  first = false;
2322 
2323  deparseColumnRef(buf, rtindex, attnum, rte, false);
2324  appendStringInfoString(buf, " = ");
2325  deparseExpr((Expr *) tle->expr, &context);
2326  }
2327 
2328  reset_transmission_modes(nestlevel);
2329 
2330  if (foreignrel->reloptkind == RELOPT_JOINREL)
2331  {
2332  List *ignore_conds = NIL;
2333 
2334 
2335  appendStringInfoString(buf, " FROM ");
2336  deparseFromExprForRel(buf, root, foreignrel, true, rtindex,
2337  &ignore_conds, &additional_conds, params_list);
2338  remote_conds = list_concat(remote_conds, ignore_conds);
2339  }
2340 
2341  appendWhereClause(remote_conds, additional_conds, &context);
2342 
2343  if (additional_conds != NIL)
2344  list_free_deep(additional_conds);
2345 
2346  if (foreignrel->reloptkind == RELOPT_JOINREL)
2347  deparseExplicitTargetList(returningList, true, retrieved_attrs,
2348  &context);
2349  else
2350  deparseReturningList(buf, rte, rtindex, rel, false,
2351  NIL, returningList, retrieved_attrs);
2352 }
#define Assert(condition)
Definition: c.h:858
static void deparseColumnRef(StringInfo buf, int varno, int varattno, RangeTblEntry *rte, bool qualify_col)
Definition: deparse.c:2681
static void deparseExpr(Expr *node, deparse_expr_cxt *context)
Definition: deparse.c:2884
int16 attnum
Definition: pg_attribute.h:74
#define forboth(cell1, list1, cell2, list2)
Definition: pg_list.h:518
#define lfirst_int(lc)
Definition: pg_list.h:173
void reset_transmission_modes(int nestlevel)
int set_transmission_modes(void)
Expr * expr
Definition: primnodes.h:2162

References appendStringInfo(), appendStringInfoString(), appendWhereClause(), Assert, attnum, buf, context, deparseColumnRef(), deparseExplicitTargetList(), deparseExpr(), deparseFromExprForRel(), deparseRelation(), deparseReturningList(), TargetEntry::expr, forboth, lfirst_int, lfirst_node, list_concat(), list_free_deep(), NIL, planner_rt_fetch, REL_ALIAS_PREFIX, RELOPT_JOINREL, RelOptInfo::reloptkind, reset_transmission_modes(), root, and set_transmission_modes().

Referenced by postgresPlanDirectModify().

◆ deparseInsertSql()

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 
)

Definition at line 2083 of file deparse.c.

2088 {
2089  TupleDesc tupdesc = RelationGetDescr(rel);
2090  AttrNumber pindex;
2091  bool first;
2092  ListCell *lc;
2093 
2094  appendStringInfoString(buf, "INSERT INTO ");
2095  deparseRelation(buf, rel);
2096 
2097  if (targetAttrs)
2098  {
2099  appendStringInfoChar(buf, '(');
2100 
2101  first = true;
2102  foreach(lc, targetAttrs)
2103  {
2104  int attnum = lfirst_int(lc);
2105 
2106  if (!first)
2107  appendStringInfoString(buf, ", ");
2108  first = false;
2109 
2110  deparseColumnRef(buf, rtindex, attnum, rte, false);
2111  }
2112 
2113  appendStringInfoString(buf, ") VALUES (");
2114 
2115  pindex = 1;
2116  first = true;
2117  foreach(lc, targetAttrs)
2118  {
2119  int attnum = lfirst_int(lc);
2120  Form_pg_attribute attr = TupleDescAttr(tupdesc, attnum - 1);
2121 
2122  if (!first)
2123  appendStringInfoString(buf, ", ");
2124  first = false;
2125 
2126  if (attr->attgenerated)
2127  appendStringInfoString(buf, "DEFAULT");
2128  else
2129  {
2130  appendStringInfo(buf, "$%d", pindex);
2131  pindex++;
2132  }
2133  }
2134 
2135  appendStringInfoChar(buf, ')');
2136  }
2137  else
2138  appendStringInfoString(buf, " DEFAULT VALUES");
2139  *values_end_len = buf->len;
2140 
2141  if (doNothing)
2142  appendStringInfoString(buf, " ON CONFLICT DO NOTHING");
2143 
2144  deparseReturningList(buf, rte, rtindex, rel,
2145  rel->trigdesc && rel->trigdesc->trig_insert_after_row,
2146  withCheckOptionList, returningList, retrieved_attrs);
2147 }
int16 AttrNumber
Definition: attnum.h:21
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:209
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:194
bool trig_insert_after_row
Definition: reltrigger.h:57

References appendStringInfo(), appendStringInfoChar(), appendStringInfoString(), attnum, buf, deparseColumnRef(), deparseRelation(), deparseReturningList(), lfirst_int, RelationGetDescr, TriggerDesc::trig_insert_after_row, RelationData::trigdesc, and TupleDescAttr.

Referenced by postgresBeginForeignInsert(), and postgresPlanForeignModify().

◆ deparseSelectStmtForRel()

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 
)

Definition at line 1233 of file deparse.c.

1237 {
1239  PgFdwRelationInfo *fpinfo = (PgFdwRelationInfo *) rel->fdw_private;
1240  List *quals;
1241 
1242  /*
1243  * We handle relations for foreign tables, joins between those and upper
1244  * relations.
1245  */
1246  Assert(IS_JOIN_REL(rel) || IS_SIMPLE_REL(rel) || IS_UPPER_REL(rel));
1247 
1248  /* Fill portions of context common to upper, join and base relation */
1249  context.buf = buf;
1250  context.root = root;
1251  context.foreignrel = rel;
1252  context.scanrel = IS_UPPER_REL(rel) ? fpinfo->outerrel : rel;
1253  context.params_list = params_list;
1254 
1255  /* Construct SELECT clause */
1256  deparseSelectSql(tlist, is_subquery, retrieved_attrs, &context);
1257 
1258  /*
1259  * For upper relations, the WHERE clause is built from the remote
1260  * conditions of the underlying scan relation; otherwise, we can use the
1261  * supplied list of remote conditions directly.
1262  */
1263  if (IS_UPPER_REL(rel))
1264  {
1265  PgFdwRelationInfo *ofpinfo;
1266 
1267  ofpinfo = (PgFdwRelationInfo *) fpinfo->outerrel->fdw_private;
1268  quals = ofpinfo->remote_conds;
1269  }
1270  else
1271  quals = remote_conds;
1272 
1273  /* Construct FROM and WHERE clauses */
1274  deparseFromExpr(quals, &context);
1275 
1276  if (IS_UPPER_REL(rel))
1277  {
1278  /* Append GROUP BY clause */
1279  appendGroupByClause(tlist, &context);
1280 
1281  /* Append HAVING clause */
1282  if (remote_conds)
1283  {
1284  appendStringInfoString(buf, " HAVING ");
1285  appendConditions(remote_conds, &context);
1286  }
1287  }
1288 
1289  /* Add ORDER BY clause if we found any useful pathkeys */
1290  if (pathkeys)
1291  appendOrderByClause(pathkeys, has_final_sort, &context);
1292 
1293  /* Add LIMIT clause if necessary */
1294  if (has_limit)
1296 
1297  /* Add any necessary FOR UPDATE/SHARE. */
1299 }
static void appendGroupByClause(List *tlist, deparse_expr_cxt *context)
Definition: deparse.c:3862
static void deparseFromExpr(List *quals, deparse_expr_cxt *context)
Definition: deparse.c:1373
static void deparseLockingClause(deparse_expr_cxt *context)
Definition: deparse.c:1481
static void appendOrderByClause(List *pathkeys, bool has_final_sort, deparse_expr_cxt *context)
Definition: deparse.c:3910
static void appendConditions(List *exprs, deparse_expr_cxt *context)
Definition: deparse.c:1571
static void appendLimitClause(deparse_expr_cxt *context)
Definition: deparse.c:4004
static void deparseSelectSql(List *tlist, bool is_subquery, List **retrieved_attrs, deparse_expr_cxt *context)
Definition: deparse.c:1315
#define IS_SIMPLE_REL(rel)
Definition: pathnodes.h:829
#define IS_JOIN_REL(rel)
Definition: pathnodes.h:834
RelOptInfo * outerrel
Definition: postgres_fdw.h:102

References appendConditions(), appendGroupByClause(), appendLimitClause(), appendOrderByClause(), appendStringInfoString(), Assert, buf, context, deparseFromExpr(), deparseLockingClause(), deparseSelectSql(), IS_JOIN_REL, IS_SIMPLE_REL, IS_UPPER_REL, PgFdwRelationInfo::outerrel, PgFdwRelationInfo::remote_conds, and root.

Referenced by deparseRangeTblRef(), estimate_path_cost_size(), and postgresGetForeignPlan().

◆ deparseStringLiteral()

void deparseStringLiteral ( StringInfo  buf,
const char *  val 
)

Definition at line 2849 of file deparse.c.

2850 {
2851  const char *valptr;
2852 
2853  /*
2854  * Rather than making assumptions about the remote server's value of
2855  * standard_conforming_strings, always use E'foo' syntax if there are any
2856  * backslashes. This will fail on remote servers before 8.1, but those
2857  * are long out of support.
2858  */
2859  if (strchr(val, '\\') != NULL)
2861  appendStringInfoChar(buf, '\'');
2862  for (valptr = val; *valptr; valptr++)
2863  {
2864  char ch = *valptr;
2865 
2866  if (SQL_STR_DOUBLE(ch, true))
2869  }
2870  appendStringInfoChar(buf, '\'');
2871 }
#define ESCAPE_STRING_SYNTAX
Definition: c.h:1166
#define SQL_STR_DOUBLE(ch, escape_backslash)
Definition: c.h:1163
long val
Definition: informix.c:670

References appendStringInfoChar(), buf, ESCAPE_STRING_SYNTAX, SQL_STR_DOUBLE, and val.

Referenced by deparseAnalyzeInfoSql(), deparseAnalyzeSizeSql(), deparseConst(), and postgresImportForeignSchema().

◆ deparseTruncateSql()

void deparseTruncateSql ( StringInfo  buf,
List rels,
DropBehavior  behavior,
bool  restart_seqs 
)

Definition at line 2646 of file deparse.c.

2650 {
2651  ListCell *cell;
2652 
2653  appendStringInfoString(buf, "TRUNCATE ");
2654 
2655  foreach(cell, rels)
2656  {
2657  Relation rel = lfirst(cell);
2658 
2659  if (cell != list_head(rels))
2660  appendStringInfoString(buf, ", ");
2661 
2662  deparseRelation(buf, rel);
2663  }
2664 
2665  appendStringInfo(buf, " %s IDENTITY",
2666  restart_seqs ? "RESTART" : "CONTINUE");
2667 
2668  if (behavior == DROP_RESTRICT)
2669  appendStringInfoString(buf, " RESTRICT");
2670  else if (behavior == DROP_CASCADE)
2671  appendStringInfoString(buf, " CASCADE");
2672 }
@ DROP_CASCADE
Definition: parsenodes.h:2337
@ DROP_RESTRICT
Definition: parsenodes.h:2336
static ListCell * list_head(const List *l)
Definition: pg_list.h:128

References appendStringInfo(), appendStringInfoString(), buf, deparseRelation(), DROP_CASCADE, DROP_RESTRICT, lfirst, and list_head().

Referenced by postgresExecForeignTruncate().

◆ deparseUpdateSql()

void deparseUpdateSql ( StringInfo  buf,
RangeTblEntry rte,
Index  rtindex,
Relation  rel,
List targetAttrs,
List withCheckOptionList,
List returningList,
List **  retrieved_attrs 
)

Definition at line 2216 of file deparse.c.

2221 {
2222  TupleDesc tupdesc = RelationGetDescr(rel);
2223  AttrNumber pindex;
2224  bool first;
2225  ListCell *lc;
2226 
2227  appendStringInfoString(buf, "UPDATE ");
2228  deparseRelation(buf, rel);
2229  appendStringInfoString(buf, " SET ");
2230 
2231  pindex = 2; /* ctid is always the first param */
2232  first = true;
2233  foreach(lc, targetAttrs)
2234  {
2235  int attnum = lfirst_int(lc);
2236  Form_pg_attribute attr = TupleDescAttr(tupdesc, attnum - 1);
2237 
2238  if (!first)
2239  appendStringInfoString(buf, ", ");
2240  first = false;
2241 
2242  deparseColumnRef(buf, rtindex, attnum, rte, false);
2243  if (attr->attgenerated)
2244  appendStringInfoString(buf, " = DEFAULT");
2245  else
2246  {
2247  appendStringInfo(buf, " = $%d", pindex);
2248  pindex++;
2249  }
2250  }
2251  appendStringInfoString(buf, " WHERE ctid = $1");
2252 
2253  deparseReturningList(buf, rte, rtindex, rel,
2254  rel->trigdesc && rel->trigdesc->trig_update_after_row,
2255  withCheckOptionList, returningList, retrieved_attrs);
2256 }
bool trig_update_after_row
Definition: reltrigger.h:62

References appendStringInfo(), appendStringInfoString(), attnum, buf, deparseColumnRef(), deparseRelation(), deparseReturningList(), lfirst_int, RelationGetDescr, TriggerDesc::trig_update_after_row, RelationData::trigdesc, and TupleDescAttr.

Referenced by postgresPlanForeignModify().

◆ do_sql_command()

void do_sql_command ( PGconn conn,
const char *  sql 
)

Definition at line 699 of file connection.c.

700 {
702  do_sql_command_end(conn, sql, false);
703 }
static void do_sql_command_end(PGconn *conn, const char *sql, bool consume_input)
Definition: connection.c:713
static void do_sql_command_begin(PGconn *conn, const char *sql)
Definition: connection.c:706
PGconn * conn
Definition: streamutil.c:55

References conn, do_sql_command_begin(), and do_sql_command_end().

Referenced by begin_remote_xact(), configure_remote_session(), pgfdw_subxact_callback(), pgfdw_xact_callback(), and postgresExecForeignTruncate().

◆ ExtractConnectionOptions()

int ExtractConnectionOptions ( List defelems,
const char **  keywords,
const char **  values 
)

Definition at line 414 of file option.c.

416 {
417  ListCell *lc;
418  int i;
419 
420  /* Build our options lists if we didn't yet. */
422 
423  i = 0;
424  foreach(lc, defelems)
425  {
426  DefElem *d = (DefElem *) lfirst(lc);
427 
428  if (is_libpq_option(d->defname))
429  {
430  keywords[i] = d->defname;
431  values[i] = defGetString(d);
432  i++;
433  }
434  }
435  return i;
436 }
static Datum values[MAXATTR]
Definition: bootstrap.c:152
static bool is_libpq_option(const char *keyword)
Definition: option.c:393
static void InitPgFdwOptions(void)
Definition: option.c:240

References defGetString(), DefElem::defname, i, InitPgFdwOptions(), is_libpq_option(), lfirst, and values.

Referenced by connect_pg_server().

◆ ExtractExtensionList()

List* ExtractExtensionList ( const char *  extensionsString,
bool  warnOnMissing 
)

Definition at line 445 of file option.c.

446 {
447  List *extensionOids = NIL;
448  List *extlist;
449  ListCell *lc;
450 
451  /* SplitIdentifierString scribbles on its input, so pstrdup first */
452  if (!SplitIdentifierString(pstrdup(extensionsString), ',', &extlist))
453  {
454  /* syntax error in name list */
455  ereport(ERROR,
456  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
457  errmsg("parameter \"%s\" must be a list of extension names",
458  "extensions")));
459  }
460 
461  foreach(lc, extlist)
462  {
463  const char *extension_name = (const char *) lfirst(lc);
464  Oid extension_oid = get_extension_oid(extension_name, true);
465 
466  if (OidIsValid(extension_oid))
467  {
468  extensionOids = lappend_oid(extensionOids, extension_oid);
469  }
470  else if (warnOnMissing)
471  {
473  (errcode(ERRCODE_UNDEFINED_OBJECT),
474  errmsg("extension \"%s\" is not installed",
475  extension_name)));
476  }
477  }
478 
479  list_free(extlist);
480  return extensionOids;
481 }
#define OidIsValid(objectId)
Definition: c.h:775
int errcode(int sqlerrcode)
Definition: elog.c:859
int errmsg(const char *fmt,...)
Definition: elog.c:1072
#define WARNING
Definition: elog.h:36
#define ereport(elevel,...)
Definition: elog.h:149
Oid get_extension_oid(const char *extname, bool missing_ok)
Definition: extension.c:145
List * lappend_oid(List *list, Oid datum)
Definition: list.c:375
void list_free(List *list)
Definition: list.c:1546
char * pstrdup(const char *in)
Definition: mcxt.c:1695
bool SplitIdentifierString(char *rawstring, char separator, List **namelist)
Definition: varlena.c:3457

References ereport, errcode(), errmsg(), ERROR, get_extension_oid(), lappend_oid(), lfirst, list_free(), NIL, OidIsValid, pstrdup(), SplitIdentifierString(), and WARNING.

Referenced by apply_server_options(), and postgres_fdw_validator().

◆ find_em_for_rel()

EquivalenceMember* find_em_for_rel ( PlannerInfo root,
EquivalenceClass ec,
RelOptInfo rel 
)

Definition at line 7776 of file postgres_fdw.c.

7777 {
7778  ListCell *lc;
7779 
7780  PgFdwRelationInfo *fpinfo = (PgFdwRelationInfo *) rel->fdw_private;
7781 
7782  foreach(lc, ec->ec_members)
7783  {
7785 
7786  /*
7787  * Note we require !bms_is_empty, else we'd accept constant
7788  * expressions which are not suitable for the purpose.
7789  */
7790  if (bms_is_subset(em->em_relids, rel->relids) &&
7791  !bms_is_empty(em->em_relids) &&
7793  is_foreign_expr(root, rel, em->em_expr))
7794  return em;
7795  }
7796 
7797  return NULL;
7798 }
bool bms_is_subset(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:412
Bitmapset * bms_intersect(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:292
#define bms_is_empty(a)
Definition: bitmapset.h:118
Relids hidden_subquery_rels
Definition: postgres_fdw.h:121
Relids relids
Definition: pathnodes.h:861

References bms_intersect(), bms_is_empty, bms_is_subset(), EquivalenceClass::ec_members, EquivalenceMember::em_expr, EquivalenceMember::em_relids, PgFdwRelationInfo::hidden_subquery_rels, is_foreign_expr(), lfirst, RelOptInfo::relids, and root.

Referenced by appendOrderByClause(), get_useful_pathkeys_for_relation(), and is_foreign_pathkey().

◆ find_em_for_rel_target()

EquivalenceMember* find_em_for_rel_target ( PlannerInfo root,
EquivalenceClass ec,
RelOptInfo rel 
)

Definition at line 7812 of file postgres_fdw.c.

7814 {
7815  PathTarget *target = rel->reltarget;
7816  ListCell *lc1;
7817  int i;
7818 
7819  i = 0;
7820  foreach(lc1, target->exprs)
7821  {
7822  Expr *expr = (Expr *) lfirst(lc1);
7823  Index sgref = get_pathtarget_sortgroupref(target, i);
7824  ListCell *lc2;
7825 
7826  /* Ignore non-sort expressions */
7827  if (sgref == 0 ||
7829  root->parse->sortClause) == NULL)
7830  {
7831  i++;
7832  continue;
7833  }
7834 
7835  /* We ignore binary-compatible relabeling on both ends */
7836  while (expr && IsA(expr, RelabelType))
7837  expr = ((RelabelType *) expr)->arg;
7838 
7839  /* Locate an EquivalenceClass member matching this expr, if any */
7840  foreach(lc2, ec->ec_members)
7841  {
7843  Expr *em_expr;
7844 
7845  /* Don't match constants */
7846  if (em->em_is_const)
7847  continue;
7848 
7849  /* Ignore child members */
7850  if (em->em_is_child)
7851  continue;
7852 
7853  /* Match if same expression (after stripping relabel) */
7854  em_expr = em->em_expr;
7855  while (em_expr && IsA(em_expr, RelabelType))
7856  em_expr = ((RelabelType *) em_expr)->arg;
7857 
7858  if (!equal(em_expr, expr))
7859  continue;
7860 
7861  /* Check that expression (including relabels!) is shippable */
7862  if (is_foreign_expr(root, rel, em->em_expr))
7863  return em;
7864  }
7865 
7866  i++;
7867  }
7868 
7869  return NULL;
7870 }
unsigned int Index
Definition: c.h:614
bool equal(const void *a, const void *b)
Definition: equalfuncs.c:223
#define IsA(nodeptr, _type_)
Definition: nodes.h:158
#define get_pathtarget_sortgroupref(target, colno)
Definition: pathnodes.h:1538
void * arg
SortGroupClause * get_sortgroupref_clause_noerr(Index sortref, List *clauses)
Definition: tlist.c:443

References arg, EquivalenceClass::ec_members, EquivalenceMember::em_expr, EquivalenceMember::em_is_child, EquivalenceMember::em_is_const, equal(), PathTarget::exprs, get_pathtarget_sortgroupref, get_sortgroupref_clause_noerr(), i, is_foreign_expr(), IsA, lfirst, RelOptInfo::reltarget, and root.

Referenced by add_foreign_ordered_paths(), and appendOrderByClause().

◆ get_jointype_name()

const char* get_jointype_name ( JoinType  jointype)

Definition at line 1641 of file deparse.c.

1642 {
1643  switch (jointype)
1644  {
1645  case JOIN_INNER:
1646  return "INNER";
1647 
1648  case JOIN_LEFT:
1649  return "LEFT";
1650 
1651  case JOIN_RIGHT:
1652  return "RIGHT";
1653 
1654  case JOIN_FULL:
1655  return "FULL";
1656 
1657  case JOIN_SEMI:
1658  return "SEMI";
1659 
1660  default:
1661  /* Shouldn't come here, but protect from buggy code. */
1662  elog(ERROR, "unsupported join type %d", jointype);
1663  }
1664 
1665  /* Keep compiler happy */
1666  return NULL;
1667 }
@ JOIN_SEMI
Definition: nodes.h:307
@ JOIN_FULL
Definition: nodes.h:295
@ JOIN_INNER
Definition: nodes.h:293
@ JOIN_RIGHT
Definition: nodes.h:296
@ JOIN_LEFT
Definition: nodes.h:294

References elog, ERROR, JOIN_FULL, JOIN_INNER, JOIN_LEFT, JOIN_RIGHT, and JOIN_SEMI.

Referenced by deparseFromExprForRel(), and foreign_join_ok().

◆ GetConnection()

PGconn* GetConnection ( UserMapping user,
bool  will_prep_stmt,
PgFdwConnState **  state 
)

Definition at line 177 of file connection.c.

178 {
179  bool found;
180  bool retry = false;
181  ConnCacheEntry *entry;
184 
185  /* First time through, initialize connection cache hashtable */
186  if (ConnectionHash == NULL)
187  {
188  HASHCTL ctl;
189 
190  if (pgfdw_we_get_result == 0)
192  WaitEventExtensionNew("PostgresFdwGetResult");
193 
194  ctl.keysize = sizeof(ConnCacheKey);
195  ctl.entrysize = sizeof(ConnCacheEntry);
196  ConnectionHash = hash_create("postgres_fdw connections", 8,
197  &ctl,
199 
200  /*
201  * Register some callback functions that manage connection cleanup.
202  * This should be done just once in each backend.
203  */
206  CacheRegisterSyscacheCallback(FOREIGNSERVEROID,
208  CacheRegisterSyscacheCallback(USERMAPPINGOID,
210  }
211 
212  /* Set flag that we did GetConnection during the current transaction */
213  xact_got_connection = true;
214 
215  /* Create hash key for the entry. Assume no pad bytes in key struct */
216  key = user->umid;
217 
218  /*
219  * Find or create cached entry for requested connection.
220  */
221  entry = hash_search(ConnectionHash, &key, HASH_ENTER, &found);
222  if (!found)
223  {
224  /*
225  * We need only clear "conn" here; remaining fields will be filled
226  * later when "conn" is set.
227  */
228  entry->conn = NULL;
229  }
230 
231  /* Reject further use of connections which failed abort cleanup. */
233 
234  /*
235  * If the connection needs to be remade due to invalidation, disconnect as
236  * soon as we're out of all transactions.
237  */
238  if (entry->conn != NULL && entry->invalidated && entry->xact_depth == 0)
239  {
240  elog(DEBUG3, "closing connection %p for option changes to take effect",
241  entry->conn);
242  disconnect_pg_server(entry);
243  }
244 
245  /*
246  * If cache entry doesn't have a connection, we have to establish a new
247  * connection. (If connect_pg_server throws an error, the cache entry
248  * will remain in a valid empty state, ie conn == NULL.)
249  */
250  if (entry->conn == NULL)
251  make_new_connection(entry, user);
252 
253  /*
254  * We check the health of the cached connection here when using it. In
255  * cases where we're out of all transactions, if a broken connection is
256  * detected, we try to reestablish a new connection later.
257  */
258  PG_TRY();
259  {
260  /* Process a pending asynchronous request if any. */
261  if (entry->state.pendingAreq)
263  /* Start a new transaction or subtransaction if needed. */
264  begin_remote_xact(entry);
265  }
266  PG_CATCH();
267  {
269  ErrorData *errdata = CopyErrorData();
270 
271  /*
272  * Determine whether to try to reestablish the connection.
273  *
274  * After a broken connection is detected in libpq, any error other
275  * than connection failure (e.g., out-of-memory) can be thrown
276  * somewhere between return from libpq and the expected ereport() call
277  * in pgfdw_report_error(). In this case, since PQstatus() indicates
278  * CONNECTION_BAD, checking only PQstatus() causes the false detection
279  * of connection failure. To avoid this, we also verify that the
280  * error's sqlstate is ERRCODE_CONNECTION_FAILURE. Note that also
281  * checking only the sqlstate can cause another false detection
282  * because pgfdw_report_error() may report ERRCODE_CONNECTION_FAILURE
283  * for any libpq-originated error condition.
284  */
285  if (errdata->sqlerrcode != ERRCODE_CONNECTION_FAILURE ||
286  PQstatus(entry->conn) != CONNECTION_BAD ||
287  entry->xact_depth > 0)
288  {
289  MemoryContextSwitchTo(ecxt);
290  PG_RE_THROW();
291  }
292 
293  /* Clean up the error state */
294  FlushErrorState();
295  FreeErrorData(errdata);
296  errdata = NULL;
297 
298  retry = true;
299  }
300  PG_END_TRY();
301 
302  /*
303  * If a broken connection is detected, disconnect it, reestablish a new
304  * connection and retry a new remote transaction. If connection failure is
305  * reported again, we give up getting a connection.
306  */
307  if (retry)
308  {
309  Assert(entry->xact_depth == 0);
310 
311  ereport(DEBUG3,
312  (errmsg_internal("could not start remote transaction on connection %p",
313  entry->conn)),
314  errdetail_internal("%s", pchomp(PQerrorMessage(entry->conn))));
315 
316  elog(DEBUG3, "closing connection %p to reestablish a new one",
317  entry->conn);
318  disconnect_pg_server(entry);
319 
320  make_new_connection(entry, user);
321 
322  begin_remote_xact(entry);
323  }
324 
325  /* Remember if caller will prepare statements */
326  entry->have_prep_stmt |= will_prep_stmt;
327 
328  /* If caller needs access to the per-connection state, return it. */
329  if (state)
330  *state = &entry->state;
331 
332  return entry->conn;
333 }
Oid ConnCacheKey
Definition: connection.c:51
static void disconnect_pg_server(ConnCacheEntry *entry)
Definition: connection.c:580
static uint32 pgfdw_we_get_result
Definition: connection.c:89
static bool xact_got_connection
Definition: connection.c:84
struct ConnCacheEntry ConnCacheEntry
static HTAB * ConnectionHash
Definition: connection.c:77
static void make_new_connection(ConnCacheEntry *entry, UserMapping *user)
Definition: connection.c:340
static void pgfdw_subxact_callback(SubXactEvent event, SubTransactionId mySubid, SubTransactionId parentSubid, void *arg)
Definition: connection.c:1077
static void pgfdw_reject_incomplete_xact_state_change(ConnCacheEntry *entry)
Definition: connection.c:1240
static void pgfdw_inval_callback(Datum arg, int cacheid, uint32 hashvalue)
Definition: connection.c:1190
static void pgfdw_xact_callback(XactEvent event, void *arg)
Definition: connection.c:927
static void begin_remote_xact(ConnCacheEntry *entry)
Definition: connection.c:742
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:955
HTAB * hash_create(const char *tabname, long nelem, const HASHCTL *info, int flags)
Definition: dynahash.c:352
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1159
void FreeErrorData(ErrorData *edata)
Definition: elog.c:1787
int errdetail_internal(const char *fmt,...)
Definition: elog.c:1232
void FlushErrorState(void)
Definition: elog.c:1836
ErrorData * CopyErrorData(void)
Definition: elog.c:1731
#define PG_RE_THROW()
Definition: elog.h:411
#define DEBUG3
Definition: elog.h:28
#define PG_TRY(...)
Definition: elog.h:370
#define PG_END_TRY(...)
Definition: elog.h:395
#define PG_CATCH(...)
Definition: elog.h:380
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:7147
ConnStatusType PQstatus(const PGconn *conn)
Definition: fe-connect.c:7094
@ HASH_ENTER
Definition: hsearch.h:114
#define HASH_ELEM
Definition: hsearch.h:95
#define HASH_BLOBS
Definition: hsearch.h:97
void CacheRegisterSyscacheCallback(int cacheid, SyscacheCallbackFunction func, Datum arg)
Definition: inval.c:1516
@ CONNECTION_BAD
Definition: libpq-fe.h:62
char * pchomp(const char *in)
Definition: mcxt.c:1723
MemoryContext CurrentMemoryContext
Definition: mcxt.c:143
static char * user
Definition: pg_regress.c:120
uintptr_t Datum
Definition: postgres.h:64
void process_pending_request(AsyncRequest *areq)
MemoryContextSwitchTo(old_ctx)
tree ctl
Definition: radixtree.h:1847
PGconn * conn
Definition: connection.c:56
bool have_prep_stmt
Definition: connection.c:60
PgFdwConnState state
Definition: connection.c:71
bool invalidated
Definition: connection.c:65
int sqlerrcode
Definition: elog.h:438
AsyncRequest * pendingAreq
Definition: postgres_fdw.h:138
Definition: regguts.h:323
uint32 WaitEventExtensionNew(const char *wait_event_name)
Definition: wait_event.c:162
void RegisterXactCallback(XactCallback callback, void *arg)
Definition: xact.c:3753
void RegisterSubXactCallback(SubXactCallback callback, void *arg)
Definition: xact.c:3813

References Assert, begin_remote_xact(), CacheRegisterSyscacheCallback(), ConnCacheEntry::conn, CONNECTION_BAD, ConnectionHash, CopyErrorData(), ctl, CurrentMemoryContext, DEBUG3, disconnect_pg_server(), elog, ereport, errdetail_internal(), errmsg_internal(), FlushErrorState(), FreeErrorData(), HASH_BLOBS, hash_create(), HASH_ELEM, HASH_ENTER, hash_search(), ConnCacheEntry::have_prep_stmt, ConnCacheEntry::invalidated, sort-test::key, make_new_connection(), MemoryContextSwitchTo(), pchomp(), PgFdwConnState::pendingAreq, PG_CATCH, PG_END_TRY, PG_RE_THROW, PG_TRY, pgfdw_inval_callback(), pgfdw_reject_incomplete_xact_state_change(), pgfdw_subxact_callback(), pgfdw_we_get_result, pgfdw_xact_callback(), PQerrorMessage(), PQstatus(), process_pending_request(), RegisterSubXactCallback(), RegisterXactCallback(), ErrorData::sqlerrcode, ConnCacheEntry::state, user, WaitEventExtensionNew(), ConnCacheEntry::xact_depth, and xact_got_connection.

Referenced by create_foreign_modify(), dumpDatabase(), dumpDatabaseConfig(), dumpLOs(), dumpTableData_copy(), estimate_path_cost_size(), expand_extension_name_patterns(), expand_foreign_server_name_patterns(), expand_schema_name_patterns(), expand_table_name_patterns(), getTables(), main(), postgresAcquireSampleRowsFunc(), postgresAnalyzeForeignTable(), postgresBeginDirectModify(), postgresBeginForeignScan(), postgresExecForeignTruncate(), postgresGetAnalyzeInfoForForeignTable(), postgresImportForeignSchema(), setup_connection(), StartLogStreamer(), StreamLog(), and StreamLogicalLog().

◆ GetCursorNumber()

unsigned int GetCursorNumber ( PGconn conn)

Definition at line 806 of file connection.c.

807 {
808  return ++cursor_number;
809 }
static unsigned int cursor_number
Definition: connection.c:80

References cursor_number.

Referenced by postgresAcquireSampleRowsFunc(), and postgresBeginForeignScan().

◆ GetPrepStmtNumber()

unsigned int GetPrepStmtNumber ( PGconn conn)

Definition at line 820 of file connection.c.

821 {
822  return ++prep_stmt_number;
823 }
static unsigned int prep_stmt_number
Definition: connection.c:81

References prep_stmt_number.

Referenced by prepare_foreign_modify().

◆ is_builtin()

bool is_builtin ( Oid  objectId)

Definition at line 152 of file shippable.c.

153 {
154  return (objectId < FirstGenbkiObjectId);
155 }
#define FirstGenbkiObjectId
Definition: transam.h:195

References FirstGenbkiObjectId.

Referenced by deparse_type_name(), and is_shippable().

◆ is_foreign_expr()

bool is_foreign_expr ( PlannerInfo root,
RelOptInfo baserel,
Expr expr 
)

Definition at line 244 of file deparse.c.

247 {
248  foreign_glob_cxt glob_cxt;
249  foreign_loc_cxt loc_cxt;
250  PgFdwRelationInfo *fpinfo = (PgFdwRelationInfo *) (baserel->fdw_private);
251 
252  /*
253  * Check that the expression consists of nodes that are safe to execute
254  * remotely.
255  */
256  glob_cxt.root = root;
257  glob_cxt.foreignrel = baserel;
258 
259  /*
260  * For an upper relation, use relids from its underneath scan relation,
261  * because the upperrel's own relids currently aren't set to anything
262  * meaningful by the core code. For other relation, use their own relids.
263  */
264  if (IS_UPPER_REL(baserel))
265  glob_cxt.relids = fpinfo->outerrel->relids;
266  else
267  glob_cxt.relids = baserel->relids;
268  loc_cxt.collation = InvalidOid;
269  loc_cxt.state = FDW_COLLATE_NONE;
270  if (!foreign_expr_walker((Node *) expr, &glob_cxt, &loc_cxt, NULL))
271  return false;
272 
273  /*
274  * If the expression has a valid collation that does not arise from a
275  * foreign var, the expression can not be sent over.
276  */
277  if (loc_cxt.state == FDW_COLLATE_UNSAFE)
278  return false;
279 
280  /*
281  * An expression which includes any mutable functions can't be sent over
282  * because its result is not stable. For example, sending now() remote
283  * side could cause confusion from clock offsets. Future versions might
284  * be able to make this choice with more granularity. (We check this last
285  * because it requires a lot of expensive catalog lookups.)
286  */
287  if (contain_mutable_functions((Node *) expr))
288  return false;
289 
290  /* OK to evaluate on the remote server */
291  return true;
292 }
bool contain_mutable_functions(Node *clause)
Definition: clauses.c:370
@ FDW_COLLATE_UNSAFE
Definition: deparse.c:86
@ FDW_COLLATE_NONE
Definition: deparse.c:82
static bool foreign_expr_walker(Node *node, foreign_glob_cxt *glob_cxt, foreign_loc_cxt *outer_cxt, foreign_loc_cxt *case_arg_cxt)
Definition: deparse.c:312
#define InvalidOid
Definition: postgres_ext.h:36
RelOptInfo * foreignrel
Definition: deparse.c:71
Relids relids
Definition: deparse.c:72
PlannerInfo * root
Definition: deparse.c:70
FDWCollateState state
Definition: deparse.c:93

References foreign_loc_cxt::collation, contain_mutable_functions(), FDW_COLLATE_NONE, FDW_COLLATE_UNSAFE, foreign_expr_walker(), foreign_glob_cxt::foreignrel, if(), InvalidOid, IS_UPPER_REL, PgFdwRelationInfo::outerrel, foreign_glob_cxt::relids, RelOptInfo::relids, foreign_glob_cxt::root, root, and foreign_loc_cxt::state.

Referenced by add_foreign_final_paths(), classifyConditions(), find_em_for_rel(), find_em_for_rel_target(), foreign_grouping_ok(), foreign_join_ok(), postgresGetForeignPaths(), postgresGetForeignPlan(), and postgresPlanDirectModify().

◆ is_foreign_param()

bool is_foreign_param ( PlannerInfo root,
RelOptInfo baserel,
Expr expr 
)

Definition at line 1082 of file deparse.c.

1085 {
1086  if (expr == NULL)
1087  return false;
1088 
1089  switch (nodeTag(expr))
1090  {
1091  case T_Var:
1092  {
1093  /* It would have to be sent unless it's a foreign Var */
1094  Var *var = (Var *) expr;
1095  PgFdwRelationInfo *fpinfo = (PgFdwRelationInfo *) (baserel->fdw_private);
1096  Relids relids;
1097 
1098  if (IS_UPPER_REL(baserel))
1099  relids = fpinfo->outerrel->relids;
1100  else
1101  relids = baserel->relids;
1102 
1103  if (bms_is_member(var->varno, relids) && var->varlevelsup == 0)
1104  return false; /* foreign Var, so not a param */
1105  else
1106  return true; /* it'd have to be a param */
1107  break;
1108  }
1109  case T_Param:
1110  /* Params always have to be sent to the foreign server */
1111  return true;
1112  default:
1113  break;
1114  }
1115  return false;
1116 }
bool bms_is_member(int x, const Bitmapset *a)
Definition: bitmapset.c:510
#define nodeTag(nodeptr)
Definition: nodes.h:133
Definition: primnodes.h:248
int varno
Definition: primnodes.h:255
Index varlevelsup
Definition: primnodes.h:280

References bms_is_member(), if(), IS_UPPER_REL, nodeTag, PgFdwRelationInfo::outerrel, RelOptInfo::relids, Var::varlevelsup, and Var::varno.

Referenced by foreign_grouping_ok().

◆ is_foreign_pathkey()

bool is_foreign_pathkey ( PlannerInfo root,
RelOptInfo baserel,
PathKey pathkey 
)

Definition at line 1123 of file deparse.c.

1126 {
1127  EquivalenceClass *pathkey_ec = pathkey->pk_eclass;
1128  PgFdwRelationInfo *fpinfo = (PgFdwRelationInfo *) baserel->fdw_private;
1129 
1130  /*
1131  * is_foreign_expr would detect volatile expressions as well, but checking
1132  * ec_has_volatile here saves some cycles.
1133  */
1134  if (pathkey_ec->ec_has_volatile)
1135  return false;
1136 
1137  /* can't push down the sort if the pathkey's opfamily is not shippable */
1138  if (!is_shippable(pathkey->pk_opfamily, OperatorFamilyRelationId, fpinfo))
1139  return false;
1140 
1141  /* can push if a suitable EC member exists */
1142  return (find_em_for_rel(root, pathkey_ec, baserel) != NULL);
1143 }
EquivalenceMember * find_em_for_rel(PlannerInfo *root, EquivalenceClass *ec, RelOptInfo *rel)
bool is_shippable(Oid objectId, Oid classId, PgFdwRelationInfo *fpinfo)
Definition: shippable.c:162
Oid pk_opfamily
Definition: pathnodes.h:1465

References EquivalenceClass::ec_has_volatile, find_em_for_rel(), if(), is_shippable(), PathKey::pk_opfamily, and root.

Referenced by get_useful_pathkeys_for_relation().

◆ is_shippable()

bool is_shippable ( Oid  objectId,
Oid  classId,
PgFdwRelationInfo fpinfo 
)

Definition at line 162 of file shippable.c.

163 {
165  ShippableCacheEntry *entry;
166 
167  /* Built-in objects are presumed shippable. */
168  if (is_builtin(objectId))
169  return true;
170 
171  /* Otherwise, give up if user hasn't specified any shippable extensions. */
172  if (fpinfo->shippable_extensions == NIL)
173  return false;
174 
175  /* Initialize cache if first time through. */
176  if (!ShippableCacheHash)
178 
179  /* Set up cache hash key */
180  key.objid = objectId;
181  key.classid = classId;
182  key.serverid = fpinfo->server->serverid;
183 
184  /* See if we already cached the result. */
185  entry = (ShippableCacheEntry *)
187 
188  if (!entry)
189  {
190  /* Not found in cache, so perform shippability lookup. */
191  bool shippable = lookup_shippable(objectId, classId, fpinfo);
192 
193  /*
194  * Don't create a new hash entry until *after* we have the shippable
195  * result in hand, as the underlying catalog lookups might trigger a
196  * cache invalidation.
197  */
198  entry = (ShippableCacheEntry *)
200 
201  entry->shippable = shippable;
202  }
203 
204  return entry->shippable;
205 }
@ HASH_FIND
Definition: hsearch.h:113
static bool lookup_shippable(Oid objectId, Oid classId, PgFdwRelationInfo *fpinfo)
Definition: shippable.c:116
bool is_builtin(Oid objectId)
Definition: shippable.c:152
static void InitializeShippableCache(void)
Definition: shippable.c:91
static HTAB * ShippableCacheHash
Definition: shippable.c:34
Oid serverid
Definition: foreign.h:36
List * shippable_extensions
Definition: postgres_fdw.h:81
ForeignServer * server
Definition: postgres_fdw.h:86

References HASH_ENTER, HASH_FIND, hash_search(), InitializeShippableCache(), is_builtin(), sort-test::key, lookup_shippable(), NIL, PgFdwRelationInfo::server, ForeignServer::serverid, ShippableCacheEntry::shippable, PgFdwRelationInfo::shippable_extensions, and ShippableCacheHash.

Referenced by add_foreign_ordered_paths(), foreign_expr_walker(), get_useful_pathkeys_for_relation(), and is_foreign_pathkey().

◆ pgfdw_exec_query()

PGresult* pgfdw_exec_query ( PGconn conn,
const char *  query,
PgFdwConnState state 
)

Definition at line 835 of file connection.c.

836 {
837  /* First, process a pending asynchronous request, if any. */
838  if (state && state->pendingAreq)
839  process_pending_request(state->pendingAreq);
840 
841  if (!PQsendQuery(conn, query))
842  return NULL;
843  return pgfdw_get_result(conn);
844 }
PGresult * pgfdw_get_result(PGconn *conn)
Definition: connection.c:852
int PQsendQuery(PGconn *conn, const char *query)
Definition: fe-exec.c:1416

References conn, pgfdw_get_result(), PQsendQuery(), and process_pending_request().

Referenced by close_cursor(), deallocate_query(), fetch_more_data(), get_remote_estimate(), pgfdw_xact_callback(), postgresAcquireSampleRowsFunc(), postgresAnalyzeForeignTable(), postgresGetAnalyzeInfoForForeignTable(), postgresImportForeignSchema(), and postgresReScanForeignScan().

◆ pgfdw_get_result()

PGresult* pgfdw_get_result ( PGconn conn)

Definition at line 852 of file connection.c.

853 {
855 }
static PGresult * libpqsrv_get_result_last(PGconn *conn, uint32 wait_event_info)

References conn, libpqsrv_get_result_last(), and pgfdw_we_get_result.

Referenced by create_cursor(), do_sql_command_end(), execute_dml_stmt(), execute_foreign_modify(), fetch_more_data(), pgfdw_exec_query(), and prepare_foreign_modify().

◆ pgfdw_report_error()

void pgfdw_report_error ( int  elevel,
PGresult res,
PGconn conn,
bool  clear,
const char *  sql 
)

Definition at line 871 of file connection.c.

873 {
874  /* If requested, PGresult must be released before leaving this function. */
875  PG_TRY();
876  {
877  char *diag_sqlstate = PQresultErrorField(res, PG_DIAG_SQLSTATE);
878  char *message_primary = PQresultErrorField(res, PG_DIAG_MESSAGE_PRIMARY);
879  char *message_detail = PQresultErrorField(res, PG_DIAG_MESSAGE_DETAIL);
880  char *message_hint = PQresultErrorField(res, PG_DIAG_MESSAGE_HINT);
881  char *message_context = PQresultErrorField(res, PG_DIAG_CONTEXT);
882  int sqlstate;
883 
884  if (diag_sqlstate)
885  sqlstate = MAKE_SQLSTATE(diag_sqlstate[0],
886  diag_sqlstate[1],
887  diag_sqlstate[2],
888  diag_sqlstate[3],
889  diag_sqlstate[4]);
890  else
891  sqlstate = ERRCODE_CONNECTION_FAILURE;
892 
893  /*
894  * If we don't get a message from the PGresult, try the PGconn. This
895  * is needed because for connection-level failures, PQgetResult may
896  * just return NULL, not a PGresult at all.
897  */
898  if (message_primary == NULL)
899  message_primary = pchomp(PQerrorMessage(conn));
900 
901  ereport(elevel,
902  (errcode(sqlstate),
903  (message_primary != NULL && message_primary[0] != '\0') ?
904  errmsg_internal("%s", message_primary) :
905  errmsg("could not obtain message string for remote error"),
906  message_detail ? errdetail_internal("%s", message_detail) : 0,
907  message_hint ? errhint("%s", message_hint) : 0,
908  message_context ? errcontext("%s", message_context) : 0,
909  sql ? errcontext("remote SQL command: %s", sql) : 0));
910  }
911  PG_FINALLY();
912  {
913  if (clear)
914  PQclear(res);
915  }
916  PG_END_TRY();
917 }
int errhint(const char *fmt,...)
Definition: elog.c:1319
#define errcontext
Definition: elog.h:196
#define MAKE_SQLSTATE(ch1, ch2, ch3, ch4, ch5)
Definition: elog.h:56
#define PG_FINALLY(...)
Definition: elog.h:387
char * PQresultErrorField(const PGresult *res, int fieldcode)
Definition: fe-exec.c:3466
#define PG_DIAG_MESSAGE_HINT
Definition: postgres_ext.h:59
#define PG_DIAG_SQLSTATE
Definition: postgres_ext.h:56
#define PG_DIAG_MESSAGE_PRIMARY
Definition: postgres_ext.h:57
#define PG_DIAG_MESSAGE_DETAIL
Definition: postgres_ext.h:58
#define PG_DIAG_CONTEXT
Definition: postgres_ext.h:63

References conn, ereport, errcode(), errcontext, errdetail_internal(), errhint(), errmsg(), errmsg_internal(), MAKE_SQLSTATE, pchomp(), PG_DIAG_CONTEXT, PG_DIAG_MESSAGE_DETAIL, PG_DIAG_MESSAGE_HINT, PG_DIAG_MESSAGE_PRIMARY, PG_DIAG_SQLSTATE, PG_END_TRY, PG_FINALLY, PG_TRY, PQclear(), PQerrorMessage(), PQresultErrorField(), and res.

Referenced by close_cursor(), create_cursor(), deallocate_query(), do_sql_command_begin(), do_sql_command_end(), execute_dml_stmt(), execute_foreign_modify(), fetch_more_data(), fetch_more_data_begin(), get_remote_estimate(), pgfdw_exec_cleanup_query_begin(), pgfdw_exec_cleanup_query_end(), postgresAcquireSampleRowsFunc(), postgresAnalyzeForeignTable(), postgresForeignAsyncNotify(), postgresGetAnalyzeInfoForForeignTable(), postgresImportForeignSchema(), postgresReScanForeignScan(), and prepare_foreign_modify().

◆ process_pending_request()

void process_pending_request ( AsyncRequest areq)

Definition at line 7449 of file postgres_fdw.c.

7450 {
7451  ForeignScanState *node = (ForeignScanState *) areq->requestee;
7452  PgFdwScanState *fsstate = (PgFdwScanState *) node->fdw_state;
7453 
7454  /* The request would have been pending for a callback */
7455  Assert(areq->callback_pending);
7456 
7457  /* The request should be currently in-process */
7458  Assert(fsstate->conn_state->pendingAreq == areq);
7459 
7460  fetch_more_data(node);
7461 
7462  /*
7463  * If we didn't get any tuples, must be end of data; complete the request
7464  * now. Otherwise, we postpone completing the request until we are called
7465  * from postgresForeignAsyncConfigureWait()/postgresForeignAsyncNotify().
7466  */
7467  if (fsstate->next_tuple >= fsstate->num_tuples)
7468  {
7469  /* Unlike AsyncNotify, we unset callback_pending ourselves */
7470  areq->callback_pending = false;
7471  /* Mark the request as complete */
7472  ExecAsyncRequestDone(areq, NULL);
7473  /* Unlike AsyncNotify, we call ExecAsyncResponse ourselves */
7474  ExecAsyncResponse(areq);
7475  }
7476 }
void ExecAsyncResponse(AsyncRequest *areq)
Definition: execAsync.c:117
void ExecAsyncRequestDone(AsyncRequest *areq, TupleTableSlot *result)
Definition: execAsync.c:137
static void fetch_more_data(ForeignScanState *node)
bool callback_pending
Definition: execnodes.h:606
struct PlanState * requestee
Definition: execnodes.h:604

References Assert, AsyncRequest::callback_pending, ExecAsyncRequestDone(), ExecAsyncResponse(), ForeignScanState::fdw_state, fetch_more_data(), and AsyncRequest::requestee.

Referenced by create_cursor(), execute_dml_stmt(), execute_foreign_modify(), GetConnection(), pgfdw_exec_query(), and postgresForeignAsyncConfigureWait().

◆ process_pgfdw_appname()

char* process_pgfdw_appname ( const char *  appname)

Definition at line 491 of file option.c.

492 {
493  const char *p;
495 
497 
498  for (p = appname; *p != '\0'; p++)
499  {
500  if (*p != '%')
501  {
502  /* literal char, just copy */
504  continue;
505  }
506 
507  /* must be a '%', so skip to the next char */
508  p++;
509  if (*p == '\0')
510  break; /* format error - ignore it */
511  else if (*p == '%')
512  {
513  /* string contains %% */
514  appendStringInfoChar(&buf, '%');
515  continue;
516  }
517 
518  /* process the option */
519  switch (*p)
520  {
521  case 'a':
523  break;
524  case 'c':
525  appendStringInfo(&buf, "%lx.%x", (long) (MyStartTime), MyProcPid);
526  break;
527  case 'C':
529  break;
530  case 'd':
531  if (MyProcPort)
532  {
533  const char *dbname = MyProcPort->database_name;
534 
535  if (dbname)
537  else
538  appendStringInfoString(&buf, "[unknown]");
539  }
540  break;
541  case 'p':
542  appendStringInfo(&buf, "%d", MyProcPid);
543  break;
544  case 'u':
545  if (MyProcPort)
546  {
547  const char *username = MyProcPort->user_name;
548 
549  if (username)
551  else
552  appendStringInfoString(&buf, "[unknown]");
553  }
554  break;
555  default:
556  /* format error - ignore it */
557  break;
558  }
559  }
560 
561  return buf.data;
562 }
int MyProcPid
Definition: globals.c:45
struct Port * MyProcPort
Definition: globals.c:49
pg_time_t MyStartTime
Definition: globals.c:46
char * cluster_name
Definition: guc_tables.c:540
char * application_name
Definition: guc_tables.c:546
const char * username
Definition: pgbench.c:296
char * dbname
Definition: streamutil.c:52
char * user_name
Definition: libpq-be.h:152
char * database_name
Definition: libpq-be.h:151

References appendStringInfo(), appendStringInfoChar(), appendStringInfoString(), application_name, buf, cluster_name, Port::database_name, dbname, initStringInfo(), MyProcPid, MyProcPort, MyStartTime, Port::user_name, and username.

Referenced by connect_pg_server().

◆ rebuildInsertSql()

void rebuildInsertSql ( StringInfo  buf,
Relation  rel,
char *  orig_query,
List target_attrs,
int  values_end_len,
int  num_params,
int  num_rows 
)

Definition at line 2156 of file deparse.c.

2160 {
2161  TupleDesc tupdesc = RelationGetDescr(rel);
2162  int i;
2163  int pindex;
2164  bool first;
2165  ListCell *lc;
2166 
2167  /* Make sure the values_end_len is sensible */
2168  Assert((values_end_len > 0) && (values_end_len <= strlen(orig_query)));
2169 
2170  /* Copy up to the end of the first record from the original query */
2171  appendBinaryStringInfo(buf, orig_query, values_end_len);
2172 
2173  /*
2174  * Add records to VALUES clause (we already have parameters for the first
2175  * row, so start at the right offset).
2176  */
2177  pindex = num_params + 1;
2178  for (i = 0; i < num_rows; i++)
2179  {
2180  appendStringInfoString(buf, ", (");
2181 
2182  first = true;
2183  foreach(lc, target_attrs)
2184  {
2185  int attnum = lfirst_int(lc);
2186  Form_pg_attribute attr = TupleDescAttr(tupdesc, attnum - 1);
2187 
2188  if (!first)
2189  appendStringInfoString(buf, ", ");
2190  first = false;
2191 
2192  if (attr->attgenerated)
2193  appendStringInfoString(buf, "DEFAULT");
2194  else
2195  {
2196  appendStringInfo(buf, "$%d", pindex);
2197  pindex++;
2198  }
2199  }
2200 
2201  appendStringInfoChar(buf, ')');
2202  }
2203 
2204  /* Copy stuff after VALUES clause from the original query */
2205  appendStringInfoString(buf, orig_query + values_end_len);
2206 }
void appendBinaryStringInfo(StringInfo str, const void *data, int datalen)
Definition: stringinfo.c:233

References appendBinaryStringInfo(), appendStringInfo(), appendStringInfoChar(), appendStringInfoString(), Assert, attnum, buf, i, lfirst_int, RelationGetDescr, and TupleDescAttr.

Referenced by execute_foreign_modify().

◆ ReleaseConnection()

void ReleaseConnection ( PGconn conn)

Definition at line 785 of file connection.c.

786 {
787  /*
788  * Currently, we don't actually track connection references because all
789  * cleanup is managed on a transaction or subtransaction basis instead. So
790  * there's nothing to do here.
791  */
792 }

Referenced by estimate_path_cost_size(), finish_foreign_modify(), postgresAcquireSampleRowsFunc(), postgresAnalyzeForeignTable(), postgresEndDirectModify(), postgresEndForeignScan(), postgresGetAnalyzeInfoForForeignTable(), and postgresImportForeignSchema().

◆ reset_transmission_modes()

void reset_transmission_modes ( int  nestlevel)

Definition at line 3923 of file postgres_fdw.c.

3924 {
3925  AtEOXact_GUC(true, nestlevel);
3926 }
void AtEOXact_GUC(bool isCommit, int nestLevel)
Definition: guc.c:2264

References AtEOXact_GUC().

Referenced by appendConditions(), appendLimitClause(), appendOrderByClause(), convert_prep_stmt_params(), deparseDirectUpdateSql(), and process_query_params().

◆ set_transmission_modes()

int set_transmission_modes ( void  )

Definition at line 3887 of file postgres_fdw.c.

3888 {
3889  int nestlevel = NewGUCNestLevel();
3890 
3891  /*
3892  * The values set here should match what pg_dump does. See also
3893  * configure_remote_session in connection.c.
3894  */
3895  if (DateStyle != USE_ISO_DATES)
3896  (void) set_config_option("datestyle", "ISO",
3898  GUC_ACTION_SAVE, true, 0, false);
3900  (void) set_config_option("intervalstyle", "postgres",
3902  GUC_ACTION_SAVE, true, 0, false);
3903  if (extra_float_digits < 3)
3904  (void) set_config_option("extra_float_digits", "3",
3906  GUC_ACTION_SAVE, true, 0, false);
3907 
3908  /*
3909  * In addition force restrictive search_path, in case there are any
3910  * regproc or similar constants to be printed.
3911  */
3912  (void) set_config_option("search_path", "pg_catalog",
3914  GUC_ACTION_SAVE, true, 0, false);
3915 
3916  return nestlevel;
3917 }
int extra_float_digits
Definition: float.c:41
int DateStyle
Definition: globals.c:122
int IntervalStyle
Definition: globals.c:124
int NewGUCNestLevel(void)
Definition: guc.c:2237
int set_config_option(const char *name, const char *value, GucContext context, GucSource source, GucAction action, bool changeVal, int elevel, bool is_reload)
Definition: guc.c:3343
@ GUC_ACTION_SAVE
Definition: guc.h:201
@ PGC_S_SESSION
Definition: guc.h:122
@ PGC_USERSET
Definition: guc.h:75
#define USE_ISO_DATES
Definition: miscadmin.h:235
#define INTSTYLE_POSTGRES
Definition: miscadmin.h:255

References DateStyle, extra_float_digits, GUC_ACTION_SAVE, IntervalStyle, INTSTYLE_POSTGRES, NewGUCNestLevel(), PGC_S_SESSION, PGC_USERSET, set_config_option(), and USE_ISO_DATES.

Referenced by appendConditions(), appendLimitClause(), appendOrderByClause(), convert_prep_stmt_params(), deparseDirectUpdateSql(), and process_query_params().

Variable Documentation

◆ pgfdw_application_name

char* pgfdw_application_name
extern

Definition at line 52 of file option.c.

Referenced by _PG_init(), and connect_pg_server().