PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
postgres_fdw.h File Reference
#include "foreign/foreign.h"
#include "lib/stringinfo.h"
#include "nodes/relation.h"
#include "utils/relcache.h"
#include "libpq-fe.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
 

Typedefs

typedef struct PgFdwRelationInfo PgFdwRelationInfo
 

Functions

int set_transmission_modes (void)
 
void reset_transmission_modes (int nestlevel)
 
PGconnGetConnection (UserMapping *user, bool will_prep_stmt)
 
void ReleaseConnection (PGconn *conn)
 
unsigned int GetCursorNumber (PGconn *conn)
 
unsigned int GetPrepStmtNumber (PGconn *conn)
 
PGresultpgfdw_get_result (PGconn *conn, const char *query)
 
PGresultpgfdw_exec_query (PGconn *conn, const char *query)
 
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)
 
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)
 
void deparseInsertSql (StringInfo buf, PlannerInfo *root, Index rtindex, Relation rel, List *targetAttrs, bool doNothing, List *returningList, List **retrieved_attrs)
 
void deparseUpdateSql (StringInfo buf, PlannerInfo *root, Index rtindex, Relation rel, List *targetAttrs, List *returningList, List **retrieved_attrs)
 
void deparseDirectUpdateSql (StringInfo buf, PlannerInfo *root, Index rtindex, Relation rel, List *targetlist, List *targetAttrs, List *remote_conds, List **params_list, List *returningList, List **retrieved_attrs)
 
void deparseDeleteSql (StringInfo buf, PlannerInfo *root, Index rtindex, Relation rel, List *returningList, List **retrieved_attrs)
 
void deparseDirectDeleteSql (StringInfo buf, PlannerInfo *root, Index rtindex, Relation rel, List *remote_conds, List **params_list, List *returningList, List **retrieved_attrs)
 
void deparseAnalyzeSizeSql (StringInfo buf, Relation rel)
 
void deparseAnalyzeSql (StringInfo buf, Relation rel, List **retrieved_attrs)
 
void deparseStringLiteral (StringInfo buf, const char *val)
 
Exprfind_em_expr_for_rel (EquivalenceClass *ec, RelOptInfo *rel)
 
Listbuild_tlist_to_deparse (RelOptInfo *foreignrel)
 
void deparseSelectStmtForRel (StringInfo buf, PlannerInfo *root, RelOptInfo *foreignrel, List *tlist, List *remote_conds, List *pathkeys, bool is_subquery, List **retrieved_attrs, List **params_list)
 
bool is_builtin (Oid objectId)
 
bool is_shippable (Oid objectId, Oid classId, PgFdwRelationInfo *fpinfo)
 
const char * get_jointype_name (JoinType jointype)
 

Typedef Documentation

Function Documentation

List* build_tlist_to_deparse ( RelOptInfo foreignrel)

Definition at line 868 of file deparse.c.

References add_to_flat_tlist(), RestrictInfo::clause, PathTarget::exprs, RelOptInfo::fdw_private, PgFdwRelationInfo::grouped_tlist, 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().

869 {
870  List *tlist = NIL;
871  PgFdwRelationInfo *fpinfo = (PgFdwRelationInfo *) foreignrel->fdw_private;
872  ListCell *lc;
873 
874  /*
875  * For an upper relation, we have already built the target list while
876  * checking shippability, so just return that.
877  */
878  if (IS_UPPER_REL(foreignrel))
879  return fpinfo->grouped_tlist;
880 
881  /*
882  * We require columns specified in foreignrel->reltarget->exprs and those
883  * required for evaluating the local conditions.
884  */
885  tlist = add_to_flat_tlist(tlist,
886  pull_var_clause((Node *) foreignrel->reltarget->exprs,
888  foreach(lc, fpinfo->local_conds)
889  {
890  RestrictInfo *rinfo = lfirst_node(RestrictInfo, lc);
891 
892  tlist = add_to_flat_tlist(tlist,
893  pull_var_clause((Node *) rinfo->clause,
895  }
896 
897  return tlist;
898 }
#define NIL
Definition: pg_list.h:69
#define IS_UPPER_REL(rel)
Definition: relation.h:513
Definition: nodes.h:509
List * pull_var_clause(Node *node, int flags)
Definition: var.c:535
#define PVC_RECURSE_PLACEHOLDERS
Definition: var.h:26
#define lfirst_node(type, lc)
Definition: pg_list.h:109
Expr * clause
Definition: relation.h:1747
List * exprs
Definition: relation.h:883
void * fdw_private
Definition: relation.h:577
List * add_to_flat_tlist(List *tlist, List *exprs)
Definition: tlist.c:135
Definition: pg_list.h:45
struct PathTarget * reltarget
Definition: relation.h:536
void classifyConditions ( PlannerInfo root,
RelOptInfo baserel,
List input_conds,
List **  remote_conds,
List **  local_conds 
)

Definition at line 200 of file deparse.c.

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

Referenced by estimate_path_cost_size(), and postgresGetForeignRelSize().

205 {
206  ListCell *lc;
207 
208  *remote_conds = NIL;
209  *local_conds = NIL;
210 
211  foreach(lc, input_conds)
212  {
214 
215  if (is_foreign_expr(root, baserel, ri->clause))
216  *remote_conds = lappend(*remote_conds, ri);
217  else
218  *local_conds = lappend(*local_conds, ri);
219  }
220 }
#define NIL
Definition: pg_list.h:69
#define lfirst_node(type, lc)
Definition: pg_list.h:109
List * lappend(List *list, void *datum)
Definition: list.c:128
Expr * clause
Definition: relation.h:1747
bool is_foreign_expr(PlannerInfo *root, RelOptInfo *baserel, Expr *expr)
Definition: deparse.c:226
void deparseAnalyzeSizeSql ( StringInfo  buf,
Relation  rel 
)

Definition at line 1818 of file deparse.c.

References appendStringInfo(), appendStringInfoString(), StringInfoData::data, deparseRelation(), deparseStringLiteral(), and initStringInfo().

Referenced by postgresAnalyzeForeignTable().

1819 {
1820  StringInfoData relname;
1821 
1822  /* We'll need the remote relation name as a literal. */
1823  initStringInfo(&relname);
1824  deparseRelation(&relname, rel);
1825 
1826  appendStringInfoString(buf, "SELECT pg_catalog.pg_relation_size(");
1827  deparseStringLiteral(buf, relname.data);
1828  appendStringInfo(buf, "::pg_catalog.regclass) / %d", BLCKSZ);
1829 }
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:157
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
void deparseStringLiteral(StringInfo buf, const char *val)
Definition: deparse.c:2084
static void deparseRelation(StringInfo buf, Relation rel)
Definition: deparse.c:2044
void deparseAnalyzeSql ( StringInfo  buf,
Relation  rel,
List **  retrieved_attrs 
)

Definition at line 1838 of file deparse.c.

References appendStringInfoString(), tupleDesc::attrs, defGetString(), DefElem::defname, deparseRelation(), GetForeignColumnOptions(), i, lappend_int(), lfirst, NameStr, tupleDesc::natts, NIL, options, quote_identifier(), RelationGetDescr, and RelationGetRelid.

Referenced by postgresAcquireSampleRowsFunc().

1839 {
1840  Oid relid = RelationGetRelid(rel);
1841  TupleDesc tupdesc = RelationGetDescr(rel);
1842  int i;
1843  char *colname;
1844  List *options;
1845  ListCell *lc;
1846  bool first = true;
1847 
1848  *retrieved_attrs = NIL;
1849 
1850  appendStringInfoString(buf, "SELECT ");
1851  for (i = 0; i < tupdesc->natts; i++)
1852  {
1853  /* Ignore dropped columns. */
1854  if (tupdesc->attrs[i]->attisdropped)
1855  continue;
1856 
1857  if (!first)
1858  appendStringInfoString(buf, ", ");
1859  first = false;
1860 
1861  /* Use attribute name or column_name option. */
1862  colname = NameStr(tupdesc->attrs[i]->attname);
1863  options = GetForeignColumnOptions(relid, i + 1);
1864 
1865  foreach(lc, options)
1866  {
1867  DefElem *def = (DefElem *) lfirst(lc);
1868 
1869  if (strcmp(def->defname, "column_name") == 0)
1870  {
1871  colname = defGetString(def);
1872  break;
1873  }
1874  }
1875 
1877 
1878  *retrieved_attrs = lappend_int(*retrieved_attrs, i + 1);
1879  }
1880 
1881  /* Don't generate bad syntax for zero-column relation. */
1882  if (first)
1883  appendStringInfoString(buf, "NULL");
1884 
1885  /*
1886  * Construct FROM clause
1887  */
1888  appendStringInfoString(buf, " FROM ");
1889  deparseRelation(buf, rel);
1890 }
#define NIL
Definition: pg_list.h:69
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:10284
#define RelationGetDescr(relation)
Definition: rel.h:429
Form_pg_attribute * attrs
Definition: tupdesc.h:74
unsigned int Oid
Definition: postgres_ext.h:31
int natts
Definition: tupdesc.h:73
List * GetForeignColumnOptions(Oid relid, AttrNumber attnum)
Definition: foreign.c:254
char * defGetString(DefElem *def)
Definition: define.c:49
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:157
List * lappend_int(List *list, int datum)
Definition: list.c:146
static char ** options
static void deparseRelation(StringInfo buf, Relation rel)
Definition: deparse.c:2044
#define lfirst(lc)
Definition: pg_list.h:106
int i
#define NameStr(name)
Definition: c.h:499
char * defname
Definition: parsenodes.h:720
Definition: pg_list.h:45
#define RelationGetRelid(relation)
Definition: rel.h:417
void deparseDeleteSql ( StringInfo  buf,
PlannerInfo root,
Index  rtindex,
Relation  rel,
List returningList,
List **  retrieved_attrs 
)

Definition at line 1721 of file deparse.c.

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

Referenced by postgresPlanForeignModify().

1725 {
1726  appendStringInfoString(buf, "DELETE FROM ");
1727  deparseRelation(buf, rel);
1728  appendStringInfoString(buf, " WHERE ctid = $1");
1729 
1730  deparseReturningList(buf, root, rtindex, rel,
1731  rel->trigdesc && rel->trigdesc->trig_delete_after_row,
1732  returningList, retrieved_attrs);
1733 }
TriggerDesc * trigdesc
Definition: rel.h:120
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:157
bool trig_delete_after_row
Definition: reltrigger.h:66
static void deparseRelation(StringInfo buf, Relation rel)
Definition: deparse.c:2044
static void deparseReturningList(StringInfo buf, PlannerInfo *root, Index rtindex, Relation rel, bool trig_after_row, List *returningList, List **retrieved_attrs)
Definition: deparse.c:1777
void deparseDirectDeleteSql ( StringInfo  buf,
PlannerInfo root,
Index  rtindex,
Relation  rel,
List remote_conds,
List **  params_list,
List returningList,
List **  retrieved_attrs 
)

Definition at line 1743 of file deparse.c.

References appendConditions(), appendStringInfo(), appendStringInfoString(), buf, deparse_expr_cxt::buf, deparseRelation(), deparseReturningList(), deparse_expr_cxt::foreignrel, deparse_expr_cxt::params_list, deparse_expr_cxt::root, deparse_expr_cxt::scanrel, and PlannerInfo::simple_rel_array.

Referenced by postgresPlanDirectModify().

1749 {
1750  RelOptInfo *baserel = root->simple_rel_array[rtindex];
1751  deparse_expr_cxt context;
1752 
1753  /* Set up context struct for recursion */
1754  context.root = root;
1755  context.foreignrel = baserel;
1756  context.scanrel = baserel;
1757  context.buf = buf;
1758  context.params_list = params_list;
1759 
1760  appendStringInfoString(buf, "DELETE FROM ");
1761  deparseRelation(buf, rel);
1762 
1763  if (remote_conds)
1764  {
1765  appendStringInfo(buf, " WHERE ");
1766  appendConditions(remote_conds, &context);
1767  }
1768 
1769  deparseReturningList(buf, root, rtindex, rel, false,
1770  returningList, retrieved_attrs);
1771 }
List ** params_list
Definition: deparse.c:105
struct RelOptInfo ** simple_rel_array
Definition: relation.h:179
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:157
static char * buf
Definition: pg_test_fsync.c:66
static void appendConditions(List *exprs, deparse_expr_cxt *context)
Definition: deparse.c:1277
StringInfo buf
Definition: deparse.c:104
static void deparseRelation(StringInfo buf, Relation rel)
Definition: deparse.c:2044
PlannerInfo * root
Definition: deparse.c:99
static void deparseReturningList(StringInfo buf, PlannerInfo *root, Index rtindex, Relation rel, bool trig_after_row, List *returningList, List **retrieved_attrs)
Definition: deparse.c:1777
RelOptInfo * scanrel
Definition: deparse.c:101
RelOptInfo * foreignrel
Definition: deparse.c:100
void deparseDirectUpdateSql ( StringInfo  buf,
PlannerInfo root,
Index  rtindex,
Relation  rel,
List targetlist,
List targetAttrs,
List remote_conds,
List **  params_list,
List returningList,
List **  retrieved_attrs 
)

Definition at line 1653 of file deparse.c.

References appendConditions(), appendStringInfo(), appendStringInfoString(), buf, deparse_expr_cxt::buf, deparseColumnRef(), deparseExpr(), deparseRelation(), deparseReturningList(), elog, ERROR, TargetEntry::expr, deparse_expr_cxt::foreignrel, get_tle_by_resno(), lfirst_int, deparse_expr_cxt::params_list, reset_transmission_modes(), deparse_expr_cxt::root, deparse_expr_cxt::scanrel, set_transmission_modes(), and PlannerInfo::simple_rel_array.

Referenced by postgresPlanDirectModify().

1661 {
1662  RelOptInfo *baserel = root->simple_rel_array[rtindex];
1663  deparse_expr_cxt context;
1664  int nestlevel;
1665  bool first;
1666  ListCell *lc;
1667 
1668  /* Set up context struct for recursion */
1669  context.root = root;
1670  context.foreignrel = baserel;
1671  context.scanrel = baserel;
1672  context.buf = buf;
1673  context.params_list = params_list;
1674 
1675  appendStringInfoString(buf, "UPDATE ");
1676  deparseRelation(buf, rel);
1677  appendStringInfoString(buf, " SET ");
1678 
1679  /* Make sure any constants in the exprs are printed portably */
1680  nestlevel = set_transmission_modes();
1681 
1682  first = true;
1683  foreach(lc, targetAttrs)
1684  {
1685  int attnum = lfirst_int(lc);
1686  TargetEntry *tle = get_tle_by_resno(targetlist, attnum);
1687 
1688  if (!tle)
1689  elog(ERROR, "attribute number %d not found in UPDATE targetlist",
1690  attnum);
1691 
1692  if (!first)
1693  appendStringInfoString(buf, ", ");
1694  first = false;
1695 
1696  deparseColumnRef(buf, rtindex, attnum, root, false);
1697  appendStringInfoString(buf, " = ");
1698  deparseExpr((Expr *) tle->expr, &context);
1699  }
1700 
1701  reset_transmission_modes(nestlevel);
1702 
1703  if (remote_conds)
1704  {
1705  appendStringInfo(buf, " WHERE ");
1706  appendConditions(remote_conds, &context);
1707  }
1708 
1709  deparseReturningList(buf, root, rtindex, rel, false,
1710  returningList, retrieved_attrs);
1711 }
List ** params_list
Definition: deparse.c:105
int set_transmission_modes(void)
static void deparseColumnRef(StringInfo buf, int varno, int varattno, PlannerInfo *root, bool qualify_col)
Definition: deparse.c:1899
struct RelOptInfo ** simple_rel_array
Definition: relation.h:179
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
#define ERROR
Definition: elog.h:43
#define lfirst_int(lc)
Definition: pg_list.h:107
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:157
static char * buf
Definition: pg_test_fsync.c:66
static void appendConditions(List *exprs, deparse_expr_cxt *context)
Definition: deparse.c:1277
StringInfo buf
Definition: deparse.c:104
static void deparseRelation(StringInfo buf, Relation rel)
Definition: deparse.c:2044
PlannerInfo * root
Definition: deparse.c:99
Expr * expr
Definition: primnodes.h:1367
void reset_transmission_modes(int nestlevel)
static void deparseExpr(Expr *expr, deparse_expr_cxt *context)
Definition: deparse.c:2119
TargetEntry * get_tle_by_resno(List *tlist, AttrNumber resno)
static void deparseReturningList(StringInfo buf, PlannerInfo *root, Index rtindex, Relation rel, bool trig_after_row, List *returningList, List **retrieved_attrs)
Definition: deparse.c:1777
#define elog
Definition: elog.h:219
RelOptInfo * scanrel
Definition: deparse.c:101
RelOptInfo * foreignrel
Definition: deparse.c:100
void deparseInsertSql ( StringInfo  buf,
PlannerInfo root,
Index  rtindex,
Relation  rel,
List targetAttrs,
bool  doNothing,
List returningList,
List **  retrieved_attrs 
)

Definition at line 1548 of file deparse.c.

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

Referenced by postgresPlanForeignModify().

1552 {
1553  AttrNumber pindex;
1554  bool first;
1555  ListCell *lc;
1556 
1557  appendStringInfoString(buf, "INSERT INTO ");
1558  deparseRelation(buf, rel);
1559 
1560  if (targetAttrs)
1561  {
1562  appendStringInfoChar(buf, '(');
1563 
1564  first = true;
1565  foreach(lc, targetAttrs)
1566  {
1567  int attnum = lfirst_int(lc);
1568 
1569  if (!first)
1570  appendStringInfoString(buf, ", ");
1571  first = false;
1572 
1573  deparseColumnRef(buf, rtindex, attnum, root, false);
1574  }
1575 
1576  appendStringInfoString(buf, ") VALUES (");
1577 
1578  pindex = 1;
1579  first = true;
1580  foreach(lc, targetAttrs)
1581  {
1582  if (!first)
1583  appendStringInfoString(buf, ", ");
1584  first = false;
1585 
1586  appendStringInfo(buf, "$%d", pindex);
1587  pindex++;
1588  }
1589 
1590  appendStringInfoChar(buf, ')');
1591  }
1592  else
1593  appendStringInfoString(buf, " DEFAULT VALUES");
1594 
1595  if (doNothing)
1596  appendStringInfoString(buf, " ON CONFLICT DO NOTHING");
1597 
1598  deparseReturningList(buf, root, rtindex, rel,
1599  rel->trigdesc && rel->trigdesc->trig_insert_after_row,
1600  returningList, retrieved_attrs);
1601 }
static void deparseColumnRef(StringInfo buf, int varno, int varattno, PlannerInfo *root, bool qualify_col)
Definition: deparse.c:1899
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
#define lfirst_int(lc)
Definition: pg_list.h:107
TriggerDesc * trigdesc
Definition: rel.h:120
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:157
bool trig_insert_after_row
Definition: reltrigger.h:56
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:169
static void deparseRelation(StringInfo buf, Relation rel)
Definition: deparse.c:2044
static void deparseReturningList(StringInfo buf, PlannerInfo *root, Index rtindex, Relation rel, bool trig_after_row, List *returningList, List **retrieved_attrs)
Definition: deparse.c:1777
int16 AttrNumber
Definition: attnum.h:21
void deparseSelectStmtForRel ( StringInfo  buf,
PlannerInfo root,
RelOptInfo foreignrel,
List tlist,
List remote_conds,
List pathkeys,
bool  is_subquery,
List **  retrieved_attrs,
List **  params_list 
)

Definition at line 925 of file deparse.c.

References appendConditions(), appendGroupByClause(), appendOrderByClause(), appendStringInfo(), Assert, buf, deparse_expr_cxt::buf, deparseFromExpr(), deparseLockingClause(), deparseSelectSql(), RelOptInfo::fdw_private, deparse_expr_cxt::foreignrel, IS_JOIN_REL, IS_SIMPLE_REL, IS_UPPER_REL, PgFdwRelationInfo::outerrel, deparse_expr_cxt::params_list, PgFdwRelationInfo::remote_conds, deparse_expr_cxt::root, and deparse_expr_cxt::scanrel.

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

929 {
930  deparse_expr_cxt context;
931  PgFdwRelationInfo *fpinfo = (PgFdwRelationInfo *) rel->fdw_private;
932  List *quals;
933 
934  /*
935  * We handle relations for foreign tables, joins between those and upper
936  * relations.
937  */
938  Assert(IS_JOIN_REL(rel) || IS_SIMPLE_REL(rel) || IS_UPPER_REL(rel));
939 
940  /* Fill portions of context common to upper, join and base relation */
941  context.buf = buf;
942  context.root = root;
943  context.foreignrel = rel;
944  context.scanrel = IS_UPPER_REL(rel) ? fpinfo->outerrel : rel;
945  context.params_list = params_list;
946 
947  /* Construct SELECT clause */
948  deparseSelectSql(tlist, is_subquery, retrieved_attrs, &context);
949 
950  /*
951  * For upper relations, the WHERE clause is built from the remote
952  * conditions of the underlying scan relation; otherwise, we can use the
953  * supplied list of remote conditions directly.
954  */
955  if (IS_UPPER_REL(rel))
956  {
957  PgFdwRelationInfo *ofpinfo;
958 
959  ofpinfo = (PgFdwRelationInfo *) fpinfo->outerrel->fdw_private;
960  quals = ofpinfo->remote_conds;
961  }
962  else
963  quals = remote_conds;
964 
965  /* Construct FROM and WHERE clauses */
966  deparseFromExpr(quals, &context);
967 
968  if (IS_UPPER_REL(rel))
969  {
970  /* Append GROUP BY clause */
971  appendGroupByClause(tlist, &context);
972 
973  /* Append HAVING clause */
974  if (remote_conds)
975  {
976  appendStringInfo(buf, " HAVING ");
977  appendConditions(remote_conds, &context);
978  }
979  }
980 
981  /* Add ORDER BY clause if we found any useful pathkeys */
982  if (pathkeys)
983  appendOrderByClause(pathkeys, &context);
984 
985  /* Add any necessary FOR UPDATE/SHARE. */
986  deparseLockingClause(&context);
987 }
static void appendGroupByClause(List *tlist, deparse_expr_cxt *context)
Definition: deparse.c:2936
List ** params_list
Definition: deparse.c:105
#define IS_UPPER_REL(rel)
Definition: relation.h:513
#define IS_JOIN_REL(rel)
Definition: relation.h:510
RelOptInfo * outerrel
Definition: postgres_fdw.h:89
#define IS_SIMPLE_REL(rel)
Definition: relation.h:505
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
static void appendOrderByClause(List *pathkeys, deparse_expr_cxt *context)
Definition: deparse.c:2973
static char * buf
Definition: pg_test_fsync.c:66
static void deparseSelectSql(List *tlist, bool is_subquery, List **retrieved_attrs, deparse_expr_cxt *context)
Definition: deparse.c:1003
static void appendConditions(List *exprs, deparse_expr_cxt *context)
Definition: deparse.c:1277
StringInfo buf
Definition: deparse.c:104
void * fdw_private
Definition: relation.h:577
PlannerInfo * root
Definition: deparse.c:99
#define Assert(condition)
Definition: c.h:675
static void deparseFromExpr(List *quals, deparse_expr_cxt *context)
Definition: deparse.c:1061
static void deparseLockingClause(deparse_expr_cxt *context)
Definition: deparse.c:1187
RelOptInfo * scanrel
Definition: deparse.c:101
Definition: pg_list.h:45
RelOptInfo * foreignrel
Definition: deparse.c:100
void deparseStringLiteral ( StringInfo  buf,
const char *  val 
)

Definition at line 2084 of file deparse.c.

References appendStringInfoChar(), ESCAPE_STRING_SYNTAX, NULL, and SQL_STR_DOUBLE.

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

2085 {
2086  const char *valptr;
2087 
2088  /*
2089  * Rather than making assumptions about the remote server's value of
2090  * standard_conforming_strings, always use E'foo' syntax if there are any
2091  * backslashes. This will fail on remote servers before 8.1, but those
2092  * are long out of support.
2093  */
2094  if (strchr(val, '\\') != NULL)
2096  appendStringInfoChar(buf, '\'');
2097  for (valptr = val; *valptr; valptr++)
2098  {
2099  char ch = *valptr;
2100 
2101  if (SQL_STR_DOUBLE(ch, true))
2102  appendStringInfoChar(buf, ch);
2103  appendStringInfoChar(buf, ch);
2104  }
2105  appendStringInfoChar(buf, '\'');
2106 }
#define ESCAPE_STRING_SYNTAX
Definition: c.h:510
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:169
#define NULL
Definition: c.h:229
#define SQL_STR_DOUBLE(ch, escape_backslash)
Definition: c.h:507
long val
Definition: informix.c:689
void deparseUpdateSql ( StringInfo  buf,
PlannerInfo root,
Index  rtindex,
Relation  rel,
List targetAttrs,
List returningList,
List **  retrieved_attrs 
)

Definition at line 1611 of file deparse.c.

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

Referenced by postgresPlanForeignModify().

1615 {
1616  AttrNumber pindex;
1617  bool first;
1618  ListCell *lc;
1619 
1620  appendStringInfoString(buf, "UPDATE ");
1621  deparseRelation(buf, rel);
1622  appendStringInfoString(buf, " SET ");
1623 
1624  pindex = 2; /* ctid is always the first param */
1625  first = true;
1626  foreach(lc, targetAttrs)
1627  {
1628  int attnum = lfirst_int(lc);
1629 
1630  if (!first)
1631  appendStringInfoString(buf, ", ");
1632  first = false;
1633 
1634  deparseColumnRef(buf, rtindex, attnum, root, false);
1635  appendStringInfo(buf, " = $%d", pindex);
1636  pindex++;
1637  }
1638  appendStringInfoString(buf, " WHERE ctid = $1");
1639 
1640  deparseReturningList(buf, root, rtindex, rel,
1641  rel->trigdesc && rel->trigdesc->trig_update_after_row,
1642  returningList, retrieved_attrs);
1643 }
static void deparseColumnRef(StringInfo buf, int varno, int varattno, PlannerInfo *root, bool qualify_col)
Definition: deparse.c:1899
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
#define lfirst_int(lc)
Definition: pg_list.h:107
TriggerDesc * trigdesc
Definition: rel.h:120
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:157
bool trig_update_after_row
Definition: reltrigger.h:61
static void deparseRelation(StringInfo buf, Relation rel)
Definition: deparse.c:2044
static void deparseReturningList(StringInfo buf, PlannerInfo *root, Index rtindex, Relation rel, bool trig_after_row, List *returningList, List **retrieved_attrs)
Definition: deparse.c:1777
int16 AttrNumber
Definition: attnum.h:21
int ExtractConnectionOptions ( List defelems,
const char **  keywords,
const char **  values 
)

Definition at line 297 of file option.c.

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

Referenced by connect_pg_server().

299 {
300  ListCell *lc;
301  int i;
302 
303  /* Build our options lists if we didn't yet. */
305 
306  i = 0;
307  foreach(lc, defelems)
308  {
309  DefElem *d = (DefElem *) lfirst(lc);
310 
311  if (is_libpq_option(d->defname))
312  {
313  keywords[i] = d->defname;
314  values[i] = defGetString(d);
315  i++;
316  }
317  }
318  return i;
319 }
char * defGetString(DefElem *def)
Definition: define.c:49
#define lfirst(lc)
Definition: pg_list.h:106
static Datum values[MAXATTR]
Definition: bootstrap.c:163
int i
static bool is_libpq_option(const char *keyword)
Definition: option.c:276
char * defname
Definition: parsenodes.h:720
static void InitPgFdwOptions(void)
Definition: option.c:155
List* ExtractExtensionList ( const char *  extensionsString,
bool  warnOnMissing 
)

Definition at line 328 of file option.c.

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().

329 {
330  List *extensionOids = NIL;
331  List *extlist;
332  ListCell *lc;
333 
334  /* SplitIdentifierString scribbles on its input, so pstrdup first */
335  if (!SplitIdentifierString(pstrdup(extensionsString), ',', &extlist))
336  {
337  /* syntax error in name list */
338  ereport(ERROR,
339  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
340  errmsg("parameter \"%s\" must be a list of extension names",
341  "extensions")));
342  }
343 
344  foreach(lc, extlist)
345  {
346  const char *extension_name = (const char *) lfirst(lc);
347  Oid extension_oid = get_extension_oid(extension_name, true);
348 
349  if (OidIsValid(extension_oid))
350  {
351  extensionOids = lappend_oid(extensionOids, extension_oid);
352  }
353  else if (warnOnMissing)
354  {
356  (errcode(ERRCODE_UNDEFINED_OBJECT),
357  errmsg("extension \"%s\" is not installed",
358  extension_name)));
359  }
360  }
361 
362  list_free(extlist);
363  return extensionOids;
364 }
#define NIL
Definition: pg_list.h:69
char * pstrdup(const char *in)
Definition: mcxt.c:1077
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
List * lappend_oid(List *list, Oid datum)
Definition: list.c:164
#define OidIsValid(objectId)
Definition: c.h:538
#define ERROR
Definition: elog.h:43
bool SplitIdentifierString(char *rawstring, char separator, List **namelist)
Definition: varlena.c:3247
#define ereport(elevel, rest)
Definition: elog.h:122
#define WARNING
Definition: elog.h:40
#define lfirst(lc)
Definition: pg_list.h:106
Oid get_extension_oid(const char *extname, bool missing_ok)
Definition: extension.c:134
int errmsg(const char *fmt,...)
Definition: elog.c:797
void list_free(List *list)
Definition: list.c:1133
Definition: pg_list.h:45
Expr* find_em_expr_for_rel ( EquivalenceClass ec,
RelOptInfo rel 
)

Definition at line 5153 of file postgres_fdw.c.

References bms_is_subset(), EquivalenceClass::ec_members, EquivalenceMember::em_expr, EquivalenceMember::em_relids, lfirst, NULL, and RelOptInfo::relids.

Referenced by appendOrderByClause(), and get_useful_pathkeys_for_relation().

5154 {
5155  ListCell *lc_em;
5156 
5157  foreach(lc_em, ec->ec_members)
5158  {
5159  EquivalenceMember *em = lfirst(lc_em);
5160 
5161  if (bms_is_subset(em->em_relids, rel->relids))
5162  {
5163  /*
5164  * If there is more than one equivalence member whose Vars are
5165  * taken entirely from this relation, we'll be content to choose
5166  * any one of those.
5167  */
5168  return em->em_expr;
5169  }
5170  }
5171 
5172  /* We didn't find any suitable equivalence class expression */
5173  return NULL;
5174 }
bool bms_is_subset(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:308
Relids relids
Definition: relation.h:525
Relids em_relids
Definition: relation.h:822
#define NULL
Definition: c.h:229
#define lfirst(lc)
Definition: pg_list.h:106
List * ec_members
Definition: relation.h:773
const char* get_jointype_name ( JoinType  jointype)

Definition at line 1311 of file deparse.c.

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

Referenced by deparseFromExprForRel(), and foreign_join_ok().

1312 {
1313  switch (jointype)
1314  {
1315  case JOIN_INNER:
1316  return "INNER";
1317 
1318  case JOIN_LEFT:
1319  return "LEFT";
1320 
1321  case JOIN_RIGHT:
1322  return "RIGHT";
1323 
1324  case JOIN_FULL:
1325  return "FULL";
1326 
1327  default:
1328  /* Shouldn't come here, but protect from buggy code. */
1329  elog(ERROR, "unsupported join type %d", jointype);
1330  }
1331 
1332  /* Keep compiler happy */
1333  return NULL;
1334 }
#define ERROR
Definition: elog.h:43
#define NULL
Definition: c.h:229
#define elog
Definition: elog.h:219
PGconn* GetConnection ( UserMapping user,
bool  will_prep_stmt 
)

Definition at line 97 of file connection.c.

References begin_remote_xact(), CacheMemoryContext, ConnCacheEntry::conn, connect_pg_server(), DEBUG3, elog, HASHCTL::entrysize, GetForeignServer(), HASH_BLOBS, HASH_CONTEXT, hash_create(), HASH_ELEM, HASH_ENTER, hash_search(), ConnCacheEntry::have_error, ConnCacheEntry::have_prep_stmt, HASHCTL::hcxt, HASHCTL::keysize, MemSet, NULL, pgfdw_subxact_callback(), pgfdw_xact_callback(), RegisterSubXactCallback(), RegisterXactCallback(), UserMapping::serverid, ForeignServer::servername, UserMapping::umid, UserMapping::userid, ConnCacheEntry::xact_depth, and xact_got_connection.

Referenced by dumpBlobs(), dumpDatabase(), dumpTableData_copy(), estimate_path_cost_size(), expand_schema_name_patterns(), expand_table_name_patterns(), getTables(), main(), postgresAcquireSampleRowsFunc(), postgresAnalyzeForeignTable(), postgresBeginDirectModify(), postgresBeginForeignModify(), postgresBeginForeignScan(), postgresImportForeignSchema(), setup_connection(), StartLogStreamer(), StreamLog(), and StreamLogicalLog().

98 {
99  bool found;
100  ConnCacheEntry *entry;
101  ConnCacheKey key;
102 
103  /* First time through, initialize connection cache hashtable */
104  if (ConnectionHash == NULL)
105  {
106  HASHCTL ctl;
107 
108  MemSet(&ctl, 0, sizeof(ctl));
109  ctl.keysize = sizeof(ConnCacheKey);
110  ctl.entrysize = sizeof(ConnCacheEntry);
111  /* allocate ConnectionHash in the cache context */
112  ctl.hcxt = CacheMemoryContext;
113  ConnectionHash = hash_create("postgres_fdw connections", 8,
114  &ctl,
116 
117  /*
118  * Register some callback functions that manage connection cleanup.
119  * This should be done just once in each backend.
120  */
123  }
124 
125  /* Set flag that we did GetConnection during the current transaction */
126  xact_got_connection = true;
127 
128  /* Create hash key for the entry. Assume no pad bytes in key struct */
129  key = user->umid;
130 
131  /*
132  * Find or create cached entry for requested connection.
133  */
134  entry = hash_search(ConnectionHash, &key, HASH_ENTER, &found);
135  if (!found)
136  {
137  /* initialize new hashtable entry (key is already filled in) */
138  entry->conn = NULL;
139  entry->xact_depth = 0;
140  entry->have_prep_stmt = false;
141  entry->have_error = false;
142  }
143 
144  /*
145  * We don't check the health of cached connection here, because it would
146  * require some overhead. Broken connection will be detected when the
147  * connection is actually used.
148  */
149 
150  /*
151  * If cache entry doesn't have a connection, we have to establish a new
152  * connection. (If connect_pg_server throws an error, the cache entry
153  * will be left in a valid empty state.)
154  */
155  if (entry->conn == NULL)
156  {
157  ForeignServer *server = GetForeignServer(user->serverid);
158 
159  entry->xact_depth = 0; /* just to be sure */
160  entry->have_prep_stmt = false;
161  entry->have_error = false;
162  entry->conn = connect_pg_server(server, user);
163 
164  elog(DEBUG3, "new postgres_fdw connection %p for server \"%s\" (user mapping oid %u, userid %u)",
165  entry->conn, server->servername, user->umid, user->userid);
166  }
167 
168  /*
169  * Start a new transaction or subtransaction if needed.
170  */
171  begin_remote_xact(entry);
172 
173  /* Remember if caller will prepare statements */
174  entry->have_prep_stmt |= will_prep_stmt;
175 
176  return entry->conn;
177 }
Oid umid
Definition: foreign.h:58
#define HASH_CONTEXT
Definition: hsearch.h:93
#define HASH_ELEM
Definition: hsearch.h:87
MemoryContext hcxt
Definition: hsearch.h:78
#define DEBUG3
Definition: elog.h:23
struct ConnCacheEntry ConnCacheEntry
Size entrysize
Definition: hsearch.h:73
#define MemSet(start, val, len)
Definition: c.h:857
bool have_prep_stmt
Definition: connection.c:50
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:885
Oid userid
Definition: foreign.h:59
#define HASH_BLOBS
Definition: hsearch.h:88
static void pgfdw_xact_callback(XactEvent event, void *arg)
Definition: connection.c:582
static HTAB * ConnectionHash
Definition: connection.c:57
ForeignServer * GetForeignServer(Oid serverid)
Definition: foreign.c:93
HTAB * hash_create(const char *tabname, long nelem, HASHCTL *info, int flags)
Definition: dynahash.c:301
void RegisterSubXactCallback(SubXactCallback callback, void *arg)
Definition: xact.c:3362
Size keysize
Definition: hsearch.h:72
PGconn * conn
Definition: connection.c:47
#define NULL
Definition: c.h:229
void RegisterXactCallback(XactCallback callback, void *arg)
Definition: xact.c:3307
static bool xact_got_connection
Definition: connection.c:64
Oid serverid
Definition: foreign.h:60
char * servername
Definition: foreign.h:50
#define elog
Definition: elog.h:219
static void pgfdw_subxact_callback(SubXactEvent event, SubTransactionId mySubid, SubTransactionId parentSubid, void *arg)
Definition: connection.c:742
static void begin_remote_xact(ConnCacheEntry *entry)
Definition: connection.c:363
Oid ConnCacheKey
Definition: connection.c:42
MemoryContext CacheMemoryContext
Definition: mcxt.c:46
static PGconn * connect_pg_server(ForeignServer *server, UserMapping *user)
Definition: connection.c:183
unsigned int GetCursorNumber ( PGconn conn)

Definition at line 423 of file connection.c.

References cursor_number.

Referenced by postgresAcquireSampleRowsFunc(), and postgresBeginForeignScan().

424 {
425  return ++cursor_number;
426 }
static unsigned int cursor_number
Definition: connection.c:60
unsigned int GetPrepStmtNumber ( PGconn conn)

Definition at line 437 of file connection.c.

References prep_stmt_number.

Referenced by prepare_foreign_modify().

438 {
439  return ++prep_stmt_number;
440 }
static unsigned int prep_stmt_number
Definition: connection.c:61
bool is_builtin ( Oid  objectId)

Definition at line 155 of file shippable.c.

References FirstBootstrapObjectId.

Referenced by deparse_type_name(), and is_shippable().

156 {
157  return (objectId < FirstBootstrapObjectId);
158 }
#define FirstBootstrapObjectId
Definition: transam.h:93
bool is_foreign_expr ( PlannerInfo root,
RelOptInfo baserel,
Expr expr 
)

Definition at line 226 of file deparse.c.

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

Referenced by classifyConditions(), foreign_grouping_ok(), foreign_join_ok(), get_useful_pathkeys_for_relation(), postgresGetForeignPaths(), postgresGetForeignPlan(), and postgresPlanDirectModify().

229 {
230  foreign_glob_cxt glob_cxt;
231  foreign_loc_cxt loc_cxt;
232  PgFdwRelationInfo *fpinfo = (PgFdwRelationInfo *) (baserel->fdw_private);
233 
234  /*
235  * Check that the expression consists of nodes that are safe to execute
236  * remotely.
237  */
238  glob_cxt.root = root;
239  glob_cxt.foreignrel = baserel;
240 
241  /*
242  * For an upper relation, use relids from its underneath scan relation,
243  * because the upperrel's own relids currently aren't set to anything
244  * meaningful by the core code. For other relation, use their own relids.
245  */
246  if (IS_UPPER_REL(baserel))
247  glob_cxt.relids = fpinfo->outerrel->relids;
248  else
249  glob_cxt.relids = baserel->relids;
250  loc_cxt.collation = InvalidOid;
251  loc_cxt.state = FDW_COLLATE_NONE;
252  if (!foreign_expr_walker((Node *) expr, &glob_cxt, &loc_cxt))
253  return false;
254 
255  /*
256  * If the expression has a valid collation that does not arise from a
257  * foreign var, the expression can not be sent over.
258  */
259  if (loc_cxt.state == FDW_COLLATE_UNSAFE)
260  return false;
261 
262  /*
263  * An expression which includes any mutable functions can't be sent over
264  * because its result is not stable. For example, sending now() remote
265  * side could cause confusion from clock offsets. Future versions might
266  * be able to make this choice with more granularity. (We check this last
267  * because it requires a lot of expensive catalog lookups.)
268  */
269  if (contain_mutable_functions((Node *) expr))
270  return false;
271 
272  /* OK to evaluate on the remote server */
273  return true;
274 }
FDWCollateState state
Definition: deparse.c:91
#define IS_UPPER_REL(rel)
Definition: relation.h:513
Definition: nodes.h:509
RelOptInfo * outerrel
Definition: postgres_fdw.h:89
Relids relids
Definition: deparse.c:70
PlannerInfo * root
Definition: deparse.c:68
RelOptInfo * foreignrel
Definition: deparse.c:69
Relids relids
Definition: relation.h:525
static bool foreign_expr_walker(Node *node, foreign_glob_cxt *glob_cxt, foreign_loc_cxt *outer_cxt)
Definition: deparse.c:290
#define InvalidOid
Definition: postgres_ext.h:36
void * fdw_private
Definition: relation.h:577
bool contain_mutable_functions(Node *clause)
Definition: clauses.c:878
bool is_shippable ( Oid  objectId,
Oid  classId,
PgFdwRelationInfo fpinfo 
)

Definition at line 165 of file shippable.c.

References ShippableCacheKey::classid, HASH_ENTER, HASH_FIND, hash_search(), InitializeShippableCache(), is_builtin(), lookup_shippable(), NIL, NULL, ShippableCacheKey::objid, PgFdwRelationInfo::server, ForeignServer::serverid, ShippableCacheKey::serverid, ShippableCacheEntry::shippable, and PgFdwRelationInfo::shippable_extensions.

Referenced by foreign_expr_walker().

166 {
167  ShippableCacheKey key;
168  ShippableCacheEntry *entry;
169 
170  /* Built-in objects are presumed shippable. */
171  if (is_builtin(objectId))
172  return true;
173 
174  /* Otherwise, give up if user hasn't specified any shippable extensions. */
175  if (fpinfo->shippable_extensions == NIL)
176  return false;
177 
178  /* Initialize cache if first time through. */
179  if (!ShippableCacheHash)
181 
182  /* Set up cache hash key */
183  key.objid = objectId;
184  key.classid = classId;
185  key.serverid = fpinfo->server->serverid;
186 
187  /* See if we already cached the result. */
188  entry = (ShippableCacheEntry *)
190  (void *) &key,
191  HASH_FIND,
192  NULL);
193 
194  if (!entry)
195  {
196  /* Not found in cache, so perform shippability lookup. */
197  bool shippable = lookup_shippable(objectId, classId, fpinfo);
198 
199  /*
200  * Don't create a new hash entry until *after* we have the shippable
201  * result in hand, as the underlying catalog lookups might trigger a
202  * cache invalidation.
203  */
204  entry = (ShippableCacheEntry *)
206  (void *) &key,
207  HASH_ENTER,
208  NULL);
209 
210  entry->shippable = shippable;
211  }
212 
213  return entry->shippable;
214 }
#define NIL
Definition: pg_list.h:69
bool is_builtin(Oid objectId)
Definition: shippable.c:155
ForeignServer * server
Definition: postgres_fdw.h:76
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:885
static void InitializeShippableCache(void)
Definition: shippable.c:93
static bool lookup_shippable(Oid objectId, Oid classId, PgFdwRelationInfo *fpinfo)
Definition: shippable.c:119
#define NULL
Definition: c.h:229
static HTAB * ShippableCacheHash
Definition: shippable.c:36
List * shippable_extensions
Definition: postgres_fdw.h:72
Oid serverid
Definition: foreign.h:47
PGresult* pgfdw_exec_query ( PGconn conn,
const char *  query 
)

Definition at line 450 of file connection.c.

References ERROR, NULL, pgfdw_get_result(), pgfdw_report_error(), and PQsendQuery().

Referenced by close_cursor(), fetch_more_data(), get_remote_estimate(), postgresAcquireSampleRowsFunc(), postgresAnalyzeForeignTable(), postgresEndForeignModify(), postgresImportForeignSchema(), and postgresReScanForeignScan().

451 {
452  /*
453  * Submit a query. Since we don't use non-blocking mode, this also can
454  * block. But its risk is relatively small, so we ignore that for now.
455  */
456  if (!PQsendQuery(conn, query))
457  pgfdw_report_error(ERROR, NULL, conn, false, query);
458 
459  /* Wait for the result. */
460  return pgfdw_get_result(conn, query);
461 }
int PQsendQuery(PGconn *conn, const char *query)
Definition: fe-exec.c:1132
#define ERROR
Definition: elog.h:43
void pgfdw_report_error(int elevel, PGresult *res, PGconn *conn, bool clear, const char *sql)
Definition: connection.c:528
PGresult * pgfdw_get_result(PGconn *conn, const char *query)
Definition: connection.c:474
#define NULL
Definition: c.h:229
PGresult* pgfdw_get_result ( PGconn conn,
const char *  query 
)

Definition at line 474 of file connection.c.

References CHECK_FOR_INTERRUPTS, ERROR, MyLatch, NULL, PG_WAIT_EXTENSION, pgfdw_report_error(), PQclear(), PQconsumeInput(), PQgetResult(), PQisBusy(), PQsocket(), ResetLatch(), WaitLatchOrSocket(), WL_LATCH_SET, and WL_SOCKET_READABLE.

Referenced by create_cursor(), execute_dml_stmt(), pgfdw_exec_query(), postgresExecForeignDelete(), postgresExecForeignInsert(), postgresExecForeignUpdate(), and prepare_foreign_modify().

475 {
476  PGresult *last_res = NULL;
477 
478  for (;;)
479  {
480  PGresult *res;
481 
482  while (PQisBusy(conn))
483  {
484  int wc;
485 
486  /* Sleep until there's something to do */
489  PQsocket(conn),
490  -1L, PG_WAIT_EXTENSION);
492 
494 
495  /* Data available in socket */
496  if (wc & WL_SOCKET_READABLE)
497  {
498  if (!PQconsumeInput(conn))
499  pgfdw_report_error(ERROR, NULL, conn, false, query);
500  }
501  }
502 
503  res = PQgetResult(conn);
504  if (res == NULL)
505  break; /* query is complete */
506 
507  PQclear(last_res);
508  last_res = res;
509  }
510 
511  return last_res;
512 }
#define WL_SOCKET_READABLE
Definition: latch.h:125
void ResetLatch(volatile Latch *latch)
Definition: latch.c:498
#define ERROR
Definition: elog.h:43
void pgfdw_report_error(int elevel, PGresult *res, PGconn *conn, bool clear, const char *sql)
Definition: connection.c:528
#define PG_WAIT_EXTENSION
Definition: pgstat.h:742
int PQconsumeInput(PGconn *conn)
Definition: fe-exec.c:1631
void PQclear(PGresult *res)
Definition: fe-exec.c:650
#define NULL
Definition: c.h:229
int WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock, long timeout, uint32 wait_event_info)
Definition: latch.c:356
int PQisBusy(PGconn *conn)
Definition: fe-exec.c:1681
struct Latch * MyLatch
Definition: globals.c:51
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:97
#define WL_LATCH_SET
Definition: latch.h:124
int PQsocket(const PGconn *conn)
Definition: fe-connect.c:6006
PGresult * PQgetResult(PGconn *conn)
Definition: fe-exec.c:1702
void pgfdw_report_error ( int  elevel,
PGresult res,
PGconn conn,
bool  clear,
const char *  sql 
)

Definition at line 528 of file connection.c.

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

Referenced by close_cursor(), create_cursor(), do_sql_command(), execute_dml_stmt(), fetch_more_data(), get_remote_estimate(), pgfdw_exec_query(), pgfdw_get_result(), pgfdw_subxact_callback(), pgfdw_xact_callback(), postgresAcquireSampleRowsFunc(), postgresAnalyzeForeignTable(), postgresEndForeignModify(), postgresExecForeignDelete(), postgresExecForeignInsert(), postgresExecForeignUpdate(), postgresImportForeignSchema(), postgresReScanForeignScan(), and prepare_foreign_modify().

530 {
531  /* If requested, PGresult must be released before leaving this function. */
532  PG_TRY();
533  {
534  char *diag_sqlstate = PQresultErrorField(res, PG_DIAG_SQLSTATE);
535  char *message_primary = PQresultErrorField(res, PG_DIAG_MESSAGE_PRIMARY);
536  char *message_detail = PQresultErrorField(res, PG_DIAG_MESSAGE_DETAIL);
537  char *message_hint = PQresultErrorField(res, PG_DIAG_MESSAGE_HINT);
538  char *message_context = PQresultErrorField(res, PG_DIAG_CONTEXT);
539  int sqlstate;
540 
541  if (diag_sqlstate)
542  sqlstate = MAKE_SQLSTATE(diag_sqlstate[0],
543  diag_sqlstate[1],
544  diag_sqlstate[2],
545  diag_sqlstate[3],
546  diag_sqlstate[4]);
547  else
548  sqlstate = ERRCODE_CONNECTION_FAILURE;
549 
550  /*
551  * If we don't get a message from the PGresult, try the PGconn. This
552  * is needed because for connection-level failures, PQexec may just
553  * return NULL, not a PGresult at all.
554  */
555  if (message_primary == NULL)
556  message_primary = pchomp(PQerrorMessage(conn));
557 
558  ereport(elevel,
559  (errcode(sqlstate),
560  message_primary ? errmsg_internal("%s", message_primary) :
561  errmsg("could not obtain message string for remote error"),
562  message_detail ? errdetail_internal("%s", message_detail) : 0,
563  message_hint ? errhint("%s", message_hint) : 0,
564  message_context ? errcontext("%s", message_context) : 0,
565  sql ? errcontext("Remote SQL command: %s", sql) : 0));
566  }
567  PG_CATCH();
568  {
569  if (clear)
570  PQclear(res);
571  PG_RE_THROW();
572  }
573  PG_END_TRY();
574  if (clear)
575  PQclear(res);
576 }
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:5988
int errhint(const char *fmt,...)
Definition: elog.c:987
#define PG_DIAG_MESSAGE_PRIMARY
Definition: postgres_ext.h:58
#define PG_DIAG_MESSAGE_DETAIL
Definition: postgres_ext.h:59
#define MAKE_SQLSTATE(ch1, ch2, ch3, ch4, ch5)
Definition: elog.h:62
int errcode(int sqlerrcode)
Definition: elog.c:575
#define PG_DIAG_SQLSTATE
Definition: postgres_ext.h:57
int errdetail_internal(const char *fmt,...)
Definition: elog.c:900
char * pchomp(const char *in)
Definition: mcxt.c:1101
#define ereport(elevel, rest)
Definition: elog.h:122
static int elevel
Definition: vacuumlazy.c:137
#define PG_DIAG_MESSAGE_HINT
Definition: postgres_ext.h:60
void PQclear(PGresult *res)
Definition: fe-exec.c:650
int errmsg_internal(const char *fmt,...)
Definition: elog.c:827
#define PG_CATCH()
Definition: elog.h:293
char * PQresultErrorField(const PGresult *res, int fieldcode)
Definition: fe-exec.c:2658
#define NULL
Definition: c.h:229
#define PG_RE_THROW()
Definition: elog.h:314
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define errcontext
Definition: elog.h:164
#define PG_TRY()
Definition: elog.h:284
#define PG_END_TRY()
Definition: elog.h:300
#define PG_DIAG_CONTEXT
Definition: postgres_ext.h:64
void ReleaseConnection ( PGconn conn)

Definition at line 402 of file connection.c.

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

403 {
404  /*
405  * Currently, we don't actually track connection references because all
406  * cleanup is managed on a transaction or subtransaction basis instead. So
407  * there's nothing to do here.
408  */
409 }
void reset_transmission_modes ( int  nestlevel)

Definition at line 3106 of file postgres_fdw.c.

References AtEOXact_GUC().

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

3107 {
3108  AtEOXact_GUC(true, nestlevel);
3109 }
void AtEOXact_GUC(bool isCommit, int nestLevel)
Definition: guc.c:5079
int set_transmission_modes ( void  )

Definition at line 3078 of file postgres_fdw.c.

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(), appendOrderByClause(), convert_prep_stmt_params(), deparseDirectUpdateSql(), and process_query_params().

3079 {
3080  int nestlevel = NewGUCNestLevel();
3081 
3082  /*
3083  * The values set here should match what pg_dump does. See also
3084  * configure_remote_session in connection.c.
3085  */
3086  if (DateStyle != USE_ISO_DATES)
3087  (void) set_config_option("datestyle", "ISO",
3089  GUC_ACTION_SAVE, true, 0, false);
3091  (void) set_config_option("intervalstyle", "postgres",
3093  GUC_ACTION_SAVE, true, 0, false);
3094  if (extra_float_digits < 3)
3095  (void) set_config_option("extra_float_digits", "3",
3097  GUC_ACTION_SAVE, true, 0, false);
3098 
3099  return nestlevel;
3100 }
int IntervalStyle
Definition: globals.c:108
#define USE_ISO_DATES
Definition: miscadmin.h:210
int extra_float_digits
Definition: float.c:68
int DateStyle
Definition: globals.c:106
int NewGUCNestLevel(void)
Definition: guc.c:5065
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:5908
#define INTSTYLE_POSTGRES
Definition: miscadmin.h:230