You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

deparse.c 91KB

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