]> granicus.if.org Git - postgresql/blob - contrib/postgres_fdw/deparse.c
Replace heapam.h includes with {table, relation}.h where applicable.
[postgresql] / contrib / postgres_fdw / deparse.c
1 /*-------------------------------------------------------------------------
2  *
3  * deparse.c
4  *                Query deparser for postgres_fdw
5  *
6  * This file includes functions that examine query WHERE clauses to see
7  * whether they're safe to send to the remote server for execution, as
8  * well as functions to construct the query text to be sent.  The latter
9  * functionality is annoyingly duplicative of ruleutils.c, but there are
10  * enough special considerations that it seems best to keep this separate.
11  * One saving grace is that we only need deparse logic for node types that
12  * we consider safe to send.
13  *
14  * We assume that the remote session's search_path is exactly "pg_catalog",
15  * and thus we need schema-qualify all and only names outside pg_catalog.
16  *
17  * We do not consider that it is ever safe to send COLLATE expressions to
18  * the remote server: it might not have the same collation names we do.
19  * (Later we might consider it safe to send COLLATE "C", but even that would
20  * fail on old remote servers.)  An expression is considered safe to send
21  * only if all operator/function input collations used in it are traceable to
22  * Var(s) of the foreign table.  That implies that if the remote server gets
23  * a different answer than we do, the foreign table's columns are not marked
24  * with collations that match the remote table's columns, which we can
25  * consider to be user error.
26  *
27  * Portions Copyright (c) 2012-2019, PostgreSQL Global Development Group
28  *
29  * IDENTIFICATION
30  *                contrib/postgres_fdw/deparse.c
31  *
32  *-------------------------------------------------------------------------
33  */
34 #include "postgres.h"
35
36 #include "postgres_fdw.h"
37
38 #include "access/htup_details.h"
39 #include "access/sysattr.h"
40 #include "access/table.h"
41 #include "catalog/pg_aggregate.h"
42 #include "catalog/pg_collation.h"
43 #include "catalog/pg_namespace.h"
44 #include "catalog/pg_operator.h"
45 #include "catalog/pg_proc.h"
46 #include "catalog/pg_type.h"
47 #include "commands/defrem.h"
48 #include "nodes/makefuncs.h"
49 #include "nodes/nodeFuncs.h"
50 #include "nodes/plannodes.h"
51 #include "optimizer/clauses.h"
52 #include "optimizer/prep.h"
53 #include "optimizer/tlist.h"
54 #include "optimizer/var.h"
55 #include "parser/parsetree.h"
56 #include "utils/builtins.h"
57 #include "utils/lsyscache.h"
58 #include "utils/rel.h"
59 #include "utils/syscache.h"
60 #include "utils/typcache.h"
61
62
63 /*
64  * Global context for foreign_expr_walker's search of an expression tree.
65  */
66 typedef struct foreign_glob_cxt
67 {
68         PlannerInfo *root;                      /* global planner state */
69         RelOptInfo *foreignrel;         /* the foreign relation we are planning for */
70         Relids          relids;                 /* relids of base relations in the underlying
71                                                                  * scan */
72 } foreign_glob_cxt;
73
74 /*
75  * Local (per-tree-level) context for foreign_expr_walker's search.
76  * This is concerned with identifying collations used in the expression.
77  */
78 typedef enum
79 {
80         FDW_COLLATE_NONE,                       /* expression is of a noncollatable type, or
81                                                                  * it has default collation that is not
82                                                                  * traceable to a foreign Var */
83         FDW_COLLATE_SAFE,                       /* collation derives from a foreign Var */
84         FDW_COLLATE_UNSAFE                      /* collation is non-default and derives from
85                                                                  * something other than a foreign Var */
86 } FDWCollateState;
87
88 typedef struct foreign_loc_cxt
89 {
90         Oid                     collation;              /* OID of current collation, if any */
91         FDWCollateState state;          /* state of current collation choice */
92 } foreign_loc_cxt;
93
94 /*
95  * Context for deparseExpr
96  */
97 typedef struct deparse_expr_cxt
98 {
99         PlannerInfo *root;                      /* global planner state */
100         RelOptInfo *foreignrel;         /* the foreign relation we are planning for */
101         RelOptInfo *scanrel;            /* the underlying scan relation. Same as
102                                                                  * foreignrel, when that represents a join or
103                                                                  * a base relation. */
104         StringInfo      buf;                    /* output buffer to append to */
105         List      **params_list;        /* exprs that will become remote Params */
106 } deparse_expr_cxt;
107
108 #define REL_ALIAS_PREFIX        "r"
109 /* Handy macro to add relation name qualification */
110 #define ADD_REL_QUALIFIER(buf, varno)   \
111                 appendStringInfo((buf), "%s%d.", REL_ALIAS_PREFIX, (varno))
112 #define SUBQUERY_REL_ALIAS_PREFIX       "s"
113 #define SUBQUERY_COL_ALIAS_PREFIX       "c"
114
115 /*
116  * Functions to determine whether an expression can be evaluated safely on
117  * remote server.
118  */
119 static bool foreign_expr_walker(Node *node,
120                                         foreign_glob_cxt *glob_cxt,
121                                         foreign_loc_cxt *outer_cxt);
122 static char *deparse_type_name(Oid type_oid, int32 typemod);
123
124 /*
125  * Functions to construct string representation of a node tree.
126  */
127 static void deparseTargetList(StringInfo buf,
128                                   RangeTblEntry *rte,
129                                   Index rtindex,
130                                   Relation rel,
131                                   bool is_returning,
132                                   Bitmapset *attrs_used,
133                                   bool qualify_col,
134                                   List **retrieved_attrs);
135 static void deparseExplicitTargetList(List *tlist,
136                                                   bool is_returning,
137                                                   List **retrieved_attrs,
138                                                   deparse_expr_cxt *context);
139 static void deparseSubqueryTargetList(deparse_expr_cxt *context);
140 static void deparseReturningList(StringInfo buf, RangeTblEntry *rte,
141                                          Index rtindex, Relation rel,
142                                          bool trig_after_row,
143                                          List *withCheckOptionList,
144                                          List *returningList,
145                                          List **retrieved_attrs);
146 static void deparseColumnRef(StringInfo buf, int varno, int varattno,
147                                  RangeTblEntry *rte, bool qualify_col);
148 static void deparseRelation(StringInfo buf, Relation rel);
149 static void deparseExpr(Expr *expr, deparse_expr_cxt *context);
150 static void deparseVar(Var *node, deparse_expr_cxt *context);
151 static void deparseConst(Const *node, deparse_expr_cxt *context, int showtype);
152 static void deparseParam(Param *node, deparse_expr_cxt *context);
153 static void deparseArrayRef(ArrayRef *node, deparse_expr_cxt *context);
154 static void deparseFuncExpr(FuncExpr *node, deparse_expr_cxt *context);
155 static void deparseOpExpr(OpExpr *node, deparse_expr_cxt *context);
156 static void deparseOperatorName(StringInfo buf, Form_pg_operator opform);
157 static void deparseDistinctExpr(DistinctExpr *node, deparse_expr_cxt *context);
158 static void deparseScalarArrayOpExpr(ScalarArrayOpExpr *node,
159                                                  deparse_expr_cxt *context);
160 static void deparseRelabelType(RelabelType *node, deparse_expr_cxt *context);
161 static void deparseBoolExpr(BoolExpr *node, deparse_expr_cxt *context);
162 static void deparseNullTest(NullTest *node, deparse_expr_cxt *context);
163 static void deparseArrayExpr(ArrayExpr *node, deparse_expr_cxt *context);
164 static void printRemoteParam(int paramindex, Oid paramtype, int32 paramtypmod,
165                                  deparse_expr_cxt *context);
166 static void printRemotePlaceholder(Oid paramtype, int32 paramtypmod,
167                                            deparse_expr_cxt *context);
168 static void deparseSelectSql(List *tlist, bool is_subquery, List **retrieved_attrs,
169                                  deparse_expr_cxt *context);
170 static void deparseLockingClause(deparse_expr_cxt *context);
171 static void appendOrderByClause(List *pathkeys, deparse_expr_cxt *context);
172 static void appendConditions(List *exprs, deparse_expr_cxt *context);
173 static void deparseFromExprForRel(StringInfo buf, PlannerInfo *root,
174                                           RelOptInfo *foreignrel, bool use_alias,
175                                           Index ignore_rel, List **ignore_conds,
176                                           List **params_list);
177 static void deparseFromExpr(List *quals, deparse_expr_cxt *context);
178 static void deparseRangeTblRef(StringInfo buf, PlannerInfo *root,
179                                    RelOptInfo *foreignrel, bool make_subquery,
180                                    Index ignore_rel, List **ignore_conds, List **params_list);
181 static void deparseAggref(Aggref *node, deparse_expr_cxt *context);
182 static void appendGroupByClause(List *tlist, deparse_expr_cxt *context);
183 static void appendAggOrderBy(List *orderList, List *targetList,
184                                  deparse_expr_cxt *context);
185 static void appendFunctionName(Oid funcid, deparse_expr_cxt *context);
186 static Node *deparseSortGroupClause(Index ref, List *tlist, bool force_colno,
187                                            deparse_expr_cxt *context);
188
189 /*
190  * Helper functions
191  */
192 static bool is_subquery_var(Var *node, RelOptInfo *foreignrel,
193                                 int *relno, int *colno);
194 static void get_relation_column_alias_ids(Var *node, RelOptInfo *foreignrel,
195                                                           int *relno, int *colno);
196
197
198 /*
199  * Examine each qual clause in input_conds, and classify them into two groups,
200  * which are returned as two lists:
201  *      - remote_conds contains expressions that can be evaluated remotely
202  *      - local_conds contains expressions that can't be evaluated remotely
203  */
204 void
205 classifyConditions(PlannerInfo *root,
206                                    RelOptInfo *baserel,
207                                    List *input_conds,
208                                    List **remote_conds,
209                                    List **local_conds)
210 {
211         ListCell   *lc;
212
213         *remote_conds = NIL;
214         *local_conds = NIL;
215
216         foreach(lc, input_conds)
217         {
218                 RestrictInfo *ri = lfirst_node(RestrictInfo, lc);
219
220                 if (is_foreign_expr(root, baserel, ri->clause))
221                         *remote_conds = lappend(*remote_conds, ri);
222                 else
223                         *local_conds = lappend(*local_conds, ri);
224         }
225 }
226
227 /*
228  * Returns true if given expr is safe to evaluate on the foreign server.
229  */
230 bool
231 is_foreign_expr(PlannerInfo *root,
232                                 RelOptInfo *baserel,
233                                 Expr *expr)
234 {
235         foreign_glob_cxt glob_cxt;
236         foreign_loc_cxt loc_cxt;
237         PgFdwRelationInfo *fpinfo = (PgFdwRelationInfo *) (baserel->fdw_private);
238
239         /*
240          * Check that the expression consists of nodes that are safe to execute
241          * remotely.
242          */
243         glob_cxt.root = root;
244         glob_cxt.foreignrel = baserel;
245
246         /*
247          * For an upper relation, use relids from its underneath scan relation,
248          * because the upperrel's own relids currently aren't set to anything
249          * meaningful by the core code.  For other relation, use their own relids.
250          */
251         if (IS_UPPER_REL(baserel))
252                 glob_cxt.relids = fpinfo->outerrel->relids;
253         else
254                 glob_cxt.relids = baserel->relids;
255         loc_cxt.collation = InvalidOid;
256         loc_cxt.state = FDW_COLLATE_NONE;
257         if (!foreign_expr_walker((Node *) expr, &glob_cxt, &loc_cxt))
258                 return false;
259
260         /*
261          * If the expression has a valid collation that does not arise from a
262          * foreign var, the expression can not be sent over.
263          */
264         if (loc_cxt.state == FDW_COLLATE_UNSAFE)
265                 return false;
266
267         /*
268          * An expression which includes any mutable functions can't be sent over
269          * because its result is not stable.  For example, sending now() remote
270          * side could cause confusion from clock offsets.  Future versions might
271          * be able to make this choice with more granularity.  (We check this last
272          * because it requires a lot of expensive catalog lookups.)
273          */
274         if (contain_mutable_functions((Node *) expr))
275                 return false;
276
277         /* OK to evaluate on the remote server */
278         return true;
279 }
280
281 /*
282  * Check if expression is safe to execute remotely, and return true if so.
283  *
284  * In addition, *outer_cxt is updated with collation information.
285  *
286  * We must check that the expression contains only node types we can deparse,
287  * that all types/functions/operators are safe to send (they are "shippable"),
288  * and that all collations used in the expression derive from Vars of the
289  * foreign table.  Because of the latter, the logic is pretty close to
290  * assign_collations_walker() in parse_collate.c, though we can assume here
291  * that the given expression is valid.  Note function mutability is not
292  * currently considered here.
293  */
294 static bool
295 foreign_expr_walker(Node *node,
296                                         foreign_glob_cxt *glob_cxt,
297                                         foreign_loc_cxt *outer_cxt)
298 {
299         bool            check_type = true;
300         PgFdwRelationInfo *fpinfo;
301         foreign_loc_cxt inner_cxt;
302         Oid                     collation;
303         FDWCollateState state;
304
305         /* Need do nothing for empty subexpressions */
306         if (node == NULL)
307                 return true;
308
309         /* May need server info from baserel's fdw_private struct */
310         fpinfo = (PgFdwRelationInfo *) (glob_cxt->foreignrel->fdw_private);
311
312         /* Set up inner_cxt for possible recursion to child nodes */
313         inner_cxt.collation = InvalidOid;
314         inner_cxt.state = FDW_COLLATE_NONE;
315
316         switch (nodeTag(node))
317         {
318                 case T_Var:
319                         {
320                                 Var                *var = (Var *) node;
321
322                                 /*
323                                  * If the Var is from the foreign table, we consider its
324                                  * collation (if any) safe to use.  If it is from another
325                                  * table, we treat its collation the same way as we would a
326                                  * Param's collation, ie it's not safe for it to have a
327                                  * non-default collation.
328                                  */
329                                 if (bms_is_member(var->varno, glob_cxt->relids) &&
330                                         var->varlevelsup == 0)
331                                 {
332                                         /* Var belongs to foreign table */
333
334                                         /*
335                                          * System columns other than ctid should not be sent to
336                                          * the remote, since we don't make any effort to ensure
337                                          * that local and remote values match (tableoid, in
338                                          * particular, almost certainly doesn't match).
339                                          */
340                                         if (var->varattno < 0 &&
341                                                 var->varattno != SelfItemPointerAttributeNumber)
342                                                 return false;
343
344                                         /* Else check the collation */
345                                         collation = var->varcollid;
346                                         state = OidIsValid(collation) ? FDW_COLLATE_SAFE : FDW_COLLATE_NONE;
347                                 }
348                                 else
349                                 {
350                                         /* Var belongs to some other table */
351                                         collation = var->varcollid;
352                                         if (collation == InvalidOid ||
353                                                 collation == DEFAULT_COLLATION_OID)
354                                         {
355                                                 /*
356                                                  * It's noncollatable, or it's safe to combine with a
357                                                  * collatable foreign Var, so set state to NONE.
358                                                  */
359                                                 state = FDW_COLLATE_NONE;
360                                         }
361                                         else
362                                         {
363                                                 /*
364                                                  * Do not fail right away, since the Var might appear
365                                                  * in a collation-insensitive context.
366                                                  */
367                                                 state = FDW_COLLATE_UNSAFE;
368                                         }
369                                 }
370                         }
371                         break;
372                 case T_Const:
373                         {
374                                 Const      *c = (Const *) node;
375
376                                 /*
377                                  * If the constant has nondefault collation, either it's of a
378                                  * non-builtin type, or it reflects folding of a CollateExpr.
379                                  * It's unsafe to send to the remote unless it's used in a
380                                  * non-collation-sensitive context.
381                                  */
382                                 collation = c->constcollid;
383                                 if (collation == InvalidOid ||
384                                         collation == DEFAULT_COLLATION_OID)
385                                         state = FDW_COLLATE_NONE;
386                                 else
387                                         state = FDW_COLLATE_UNSAFE;
388                         }
389                         break;
390                 case T_Param:
391                         {
392                                 Param      *p = (Param *) node;
393
394                                 /*
395                                  * Collation rule is same as for Consts and non-foreign Vars.
396                                  */
397                                 collation = p->paramcollid;
398                                 if (collation == InvalidOid ||
399                                         collation == DEFAULT_COLLATION_OID)
400                                         state = FDW_COLLATE_NONE;
401                                 else
402                                         state = FDW_COLLATE_UNSAFE;
403                         }
404                         break;
405                 case T_ArrayRef:
406                         {
407                                 ArrayRef   *ar = (ArrayRef *) node;
408
409                                 /* Assignment should not be in restrictions. */
410                                 if (ar->refassgnexpr != NULL)
411                                         return false;
412
413                                 /*
414                                  * Recurse to remaining subexpressions.  Since the array
415                                  * subscripts must yield (noncollatable) integers, they won't
416                                  * affect the inner_cxt state.
417                                  */
418                                 if (!foreign_expr_walker((Node *) ar->refupperindexpr,
419                                                                                  glob_cxt, &inner_cxt))
420                                         return false;
421                                 if (!foreign_expr_walker((Node *) ar->reflowerindexpr,
422                                                                                  glob_cxt, &inner_cxt))
423                                         return false;
424                                 if (!foreign_expr_walker((Node *) ar->refexpr,
425                                                                                  glob_cxt, &inner_cxt))
426                                         return false;
427
428                                 /*
429                                  * Array subscripting should yield same collation as input,
430                                  * but for safety use same logic as for function nodes.
431                                  */
432                                 collation = ar->refcollid;
433                                 if (collation == InvalidOid)
434                                         state = FDW_COLLATE_NONE;
435                                 else if (inner_cxt.state == FDW_COLLATE_SAFE &&
436                                                  collation == inner_cxt.collation)
437                                         state = FDW_COLLATE_SAFE;
438                                 else if (collation == DEFAULT_COLLATION_OID)
439                                         state = FDW_COLLATE_NONE;
440                                 else
441                                         state = FDW_COLLATE_UNSAFE;
442                         }
443                         break;
444                 case T_FuncExpr:
445                         {
446                                 FuncExpr   *fe = (FuncExpr *) node;
447
448                                 /*
449                                  * If function used by the expression is not shippable, it
450                                  * can't be sent to remote because it might have incompatible
451                                  * semantics on remote side.
452                                  */
453                                 if (!is_shippable(fe->funcid, ProcedureRelationId, fpinfo))
454                                         return false;
455
456                                 /*
457                                  * Recurse to input subexpressions.
458                                  */
459                                 if (!foreign_expr_walker((Node *) fe->args,
460                                                                                  glob_cxt, &inner_cxt))
461                                         return false;
462
463                                 /*
464                                  * If function's input collation is not derived from a foreign
465                                  * Var, it can't be sent to remote.
466                                  */
467                                 if (fe->inputcollid == InvalidOid)
468                                          /* OK, inputs are all noncollatable */ ;
469                                 else if (inner_cxt.state != FDW_COLLATE_SAFE ||
470                                                  fe->inputcollid != inner_cxt.collation)
471                                         return false;
472
473                                 /*
474                                  * Detect whether node is introducing a collation not derived
475                                  * from a foreign Var.  (If so, we just mark it unsafe for now
476                                  * rather than immediately returning false, since the parent
477                                  * node might not care.)
478                                  */
479                                 collation = fe->funccollid;
480                                 if (collation == InvalidOid)
481                                         state = FDW_COLLATE_NONE;
482                                 else if (inner_cxt.state == FDW_COLLATE_SAFE &&
483                                                  collation == inner_cxt.collation)
484                                         state = FDW_COLLATE_SAFE;
485                                 else if (collation == DEFAULT_COLLATION_OID)
486                                         state = FDW_COLLATE_NONE;
487                                 else
488                                         state = FDW_COLLATE_UNSAFE;
489                         }
490                         break;
491                 case T_OpExpr:
492                 case T_DistinctExpr:    /* struct-equivalent to OpExpr */
493                         {
494                                 OpExpr     *oe = (OpExpr *) node;
495
496                                 /*
497                                  * Similarly, only shippable operators can be sent to remote.
498                                  * (If the operator is shippable, we assume its underlying
499                                  * function is too.)
500                                  */
501                                 if (!is_shippable(oe->opno, OperatorRelationId, fpinfo))
502                                         return false;
503
504                                 /*
505                                  * Recurse to input subexpressions.
506                                  */
507                                 if (!foreign_expr_walker((Node *) oe->args,
508                                                                                  glob_cxt, &inner_cxt))
509                                         return false;
510
511                                 /*
512                                  * If operator's input collation is not derived from a foreign
513                                  * Var, it can't be sent to remote.
514                                  */
515                                 if (oe->inputcollid == InvalidOid)
516                                          /* OK, inputs are all noncollatable */ ;
517                                 else if (inner_cxt.state != FDW_COLLATE_SAFE ||
518                                                  oe->inputcollid != inner_cxt.collation)
519                                         return false;
520
521                                 /* Result-collation handling is same as for functions */
522                                 collation = oe->opcollid;
523                                 if (collation == InvalidOid)
524                                         state = FDW_COLLATE_NONE;
525                                 else if (inner_cxt.state == FDW_COLLATE_SAFE &&
526                                                  collation == inner_cxt.collation)
527                                         state = FDW_COLLATE_SAFE;
528                                 else if (collation == DEFAULT_COLLATION_OID)
529                                         state = FDW_COLLATE_NONE;
530                                 else
531                                         state = FDW_COLLATE_UNSAFE;
532                         }
533                         break;
534                 case T_ScalarArrayOpExpr:
535                         {
536                                 ScalarArrayOpExpr *oe = (ScalarArrayOpExpr *) node;
537
538                                 /*
539                                  * Again, only shippable operators can be sent to remote.
540                                  */
541                                 if (!is_shippable(oe->opno, OperatorRelationId, fpinfo))
542                                         return false;
543
544                                 /*
545                                  * Recurse to input subexpressions.
546                                  */
547                                 if (!foreign_expr_walker((Node *) oe->args,
548                                                                                  glob_cxt, &inner_cxt))
549                                         return false;
550
551                                 /*
552                                  * If operator's input collation is not derived from a foreign
553                                  * Var, it can't be sent to remote.
554                                  */
555                                 if (oe->inputcollid == InvalidOid)
556                                          /* OK, inputs are all noncollatable */ ;
557                                 else if (inner_cxt.state != FDW_COLLATE_SAFE ||
558                                                  oe->inputcollid != inner_cxt.collation)
559                                         return false;
560
561                                 /* Output is always boolean and so noncollatable. */
562                                 collation = InvalidOid;
563                                 state = FDW_COLLATE_NONE;
564                         }
565                         break;
566                 case T_RelabelType:
567                         {
568                                 RelabelType *r = (RelabelType *) node;
569
570                                 /*
571                                  * Recurse to input subexpression.
572                                  */
573                                 if (!foreign_expr_walker((Node *) r->arg,
574                                                                                  glob_cxt, &inner_cxt))
575                                         return false;
576
577                                 /*
578                                  * RelabelType must not introduce a collation not derived from
579                                  * an input foreign Var (same logic as for a real function).
580                                  */
581                                 collation = r->resultcollid;
582                                 if (collation == InvalidOid)
583                                         state = FDW_COLLATE_NONE;
584                                 else if (inner_cxt.state == FDW_COLLATE_SAFE &&
585                                                  collation == inner_cxt.collation)
586                                         state = FDW_COLLATE_SAFE;
587                                 else if (collation == DEFAULT_COLLATION_OID)
588                                         state = FDW_COLLATE_NONE;
589                                 else
590                                         state = FDW_COLLATE_UNSAFE;
591                         }
592                         break;
593                 case T_BoolExpr:
594                         {
595                                 BoolExpr   *b = (BoolExpr *) node;
596
597                                 /*
598                                  * Recurse to input subexpressions.
599                                  */
600                                 if (!foreign_expr_walker((Node *) b->args,
601                                                                                  glob_cxt, &inner_cxt))
602                                         return false;
603
604                                 /* Output is always boolean and so noncollatable. */
605                                 collation = InvalidOid;
606                                 state = FDW_COLLATE_NONE;
607                         }
608                         break;
609                 case T_NullTest:
610                         {
611                                 NullTest   *nt = (NullTest *) node;
612
613                                 /*
614                                  * Recurse to input subexpressions.
615                                  */
616                                 if (!foreign_expr_walker((Node *) nt->arg,
617                                                                                  glob_cxt, &inner_cxt))
618                                         return false;
619
620                                 /* Output is always boolean and so noncollatable. */
621                                 collation = InvalidOid;
622                                 state = FDW_COLLATE_NONE;
623                         }
624                         break;
625                 case T_ArrayExpr:
626                         {
627                                 ArrayExpr  *a = (ArrayExpr *) node;
628
629                                 /*
630                                  * Recurse to input subexpressions.
631                                  */
632                                 if (!foreign_expr_walker((Node *) a->elements,
633                                                                                  glob_cxt, &inner_cxt))
634                                         return false;
635
636                                 /*
637                                  * ArrayExpr must not introduce a collation not derived from
638                                  * an input foreign Var (same logic as for a function).
639                                  */
640                                 collation = a->array_collid;
641                                 if (collation == InvalidOid)
642                                         state = FDW_COLLATE_NONE;
643                                 else if (inner_cxt.state == FDW_COLLATE_SAFE &&
644                                                  collation == inner_cxt.collation)
645                                         state = FDW_COLLATE_SAFE;
646                                 else if (collation == DEFAULT_COLLATION_OID)
647                                         state = FDW_COLLATE_NONE;
648                                 else
649                                         state = FDW_COLLATE_UNSAFE;
650                         }
651                         break;
652                 case T_List:
653                         {
654                                 List       *l = (List *) node;
655                                 ListCell   *lc;
656
657                                 /*
658                                  * Recurse to component subexpressions.
659                                  */
660                                 foreach(lc, l)
661                                 {
662                                         if (!foreign_expr_walker((Node *) lfirst(lc),
663                                                                                          glob_cxt, &inner_cxt))
664                                                 return false;
665                                 }
666
667                                 /*
668                                  * When processing a list, collation state just bubbles up
669                                  * from the list elements.
670                                  */
671                                 collation = inner_cxt.collation;
672                                 state = inner_cxt.state;
673
674                                 /* Don't apply exprType() to the list. */
675                                 check_type = false;
676                         }
677                         break;
678                 case T_Aggref:
679                         {
680                                 Aggref     *agg = (Aggref *) node;
681                                 ListCell   *lc;
682
683                                 /* Not safe to pushdown when not in grouping context */
684                                 if (!IS_UPPER_REL(glob_cxt->foreignrel))
685                                         return false;
686
687                                 /* Only non-split aggregates are pushable. */
688                                 if (agg->aggsplit != AGGSPLIT_SIMPLE)
689                                         return false;
690
691                                 /* As usual, it must be shippable. */
692                                 if (!is_shippable(agg->aggfnoid, ProcedureRelationId, fpinfo))
693                                         return false;
694
695                                 /*
696                                  * Recurse to input args. aggdirectargs, aggorder and
697                                  * aggdistinct are all present in args, so no need to check
698                                  * their shippability explicitly.
699                                  */
700                                 foreach(lc, agg->args)
701                                 {
702                                         Node       *n = (Node *) lfirst(lc);
703
704                                         /* If TargetEntry, extract the expression from it */
705                                         if (IsA(n, TargetEntry))
706                                         {
707                                                 TargetEntry *tle = (TargetEntry *) n;
708
709                                                 n = (Node *) tle->expr;
710                                         }
711
712                                         if (!foreign_expr_walker(n, glob_cxt, &inner_cxt))
713                                                 return false;
714                                 }
715
716                                 /*
717                                  * For aggorder elements, check whether the sort operator, if
718                                  * specified, is shippable or not.
719                                  */
720                                 if (agg->aggorder)
721                                 {
722                                         ListCell   *lc;
723
724                                         foreach(lc, agg->aggorder)
725                                         {
726                                                 SortGroupClause *srt = (SortGroupClause *) lfirst(lc);
727                                                 Oid                     sortcoltype;
728                                                 TypeCacheEntry *typentry;
729                                                 TargetEntry *tle;
730
731                                                 tle = get_sortgroupref_tle(srt->tleSortGroupRef,
732                                                                                                    agg->args);
733                                                 sortcoltype = exprType((Node *) tle->expr);
734                                                 typentry = lookup_type_cache(sortcoltype,
735                                                                                                          TYPECACHE_LT_OPR | TYPECACHE_GT_OPR);
736                                                 /* Check shippability of non-default sort operator. */
737                                                 if (srt->sortop != typentry->lt_opr &&
738                                                         srt->sortop != typentry->gt_opr &&
739                                                         !is_shippable(srt->sortop, OperatorRelationId,
740                                                                                   fpinfo))
741                                                         return false;
742                                         }
743                                 }
744
745                                 /* Check aggregate filter */
746                                 if (!foreign_expr_walker((Node *) agg->aggfilter,
747                                                                                  glob_cxt, &inner_cxt))
748                                         return false;
749
750                                 /*
751                                  * If aggregate's input collation is not derived from a
752                                  * foreign Var, it can't be sent to remote.
753                                  */
754                                 if (agg->inputcollid == InvalidOid)
755                                          /* OK, inputs are all noncollatable */ ;
756                                 else if (inner_cxt.state != FDW_COLLATE_SAFE ||
757                                                  agg->inputcollid != inner_cxt.collation)
758                                         return false;
759
760                                 /*
761                                  * Detect whether node is introducing a collation not derived
762                                  * from a foreign Var.  (If so, we just mark it unsafe for now
763                                  * rather than immediately returning false, since the parent
764                                  * node might not care.)
765                                  */
766                                 collation = agg->aggcollid;
767                                 if (collation == InvalidOid)
768                                         state = FDW_COLLATE_NONE;
769                                 else if (inner_cxt.state == FDW_COLLATE_SAFE &&
770                                                  collation == inner_cxt.collation)
771                                         state = FDW_COLLATE_SAFE;
772                                 else if (collation == DEFAULT_COLLATION_OID)
773                                         state = FDW_COLLATE_NONE;
774                                 else
775                                         state = FDW_COLLATE_UNSAFE;
776                         }
777                         break;
778                 default:
779
780                         /*
781                          * If it's anything else, assume it's unsafe.  This list can be
782                          * expanded later, but don't forget to add deparse support below.
783                          */
784                         return false;
785         }
786
787         /*
788          * If result type of given expression is not shippable, it can't be sent
789          * to remote because it might have incompatible semantics on remote side.
790          */
791         if (check_type && !is_shippable(exprType(node), TypeRelationId, fpinfo))
792                 return false;
793
794         /*
795          * Now, merge my collation information into my parent's state.
796          */
797         if (state > outer_cxt->state)
798         {
799                 /* Override previous parent state */
800                 outer_cxt->collation = collation;
801                 outer_cxt->state = state;
802         }
803         else if (state == outer_cxt->state)
804         {
805                 /* Merge, or detect error if there's a collation conflict */
806                 switch (state)
807                 {
808                         case FDW_COLLATE_NONE:
809                                 /* Nothing + nothing is still nothing */
810                                 break;
811                         case FDW_COLLATE_SAFE:
812                                 if (collation != outer_cxt->collation)
813                                 {
814                                         /*
815                                          * Non-default collation always beats default.
816                                          */
817                                         if (outer_cxt->collation == DEFAULT_COLLATION_OID)
818                                         {
819                                                 /* Override previous parent state */
820                                                 outer_cxt->collation = collation;
821                                         }
822                                         else if (collation != DEFAULT_COLLATION_OID)
823                                         {
824                                                 /*
825                                                  * Conflict; show state as indeterminate.  We don't
826                                                  * want to "return false" right away, since parent
827                                                  * node might not care about collation.
828                                                  */
829                                                 outer_cxt->state = FDW_COLLATE_UNSAFE;
830                                         }
831                                 }
832                                 break;
833                         case FDW_COLLATE_UNSAFE:
834                                 /* We're still conflicted ... */
835                                 break;
836                 }
837         }
838
839         /* It looks OK */
840         return true;
841 }
842
843 /*
844  * Convert type OID + typmod info into a type name we can ship to the remote
845  * server.  Someplace else had better have verified that this type name is
846  * expected to be known on the remote end.
847  *
848  * This is almost just format_type_with_typemod(), except that if left to its
849  * own devices, that function will make schema-qualification decisions based
850  * on the local search_path, which is wrong.  We must schema-qualify all
851  * type names that are not in pg_catalog.  We assume here that built-in types
852  * are all in pg_catalog and need not be qualified; otherwise, qualify.
853  */
854 static char *
855 deparse_type_name(Oid type_oid, int32 typemod)
856 {
857         bits16          flags = FORMAT_TYPE_TYPEMOD_GIVEN;
858
859         if (!is_builtin(type_oid))
860                 flags |= FORMAT_TYPE_FORCE_QUALIFY;
861
862         return format_type_extended(type_oid, typemod, flags);
863 }
864
865 /*
866  * Build the targetlist for given relation to be deparsed as SELECT clause.
867  *
868  * The output targetlist contains the columns that need to be fetched from the
869  * foreign server for the given relation.  If foreignrel is an upper relation,
870  * then the output targetlist can also contain expressions to be evaluated on
871  * foreign server.
872  */
873 List *
874 build_tlist_to_deparse(RelOptInfo *foreignrel)
875 {
876         List       *tlist = NIL;
877         PgFdwRelationInfo *fpinfo = (PgFdwRelationInfo *) foreignrel->fdw_private;
878         ListCell   *lc;
879
880         /*
881          * For an upper relation, we have already built the target list while
882          * checking shippability, so just return that.
883          */
884         if (IS_UPPER_REL(foreignrel))
885                 return fpinfo->grouped_tlist;
886
887         /*
888          * We require columns specified in foreignrel->reltarget->exprs and those
889          * required for evaluating the local conditions.
890          */
891         tlist = add_to_flat_tlist(tlist,
892                                                           pull_var_clause((Node *) foreignrel->reltarget->exprs,
893                                                                                           PVC_RECURSE_PLACEHOLDERS));
894         foreach(lc, fpinfo->local_conds)
895         {
896                 RestrictInfo *rinfo = lfirst_node(RestrictInfo, lc);
897
898                 tlist = add_to_flat_tlist(tlist,
899                                                                   pull_var_clause((Node *) rinfo->clause,
900                                                                                                   PVC_RECURSE_PLACEHOLDERS));
901         }
902
903         return tlist;
904 }
905
906 /*
907  * Deparse SELECT statement for given relation into buf.
908  *
909  * tlist contains the list of desired columns to be fetched from foreign server.
910  * For a base relation fpinfo->attrs_used is used to construct SELECT clause,
911  * hence the tlist is ignored for a base relation.
912  *
913  * remote_conds is the list of conditions to be deparsed into the WHERE clause
914  * (or, in the case of upper relations, into the HAVING clause).
915  *
916  * If params_list is not NULL, it receives a list of Params and other-relation
917  * Vars used in the clauses; these values must be transmitted to the remote
918  * server as parameter values.
919  *
920  * If params_list is NULL, we're generating the query for EXPLAIN purposes,
921  * so Params and other-relation Vars should be replaced by dummy values.
922  *
923  * pathkeys is the list of pathkeys to order the result by.
924  *
925  * is_subquery is the flag to indicate whether to deparse the specified
926  * relation as a subquery.
927  *
928  * List of columns selected is returned in retrieved_attrs.
929  */
930 void
931 deparseSelectStmtForRel(StringInfo buf, PlannerInfo *root, RelOptInfo *rel,
932                                                 List *tlist, List *remote_conds, List *pathkeys,
933                                                 bool is_subquery, List **retrieved_attrs,
934                                                 List **params_list)
935 {
936         deparse_expr_cxt context;
937         PgFdwRelationInfo *fpinfo = (PgFdwRelationInfo *) rel->fdw_private;
938         List       *quals;
939
940         /*
941          * We handle relations for foreign tables, joins between those and upper
942          * relations.
943          */
944         Assert(IS_JOIN_REL(rel) || IS_SIMPLE_REL(rel) || IS_UPPER_REL(rel));
945
946         /* Fill portions of context common to upper, join and base relation */
947         context.buf = buf;
948         context.root = root;
949         context.foreignrel = rel;
950         context.scanrel = IS_UPPER_REL(rel) ? fpinfo->outerrel : rel;
951         context.params_list = params_list;
952
953         /* Construct SELECT clause */
954         deparseSelectSql(tlist, is_subquery, retrieved_attrs, &context);
955
956         /*
957          * For upper relations, the WHERE clause is built from the remote
958          * conditions of the underlying scan relation; otherwise, we can use the
959          * supplied list of remote conditions directly.
960          */
961         if (IS_UPPER_REL(rel))
962         {
963                 PgFdwRelationInfo *ofpinfo;
964
965                 ofpinfo = (PgFdwRelationInfo *) fpinfo->outerrel->fdw_private;
966                 quals = ofpinfo->remote_conds;
967         }
968         else
969                 quals = remote_conds;
970
971         /* Construct FROM and WHERE clauses */
972         deparseFromExpr(quals, &context);
973
974         if (IS_UPPER_REL(rel))
975         {
976                 /* Append GROUP BY clause */
977                 appendGroupByClause(tlist, &context);
978
979                 /* Append HAVING clause */
980                 if (remote_conds)
981                 {
982                         appendStringInfoString(buf, " HAVING ");
983                         appendConditions(remote_conds, &context);
984                 }
985         }
986
987         /* Add ORDER BY clause if we found any useful pathkeys */
988         if (pathkeys)
989                 appendOrderByClause(pathkeys, &context);
990
991         /* Add any necessary FOR UPDATE/SHARE. */
992         deparseLockingClause(&context);
993 }
994
995 /*
996  * Construct a simple SELECT statement that retrieves desired columns
997  * of the specified foreign table, and append it to "buf".  The output
998  * contains just "SELECT ... ".
999  *
1000  * We also create an integer List of the columns being retrieved, which is
1001  * returned to *retrieved_attrs, unless we deparse the specified relation
1002  * as a subquery.
1003  *
1004  * tlist is the list of desired columns.  is_subquery is the flag to
1005  * indicate whether to deparse the specified relation as a subquery.
1006  * Read prologue of deparseSelectStmtForRel() for details.
1007  */
1008 static void
1009 deparseSelectSql(List *tlist, bool is_subquery, List **retrieved_attrs,
1010                                  deparse_expr_cxt *context)
1011 {
1012         StringInfo      buf = context->buf;
1013         RelOptInfo *foreignrel = context->foreignrel;
1014         PlannerInfo *root = context->root;
1015         PgFdwRelationInfo *fpinfo = (PgFdwRelationInfo *) foreignrel->fdw_private;
1016
1017         /*
1018          * Construct SELECT list
1019          */
1020         appendStringInfoString(buf, "SELECT ");
1021
1022         if (is_subquery)
1023         {
1024                 /*
1025                  * For a relation that is deparsed as a subquery, emit expressions
1026                  * specified in the relation's reltarget.  Note that since this is for
1027                  * the subquery, no need to care about *retrieved_attrs.
1028                  */
1029                 deparseSubqueryTargetList(context);
1030         }
1031         else if (IS_JOIN_REL(foreignrel) || IS_UPPER_REL(foreignrel))
1032         {
1033                 /*
1034                  * For a join or upper relation the input tlist gives the list of
1035                  * columns required to be fetched from the foreign server.
1036                  */
1037                 deparseExplicitTargetList(tlist, false, retrieved_attrs, context);
1038         }
1039         else
1040         {
1041                 /*
1042                  * For a base relation fpinfo->attrs_used gives the list of columns
1043                  * required to be fetched from the foreign server.
1044                  */
1045                 RangeTblEntry *rte = planner_rt_fetch(foreignrel->relid, root);
1046
1047                 /*
1048                  * Core code already has some lock on each rel being planned, so we
1049                  * can use NoLock here.
1050                  */
1051                 Relation        rel = heap_open(rte->relid, NoLock);
1052
1053                 deparseTargetList(buf, rte, foreignrel->relid, rel, false,
1054                                                   fpinfo->attrs_used, false, retrieved_attrs);
1055                 heap_close(rel, NoLock);
1056         }
1057 }
1058
1059 /*
1060  * Construct a FROM clause and, if needed, a WHERE clause, and append those to
1061  * "buf".
1062  *
1063  * quals is the list of clauses to be included in the WHERE clause.
1064  * (These may or may not include RestrictInfo decoration.)
1065  */
1066 static void
1067 deparseFromExpr(List *quals, deparse_expr_cxt *context)
1068 {
1069         StringInfo      buf = context->buf;
1070         RelOptInfo *scanrel = context->scanrel;
1071
1072         /* For upper relations, scanrel must be either a joinrel or a baserel */
1073         Assert(!IS_UPPER_REL(context->foreignrel) ||
1074                    IS_JOIN_REL(scanrel) || IS_SIMPLE_REL(scanrel));
1075
1076         /* Construct FROM clause */
1077         appendStringInfoString(buf, " FROM ");
1078         deparseFromExprForRel(buf, context->root, scanrel,
1079                                                   (bms_membership(scanrel->relids) == BMS_MULTIPLE),
1080                                                   (Index) 0, NULL, context->params_list);
1081
1082         /* Construct WHERE clause */
1083         if (quals != NIL)
1084         {
1085                 appendStringInfoString(buf, " WHERE ");
1086                 appendConditions(quals, context);
1087         }
1088 }
1089
1090 /*
1091  * Emit a target list that retrieves the columns specified in attrs_used.
1092  * This is used for both SELECT and RETURNING targetlists; the is_returning
1093  * parameter is true only for a RETURNING targetlist.
1094  *
1095  * The tlist text is appended to buf, and we also create an integer List
1096  * of the columns being retrieved, which is returned to *retrieved_attrs.
1097  *
1098  * If qualify_col is true, add relation alias before the column name.
1099  */
1100 static void
1101 deparseTargetList(StringInfo buf,
1102                                   RangeTblEntry *rte,
1103                                   Index rtindex,
1104                                   Relation rel,
1105                                   bool is_returning,
1106                                   Bitmapset *attrs_used,
1107                                   bool qualify_col,
1108                                   List **retrieved_attrs)
1109 {
1110         TupleDesc       tupdesc = RelationGetDescr(rel);
1111         bool            have_wholerow;
1112         bool            first;
1113         int                     i;
1114
1115         *retrieved_attrs = NIL;
1116
1117         /* If there's a whole-row reference, we'll need all the columns. */
1118         have_wholerow = bms_is_member(0 - FirstLowInvalidHeapAttributeNumber,
1119                                                                   attrs_used);
1120
1121         first = true;
1122         for (i = 1; i <= tupdesc->natts; i++)
1123         {
1124                 Form_pg_attribute attr = TupleDescAttr(tupdesc, i - 1);
1125
1126                 /* Ignore dropped attributes. */
1127                 if (attr->attisdropped)
1128                         continue;
1129
1130                 if (have_wholerow ||
1131                         bms_is_member(i - FirstLowInvalidHeapAttributeNumber,
1132                                                   attrs_used))
1133                 {
1134                         if (!first)
1135                                 appendStringInfoString(buf, ", ");
1136                         else if (is_returning)
1137                                 appendStringInfoString(buf, " RETURNING ");
1138                         first = false;
1139
1140                         deparseColumnRef(buf, rtindex, i, rte, qualify_col);
1141
1142                         *retrieved_attrs = lappend_int(*retrieved_attrs, i);
1143                 }
1144         }
1145
1146         /*
1147          * Add ctid if needed.  We currently don't support retrieving any other
1148          * system columns.
1149          */
1150         if (bms_is_member(SelfItemPointerAttributeNumber - FirstLowInvalidHeapAttributeNumber,
1151                                           attrs_used))
1152         {
1153                 if (!first)
1154                         appendStringInfoString(buf, ", ");
1155                 else if (is_returning)
1156                         appendStringInfoString(buf, " RETURNING ");
1157                 first = false;
1158
1159                 if (qualify_col)
1160                         ADD_REL_QUALIFIER(buf, rtindex);
1161                 appendStringInfoString(buf, "ctid");
1162
1163                 *retrieved_attrs = lappend_int(*retrieved_attrs,
1164                                                                            SelfItemPointerAttributeNumber);
1165         }
1166
1167         /* Don't generate bad syntax if no undropped columns */
1168         if (first && !is_returning)
1169                 appendStringInfoString(buf, "NULL");
1170 }
1171
1172 /*
1173  * Deparse the appropriate locking clause (FOR UPDATE or FOR SHARE) for a
1174  * given relation (context->scanrel).
1175  */
1176 static void
1177 deparseLockingClause(deparse_expr_cxt *context)
1178 {
1179         StringInfo      buf = context->buf;
1180         PlannerInfo *root = context->root;
1181         RelOptInfo *rel = context->scanrel;
1182         PgFdwRelationInfo *fpinfo = (PgFdwRelationInfo *) rel->fdw_private;
1183         int                     relid = -1;
1184
1185         while ((relid = bms_next_member(rel->relids, relid)) >= 0)
1186         {
1187                 /*
1188                  * Ignore relation if it appears in a lower subquery.  Locking clause
1189                  * for such a relation is included in the subquery if necessary.
1190                  */
1191                 if (bms_is_member(relid, fpinfo->lower_subquery_rels))
1192                         continue;
1193
1194                 /*
1195                  * Add FOR UPDATE/SHARE if appropriate.  We apply locking during the
1196                  * initial row fetch, rather than later on as is done for local
1197                  * tables. The extra roundtrips involved in trying to duplicate the
1198                  * local semantics exactly don't seem worthwhile (see also comments
1199                  * for RowMarkType).
1200                  *
1201                  * Note: because we actually run the query as a cursor, this assumes
1202                  * that DECLARE CURSOR ... FOR UPDATE is supported, which it isn't
1203                  * before 8.3.
1204                  */
1205                 if (relid == root->parse->resultRelation &&
1206                         (root->parse->commandType == CMD_UPDATE ||
1207                          root->parse->commandType == CMD_DELETE))
1208                 {
1209                         /* Relation is UPDATE/DELETE target, so use FOR UPDATE */
1210                         appendStringInfoString(buf, " FOR UPDATE");
1211
1212                         /* Add the relation alias if we are here for a join relation */
1213                         if (IS_JOIN_REL(rel))
1214                                 appendStringInfo(buf, " OF %s%d", REL_ALIAS_PREFIX, relid);
1215                 }
1216                 else
1217                 {
1218                         PlanRowMark *rc = get_plan_rowmark(root->rowMarks, relid);
1219
1220                         if (rc)
1221                         {
1222                                 /*
1223                                  * Relation is specified as a FOR UPDATE/SHARE target, so
1224                                  * handle that.  (But we could also see LCS_NONE, meaning this
1225                                  * isn't a target relation after all.)
1226                                  *
1227                                  * For now, just ignore any [NO] KEY specification, since (a)
1228                                  * it's not clear what that means for a remote table that we
1229                                  * don't have complete information about, and (b) it wouldn't
1230                                  * work anyway on older remote servers.  Likewise, we don't
1231                                  * worry about NOWAIT.
1232                                  */
1233                                 switch (rc->strength)
1234                                 {
1235                                         case LCS_NONE:
1236                                                 /* No locking needed */
1237                                                 break;
1238                                         case LCS_FORKEYSHARE:
1239                                         case LCS_FORSHARE:
1240                                                 appendStringInfoString(buf, " FOR SHARE");
1241                                                 break;
1242                                         case LCS_FORNOKEYUPDATE:
1243                                         case LCS_FORUPDATE:
1244                                                 appendStringInfoString(buf, " FOR UPDATE");
1245                                                 break;
1246                                 }
1247
1248                                 /* Add the relation alias if we are here for a join relation */
1249                                 if (bms_membership(rel->relids) == BMS_MULTIPLE &&
1250                                         rc->strength != LCS_NONE)
1251                                         appendStringInfo(buf, " OF %s%d", REL_ALIAS_PREFIX, relid);
1252                         }
1253                 }
1254         }
1255 }
1256
1257 /*
1258  * Deparse conditions from the provided list and append them to buf.
1259  *
1260  * The conditions in the list are assumed to be ANDed. This function is used to
1261  * deparse WHERE clauses, JOIN .. ON clauses and HAVING clauses.
1262  *
1263  * Depending on the caller, the list elements might be either RestrictInfos
1264  * or bare clauses.
1265  */
1266 static void
1267 appendConditions(List *exprs, deparse_expr_cxt *context)
1268 {
1269         int                     nestlevel;
1270         ListCell   *lc;
1271         bool            is_first = true;
1272         StringInfo      buf = context->buf;
1273
1274         /* Make sure any constants in the exprs are printed portably */
1275         nestlevel = set_transmission_modes();
1276
1277         foreach(lc, exprs)
1278         {
1279                 Expr       *expr = (Expr *) lfirst(lc);
1280
1281                 /* Extract clause from RestrictInfo, if required */
1282                 if (IsA(expr, RestrictInfo))
1283                         expr = ((RestrictInfo *) expr)->clause;
1284
1285                 /* Connect expressions with "AND" and parenthesize each condition. */
1286                 if (!is_first)
1287                         appendStringInfoString(buf, " AND ");
1288
1289                 appendStringInfoChar(buf, '(');
1290                 deparseExpr(expr, context);
1291                 appendStringInfoChar(buf, ')');
1292
1293                 is_first = false;
1294         }
1295
1296         reset_transmission_modes(nestlevel);
1297 }
1298
1299 /* Output join name for given join type */
1300 const char *
1301 get_jointype_name(JoinType jointype)
1302 {
1303         switch (jointype)
1304         {
1305                 case JOIN_INNER:
1306                         return "INNER";
1307
1308                 case JOIN_LEFT:
1309                         return "LEFT";
1310
1311                 case JOIN_RIGHT:
1312                         return "RIGHT";
1313
1314                 case JOIN_FULL:
1315                         return "FULL";
1316
1317                 default:
1318                         /* Shouldn't come here, but protect from buggy code. */
1319                         elog(ERROR, "unsupported join type %d", jointype);
1320         }
1321
1322         /* Keep compiler happy */
1323         return NULL;
1324 }
1325
1326 /*
1327  * Deparse given targetlist and append it to context->buf.
1328  *
1329  * tlist is list of TargetEntry's which in turn contain Var nodes.
1330  *
1331  * retrieved_attrs is the list of continuously increasing integers starting
1332  * from 1. It has same number of entries as tlist.
1333  *
1334  * This is used for both SELECT and RETURNING targetlists; the is_returning
1335  * parameter is true only for a RETURNING targetlist.
1336  */
1337 static void
1338 deparseExplicitTargetList(List *tlist,
1339                                                   bool is_returning,
1340                                                   List **retrieved_attrs,
1341                                                   deparse_expr_cxt *context)
1342 {
1343         ListCell   *lc;
1344         StringInfo      buf = context->buf;
1345         int                     i = 0;
1346
1347         *retrieved_attrs = NIL;
1348
1349         foreach(lc, tlist)
1350         {
1351                 TargetEntry *tle = lfirst_node(TargetEntry, lc);
1352
1353                 if (i > 0)
1354                         appendStringInfoString(buf, ", ");
1355                 else if (is_returning)
1356                         appendStringInfoString(buf, " RETURNING ");
1357
1358                 deparseExpr((Expr *) tle->expr, context);
1359
1360                 *retrieved_attrs = lappend_int(*retrieved_attrs, i + 1);
1361                 i++;
1362         }
1363
1364         if (i == 0 && !is_returning)
1365                 appendStringInfoString(buf, "NULL");
1366 }
1367
1368 /*
1369  * Emit expressions specified in the given relation's reltarget.
1370  *
1371  * This is used for deparsing the given relation as a subquery.
1372  */
1373 static void
1374 deparseSubqueryTargetList(deparse_expr_cxt *context)
1375 {
1376         StringInfo      buf = context->buf;
1377         RelOptInfo *foreignrel = context->foreignrel;
1378         bool            first;
1379         ListCell   *lc;
1380
1381         /* Should only be called in these cases. */
1382         Assert(IS_SIMPLE_REL(foreignrel) || IS_JOIN_REL(foreignrel));
1383
1384         first = true;
1385         foreach(lc, foreignrel->reltarget->exprs)
1386         {
1387                 Node       *node = (Node *) lfirst(lc);
1388
1389                 if (!first)
1390                         appendStringInfoString(buf, ", ");
1391                 first = false;
1392
1393                 deparseExpr((Expr *) node, context);
1394         }
1395
1396         /* Don't generate bad syntax if no expressions */
1397         if (first)
1398                 appendStringInfoString(buf, "NULL");
1399 }
1400
1401 /*
1402  * Construct FROM clause for given relation
1403  *
1404  * The function constructs ... JOIN ... ON ... for join relation. For a base
1405  * relation it just returns schema-qualified tablename, with the appropriate
1406  * alias if so requested.
1407  *
1408  * 'ignore_rel' is either zero or the RT index of a target relation.  In the
1409  * latter case the function constructs FROM clause of UPDATE or USING clause
1410  * of DELETE; it deparses the join relation as if the relation never contained
1411  * the target relation, and creates a List of conditions to be deparsed into
1412  * the top-level WHERE clause, which is returned to *ignore_conds.
1413  */
1414 static void
1415 deparseFromExprForRel(StringInfo buf, PlannerInfo *root, RelOptInfo *foreignrel,
1416                                           bool use_alias, Index ignore_rel, List **ignore_conds,
1417                                           List **params_list)
1418 {
1419         PgFdwRelationInfo *fpinfo = (PgFdwRelationInfo *) foreignrel->fdw_private;
1420
1421         if (IS_JOIN_REL(foreignrel))
1422         {
1423                 StringInfoData join_sql_o;
1424                 StringInfoData join_sql_i;
1425                 RelOptInfo *outerrel = fpinfo->outerrel;
1426                 RelOptInfo *innerrel = fpinfo->innerrel;
1427                 bool            outerrel_is_target = false;
1428                 bool            innerrel_is_target = false;
1429
1430                 if (ignore_rel > 0 && bms_is_member(ignore_rel, foreignrel->relids))
1431                 {
1432                         /*
1433                          * If this is an inner join, add joinclauses to *ignore_conds and
1434                          * set it to empty so that those can be deparsed into the WHERE
1435                          * clause.  Note that since the target relation can never be
1436                          * within the nullable side of an outer join, those could safely
1437                          * be pulled up into the WHERE clause (see foreign_join_ok()).
1438                          * Note also that since the target relation is only inner-joined
1439                          * to any other relation in the query, all conditions in the join
1440                          * tree mentioning the target relation could be deparsed into the
1441                          * WHERE clause by doing this recursively.
1442                          */
1443                         if (fpinfo->jointype == JOIN_INNER)
1444                         {
1445                                 *ignore_conds = list_concat(*ignore_conds,
1446                                                                                         list_copy(fpinfo->joinclauses));
1447                                 fpinfo->joinclauses = NIL;
1448                         }
1449
1450                         /*
1451                          * Check if either of the input relations is the target relation.
1452                          */
1453                         if (outerrel->relid == ignore_rel)
1454                                 outerrel_is_target = true;
1455                         else if (innerrel->relid == ignore_rel)
1456                                 innerrel_is_target = true;
1457                 }
1458
1459                 /* Deparse outer relation if not the target relation. */
1460                 if (!outerrel_is_target)
1461                 {
1462                         initStringInfo(&join_sql_o);
1463                         deparseRangeTblRef(&join_sql_o, root, outerrel,
1464                                                            fpinfo->make_outerrel_subquery,
1465                                                            ignore_rel, ignore_conds, params_list);
1466
1467                         /*
1468                          * If inner relation is the target relation, skip deparsing it.
1469                          * Note that since the join of the target relation with any other
1470                          * relation in the query is an inner join and can never be within
1471                          * the nullable side of an outer join, the join could be
1472                          * interchanged with higher-level joins (cf. identity 1 on outer
1473                          * join reordering shown in src/backend/optimizer/README), which
1474                          * means it's safe to skip the target-relation deparsing here.
1475                          */
1476                         if (innerrel_is_target)
1477                         {
1478                                 Assert(fpinfo->jointype == JOIN_INNER);
1479                                 Assert(fpinfo->joinclauses == NIL);
1480                                 appendStringInfo(buf, "%s", join_sql_o.data);
1481                                 return;
1482                         }
1483                 }
1484
1485                 /* Deparse inner relation if not the target relation. */
1486                 if (!innerrel_is_target)
1487                 {
1488                         initStringInfo(&join_sql_i);
1489                         deparseRangeTblRef(&join_sql_i, root, innerrel,
1490                                                            fpinfo->make_innerrel_subquery,
1491                                                            ignore_rel, ignore_conds, params_list);
1492
1493                         /*
1494                          * If outer relation is the target relation, skip deparsing it.
1495                          * See the above note about safety.
1496                          */
1497                         if (outerrel_is_target)
1498                         {
1499                                 Assert(fpinfo->jointype == JOIN_INNER);
1500                                 Assert(fpinfo->joinclauses == NIL);
1501                                 appendStringInfo(buf, "%s", join_sql_i.data);
1502                                 return;
1503                         }
1504                 }
1505
1506                 /* Neither of the relations is the target relation. */
1507                 Assert(!outerrel_is_target && !innerrel_is_target);
1508
1509                 /*
1510                  * For a join relation FROM clause entry is deparsed as
1511                  *
1512                  * ((outer relation) <join type> (inner relation) ON (joinclauses))
1513                  */
1514                 appendStringInfo(buf, "(%s %s JOIN %s ON ", join_sql_o.data,
1515                                                  get_jointype_name(fpinfo->jointype), join_sql_i.data);
1516
1517                 /* Append join clause; (TRUE) if no join clause */
1518                 if (fpinfo->joinclauses)
1519                 {
1520                         deparse_expr_cxt context;
1521
1522                         context.buf = buf;
1523                         context.foreignrel = foreignrel;
1524                         context.scanrel = foreignrel;
1525                         context.root = root;
1526                         context.params_list = params_list;
1527
1528                         appendStringInfoChar(buf, '(');
1529                         appendConditions(fpinfo->joinclauses, &context);
1530                         appendStringInfoChar(buf, ')');
1531                 }
1532                 else
1533                         appendStringInfoString(buf, "(TRUE)");
1534
1535                 /* End the FROM clause entry. */
1536                 appendStringInfoChar(buf, ')');
1537         }
1538         else
1539         {
1540                 RangeTblEntry *rte = planner_rt_fetch(foreignrel->relid, root);
1541
1542                 /*
1543                  * Core code already has some lock on each rel being planned, so we
1544                  * can use NoLock here.
1545                  */
1546                 Relation        rel = heap_open(rte->relid, NoLock);
1547
1548                 deparseRelation(buf, rel);
1549
1550                 /*
1551                  * Add a unique alias to avoid any conflict in relation names due to
1552                  * pulled up subqueries in the query being built for a pushed down
1553                  * join.
1554                  */
1555                 if (use_alias)
1556                         appendStringInfo(buf, " %s%d", REL_ALIAS_PREFIX, foreignrel->relid);
1557
1558                 heap_close(rel, NoLock);
1559         }
1560 }
1561
1562 /*
1563  * Append FROM clause entry for the given relation into buf.
1564  */
1565 static void
1566 deparseRangeTblRef(StringInfo buf, PlannerInfo *root, RelOptInfo *foreignrel,
1567                                    bool make_subquery, Index ignore_rel, List **ignore_conds,
1568                                    List **params_list)
1569 {
1570         PgFdwRelationInfo *fpinfo = (PgFdwRelationInfo *) foreignrel->fdw_private;
1571
1572         /* Should only be called in these cases. */
1573         Assert(IS_SIMPLE_REL(foreignrel) || IS_JOIN_REL(foreignrel));
1574
1575         Assert(fpinfo->local_conds == NIL);
1576
1577         /* If make_subquery is true, deparse the relation as a subquery. */
1578         if (make_subquery)
1579         {
1580                 List       *retrieved_attrs;
1581                 int                     ncols;
1582
1583                 /*
1584                  * The given relation shouldn't contain the target relation, because
1585                  * this should only happen for input relations for a full join, and
1586                  * such relations can never contain an UPDATE/DELETE target.
1587                  */
1588                 Assert(ignore_rel == 0 ||
1589                            !bms_is_member(ignore_rel, foreignrel->relids));
1590
1591                 /* Deparse the subquery representing the relation. */
1592                 appendStringInfoChar(buf, '(');
1593                 deparseSelectStmtForRel(buf, root, foreignrel, NIL,
1594                                                                 fpinfo->remote_conds, NIL, true,
1595                                                                 &retrieved_attrs, params_list);
1596                 appendStringInfoChar(buf, ')');
1597
1598                 /* Append the relation alias. */
1599                 appendStringInfo(buf, " %s%d", SUBQUERY_REL_ALIAS_PREFIX,
1600                                                  fpinfo->relation_index);
1601
1602                 /*
1603                  * Append the column aliases if needed.  Note that the subquery emits
1604                  * expressions specified in the relation's reltarget (see
1605                  * deparseSubqueryTargetList).
1606                  */
1607                 ncols = list_length(foreignrel->reltarget->exprs);
1608                 if (ncols > 0)
1609                 {
1610                         int                     i;
1611
1612                         appendStringInfoChar(buf, '(');
1613                         for (i = 1; i <= ncols; i++)
1614                         {
1615                                 if (i > 1)
1616                                         appendStringInfoString(buf, ", ");
1617
1618                                 appendStringInfo(buf, "%s%d", SUBQUERY_COL_ALIAS_PREFIX, i);
1619                         }
1620                         appendStringInfoChar(buf, ')');
1621                 }
1622         }
1623         else
1624                 deparseFromExprForRel(buf, root, foreignrel, true, ignore_rel,
1625                                                           ignore_conds, params_list);
1626 }
1627
1628 /*
1629  * deparse remote INSERT statement
1630  *
1631  * The statement text is appended to buf, and we also create an integer List
1632  * of the columns being retrieved by WITH CHECK OPTION or RETURNING (if any),
1633  * which is returned to *retrieved_attrs.
1634  */
1635 void
1636 deparseInsertSql(StringInfo buf, RangeTblEntry *rte,
1637                                  Index rtindex, Relation rel,
1638                                  List *targetAttrs, bool doNothing,
1639                                  List *withCheckOptionList, List *returningList,
1640                                  List **retrieved_attrs)
1641 {
1642         AttrNumber      pindex;
1643         bool            first;
1644         ListCell   *lc;
1645
1646         appendStringInfoString(buf, "INSERT INTO ");
1647         deparseRelation(buf, rel);
1648
1649         if (targetAttrs)
1650         {
1651                 appendStringInfoChar(buf, '(');
1652
1653                 first = true;
1654                 foreach(lc, targetAttrs)
1655                 {
1656                         int                     attnum = lfirst_int(lc);
1657
1658                         if (!first)
1659                                 appendStringInfoString(buf, ", ");
1660                         first = false;
1661
1662                         deparseColumnRef(buf, rtindex, attnum, rte, false);
1663                 }
1664
1665                 appendStringInfoString(buf, ") VALUES (");
1666
1667                 pindex = 1;
1668                 first = true;
1669                 foreach(lc, targetAttrs)
1670                 {
1671                         if (!first)
1672                                 appendStringInfoString(buf, ", ");
1673                         first = false;
1674
1675                         appendStringInfo(buf, "$%d", pindex);
1676                         pindex++;
1677                 }
1678
1679                 appendStringInfoChar(buf, ')');
1680         }
1681         else
1682                 appendStringInfoString(buf, " DEFAULT VALUES");
1683
1684         if (doNothing)
1685                 appendStringInfoString(buf, " ON CONFLICT DO NOTHING");
1686
1687         deparseReturningList(buf, rte, rtindex, rel,
1688                                                  rel->trigdesc && rel->trigdesc->trig_insert_after_row,
1689                                                  withCheckOptionList, returningList, retrieved_attrs);
1690 }
1691
1692 /*
1693  * deparse remote UPDATE statement
1694  *
1695  * The statement text is appended to buf, and we also create an integer List
1696  * of the columns being retrieved by WITH CHECK OPTION or RETURNING (if any),
1697  * which is returned to *retrieved_attrs.
1698  */
1699 void
1700 deparseUpdateSql(StringInfo buf, RangeTblEntry *rte,
1701                                  Index rtindex, Relation rel,
1702                                  List *targetAttrs,
1703                                  List *withCheckOptionList, List *returningList,
1704                                  List **retrieved_attrs)
1705 {
1706         AttrNumber      pindex;
1707         bool            first;
1708         ListCell   *lc;
1709
1710         appendStringInfoString(buf, "UPDATE ");
1711         deparseRelation(buf, rel);
1712         appendStringInfoString(buf, " SET ");
1713
1714         pindex = 2;                                     /* ctid is always the first param */
1715         first = true;
1716         foreach(lc, targetAttrs)
1717         {
1718                 int                     attnum = lfirst_int(lc);
1719
1720                 if (!first)
1721                         appendStringInfoString(buf, ", ");
1722                 first = false;
1723
1724                 deparseColumnRef(buf, rtindex, attnum, rte, false);
1725                 appendStringInfo(buf, " = $%d", pindex);
1726                 pindex++;
1727         }
1728         appendStringInfoString(buf, " WHERE ctid = $1");
1729
1730         deparseReturningList(buf, rte, rtindex, rel,
1731                                                  rel->trigdesc && rel->trigdesc->trig_update_after_row,
1732                                                  withCheckOptionList, returningList, retrieved_attrs);
1733 }
1734
1735 /*
1736  * deparse remote UPDATE statement
1737  *
1738  * 'buf' is the output buffer to append the statement to
1739  * 'rtindex' is the RT index of the associated target relation
1740  * 'rel' is the relation descriptor for the target relation
1741  * 'foreignrel' is the RelOptInfo for the target relation or the join relation
1742  *              containing all base relations in the query
1743  * 'targetlist' is the tlist of the underlying foreign-scan plan node
1744  * 'targetAttrs' is the target columns of the UPDATE
1745  * 'remote_conds' is the qual clauses that must be evaluated remotely
1746  * '*params_list' is an output list of exprs that will become remote Params
1747  * 'returningList' is the RETURNING targetlist
1748  * '*retrieved_attrs' is an output list of integers of columns being retrieved
1749  *              by RETURNING (if any)
1750  */
1751 void
1752 deparseDirectUpdateSql(StringInfo buf, PlannerInfo *root,
1753                                            Index rtindex, Relation rel,
1754                                            RelOptInfo *foreignrel,
1755                                            List *targetlist,
1756                                            List *targetAttrs,
1757                                            List *remote_conds,
1758                                            List **params_list,
1759                                            List *returningList,
1760                                            List **retrieved_attrs)
1761 {
1762         deparse_expr_cxt context;
1763         int                     nestlevel;
1764         bool            first;
1765         ListCell   *lc;
1766         RangeTblEntry *rte = planner_rt_fetch(rtindex, root);
1767
1768         /* Set up context struct for recursion */
1769         context.root = root;
1770         context.foreignrel = foreignrel;
1771         context.scanrel = foreignrel;
1772         context.buf = buf;
1773         context.params_list = params_list;
1774
1775         appendStringInfoString(buf, "UPDATE ");
1776         deparseRelation(buf, rel);
1777         if (foreignrel->reloptkind == RELOPT_JOINREL)
1778                 appendStringInfo(buf, " %s%d", REL_ALIAS_PREFIX, rtindex);
1779         appendStringInfoString(buf, " SET ");
1780
1781         /* Make sure any constants in the exprs are printed portably */
1782         nestlevel = set_transmission_modes();
1783
1784         first = true;
1785         foreach(lc, targetAttrs)
1786         {
1787                 int                     attnum = lfirst_int(lc);
1788                 TargetEntry *tle = get_tle_by_resno(targetlist, attnum);
1789
1790                 if (!tle)
1791                         elog(ERROR, "attribute number %d not found in UPDATE targetlist",
1792                                  attnum);
1793
1794                 if (!first)
1795                         appendStringInfoString(buf, ", ");
1796                 first = false;
1797
1798                 deparseColumnRef(buf, rtindex, attnum, rte, false);
1799                 appendStringInfoString(buf, " = ");
1800                 deparseExpr((Expr *) tle->expr, &context);
1801         }
1802
1803         reset_transmission_modes(nestlevel);
1804
1805         if (foreignrel->reloptkind == RELOPT_JOINREL)
1806         {
1807                 List       *ignore_conds = NIL;
1808
1809                 appendStringInfo(buf, " FROM ");
1810                 deparseFromExprForRel(buf, root, foreignrel, true, rtindex,
1811                                                           &ignore_conds, params_list);
1812                 remote_conds = list_concat(remote_conds, ignore_conds);
1813         }
1814
1815         if (remote_conds)
1816         {
1817                 appendStringInfoString(buf, " WHERE ");
1818                 appendConditions(remote_conds, &context);
1819         }
1820
1821         if (foreignrel->reloptkind == RELOPT_JOINREL)
1822                 deparseExplicitTargetList(returningList, true, retrieved_attrs,
1823                                                                   &context);
1824         else
1825                 deparseReturningList(buf, rte, rtindex, rel, false,
1826                                                          NIL, returningList, retrieved_attrs);
1827 }
1828
1829 /*
1830  * deparse remote DELETE statement
1831  *
1832  * The statement text is appended to buf, and we also create an integer List
1833  * of the columns being retrieved by RETURNING (if any), which is returned
1834  * to *retrieved_attrs.
1835  */
1836 void
1837 deparseDeleteSql(StringInfo buf, RangeTblEntry *rte,
1838                                  Index rtindex, Relation rel,
1839                                  List *returningList,
1840                                  List **retrieved_attrs)
1841 {
1842         appendStringInfoString(buf, "DELETE FROM ");
1843         deparseRelation(buf, rel);
1844         appendStringInfoString(buf, " WHERE ctid = $1");
1845
1846         deparseReturningList(buf, rte, rtindex, rel,
1847                                                  rel->trigdesc && rel->trigdesc->trig_delete_after_row,
1848                                                  NIL, returningList, retrieved_attrs);
1849 }
1850
1851 /*
1852  * deparse remote DELETE statement
1853  *
1854  * 'buf' is the output buffer to append the statement to
1855  * 'rtindex' is the RT index of the associated target relation
1856  * 'rel' is the relation descriptor for the target relation
1857  * 'foreignrel' is the RelOptInfo for the target relation or the join relation
1858  *              containing all base relations in the query
1859  * 'remote_conds' is the qual clauses that must be evaluated remotely
1860  * '*params_list' is an output list of exprs that will become remote Params
1861  * 'returningList' is the RETURNING targetlist
1862  * '*retrieved_attrs' is an output list of integers of columns being retrieved
1863  *              by RETURNING (if any)
1864  */
1865 void
1866 deparseDirectDeleteSql(StringInfo buf, PlannerInfo *root,
1867                                            Index rtindex, Relation rel,
1868                                            RelOptInfo *foreignrel,
1869                                            List *remote_conds,
1870                                            List **params_list,
1871                                            List *returningList,
1872                                            List **retrieved_attrs)
1873 {
1874         deparse_expr_cxt context;
1875
1876         /* Set up context struct for recursion */
1877         context.root = root;
1878         context.foreignrel = foreignrel;
1879         context.scanrel = foreignrel;
1880         context.buf = buf;
1881         context.params_list = params_list;
1882
1883         appendStringInfoString(buf, "DELETE FROM ");
1884         deparseRelation(buf, rel);
1885         if (foreignrel->reloptkind == RELOPT_JOINREL)
1886                 appendStringInfo(buf, " %s%d", REL_ALIAS_PREFIX, rtindex);
1887
1888         if (foreignrel->reloptkind == RELOPT_JOINREL)
1889         {
1890                 List       *ignore_conds = NIL;
1891
1892                 appendStringInfo(buf, " USING ");
1893                 deparseFromExprForRel(buf, root, foreignrel, true, rtindex,
1894                                                           &ignore_conds, params_list);
1895                 remote_conds = list_concat(remote_conds, ignore_conds);
1896         }
1897
1898         if (remote_conds)
1899         {
1900                 appendStringInfoString(buf, " WHERE ");
1901                 appendConditions(remote_conds, &context);
1902         }
1903
1904         if (foreignrel->reloptkind == RELOPT_JOINREL)
1905                 deparseExplicitTargetList(returningList, true, retrieved_attrs,
1906                                                                   &context);
1907         else
1908                 deparseReturningList(buf, planner_rt_fetch(rtindex, root),
1909                                                          rtindex, rel, false,
1910                                                          NIL, returningList, retrieved_attrs);
1911 }
1912
1913 /*
1914  * Add a RETURNING clause, if needed, to an INSERT/UPDATE/DELETE.
1915  */
1916 static void
1917 deparseReturningList(StringInfo buf, RangeTblEntry *rte,
1918                                          Index rtindex, Relation rel,
1919                                          bool trig_after_row,
1920                                          List *withCheckOptionList,
1921                                          List *returningList,
1922                                          List **retrieved_attrs)
1923 {
1924         Bitmapset  *attrs_used = NULL;
1925
1926         if (trig_after_row)
1927         {
1928                 /* whole-row reference acquires all non-system columns */
1929                 attrs_used =
1930                         bms_make_singleton(0 - FirstLowInvalidHeapAttributeNumber);
1931         }
1932
1933         if (withCheckOptionList != NIL)
1934         {
1935                 /*
1936                  * We need the attrs, non-system and system, mentioned in the local
1937                  * query's WITH CHECK OPTION list.
1938                  *
1939                  * Note: we do this to ensure that WCO constraints will be evaluated
1940                  * on the data actually inserted/updated on the remote side, which
1941                  * might differ from the data supplied by the core code, for example
1942                  * as a result of remote triggers.
1943                  */
1944                 pull_varattnos((Node *) withCheckOptionList, rtindex,
1945                                            &attrs_used);
1946         }
1947
1948         if (returningList != NIL)
1949         {
1950                 /*
1951                  * We need the attrs, non-system and system, mentioned in the local
1952                  * query's RETURNING list.
1953                  */
1954                 pull_varattnos((Node *) returningList, rtindex,
1955                                            &attrs_used);
1956         }
1957
1958         if (attrs_used != NULL)
1959                 deparseTargetList(buf, rte, rtindex, rel, true, attrs_used, false,
1960                                                   retrieved_attrs);
1961         else
1962                 *retrieved_attrs = NIL;
1963 }
1964
1965 /*
1966  * Construct SELECT statement to acquire size in blocks of given relation.
1967  *
1968  * Note: we use local definition of block size, not remote definition.
1969  * This is perhaps debatable.
1970  *
1971  * Note: pg_relation_size() exists in 8.1 and later.
1972  */
1973 void
1974 deparseAnalyzeSizeSql(StringInfo buf, Relation rel)
1975 {
1976         StringInfoData relname;
1977
1978         /* We'll need the remote relation name as a literal. */
1979         initStringInfo(&relname);
1980         deparseRelation(&relname, rel);
1981
1982         appendStringInfoString(buf, "SELECT pg_catalog.pg_relation_size(");
1983         deparseStringLiteral(buf, relname.data);
1984         appendStringInfo(buf, "::pg_catalog.regclass) / %d", BLCKSZ);
1985 }
1986
1987 /*
1988  * Construct SELECT statement to acquire sample rows of given relation.
1989  *
1990  * SELECT command is appended to buf, and list of columns retrieved
1991  * is returned to *retrieved_attrs.
1992  */
1993 void
1994 deparseAnalyzeSql(StringInfo buf, Relation rel, List **retrieved_attrs)
1995 {
1996         Oid                     relid = RelationGetRelid(rel);
1997         TupleDesc       tupdesc = RelationGetDescr(rel);
1998         int                     i;
1999         char       *colname;
2000         List       *options;
2001         ListCell   *lc;
2002         bool            first = true;
2003
2004         *retrieved_attrs = NIL;
2005
2006         appendStringInfoString(buf, "SELECT ");
2007         for (i = 0; i < tupdesc->natts; i++)
2008         {
2009                 /* Ignore dropped columns. */
2010                 if (TupleDescAttr(tupdesc, i)->attisdropped)
2011                         continue;
2012
2013                 if (!first)
2014                         appendStringInfoString(buf, ", ");
2015                 first = false;
2016
2017                 /* Use attribute name or column_name option. */
2018                 colname = NameStr(TupleDescAttr(tupdesc, i)->attname);
2019                 options = GetForeignColumnOptions(relid, i + 1);
2020
2021                 foreach(lc, options)
2022                 {
2023                         DefElem    *def = (DefElem *) lfirst(lc);
2024
2025                         if (strcmp(def->defname, "column_name") == 0)
2026                         {
2027                                 colname = defGetString(def);
2028                                 break;
2029                         }
2030                 }
2031
2032                 appendStringInfoString(buf, quote_identifier(colname));
2033
2034                 *retrieved_attrs = lappend_int(*retrieved_attrs, i + 1);
2035         }
2036
2037         /* Don't generate bad syntax for zero-column relation. */
2038         if (first)
2039                 appendStringInfoString(buf, "NULL");
2040
2041         /*
2042          * Construct FROM clause
2043          */
2044         appendStringInfoString(buf, " FROM ");
2045         deparseRelation(buf, rel);
2046 }
2047
2048 /*
2049  * Construct name to use for given column, and emit it into buf.
2050  * If it has a column_name FDW option, use that instead of attribute name.
2051  *
2052  * If qualify_col is true, qualify column name with the alias of relation.
2053  */
2054 static void
2055 deparseColumnRef(StringInfo buf, int varno, int varattno, RangeTblEntry *rte,
2056                                  bool qualify_col)
2057 {
2058         /* We support fetching the remote side's CTID and OID. */
2059         if (varattno == SelfItemPointerAttributeNumber)
2060         {
2061                 if (qualify_col)
2062                         ADD_REL_QUALIFIER(buf, varno);
2063                 appendStringInfoString(buf, "ctid");
2064         }
2065         else if (varattno < 0)
2066         {
2067                 /*
2068                  * All other system attributes are fetched as 0, except for table OID,
2069                  * which is fetched as the local table OID.  However, we must be
2070                  * careful; the table could be beneath an outer join, in which case it
2071                  * must go to NULL whenever the rest of the row does.
2072                  */
2073                 Oid                     fetchval = 0;
2074
2075                 if (varattno == TableOidAttributeNumber)
2076                         fetchval = rte->relid;
2077
2078                 if (qualify_col)
2079                 {
2080                         appendStringInfoString(buf, "CASE WHEN (");
2081                         ADD_REL_QUALIFIER(buf, varno);
2082                         appendStringInfo(buf, "*)::text IS NOT NULL THEN %u END", fetchval);
2083                 }
2084                 else
2085                         appendStringInfo(buf, "%u", fetchval);
2086         }
2087         else if (varattno == 0)
2088         {
2089                 /* Whole row reference */
2090                 Relation        rel;
2091                 Bitmapset  *attrs_used;
2092
2093                 /* Required only to be passed down to deparseTargetList(). */
2094                 List       *retrieved_attrs;
2095
2096                 /*
2097                  * The lock on the relation will be held by upper callers, so it's
2098                  * fine to open it with no lock here.
2099                  */
2100                 rel = heap_open(rte->relid, NoLock);
2101
2102                 /*
2103                  * The local name of the foreign table can not be recognized by the
2104                  * foreign server and the table it references on foreign server might
2105                  * have different column ordering or different columns than those
2106                  * declared locally. Hence we have to deparse whole-row reference as
2107                  * ROW(columns referenced locally). Construct this by deparsing a
2108                  * "whole row" attribute.
2109                  */
2110                 attrs_used = bms_add_member(NULL,
2111                                                                         0 - FirstLowInvalidHeapAttributeNumber);
2112
2113                 /*
2114                  * In case the whole-row reference is under an outer join then it has
2115                  * to go NULL whenever the rest of the row goes NULL. Deparsing a join
2116                  * query would always involve multiple relations, thus qualify_col
2117                  * would be true.
2118                  */
2119                 if (qualify_col)
2120                 {
2121                         appendStringInfoString(buf, "CASE WHEN (");
2122                         ADD_REL_QUALIFIER(buf, varno);
2123                         appendStringInfoString(buf, "*)::text IS NOT NULL THEN ");
2124                 }
2125
2126                 appendStringInfoString(buf, "ROW(");
2127                 deparseTargetList(buf, rte, varno, rel, false, attrs_used, qualify_col,
2128                                                   &retrieved_attrs);
2129                 appendStringInfoChar(buf, ')');
2130
2131                 /* Complete the CASE WHEN statement started above. */
2132                 if (qualify_col)
2133                         appendStringInfoString(buf, " END");
2134
2135                 heap_close(rel, NoLock);
2136                 bms_free(attrs_used);
2137         }
2138         else
2139         {
2140                 char       *colname = NULL;
2141                 List       *options;
2142                 ListCell   *lc;
2143
2144                 /* varno must not be any of OUTER_VAR, INNER_VAR and INDEX_VAR. */
2145                 Assert(!IS_SPECIAL_VARNO(varno));
2146
2147                 /*
2148                  * If it's a column of a foreign table, and it has the column_name FDW
2149                  * option, use that value.
2150                  */
2151                 options = GetForeignColumnOptions(rte->relid, varattno);
2152                 foreach(lc, options)
2153                 {
2154                         DefElem    *def = (DefElem *) lfirst(lc);
2155
2156                         if (strcmp(def->defname, "column_name") == 0)
2157                         {
2158                                 colname = defGetString(def);
2159                                 break;
2160                         }
2161                 }
2162
2163                 /*
2164                  * If it's a column of a regular table or it doesn't have column_name
2165                  * FDW option, use attribute name.
2166                  */
2167                 if (colname == NULL)
2168                         colname = get_attname(rte->relid, varattno, false);
2169
2170                 if (qualify_col)
2171                         ADD_REL_QUALIFIER(buf, varno);
2172
2173                 appendStringInfoString(buf, quote_identifier(colname));
2174         }
2175 }
2176
2177 /*
2178  * Append remote name of specified foreign table to buf.
2179  * Use value of table_name FDW option (if any) instead of relation's name.
2180  * Similarly, schema_name FDW option overrides schema name.
2181  */
2182 static void
2183 deparseRelation(StringInfo buf, Relation rel)
2184 {
2185         ForeignTable *table;
2186         const char *nspname = NULL;
2187         const char *relname = NULL;
2188         ListCell   *lc;
2189
2190         /* obtain additional catalog information. */
2191         table = GetForeignTable(RelationGetRelid(rel));
2192
2193         /*
2194          * Use value of FDW options if any, instead of the name of object itself.
2195          */
2196         foreach(lc, table->options)
2197         {
2198                 DefElem    *def = (DefElem *) lfirst(lc);
2199
2200                 if (strcmp(def->defname, "schema_name") == 0)
2201                         nspname = defGetString(def);
2202                 else if (strcmp(def->defname, "table_name") == 0)
2203                         relname = defGetString(def);
2204         }
2205
2206         /*
2207          * Note: we could skip printing the schema name if it's pg_catalog, but
2208          * that doesn't seem worth the trouble.
2209          */
2210         if (nspname == NULL)
2211                 nspname = get_namespace_name(RelationGetNamespace(rel));
2212         if (relname == NULL)
2213                 relname = RelationGetRelationName(rel);
2214
2215         appendStringInfo(buf, "%s.%s",
2216                                          quote_identifier(nspname), quote_identifier(relname));
2217 }
2218
2219 /*
2220  * Append a SQL string literal representing "val" to buf.
2221  */
2222 void
2223 deparseStringLiteral(StringInfo buf, const char *val)
2224 {
2225         const char *valptr;
2226
2227         /*
2228          * Rather than making assumptions about the remote server's value of
2229          * standard_conforming_strings, always use E'foo' syntax if there are any
2230          * backslashes.  This will fail on remote servers before 8.1, but those
2231          * are long out of support.
2232          */
2233         if (strchr(val, '\\') != NULL)
2234                 appendStringInfoChar(buf, ESCAPE_STRING_SYNTAX);
2235         appendStringInfoChar(buf, '\'');
2236         for (valptr = val; *valptr; valptr++)
2237         {
2238                 char            ch = *valptr;
2239
2240                 if (SQL_STR_DOUBLE(ch, true))
2241                         appendStringInfoChar(buf, ch);
2242                 appendStringInfoChar(buf, ch);
2243         }
2244         appendStringInfoChar(buf, '\'');
2245 }
2246
2247 /*
2248  * Deparse given expression into context->buf.
2249  *
2250  * This function must support all the same node types that foreign_expr_walker
2251  * accepts.
2252  *
2253  * Note: unlike ruleutils.c, we just use a simple hard-wired parenthesization
2254  * scheme: anything more complex than a Var, Const, function call or cast
2255  * should be self-parenthesized.
2256  */
2257 static void
2258 deparseExpr(Expr *node, deparse_expr_cxt *context)
2259 {
2260         if (node == NULL)
2261                 return;
2262
2263         switch (nodeTag(node))
2264         {
2265                 case T_Var:
2266                         deparseVar((Var *) node, context);
2267                         break;
2268                 case T_Const:
2269                         deparseConst((Const *) node, context, 0);
2270                         break;
2271                 case T_Param:
2272                         deparseParam((Param *) node, context);
2273                         break;
2274                 case T_ArrayRef:
2275                         deparseArrayRef((ArrayRef *) node, context);
2276                         break;
2277                 case T_FuncExpr:
2278                         deparseFuncExpr((FuncExpr *) node, context);
2279                         break;
2280                 case T_OpExpr:
2281                         deparseOpExpr((OpExpr *) node, context);
2282                         break;
2283                 case T_DistinctExpr:
2284                         deparseDistinctExpr((DistinctExpr *) node, context);
2285                         break;
2286                 case T_ScalarArrayOpExpr:
2287                         deparseScalarArrayOpExpr((ScalarArrayOpExpr *) node, context);
2288                         break;
2289                 case T_RelabelType:
2290                         deparseRelabelType((RelabelType *) node, context);
2291                         break;
2292                 case T_BoolExpr:
2293                         deparseBoolExpr((BoolExpr *) node, context);
2294                         break;
2295                 case T_NullTest:
2296                         deparseNullTest((NullTest *) node, context);
2297                         break;
2298                 case T_ArrayExpr:
2299                         deparseArrayExpr((ArrayExpr *) node, context);
2300                         break;
2301                 case T_Aggref:
2302                         deparseAggref((Aggref *) node, context);
2303                         break;
2304                 default:
2305                         elog(ERROR, "unsupported expression type for deparse: %d",
2306                                  (int) nodeTag(node));
2307                         break;
2308         }
2309 }
2310
2311 /*
2312  * Deparse given Var node into context->buf.
2313  *
2314  * If the Var belongs to the foreign relation, just print its remote name.
2315  * Otherwise, it's effectively a Param (and will in fact be a Param at
2316  * run time).  Handle it the same way we handle plain Params --- see
2317  * deparseParam for comments.
2318  */
2319 static void
2320 deparseVar(Var *node, deparse_expr_cxt *context)
2321 {
2322         Relids          relids = context->scanrel->relids;
2323         int                     relno;
2324         int                     colno;
2325
2326         /* Qualify columns when multiple relations are involved. */
2327         bool            qualify_col = (bms_membership(relids) == BMS_MULTIPLE);
2328
2329         /*
2330          * If the Var belongs to the foreign relation that is deparsed as a
2331          * subquery, use the relation and column alias to the Var provided by the
2332          * subquery, instead of the remote name.
2333          */
2334         if (is_subquery_var(node, context->scanrel, &relno, &colno))
2335         {
2336                 appendStringInfo(context->buf, "%s%d.%s%d",
2337                                                  SUBQUERY_REL_ALIAS_PREFIX, relno,
2338                                                  SUBQUERY_COL_ALIAS_PREFIX, colno);
2339                 return;
2340         }
2341
2342         if (bms_is_member(node->varno, relids) && node->varlevelsup == 0)
2343                 deparseColumnRef(context->buf, node->varno, node->varattno,
2344                                                  planner_rt_fetch(node->varno, context->root),
2345                                                  qualify_col);
2346         else
2347         {
2348                 /* Treat like a Param */
2349                 if (context->params_list)
2350                 {
2351                         int                     pindex = 0;
2352                         ListCell   *lc;
2353
2354                         /* find its index in params_list */
2355                         foreach(lc, *context->params_list)
2356                         {
2357                                 pindex++;
2358                                 if (equal(node, (Node *) lfirst(lc)))
2359                                         break;
2360                         }
2361                         if (lc == NULL)
2362                         {
2363                                 /* not in list, so add it */
2364                                 pindex++;
2365                                 *context->params_list = lappend(*context->params_list, node);
2366                         }
2367
2368                         printRemoteParam(pindex, node->vartype, node->vartypmod, context);
2369                 }
2370                 else
2371                 {
2372                         printRemotePlaceholder(node->vartype, node->vartypmod, context);
2373                 }
2374         }
2375 }
2376
2377 /*
2378  * Deparse given constant value into context->buf.
2379  *
2380  * This function has to be kept in sync with ruleutils.c's get_const_expr.
2381  * As for that function, showtype can be -1 to never show "::typename" decoration,
2382  * or +1 to always show it, or 0 to show it only if the constant wouldn't be assumed
2383  * to be the right type by default.
2384  */
2385 static void
2386 deparseConst(Const *node, deparse_expr_cxt *context, int showtype)
2387 {
2388         StringInfo      buf = context->buf;
2389         Oid                     typoutput;
2390         bool            typIsVarlena;
2391         char       *extval;
2392         bool            isfloat = false;
2393         bool            needlabel;
2394
2395         if (node->constisnull)
2396         {
2397                 appendStringInfoString(buf, "NULL");
2398                 if (showtype >= 0)
2399                         appendStringInfo(buf, "::%s",
2400                                                          deparse_type_name(node->consttype,
2401                                                                                            node->consttypmod));
2402                 return;
2403         }
2404
2405         getTypeOutputInfo(node->consttype,
2406                                           &typoutput, &typIsVarlena);
2407         extval = OidOutputFunctionCall(typoutput, node->constvalue);
2408
2409         switch (node->consttype)
2410         {
2411                 case INT2OID:
2412                 case INT4OID:
2413                 case INT8OID:
2414                 case OIDOID:
2415                 case FLOAT4OID:
2416                 case FLOAT8OID:
2417                 case NUMERICOID:
2418                         {
2419                                 /*
2420                                  * No need to quote unless it's a special value such as 'NaN'.
2421                                  * See comments in get_const_expr().
2422                                  */
2423                                 if (strspn(extval, "0123456789+-eE.") == strlen(extval))
2424                                 {
2425                                         if (extval[0] == '+' || extval[0] == '-')
2426                                                 appendStringInfo(buf, "(%s)", extval);
2427                                         else
2428                                                 appendStringInfoString(buf, extval);
2429                                         if (strcspn(extval, "eE.") != strlen(extval))
2430                                                 isfloat = true; /* it looks like a float */
2431                                 }
2432                                 else
2433                                         appendStringInfo(buf, "'%s'", extval);
2434                         }
2435                         break;
2436                 case BITOID:
2437                 case VARBITOID:
2438                         appendStringInfo(buf, "B'%s'", extval);
2439                         break;
2440                 case BOOLOID:
2441                         if (strcmp(extval, "t") == 0)
2442                                 appendStringInfoString(buf, "true");
2443                         else
2444                                 appendStringInfoString(buf, "false");
2445                         break;
2446                 default:
2447                         deparseStringLiteral(buf, extval);
2448                         break;
2449         }
2450
2451         pfree(extval);
2452
2453         if (showtype < 0)
2454                 return;
2455
2456         /*
2457          * For showtype == 0, append ::typename unless the constant will be
2458          * implicitly typed as the right type when it is read in.
2459          *
2460          * XXX this code has to be kept in sync with the behavior of the parser,
2461          * especially make_const.
2462          */
2463         switch (node->consttype)
2464         {
2465                 case BOOLOID:
2466                 case INT4OID:
2467                 case UNKNOWNOID:
2468                         needlabel = false;
2469                         break;
2470                 case NUMERICOID:
2471                         needlabel = !isfloat || (node->consttypmod >= 0);
2472                         break;
2473                 default:
2474                         needlabel = true;
2475                         break;
2476         }
2477         if (needlabel || showtype > 0)
2478                 appendStringInfo(buf, "::%s",
2479                                                  deparse_type_name(node->consttype,
2480                                                                                    node->consttypmod));
2481 }
2482
2483 /*
2484  * Deparse given Param node.
2485  *
2486  * If we're generating the query "for real", add the Param to
2487  * context->params_list if it's not already present, and then use its index
2488  * in that list as the remote parameter number.  During EXPLAIN, there's
2489  * no need to identify a parameter number.
2490  */
2491 static void
2492 deparseParam(Param *node, deparse_expr_cxt *context)
2493 {
2494         if (context->params_list)
2495         {
2496                 int                     pindex = 0;
2497                 ListCell   *lc;
2498
2499                 /* find its index in params_list */
2500                 foreach(lc, *context->params_list)
2501                 {
2502                         pindex++;
2503                         if (equal(node, (Node *) lfirst(lc)))
2504                                 break;
2505                 }
2506                 if (lc == NULL)
2507                 {
2508                         /* not in list, so add it */
2509                         pindex++;
2510                         *context->params_list = lappend(*context->params_list, node);
2511                 }
2512
2513                 printRemoteParam(pindex, node->paramtype, node->paramtypmod, context);
2514         }
2515         else
2516         {
2517                 printRemotePlaceholder(node->paramtype, node->paramtypmod, context);
2518         }
2519 }
2520
2521 /*
2522  * Deparse an array subscript expression.
2523  */
2524 static void
2525 deparseArrayRef(ArrayRef *node, deparse_expr_cxt *context)
2526 {
2527         StringInfo      buf = context->buf;
2528         ListCell   *lowlist_item;
2529         ListCell   *uplist_item;
2530
2531         /* Always parenthesize the expression. */
2532         appendStringInfoChar(buf, '(');
2533
2534         /*
2535          * Deparse referenced array expression first.  If that expression includes
2536          * a cast, we have to parenthesize to prevent the array subscript from
2537          * being taken as typename decoration.  We can avoid that in the typical
2538          * case of subscripting a Var, but otherwise do it.
2539          */
2540         if (IsA(node->refexpr, Var))
2541                 deparseExpr(node->refexpr, context);
2542         else
2543         {
2544                 appendStringInfoChar(buf, '(');
2545                 deparseExpr(node->refexpr, context);
2546                 appendStringInfoChar(buf, ')');
2547         }
2548
2549         /* Deparse subscript expressions. */
2550         lowlist_item = list_head(node->reflowerindexpr);        /* could be NULL */
2551         foreach(uplist_item, node->refupperindexpr)
2552         {
2553                 appendStringInfoChar(buf, '[');
2554                 if (lowlist_item)
2555                 {
2556                         deparseExpr(lfirst(lowlist_item), context);
2557                         appendStringInfoChar(buf, ':');
2558                         lowlist_item = lnext(lowlist_item);
2559                 }
2560                 deparseExpr(lfirst(uplist_item), context);
2561                 appendStringInfoChar(buf, ']');
2562         }
2563
2564         appendStringInfoChar(buf, ')');
2565 }
2566
2567 /*
2568  * Deparse a function call.
2569  */
2570 static void
2571 deparseFuncExpr(FuncExpr *node, deparse_expr_cxt *context)
2572 {
2573         StringInfo      buf = context->buf;
2574         bool            use_variadic;
2575         bool            first;
2576         ListCell   *arg;
2577
2578         /*
2579          * If the function call came from an implicit coercion, then just show the
2580          * first argument.
2581          */
2582         if (node->funcformat == COERCE_IMPLICIT_CAST)
2583         {
2584                 deparseExpr((Expr *) linitial(node->args), context);
2585                 return;
2586         }
2587
2588         /*
2589          * If the function call came from a cast, then show the first argument
2590          * plus an explicit cast operation.
2591          */
2592         if (node->funcformat == COERCE_EXPLICIT_CAST)
2593         {
2594                 Oid                     rettype = node->funcresulttype;
2595                 int32           coercedTypmod;
2596
2597                 /* Get the typmod if this is a length-coercion function */
2598                 (void) exprIsLengthCoercion((Node *) node, &coercedTypmod);
2599
2600                 deparseExpr((Expr *) linitial(node->args), context);
2601                 appendStringInfo(buf, "::%s",
2602                                                  deparse_type_name(rettype, coercedTypmod));
2603                 return;
2604         }
2605
2606         /* Check if need to print VARIADIC (cf. ruleutils.c) */
2607         use_variadic = node->funcvariadic;
2608
2609         /*
2610          * Normal function: display as proname(args).
2611          */
2612         appendFunctionName(node->funcid, context);
2613         appendStringInfoChar(buf, '(');
2614
2615         /* ... and all the arguments */
2616         first = true;
2617         foreach(arg, node->args)
2618         {
2619                 if (!first)
2620                         appendStringInfoString(buf, ", ");
2621                 if (use_variadic && lnext(arg) == NULL)
2622                         appendStringInfoString(buf, "VARIADIC ");
2623                 deparseExpr((Expr *) lfirst(arg), context);
2624                 first = false;
2625         }
2626         appendStringInfoChar(buf, ')');
2627 }
2628
2629 /*
2630  * Deparse given operator expression.   To avoid problems around
2631  * priority of operations, we always parenthesize the arguments.
2632  */
2633 static void
2634 deparseOpExpr(OpExpr *node, deparse_expr_cxt *context)
2635 {
2636         StringInfo      buf = context->buf;
2637         HeapTuple       tuple;
2638         Form_pg_operator form;
2639         char            oprkind;
2640         ListCell   *arg;
2641
2642         /* Retrieve information about the operator from system catalog. */
2643         tuple = SearchSysCache1(OPEROID, ObjectIdGetDatum(node->opno));
2644         if (!HeapTupleIsValid(tuple))
2645                 elog(ERROR, "cache lookup failed for operator %u", node->opno);
2646         form = (Form_pg_operator) GETSTRUCT(tuple);
2647         oprkind = form->oprkind;
2648
2649         /* Sanity check. */
2650         Assert((oprkind == 'r' && list_length(node->args) == 1) ||
2651                    (oprkind == 'l' && list_length(node->args) == 1) ||
2652                    (oprkind == 'b' && list_length(node->args) == 2));
2653
2654         /* Always parenthesize the expression. */
2655         appendStringInfoChar(buf, '(');
2656
2657         /* Deparse left operand. */
2658         if (oprkind == 'r' || oprkind == 'b')
2659         {
2660                 arg = list_head(node->args);
2661                 deparseExpr(lfirst(arg), context);
2662                 appendStringInfoChar(buf, ' ');
2663         }
2664
2665         /* Deparse operator name. */
2666         deparseOperatorName(buf, form);
2667
2668         /* Deparse right operand. */
2669         if (oprkind == 'l' || oprkind == 'b')
2670         {
2671                 arg = list_tail(node->args);
2672                 appendStringInfoChar(buf, ' ');
2673                 deparseExpr(lfirst(arg), context);
2674         }
2675
2676         appendStringInfoChar(buf, ')');
2677
2678         ReleaseSysCache(tuple);
2679 }
2680
2681 /*
2682  * Print the name of an operator.
2683  */
2684 static void
2685 deparseOperatorName(StringInfo buf, Form_pg_operator opform)
2686 {
2687         char       *opname;
2688
2689         /* opname is not a SQL identifier, so we should not quote it. */
2690         opname = NameStr(opform->oprname);
2691
2692         /* Print schema name only if it's not pg_catalog */
2693         if (opform->oprnamespace != PG_CATALOG_NAMESPACE)
2694         {
2695                 const char *opnspname;
2696
2697                 opnspname = get_namespace_name(opform->oprnamespace);
2698                 /* Print fully qualified operator name. */
2699                 appendStringInfo(buf, "OPERATOR(%s.%s)",
2700                                                  quote_identifier(opnspname), opname);
2701         }
2702         else
2703         {
2704                 /* Just print operator name. */
2705                 appendStringInfoString(buf, opname);
2706         }
2707 }
2708
2709 /*
2710  * Deparse IS DISTINCT FROM.
2711  */
2712 static void
2713 deparseDistinctExpr(DistinctExpr *node, deparse_expr_cxt *context)
2714 {
2715         StringInfo      buf = context->buf;
2716
2717         Assert(list_length(node->args) == 2);
2718
2719         appendStringInfoChar(buf, '(');
2720         deparseExpr(linitial(node->args), context);
2721         appendStringInfoString(buf, " IS DISTINCT FROM ");
2722         deparseExpr(lsecond(node->args), context);
2723         appendStringInfoChar(buf, ')');
2724 }
2725
2726 /*
2727  * Deparse given ScalarArrayOpExpr expression.  To avoid problems
2728  * around priority of operations, we always parenthesize the arguments.
2729  */
2730 static void
2731 deparseScalarArrayOpExpr(ScalarArrayOpExpr *node, deparse_expr_cxt *context)
2732 {
2733         StringInfo      buf = context->buf;
2734         HeapTuple       tuple;
2735         Form_pg_operator form;
2736         Expr       *arg1;
2737         Expr       *arg2;
2738
2739         /* Retrieve information about the operator from system catalog. */
2740         tuple = SearchSysCache1(OPEROID, ObjectIdGetDatum(node->opno));
2741         if (!HeapTupleIsValid(tuple))
2742                 elog(ERROR, "cache lookup failed for operator %u", node->opno);
2743         form = (Form_pg_operator) GETSTRUCT(tuple);
2744
2745         /* Sanity check. */
2746         Assert(list_length(node->args) == 2);
2747
2748         /* Always parenthesize the expression. */
2749         appendStringInfoChar(buf, '(');
2750
2751         /* Deparse left operand. */
2752         arg1 = linitial(node->args);
2753         deparseExpr(arg1, context);
2754         appendStringInfoChar(buf, ' ');
2755
2756         /* Deparse operator name plus decoration. */
2757         deparseOperatorName(buf, form);
2758         appendStringInfo(buf, " %s (", node->useOr ? "ANY" : "ALL");
2759
2760         /* Deparse right operand. */
2761         arg2 = lsecond(node->args);
2762         deparseExpr(arg2, context);
2763
2764         appendStringInfoChar(buf, ')');
2765
2766         /* Always parenthesize the expression. */
2767         appendStringInfoChar(buf, ')');
2768
2769         ReleaseSysCache(tuple);
2770 }
2771
2772 /*
2773  * Deparse a RelabelType (binary-compatible cast) node.
2774  */
2775 static void
2776 deparseRelabelType(RelabelType *node, deparse_expr_cxt *context)
2777 {
2778         deparseExpr(node->arg, context);
2779         if (node->relabelformat != COERCE_IMPLICIT_CAST)
2780                 appendStringInfo(context->buf, "::%s",
2781                                                  deparse_type_name(node->resulttype,
2782                                                                                    node->resulttypmod));
2783 }
2784
2785 /*
2786  * Deparse a BoolExpr node.
2787  */
2788 static void
2789 deparseBoolExpr(BoolExpr *node, deparse_expr_cxt *context)
2790 {
2791         StringInfo      buf = context->buf;
2792         const char *op = NULL;          /* keep compiler quiet */
2793         bool            first;
2794         ListCell   *lc;
2795
2796         switch (node->boolop)
2797         {
2798                 case AND_EXPR:
2799                         op = "AND";
2800                         break;
2801                 case OR_EXPR:
2802                         op = "OR";
2803                         break;
2804                 case NOT_EXPR:
2805                         appendStringInfoString(buf, "(NOT ");
2806                         deparseExpr(linitial(node->args), context);
2807                         appendStringInfoChar(buf, ')');
2808                         return;
2809         }
2810
2811         appendStringInfoChar(buf, '(');
2812         first = true;
2813         foreach(lc, node->args)
2814         {
2815                 if (!first)
2816                         appendStringInfo(buf, " %s ", op);
2817                 deparseExpr((Expr *) lfirst(lc), context);
2818                 first = false;
2819         }
2820         appendStringInfoChar(buf, ')');
2821 }
2822
2823 /*
2824  * Deparse IS [NOT] NULL expression.
2825  */
2826 static void
2827 deparseNullTest(NullTest *node, deparse_expr_cxt *context)
2828 {
2829         StringInfo      buf = context->buf;
2830
2831         appendStringInfoChar(buf, '(');
2832         deparseExpr(node->arg, context);
2833
2834         /*
2835          * For scalar inputs, we prefer to print as IS [NOT] NULL, which is
2836          * shorter and traditional.  If it's a rowtype input but we're applying a
2837          * scalar test, must print IS [NOT] DISTINCT FROM NULL to be semantically
2838          * correct.
2839          */
2840         if (node->argisrow || !type_is_rowtype(exprType((Node *) node->arg)))
2841         {
2842                 if (node->nulltesttype == IS_NULL)
2843                         appendStringInfoString(buf, " IS NULL)");
2844                 else
2845                         appendStringInfoString(buf, " IS NOT NULL)");
2846         }
2847         else
2848         {
2849                 if (node->nulltesttype == IS_NULL)
2850                         appendStringInfoString(buf, " IS NOT DISTINCT FROM NULL)");
2851                 else
2852                         appendStringInfoString(buf, " IS DISTINCT FROM NULL)");
2853         }
2854 }
2855
2856 /*
2857  * Deparse ARRAY[...] construct.
2858  */
2859 static void
2860 deparseArrayExpr(ArrayExpr *node, deparse_expr_cxt *context)
2861 {
2862         StringInfo      buf = context->buf;
2863         bool            first = true;
2864         ListCell   *lc;
2865
2866         appendStringInfoString(buf, "ARRAY[");
2867         foreach(lc, node->elements)
2868         {
2869                 if (!first)
2870                         appendStringInfoString(buf, ", ");
2871                 deparseExpr(lfirst(lc), context);
2872                 first = false;
2873         }
2874         appendStringInfoChar(buf, ']');
2875
2876         /* If the array is empty, we need an explicit cast to the array type. */
2877         if (node->elements == NIL)
2878                 appendStringInfo(buf, "::%s",
2879                                                  deparse_type_name(node->array_typeid, -1));
2880 }
2881
2882 /*
2883  * Deparse an Aggref node.
2884  */
2885 static void
2886 deparseAggref(Aggref *node, deparse_expr_cxt *context)
2887 {
2888         StringInfo      buf = context->buf;
2889         bool            use_variadic;
2890
2891         /* Only basic, non-split aggregation accepted. */
2892         Assert(node->aggsplit == AGGSPLIT_SIMPLE);
2893
2894         /* Check if need to print VARIADIC (cf. ruleutils.c) */
2895         use_variadic = node->aggvariadic;
2896
2897         /* Find aggregate name from aggfnoid which is a pg_proc entry */
2898         appendFunctionName(node->aggfnoid, context);
2899         appendStringInfoChar(buf, '(');
2900
2901         /* Add DISTINCT */
2902         appendStringInfoString(buf, (node->aggdistinct != NIL) ? "DISTINCT " : "");
2903
2904         if (AGGKIND_IS_ORDERED_SET(node->aggkind))
2905         {
2906                 /* Add WITHIN GROUP (ORDER BY ..) */
2907                 ListCell   *arg;
2908                 bool            first = true;
2909
2910                 Assert(!node->aggvariadic);
2911                 Assert(node->aggorder != NIL);
2912
2913                 foreach(arg, node->aggdirectargs)
2914                 {
2915                         if (!first)
2916                                 appendStringInfoString(buf, ", ");
2917                         first = false;
2918
2919                         deparseExpr((Expr *) lfirst(arg), context);
2920                 }
2921
2922                 appendStringInfoString(buf, ") WITHIN GROUP (ORDER BY ");
2923                 appendAggOrderBy(node->aggorder, node->args, context);
2924         }
2925         else
2926         {
2927                 /* aggstar can be set only in zero-argument aggregates */
2928                 if (node->aggstar)
2929                         appendStringInfoChar(buf, '*');
2930                 else
2931                 {
2932                         ListCell   *arg;
2933                         bool            first = true;
2934
2935                         /* Add all the arguments */
2936                         foreach(arg, node->args)
2937                         {
2938                                 TargetEntry *tle = (TargetEntry *) lfirst(arg);
2939                                 Node       *n = (Node *) tle->expr;
2940
2941                                 if (tle->resjunk)
2942                                         continue;
2943
2944                                 if (!first)
2945                                         appendStringInfoString(buf, ", ");
2946                                 first = false;
2947
2948                                 /* Add VARIADIC */
2949                                 if (use_variadic && lnext(arg) == NULL)
2950                                         appendStringInfoString(buf, "VARIADIC ");
2951
2952                                 deparseExpr((Expr *) n, context);
2953                         }
2954                 }
2955
2956                 /* Add ORDER BY */
2957                 if (node->aggorder != NIL)
2958                 {
2959                         appendStringInfoString(buf, " ORDER BY ");
2960                         appendAggOrderBy(node->aggorder, node->args, context);
2961                 }
2962         }
2963
2964         /* Add FILTER (WHERE ..) */
2965         if (node->aggfilter != NULL)
2966         {
2967                 appendStringInfoString(buf, ") FILTER (WHERE ");
2968                 deparseExpr((Expr *) node->aggfilter, context);
2969         }
2970
2971         appendStringInfoChar(buf, ')');
2972 }
2973
2974 /*
2975  * Append ORDER BY within aggregate function.
2976  */
2977 static void
2978 appendAggOrderBy(List *orderList, List *targetList, deparse_expr_cxt *context)
2979 {
2980         StringInfo      buf = context->buf;
2981         ListCell   *lc;
2982         bool            first = true;
2983
2984         foreach(lc, orderList)
2985         {
2986                 SortGroupClause *srt = (SortGroupClause *) lfirst(lc);
2987                 Node       *sortexpr;
2988                 Oid                     sortcoltype;
2989                 TypeCacheEntry *typentry;
2990
2991                 if (!first)
2992                         appendStringInfoString(buf, ", ");
2993                 first = false;
2994
2995                 sortexpr = deparseSortGroupClause(srt->tleSortGroupRef, targetList,
2996                                                                                   false, context);
2997                 sortcoltype = exprType(sortexpr);
2998                 /* See whether operator is default < or > for datatype */
2999                 typentry = lookup_type_cache(sortcoltype,
3000                                                                          TYPECACHE_LT_OPR | TYPECACHE_GT_OPR);
3001                 if (srt->sortop == typentry->lt_opr)
3002                         appendStringInfoString(buf, " ASC");
3003                 else if (srt->sortop == typentry->gt_opr)
3004                         appendStringInfoString(buf, " DESC");
3005                 else
3006                 {
3007                         HeapTuple       opertup;
3008                         Form_pg_operator operform;
3009
3010                         appendStringInfoString(buf, " USING ");
3011
3012                         /* Append operator name. */
3013                         opertup = SearchSysCache1(OPEROID, ObjectIdGetDatum(srt->sortop));
3014                         if (!HeapTupleIsValid(opertup))
3015                                 elog(ERROR, "cache lookup failed for operator %u", srt->sortop);
3016                         operform = (Form_pg_operator) GETSTRUCT(opertup);
3017                         deparseOperatorName(buf, operform);
3018                         ReleaseSysCache(opertup);
3019                 }
3020
3021                 if (srt->nulls_first)
3022                         appendStringInfoString(buf, " NULLS FIRST");
3023                 else
3024                         appendStringInfoString(buf, " NULLS LAST");
3025         }
3026 }
3027
3028 /*
3029  * Print the representation of a parameter to be sent to the remote side.
3030  *
3031  * Note: we always label the Param's type explicitly rather than relying on
3032  * transmitting a numeric type OID in PQexecParams().  This allows us to
3033  * avoid assuming that types have the same OIDs on the remote side as they
3034  * do locally --- they need only have the same names.
3035  */
3036 static void
3037 printRemoteParam(int paramindex, Oid paramtype, int32 paramtypmod,
3038                                  deparse_expr_cxt *context)
3039 {
3040         StringInfo      buf = context->buf;
3041         char       *ptypename = deparse_type_name(paramtype, paramtypmod);
3042
3043         appendStringInfo(buf, "$%d::%s", paramindex, ptypename);
3044 }
3045
3046 /*
3047  * Print the representation of a placeholder for a parameter that will be
3048  * sent to the remote side at execution time.
3049  *
3050  * This is used when we're just trying to EXPLAIN the remote query.
3051  * We don't have the actual value of the runtime parameter yet, and we don't
3052  * want the remote planner to generate a plan that depends on such a value
3053  * anyway.  Thus, we can't do something simple like "$1::paramtype".
3054  * Instead, we emit "((SELECT null::paramtype)::paramtype)".
3055  * In all extant versions of Postgres, the planner will see that as an unknown
3056  * constant value, which is what we want.  This might need adjustment if we
3057  * ever make the planner flatten scalar subqueries.  Note: the reason for the
3058  * apparently useless outer cast is to ensure that the representation as a
3059  * whole will be parsed as an a_expr and not a select_with_parens; the latter
3060  * would do the wrong thing in the context "x = ANY(...)".
3061  */
3062 static void
3063 printRemotePlaceholder(Oid paramtype, int32 paramtypmod,
3064                                            deparse_expr_cxt *context)
3065 {
3066         StringInfo      buf = context->buf;
3067         char       *ptypename = deparse_type_name(paramtype, paramtypmod);
3068
3069         appendStringInfo(buf, "((SELECT null::%s)::%s)", ptypename, ptypename);
3070 }
3071
3072 /*
3073  * Deparse GROUP BY clause.
3074  */
3075 static void
3076 appendGroupByClause(List *tlist, deparse_expr_cxt *context)
3077 {
3078         StringInfo      buf = context->buf;
3079         Query      *query = context->root->parse;
3080         ListCell   *lc;
3081         bool            first = true;
3082
3083         /* Nothing to be done, if there's no GROUP BY clause in the query. */
3084         if (!query->groupClause)
3085                 return;
3086
3087         appendStringInfoString(buf, " GROUP BY ");
3088
3089         /*
3090          * Queries with grouping sets are not pushed down, so we don't expect
3091          * grouping sets here.
3092          */
3093         Assert(!query->groupingSets);
3094
3095         foreach(lc, query->groupClause)
3096         {
3097                 SortGroupClause *grp = (SortGroupClause *) lfirst(lc);
3098
3099                 if (!first)
3100                         appendStringInfoString(buf, ", ");
3101                 first = false;
3102
3103                 deparseSortGroupClause(grp->tleSortGroupRef, tlist, true, context);
3104         }
3105 }
3106
3107 /*
3108  * Deparse ORDER BY clause according to the given pathkeys for given base
3109  * relation. From given pathkeys expressions belonging entirely to the given
3110  * base relation are obtained and deparsed.
3111  */
3112 static void
3113 appendOrderByClause(List *pathkeys, deparse_expr_cxt *context)
3114 {
3115         ListCell   *lcell;
3116         int                     nestlevel;
3117         char       *delim = " ";
3118         RelOptInfo *baserel = context->scanrel;
3119         StringInfo      buf = context->buf;
3120
3121         /* Make sure any constants in the exprs are printed portably */
3122         nestlevel = set_transmission_modes();
3123
3124         appendStringInfoString(buf, " ORDER BY");
3125         foreach(lcell, pathkeys)
3126         {
3127                 PathKey    *pathkey = lfirst(lcell);
3128                 Expr       *em_expr;
3129
3130                 em_expr = find_em_expr_for_rel(pathkey->pk_eclass, baserel);
3131                 Assert(em_expr != NULL);
3132
3133                 appendStringInfoString(buf, delim);
3134                 deparseExpr(em_expr, context);
3135                 if (pathkey->pk_strategy == BTLessStrategyNumber)
3136                         appendStringInfoString(buf, " ASC");
3137                 else
3138                         appendStringInfoString(buf, " DESC");
3139
3140                 if (pathkey->pk_nulls_first)
3141                         appendStringInfoString(buf, " NULLS FIRST");
3142                 else
3143                         appendStringInfoString(buf, " NULLS LAST");
3144
3145                 delim = ", ";
3146         }
3147         reset_transmission_modes(nestlevel);
3148 }
3149
3150 /*
3151  * appendFunctionName
3152  *              Deparses function name from given function oid.
3153  */
3154 static void
3155 appendFunctionName(Oid funcid, deparse_expr_cxt *context)
3156 {
3157         StringInfo      buf = context->buf;
3158         HeapTuple       proctup;
3159         Form_pg_proc procform;
3160         const char *proname;
3161
3162         proctup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
3163         if (!HeapTupleIsValid(proctup))
3164                 elog(ERROR, "cache lookup failed for function %u", funcid);
3165         procform = (Form_pg_proc) GETSTRUCT(proctup);
3166
3167         /* Print schema name only if it's not pg_catalog */
3168         if (procform->pronamespace != PG_CATALOG_NAMESPACE)
3169         {
3170                 const char *schemaname;
3171
3172                 schemaname = get_namespace_name(procform->pronamespace);
3173                 appendStringInfo(buf, "%s.", quote_identifier(schemaname));
3174         }
3175
3176         /* Always print the function name */
3177         proname = NameStr(procform->proname);
3178         appendStringInfoString(buf, quote_identifier(proname));
3179
3180         ReleaseSysCache(proctup);
3181 }
3182
3183 /*
3184  * Appends a sort or group clause.
3185  *
3186  * Like get_rule_sortgroupclause(), returns the expression tree, so caller
3187  * need not find it again.
3188  */
3189 static Node *
3190 deparseSortGroupClause(Index ref, List *tlist, bool force_colno,
3191                                            deparse_expr_cxt *context)
3192 {
3193         StringInfo      buf = context->buf;
3194         TargetEntry *tle;
3195         Expr       *expr;
3196
3197         tle = get_sortgroupref_tle(ref, tlist);
3198         expr = tle->expr;
3199
3200         if (force_colno)
3201         {
3202                 /* Use column-number form when requested by caller. */
3203                 Assert(!tle->resjunk);
3204                 appendStringInfo(buf, "%d", tle->resno);
3205         }
3206         else if (expr && IsA(expr, Const))
3207         {
3208                 /*
3209                  * Force a typecast here so that we don't emit something like "GROUP
3210                  * BY 2", which will be misconstrued as a column position rather than
3211                  * a constant.
3212                  */
3213                 deparseConst((Const *) expr, context, 1);
3214         }
3215         else if (!expr || IsA(expr, Var))
3216                 deparseExpr(expr, context);
3217         else
3218         {
3219                 /* Always parenthesize the expression. */
3220                 appendStringInfoChar(buf, '(');
3221                 deparseExpr(expr, context);
3222                 appendStringInfoChar(buf, ')');
3223         }
3224
3225         return (Node *) expr;
3226 }
3227
3228
3229 /*
3230  * Returns true if given Var is deparsed as a subquery output column, in
3231  * which case, *relno and *colno are set to the IDs for the relation and
3232  * column alias to the Var provided by the subquery.
3233  */
3234 static bool
3235 is_subquery_var(Var *node, RelOptInfo *foreignrel, int *relno, int *colno)
3236 {
3237         PgFdwRelationInfo *fpinfo = (PgFdwRelationInfo *) foreignrel->fdw_private;
3238         RelOptInfo *outerrel = fpinfo->outerrel;
3239         RelOptInfo *innerrel = fpinfo->innerrel;
3240
3241         /* Should only be called in these cases. */
3242         Assert(IS_SIMPLE_REL(foreignrel) || IS_JOIN_REL(foreignrel));
3243
3244         /*
3245          * If the given relation isn't a join relation, it doesn't have any lower
3246          * subqueries, so the Var isn't a subquery output column.
3247          */
3248         if (!IS_JOIN_REL(foreignrel))
3249                 return false;
3250
3251         /*
3252          * If the Var doesn't belong to any lower subqueries, it isn't a subquery
3253          * output column.
3254          */
3255         if (!bms_is_member(node->varno, fpinfo->lower_subquery_rels))
3256                 return false;
3257
3258         if (bms_is_member(node->varno, outerrel->relids))
3259         {
3260                 /*
3261                  * If outer relation is deparsed as a subquery, the Var is an output
3262                  * column of the subquery; get the IDs for the relation/column alias.
3263                  */
3264                 if (fpinfo->make_outerrel_subquery)
3265                 {
3266                         get_relation_column_alias_ids(node, outerrel, relno, colno);
3267                         return true;
3268                 }
3269
3270                 /* Otherwise, recurse into the outer relation. */
3271                 return is_subquery_var(node, outerrel, relno, colno);
3272         }
3273         else
3274         {
3275                 Assert(bms_is_member(node->varno, innerrel->relids));
3276
3277                 /*
3278                  * If inner relation is deparsed as a subquery, the Var is an output
3279                  * column of the subquery; get the IDs for the relation/column alias.
3280                  */
3281                 if (fpinfo->make_innerrel_subquery)
3282                 {
3283                         get_relation_column_alias_ids(node, innerrel, relno, colno);
3284                         return true;
3285                 }
3286
3287                 /* Otherwise, recurse into the inner relation. */
3288                 return is_subquery_var(node, innerrel, relno, colno);
3289         }
3290 }
3291
3292 /*
3293  * Get the IDs for the relation and column alias to given Var belonging to
3294  * given relation, which are returned into *relno and *colno.
3295  */
3296 static void
3297 get_relation_column_alias_ids(Var *node, RelOptInfo *foreignrel,
3298                                                           int *relno, int *colno)
3299 {
3300         PgFdwRelationInfo *fpinfo = (PgFdwRelationInfo *) foreignrel->fdw_private;
3301         int                     i;
3302         ListCell   *lc;
3303
3304         /* Get the relation alias ID */
3305         *relno = fpinfo->relation_index;
3306
3307         /* Get the column alias ID */
3308         i = 1;
3309         foreach(lc, foreignrel->reltarget->exprs)
3310         {
3311                 if (equal(lfirst(lc), (Node *) node))
3312                 {
3313                         *colno = i;
3314                         return;
3315                 }
3316                 i++;
3317         }
3318
3319         /* Shouldn't get here */
3320         elog(ERROR, "unexpected expression in subquery output");
3321 }