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

855 {
856  List *tlist = NIL;
857  PgFdwRelationInfo *fpinfo = (PgFdwRelationInfo *) foreignrel->fdw_private;
858 
859  /*
860  * For an upper relation, we have already built the target list while
861  * checking shippability, so just return that.
862  */
863  if (foreignrel->reloptkind == RELOPT_UPPER_REL)
864  return fpinfo->grouped_tlist;
865 
866  /*
867  * We require columns specified in foreignrel->reltarget->exprs and those
868  * required for evaluating the local conditions.
869  */
870  tlist = add_to_flat_tlist(tlist,
871  pull_var_clause((Node *) foreignrel->reltarget->exprs,
873  tlist = add_to_flat_tlist(tlist,
874  pull_var_clause((Node *) fpinfo->local_conds,
876 
877  return tlist;
878 }
#define NIL
Definition: pg_list.h:69
RelOptKind reloptkind
Definition: relation.h:487
Definition: nodes.h:508
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:824
void * fdw_private
Definition: relation.h:541
List * add_to_flat_tlist(List *tlist, List *exprs)
Definition: tlist.c:135
Definition: pg_list.h:45
struct PathTarget * reltarget
Definition: relation.h:501
void classifyConditions ( PlannerInfo root,
RelOptInfo baserel,
List input_conds,
List **  remote_conds,
List **  local_conds 
)

Definition at line 186 of file deparse.c.

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

Referenced by estimate_path_cost_size(), and postgresGetForeignRelSize().

191 {
192  ListCell *lc;
193 
194  *remote_conds = NIL;
195  *local_conds = NIL;
196 
197  foreach(lc, input_conds)
198  {
199  RestrictInfo *ri = (RestrictInfo *) lfirst(lc);
200 
201  if (is_foreign_expr(root, baserel, ri->clause))
202  *remote_conds = lappend(*remote_conds, ri);
203  else
204  *local_conds = lappend(*local_conds, ri);
205  }
206 }
#define NIL
Definition: pg_list.h:69
List * lappend(List *list, void *datum)
Definition: list.c:128
Expr * clause
Definition: relation.h:1637
#define lfirst(lc)
Definition: pg_list.h:106
bool is_foreign_expr(PlannerInfo *root, RelOptInfo *baserel, Expr *expr)
Definition: deparse.c:212
void deparseAnalyzeSizeSql ( StringInfo  buf,
Relation  rel 
)

Definition at line 1691 of file deparse.c.

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

Referenced by postgresAnalyzeForeignTable().

1692 {
1693  StringInfoData relname;
1694 
1695  /* We'll need the remote relation name as a literal. */
1696  initStringInfo(&relname);
1697  deparseRelation(&relname, rel);
1698 
1699  appendStringInfoString(buf, "SELECT pg_catalog.pg_relation_size(");
1700  deparseStringLiteral(buf, relname.data);
1701  appendStringInfo(buf, "::pg_catalog.regclass) / %d", BLCKSZ);
1702 }
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:1957
static void deparseRelation(StringInfo buf, Relation rel)
Definition: deparse.c:1917
void deparseAnalyzeSql ( StringInfo  buf,
Relation  rel,
List **  retrieved_attrs 
)

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

1712 {
1713  Oid relid = RelationGetRelid(rel);
1714  TupleDesc tupdesc = RelationGetDescr(rel);
1715  int i;
1716  char *colname;
1717  List *options;
1718  ListCell *lc;
1719  bool first = true;
1720 
1721  *retrieved_attrs = NIL;
1722 
1723  appendStringInfoString(buf, "SELECT ");
1724  for (i = 0; i < tupdesc->natts; i++)
1725  {
1726  /* Ignore dropped columns. */
1727  if (tupdesc->attrs[i]->attisdropped)
1728  continue;
1729 
1730  if (!first)
1731  appendStringInfoString(buf, ", ");
1732  first = false;
1733 
1734  /* Use attribute name or column_name option. */
1735  colname = NameStr(tupdesc->attrs[i]->attname);
1736  options = GetForeignColumnOptions(relid, i + 1);
1737 
1738  foreach(lc, options)
1739  {
1740  DefElem *def = (DefElem *) lfirst(lc);
1741 
1742  if (strcmp(def->defname, "column_name") == 0)
1743  {
1744  colname = defGetString(def);
1745  break;
1746  }
1747  }
1748 
1750 
1751  *retrieved_attrs = lappend_int(*retrieved_attrs, i + 1);
1752  }
1753 
1754  /* Don't generate bad syntax for zero-column relation. */
1755  if (first)
1756  appendStringInfoString(buf, "NULL");
1757 
1758  /*
1759  * Construct FROM clause
1760  */
1761  appendStringInfoString(buf, " FROM ");
1762  deparseRelation(buf, rel);
1763 }
#define NIL
Definition: pg_list.h:69
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:9968
#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:1917
#define lfirst(lc)
Definition: pg_list.h:106
int i
#define NameStr(name)
Definition: c.h:495
char * defname
Definition: parsenodes.h:675
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 1594 of file deparse.c.

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

Referenced by postgresPlanForeignModify().

1598 {
1599  appendStringInfoString(buf, "DELETE FROM ");
1600  deparseRelation(buf, rel);
1601  appendStringInfoString(buf, " WHERE ctid = $1");
1602 
1603  deparseReturningList(buf, root, rtindex, rel,
1604  rel->trigdesc && rel->trigdesc->trig_delete_after_row,
1605  returningList, retrieved_attrs);
1606 }
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:1917
static void deparseReturningList(StringInfo buf, PlannerInfo *root, Index rtindex, Relation rel, bool trig_after_row, List *returningList, List **retrieved_attrs)
Definition: deparse.c:1650
void deparseDirectDeleteSql ( StringInfo  buf,
PlannerInfo root,
Index  rtindex,
Relation  rel,
List remote_conds,
List **  params_list,
List returningList,
List **  retrieved_attrs 
)

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

1622 {
1623  RelOptInfo *baserel = root->simple_rel_array[rtindex];
1624  deparse_expr_cxt context;
1625 
1626  /* Set up context struct for recursion */
1627  context.root = root;
1628  context.foreignrel = baserel;
1629  context.scanrel = baserel;
1630  context.buf = buf;
1631  context.params_list = params_list;
1632 
1633  appendStringInfoString(buf, "DELETE FROM ");
1634  deparseRelation(buf, rel);
1635 
1636  if (remote_conds)
1637  {
1638  appendStringInfo(buf, " WHERE ");
1639  appendConditions(remote_conds, &context);
1640  }
1641 
1642  deparseReturningList(buf, root, rtindex, rel, false,
1643  returningList, retrieved_attrs);
1644 }
List ** params_list
Definition: deparse.c:105
struct RelOptInfo ** simple_rel_array
Definition: relation.h:176
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:1232
StringInfo buf
Definition: deparse.c:104
static void deparseRelation(StringInfo buf, Relation rel)
Definition: deparse.c:1917
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:1650
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 1526 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().

1534 {
1535  RelOptInfo *baserel = root->simple_rel_array[rtindex];
1536  deparse_expr_cxt context;
1537  int nestlevel;
1538  bool first;
1539  ListCell *lc;
1540 
1541  /* Set up context struct for recursion */
1542  context.root = root;
1543  context.foreignrel = baserel;
1544  context.scanrel = baserel;
1545  context.buf = buf;
1546  context.params_list = params_list;
1547 
1548  appendStringInfoString(buf, "UPDATE ");
1549  deparseRelation(buf, rel);
1550  appendStringInfoString(buf, " SET ");
1551 
1552  /* Make sure any constants in the exprs are printed portably */
1553  nestlevel = set_transmission_modes();
1554 
1555  first = true;
1556  foreach(lc, targetAttrs)
1557  {
1558  int attnum = lfirst_int(lc);
1559  TargetEntry *tle = get_tle_by_resno(targetlist, attnum);
1560 
1561  if (!tle)
1562  elog(ERROR, "attribute number %d not found in UPDATE targetlist",
1563  attnum);
1564 
1565  if (!first)
1566  appendStringInfoString(buf, ", ");
1567  first = false;
1568 
1569  deparseColumnRef(buf, rtindex, attnum, root, false);
1570  appendStringInfoString(buf, " = ");
1571  deparseExpr((Expr *) tle->expr, &context);
1572  }
1573 
1574  reset_transmission_modes(nestlevel);
1575 
1576  if (remote_conds)
1577  {
1578  appendStringInfo(buf, " WHERE ");
1579  appendConditions(remote_conds, &context);
1580  }
1581 
1582  deparseReturningList(buf, root, rtindex, rel, false,
1583  returningList, retrieved_attrs);
1584 }
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:1772
struct RelOptInfo ** simple_rel_array
Definition: relation.h:176
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:1232
StringInfo buf
Definition: deparse.c:104
static void deparseRelation(StringInfo buf, Relation rel)
Definition: deparse.c:1917
PlannerInfo * root
Definition: deparse.c:99
Expr * expr
Definition: primnodes.h:1330
void reset_transmission_modes(int nestlevel)
static void deparseExpr(Expr *expr, deparse_expr_cxt *context)
Definition: deparse.c:1992
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:1650
#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 1421 of file deparse.c.

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

Referenced by postgresPlanForeignModify().

1425 {
1426  AttrNumber pindex;
1427  bool first;
1428  ListCell *lc;
1429 
1430  appendStringInfoString(buf, "INSERT INTO ");
1431  deparseRelation(buf, rel);
1432 
1433  if (targetAttrs)
1434  {
1435  appendStringInfoChar(buf, '(');
1436 
1437  first = true;
1438  foreach(lc, targetAttrs)
1439  {
1440  int attnum = lfirst_int(lc);
1441 
1442  if (!first)
1443  appendStringInfoString(buf, ", ");
1444  first = false;
1445 
1446  deparseColumnRef(buf, rtindex, attnum, root, false);
1447  }
1448 
1449  appendStringInfoString(buf, ") VALUES (");
1450 
1451  pindex = 1;
1452  first = true;
1453  foreach(lc, targetAttrs)
1454  {
1455  if (!first)
1456  appendStringInfoString(buf, ", ");
1457  first = false;
1458 
1459  appendStringInfo(buf, "$%d", pindex);
1460  pindex++;
1461  }
1462 
1463  appendStringInfoChar(buf, ')');
1464  }
1465  else
1466  appendStringInfoString(buf, " DEFAULT VALUES");
1467 
1468  if (doNothing)
1469  appendStringInfoString(buf, " ON CONFLICT DO NOTHING");
1470 
1471  deparseReturningList(buf, root, rtindex, rel,
1472  rel->trigdesc && rel->trigdesc->trig_insert_after_row,
1473  returningList, retrieved_attrs);
1474 }
static void deparseColumnRef(StringInfo buf, int varno, int varattno, PlannerInfo *root, bool qualify_col)
Definition: deparse.c:1772
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:1917
static void deparseReturningList(StringInfo buf, PlannerInfo *root, Index rtindex, Relation rel, bool trig_after_row, List *returningList, List **retrieved_attrs)
Definition: deparse.c:1650
int16 AttrNumber
Definition: attnum.h:21
void deparseSelectStmtForRel ( StringInfo  buf,
PlannerInfo root,
RelOptInfo foreignrel,
List tlist,
List remote_conds,
List pathkeys,
List **  retrieved_attrs,
List **  params_list 
)

Definition at line 902 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 estimate_path_cost_size(), and postgresGetForeignPlan().

905 {
906  deparse_expr_cxt context;
907  PgFdwRelationInfo *fpinfo = (PgFdwRelationInfo *) rel->fdw_private;
908  List *quals;
909 
910  /*
911  * We handle relations for foreign tables, joins between those and upper
912  * relations.
913  */
914  Assert(rel->reloptkind == RELOPT_JOINREL ||
915  rel->reloptkind == RELOPT_BASEREL ||
916  rel->reloptkind == RELOPT_OTHER_MEMBER_REL ||
917  rel->reloptkind == RELOPT_UPPER_REL);
918 
919  /* Fill portions of context common to upper, join and base relation */
920  context.buf = buf;
921  context.root = root;
922  context.foreignrel = rel;
923  context.scanrel = (rel->reloptkind == RELOPT_UPPER_REL) ?
924  fpinfo->outerrel : rel;
925  context.params_list = params_list;
926 
927  /* Construct SELECT clause */
928  deparseSelectSql(tlist, retrieved_attrs, &context);
929 
930  /*
931  * For upper relations, the WHERE clause is built from the remote
932  * conditions of the underlying scan relation; otherwise, we can use the
933  * supplied list of remote conditions directly.
934  */
935  if (rel->reloptkind == RELOPT_UPPER_REL)
936  {
937  PgFdwRelationInfo *ofpinfo;
938 
939  ofpinfo = (PgFdwRelationInfo *) fpinfo->outerrel->fdw_private;
940  quals = ofpinfo->remote_conds;
941  }
942  else
943  quals = remote_conds;
944 
945  /* Construct FROM and WHERE clauses */
946  deparseFromExpr(quals, &context);
947 
948  if (rel->reloptkind == RELOPT_UPPER_REL)
949  {
950  /* Append GROUP BY clause */
951  appendGroupByClause(tlist, &context);
952 
953  /* Append HAVING clause */
954  if (remote_conds)
955  {
956  appendStringInfo(buf, " HAVING ");
957  appendConditions(remote_conds, &context);
958  }
959  }
960 
961  /* Add ORDER BY clause if we found any useful pathkeys */
962  if (pathkeys)
963  appendOrderByClause(pathkeys, &context);
964 
965  /* Add any necessary FOR UPDATE/SHARE. */
966  deparseLockingClause(&context);
967 }
static void appendGroupByClause(List *tlist, deparse_expr_cxt *context)
Definition: deparse.c:2794
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:2831
static char * buf
Definition: pg_test_fsync.c:65
static void appendConditions(List *exprs, deparse_expr_cxt *context)
Definition: deparse.c:1232
StringInfo buf
Definition: deparse.c:104
void * fdw_private
Definition: relation.h:541
PlannerInfo * root
Definition: deparse.c:99
#define Assert(condition)
Definition: c.h:671
static void deparseFromExpr(List *quals, deparse_expr_cxt *context)
Definition: deparse.c:1026
static void deparseLockingClause(deparse_expr_cxt *context)
Definition: deparse.c:1153
RelOptInfo * scanrel
Definition: deparse.c:101
static void deparseSelectSql(List *tlist, List **retrieved_attrs, deparse_expr_cxt *context)
Definition: deparse.c:981
Definition: pg_list.h:45
RelOptInfo * foreignrel
Definition: deparse.c:100
void deparseStringLiteral ( StringInfo  buf,
const char *  val 
)

Definition at line 1957 of file deparse.c.

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

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

1958 {
1959  const char *valptr;
1960 
1961  /*
1962  * Rather than making assumptions about the remote server's value of
1963  * standard_conforming_strings, always use E'foo' syntax if there are any
1964  * backslashes. This will fail on remote servers before 8.1, but those
1965  * are long out of support.
1966  */
1967  if (strchr(val, '\\') != NULL)
1969  appendStringInfoChar(buf, '\'');
1970  for (valptr = val; *valptr; valptr++)
1971  {
1972  char ch = *valptr;
1973 
1974  if (SQL_STR_DOUBLE(ch, true))
1975  appendStringInfoChar(buf, ch);
1976  appendStringInfoChar(buf, ch);
1977  }
1978  appendStringInfoChar(buf, '\'');
1979 }
#define ESCAPE_STRING_SYNTAX
Definition: c.h:506
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:201
#define NULL
Definition: c.h:226
#define SQL_STR_DOUBLE(ch, escape_backslash)
Definition: c.h:503
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 1484 of file deparse.c.

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

Referenced by postgresPlanForeignModify().

1488 {
1489  AttrNumber pindex;
1490  bool first;
1491  ListCell *lc;
1492 
1493  appendStringInfoString(buf, "UPDATE ");
1494  deparseRelation(buf, rel);
1495  appendStringInfoString(buf, " SET ");
1496 
1497  pindex = 2; /* ctid is always the first param */
1498  first = true;
1499  foreach(lc, targetAttrs)
1500  {
1501  int attnum = lfirst_int(lc);
1502 
1503  if (!first)
1504  appendStringInfoString(buf, ", ");
1505  first = false;
1506 
1507  deparseColumnRef(buf, rtindex, attnum, root, false);
1508  appendStringInfo(buf, " = $%d", pindex);
1509  pindex++;
1510  }
1511  appendStringInfoString(buf, " WHERE ctid = $1");
1512 
1513  deparseReturningList(buf, root, rtindex, rel,
1514  rel->trigdesc && rel->trigdesc->trig_update_after_row,
1515  returningList, retrieved_attrs);
1516 }
static void deparseColumnRef(StringInfo buf, int varno, int varattno, PlannerInfo *root, bool qualify_col)
Definition: deparse.c:1772
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:1917
static void deparseReturningList(StringInfo buf, PlannerInfo *root, Index rtindex, Relation rel, bool trig_after_row, List *returningList, List **retrieved_attrs)
Definition: deparse.c:1650
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:675
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:1165
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:534
#define ERROR
Definition: elog.h:43
bool SplitIdentifierString(char *rawstring, char separator, List **namelist)
Definition: varlena.c:3129
#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 5004 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().

5005 {
5006  ListCell *lc_em;
5007 
5008  foreach(lc_em, ec->ec_members)
5009  {
5010  EquivalenceMember *em = lfirst(lc_em);
5011 
5012  if (bms_is_subset(em->em_relids, rel->relids))
5013  {
5014  /*
5015  * If there is more than one equivalence member whose Vars are
5016  * taken entirely from this relation, we'll be content to choose
5017  * any one of those.
5018  */
5019  return em->em_expr;
5020  }
5021  }
5022 
5023  /* We didn't find any suitable equivalence class expression */
5024  return NULL;
5025 }
bool bms_is_subset(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:307
Relids relids
Definition: relation.h:490
Relids em_relids
Definition: relation.h:763
#define NULL
Definition: c.h:226
#define lfirst(lc)
Definition: pg_list.h:106
List * ec_members
Definition: relation.h:714
const char* get_jointype_name ( JoinType  jointype)

Definition at line 1273 of file deparse.c.

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

Referenced by deparseFromExprForRel(), and foreign_join_ok().

1274 {
1275  switch (jointype)
1276  {
1277  case JOIN_INNER:
1278  return "INNER";
1279 
1280  case JOIN_LEFT:
1281  return "LEFT";
1282 
1283  case JOIN_RIGHT:
1284  return "RIGHT";
1285 
1286  case JOIN_FULL:
1287  return "FULL";
1288 
1289  default:
1290  /* Shouldn't come here, but protect from buggy code. */
1291  elog(ERROR, "unsupported join type %d", jointype);
1292  }
1293 
1294  /* Keep compiler happy */
1295  return NULL;
1296 }
#define ERROR
Definition: elog.h:43
#define NULL
Definition: c.h:226
#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:853
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:592
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:3358
Size keysize
Definition: hsearch.h:72
PGconn * conn
Definition: connection.c:47
#define NULL
Definition: c.h:226
void RegisterXactCallback(XactCallback callback, void *arg)
Definition: xact.c:3303
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:752
static void begin_remote_xact(ConnCacheEntry *entry)
Definition: connection.c:373
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 433 of file connection.c.

References cursor_number.

Referenced by postgresAcquireSampleRowsFunc(), and postgresBeginForeignScan().

434 {
435  return ++cursor_number;
436 }
static unsigned int cursor_number
Definition: connection.c:60
unsigned int GetPrepStmtNumber ( PGconn conn)

Definition at line 447 of file connection.c.

References prep_stmt_number.

Referenced by prepare_foreign_modify().

448 {
449  return ++prep_stmt_number;
450 }
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 212 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().

215 {
216  foreign_glob_cxt glob_cxt;
217  foreign_loc_cxt loc_cxt;
218  PgFdwRelationInfo *fpinfo = (PgFdwRelationInfo *) (baserel->fdw_private);
219 
220  /*
221  * Check that the expression consists of nodes that are safe to execute
222  * remotely.
223  */
224  glob_cxt.root = root;
225  glob_cxt.foreignrel = baserel;
226 
227  /*
228  * For an upper relation, use relids from its underneath scan relation,
229  * because the upperrel's own relids currently aren't set to anything
230  * meaningful by the core code. For other relation, use their own relids.
231  */
232  if (baserel->reloptkind == RELOPT_UPPER_REL)
233  glob_cxt.relids = fpinfo->outerrel->relids;
234  else
235  glob_cxt.relids = baserel->relids;
236  loc_cxt.collation = InvalidOid;
237  loc_cxt.state = FDW_COLLATE_NONE;
238  if (!foreign_expr_walker((Node *) expr, &glob_cxt, &loc_cxt))
239  return false;
240 
241  /*
242  * If the expression has a valid collation that does not arise from a
243  * foreign var, the expression can not be sent over.
244  */
245  if (loc_cxt.state == FDW_COLLATE_UNSAFE)
246  return false;
247 
248  /*
249  * An expression which includes any mutable functions can't be sent over
250  * because its result is not stable. For example, sending now() remote
251  * side could cause confusion from clock offsets. Future versions might
252  * be able to make this choice with more granularity. (We check this last
253  * because it requires a lot of expensive catalog lookups.)
254  */
255  if (contain_mutable_functions((Node *) expr))
256  return false;
257 
258  /* OK to evaluate on the remote server */
259  return true;
260 }
RelOptKind reloptkind
Definition: relation.h:487
FDWCollateState state
Definition: deparse.c:91
Definition: nodes.h:508
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:490
static bool foreign_expr_walker(Node *node, foreign_glob_cxt *glob_cxt, foreign_loc_cxt *outer_cxt)
Definition: deparse.c:276
#define InvalidOid
Definition: postgres_ext.h:36
void * fdw_private
Definition: relation.h:541
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:226
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 460 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().

461 {
462  /*
463  * Submit a query. Since we don't use non-blocking mode, this also can
464  * block. But its risk is relatively small, so we ignore that for now.
465  */
466  if (!PQsendQuery(conn, query))
467  pgfdw_report_error(ERROR, NULL, conn, false, query);
468 
469  /* Wait for the result. */
470  return pgfdw_get_result(conn, query);
471 }
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:538
PGresult * pgfdw_get_result(PGconn *conn, const char *query)
Definition: connection.c:484
#define NULL
Definition: c.h:226
PGresult* pgfdw_get_result ( PGconn conn,
const char *  query 
)

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

485 {
486  PGresult *last_res = NULL;
487 
488  for (;;)
489  {
490  PGresult *res;
491 
492  while (PQisBusy(conn))
493  {
494  int wc;
495 
496  /* Sleep until there's something to do */
499  PQsocket(conn),
500  -1L, PG_WAIT_EXTENSION);
502 
504 
505  /* Data available in socket */
506  if (wc & WL_SOCKET_READABLE)
507  {
508  if (!PQconsumeInput(conn))
509  pgfdw_report_error(ERROR, NULL, conn, false, query);
510  }
511  }
512 
513  res = PQgetResult(conn);
514  if (res == NULL)
515  break; /* query is complete */
516 
517  PQclear(last_res);
518  last_res = res;
519  }
520 
521  return last_res;
522 }
#define WL_SOCKET_READABLE
Definition: latch.h:125
void ResetLatch(volatile Latch *latch)
Definition: latch.c:462
#define ERROR
Definition: elog.h:43
void pgfdw_report_error(int elevel, PGresult *res, PGconn *conn, bool clear, const char *sql)
Definition: connection.c:538
#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:226
int WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock, long timeout, uint32 wait_event_info)
Definition: latch.c:321
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:5978
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 538 of file connection.c.

References ereport, errcode(), errcontext, errdetail_internal(), errhint(), errmsg(), errmsg_internal(), MAKE_SQLSTATE, NULL, 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().

540 {
541  /* If requested, PGresult must be released before leaving this function. */
542  PG_TRY();
543  {
544  char *diag_sqlstate = PQresultErrorField(res, PG_DIAG_SQLSTATE);
545  char *message_primary = PQresultErrorField(res, PG_DIAG_MESSAGE_PRIMARY);
546  char *message_detail = PQresultErrorField(res, PG_DIAG_MESSAGE_DETAIL);
547  char *message_hint = PQresultErrorField(res, PG_DIAG_MESSAGE_HINT);
548  char *message_context = PQresultErrorField(res, PG_DIAG_CONTEXT);
549  int sqlstate;
550 
551  if (diag_sqlstate)
552  sqlstate = MAKE_SQLSTATE(diag_sqlstate[0],
553  diag_sqlstate[1],
554  diag_sqlstate[2],
555  diag_sqlstate[3],
556  diag_sqlstate[4]);
557  else
558  sqlstate = ERRCODE_CONNECTION_FAILURE;
559 
560  /*
561  * If we don't get a message from the PGresult, try the PGconn. This
562  * is needed because for connection-level failures, PQexec may just
563  * return NULL, not a PGresult at all.
564  */
565  if (message_primary == NULL)
566  message_primary = PQerrorMessage(conn);
567 
568  ereport(elevel,
569  (errcode(sqlstate),
570  message_primary ? errmsg_internal("%s", message_primary) :
571  errmsg("could not obtain message string for remote error"),
572  message_detail ? errdetail_internal("%s", message_detail) : 0,
573  message_hint ? errhint("%s", message_hint) : 0,
574  message_context ? errcontext("%s", message_context) : 0,
575  sql ? errcontext("Remote SQL command: %s", sql) : 0));
576  }
577  PG_CATCH();
578  {
579  if (clear)
580  PQclear(res);
581  PG_RE_THROW();
582  }
583  PG_END_TRY();
584  if (clear)
585  PQclear(res);
586 }
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:5960
int errhint(const char *fmt,...)
Definition: elog.c:987
#define PG_DIAG_MESSAGE_PRIMARY
Definition: postgres_ext.h:54
#define PG_DIAG_MESSAGE_DETAIL
Definition: postgres_ext.h:55
#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:53
int errdetail_internal(const char *fmt,...)
Definition: elog.c:900
#define ereport(elevel, rest)
Definition: elog.h:122
static int elevel
Definition: vacuumlazy.c:136
#define PG_DIAG_MESSAGE_HINT
Definition: postgres_ext.h:56
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:226
#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:60
void ReleaseConnection ( PGconn conn)

Definition at line 412 of file connection.c.

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

413 {
414  /*
415  * Currently, we don't actually track connection references because all
416  * cleanup is managed on a transaction or subtransaction basis instead. So
417  * there's nothing to do here.
418  */
419 }
void reset_transmission_modes ( int  nestlevel)

Definition at line 3096 of file postgres_fdw.c.

References AtEOXact_GUC().

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

3097 {
3098  AtEOXact_GUC(true, nestlevel);
3099 }
void AtEOXact_GUC(bool isCommit, int nestLevel)
Definition: guc.c:5036
int set_transmission_modes ( void  )

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

3069 {
3070  int nestlevel = NewGUCNestLevel();
3071 
3072  /*
3073  * The values set here should match what pg_dump does. See also
3074  * configure_remote_session in connection.c.
3075  */
3076  if (DateStyle != USE_ISO_DATES)
3077  (void) set_config_option("datestyle", "ISO",
3079  GUC_ACTION_SAVE, true, 0, false);
3081  (void) set_config_option("intervalstyle", "postgres",
3083  GUC_ACTION_SAVE, true, 0, false);
3084  if (extra_float_digits < 3)
3085  (void) set_config_option("extra_float_digits", "3",
3087  GUC_ACTION_SAVE, true, 0, false);
3088 
3089  return nestlevel;
3090 }
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:5022
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:5865
#define INTSTYLE_POSTGRES
Definition: miscadmin.h:230