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(), PathTarget::exprs, RelOptInfo::fdw_private, PgFdwRelationInfo::grouped_tlist, PgFdwRelationInfo::local_conds, NIL, pull_var_clause(), PVC_RECURSE_PLACEHOLDERS, RELOPT_UPPER_REL, RelOptInfo::reloptkind, and RelOptInfo::reltarget.

Referenced by estimate_path_cost_size(), and postgresGetForeignPlan().

869 {
870  List *tlist = NIL;
871  PgFdwRelationInfo *fpinfo = (PgFdwRelationInfo *) foreignrel->fdw_private;
872 
873  /*
874  * For an upper relation, we have already built the target list while
875  * checking shippability, so just return that.
876  */
877  if (foreignrel->reloptkind == RELOPT_UPPER_REL)
878  return fpinfo->grouped_tlist;
879 
880  /*
881  * We require columns specified in foreignrel->reltarget->exprs and those
882  * required for evaluating the local conditions.
883  */
884  tlist = add_to_flat_tlist(tlist,
885  pull_var_clause((Node *) foreignrel->reltarget->exprs,
887  tlist = add_to_flat_tlist(tlist,
888  pull_var_clause((Node *) fpinfo->local_conds,
890 
891  return tlist;
892 }
#define NIL
Definition: pg_list.h:69
RelOptKind reloptkind
Definition: relation.h:491
Definition: nodes.h:518
List * pull_var_clause(Node *node, int flags)
Definition: var.c:535
#define PVC_RECURSE_PLACEHOLDERS
Definition: var.h:26
List * exprs
Definition: relation.h:828
void * fdw_private
Definition: relation.h:545
List * add_to_flat_tlist(List *tlist, List *exprs)
Definition: tlist.c:135
Definition: pg_list.h:45
struct PathTarget * reltarget
Definition: relation.h:505
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, 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  {
213  RestrictInfo *ri = (RestrictInfo *) lfirst(lc);
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
List * lappend(List *list, void *datum)
Definition: list.c:128
Expr * clause
Definition: relation.h:1660
#define lfirst(lc)
Definition: pg_list.h:106
bool is_foreign_expr(PlannerInfo *root, RelOptInfo *baserel, Expr *expr)
Definition: deparse.c:226
void deparseAnalyzeSizeSql ( StringInfo  buf,
Relation  rel 
)

Definition at line 1823 of file deparse.c.

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

Referenced by postgresAnalyzeForeignTable().

1824 {
1825  StringInfoData relname;
1826 
1827  /* We'll need the remote relation name as a literal. */
1828  initStringInfo(&relname);
1829  deparseRelation(&relname, rel);
1830 
1831  appendStringInfoString(buf, "SELECT pg_catalog.pg_relation_size(");
1832  deparseStringLiteral(buf, relname.data);
1833  appendStringInfo(buf, "::pg_catalog.regclass) / %d", BLCKSZ);
1834 }
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:110
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:189
void initStringInfo(StringInfo str)
Definition: stringinfo.c:65
void deparseStringLiteral(StringInfo buf, const char *val)
Definition: deparse.c:2089
static void deparseRelation(StringInfo buf, Relation rel)
Definition: deparse.c:2049
void deparseAnalyzeSql ( StringInfo  buf,
Relation  rel,
List **  retrieved_attrs 
)

Definition at line 1843 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().

1844 {
1845  Oid relid = RelationGetRelid(rel);
1846  TupleDesc tupdesc = RelationGetDescr(rel);
1847  int i;
1848  char *colname;
1849  List *options;
1850  ListCell *lc;
1851  bool first = true;
1852 
1853  *retrieved_attrs = NIL;
1854 
1855  appendStringInfoString(buf, "SELECT ");
1856  for (i = 0; i < tupdesc->natts; i++)
1857  {
1858  /* Ignore dropped columns. */
1859  if (tupdesc->attrs[i]->attisdropped)
1860  continue;
1861 
1862  if (!first)
1863  appendStringInfoString(buf, ", ");
1864  first = false;
1865 
1866  /* Use attribute name or column_name option. */
1867  colname = NameStr(tupdesc->attrs[i]->attname);
1868  options = GetForeignColumnOptions(relid, i + 1);
1869 
1870  foreach(lc, options)
1871  {
1872  DefElem *def = (DefElem *) lfirst(lc);
1873 
1874  if (strcmp(def->defname, "column_name") == 0)
1875  {
1876  colname = defGetString(def);
1877  break;
1878  }
1879  }
1880 
1882 
1883  *retrieved_attrs = lappend_int(*retrieved_attrs, i + 1);
1884  }
1885 
1886  /* Don't generate bad syntax for zero-column relation. */
1887  if (first)
1888  appendStringInfoString(buf, "NULL");
1889 
1890  /*
1891  * Construct FROM clause
1892  */
1893  appendStringInfoString(buf, " FROM ");
1894  deparseRelation(buf, rel);
1895 }
#define NIL
Definition: pg_list.h:69
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:10114
#define RelationGetDescr(relation)
Definition: rel.h:425
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:189
List * lappend_int(List *list, int datum)
Definition: list.c:146
static char ** options
static void deparseRelation(StringInfo buf, Relation rel)
Definition: deparse.c:2049
#define lfirst(lc)
Definition: pg_list.h:106
int i
#define NameStr(name)
Definition: c.h:499
char * defname
Definition: parsenodes.h:708
Definition: pg_list.h:45
#define RelationGetRelid(relation)
Definition: rel.h:413
void deparseDeleteSql ( StringInfo  buf,
PlannerInfo root,
Index  rtindex,
Relation  rel,
List returningList,
List **  retrieved_attrs 
)

Definition at line 1726 of file deparse.c.

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

Referenced by postgresPlanForeignModify().

1730 {
1731  appendStringInfoString(buf, "DELETE FROM ");
1732  deparseRelation(buf, rel);
1733  appendStringInfoString(buf, " WHERE ctid = $1");
1734 
1735  deparseReturningList(buf, root, rtindex, rel,
1736  rel->trigdesc && rel->trigdesc->trig_delete_after_row,
1737  returningList, retrieved_attrs);
1738 }
TriggerDesc * trigdesc
Definition: rel.h:119
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:189
bool trig_delete_after_row
Definition: reltrigger.h:66
static void deparseRelation(StringInfo buf, Relation rel)
Definition: deparse.c:2049
static void deparseReturningList(StringInfo buf, PlannerInfo *root, Index rtindex, Relation rel, bool trig_after_row, List *returningList, List **retrieved_attrs)
Definition: deparse.c:1782
void deparseDirectDeleteSql ( StringInfo  buf,
PlannerInfo root,
Index  rtindex,
Relation  rel,
List remote_conds,
List **  params_list,
List returningList,
List **  retrieved_attrs 
)

Definition at line 1748 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().

1754 {
1755  RelOptInfo *baserel = root->simple_rel_array[rtindex];
1756  deparse_expr_cxt context;
1757 
1758  /* Set up context struct for recursion */
1759  context.root = root;
1760  context.foreignrel = baserel;
1761  context.scanrel = baserel;
1762  context.buf = buf;
1763  context.params_list = params_list;
1764 
1765  appendStringInfoString(buf, "DELETE FROM ");
1766  deparseRelation(buf, rel);
1767 
1768  if (remote_conds)
1769  {
1770  appendStringInfo(buf, " WHERE ");
1771  appendConditions(remote_conds, &context);
1772  }
1773 
1774  deparseReturningList(buf, root, rtindex, rel, false,
1775  returningList, retrieved_attrs);
1776 }
List ** params_list
Definition: deparse.c:105
struct RelOptInfo ** simple_rel_array
Definition: relation.h:178
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:110
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:189
static char * buf
Definition: pg_test_fsync.c:65
static void appendConditions(List *exprs, deparse_expr_cxt *context)
Definition: deparse.c:1273
StringInfo buf
Definition: deparse.c:104
static void deparseRelation(StringInfo buf, Relation rel)
Definition: deparse.c:2049
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:1782
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 1658 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().

1666 {
1667  RelOptInfo *baserel = root->simple_rel_array[rtindex];
1668  deparse_expr_cxt context;
1669  int nestlevel;
1670  bool first;
1671  ListCell *lc;
1672 
1673  /* Set up context struct for recursion */
1674  context.root = root;
1675  context.foreignrel = baserel;
1676  context.scanrel = baserel;
1677  context.buf = buf;
1678  context.params_list = params_list;
1679 
1680  appendStringInfoString(buf, "UPDATE ");
1681  deparseRelation(buf, rel);
1682  appendStringInfoString(buf, " SET ");
1683 
1684  /* Make sure any constants in the exprs are printed portably */
1685  nestlevel = set_transmission_modes();
1686 
1687  first = true;
1688  foreach(lc, targetAttrs)
1689  {
1690  int attnum = lfirst_int(lc);
1691  TargetEntry *tle = get_tle_by_resno(targetlist, attnum);
1692 
1693  if (!tle)
1694  elog(ERROR, "attribute number %d not found in UPDATE targetlist",
1695  attnum);
1696 
1697  if (!first)
1698  appendStringInfoString(buf, ", ");
1699  first = false;
1700 
1701  deparseColumnRef(buf, rtindex, attnum, root, false);
1702  appendStringInfoString(buf, " = ");
1703  deparseExpr((Expr *) tle->expr, &context);
1704  }
1705 
1706  reset_transmission_modes(nestlevel);
1707 
1708  if (remote_conds)
1709  {
1710  appendStringInfo(buf, " WHERE ");
1711  appendConditions(remote_conds, &context);
1712  }
1713 
1714  deparseReturningList(buf, root, rtindex, rel, false,
1715  returningList, retrieved_attrs);
1716 }
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:1904
struct RelOptInfo ** simple_rel_array
Definition: relation.h:178
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:110
#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:189
static char * buf
Definition: pg_test_fsync.c:65
static void appendConditions(List *exprs, deparse_expr_cxt *context)
Definition: deparse.c:1273
StringInfo buf
Definition: deparse.c:104
static void deparseRelation(StringInfo buf, Relation rel)
Definition: deparse.c:2049
PlannerInfo * root
Definition: deparse.c:99
Expr * expr
Definition: primnodes.h:1352
void reset_transmission_modes(int nestlevel)
static void deparseExpr(Expr *expr, deparse_expr_cxt *context)
Definition: deparse.c:2124
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:1782
#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 1553 of file deparse.c.

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

Referenced by postgresPlanForeignModify().

1557 {
1558  AttrNumber pindex;
1559  bool first;
1560  ListCell *lc;
1561 
1562  appendStringInfoString(buf, "INSERT INTO ");
1563  deparseRelation(buf, rel);
1564 
1565  if (targetAttrs)
1566  {
1567  appendStringInfoChar(buf, '(');
1568 
1569  first = true;
1570  foreach(lc, targetAttrs)
1571  {
1572  int attnum = lfirst_int(lc);
1573 
1574  if (!first)
1575  appendStringInfoString(buf, ", ");
1576  first = false;
1577 
1578  deparseColumnRef(buf, rtindex, attnum, root, false);
1579  }
1580 
1581  appendStringInfoString(buf, ") VALUES (");
1582 
1583  pindex = 1;
1584  first = true;
1585  foreach(lc, targetAttrs)
1586  {
1587  if (!first)
1588  appendStringInfoString(buf, ", ");
1589  first = false;
1590 
1591  appendStringInfo(buf, "$%d", pindex);
1592  pindex++;
1593  }
1594 
1595  appendStringInfoChar(buf, ')');
1596  }
1597  else
1598  appendStringInfoString(buf, " DEFAULT VALUES");
1599 
1600  if (doNothing)
1601  appendStringInfoString(buf, " ON CONFLICT DO NOTHING");
1602 
1603  deparseReturningList(buf, root, rtindex, rel,
1604  rel->trigdesc && rel->trigdesc->trig_insert_after_row,
1605  returningList, retrieved_attrs);
1606 }
static void deparseColumnRef(StringInfo buf, int varno, int varattno, PlannerInfo *root, bool qualify_col)
Definition: deparse.c:1904
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:110
#define lfirst_int(lc)
Definition: pg_list.h:107
TriggerDesc * trigdesc
Definition: rel.h:119
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:189
bool trig_insert_after_row
Definition: reltrigger.h:56
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:201
static void deparseRelation(StringInfo buf, Relation rel)
Definition: deparse.c:2049
static void deparseReturningList(StringInfo buf, PlannerInfo *root, Index rtindex, Relation rel, bool trig_after_row, List *returningList, List **retrieved_attrs)
Definition: deparse.c:1782
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 919 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, PgFdwRelationInfo::outerrel, deparse_expr_cxt::params_list, RELOPT_BASEREL, RELOPT_JOINREL, RELOPT_OTHER_MEMBER_REL, RELOPT_UPPER_REL, RelOptInfo::reloptkind, PgFdwRelationInfo::remote_conds, deparse_expr_cxt::root, and deparse_expr_cxt::scanrel.

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

923 {
924  deparse_expr_cxt context;
925  PgFdwRelationInfo *fpinfo = (PgFdwRelationInfo *) rel->fdw_private;
926  List *quals;
927 
928  /*
929  * We handle relations for foreign tables, joins between those and upper
930  * relations.
931  */
932  Assert(rel->reloptkind == RELOPT_JOINREL ||
933  rel->reloptkind == RELOPT_BASEREL ||
934  rel->reloptkind == RELOPT_OTHER_MEMBER_REL ||
935  rel->reloptkind == RELOPT_UPPER_REL);
936 
937  /* Fill portions of context common to upper, join and base relation */
938  context.buf = buf;
939  context.root = root;
940  context.foreignrel = rel;
941  context.scanrel = (rel->reloptkind == RELOPT_UPPER_REL) ?
942  fpinfo->outerrel : rel;
943  context.params_list = params_list;
944 
945  /* Construct SELECT clause */
946  deparseSelectSql(tlist, is_subquery, retrieved_attrs, &context);
947 
948  /*
949  * For upper relations, the WHERE clause is built from the remote
950  * conditions of the underlying scan relation; otherwise, we can use the
951  * supplied list of remote conditions directly.
952  */
953  if (rel->reloptkind == RELOPT_UPPER_REL)
954  {
955  PgFdwRelationInfo *ofpinfo;
956 
957  ofpinfo = (PgFdwRelationInfo *) fpinfo->outerrel->fdw_private;
958  quals = ofpinfo->remote_conds;
959  }
960  else
961  quals = remote_conds;
962 
963  /* Construct FROM and WHERE clauses */
964  deparseFromExpr(quals, &context);
965 
966  if (rel->reloptkind == RELOPT_UPPER_REL)
967  {
968  /* Append GROUP BY clause */
969  appendGroupByClause(tlist, &context);
970 
971  /* Append HAVING clause */
972  if (remote_conds)
973  {
974  appendStringInfo(buf, " HAVING ");
975  appendConditions(remote_conds, &context);
976  }
977  }
978 
979  /* Add ORDER BY clause if we found any useful pathkeys */
980  if (pathkeys)
981  appendOrderByClause(pathkeys, &context);
982 
983  /* Add any necessary FOR UPDATE/SHARE. */
984  deparseLockingClause(&context);
985 }
static void appendGroupByClause(List *tlist, deparse_expr_cxt *context)
Definition: deparse.c:2941
List ** params_list
Definition: deparse.c:105
RelOptInfo * outerrel
Definition: postgres_fdw.h:91
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:110
static void appendOrderByClause(List *pathkeys, deparse_expr_cxt *context)
Definition: deparse.c:2978
static char * buf
Definition: pg_test_fsync.c:65
static void deparseSelectSql(List *tlist, bool is_subquery, List **retrieved_attrs, deparse_expr_cxt *context)
Definition: deparse.c:1001
static void appendConditions(List *exprs, deparse_expr_cxt *context)
Definition: deparse.c:1273
StringInfo buf
Definition: deparse.c:104
void * fdw_private
Definition: relation.h:545
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:1059
static void deparseLockingClause(deparse_expr_cxt *context)
Definition: deparse.c:1186
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 2089 of file deparse.c.

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

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

2090 {
2091  const char *valptr;
2092 
2093  /*
2094  * Rather than making assumptions about the remote server's value of
2095  * standard_conforming_strings, always use E'foo' syntax if there are any
2096  * backslashes. This will fail on remote servers before 8.1, but those
2097  * are long out of support.
2098  */
2099  if (strchr(val, '\\') != NULL)
2101  appendStringInfoChar(buf, '\'');
2102  for (valptr = val; *valptr; valptr++)
2103  {
2104  char ch = *valptr;
2105 
2106  if (SQL_STR_DOUBLE(ch, true))
2107  appendStringInfoChar(buf, ch);
2108  appendStringInfoChar(buf, ch);
2109  }
2110  appendStringInfoChar(buf, '\'');
2111 }
#define ESCAPE_STRING_SYNTAX
Definition: c.h:510
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:201
#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 1616 of file deparse.c.

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

Referenced by postgresPlanForeignModify().

1620 {
1621  AttrNumber pindex;
1622  bool first;
1623  ListCell *lc;
1624 
1625  appendStringInfoString(buf, "UPDATE ");
1626  deparseRelation(buf, rel);
1627  appendStringInfoString(buf, " SET ");
1628 
1629  pindex = 2; /* ctid is always the first param */
1630  first = true;
1631  foreach(lc, targetAttrs)
1632  {
1633  int attnum = lfirst_int(lc);
1634 
1635  if (!first)
1636  appendStringInfoString(buf, ", ");
1637  first = false;
1638 
1639  deparseColumnRef(buf, rtindex, attnum, root, false);
1640  appendStringInfo(buf, " = $%d", pindex);
1641  pindex++;
1642  }
1643  appendStringInfoString(buf, " WHERE ctid = $1");
1644 
1645  deparseReturningList(buf, root, rtindex, rel,
1646  rel->trigdesc && rel->trigdesc->trig_update_after_row,
1647  returningList, retrieved_attrs);
1648 }
static void deparseColumnRef(StringInfo buf, int varno, int varattno, PlannerInfo *root, bool qualify_col)
Definition: deparse.c:1904
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:110
#define lfirst_int(lc)
Definition: pg_list.h:107
TriggerDesc * trigdesc
Definition: rel.h:119
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:189
bool trig_update_after_row
Definition: reltrigger.h:61
static void deparseRelation(StringInfo buf, Relation rel)
Definition: deparse.c:2049
static void deparseReturningList(StringInfo buf, PlannerInfo *root, Index rtindex, Relation rel, bool trig_after_row, List *returningList, List **retrieved_attrs)
Definition: deparse.c:1782
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:162
int i
static bool is_libpq_option(const char *keyword)
Definition: option.c:276
char * defname
Definition: parsenodes.h:708
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 postgres_fdw_validator(), and postgresGetForeignRelSize().

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:3115
#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 5058 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().

5059 {
5060  ListCell *lc_em;
5061 
5062  foreach(lc_em, ec->ec_members)
5063  {
5064  EquivalenceMember *em = lfirst(lc_em);
5065 
5066  if (bms_is_subset(em->em_relids, rel->relids))
5067  {
5068  /*
5069  * If there is more than one equivalence member whose Vars are
5070  * taken entirely from this relation, we'll be content to choose
5071  * any one of those.
5072  */
5073  return em->em_expr;
5074  }
5075  }
5076 
5077  /* We didn't find any suitable equivalence class expression */
5078  return NULL;
5079 }
bool bms_is_subset(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:307
Relids relids
Definition: relation.h:494
Relids em_relids
Definition: relation.h:767
#define NULL
Definition: c.h:229
#define lfirst(lc)
Definition: pg_list.h:106
List * ec_members
Definition: relation.h:718
const char* get_jointype_name ( JoinType  jointype)

Definition at line 1314 of file deparse.c.

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

Referenced by deparseFromExprForRel(), and foreign_join_ok().

1315 {
1316  switch (jointype)
1317  {
1318  case JOIN_INNER:
1319  return "INNER";
1320 
1321  case JOIN_LEFT:
1322  return "LEFT";
1323 
1324  case JOIN_RIGHT:
1325  return "RIGHT";
1326 
1327  case JOIN_FULL:
1328  return "FULL";
1329 
1330  default:
1331  /* Shouldn't come here, but protect from buggy code. */
1332  elog(ERROR, "unsupported join type %d", jointype);
1333  }
1334 
1335  /* Keep compiler happy */
1336  return NULL;
1337 }
#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:3360
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:3305
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, PgFdwRelationInfo::outerrel, foreign_glob_cxt::relids, RelOptInfo::relids, RELOPT_UPPER_REL, RelOptInfo::reloptkind, 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 (baserel->reloptkind == RELOPT_UPPER_REL)
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 }
RelOptKind reloptkind
Definition: relation.h:491
FDWCollateState state
Definition: deparse.c:91
Definition: nodes.h:518
RelOptInfo * outerrel
Definition: postgres_fdw.h:91
Relids relids
Definition: deparse.c:70
PlannerInfo * root
Definition: deparse.c:68
RelOptInfo * foreignrel
Definition: deparse.c:69
Relids relids
Definition: relation.h:494
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:545
bool contain_mutable_functions(Node *clause)
Definition: clauses.c:877
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:78
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:74
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:461
#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:723
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:320
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:6029
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:6011
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 3104 of file postgres_fdw.c.

References AtEOXact_GUC().

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

3105 {
3106  AtEOXact_GUC(true, nestlevel);
3107 }
void AtEOXact_GUC(bool isCommit, int nestLevel)
Definition: guc.c:5046
int set_transmission_modes ( void  )

Definition at line 3076 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().

3077 {
3078  int nestlevel = NewGUCNestLevel();
3079 
3080  /*
3081  * The values set here should match what pg_dump does. See also
3082  * configure_remote_session in connection.c.
3083  */
3084  if (DateStyle != USE_ISO_DATES)
3085  (void) set_config_option("datestyle", "ISO",
3087  GUC_ACTION_SAVE, true, 0, false);
3089  (void) set_config_option("intervalstyle", "postgres",
3091  GUC_ACTION_SAVE, true, 0, false);
3092  if (extra_float_digits < 3)
3093  (void) set_config_option("extra_float_digits", "3",
3095  GUC_ACTION_SAVE, true, 0, false);
3096 
3097  return nestlevel;
3098 }
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:5032
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:5875
#define INTSTYLE_POSTGRES
Definition: miscadmin.h:230