PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
postgres_fdw.h File Reference
#include "foreign/foreign.h"
#include "lib/stringinfo.h"
#include "libpq-fe.h"
#include "nodes/execnodes.h"
#include "nodes/pathnodes.h"
#include "utils/relcache.h"
Include dependency graph for postgres_fdw.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  PgFdwRelationInfo
 
struct  PgFdwConnState
 

Typedefs

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

Enumerations

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

Functions

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

Variables

char * pgfdw_application_name
 

Typedef Documentation

◆ PgFdwConnState

◆ PgFdwRelationInfo

◆ PgFdwSamplingMethod

Enumeration Type Documentation

◆ PgFdwSamplingMethod

Enumerator
ANALYZE_SAMPLE_OFF 
ANALYZE_SAMPLE_AUTO 
ANALYZE_SAMPLE_RANDOM 
ANALYZE_SAMPLE_SYSTEM 
ANALYZE_SAMPLE_BERNOULLI 

Definition at line 145 of file postgres_fdw.h.

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

Function Documentation

◆ build_tlist_to_deparse()

List * build_tlist_to_deparse ( RelOptInfo foreignrel)

Definition at line 1174 of file deparse.c.

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

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

Referenced by estimate_path_cost_size(), and postgresGetForeignPlan().

◆ classifyConditions()

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

Definition at line 216 of file deparse.c.

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

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

Referenced by estimate_path_cost_size(), and postgresGetForeignRelSize().

◆ deparseAnalyzeInfoSql()

void deparseAnalyzeInfoSql ( StringInfo  buf,
Relation  rel 
)

Definition at line 2519 of file deparse.c.

2520{
2522
2523 /* We'll need the remote relation name as a literal. */
2525 deparseRelation(&relname, rel);
2526
2527 appendStringInfoString(buf, "SELECT reltuples, relkind FROM pg_catalog.pg_class WHERE oid = ");
2529 appendStringInfoString(buf, "::pg_catalog.regclass");
2530}
void deparseStringLiteral(StringInfo buf, const char *val)
Definition: deparse.c:2847
static void deparseRelation(StringInfo buf, Relation rel)
Definition: deparse.c:2807
NameData relname
Definition: pg_class.h:38
static char * buf
Definition: pg_test_fsync.c:72
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:230
void initStringInfo(StringInfo str)
Definition: stringinfo.c:97
char data[NAMEDATALEN]
Definition: c.h:699

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

Referenced by postgresGetAnalyzeInfoForForeignTable().

◆ deparseAnalyzeSizeSql()

void deparseAnalyzeSizeSql ( StringInfo  buf,
Relation  rel 
)

Definition at line 2497 of file deparse.c.

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

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

Referenced by postgresAnalyzeForeignTable().

◆ deparseAnalyzeSql()

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

Definition at line 2559 of file deparse.c.

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

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

Referenced by postgresAcquireSampleRowsFunc().

◆ deparseDeleteSql()

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

Definition at line 2360 of file deparse.c.

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

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

Referenced by postgresPlanForeignModify().

◆ deparseDirectDeleteSql()

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

Definition at line 2389 of file deparse.c.

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

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

Referenced by postgresPlanDirectModify().

◆ deparseDirectUpdateSql()

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

Definition at line 2274 of file deparse.c.

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

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

Referenced by postgresPlanDirectModify().

◆ deparseInsertSql()

void deparseInsertSql ( StringInfo  buf,
RangeTblEntry rte,
Index  rtindex,
Relation  rel,
List targetAttrs,
bool  doNothing,
List withCheckOptionList,
List returningList,
List **  retrieved_attrs,
int *  values_end_len 
)

Definition at line 2081 of file deparse.c.

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

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

Referenced by postgresBeginForeignInsert(), and postgresPlanForeignModify().

◆ deparseSelectStmtForRel()

void deparseSelectStmtForRel ( StringInfo  buf,
PlannerInfo root,
RelOptInfo rel,
List tlist,
List remote_conds,
List pathkeys,
bool  has_final_sort,
bool  has_limit,
bool  is_subquery,
List **  retrieved_attrs,
List **  params_list 
)

Definition at line 1231 of file deparse.c.

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

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

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

◆ deparseStringLiteral()

void deparseStringLiteral ( StringInfo  buf,
const char *  val 
)

Definition at line 2847 of file deparse.c.

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

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

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

◆ deparseTruncateSql()

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

Definition at line 2644 of file deparse.c.

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

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

Referenced by postgresExecForeignTruncate().

◆ deparseUpdateSql()

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

Definition at line 2214 of file deparse.c.

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

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

Referenced by postgresPlanForeignModify().

◆ do_sql_command()

void do_sql_command ( PGconn conn,
const char *  sql 
)

Definition at line 784 of file connection.c.

785{
787 do_sql_command_end(conn, sql, false);
788}
static void do_sql_command_end(PGconn *conn, const char *sql, bool consume_input)
Definition: connection.c:798
static void do_sql_command_begin(PGconn *conn, const char *sql)
Definition: connection.c:791
PGconn * conn
Definition: streamutil.c:53

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

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

◆ ExtractConnectionOptions()

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

Definition at line 416 of file option.c.

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

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

Referenced by connect_pg_server().

◆ ExtractExtensionList()

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

Definition at line 447 of file option.c.

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

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

Referenced by apply_server_options(), and postgres_fdw_validator().

◆ find_em_for_rel()

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

Definition at line 7829 of file postgres_fdw.c.

7830{
7831 ListCell *lc;
7832
7833 PgFdwRelationInfo *fpinfo = (PgFdwRelationInfo *) rel->fdw_private;
7834
7835 foreach(lc, ec->ec_members)
7836 {
7838
7839 /*
7840 * Note we require !bms_is_empty, else we'd accept constant
7841 * expressions which are not suitable for the purpose.
7842 */
7843 if (bms_is_subset(em->em_relids, rel->relids) &&
7844 !bms_is_empty(em->em_relids) &&
7846 is_foreign_expr(root, rel, em->em_expr))
7847 return em;
7848 }
7849
7850 return NULL;
7851}
Bitmapset * bms_intersect(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:292
bool bms_is_subset(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:412
#define bms_is_empty(a)
Definition: bitmapset.h:118
Relids hidden_subquery_rels
Definition: postgres_fdw.h:122
Relids relids
Definition: pathnodes.h:871

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

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

◆ find_em_for_rel_target()

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

Definition at line 7865 of file postgres_fdw.c.

7867{
7868 PathTarget *target = rel->reltarget;
7869 ListCell *lc1;
7870 int i;
7871
7872 i = 0;
7873 foreach(lc1, target->exprs)
7874 {
7875 Expr *expr = (Expr *) lfirst(lc1);
7876 Index sgref = get_pathtarget_sortgroupref(target, i);
7877 ListCell *lc2;
7878
7879 /* Ignore non-sort expressions */
7880 if (sgref == 0 ||
7882 root->parse->sortClause) == NULL)
7883 {
7884 i++;
7885 continue;
7886 }
7887
7888 /* We ignore binary-compatible relabeling on both ends */
7889 while (expr && IsA(expr, RelabelType))
7890 expr = ((RelabelType *) expr)->arg;
7891
7892 /* Locate an EquivalenceClass member matching this expr, if any */
7893 foreach(lc2, ec->ec_members)
7894 {
7896 Expr *em_expr;
7897
7898 /* Don't match constants */
7899 if (em->em_is_const)
7900 continue;
7901
7902 /* Ignore child members */
7903 if (em->em_is_child)
7904 continue;
7905
7906 /* Match if same expression (after stripping relabel) */
7907 em_expr = em->em_expr;
7908 while (em_expr && IsA(em_expr, RelabelType))
7909 em_expr = ((RelabelType *) em_expr)->arg;
7910
7911 if (!equal(em_expr, expr))
7912 continue;
7913
7914 /* Check that expression (including relabels!) is shippable */
7915 if (is_foreign_expr(root, rel, em->em_expr))
7916 return em;
7917 }
7918
7919 i++;
7920 }
7921
7922 return NULL;
7923}
unsigned int Index
Definition: c.h:571
bool equal(const void *a, const void *b)
Definition: equalfuncs.c:223
#define IsA(nodeptr, _type_)
Definition: nodes.h:158
#define get_pathtarget_sortgroupref(target, colno)
Definition: pathnodes.h:1560
void * arg
SortGroupClause * get_sortgroupref_clause_noerr(Index sortref, List *clauses)
Definition: tlist.c:443

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

Referenced by add_foreign_ordered_paths(), and appendOrderByClause().

◆ get_jointype_name()

const char * get_jointype_name ( JoinType  jointype)

Definition at line 1639 of file deparse.c.

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

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

Referenced by deparseFromExprForRel(), and foreign_join_ok().

◆ GetConnection()

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

Definition at line 202 of file connection.c.

203{
204 bool found;
205 bool retry = false;
206 ConnCacheEntry *entry;
209
210 /* First time through, initialize connection cache hashtable */
211 if (ConnectionHash == NULL)
212 {
213 HASHCTL ctl;
214
215 if (pgfdw_we_get_result == 0)
217 WaitEventExtensionNew("PostgresFdwGetResult");
218
219 ctl.keysize = sizeof(ConnCacheKey);
220 ctl.entrysize = sizeof(ConnCacheEntry);
221 ConnectionHash = hash_create("postgres_fdw connections", 8,
222 &ctl,
224
225 /*
226 * Register some callback functions that manage connection cleanup.
227 * This should be done just once in each backend.
228 */
231 CacheRegisterSyscacheCallback(FOREIGNSERVEROID,
233 CacheRegisterSyscacheCallback(USERMAPPINGOID,
235 }
236
237 /* Set flag that we did GetConnection during the current transaction */
238 xact_got_connection = true;
239
240 /* Create hash key for the entry. Assume no pad bytes in key struct */
241 key = user->umid;
242
243 /*
244 * Find or create cached entry for requested connection.
245 */
246 entry = hash_search(ConnectionHash, &key, HASH_ENTER, &found);
247 if (!found)
248 {
249 /*
250 * We need only clear "conn" here; remaining fields will be filled
251 * later when "conn" is set.
252 */
253 entry->conn = NULL;
254 }
255
256 /* Reject further use of connections which failed abort cleanup. */
258
259 /*
260 * If the connection needs to be remade due to invalidation, disconnect as
261 * soon as we're out of all transactions.
262 */
263 if (entry->conn != NULL && entry->invalidated && entry->xact_depth == 0)
264 {
265 elog(DEBUG3, "closing connection %p for option changes to take effect",
266 entry->conn);
268 }
269
270 /*
271 * If cache entry doesn't have a connection, we have to establish a new
272 * connection. (If connect_pg_server throws an error, the cache entry
273 * will remain in a valid empty state, ie conn == NULL.)
274 */
275 if (entry->conn == NULL)
277
278 /*
279 * We check the health of the cached connection here when using it. In
280 * cases where we're out of all transactions, if a broken connection is
281 * detected, we try to reestablish a new connection later.
282 */
283 PG_TRY();
284 {
285 /* Process a pending asynchronous request if any. */
286 if (entry->state.pendingAreq)
288 /* Start a new transaction or subtransaction if needed. */
289 begin_remote_xact(entry);
290 }
291 PG_CATCH();
292 {
294 ErrorData *errdata = CopyErrorData();
295
296 /*
297 * Determine whether to try to reestablish the connection.
298 *
299 * After a broken connection is detected in libpq, any error other
300 * than connection failure (e.g., out-of-memory) can be thrown
301 * somewhere between return from libpq and the expected ereport() call
302 * in pgfdw_report_error(). In this case, since PQstatus() indicates
303 * CONNECTION_BAD, checking only PQstatus() causes the false detection
304 * of connection failure. To avoid this, we also verify that the
305 * error's sqlstate is ERRCODE_CONNECTION_FAILURE. Note that also
306 * checking only the sqlstate can cause another false detection
307 * because pgfdw_report_error() may report ERRCODE_CONNECTION_FAILURE
308 * for any libpq-originated error condition.
309 */
310 if (errdata->sqlerrcode != ERRCODE_CONNECTION_FAILURE ||
311 PQstatus(entry->conn) != CONNECTION_BAD ||
312 entry->xact_depth > 0)
313 {
315 PG_RE_THROW();
316 }
317
318 /* Clean up the error state */
320 FreeErrorData(errdata);
321 errdata = NULL;
322
323 retry = true;
324 }
325 PG_END_TRY();
326
327 /*
328 * If a broken connection is detected, disconnect it, reestablish a new
329 * connection and retry a new remote transaction. If connection failure is
330 * reported again, we give up getting a connection.
331 */
332 if (retry)
333 {
334 Assert(entry->xact_depth == 0);
335
337 (errmsg_internal("could not start remote transaction on connection %p",
338 entry->conn)),
340
341 elog(DEBUG3, "closing connection %p to reestablish a new one",
342 entry->conn);
344
346
347 begin_remote_xact(entry);
348 }
349
350 /* Remember if caller will prepare statements */
351 entry->have_prep_stmt |= will_prep_stmt;
352
353 /* If caller needs access to the per-connection state, return it. */
354 if (state)
355 *state = &entry->state;
356
357 return entry->conn;
358}
Oid ConnCacheKey
Definition: connection.c:52
static void disconnect_pg_server(ConnCacheEntry *entry)
Definition: connection.c:641
static uint32 pgfdw_we_get_result
Definition: connection.c:90
static bool xact_got_connection
Definition: connection.c:85
struct ConnCacheEntry ConnCacheEntry
static HTAB * ConnectionHash
Definition: connection.c:78
static void make_new_connection(ConnCacheEntry *entry, UserMapping *user)
Definition: connection.c:365
static void pgfdw_subxact_callback(SubXactEvent event, SubTransactionId mySubid, SubTransactionId parentSubid, void *arg)
Definition: connection.c:1162
static void pgfdw_reject_incomplete_xact_state_change(ConnCacheEntry *entry)
Definition: connection.c:1325
static void pgfdw_inval_callback(Datum arg, int cacheid, uint32 hashvalue)
Definition: connection.c:1275
static void pgfdw_xact_callback(XactEvent event, void *arg)
Definition: connection.c:1012
static void begin_remote_xact(ConnCacheEntry *entry)
Definition: connection.c:827
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:955
HTAB * hash_create(const char *tabname, long nelem, const HASHCTL *info, int flags)
Definition: dynahash.c:352
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1157
void FreeErrorData(ErrorData *edata)
Definition: elog.c:1818
int errdetail_internal(const char *fmt,...)
Definition: elog.c:1230
ErrorData * CopyErrorData(void)
Definition: elog.c:1746
void FlushErrorState(void)
Definition: elog.c:1867
#define PG_RE_THROW()
Definition: elog.h:412
#define DEBUG3
Definition: elog.h:28
#define PG_TRY(...)
Definition: elog.h:371
#define PG_END_TRY(...)
Definition: elog.h:396
#define PG_CATCH(...)
Definition: elog.h:381
ConnStatusType PQstatus(const PGconn *conn)
Definition: fe-connect.c:7205
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:7268
@ HASH_ENTER
Definition: hsearch.h:114
#define HASH_ELEM
Definition: hsearch.h:95
#define HASH_BLOBS
Definition: hsearch.h:97
void CacheRegisterSyscacheCallback(int cacheid, SyscacheCallbackFunction func, Datum arg)
Definition: inval.c:1704
@ CONNECTION_BAD
Definition: libpq-fe.h:82
char * pchomp(const char *in)
Definition: mcxt.c:1724
MemoryContext CurrentMemoryContext
Definition: mcxt.c:143
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124
static char * user
Definition: pg_regress.c:119
uintptr_t Datum
Definition: postgres.h:69
void process_pending_request(AsyncRequest *areq)
tree ctl
Definition: radixtree.h:1838
PGconn * conn
Definition: connection.c:57
bool have_prep_stmt
Definition: connection.c:61
PgFdwConnState state
Definition: connection.c:72
bool invalidated
Definition: connection.c:66
int sqlerrcode
Definition: elog.h:439
AsyncRequest * pendingAreq
Definition: postgres_fdw.h:139
Definition: regguts.h:323
uint32 WaitEventExtensionNew(const char *wait_event_name)
Definition: wait_event.c:163
void RegisterXactCallback(XactCallback callback, void *arg)
Definition: xact.c:3796
void RegisterSubXactCallback(SubXactCallback callback, void *arg)
Definition: xact.c:3856

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

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

◆ GetCursorNumber()

unsigned int GetCursorNumber ( PGconn conn)

Definition at line 891 of file connection.c.

892{
893 return ++cursor_number;
894}
static unsigned int cursor_number
Definition: connection.c:81

References cursor_number.

Referenced by postgresAcquireSampleRowsFunc(), and postgresBeginForeignScan().

◆ GetPrepStmtNumber()

unsigned int GetPrepStmtNumber ( PGconn conn)

Definition at line 905 of file connection.c.

906{
907 return ++prep_stmt_number;
908}
static unsigned int prep_stmt_number
Definition: connection.c:82

References prep_stmt_number.

Referenced by prepare_foreign_modify().

◆ is_builtin()

bool is_builtin ( Oid  objectId)

Definition at line 152 of file shippable.c.

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

References FirstGenbkiObjectId.

Referenced by deparse_type_name(), and is_shippable().

◆ is_foreign_expr()

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

Definition at line 242 of file deparse.c.

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

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

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

◆ is_foreign_param()

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

Definition at line 1080 of file deparse.c.

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

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

Referenced by foreign_grouping_ok().

◆ is_foreign_pathkey()

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

Definition at line 1121 of file deparse.c.

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

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

Referenced by get_useful_pathkeys_for_relation().

◆ is_shippable()

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

Definition at line 162 of file shippable.c.

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

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

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

◆ pgfdw_exec_query()

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

Definition at line 920 of file connection.c.

921{
922 /* First, process a pending asynchronous request, if any. */
923 if (state && state->pendingAreq)
924 process_pending_request(state->pendingAreq);
925
926 if (!PQsendQuery(conn, query))
927 return NULL;
928 return pgfdw_get_result(conn);
929}
PGresult * pgfdw_get_result(PGconn *conn)
Definition: connection.c:937
int PQsendQuery(PGconn *conn, const char *query)
Definition: fe-exec.c:1416

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

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

◆ pgfdw_get_result()

PGresult * pgfdw_get_result ( PGconn conn)

Definition at line 937 of file connection.c.

938{
940}
static PGresult * libpqsrv_get_result_last(PGconn *conn, uint32 wait_event_info)

References conn, libpqsrv_get_result_last(), and pgfdw_we_get_result.

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

◆ pgfdw_report_error()

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

Definition at line 956 of file connection.c.

958{
959 /* If requested, PGresult must be released before leaving this function. */
960 PG_TRY();
961 {
962 char *diag_sqlstate = PQresultErrorField(res, PG_DIAG_SQLSTATE);
963 char *message_primary = PQresultErrorField(res, PG_DIAG_MESSAGE_PRIMARY);
964 char *message_detail = PQresultErrorField(res, PG_DIAG_MESSAGE_DETAIL);
965 char *message_hint = PQresultErrorField(res, PG_DIAG_MESSAGE_HINT);
966 char *message_context = PQresultErrorField(res, PG_DIAG_CONTEXT);
967 int sqlstate;
968
969 if (diag_sqlstate)
970 sqlstate = MAKE_SQLSTATE(diag_sqlstate[0],
971 diag_sqlstate[1],
972 diag_sqlstate[2],
973 diag_sqlstate[3],
974 diag_sqlstate[4]);
975 else
976 sqlstate = ERRCODE_CONNECTION_FAILURE;
977
978 /*
979 * If we don't get a message from the PGresult, try the PGconn. This
980 * is needed because for connection-level failures, PQgetResult may
981 * just return NULL, not a PGresult at all.
982 */
983 if (message_primary == NULL)
984 message_primary = pchomp(PQerrorMessage(conn));
985
986 ereport(elevel,
987 (errcode(sqlstate),
988 (message_primary != NULL && message_primary[0] != '\0') ?
989 errmsg_internal("%s", message_primary) :
990 errmsg("could not obtain message string for remote error"),
991 message_detail ? errdetail_internal("%s", message_detail) : 0,
992 message_hint ? errhint("%s", message_hint) : 0,
993 message_context ? errcontext("%s", message_context) : 0,
994 sql ? errcontext("remote SQL command: %s", sql) : 0));
995 }
996 PG_FINALLY();
997 {
998 if (clear)
999 PQclear(res);
1000 }
1001 PG_END_TRY();
1002}
int errhint(const char *fmt,...)
Definition: elog.c:1317
#define errcontext
Definition: elog.h:196
#define MAKE_SQLSTATE(ch1, ch2, ch3, ch4, ch5)
Definition: elog.h:56
#define PG_FINALLY(...)
Definition: elog.h:388
char * PQresultErrorField(const PGresult *res, int fieldcode)
Definition: fe-exec.c:3466
#define PG_DIAG_MESSAGE_HINT
Definition: postgres_ext.h:60
#define PG_DIAG_SQLSTATE
Definition: postgres_ext.h:57
#define PG_DIAG_MESSAGE_PRIMARY
Definition: postgres_ext.h:58
#define PG_DIAG_MESSAGE_DETAIL
Definition: postgres_ext.h:59
#define PG_DIAG_CONTEXT
Definition: postgres_ext.h:64

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

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

◆ process_pending_request()

void process_pending_request ( AsyncRequest areq)

Definition at line 7502 of file postgres_fdw.c.

7503{
7505 PgFdwScanState *fsstate = (PgFdwScanState *) node->fdw_state;
7506
7507 /* The request would have been pending for a callback */
7508 Assert(areq->callback_pending);
7509
7510 /* The request should be currently in-process */
7511 Assert(fsstate->conn_state->pendingAreq == areq);
7512
7513 fetch_more_data(node);
7514
7515 /*
7516 * If we didn't get any tuples, must be end of data; complete the request
7517 * now. Otherwise, we postpone completing the request until we are called
7518 * from postgresForeignAsyncConfigureWait()/postgresForeignAsyncNotify().
7519 */
7520 if (fsstate->next_tuple >= fsstate->num_tuples)
7521 {
7522 /* Unlike AsyncNotify, we unset callback_pending ourselves */
7523 areq->callback_pending = false;
7524 /* Mark the request as complete */
7525 ExecAsyncRequestDone(areq, NULL);
7526 /* Unlike AsyncNotify, we call ExecAsyncResponse ourselves */
7527 ExecAsyncResponse(areq);
7528 }
7529}
void ExecAsyncResponse(AsyncRequest *areq)
Definition: execAsync.c:117
void ExecAsyncRequestDone(AsyncRequest *areq, TupleTableSlot *result)
Definition: execAsync.c:137
static void fetch_more_data(ForeignScanState *node)
bool callback_pending
Definition: execnodes.h:630
struct PlanState * requestee
Definition: execnodes.h:628

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

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

◆ process_pgfdw_appname()

char * process_pgfdw_appname ( const char *  appname)

Definition at line 493 of file option.c.

494{
495 const char *p;
497
499
500 for (p = appname; *p != '\0'; p++)
501 {
502 if (*p != '%')
503 {
504 /* literal char, just copy */
506 continue;
507 }
508
509 /* must be a '%', so skip to the next char */
510 p++;
511 if (*p == '\0')
512 break; /* format error - ignore it */
513 else if (*p == '%')
514 {
515 /* string contains %% */
517 continue;
518 }
519
520 /* process the option */
521 switch (*p)
522 {
523 case 'a':
525 break;
526 case 'c':
528 break;
529 case 'C':
531 break;
532 case 'd':
533 if (MyProcPort)
534 {
535 const char *dbname = MyProcPort->database_name;
536
537 if (dbname)
539 else
540 appendStringInfoString(&buf, "[unknown]");
541 }
542 break;
543 case 'p':
545 break;
546 case 'u':
547 if (MyProcPort)
548 {
549 const char *username = MyProcPort->user_name;
550
551 if (username)
553 else
554 appendStringInfoString(&buf, "[unknown]");
555 }
556 break;
557 default:
558 /* format error - ignore it */
559 break;
560 }
561 }
562
563 return buf.data;
564}
#define INT64_HEX_FORMAT
Definition: c.h:508
int MyProcPid
Definition: globals.c:46
struct Port * MyProcPort
Definition: globals.c:50
pg_time_t MyStartTime
Definition: globals.c:47
char * cluster_name
Definition: guc_tables.c:537
char * application_name
Definition: guc_tables.c:543
static char * username
Definition: initdb.c:153
char * dbname
Definition: streamutil.c:50
char * user_name
Definition: libpq-be.h:154
char * database_name
Definition: libpq-be.h:153

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

Referenced by connect_pg_server().

◆ rebuildInsertSql()

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

Definition at line 2154 of file deparse.c.

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

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

Referenced by execute_foreign_modify().

◆ ReleaseConnection()

void ReleaseConnection ( PGconn conn)

Definition at line 870 of file connection.c.

871{
872 /*
873 * Currently, we don't actually track connection references because all
874 * cleanup is managed on a transaction or subtransaction basis instead. So
875 * there's nothing to do here.
876 */
877}

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

◆ reset_transmission_modes()

void reset_transmission_modes ( int  nestlevel)

Definition at line 3943 of file postgres_fdw.c.

3944{
3945 AtEOXact_GUC(true, nestlevel);
3946}
void AtEOXact_GUC(bool isCommit, int nestLevel)
Definition: guc.c:2262

References AtEOXact_GUC().

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

◆ set_transmission_modes()

int set_transmission_modes ( void  )

Definition at line 3907 of file postgres_fdw.c.

3908{
3909 int nestlevel = NewGUCNestLevel();
3910
3911 /*
3912 * The values set here should match what pg_dump does. See also
3913 * configure_remote_session in connection.c.
3914 */
3915 if (DateStyle != USE_ISO_DATES)
3916 (void) set_config_option("datestyle", "ISO",
3918 GUC_ACTION_SAVE, true, 0, false);
3920 (void) set_config_option("intervalstyle", "postgres",
3922 GUC_ACTION_SAVE, true, 0, false);
3923 if (extra_float_digits < 3)
3924 (void) set_config_option("extra_float_digits", "3",
3926 GUC_ACTION_SAVE, true, 0, false);
3927
3928 /*
3929 * In addition force restrictive search_path, in case there are any
3930 * regproc or similar constants to be printed.
3931 */
3932 (void) set_config_option("search_path", "pg_catalog",
3934 GUC_ACTION_SAVE, true, 0, false);
3935
3936 return nestlevel;
3937}
int extra_float_digits
Definition: float.c:40
int DateStyle
Definition: globals.c:124
int IntervalStyle
Definition: globals.c:126
int NewGUCNestLevel(void)
Definition: guc.c:2235
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:3342
@ GUC_ACTION_SAVE
Definition: guc.h:201
@ PGC_S_SESSION
Definition: guc.h:122
@ PGC_USERSET
Definition: guc.h:75
#define USE_ISO_DATES
Definition: miscadmin.h:236
#define INTSTYLE_POSTGRES
Definition: miscadmin.h:256

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

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

Variable Documentation

◆ pgfdw_application_name

char* pgfdw_application_name
extern

Definition at line 51 of file option.c.

Referenced by _PG_init(), and connect_pg_server().