PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
ruleutils.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * ruleutils.c
4  * Functions to convert stored expressions/querytrees back to
5  * source text
6  *
7  * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
8  * Portions Copyright (c) 1994, Regents of the University of California
9  *
10  *
11  * IDENTIFICATION
12  * src/backend/utils/adt/ruleutils.c
13  *
14  *-------------------------------------------------------------------------
15  */
16 #include "postgres.h"
17 
18 #include <ctype.h>
19 #include <unistd.h>
20 #include <fcntl.h>
21 
22 #include "access/amapi.h"
23 #include "access/htup_details.h"
24 #include "access/sysattr.h"
25 #include "catalog/dependency.h"
26 #include "catalog/indexing.h"
27 #include "catalog/pg_aggregate.h"
28 #include "catalog/pg_am.h"
29 #include "catalog/pg_authid.h"
30 #include "catalog/pg_collation.h"
31 #include "catalog/pg_constraint.h"
32 #include "catalog/pg_depend.h"
33 #include "catalog/pg_language.h"
34 #include "catalog/pg_opclass.h"
35 #include "catalog/pg_operator.h"
37 #include "catalog/pg_proc.h"
39 #include "catalog/pg_trigger.h"
40 #include "catalog/pg_type.h"
41 #include "commands/defrem.h"
42 #include "commands/tablespace.h"
43 #include "common/keywords.h"
44 #include "executor/spi.h"
45 #include "funcapi.h"
46 #include "mb/pg_wchar.h"
47 #include "miscadmin.h"
48 #include "nodes/makefuncs.h"
49 #include "nodes/nodeFuncs.h"
50 #include "optimizer/tlist.h"
51 #include "parser/parse_node.h"
52 #include "parser/parse_agg.h"
53 #include "parser/parse_func.h"
54 #include "parser/parse_oper.h"
55 #include "parser/parser.h"
56 #include "parser/parsetree.h"
57 #include "rewrite/rewriteHandler.h"
58 #include "rewrite/rewriteManip.h"
59 #include "rewrite/rewriteSupport.h"
60 #include "utils/array.h"
61 #include "utils/builtins.h"
62 #include "utils/fmgroids.h"
63 #include "utils/hsearch.h"
64 #include "utils/lsyscache.h"
65 #include "utils/rel.h"
66 #include "utils/ruleutils.h"
67 #include "utils/snapmgr.h"
68 #include "utils/syscache.h"
69 #include "utils/tqual.h"
70 #include "utils/typcache.h"
71 #include "utils/varlena.h"
72 #include "utils/xml.h"
73 
74 
75 /* ----------
76  * Pretty formatting constants
77  * ----------
78  */
79 
80 /* Indent counts */
81 #define PRETTYINDENT_STD 8
82 #define PRETTYINDENT_JOIN 4
83 #define PRETTYINDENT_VAR 4
84 
85 #define PRETTYINDENT_LIMIT 40 /* wrap limit */
86 
87 /* Pretty flags */
88 #define PRETTYFLAG_PAREN 1
89 #define PRETTYFLAG_INDENT 2
90 
91 /* Default line length for pretty-print wrapping: 0 means wrap always */
92 #define WRAP_COLUMN_DEFAULT 0
93 
94 /* macro to test if pretty action needed */
95 #define PRETTY_PAREN(context) ((context)->prettyFlags & PRETTYFLAG_PAREN)
96 #define PRETTY_INDENT(context) ((context)->prettyFlags & PRETTYFLAG_INDENT)
97 
98 
99 /* ----------
100  * Local data types
101  * ----------
102  */
103 
104 /* Context info needed for invoking a recursive querytree display routine */
105 typedef struct
106 {
107  StringInfo buf; /* output buffer to append to */
108  List *namespaces; /* List of deparse_namespace nodes */
109  List *windowClause; /* Current query level's WINDOW clause */
110  List *windowTList; /* targetlist for resolving WINDOW clause */
111  int prettyFlags; /* enabling of pretty-print functions */
112  int wrapColumn; /* max line length, or -1 for no limit */
113  int indentLevel; /* current indent level for prettyprint */
114  bool varprefix; /* TRUE to print prefixes on Vars */
115  ParseExprKind special_exprkind; /* set only for exprkinds needing
116  * special handling */
118 
119 /*
120  * Each level of query context around a subtree needs a level of Var namespace.
121  * A Var having varlevelsup=N refers to the N'th item (counting from 0) in
122  * the current context's namespaces list.
123  *
124  * The rangetable is the list of actual RTEs from the query tree, and the
125  * cte list is the list of actual CTEs.
126  *
127  * rtable_names holds the alias name to be used for each RTE (either a C
128  * string, or NULL for nameless RTEs such as unnamed joins).
129  * rtable_columns holds the column alias names to be used for each RTE.
130  *
131  * In some cases we need to make names of merged JOIN USING columns unique
132  * across the whole query, not only per-RTE. If so, unique_using is TRUE
133  * and using_names is a list of C strings representing names already assigned
134  * to USING columns.
135  *
136  * When deparsing plan trees, there is always just a single item in the
137  * deparse_namespace list (since a plan tree never contains Vars with
138  * varlevelsup > 0). We store the PlanState node that is the immediate
139  * parent of the expression to be deparsed, as well as a list of that
140  * PlanState's ancestors. In addition, we store its outer and inner subplan
141  * state nodes, as well as their plan nodes' targetlists, and the index tlist
142  * if the current plan node might contain INDEX_VAR Vars. (These fields could
143  * be derived on-the-fly from the current PlanState, but it seems notationally
144  * clearer to set them up as separate fields.)
145  */
146 typedef struct
147 {
148  List *rtable; /* List of RangeTblEntry nodes */
149  List *rtable_names; /* Parallel list of names for RTEs */
150  List *rtable_columns; /* Parallel list of deparse_columns structs */
151  List *ctes; /* List of CommonTableExpr nodes */
152  /* Workspace for column alias assignment: */
153  bool unique_using; /* Are we making USING names globally unique */
154  List *using_names; /* List of assigned names for USING columns */
155  /* Remaining fields are used only when deparsing a Plan tree: */
156  PlanState *planstate; /* immediate parent of current expression */
157  List *ancestors; /* ancestors of planstate */
158  PlanState *outer_planstate; /* outer subplan state, or NULL if none */
159  PlanState *inner_planstate; /* inner subplan state, or NULL if none */
160  List *outer_tlist; /* referent for OUTER_VAR Vars */
161  List *inner_tlist; /* referent for INNER_VAR Vars */
162  List *index_tlist; /* referent for INDEX_VAR Vars */
164 
165 /*
166  * Per-relation data about column alias names.
167  *
168  * Selecting aliases is unreasonably complicated because of the need to dump
169  * rules/views whose underlying tables may have had columns added, deleted, or
170  * renamed since the query was parsed. We must nonetheless print the rule/view
171  * in a form that can be reloaded and will produce the same results as before.
172  *
173  * For each RTE used in the query, we must assign column aliases that are
174  * unique within that RTE. SQL does not require this of the original query,
175  * but due to factors such as *-expansion we need to be able to uniquely
176  * reference every column in a decompiled query. As long as we qualify all
177  * column references, per-RTE uniqueness is sufficient for that.
178  *
179  * However, we can't ensure per-column name uniqueness for unnamed join RTEs,
180  * since they just inherit column names from their input RTEs, and we can't
181  * rename the columns at the join level. Most of the time this isn't an issue
182  * because we don't need to reference the join's output columns as such; we
183  * can reference the input columns instead. That approach can fail for merged
184  * JOIN USING columns, however, so when we have one of those in an unnamed
185  * join, we have to make that column's alias globally unique across the whole
186  * query to ensure it can be referenced unambiguously.
187  *
188  * Another problem is that a JOIN USING clause requires the columns to be
189  * merged to have the same aliases in both input RTEs, and that no other
190  * columns in those RTEs or their children conflict with the USING names.
191  * To handle that, we do USING-column alias assignment in a recursive
192  * traversal of the query's jointree. When descending through a JOIN with
193  * USING, we preassign the USING column names to the child columns, overriding
194  * other rules for column alias assignment. We also mark each RTE with a list
195  * of all USING column names selected for joins containing that RTE, so that
196  * when we assign other columns' aliases later, we can avoid conflicts.
197  *
198  * Another problem is that if a JOIN's input tables have had columns added or
199  * deleted since the query was parsed, we must generate a column alias list
200  * for the join that matches the current set of input columns --- otherwise, a
201  * change in the number of columns in the left input would throw off matching
202  * of aliases to columns of the right input. Thus, positions in the printable
203  * column alias list are not necessarily one-for-one with varattnos of the
204  * JOIN, so we need a separate new_colnames[] array for printing purposes.
205  */
206 typedef struct
207 {
208  /*
209  * colnames is an array containing column aliases to use for columns that
210  * existed when the query was parsed. Dropped columns have NULL entries.
211  * This array can be directly indexed by varattno to get a Var's name.
212  *
213  * Non-NULL entries are guaranteed unique within the RTE, *except* when
214  * this is for an unnamed JOIN RTE. In that case we merely copy up names
215  * from the two input RTEs.
216  *
217  * During the recursive descent in set_using_names(), forcible assignment
218  * of a child RTE's column name is represented by pre-setting that element
219  * of the child's colnames array. So at that stage, NULL entries in this
220  * array just mean that no name has been preassigned, not necessarily that
221  * the column is dropped.
222  */
223  int num_cols; /* length of colnames[] array */
224  char **colnames; /* array of C strings and NULLs */
225 
226  /*
227  * new_colnames is an array containing column aliases to use for columns
228  * that would exist if the query was re-parsed against the current
229  * definitions of its base tables. This is what to print as the column
230  * alias list for the RTE. This array does not include dropped columns,
231  * but it will include columns added since original parsing. Indexes in
232  * it therefore have little to do with current varattno values. As above,
233  * entries are unique unless this is for an unnamed JOIN RTE. (In such an
234  * RTE, we never actually print this array, but we must compute it anyway
235  * for possible use in computing column names of upper joins.) The
236  * parallel array is_new_col marks which of these columns are new since
237  * original parsing. Entries with is_new_col false must match the
238  * non-NULL colnames entries one-for-one.
239  */
240  int num_new_cols; /* length of new_colnames[] array */
241  char **new_colnames; /* array of C strings */
242  bool *is_new_col; /* array of bool flags */
243 
244  /* This flag tells whether we should actually print a column alias list */
246 
247  /* This list has all names used as USING names in joins above this RTE */
248  List *parentUsing; /* names assigned to parent merged columns */
249 
250  /*
251  * If this struct is for a JOIN RTE, we fill these fields during the
252  * set_using_names() pass to describe its relationship to its child RTEs.
253  *
254  * leftattnos and rightattnos are arrays with one entry per existing
255  * output column of the join (hence, indexable by join varattno). For a
256  * simple reference to a column of the left child, leftattnos[i] is the
257  * child RTE's attno and rightattnos[i] is zero; and conversely for a
258  * column of the right child. But for merged columns produced by JOIN
259  * USING/NATURAL JOIN, both leftattnos[i] and rightattnos[i] are nonzero.
260  * Also, if the column has been dropped, both are zero.
261  *
262  * If it's a JOIN USING, usingNames holds the alias names selected for the
263  * merged columns (these might be different from the original USING list,
264  * if we had to modify names to achieve uniqueness).
265  */
266  int leftrti; /* rangetable index of left child */
267  int rightrti; /* rangetable index of right child */
268  int *leftattnos; /* left-child varattnos of join cols, or 0 */
269  int *rightattnos; /* right-child varattnos of join cols, or 0 */
270  List *usingNames; /* names assigned to merged columns */
272 
273 /* This macro is analogous to rt_fetch(), but for deparse_columns structs */
274 #define deparse_columns_fetch(rangetable_index, dpns) \
275  ((deparse_columns *) list_nth((dpns)->rtable_columns, (rangetable_index)-1))
276 
277 /*
278  * Entry in set_rtable_names' hash table
279  */
280 typedef struct
281 {
282  char name[NAMEDATALEN]; /* Hash key --- must be first */
283  int counter; /* Largest addition used so far for name */
284 } NameHashEntry;
285 
286 
287 /* ----------
288  * Global data
289  * ----------
290  */
292 static const char *query_getrulebyoid = "SELECT * FROM pg_catalog.pg_rewrite WHERE oid = $1";
294 static const char *query_getviewrule = "SELECT * FROM pg_catalog.pg_rewrite WHERE ev_class = $1 AND rulename = $2";
295 
296 /* GUC parameters */
298 
299 
300 /* ----------
301  * Local functions
302  *
303  * Most of these functions used to use fixed-size buffers to build their
304  * results. Now, they take an (already initialized) StringInfo object
305  * as a parameter, and append their text output to its contents.
306  * ----------
307  */
308 static char *deparse_expression_pretty(Node *expr, List *dpcontext,
309  bool forceprefix, bool showimplicit,
310  int prettyFlags, int startIndent);
311 static char *pg_get_viewdef_worker(Oid viewoid,
312  int prettyFlags, int wrapColumn);
313 static char *pg_get_triggerdef_worker(Oid trigid, bool pretty);
314 static void decompile_column_index_array(Datum column_index_array, Oid relId,
315  StringInfo buf);
316 static char *pg_get_ruledef_worker(Oid ruleoid, int prettyFlags);
317 static char *pg_get_indexdef_worker(Oid indexrelid, int colno,
318  const Oid *excludeOps,
319  bool attrsOnly, bool showTblSpc,
320  int prettyFlags, bool missing_ok);
321 static char *pg_get_statisticsext_worker(Oid statextid, bool missing_ok);
322 static char *pg_get_partkeydef_worker(Oid relid, int prettyFlags,
323  bool attrsOnly);
324 static char *pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
325  int prettyFlags, bool missing_ok);
326 static text *pg_get_expr_worker(text *expr, Oid relid, const char *relname,
327  int prettyFlags);
329  bool print_table_args, bool print_defaults);
330 static void print_function_rettype(StringInfo buf, HeapTuple proctup);
331 static void print_function_trftypes(StringInfo buf, HeapTuple proctup);
332 static void set_rtable_names(deparse_namespace *dpns, List *parent_namespaces,
333  Bitmapset *rels_used);
334 static void set_deparse_for_query(deparse_namespace *dpns, Query *query,
335  List *parent_namespaces);
336 static void set_simple_column_names(deparse_namespace *dpns);
337 static bool has_dangerous_join_using(deparse_namespace *dpns, Node *jtnode);
338 static void set_using_names(deparse_namespace *dpns, Node *jtnode,
339  List *parentUsing);
341  RangeTblEntry *rte,
342  deparse_columns *colinfo);
344  deparse_columns *colinfo);
345 static bool colname_is_unique(char *colname, deparse_namespace *dpns,
346  deparse_columns *colinfo);
347 static char *make_colname_unique(char *colname, deparse_namespace *dpns,
348  deparse_columns *colinfo);
349 static void expand_colnames_array_to(deparse_columns *colinfo, int n);
350 static void identify_join_columns(JoinExpr *j, RangeTblEntry *jrte,
351  deparse_columns *colinfo);
352 static void flatten_join_using_qual(Node *qual,
353  List **leftvars, List **rightvars);
354 static char *get_rtable_name(int rtindex, deparse_context *context);
355 static void set_deparse_planstate(deparse_namespace *dpns, PlanState *ps);
356 static void push_child_plan(deparse_namespace *dpns, PlanState *ps,
357  deparse_namespace *save_dpns);
358 static void pop_child_plan(deparse_namespace *dpns,
359  deparse_namespace *save_dpns);
360 static void push_ancestor_plan(deparse_namespace *dpns, ListCell *ancestor_cell,
361  deparse_namespace *save_dpns);
362 static void pop_ancestor_plan(deparse_namespace *dpns,
363  deparse_namespace *save_dpns);
364 static void make_ruledef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc,
365  int prettyFlags);
366 static void make_viewdef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc,
367  int prettyFlags, int wrapColumn);
368 static void get_query_def(Query *query, StringInfo buf, List *parentnamespace,
369  TupleDesc resultDesc,
370  int prettyFlags, int wrapColumn, int startIndent);
371 static void get_values_def(List *values_lists, deparse_context *context);
372 static void get_with_clause(Query *query, deparse_context *context);
373 static void get_select_query_def(Query *query, deparse_context *context,
374  TupleDesc resultDesc);
375 static void get_insert_query_def(Query *query, deparse_context *context);
376 static void get_update_query_def(Query *query, deparse_context *context);
377 static void get_update_query_targetlist_def(Query *query, List *targetList,
378  deparse_context *context,
379  RangeTblEntry *rte);
380 static void get_delete_query_def(Query *query, deparse_context *context);
381 static void get_utility_query_def(Query *query, deparse_context *context);
382 static void get_basic_select_query(Query *query, deparse_context *context,
383  TupleDesc resultDesc);
384 static void get_target_list(List *targetList, deparse_context *context,
385  TupleDesc resultDesc);
386 static void get_setop_query(Node *setOp, Query *query,
387  deparse_context *context,
388  TupleDesc resultDesc);
389 static Node *get_rule_sortgroupclause(Index ref, List *tlist,
390  bool force_colno,
391  deparse_context *context);
392 static void get_rule_groupingset(GroupingSet *gset, List *targetlist,
393  bool omit_parens, deparse_context *context);
394 static void get_rule_orderby(List *orderList, List *targetList,
395  bool force_colno, deparse_context *context);
396 static void get_rule_windowclause(Query *query, deparse_context *context);
397 static void get_rule_windowspec(WindowClause *wc, List *targetList,
398  deparse_context *context);
399 static char *get_variable(Var *var, int levelsup, bool istoplevel,
400  deparse_context *context);
401 static void get_special_variable(Node *node, deparse_context *context,
402  void *private);
403 static void resolve_special_varno(Node *node, deparse_context *context,
404  void *private,
405  void (*callback) (Node *, deparse_context *, void *));
406 static Node *find_param_referent(Param *param, deparse_context *context,
407  deparse_namespace **dpns_p, ListCell **ancestor_cell_p);
408 static void get_parameter(Param *param, deparse_context *context);
409 static const char *get_simple_binary_op_name(OpExpr *expr);
410 static bool isSimpleNode(Node *node, Node *parentNode, int prettyFlags);
411 static void appendContextKeyword(deparse_context *context, const char *str,
412  int indentBefore, int indentAfter, int indentPlus);
413 static void removeStringInfoSpaces(StringInfo str);
414 static void get_rule_expr(Node *node, deparse_context *context,
415  bool showimplicit);
416 static void get_rule_expr_toplevel(Node *node, deparse_context *context,
417  bool showimplicit);
418 static void get_oper_expr(OpExpr *expr, deparse_context *context);
419 static void get_func_expr(FuncExpr *expr, deparse_context *context,
420  bool showimplicit);
421 static void get_agg_expr(Aggref *aggref, deparse_context *context,
422  Aggref *original_aggref);
423 static void get_agg_combine_expr(Node *node, deparse_context *context,
424  void *private);
425 static void get_windowfunc_expr(WindowFunc *wfunc, deparse_context *context);
426 static void get_coercion_expr(Node *arg, deparse_context *context,
427  Oid resulttype, int32 resulttypmod,
428  Node *parentNode);
429 static void get_const_expr(Const *constval, deparse_context *context,
430  int showtype);
431 static void get_const_collation(Const *constval, deparse_context *context);
432 static void simple_quote_literal(StringInfo buf, const char *val);
433 static void get_sublink_expr(SubLink *sublink, deparse_context *context);
434 static void get_tablefunc(TableFunc *tf, deparse_context *context,
435  bool showimplicit);
436 static void get_from_clause(Query *query, const char *prefix,
437  deparse_context *context);
438 static void get_from_clause_item(Node *jtnode, Query *query,
439  deparse_context *context);
440 static void get_column_alias_list(deparse_columns *colinfo,
441  deparse_context *context);
442 static void get_from_clause_coldeflist(RangeTblFunction *rtfunc,
443  deparse_columns *colinfo,
444  deparse_context *context);
445 static void get_tablesample_def(TableSampleClause *tablesample,
446  deparse_context *context);
447 static void get_opclass_name(Oid opclass, Oid actual_datatype,
448  StringInfo buf);
449 static Node *processIndirection(Node *node, deparse_context *context);
450 static void printSubscripts(ArrayRef *aref, deparse_context *context);
451 static char *get_relation_name(Oid relid);
452 static char *generate_relation_name(Oid relid, List *namespaces);
453 static char *generate_qualified_relation_name(Oid relid);
454 static char *generate_function_name(Oid funcid, int nargs,
455  List *argnames, Oid *argtypes,
456  bool has_variadic, bool *use_variadic_p,
457  ParseExprKind special_exprkind);
458 static char *generate_operator_name(Oid operid, Oid arg1, Oid arg2);
459 static text *string_to_text(char *str);
460 static char *flatten_reloptions(Oid relid);
461 
462 #define only_marker(rte) ((rte)->inh ? "" : "ONLY ")
463 
464 
465 /* ----------
466  * get_ruledef - Do it all and return a text
467  * that could be used as a statement
468  * to recreate the rule
469  * ----------
470  */
471 Datum
473 {
474  Oid ruleoid = PG_GETARG_OID(0);
475  int prettyFlags;
476  char *res;
477 
478  prettyFlags = PRETTYFLAG_INDENT;
479 
480  res = pg_get_ruledef_worker(ruleoid, prettyFlags);
481 
482  if (res == NULL)
483  PG_RETURN_NULL();
484 
486 }
487 
488 
489 Datum
491 {
492  Oid ruleoid = PG_GETARG_OID(0);
493  bool pretty = PG_GETARG_BOOL(1);
494  int prettyFlags;
495  char *res;
496 
497  prettyFlags = pretty ? PRETTYFLAG_PAREN | PRETTYFLAG_INDENT : PRETTYFLAG_INDENT;
498 
499  res = pg_get_ruledef_worker(ruleoid, prettyFlags);
500 
501  if (res == NULL)
502  PG_RETURN_NULL();
503 
505 }
506 
507 
508 static char *
509 pg_get_ruledef_worker(Oid ruleoid, int prettyFlags)
510 {
511  Datum args[1];
512  char nulls[1];
513  int spirc;
514  HeapTuple ruletup;
515  TupleDesc rulettc;
517 
518  /*
519  * Do this first so that string is alloc'd in outer context not SPI's.
520  */
521  initStringInfo(&buf);
522 
523  /*
524  * Connect to SPI manager
525  */
526  if (SPI_connect() != SPI_OK_CONNECT)
527  elog(ERROR, "SPI_connect failed");
528 
529  /*
530  * On the first call prepare the plan to lookup pg_rewrite. We read
531  * pg_rewrite over the SPI manager instead of using the syscache to be
532  * checked for read access on pg_rewrite.
533  */
534  if (plan_getrulebyoid == NULL)
535  {
536  Oid argtypes[1];
537  SPIPlanPtr plan;
538 
539  argtypes[0] = OIDOID;
540  plan = SPI_prepare(query_getrulebyoid, 1, argtypes);
541  if (plan == NULL)
542  elog(ERROR, "SPI_prepare failed for \"%s\"", query_getrulebyoid);
543  SPI_keepplan(plan);
544  plan_getrulebyoid = plan;
545  }
546 
547  /*
548  * Get the pg_rewrite tuple for this rule
549  */
550  args[0] = ObjectIdGetDatum(ruleoid);
551  nulls[0] = ' ';
552  spirc = SPI_execute_plan(plan_getrulebyoid, args, nulls, true, 0);
553  if (spirc != SPI_OK_SELECT)
554  elog(ERROR, "failed to get pg_rewrite tuple for rule %u", ruleoid);
555  if (SPI_processed != 1)
556  {
557  /*
558  * There is no tuple data available here, just keep the output buffer
559  * empty.
560  */
561  }
562  else
563  {
564  /*
565  * Get the rule's definition and put it into executor's memory
566  */
567  ruletup = SPI_tuptable->vals[0];
568  rulettc = SPI_tuptable->tupdesc;
569  make_ruledef(&buf, ruletup, rulettc, prettyFlags);
570  }
571 
572  /*
573  * Disconnect from SPI manager
574  */
575  if (SPI_finish() != SPI_OK_FINISH)
576  elog(ERROR, "SPI_finish failed");
577 
578  if (buf.len == 0)
579  return NULL;
580 
581  return buf.data;
582 }
583 
584 
585 /* ----------
586  * get_viewdef - Mainly the same thing, but we
587  * only return the SELECT part of a view
588  * ----------
589  */
590 Datum
592 {
593  /* By OID */
594  Oid viewoid = PG_GETARG_OID(0);
595  int prettyFlags;
596  char *res;
597 
598  prettyFlags = PRETTYFLAG_INDENT;
599 
600  res = pg_get_viewdef_worker(viewoid, prettyFlags, WRAP_COLUMN_DEFAULT);
601 
602  if (res == NULL)
603  PG_RETURN_NULL();
604 
606 }
607 
608 
609 Datum
611 {
612  /* By OID */
613  Oid viewoid = PG_GETARG_OID(0);
614  bool pretty = PG_GETARG_BOOL(1);
615  int prettyFlags;
616  char *res;
617 
618  prettyFlags = pretty ? PRETTYFLAG_PAREN | PRETTYFLAG_INDENT : PRETTYFLAG_INDENT;
619 
620  res = pg_get_viewdef_worker(viewoid, prettyFlags, WRAP_COLUMN_DEFAULT);
621 
622  if (res == NULL)
623  PG_RETURN_NULL();
624 
626 }
627 
628 Datum
630 {
631  /* By OID */
632  Oid viewoid = PG_GETARG_OID(0);
633  int wrap = PG_GETARG_INT32(1);
634  int prettyFlags;
635  char *res;
636 
637  /* calling this implies we want pretty printing */
638  prettyFlags = PRETTYFLAG_PAREN | PRETTYFLAG_INDENT;
639 
640  res = pg_get_viewdef_worker(viewoid, prettyFlags, wrap);
641 
642  if (res == NULL)
643  PG_RETURN_NULL();
644 
646 }
647 
648 Datum
650 {
651  /* By qualified name */
652  text *viewname = PG_GETARG_TEXT_PP(0);
653  int prettyFlags;
654  RangeVar *viewrel;
655  Oid viewoid;
656  char *res;
657 
658  prettyFlags = PRETTYFLAG_INDENT;
659 
660  /* Look up view name. Can't lock it - we might not have privileges. */
662  viewoid = RangeVarGetRelid(viewrel, NoLock, false);
663 
664  res = pg_get_viewdef_worker(viewoid, prettyFlags, WRAP_COLUMN_DEFAULT);
665 
666  if (res == NULL)
667  PG_RETURN_NULL();
668 
670 }
671 
672 
673 Datum
675 {
676  /* By qualified name */
677  text *viewname = PG_GETARG_TEXT_PP(0);
678  bool pretty = PG_GETARG_BOOL(1);
679  int prettyFlags;
680  RangeVar *viewrel;
681  Oid viewoid;
682  char *res;
683 
684  prettyFlags = pretty ? PRETTYFLAG_PAREN | PRETTYFLAG_INDENT : PRETTYFLAG_INDENT;
685 
686  /* Look up view name. Can't lock it - we might not have privileges. */
688  viewoid = RangeVarGetRelid(viewrel, NoLock, false);
689 
690  res = pg_get_viewdef_worker(viewoid, prettyFlags, WRAP_COLUMN_DEFAULT);
691 
692  if (res == NULL)
693  PG_RETURN_NULL();
694 
696 }
697 
698 /*
699  * Common code for by-OID and by-name variants of pg_get_viewdef
700  */
701 static char *
702 pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn)
703 {
704  Datum args[2];
705  char nulls[2];
706  int spirc;
707  HeapTuple ruletup;
708  TupleDesc rulettc;
710 
711  /*
712  * Do this first so that string is alloc'd in outer context not SPI's.
713  */
714  initStringInfo(&buf);
715 
716  /*
717  * Connect to SPI manager
718  */
719  if (SPI_connect() != SPI_OK_CONNECT)
720  elog(ERROR, "SPI_connect failed");
721 
722  /*
723  * On the first call prepare the plan to lookup pg_rewrite. We read
724  * pg_rewrite over the SPI manager instead of using the syscache to be
725  * checked for read access on pg_rewrite.
726  */
727  if (plan_getviewrule == NULL)
728  {
729  Oid argtypes[2];
730  SPIPlanPtr plan;
731 
732  argtypes[0] = OIDOID;
733  argtypes[1] = NAMEOID;
734  plan = SPI_prepare(query_getviewrule, 2, argtypes);
735  if (plan == NULL)
736  elog(ERROR, "SPI_prepare failed for \"%s\"", query_getviewrule);
737  SPI_keepplan(plan);
738  plan_getviewrule = plan;
739  }
740 
741  /*
742  * Get the pg_rewrite tuple for the view's SELECT rule
743  */
744  args[0] = ObjectIdGetDatum(viewoid);
746  nulls[0] = ' ';
747  nulls[1] = ' ';
748  spirc = SPI_execute_plan(plan_getviewrule, args, nulls, true, 0);
749  if (spirc != SPI_OK_SELECT)
750  elog(ERROR, "failed to get pg_rewrite tuple for view %u", viewoid);
751  if (SPI_processed != 1)
752  {
753  /*
754  * There is no tuple data available here, just keep the output buffer
755  * empty.
756  */
757  }
758  else
759  {
760  /*
761  * Get the rule's definition and put it into executor's memory
762  */
763  ruletup = SPI_tuptable->vals[0];
764  rulettc = SPI_tuptable->tupdesc;
765  make_viewdef(&buf, ruletup, rulettc, prettyFlags, wrapColumn);
766  }
767 
768  /*
769  * Disconnect from SPI manager
770  */
771  if (SPI_finish() != SPI_OK_FINISH)
772  elog(ERROR, "SPI_finish failed");
773 
774  if (buf.len == 0)
775  return NULL;
776 
777  return buf.data;
778 }
779 
780 /* ----------
781  * get_triggerdef - Get the definition of a trigger
782  * ----------
783  */
784 Datum
786 {
787  Oid trigid = PG_GETARG_OID(0);
788  char *res;
789 
790  res = pg_get_triggerdef_worker(trigid, false);
791 
792  if (res == NULL)
793  PG_RETURN_NULL();
794 
796 }
797 
798 Datum
800 {
801  Oid trigid = PG_GETARG_OID(0);
802  bool pretty = PG_GETARG_BOOL(1);
803  char *res;
804 
805  res = pg_get_triggerdef_worker(trigid, pretty);
806 
807  if (res == NULL)
808  PG_RETURN_NULL();
809 
811 }
812 
813 static char *
814 pg_get_triggerdef_worker(Oid trigid, bool pretty)
815 {
816  HeapTuple ht_trig;
817  Form_pg_trigger trigrec;
819  Relation tgrel;
820  ScanKeyData skey[1];
821  SysScanDesc tgscan;
822  int findx = 0;
823  char *tgname;
824  char *tgoldtable;
825  char *tgnewtable;
826  Oid argtypes[1]; /* dummy */
827  Datum value;
828  bool isnull;
829 
830  /*
831  * Fetch the pg_trigger tuple by the Oid of the trigger
832  */
834 
835  ScanKeyInit(&skey[0],
837  BTEqualStrategyNumber, F_OIDEQ,
838  ObjectIdGetDatum(trigid));
839 
840  tgscan = systable_beginscan(tgrel, TriggerOidIndexId, true,
841  NULL, 1, skey);
842 
843  ht_trig = systable_getnext(tgscan);
844 
845  if (!HeapTupleIsValid(ht_trig))
846  {
847  systable_endscan(tgscan);
848  heap_close(tgrel, AccessShareLock);
849  return NULL;
850  }
851 
852  trigrec = (Form_pg_trigger) GETSTRUCT(ht_trig);
853 
854  /*
855  * Start the trigger definition. Note that the trigger's name should never
856  * be schema-qualified, but the trigger rel's name may be.
857  */
858  initStringInfo(&buf);
859 
860  tgname = NameStr(trigrec->tgname);
861  appendStringInfo(&buf, "CREATE %sTRIGGER %s ",
862  OidIsValid(trigrec->tgconstraint) ? "CONSTRAINT " : "",
863  quote_identifier(tgname));
864 
865  if (TRIGGER_FOR_BEFORE(trigrec->tgtype))
866  appendStringInfoString(&buf, "BEFORE");
867  else if (TRIGGER_FOR_AFTER(trigrec->tgtype))
868  appendStringInfoString(&buf, "AFTER");
869  else if (TRIGGER_FOR_INSTEAD(trigrec->tgtype))
870  appendStringInfoString(&buf, "INSTEAD OF");
871  else
872  elog(ERROR, "unexpected tgtype value: %d", trigrec->tgtype);
873 
874  if (TRIGGER_FOR_INSERT(trigrec->tgtype))
875  {
876  appendStringInfoString(&buf, " INSERT");
877  findx++;
878  }
879  if (TRIGGER_FOR_DELETE(trigrec->tgtype))
880  {
881  if (findx > 0)
882  appendStringInfoString(&buf, " OR DELETE");
883  else
884  appendStringInfoString(&buf, " DELETE");
885  findx++;
886  }
887  if (TRIGGER_FOR_UPDATE(trigrec->tgtype))
888  {
889  if (findx > 0)
890  appendStringInfoString(&buf, " OR UPDATE");
891  else
892  appendStringInfoString(&buf, " UPDATE");
893  findx++;
894  /* tgattr is first var-width field, so OK to access directly */
895  if (trigrec->tgattr.dim1 > 0)
896  {
897  int i;
898 
899  appendStringInfoString(&buf, " OF ");
900  for (i = 0; i < trigrec->tgattr.dim1; i++)
901  {
902  char *attname;
903 
904  if (i > 0)
905  appendStringInfoString(&buf, ", ");
906  attname = get_relid_attribute_name(trigrec->tgrelid,
907  trigrec->tgattr.values[i]);
909  }
910  }
911  }
912  if (TRIGGER_FOR_TRUNCATE(trigrec->tgtype))
913  {
914  if (findx > 0)
915  appendStringInfoString(&buf, " OR TRUNCATE");
916  else
917  appendStringInfoString(&buf, " TRUNCATE");
918  findx++;
919  }
920  appendStringInfo(&buf, " ON %s ",
921  generate_relation_name(trigrec->tgrelid, NIL));
922 
923  if (OidIsValid(trigrec->tgconstraint))
924  {
925  if (OidIsValid(trigrec->tgconstrrelid))
926  appendStringInfo(&buf, "FROM %s ",
927  generate_relation_name(trigrec->tgconstrrelid, NIL));
928  if (!trigrec->tgdeferrable)
929  appendStringInfoString(&buf, "NOT ");
930  appendStringInfoString(&buf, "DEFERRABLE INITIALLY ");
931  if (trigrec->tginitdeferred)
932  appendStringInfoString(&buf, "DEFERRED ");
933  else
934  appendStringInfoString(&buf, "IMMEDIATE ");
935  }
936 
937  value = fastgetattr(ht_trig, Anum_pg_trigger_tgoldtable,
938  tgrel->rd_att, &isnull);
939  if (!isnull)
940  tgoldtable = NameStr(*((NameData *) DatumGetPointer(value)));
941  else
942  tgoldtable = NULL;
943  value = fastgetattr(ht_trig, Anum_pg_trigger_tgnewtable,
944  tgrel->rd_att, &isnull);
945  if (!isnull)
946  tgnewtable = NameStr(*((NameData *) DatumGetPointer(value)));
947  else
948  tgnewtable = NULL;
949  if (tgoldtable != NULL || tgnewtable != NULL)
950  {
951  appendStringInfoString(&buf, "REFERENCING ");
952  if (tgoldtable != NULL)
953  appendStringInfo(&buf, "OLD TABLE AS %s ", tgoldtable);
954  if (tgnewtable != NULL)
955  appendStringInfo(&buf, "NEW TABLE AS %s ", tgnewtable);
956  }
957 
958  if (TRIGGER_FOR_ROW(trigrec->tgtype))
959  appendStringInfoString(&buf, "FOR EACH ROW ");
960  else
961  appendStringInfoString(&buf, "FOR EACH STATEMENT ");
962 
963  /* If the trigger has a WHEN qualification, add that */
964  value = fastgetattr(ht_trig, Anum_pg_trigger_tgqual,
965  tgrel->rd_att, &isnull);
966  if (!isnull)
967  {
968  Node *qual;
969  char relkind;
970  deparse_context context;
971  deparse_namespace dpns;
972  RangeTblEntry *oldrte;
973  RangeTblEntry *newrte;
974 
975  appendStringInfoString(&buf, "WHEN (");
976 
977  qual = stringToNode(TextDatumGetCString(value));
978 
979  relkind = get_rel_relkind(trigrec->tgrelid);
980 
981  /* Build minimal OLD and NEW RTEs for the rel */
982  oldrte = makeNode(RangeTblEntry);
983  oldrte->rtekind = RTE_RELATION;
984  oldrte->relid = trigrec->tgrelid;
985  oldrte->relkind = relkind;
986  oldrte->alias = makeAlias("old", NIL);
987  oldrte->eref = oldrte->alias;
988  oldrte->lateral = false;
989  oldrte->inh = false;
990  oldrte->inFromCl = true;
991 
992  newrte = makeNode(RangeTblEntry);
993  newrte->rtekind = RTE_RELATION;
994  newrte->relid = trigrec->tgrelid;
995  newrte->relkind = relkind;
996  newrte->alias = makeAlias("new", NIL);
997  newrte->eref = newrte->alias;
998  newrte->lateral = false;
999  newrte->inh = false;
1000  newrte->inFromCl = true;
1001 
1002  /* Build two-element rtable */
1003  memset(&dpns, 0, sizeof(dpns));
1004  dpns.rtable = list_make2(oldrte, newrte);
1005  dpns.ctes = NIL;
1006  set_rtable_names(&dpns, NIL, NULL);
1007  set_simple_column_names(&dpns);
1008 
1009  /* Set up context with one-deep namespace stack */
1010  context.buf = &buf;
1011  context.namespaces = list_make1(&dpns);
1012  context.windowClause = NIL;
1013  context.windowTList = NIL;
1014  context.varprefix = true;
1016  context.wrapColumn = WRAP_COLUMN_DEFAULT;
1017  context.indentLevel = PRETTYINDENT_STD;
1018  context.special_exprkind = EXPR_KIND_NONE;
1019 
1020  get_rule_expr(qual, &context, false);
1021 
1022  appendStringInfoString(&buf, ") ");
1023  }
1024 
1025  appendStringInfo(&buf, "EXECUTE PROCEDURE %s(",
1026  generate_function_name(trigrec->tgfoid, 0,
1027  NIL, argtypes,
1028  false, NULL, EXPR_KIND_NONE));
1029 
1030  if (trigrec->tgnargs > 0)
1031  {
1032  char *p;
1033  int i;
1034 
1035  value = fastgetattr(ht_trig, Anum_pg_trigger_tgargs,
1036  tgrel->rd_att, &isnull);
1037  if (isnull)
1038  elog(ERROR, "tgargs is null for trigger %u", trigid);
1039  p = (char *) VARDATA_ANY(DatumGetByteaPP(value));
1040  for (i = 0; i < trigrec->tgnargs; i++)
1041  {
1042  if (i > 0)
1043  appendStringInfoString(&buf, ", ");
1044  simple_quote_literal(&buf, p);
1045  /* advance p to next string embedded in tgargs */
1046  while (*p)
1047  p++;
1048  p++;
1049  }
1050  }
1051 
1052  /* We deliberately do not put semi-colon at end */
1053  appendStringInfoChar(&buf, ')');
1054 
1055  /* Clean up */
1056  systable_endscan(tgscan);
1057 
1058  heap_close(tgrel, AccessShareLock);
1059 
1060  return buf.data;
1061 }
1062 
1063 /* ----------
1064  * get_indexdef - Get the definition of an index
1065  *
1066  * In the extended version, there is a colno argument as well as pretty bool.
1067  * if colno == 0, we want a complete index definition.
1068  * if colno > 0, we only want the Nth index key's variable or expression.
1069  *
1070  * Note that the SQL-function versions of this omit any info about the
1071  * index tablespace; this is intentional because pg_dump wants it that way.
1072  * However pg_get_indexdef_string() includes the index tablespace.
1073  * ----------
1074  */
1075 Datum
1077 {
1078  Oid indexrelid = PG_GETARG_OID(0);
1079  int prettyFlags;
1080  char *res;
1081 
1082  prettyFlags = PRETTYFLAG_INDENT;
1083 
1084  res = pg_get_indexdef_worker(indexrelid, 0, NULL, false, false,
1085  prettyFlags, true);
1086 
1087  if (res == NULL)
1088  PG_RETURN_NULL();
1089 
1091 }
1092 
1093 Datum
1095 {
1096  Oid indexrelid = PG_GETARG_OID(0);
1097  int32 colno = PG_GETARG_INT32(1);
1098  bool pretty = PG_GETARG_BOOL(2);
1099  int prettyFlags;
1100  char *res;
1101 
1102  prettyFlags = pretty ? PRETTYFLAG_PAREN | PRETTYFLAG_INDENT : PRETTYFLAG_INDENT;
1103 
1104  res = pg_get_indexdef_worker(indexrelid, colno, NULL, colno != 0, false,
1105  prettyFlags, true);
1106 
1107  if (res == NULL)
1108  PG_RETURN_NULL();
1109 
1111 }
1112 
1113 /*
1114  * Internal version for use by ALTER TABLE.
1115  * Includes a tablespace clause in the result.
1116  * Returns a palloc'd C string; no pretty-printing.
1117  */
1118 char *
1120 {
1121  return pg_get_indexdef_worker(indexrelid, 0, NULL, false, true, 0, false);
1122 }
1123 
1124 /* Internal version that just reports the column definitions */
1125 char *
1126 pg_get_indexdef_columns(Oid indexrelid, bool pretty)
1127 {
1128  int prettyFlags;
1129 
1130  prettyFlags = pretty ? PRETTYFLAG_PAREN | PRETTYFLAG_INDENT : PRETTYFLAG_INDENT;
1131  return pg_get_indexdef_worker(indexrelid, 0, NULL, true, false,
1132  prettyFlags, false);
1133 }
1134 
1135 /*
1136  * Internal workhorse to decompile an index definition.
1137  *
1138  * This is now used for exclusion constraints as well: if excludeOps is not
1139  * NULL then it points to an array of exclusion operator OIDs.
1140  */
1141 static char *
1142 pg_get_indexdef_worker(Oid indexrelid, int colno,
1143  const Oid *excludeOps,
1144  bool attrsOnly, bool showTblSpc,
1145  int prettyFlags, bool missing_ok)
1146 {
1147  /* might want a separate isConstraint parameter later */
1148  bool isConstraint = (excludeOps != NULL);
1149  HeapTuple ht_idx;
1150  HeapTuple ht_idxrel;
1151  HeapTuple ht_am;
1152  Form_pg_index idxrec;
1153  Form_pg_class idxrelrec;
1154  Form_pg_am amrec;
1155  IndexAmRoutine *amroutine;
1156  List *indexprs;
1157  ListCell *indexpr_item;
1158  List *context;
1159  Oid indrelid;
1160  int keyno;
1161  Datum indcollDatum;
1162  Datum indclassDatum;
1163  Datum indoptionDatum;
1164  bool isnull;
1165  oidvector *indcollation;
1166  oidvector *indclass;
1167  int2vector *indoption;
1169  char *str;
1170  char *sep;
1171 
1172  /*
1173  * Fetch the pg_index tuple by the Oid of the index
1174  */
1175  ht_idx = SearchSysCache1(INDEXRELID, ObjectIdGetDatum(indexrelid));
1176  if (!HeapTupleIsValid(ht_idx))
1177  {
1178  if (missing_ok)
1179  return NULL;
1180  elog(ERROR, "cache lookup failed for index %u", indexrelid);
1181  }
1182  idxrec = (Form_pg_index) GETSTRUCT(ht_idx);
1183 
1184  indrelid = idxrec->indrelid;
1185  Assert(indexrelid == idxrec->indexrelid);
1186 
1187  /* Must get indcollation, indclass, and indoption the hard way */
1188  indcollDatum = SysCacheGetAttr(INDEXRELID, ht_idx,
1189  Anum_pg_index_indcollation, &isnull);
1190  Assert(!isnull);
1191  indcollation = (oidvector *) DatumGetPointer(indcollDatum);
1192 
1193  indclassDatum = SysCacheGetAttr(INDEXRELID, ht_idx,
1194  Anum_pg_index_indclass, &isnull);
1195  Assert(!isnull);
1196  indclass = (oidvector *) DatumGetPointer(indclassDatum);
1197 
1198  indoptionDatum = SysCacheGetAttr(INDEXRELID, ht_idx,
1199  Anum_pg_index_indoption, &isnull);
1200  Assert(!isnull);
1201  indoption = (int2vector *) DatumGetPointer(indoptionDatum);
1202 
1203  /*
1204  * Fetch the pg_class tuple of the index relation
1205  */
1206  ht_idxrel = SearchSysCache1(RELOID, ObjectIdGetDatum(indexrelid));
1207  if (!HeapTupleIsValid(ht_idxrel))
1208  elog(ERROR, "cache lookup failed for relation %u", indexrelid);
1209  idxrelrec = (Form_pg_class) GETSTRUCT(ht_idxrel);
1210 
1211  /*
1212  * Fetch the pg_am tuple of the index' access method
1213  */
1214  ht_am = SearchSysCache1(AMOID, ObjectIdGetDatum(idxrelrec->relam));
1215  if (!HeapTupleIsValid(ht_am))
1216  elog(ERROR, "cache lookup failed for access method %u",
1217  idxrelrec->relam);
1218  amrec = (Form_pg_am) GETSTRUCT(ht_am);
1219 
1220  /* Fetch the index AM's API struct */
1221  amroutine = GetIndexAmRoutine(amrec->amhandler);
1222 
1223  /*
1224  * Get the index expressions, if any. (NOTE: we do not use the relcache
1225  * versions of the expressions and predicate, because we want to display
1226  * non-const-folded expressions.)
1227  */
1228  if (!heap_attisnull(ht_idx, Anum_pg_index_indexprs))
1229  {
1230  Datum exprsDatum;
1231  bool isnull;
1232  char *exprsString;
1233 
1234  exprsDatum = SysCacheGetAttr(INDEXRELID, ht_idx,
1235  Anum_pg_index_indexprs, &isnull);
1236  Assert(!isnull);
1237  exprsString = TextDatumGetCString(exprsDatum);
1238  indexprs = (List *) stringToNode(exprsString);
1239  pfree(exprsString);
1240  }
1241  else
1242  indexprs = NIL;
1243 
1244  indexpr_item = list_head(indexprs);
1245 
1246  context = deparse_context_for(get_relation_name(indrelid), indrelid);
1247 
1248  /*
1249  * Start the index definition. Note that the index's name should never be
1250  * schema-qualified, but the indexed rel's name may be.
1251  */
1252  initStringInfo(&buf);
1253 
1254  if (!attrsOnly)
1255  {
1256  if (!isConstraint)
1257  appendStringInfo(&buf, "CREATE %sINDEX %s ON %s USING %s (",
1258  idxrec->indisunique ? "UNIQUE " : "",
1259  quote_identifier(NameStr(idxrelrec->relname)),
1260  generate_relation_name(indrelid, NIL),
1261  quote_identifier(NameStr(amrec->amname)));
1262  else /* currently, must be EXCLUDE constraint */
1263  appendStringInfo(&buf, "EXCLUDE USING %s (",
1264  quote_identifier(NameStr(amrec->amname)));
1265  }
1266 
1267  /*
1268  * Report the indexed attributes
1269  */
1270  sep = "";
1271  for (keyno = 0; keyno < idxrec->indnatts; keyno++)
1272  {
1273  AttrNumber attnum = idxrec->indkey.values[keyno];
1274  int16 opt = indoption->values[keyno];
1275  Oid keycoltype;
1276  Oid keycolcollation;
1277 
1278  if (!colno)
1279  appendStringInfoString(&buf, sep);
1280  sep = ", ";
1281 
1282  if (attnum != 0)
1283  {
1284  /* Simple index column */
1285  char *attname;
1286  int32 keycoltypmod;
1287 
1288  attname = get_relid_attribute_name(indrelid, attnum);
1289  if (!colno || colno == keyno + 1)
1290  appendStringInfoString(&buf, quote_identifier(attname));
1291  get_atttypetypmodcoll(indrelid, attnum,
1292  &keycoltype, &keycoltypmod,
1293  &keycolcollation);
1294  }
1295  else
1296  {
1297  /* expressional index */
1298  Node *indexkey;
1299 
1300  if (indexpr_item == NULL)
1301  elog(ERROR, "too few entries in indexprs list");
1302  indexkey = (Node *) lfirst(indexpr_item);
1303  indexpr_item = lnext(indexpr_item);
1304  /* Deparse */
1305  str = deparse_expression_pretty(indexkey, context, false, false,
1306  prettyFlags, 0);
1307  if (!colno || colno == keyno + 1)
1308  {
1309  /* Need parens if it's not a bare function call */
1310  if (indexkey && IsA(indexkey, FuncExpr) &&
1311  ((FuncExpr *) indexkey)->funcformat == COERCE_EXPLICIT_CALL)
1312  appendStringInfoString(&buf, str);
1313  else
1314  appendStringInfo(&buf, "(%s)", str);
1315  }
1316  keycoltype = exprType(indexkey);
1317  keycolcollation = exprCollation(indexkey);
1318  }
1319 
1320  if (!attrsOnly && (!colno || colno == keyno + 1))
1321  {
1322  Oid indcoll;
1323 
1324  /* Add collation, if not default for column */
1325  indcoll = indcollation->values[keyno];
1326  if (OidIsValid(indcoll) && indcoll != keycolcollation)
1327  appendStringInfo(&buf, " COLLATE %s",
1328  generate_collation_name((indcoll)));
1329 
1330  /* Add the operator class name, if not default */
1331  get_opclass_name(indclass->values[keyno], keycoltype, &buf);
1332 
1333  /* Add options if relevant */
1334  if (amroutine->amcanorder)
1335  {
1336  /* if it supports sort ordering, report DESC and NULLS opts */
1337  if (opt & INDOPTION_DESC)
1338  {
1339  appendStringInfoString(&buf, " DESC");
1340  /* NULLS FIRST is the default in this case */
1341  if (!(opt & INDOPTION_NULLS_FIRST))
1342  appendStringInfoString(&buf, " NULLS LAST");
1343  }
1344  else
1345  {
1346  if (opt & INDOPTION_NULLS_FIRST)
1347  appendStringInfoString(&buf, " NULLS FIRST");
1348  }
1349  }
1350 
1351  /* Add the exclusion operator if relevant */
1352  if (excludeOps != NULL)
1353  appendStringInfo(&buf, " WITH %s",
1354  generate_operator_name(excludeOps[keyno],
1355  keycoltype,
1356  keycoltype));
1357  }
1358  }
1359 
1360  if (!attrsOnly)
1361  {
1362  appendStringInfoChar(&buf, ')');
1363 
1364  /*
1365  * If it has options, append "WITH (options)"
1366  */
1367  str = flatten_reloptions(indexrelid);
1368  if (str)
1369  {
1370  appendStringInfo(&buf, " WITH (%s)", str);
1371  pfree(str);
1372  }
1373 
1374  /*
1375  * Print tablespace, but only if requested
1376  */
1377  if (showTblSpc)
1378  {
1379  Oid tblspc;
1380 
1381  tblspc = get_rel_tablespace(indexrelid);
1382  if (!OidIsValid(tblspc))
1383  tblspc = MyDatabaseTableSpace;
1384  if (isConstraint)
1385  appendStringInfoString(&buf, " USING INDEX");
1386  appendStringInfo(&buf, " TABLESPACE %s",
1388  }
1389 
1390  /*
1391  * If it's a partial index, decompile and append the predicate
1392  */
1393  if (!heap_attisnull(ht_idx, Anum_pg_index_indpred))
1394  {
1395  Node *node;
1396  Datum predDatum;
1397  bool isnull;
1398  char *predString;
1399 
1400  /* Convert text string to node tree */
1401  predDatum = SysCacheGetAttr(INDEXRELID, ht_idx,
1402  Anum_pg_index_indpred, &isnull);
1403  Assert(!isnull);
1404  predString = TextDatumGetCString(predDatum);
1405  node = (Node *) stringToNode(predString);
1406  pfree(predString);
1407 
1408  /* Deparse */
1409  str = deparse_expression_pretty(node, context, false, false,
1410  prettyFlags, 0);
1411  if (isConstraint)
1412  appendStringInfo(&buf, " WHERE (%s)", str);
1413  else
1414  appendStringInfo(&buf, " WHERE %s", str);
1415  }
1416  }
1417 
1418  /* Clean up */
1419  ReleaseSysCache(ht_idx);
1420  ReleaseSysCache(ht_idxrel);
1421  ReleaseSysCache(ht_am);
1422 
1423  return buf.data;
1424 }
1425 
1426 /*
1427  * pg_get_statisticsextdef
1428  * Get the definition of an extended statistics object
1429  */
1430 Datum
1432 {
1433  Oid statextid = PG_GETARG_OID(0);
1434  char *res;
1435 
1436  res = pg_get_statisticsext_worker(statextid, true);
1437 
1438  if (res == NULL)
1439  PG_RETURN_NULL();
1440 
1442 }
1443 
1444 /*
1445  * Internal workhorse to decompile an extended statistics object.
1446  */
1447 static char *
1448 pg_get_statisticsext_worker(Oid statextid, bool missing_ok)
1449 {
1450  Form_pg_statistic_ext statextrec;
1451  Form_pg_class pgclassrec;
1452  HeapTuple statexttup;
1453  HeapTuple pgclasstup;
1455  int colno;
1456 
1457  statexttup = SearchSysCache1(STATEXTOID, ObjectIdGetDatum(statextid));
1458 
1459  if (!HeapTupleIsValid(statexttup))
1460  {
1461  if (missing_ok)
1462  return NULL;
1463  elog(ERROR, "cache lookup failed for extended statistics %u", statextid);
1464  }
1465 
1466  statextrec = (Form_pg_statistic_ext) GETSTRUCT(statexttup);
1467 
1468  pgclasstup = SearchSysCache1(RELOID, ObjectIdGetDatum(statextrec->starelid));
1469 
1470  if (!HeapTupleIsValid(statexttup))
1471  {
1472  ReleaseSysCache(statexttup);
1473  elog(ERROR, "cache lookup failed for relation %u", statextrec->starelid);
1474  }
1475 
1476  pgclassrec = (Form_pg_class) GETSTRUCT(pgclasstup);
1477 
1478  initStringInfo(&buf);
1479 
1480  appendStringInfo(&buf, "CREATE STATISTICS %s ON (",
1481  quote_identifier(NameStr(statextrec->staname)));
1482 
1483  for (colno = 0; colno < statextrec->stakeys.dim1; colno++)
1484  {
1485  AttrNumber attnum = statextrec->stakeys.values[colno];
1486  char *attname;
1487 
1488  if (colno > 0)
1489  appendStringInfoString(&buf, ", ");
1490 
1491  attname = get_relid_attribute_name(statextrec->starelid, attnum);
1492 
1493  appendStringInfoString(&buf, quote_identifier(attname));
1494  }
1495 
1496  appendStringInfo(&buf, ") FROM %s",
1497  quote_identifier(NameStr(pgclassrec->relname)));
1498 
1499  ReleaseSysCache(statexttup);
1500  ReleaseSysCache(pgclasstup);
1501 
1502  return buf.data;
1503 }
1504 
1505 /*
1506  * pg_get_partkeydef
1507  *
1508  * Returns the partition key specification, ie, the following:
1509  *
1510  * PARTITION BY { RANGE | LIST } (column opt_collation opt_opclass [, ...])
1511  */
1512 Datum
1514 {
1515  Oid relid = PG_GETARG_OID(0);
1516 
1519  false)));
1520 }
1521 
1522 /* Internal version that just reports the column definitions */
1523 char *
1524 pg_get_partkeydef_columns(Oid relid, bool pretty)
1525 {
1526  int prettyFlags;
1527 
1528  prettyFlags = pretty ? PRETTYFLAG_PAREN | PRETTYFLAG_INDENT : PRETTYFLAG_INDENT;
1529  return pg_get_partkeydef_worker(relid, prettyFlags, true);
1530 }
1531 
1532 /*
1533  * Internal workhorse to decompile a partition key definition.
1534  */
1535 static char *
1536 pg_get_partkeydef_worker(Oid relid, int prettyFlags,
1537  bool attrsOnly)
1538 {
1540  HeapTuple tuple;
1541  oidvector *partclass;
1542  oidvector *partcollation;
1543  List *partexprs;
1544  ListCell *partexpr_item;
1545  List *context;
1546  Datum datum;
1547  bool isnull;
1549  int keyno;
1550  char *str;
1551  char *sep;
1552 
1553  tuple = SearchSysCache1(PARTRELID, ObjectIdGetDatum(relid));
1554  if (!HeapTupleIsValid(tuple))
1555  elog(ERROR, "cache lookup failed for partition key of %u", relid);
1556 
1557  form = (Form_pg_partitioned_table) GETSTRUCT(tuple);
1558 
1559  Assert(form->partrelid == relid);
1560 
1561  /* Must get partclass and partcollation the hard way */
1562  datum = SysCacheGetAttr(PARTRELID, tuple,
1564  Assert(!isnull);
1565  partclass = (oidvector *) DatumGetPointer(datum);
1566 
1567  datum = SysCacheGetAttr(PARTRELID, tuple,
1569  Assert(!isnull);
1570  partcollation = (oidvector *) DatumGetPointer(datum);
1571 
1572 
1573  /*
1574  * Get the expressions, if any. (NOTE: we do not use the relcache
1575  * versions of the expressions, because we want to display
1576  * non-const-folded expressions.)
1577  */
1579  {
1580  Datum exprsDatum;
1581  bool isnull;
1582  char *exprsString;
1583 
1584  exprsDatum = SysCacheGetAttr(PARTRELID, tuple,
1586  Assert(!isnull);
1587  exprsString = TextDatumGetCString(exprsDatum);
1588  partexprs = (List *) stringToNode(exprsString);
1589 
1590  if (!IsA(partexprs, List))
1591  elog(ERROR, "unexpected node type found in partexprs: %d",
1592  (int) nodeTag(partexprs));
1593 
1594  pfree(exprsString);
1595  }
1596  else
1597  partexprs = NIL;
1598 
1599  partexpr_item = list_head(partexprs);
1600  context = deparse_context_for(get_relation_name(relid), relid);
1601 
1602  initStringInfo(&buf);
1603 
1604  switch (form->partstrat)
1605  {
1607  if (!attrsOnly)
1608  appendStringInfo(&buf, "LIST");
1609  break;
1611  if (!attrsOnly)
1612  appendStringInfo(&buf, "RANGE");
1613  break;
1614  default:
1615  elog(ERROR, "unexpected partition strategy: %d",
1616  (int) form->partstrat);
1617  }
1618 
1619  if (!attrsOnly)
1620  appendStringInfo(&buf, " (");
1621  sep = "";
1622  for (keyno = 0; keyno < form->partnatts; keyno++)
1623  {
1624  AttrNumber attnum = form->partattrs.values[keyno];
1625  Oid keycoltype;
1626  Oid keycolcollation;
1627  Oid partcoll;
1628 
1629  appendStringInfoString(&buf, sep);
1630  sep = ", ";
1631  if (attnum != 0)
1632  {
1633  /* Simple attribute reference */
1634  char *attname;
1635  int32 keycoltypmod;
1636 
1637  attname = get_relid_attribute_name(relid, attnum);
1638  appendStringInfoString(&buf, quote_identifier(attname));
1639  get_atttypetypmodcoll(relid, attnum,
1640  &keycoltype, &keycoltypmod,
1641  &keycolcollation);
1642  }
1643  else
1644  {
1645  /* Expression */
1646  Node *partkey;
1647 
1648  if (partexpr_item == NULL)
1649  elog(ERROR, "too few entries in partexprs list");
1650  partkey = (Node *) lfirst(partexpr_item);
1651  partexpr_item = lnext(partexpr_item);
1652  /* Deparse */
1653  str = deparse_expression_pretty(partkey, context, false, false,
1654  0, 0);
1655 
1656  appendStringInfoString(&buf, str);
1657  keycoltype = exprType(partkey);
1658  keycolcollation = exprCollation(partkey);
1659  }
1660 
1661  /* Add collation, if not default for column */
1662  partcoll = partcollation->values[keyno];
1663  if (!attrsOnly && OidIsValid(partcoll) && partcoll != keycolcollation)
1664  appendStringInfo(&buf, " COLLATE %s",
1665  generate_collation_name((partcoll)));
1666 
1667  /* Add the operator class name, if not default */
1668  if (!attrsOnly)
1669  get_opclass_name(partclass->values[keyno], keycoltype, &buf);
1670  }
1671 
1672  if (!attrsOnly)
1673  appendStringInfoChar(&buf, ')');
1674 
1675  /* Clean up */
1676  ReleaseSysCache(tuple);
1677 
1678  return buf.data;
1679 }
1680 
1681 /*
1682  * pg_get_constraintdef
1683  *
1684  * Returns the definition for the constraint, ie, everything that needs to
1685  * appear after "ALTER TABLE ... ADD CONSTRAINT <constraintname>".
1686  */
1687 Datum
1689 {
1690  Oid constraintId = PG_GETARG_OID(0);
1691  int prettyFlags;
1692  char *res;
1693 
1694  prettyFlags = PRETTYFLAG_INDENT;
1695 
1696  res = pg_get_constraintdef_worker(constraintId, false, prettyFlags, true);
1697 
1698  if (res == NULL)
1699  PG_RETURN_NULL();
1700 
1702 }
1703 
1704 Datum
1706 {
1707  Oid constraintId = PG_GETARG_OID(0);
1708  bool pretty = PG_GETARG_BOOL(1);
1709  int prettyFlags;
1710  char *res;
1711 
1712  prettyFlags = pretty ? PRETTYFLAG_PAREN | PRETTYFLAG_INDENT : PRETTYFLAG_INDENT;
1713 
1714  res = pg_get_constraintdef_worker(constraintId, false, prettyFlags, true);
1715 
1716  if (res == NULL)
1717  PG_RETURN_NULL();
1718 
1720 }
1721 
1722 /*
1723  * Internal version that returns a full ALTER TABLE ... ADD CONSTRAINT command
1724  */
1725 char *
1727 {
1728  return pg_get_constraintdef_worker(constraintId, true, 0, false);
1729 }
1730 
1731 /*
1732  * As of 9.4, we now use an MVCC snapshot for this.
1733  */
1734 static char *
1735 pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
1736  int prettyFlags, bool missing_ok)
1737 {
1738  HeapTuple tup;
1739  Form_pg_constraint conForm;
1741  SysScanDesc scandesc;
1742  ScanKeyData scankey[1];
1745 
1746  ScanKeyInit(&scankey[0],
1748  BTEqualStrategyNumber, F_OIDEQ,
1749  ObjectIdGetDatum(constraintId));
1750 
1751  scandesc = systable_beginscan(relation,
1753  true,
1754  snapshot,
1755  1,
1756  scankey);
1757 
1758  /*
1759  * We later use the tuple with SysCacheGetAttr() as if we had obtained it
1760  * via SearchSysCache, which works fine.
1761  */
1762  tup = systable_getnext(scandesc);
1763 
1764  UnregisterSnapshot(snapshot);
1765 
1766  if (!HeapTupleIsValid(tup))
1767  {
1768  if (missing_ok)
1769  {
1770  systable_endscan(scandesc);
1771  heap_close(relation, AccessShareLock);
1772  return NULL;
1773  }
1774  elog(ERROR, "cache lookup failed for constraint %u", constraintId);
1775  }
1776 
1777  conForm = (Form_pg_constraint) GETSTRUCT(tup);
1778 
1779  initStringInfo(&buf);
1780 
1781  if (fullCommand)
1782  {
1783  /*
1784  * Currently, callers want ALTER TABLE (without ONLY) for CHECK
1785  * constraints, and other types of constraints don't inherit anyway so
1786  * it doesn't matter whether we say ONLY or not. Someday we might
1787  * need to let callers specify whether to put ONLY in the command.
1788  */
1789  appendStringInfo(&buf, "ALTER TABLE %s ADD CONSTRAINT %s ",
1790  generate_qualified_relation_name(conForm->conrelid),
1791  quote_identifier(NameStr(conForm->conname)));
1792  }
1793 
1794  switch (conForm->contype)
1795  {
1796  case CONSTRAINT_FOREIGN:
1797  {
1798  Datum val;
1799  bool isnull;
1800  const char *string;
1801 
1802  /* Start off the constraint definition */
1803  appendStringInfoString(&buf, "FOREIGN KEY (");
1804 
1805  /* Fetch and build referencing-column list */
1806  val = SysCacheGetAttr(CONSTROID, tup,
1807  Anum_pg_constraint_conkey, &isnull);
1808  if (isnull)
1809  elog(ERROR, "null conkey for constraint %u",
1810  constraintId);
1811 
1812  decompile_column_index_array(val, conForm->conrelid, &buf);
1813 
1814  /* add foreign relation name */
1815  appendStringInfo(&buf, ") REFERENCES %s(",
1816  generate_relation_name(conForm->confrelid,
1817  NIL));
1818 
1819  /* Fetch and build referenced-column list */
1820  val = SysCacheGetAttr(CONSTROID, tup,
1821  Anum_pg_constraint_confkey, &isnull);
1822  if (isnull)
1823  elog(ERROR, "null confkey for constraint %u",
1824  constraintId);
1825 
1826  decompile_column_index_array(val, conForm->confrelid, &buf);
1827 
1828  appendStringInfoChar(&buf, ')');
1829 
1830  /* Add match type */
1831  switch (conForm->confmatchtype)
1832  {
1833  case FKCONSTR_MATCH_FULL:
1834  string = " MATCH FULL";
1835  break;
1837  string = " MATCH PARTIAL";
1838  break;
1839  case FKCONSTR_MATCH_SIMPLE:
1840  string = "";
1841  break;
1842  default:
1843  elog(ERROR, "unrecognized confmatchtype: %d",
1844  conForm->confmatchtype);
1845  string = ""; /* keep compiler quiet */
1846  break;
1847  }
1848  appendStringInfoString(&buf, string);
1849 
1850  /* Add ON UPDATE and ON DELETE clauses, if needed */
1851  switch (conForm->confupdtype)
1852  {
1854  string = NULL; /* suppress default */
1855  break;
1857  string = "RESTRICT";
1858  break;
1860  string = "CASCADE";
1861  break;
1863  string = "SET NULL";
1864  break;
1866  string = "SET DEFAULT";
1867  break;
1868  default:
1869  elog(ERROR, "unrecognized confupdtype: %d",
1870  conForm->confupdtype);
1871  string = NULL; /* keep compiler quiet */
1872  break;
1873  }
1874  if (string)
1875  appendStringInfo(&buf, " ON UPDATE %s", string);
1876 
1877  switch (conForm->confdeltype)
1878  {
1880  string = NULL; /* suppress default */
1881  break;
1883  string = "RESTRICT";
1884  break;
1886  string = "CASCADE";
1887  break;
1889  string = "SET NULL";
1890  break;
1892  string = "SET DEFAULT";
1893  break;
1894  default:
1895  elog(ERROR, "unrecognized confdeltype: %d",
1896  conForm->confdeltype);
1897  string = NULL; /* keep compiler quiet */
1898  break;
1899  }
1900  if (string)
1901  appendStringInfo(&buf, " ON DELETE %s", string);
1902 
1903  break;
1904  }
1905  case CONSTRAINT_PRIMARY:
1906  case CONSTRAINT_UNIQUE:
1907  {
1908  Datum val;
1909  bool isnull;
1910  Oid indexId;
1911 
1912  /* Start off the constraint definition */
1913  if (conForm->contype == CONSTRAINT_PRIMARY)
1914  appendStringInfoString(&buf, "PRIMARY KEY (");
1915  else
1916  appendStringInfoString(&buf, "UNIQUE (");
1917 
1918  /* Fetch and build target column list */
1919  val = SysCacheGetAttr(CONSTROID, tup,
1920  Anum_pg_constraint_conkey, &isnull);
1921  if (isnull)
1922  elog(ERROR, "null conkey for constraint %u",
1923  constraintId);
1924 
1925  decompile_column_index_array(val, conForm->conrelid, &buf);
1926 
1927  appendStringInfoChar(&buf, ')');
1928 
1929  indexId = get_constraint_index(constraintId);
1930 
1931  /* XXX why do we only print these bits if fullCommand? */
1932  if (fullCommand && OidIsValid(indexId))
1933  {
1934  char *options = flatten_reloptions(indexId);
1935  Oid tblspc;
1936 
1937  if (options)
1938  {
1939  appendStringInfo(&buf, " WITH (%s)", options);
1940  pfree(options);
1941  }
1942 
1943  tblspc = get_rel_tablespace(indexId);
1944  if (OidIsValid(tblspc))
1945  appendStringInfo(&buf, " USING INDEX TABLESPACE %s",
1947  }
1948 
1949  break;
1950  }
1951  case CONSTRAINT_CHECK:
1952  {
1953  Datum val;
1954  bool isnull;
1955  char *conbin;
1956  char *consrc;
1957  Node *expr;
1958  List *context;
1959 
1960  /* Fetch constraint expression in parsetree form */
1961  val = SysCacheGetAttr(CONSTROID, tup,
1962  Anum_pg_constraint_conbin, &isnull);
1963  if (isnull)
1964  elog(ERROR, "null conbin for constraint %u",
1965  constraintId);
1966 
1967  conbin = TextDatumGetCString(val);
1968  expr = stringToNode(conbin);
1969 
1970  /* Set up deparsing context for Var nodes in constraint */
1971  if (conForm->conrelid != InvalidOid)
1972  {
1973  /* relation constraint */
1974  context = deparse_context_for(get_relation_name(conForm->conrelid),
1975  conForm->conrelid);
1976  }
1977  else
1978  {
1979  /* domain constraint --- can't have Vars */
1980  context = NIL;
1981  }
1982 
1983  consrc = deparse_expression_pretty(expr, context, false, false,
1984  prettyFlags, 0);
1985 
1986  /*
1987  * Now emit the constraint definition, adding NO INHERIT if
1988  * necessary.
1989  *
1990  * There are cases where the constraint expression will be
1991  * fully parenthesized and we don't need the outer parens ...
1992  * but there are other cases where we do need 'em. Be
1993  * conservative for now.
1994  *
1995  * Note that simply checking for leading '(' and trailing ')'
1996  * would NOT be good enough, consider "(x > 0) AND (y > 0)".
1997  */
1998  appendStringInfo(&buf, "CHECK (%s)%s",
1999  consrc,
2000  conForm->connoinherit ? " NO INHERIT" : "");
2001  break;
2002  }
2003  case CONSTRAINT_TRIGGER:
2004 
2005  /*
2006  * There isn't an ALTER TABLE syntax for creating a user-defined
2007  * constraint trigger, but it seems better to print something than
2008  * throw an error; if we throw error then this function couldn't
2009  * safely be applied to all rows of pg_constraint.
2010  */
2011  appendStringInfoString(&buf, "TRIGGER");
2012  break;
2013  case CONSTRAINT_EXCLUSION:
2014  {
2015  Oid indexOid = conForm->conindid;
2016  Datum val;
2017  bool isnull;
2018  Datum *elems;
2019  int nElems;
2020  int i;
2021  Oid *operators;
2022 
2023  /* Extract operator OIDs from the pg_constraint tuple */
2024  val = SysCacheGetAttr(CONSTROID, tup,
2026  &isnull);
2027  if (isnull)
2028  elog(ERROR, "null conexclop for constraint %u",
2029  constraintId);
2030 
2032  OIDOID, sizeof(Oid), true, 'i',
2033  &elems, NULL, &nElems);
2034 
2035  operators = (Oid *) palloc(nElems * sizeof(Oid));
2036  for (i = 0; i < nElems; i++)
2037  operators[i] = DatumGetObjectId(elems[i]);
2038 
2039  /* pg_get_indexdef_worker does the rest */
2040  /* suppress tablespace because pg_dump wants it that way */
2042  pg_get_indexdef_worker(indexOid,
2043  0,
2044  operators,
2045  false,
2046  false,
2047  prettyFlags,
2048  false));
2049  break;
2050  }
2051  default:
2052  elog(ERROR, "invalid constraint type \"%c\"", conForm->contype);
2053  break;
2054  }
2055 
2056  if (conForm->condeferrable)
2057  appendStringInfoString(&buf, " DEFERRABLE");
2058  if (conForm->condeferred)
2059  appendStringInfoString(&buf, " INITIALLY DEFERRED");
2060  if (!conForm->convalidated)
2061  appendStringInfoString(&buf, " NOT VALID");
2062 
2063  /* Cleanup */
2064  systable_endscan(scandesc);
2065  heap_close(relation, AccessShareLock);
2066 
2067  return buf.data;
2068 }
2069 
2070 
2071 /*
2072  * Convert an int16[] Datum into a comma-separated list of column names
2073  * for the indicated relation; append the list to buf.
2074  */
2075 static void
2076 decompile_column_index_array(Datum column_index_array, Oid relId,
2077  StringInfo buf)
2078 {
2079  Datum *keys;
2080  int nKeys;
2081  int j;
2082 
2083  /* Extract data from array of int16 */
2084  deconstruct_array(DatumGetArrayTypeP(column_index_array),
2085  INT2OID, 2, true, 's',
2086  &keys, NULL, &nKeys);
2087 
2088  for (j = 0; j < nKeys; j++)
2089  {
2090  char *colName;
2091 
2092  colName = get_relid_attribute_name(relId, DatumGetInt16(keys[j]));
2093 
2094  if (j == 0)
2096  else
2097  appendStringInfo(buf, ", %s", quote_identifier(colName));
2098  }
2099 }
2100 
2101 
2102 /* ----------
2103  * get_expr - Decompile an expression tree
2104  *
2105  * Input: an expression tree in nodeToString form, and a relation OID
2106  *
2107  * Output: reverse-listed expression
2108  *
2109  * Currently, the expression can only refer to a single relation, namely
2110  * the one specified by the second parameter. This is sufficient for
2111  * partial indexes, column default expressions, etc. We also support
2112  * Var-free expressions, for which the OID can be InvalidOid.
2113  * ----------
2114  */
2115 Datum
2117 {
2118  text *expr = PG_GETARG_TEXT_PP(0);
2119  Oid relid = PG_GETARG_OID(1);
2120  int prettyFlags;
2121  char *relname;
2122 
2123  prettyFlags = PRETTYFLAG_INDENT;
2124 
2125  if (OidIsValid(relid))
2126  {
2127  /* Get the name for the relation */
2128  relname = get_rel_name(relid);
2129 
2130  /*
2131  * If the OID isn't actually valid, don't throw an error, just return
2132  * NULL. This is a bit questionable, but it's what we've done
2133  * historically, and it can help avoid unwanted failures when
2134  * examining catalog entries for just-deleted relations.
2135  */
2136  if (relname == NULL)
2137  PG_RETURN_NULL();
2138  }
2139  else
2140  relname = NULL;
2141 
2142  PG_RETURN_TEXT_P(pg_get_expr_worker(expr, relid, relname, prettyFlags));
2143 }
2144 
2145 Datum
2147 {
2148  text *expr = PG_GETARG_TEXT_PP(0);
2149  Oid relid = PG_GETARG_OID(1);
2150  bool pretty = PG_GETARG_BOOL(2);
2151  int prettyFlags;
2152  char *relname;
2153 
2154  prettyFlags = pretty ? PRETTYFLAG_PAREN | PRETTYFLAG_INDENT : PRETTYFLAG_INDENT;
2155 
2156  if (OidIsValid(relid))
2157  {
2158  /* Get the name for the relation */
2159  relname = get_rel_name(relid);
2160  /* See notes above */
2161  if (relname == NULL)
2162  PG_RETURN_NULL();
2163  }
2164  else
2165  relname = NULL;
2166 
2167  PG_RETURN_TEXT_P(pg_get_expr_worker(expr, relid, relname, prettyFlags));
2168 }
2169 
2170 static text *
2171 pg_get_expr_worker(text *expr, Oid relid, const char *relname, int prettyFlags)
2172 {
2173  Node *node;
2174  List *context;
2175  char *exprstr;
2176  char *str;
2177 
2178  /* Convert input TEXT object to C string */
2179  exprstr = text_to_cstring(expr);
2180 
2181  /* Convert expression to node tree */
2182  node = (Node *) stringToNode(exprstr);
2183 
2184  pfree(exprstr);
2185 
2186  /* Prepare deparse context if needed */
2187  if (OidIsValid(relid))
2188  context = deparse_context_for(relname, relid);
2189  else
2190  context = NIL;
2191 
2192  /* Deparse */
2193  str = deparse_expression_pretty(node, context, false, false,
2194  prettyFlags, 0);
2195 
2196  return string_to_text(str);
2197 }
2198 
2199 
2200 /* ----------
2201  * get_userbyid - Get a user name by roleid and
2202  * fallback to 'unknown (OID=n)'
2203  * ----------
2204  */
2205 Datum
2207 {
2208  Oid roleid = PG_GETARG_OID(0);
2209  Name result;
2210  HeapTuple roletup;
2211  Form_pg_authid role_rec;
2212 
2213  /*
2214  * Allocate space for the result
2215  */
2216  result = (Name) palloc(NAMEDATALEN);
2217  memset(NameStr(*result), 0, NAMEDATALEN);
2218 
2219  /*
2220  * Get the pg_authid entry and print the result
2221  */
2222  roletup = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
2223  if (HeapTupleIsValid(roletup))
2224  {
2225  role_rec = (Form_pg_authid) GETSTRUCT(roletup);
2226  StrNCpy(NameStr(*result), NameStr(role_rec->rolname), NAMEDATALEN);
2227  ReleaseSysCache(roletup);
2228  }
2229  else
2230  sprintf(NameStr(*result), "unknown (OID=%u)", roleid);
2231 
2232  PG_RETURN_NAME(result);
2233 }
2234 
2235 
2236 /*
2237  * pg_get_serial_sequence
2238  * Get the name of the sequence used by a serial column,
2239  * formatted suitably for passing to setval, nextval or currval.
2240  * First parameter is not treated as double-quoted, second parameter
2241  * is --- see documentation for reason.
2242  */
2243 Datum
2245 {
2246  text *tablename = PG_GETARG_TEXT_PP(0);
2247  text *columnname = PG_GETARG_TEXT_PP(1);
2248  RangeVar *tablerv;
2249  Oid tableOid;
2250  char *column;
2251  AttrNumber attnum;
2252  Oid sequenceId = InvalidOid;
2253  Relation depRel;
2254  ScanKeyData key[3];
2255  SysScanDesc scan;
2256  HeapTuple tup;
2257 
2258  /* Look up table name. Can't lock it - we might not have privileges. */
2259  tablerv = makeRangeVarFromNameList(textToQualifiedNameList(tablename));
2260  tableOid = RangeVarGetRelid(tablerv, NoLock, false);
2261 
2262  /* Get the number of the column */
2263  column = text_to_cstring(columnname);
2264 
2265  attnum = get_attnum(tableOid, column);
2266  if (attnum == InvalidAttrNumber)
2267  ereport(ERROR,
2268  (errcode(ERRCODE_UNDEFINED_COLUMN),
2269  errmsg("column \"%s\" of relation \"%s\" does not exist",
2270  column, tablerv->relname)));
2271 
2272  /* Search the dependency table for the dependent sequence */
2274 
2275  ScanKeyInit(&key[0],
2277  BTEqualStrategyNumber, F_OIDEQ,
2279  ScanKeyInit(&key[1],
2281  BTEqualStrategyNumber, F_OIDEQ,
2282  ObjectIdGetDatum(tableOid));
2283  ScanKeyInit(&key[2],
2285  BTEqualStrategyNumber, F_INT4EQ,
2286  Int32GetDatum(attnum));
2287 
2288  scan = systable_beginscan(depRel, DependReferenceIndexId, true,
2289  NULL, 3, key);
2290 
2291  while (HeapTupleIsValid(tup = systable_getnext(scan)))
2292  {
2293  Form_pg_depend deprec = (Form_pg_depend) GETSTRUCT(tup);
2294 
2295  /*
2296  * We assume any auto dependency of a sequence on a column must be
2297  * what we are looking for. (We need the relkind test because indexes
2298  * can also have auto dependencies on columns.)
2299  */
2300  if (deprec->classid == RelationRelationId &&
2301  deprec->objsubid == 0 &&
2302  deprec->deptype == DEPENDENCY_AUTO &&
2303  get_rel_relkind(deprec->objid) == RELKIND_SEQUENCE)
2304  {
2305  sequenceId = deprec->objid;
2306  break;
2307  }
2308  }
2309 
2310  systable_endscan(scan);
2311  heap_close(depRel, AccessShareLock);
2312 
2313  if (OidIsValid(sequenceId))
2314  {
2315  char *result;
2316 
2317  result = generate_qualified_relation_name(sequenceId);
2318 
2320  }
2321 
2322  PG_RETURN_NULL();
2323 }
2324 
2325 
2326 /*
2327  * pg_get_functiondef
2328  * Returns the complete "CREATE OR REPLACE FUNCTION ..." statement for
2329  * the specified function.
2330  *
2331  * Note: if you change the output format of this function, be careful not
2332  * to break psql's rules (in \ef and \sf) for identifying the start of the
2333  * function body. To wit: the function body starts on a line that begins
2334  * with "AS ", and no preceding line will look like that.
2335  */
2336 Datum
2338 {
2339  Oid funcid = PG_GETARG_OID(0);
2341  StringInfoData dq;
2342  HeapTuple proctup;
2343  Form_pg_proc proc;
2344  Datum tmp;
2345  bool isnull;
2346  const char *prosrc;
2347  const char *name;
2348  const char *nsp;
2349  float4 procost;
2350  int oldlen;
2351 
2352  initStringInfo(&buf);
2353 
2354  /* Look up the function */
2355  proctup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
2356  if (!HeapTupleIsValid(proctup))
2357  PG_RETURN_NULL();
2358 
2359  proc = (Form_pg_proc) GETSTRUCT(proctup);
2360  name = NameStr(proc->proname);
2361 
2362  if (proc->proisagg)
2363  ereport(ERROR,
2364  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2365  errmsg("\"%s\" is an aggregate function", name)));
2366 
2367  /*
2368  * We always qualify the function name, to ensure the right function gets
2369  * replaced.
2370  */
2371  nsp = get_namespace_name(proc->pronamespace);
2372  appendStringInfo(&buf, "CREATE OR REPLACE FUNCTION %s(",
2373  quote_qualified_identifier(nsp, name));
2374  (void) print_function_arguments(&buf, proctup, false, true);
2375  appendStringInfoString(&buf, ")\n RETURNS ");
2376  print_function_rettype(&buf, proctup);
2377 
2378  print_function_trftypes(&buf, proctup);
2379 
2380  appendStringInfo(&buf, "\n LANGUAGE %s\n",
2381  quote_identifier(get_language_name(proc->prolang, false)));
2382 
2383  /* Emit some miscellaneous options on one line */
2384  oldlen = buf.len;
2385 
2386  if (proc->proiswindow)
2387  appendStringInfoString(&buf, " WINDOW");
2388  switch (proc->provolatile)
2389  {
2390  case PROVOLATILE_IMMUTABLE:
2391  appendStringInfoString(&buf, " IMMUTABLE");
2392  break;
2393  case PROVOLATILE_STABLE:
2394  appendStringInfoString(&buf, " STABLE");
2395  break;
2396  case PROVOLATILE_VOLATILE:
2397  break;
2398  }
2399 
2400  switch (proc->proparallel)
2401  {
2402  case PROPARALLEL_SAFE:
2403  appendStringInfoString(&buf, " PARALLEL SAFE");
2404  break;
2406  appendStringInfoString(&buf, " PARALLEL RESTRICTED");
2407  break;
2408  case PROPARALLEL_UNSAFE:
2409  break;
2410  }
2411 
2412  if (proc->proisstrict)
2413  appendStringInfoString(&buf, " STRICT");
2414  if (proc->prosecdef)
2415  appendStringInfoString(&buf, " SECURITY DEFINER");
2416  if (proc->proleakproof)
2417  appendStringInfoString(&buf, " LEAKPROOF");
2418 
2419  /* This code for the default cost and rows should match functioncmds.c */
2420  if (proc->prolang == INTERNALlanguageId ||
2421  proc->prolang == ClanguageId)
2422  procost = 1;
2423  else
2424  procost = 100;
2425  if (proc->procost != procost)
2426  appendStringInfo(&buf, " COST %g", proc->procost);
2427 
2428  if (proc->prorows > 0 && proc->prorows != 1000)
2429  appendStringInfo(&buf, " ROWS %g", proc->prorows);
2430 
2431  if (oldlen != buf.len)
2432  appendStringInfoChar(&buf, '\n');
2433 
2434  /* Emit any proconfig options, one per line */
2435  tmp = SysCacheGetAttr(PROCOID, proctup, Anum_pg_proc_proconfig, &isnull);
2436  if (!isnull)
2437  {
2438  ArrayType *a = DatumGetArrayTypeP(tmp);
2439  int i;
2440 
2441  Assert(ARR_ELEMTYPE(a) == TEXTOID);
2442  Assert(ARR_NDIM(a) == 1);
2443  Assert(ARR_LBOUND(a)[0] == 1);
2444 
2445  for (i = 1; i <= ARR_DIMS(a)[0]; i++)
2446  {
2447  Datum d;
2448 
2449  d = array_ref(a, 1, &i,
2450  -1 /* varlenarray */ ,
2451  -1 /* TEXT's typlen */ ,
2452  false /* TEXT's typbyval */ ,
2453  'i' /* TEXT's typalign */ ,
2454  &isnull);
2455  if (!isnull)
2456  {
2457  char *configitem = TextDatumGetCString(d);
2458  char *pos;
2459 
2460  pos = strchr(configitem, '=');
2461  if (pos == NULL)
2462  continue;
2463  *pos++ = '\0';
2464 
2465  appendStringInfo(&buf, " SET %s TO ",
2466  quote_identifier(configitem));
2467 
2468  /*
2469  * Some GUC variable names are 'LIST' type and hence must not
2470  * be quoted.
2471  */
2472  if (pg_strcasecmp(configitem, "DateStyle") == 0
2473  || pg_strcasecmp(configitem, "search_path") == 0)
2474  appendStringInfoString(&buf, pos);
2475  else
2476  simple_quote_literal(&buf, pos);
2477  appendStringInfoChar(&buf, '\n');
2478  }
2479  }
2480  }
2481 
2482  /* And finally the function definition ... */
2483  appendStringInfoString(&buf, "AS ");
2484 
2485  tmp = SysCacheGetAttr(PROCOID, proctup, Anum_pg_proc_probin, &isnull);
2486  if (!isnull)
2487  {
2489  appendStringInfoString(&buf, ", "); /* assume prosrc isn't null */
2490  }
2491 
2492  tmp = SysCacheGetAttr(PROCOID, proctup, Anum_pg_proc_prosrc, &isnull);
2493  if (isnull)
2494  elog(ERROR, "null prosrc");
2495  prosrc = TextDatumGetCString(tmp);
2496 
2497  /*
2498  * We always use dollar quoting. Figure out a suitable delimiter.
2499  *
2500  * Since the user is likely to be editing the function body string, we
2501  * shouldn't use a short delimiter that he might easily create a conflict
2502  * with. Hence prefer "$function$", but extend if needed.
2503  */
2504  initStringInfo(&dq);
2505  appendStringInfoString(&dq, "$function");
2506  while (strstr(prosrc, dq.data) != NULL)
2507  appendStringInfoChar(&dq, 'x');
2508  appendStringInfoChar(&dq, '$');
2509 
2510  appendStringInfoString(&buf, dq.data);
2511  appendStringInfoString(&buf, prosrc);
2512  appendStringInfoString(&buf, dq.data);
2513 
2514  appendStringInfoChar(&buf, '\n');
2515 
2516  ReleaseSysCache(proctup);
2517 
2519 }
2520 
2521 /*
2522  * pg_get_function_arguments
2523  * Get a nicely-formatted list of arguments for a function.
2524  * This is everything that would go between the parentheses in
2525  * CREATE FUNCTION.
2526  */
2527 Datum
2529 {
2530  Oid funcid = PG_GETARG_OID(0);
2532  HeapTuple proctup;
2533 
2534  proctup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
2535  if (!HeapTupleIsValid(proctup))
2536  PG_RETURN_NULL();
2537 
2538  initStringInfo(&buf);
2539 
2540  (void) print_function_arguments(&buf, proctup, false, true);
2541 
2542  ReleaseSysCache(proctup);
2543 
2545 }
2546 
2547 /*
2548  * pg_get_function_identity_arguments
2549  * Get a formatted list of arguments for a function.
2550  * This is everything that would go between the parentheses in
2551  * ALTER FUNCTION, etc. In particular, don't print defaults.
2552  */
2553 Datum
2555 {
2556  Oid funcid = PG_GETARG_OID(0);
2558  HeapTuple proctup;
2559 
2560  proctup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
2561  if (!HeapTupleIsValid(proctup))
2562  PG_RETURN_NULL();
2563 
2564  initStringInfo(&buf);
2565 
2566  (void) print_function_arguments(&buf, proctup, false, false);
2567 
2568  ReleaseSysCache(proctup);
2569 
2571 }
2572 
2573 /*
2574  * pg_get_function_result
2575  * Get a nicely-formatted version of the result type of a function.
2576  * This is what would appear after RETURNS in CREATE FUNCTION.
2577  */
2578 Datum
2580 {
2581  Oid funcid = PG_GETARG_OID(0);
2583  HeapTuple proctup;
2584 
2585  proctup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
2586  if (!HeapTupleIsValid(proctup))
2587  PG_RETURN_NULL();
2588 
2589  initStringInfo(&buf);
2590 
2591  print_function_rettype(&buf, proctup);
2592 
2593  ReleaseSysCache(proctup);
2594 
2596 }
2597 
2598 /*
2599  * Guts of pg_get_function_result: append the function's return type
2600  * to the specified buffer.
2601  */
2602 static void
2604 {
2605  Form_pg_proc proc = (Form_pg_proc) GETSTRUCT(proctup);
2606  int ntabargs = 0;
2607  StringInfoData rbuf;
2608 
2609  initStringInfo(&rbuf);
2610 
2611  if (proc->proretset)
2612  {
2613  /* It might be a table function; try to print the arguments */
2614  appendStringInfoString(&rbuf, "TABLE(");
2615  ntabargs = print_function_arguments(&rbuf, proctup, true, false);
2616  if (ntabargs > 0)
2617  appendStringInfoChar(&rbuf, ')');
2618  else
2619  resetStringInfo(&rbuf);
2620  }
2621 
2622  if (ntabargs == 0)
2623  {
2624  /* Not a table function, so do the normal thing */
2625  if (proc->proretset)
2626  appendStringInfoString(&rbuf, "SETOF ");
2627  appendStringInfoString(&rbuf, format_type_be(proc->prorettype));
2628  }
2629 
2630  appendStringInfoString(buf, rbuf.data);
2631 }
2632 
2633 /*
2634  * Common code for pg_get_function_arguments and pg_get_function_result:
2635  * append the desired subset of arguments to buf. We print only TABLE
2636  * arguments when print_table_args is true, and all the others when it's false.
2637  * We print argument defaults only if print_defaults is true.
2638  * Function return value is the number of arguments printed.
2639  */
2640 static int
2642  bool print_table_args, bool print_defaults)
2643 {
2644  Form_pg_proc proc = (Form_pg_proc) GETSTRUCT(proctup);
2645  int numargs;
2646  Oid *argtypes;
2647  char **argnames;
2648  char *argmodes;
2649  int insertorderbyat = -1;
2650  int argsprinted;
2651  int inputargno;
2652  int nlackdefaults;
2653  ListCell *nextargdefault = NULL;
2654  int i;
2655 
2656  numargs = get_func_arg_info(proctup,
2657  &argtypes, &argnames, &argmodes);
2658 
2659  nlackdefaults = numargs;
2660  if (print_defaults && proc->pronargdefaults > 0)
2661  {
2662  Datum proargdefaults;
2663  bool isnull;
2664 
2665  proargdefaults = SysCacheGetAttr(PROCOID, proctup,
2667  &isnull);
2668  if (!isnull)
2669  {
2670  char *str;
2671  List *argdefaults;
2672 
2673  str = TextDatumGetCString(proargdefaults);
2674  argdefaults = castNode(List, stringToNode(str));
2675  pfree(str);
2676  nextargdefault = list_head(argdefaults);
2677  /* nlackdefaults counts only *input* arguments lacking defaults */
2678  nlackdefaults = proc->pronargs - list_length(argdefaults);
2679  }
2680  }
2681 
2682  /* Check for special treatment of ordered-set aggregates */
2683  if (proc->proisagg)
2684  {
2685  HeapTuple aggtup;
2686  Form_pg_aggregate agg;
2687 
2688  aggtup = SearchSysCache1(AGGFNOID,
2689  ObjectIdGetDatum(HeapTupleGetOid(proctup)));
2690  if (!HeapTupleIsValid(aggtup))
2691  elog(ERROR, "cache lookup failed for aggregate %u",
2692  HeapTupleGetOid(proctup));
2693  agg = (Form_pg_aggregate) GETSTRUCT(aggtup);
2694  if (AGGKIND_IS_ORDERED_SET(agg->aggkind))
2695  insertorderbyat = agg->aggnumdirectargs;
2696  ReleaseSysCache(aggtup);
2697  }
2698 
2699  argsprinted = 0;
2700  inputargno = 0;
2701  for (i = 0; i < numargs; i++)
2702  {
2703  Oid argtype = argtypes[i];
2704  char *argname = argnames ? argnames[i] : NULL;
2705  char argmode = argmodes ? argmodes[i] : PROARGMODE_IN;
2706  const char *modename;
2707  bool isinput;
2708 
2709  switch (argmode)
2710  {
2711  case PROARGMODE_IN:
2712  modename = "";
2713  isinput = true;
2714  break;
2715  case PROARGMODE_INOUT:
2716  modename = "INOUT ";
2717  isinput = true;
2718  break;
2719  case PROARGMODE_OUT:
2720  modename = "OUT ";
2721  isinput = false;
2722  break;
2723  case PROARGMODE_VARIADIC:
2724  modename = "VARIADIC ";
2725  isinput = true;
2726  break;
2727  case PROARGMODE_TABLE:
2728  modename = "";
2729  isinput = false;
2730  break;
2731  default:
2732  elog(ERROR, "invalid parameter mode '%c'", argmode);
2733  modename = NULL; /* keep compiler quiet */
2734  isinput = false;
2735  break;
2736  }
2737  if (isinput)
2738  inputargno++; /* this is a 1-based counter */
2739 
2740  if (print_table_args != (argmode == PROARGMODE_TABLE))
2741  continue;
2742 
2743  if (argsprinted == insertorderbyat)
2744  {
2745  if (argsprinted)
2746  appendStringInfoChar(buf, ' ');
2747  appendStringInfoString(buf, "ORDER BY ");
2748  }
2749  else if (argsprinted)
2750  appendStringInfoString(buf, ", ");
2751 
2752  appendStringInfoString(buf, modename);
2753  if (argname && argname[0])
2754  appendStringInfo(buf, "%s ", quote_identifier(argname));
2755  appendStringInfoString(buf, format_type_be(argtype));
2756  if (print_defaults && isinput && inputargno > nlackdefaults)
2757  {
2758  Node *expr;
2759 
2760  Assert(nextargdefault != NULL);
2761  expr = (Node *) lfirst(nextargdefault);
2762  nextargdefault = lnext(nextargdefault);
2763 
2764  appendStringInfo(buf, " DEFAULT %s",
2765  deparse_expression(expr, NIL, false, false));
2766  }
2767  argsprinted++;
2768 
2769  /* nasty hack: print the last arg twice for variadic ordered-set agg */
2770  if (argsprinted == insertorderbyat && i == numargs - 1)
2771  {
2772  i--;
2773  /* aggs shouldn't have defaults anyway, but just to be sure ... */
2774  print_defaults = false;
2775  }
2776  }
2777 
2778  return argsprinted;
2779 }
2780 
2781 static bool
2782 is_input_argument(int nth, const char *argmodes)
2783 {
2784  return (!argmodes
2785  || argmodes[nth] == PROARGMODE_IN
2786  || argmodes[nth] == PROARGMODE_INOUT
2787  || argmodes[nth] == PROARGMODE_VARIADIC);
2788 }
2789 
2790 /*
2791  * Append used transformed types to specified buffer
2792  */
2793 static void
2795 {
2796  Oid *trftypes;
2797  int ntypes;
2798 
2799  ntypes = get_func_trftypes(proctup, &trftypes);
2800  if (ntypes > 0)
2801  {
2802  int i;
2803 
2804  appendStringInfoString(buf, "\n TRANSFORM ");
2805  for (i = 0; i < ntypes; i++)
2806  {
2807  if (i != 0)
2808  appendStringInfoString(buf, ", ");
2809  appendStringInfo(buf, "FOR TYPE %s", format_type_be(trftypes[i]));
2810  }
2811  }
2812 }
2813 
2814 /*
2815  * Get textual representation of a function argument's default value. The
2816  * second argument of this function is the argument number among all arguments
2817  * (i.e. proallargtypes, *not* proargtypes), starting with 1, because that's
2818  * how information_schema.sql uses it.
2819  */
2820 Datum
2822 {
2823  Oid funcid = PG_GETARG_OID(0);
2824  int32 nth_arg = PG_GETARG_INT32(1);
2825  HeapTuple proctup;
2826  Form_pg_proc proc;
2827  int numargs;
2828  Oid *argtypes;
2829  char **argnames;
2830  char *argmodes;
2831  int i;
2832  List *argdefaults;
2833  Node *node;
2834  char *str;
2835  int nth_inputarg;
2836  Datum proargdefaults;
2837  bool isnull;
2838  int nth_default;
2839 
2840  proctup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
2841  if (!HeapTupleIsValid(proctup))
2842  PG_RETURN_NULL();
2843 
2844  numargs = get_func_arg_info(proctup, &argtypes, &argnames, &argmodes);
2845  if (nth_arg < 1 || nth_arg > numargs || !is_input_argument(nth_arg - 1, argmodes))
2846  {
2847  ReleaseSysCache(proctup);
2848  PG_RETURN_NULL();
2849  }
2850 
2851  nth_inputarg = 0;
2852  for (i = 0; i < nth_arg; i++)
2853  if (is_input_argument(i, argmodes))
2854  nth_inputarg++;
2855 
2856  proargdefaults = SysCacheGetAttr(PROCOID, proctup,
2858  &isnull);
2859  if (isnull)
2860  {
2861  ReleaseSysCache(proctup);
2862  PG_RETURN_NULL();
2863  }
2864 
2865  str = TextDatumGetCString(proargdefaults);
2866  argdefaults = castNode(List, stringToNode(str));
2867  pfree(str);
2868 
2869  proc = (Form_pg_proc) GETSTRUCT(proctup);
2870 
2871  /*
2872  * Calculate index into proargdefaults: proargdefaults corresponds to the
2873  * last N input arguments, where N = pronargdefaults.
2874  */
2875  nth_default = nth_inputarg - 1 - (proc->pronargs - proc->pronargdefaults);
2876 
2877  if (nth_default < 0 || nth_default >= list_length(argdefaults))
2878  {
2879  ReleaseSysCache(proctup);
2880  PG_RETURN_NULL();
2881  }
2882  node = list_nth(argdefaults, nth_default);
2883  str = deparse_expression(node, NIL, false, false);
2884 
2885  ReleaseSysCache(proctup);
2886 
2888 }
2889 
2890 
2891 /*
2892  * deparse_expression - General utility for deparsing expressions
2893  *
2894  * calls deparse_expression_pretty with all prettyPrinting disabled
2895  */
2896 char *
2897 deparse_expression(Node *expr, List *dpcontext,
2898  bool forceprefix, bool showimplicit)
2899 {
2900  return deparse_expression_pretty(expr, dpcontext, forceprefix,
2901  showimplicit, 0, 0);
2902 }
2903 
2904 /* ----------
2905  * deparse_expression_pretty - General utility for deparsing expressions
2906  *
2907  * expr is the node tree to be deparsed. It must be a transformed expression
2908  * tree (ie, not the raw output of gram.y).
2909  *
2910  * dpcontext is a list of deparse_namespace nodes representing the context
2911  * for interpreting Vars in the node tree. It can be NIL if no Vars are
2912  * expected.
2913  *
2914  * forceprefix is TRUE to force all Vars to be prefixed with their table names.
2915  *
2916  * showimplicit is TRUE to force all implicit casts to be shown explicitly.
2917  *
2918  * Tries to pretty up the output according to prettyFlags and startIndent.
2919  *
2920  * The result is a palloc'd string.
2921  * ----------
2922  */
2923 static char *
2925  bool forceprefix, bool showimplicit,
2926  int prettyFlags, int startIndent)
2927 {
2929  deparse_context context;
2930 
2931  initStringInfo(&buf);
2932  context.buf = &buf;
2933  context.namespaces = dpcontext;
2934  context.windowClause = NIL;
2935  context.windowTList = NIL;
2936  context.varprefix = forceprefix;
2937  context.prettyFlags = prettyFlags;
2938  context.wrapColumn = WRAP_COLUMN_DEFAULT;
2939  context.indentLevel = startIndent;
2940  context.special_exprkind = EXPR_KIND_NONE;
2941 
2942  get_rule_expr(expr, &context, showimplicit);
2943 
2944  return buf.data;
2945 }
2946 
2947 /* ----------
2948  * deparse_context_for - Build deparse context for a single relation
2949  *
2950  * Given the reference name (alias) and OID of a relation, build deparsing
2951  * context for an expression referencing only that relation (as varno 1,
2952  * varlevelsup 0). This is sufficient for many uses of deparse_expression.
2953  * ----------
2954  */
2955 List *
2956 deparse_context_for(const char *aliasname, Oid relid)
2957 {
2958  deparse_namespace *dpns;
2959  RangeTblEntry *rte;
2960 
2961  dpns = (deparse_namespace *) palloc0(sizeof(deparse_namespace));
2962 
2963  /* Build a minimal RTE for the rel */
2964  rte = makeNode(RangeTblEntry);
2965  rte->rtekind = RTE_RELATION;
2966  rte->relid = relid;
2967  rte->relkind = RELKIND_RELATION; /* no need for exactness here */
2968  rte->alias = makeAlias(aliasname, NIL);
2969  rte->eref = rte->alias;
2970  rte->lateral = false;
2971  rte->inh = false;
2972  rte->inFromCl = true;
2973 
2974  /* Build one-element rtable */
2975  dpns->rtable = list_make1(rte);
2976  dpns->ctes = NIL;
2977  set_rtable_names(dpns, NIL, NULL);
2979 
2980  /* Return a one-deep namespace stack */
2981  return list_make1(dpns);
2982 }
2983 
2984 /*
2985  * deparse_context_for_plan_rtable - Build deparse context for a plan's rtable
2986  *
2987  * When deparsing an expression in a Plan tree, we use the plan's rangetable
2988  * to resolve names of simple Vars. The initialization of column names for
2989  * this is rather expensive if the rangetable is large, and it'll be the same
2990  * for every expression in the Plan tree; so we do it just once and re-use
2991  * the result of this function for each expression. (Note that the result
2992  * is not usable until set_deparse_context_planstate() is applied to it.)
2993  *
2994  * In addition to the plan's rangetable list, pass the per-RTE alias names
2995  * assigned by a previous call to select_rtable_names_for_explain.
2996  */
2997 List *
2999 {
3000  deparse_namespace *dpns;
3001 
3002  dpns = (deparse_namespace *) palloc0(sizeof(deparse_namespace));
3003 
3004  /* Initialize fields that stay the same across the whole plan tree */
3005  dpns->rtable = rtable;
3006  dpns->rtable_names = rtable_names;
3007  dpns->ctes = NIL;
3008 
3009  /*
3010  * Set up column name aliases. We will get rather bogus results for join
3011  * RTEs, but that doesn't matter because plan trees don't contain any join
3012  * alias Vars.
3013  */
3015 
3016  /* Return a one-deep namespace stack */
3017  return list_make1(dpns);
3018 }
3019 
3020 /*
3021  * set_deparse_context_planstate - Specify Plan node containing expression
3022  *
3023  * When deparsing an expression in a Plan tree, we might have to resolve
3024  * OUTER_VAR, INNER_VAR, or INDEX_VAR references. To do this, the caller must
3025  * provide the parent PlanState node. Then OUTER_VAR and INNER_VAR references
3026  * can be resolved by drilling down into the left and right child plans.
3027  * Similarly, INDEX_VAR references can be resolved by reference to the
3028  * indextlist given in a parent IndexOnlyScan node, or to the scan tlist in
3029  * ForeignScan and CustomScan nodes. (Note that we don't currently support
3030  * deparsing of indexquals in regular IndexScan or BitmapIndexScan nodes;
3031  * for those, we can only deparse the indexqualorig fields, which won't
3032  * contain INDEX_VAR Vars.)
3033  *
3034  * Note: planstate really ought to be declared as "PlanState *", but we use
3035  * "Node *" to avoid having to include execnodes.h in ruleutils.h.
3036  *
3037  * The ancestors list is a list of the PlanState's parent PlanStates, the
3038  * most-closely-nested first. This is needed to resolve PARAM_EXEC Params.
3039  * Note we assume that all the PlanStates share the same rtable.
3040  *
3041  * Once this function has been called, deparse_expression() can be called on
3042  * subsidiary expression(s) of the specified PlanState node. To deparse
3043  * expressions of a different Plan node in the same Plan tree, re-call this
3044  * function to identify the new parent Plan node.
3045  *
3046  * The result is the same List passed in; this is a notational convenience.
3047  */
3048 List *
3050  Node *planstate, List *ancestors)
3051 {
3052  deparse_namespace *dpns;
3053 
3054  /* Should always have one-entry namespace list for Plan deparsing */
3055  Assert(list_length(dpcontext) == 1);
3056  dpns = (deparse_namespace *) linitial(dpcontext);
3057 
3058  /* Set our attention on the specific plan node passed in */
3059  set_deparse_planstate(dpns, (PlanState *) planstate);
3060  dpns->ancestors = ancestors;
3061 
3062  return dpcontext;
3063 }
3064 
3065 /*
3066  * select_rtable_names_for_explain - Select RTE aliases for EXPLAIN
3067  *
3068  * Determine the relation aliases we'll use during an EXPLAIN operation.
3069  * This is just a frontend to set_rtable_names. We have to expose the aliases
3070  * to EXPLAIN because EXPLAIN needs to know the right alias names to print.
3071  */
3072 List *
3074 {
3075  deparse_namespace dpns;
3076 
3077  memset(&dpns, 0, sizeof(dpns));
3078  dpns.rtable = rtable;
3079  dpns.ctes = NIL;
3080  set_rtable_names(&dpns, NIL, rels_used);
3081  /* We needn't bother computing column aliases yet */
3082 
3083  return dpns.rtable_names;
3084 }
3085 
3086 /*
3087  * set_rtable_names: select RTE aliases to be used in printing a query
3088  *
3089  * We fill in dpns->rtable_names with a list of names that is one-for-one with
3090  * the already-filled dpns->rtable list. Each RTE name is unique among those
3091  * in the new namespace plus any ancestor namespaces listed in
3092  * parent_namespaces.
3093  *
3094  * If rels_used isn't NULL, only RTE indexes listed in it are given aliases.
3095  *
3096  * Note that this function is only concerned with relation names, not column
3097  * names.
3098  */
3099 static void
3100 set_rtable_names(deparse_namespace *dpns, List *parent_namespaces,
3101  Bitmapset *rels_used)
3102 {
3103  HASHCTL hash_ctl;
3104  HTAB *names_hash;
3105  NameHashEntry *hentry;
3106  bool found;
3107  int rtindex;
3108  ListCell *lc;
3109 
3110  dpns->rtable_names = NIL;
3111  /* nothing more to do if empty rtable */
3112  if (dpns->rtable == NIL)
3113  return;
3114 
3115  /*
3116  * We use a hash table to hold known names, so that this process is O(N)
3117  * not O(N^2) for N names.
3118  */
3119  MemSet(&hash_ctl, 0, sizeof(hash_ctl));
3120  hash_ctl.keysize = NAMEDATALEN;
3121  hash_ctl.entrysize = sizeof(NameHashEntry);
3122  hash_ctl.hcxt = CurrentMemoryContext;
3123  names_hash = hash_create("set_rtable_names names",
3124  list_length(dpns->rtable),
3125  &hash_ctl,
3127  /* Preload the hash table with names appearing in parent_namespaces */
3128  foreach(lc, parent_namespaces)
3129  {
3130  deparse_namespace *olddpns = (deparse_namespace *) lfirst(lc);
3131  ListCell *lc2;
3132 
3133  foreach(lc2, olddpns->rtable_names)
3134  {
3135  char *oldname = (char *) lfirst(lc2);
3136 
3137  if (oldname == NULL)
3138  continue;
3139  hentry = (NameHashEntry *) hash_search(names_hash,
3140  oldname,
3141  HASH_ENTER,
3142  &found);
3143  /* we do not complain about duplicate names in parent namespaces */
3144  hentry->counter = 0;
3145  }
3146  }
3147 
3148  /* Now we can scan the rtable */
3149  rtindex = 1;
3150  foreach(lc, dpns->rtable)
3151  {
3152  RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc);
3153  char *refname;
3154 
3155  /* Just in case this takes an unreasonable amount of time ... */
3157 
3158  if (rels_used && !bms_is_member(rtindex, rels_used))
3159  {
3160  /* Ignore unreferenced RTE */
3161  refname = NULL;
3162  }
3163  else if (rte->alias)
3164  {
3165  /* If RTE has a user-defined alias, prefer that */
3166  refname = rte->alias->aliasname;
3167  }
3168  else if (rte->rtekind == RTE_RELATION)
3169  {
3170  /* Use the current actual name of the relation */
3171  refname = get_rel_name(rte->relid);
3172  }
3173  else if (rte->rtekind == RTE_JOIN)
3174  {
3175  /* Unnamed join has no refname */
3176  refname = NULL;
3177  }
3178  else
3179  {
3180  /* Otherwise use whatever the parser assigned */
3181  refname = rte->eref->aliasname;
3182  }
3183 
3184  /*
3185  * If the selected name isn't unique, append digits to make it so, and
3186  * make a new hash entry for it once we've got a unique name. For a
3187  * very long input name, we might have to truncate to stay within
3188  * NAMEDATALEN.
3189  */
3190  if (refname)
3191  {
3192  hentry = (NameHashEntry *) hash_search(names_hash,
3193  refname,
3194  HASH_ENTER,
3195  &found);
3196  if (found)
3197  {
3198  /* Name already in use, must choose a new one */
3199  int refnamelen = strlen(refname);
3200  char *modname = (char *) palloc(refnamelen + 16);
3201  NameHashEntry *hentry2;
3202 
3203  do
3204  {
3205  hentry->counter++;
3206  for (;;)
3207  {
3208  /*
3209  * We avoid using %.*s here because it can misbehave
3210  * if the data is not valid in what libc thinks is the
3211  * prevailing encoding.
3212  */
3213  memcpy(modname, refname, refnamelen);
3214  sprintf(modname + refnamelen, "_%d", hentry->counter);
3215  if (strlen(modname) < NAMEDATALEN)
3216  break;
3217  /* drop chars from refname to keep all the digits */
3218  refnamelen = pg_mbcliplen(refname, refnamelen,
3219  refnamelen - 1);
3220  }
3221  hentry2 = (NameHashEntry *) hash_search(names_hash,
3222  modname,
3223  HASH_ENTER,
3224  &found);
3225  } while (found);
3226  hentry2->counter = 0; /* init new hash entry */
3227  refname = modname;
3228  }
3229  else
3230  {
3231  /* Name not previously used, need only initialize hentry */
3232  hentry->counter = 0;
3233  }
3234  }
3235 
3236  dpns->rtable_names = lappend(dpns->rtable_names, refname);
3237  rtindex++;
3238  }
3239 
3240  hash_destroy(names_hash);
3241 }
3242 
3243 /*
3244  * set_deparse_for_query: set up deparse_namespace for deparsing a Query tree
3245  *
3246  * For convenience, this is defined to initialize the deparse_namespace struct
3247  * from scratch.
3248  */
3249 static void
3251  List *parent_namespaces)
3252 {
3253  ListCell *lc;
3254  ListCell *lc2;
3255 
3256  /* Initialize *dpns and fill rtable/ctes links */
3257  memset(dpns, 0, sizeof(deparse_namespace));
3258  dpns->rtable = query->rtable;
3259  dpns->ctes = query->cteList;
3260 
3261  /* Assign a unique relation alias to each RTE */
3262  set_rtable_names(dpns, parent_namespaces, NULL);
3263 
3264  /* Initialize dpns->rtable_columns to contain zeroed structs */
3265  dpns->rtable_columns = NIL;
3266  while (list_length(dpns->rtable_columns) < list_length(dpns->rtable))
3267  dpns->rtable_columns = lappend(dpns->rtable_columns,
3268  palloc0(sizeof(deparse_columns)));
3269 
3270  /* If it's a utility query, it won't have a jointree */
3271  if (query->jointree)
3272  {
3273  /* Detect whether global uniqueness of USING names is needed */
3274  dpns->unique_using =
3275  has_dangerous_join_using(dpns, (Node *) query->jointree);
3276 
3277  /*
3278  * Select names for columns merged by USING, via a recursive pass over
3279  * the query jointree.
3280  */
3281  set_using_names(dpns, (Node *) query->jointree, NIL);
3282  }
3283 
3284  /*
3285  * Now assign remaining column aliases for each RTE. We do this in a
3286  * linear scan of the rtable, so as to process RTEs whether or not they
3287  * are in the jointree (we mustn't miss NEW.*, INSERT target relations,
3288  * etc). JOIN RTEs must be processed after their children, but this is
3289  * okay because they appear later in the rtable list than their children
3290  * (cf Asserts in identify_join_columns()).
3291  */
3292  forboth(lc, dpns->rtable, lc2, dpns->rtable_columns)
3293  {
3294  RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc);
3295  deparse_columns *colinfo = (deparse_columns *) lfirst(lc2);
3296 
3297  if (rte->rtekind == RTE_JOIN)
3298  set_join_column_names(dpns, rte, colinfo);
3299  else
3300  set_relation_column_names(dpns, rte, colinfo);
3301  }
3302 }
3303 
3304 /*
3305  * set_simple_column_names: fill in column aliases for non-query situations
3306  *
3307  * This handles EXPLAIN and cases where we only have relation RTEs. Without
3308  * a join tree, we can't do anything smart about join RTEs, but we don't
3309  * need to (note that EXPLAIN should never see join alias Vars anyway).
3310  * If we do hit a join RTE we'll just process it like a non-table base RTE.
3311  */
3312 static void
3314 {
3315  ListCell *lc;
3316  ListCell *lc2;
3317 
3318  /* Initialize dpns->rtable_columns to contain zeroed structs */
3319  dpns->rtable_columns = NIL;
3320  while (list_length(dpns->rtable_columns) < list_length(dpns->rtable))
3321  dpns->rtable_columns = lappend(dpns->rtable_columns,
3322  palloc0(sizeof(deparse_columns)));
3323 
3324  /* Assign unique column aliases within each RTE */
3325  forboth(lc, dpns->rtable, lc2, dpns->rtable_columns)
3326  {
3327  RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc);
3328  deparse_columns *colinfo = (deparse_columns *) lfirst(lc2);
3329 
3330  set_relation_column_names(dpns, rte, colinfo);
3331  }
3332 }
3333 
3334 /*
3335  * has_dangerous_join_using: search jointree for unnamed JOIN USING
3336  *
3337  * Merged columns of a JOIN USING may act differently from either of the input
3338  * columns, either because they are merged with COALESCE (in a FULL JOIN) or
3339  * because an implicit coercion of the underlying input column is required.
3340  * In such a case the column must be referenced as a column of the JOIN not as
3341  * a column of either input. And this is problematic if the join is unnamed
3342  * (alias-less): we cannot qualify the column's name with an RTE name, since
3343  * there is none. (Forcibly assigning an alias to the join is not a solution,
3344  * since that will prevent legal references to tables below the join.)
3345  * To ensure that every column in the query is unambiguously referenceable,
3346  * we must assign such merged columns names that are globally unique across
3347  * the whole query, aliasing other columns out of the way as necessary.
3348  *
3349  * Because the ensuing re-aliasing is fairly damaging to the readability of
3350  * the query, we don't do this unless we have to. So, we must pre-scan
3351  * the join tree to see if we have to, before starting set_using_names().
3352  */
3353 static bool
3355 {
3356  if (IsA(jtnode, RangeTblRef))
3357  {
3358  /* nothing to do here */
3359  }
3360  else if (IsA(jtnode, FromExpr))
3361  {
3362  FromExpr *f = (FromExpr *) jtnode;
3363  ListCell *lc;
3364 
3365  foreach(lc, f->fromlist)
3366  {
3367  if (has_dangerous_join_using(dpns, (Node *) lfirst(lc)))
3368  return true;
3369  }
3370  }
3371  else if (IsA(jtnode, JoinExpr))
3372  {
3373  JoinExpr *j = (JoinExpr *) jtnode;
3374 
3375  /* Is it an unnamed JOIN with USING? */
3376  if (j->alias == NULL && j->usingClause)
3377  {
3378  /*
3379  * Yes, so check each join alias var to see if any of them are not
3380  * simple references to underlying columns. If so, we have a
3381  * dangerous situation and must pick unique aliases.
3382  */
3383  RangeTblEntry *jrte = rt_fetch(j->rtindex, dpns->rtable);
3384  ListCell *lc;
3385 
3386  foreach(lc, jrte->joinaliasvars)
3387  {
3388  Var *aliasvar = (Var *) lfirst(lc);
3389 
3390  if (aliasvar != NULL && !IsA(aliasvar, Var))
3391  return true;
3392  }
3393  }
3394 
3395  /* Nope, but inspect children */
3396  if (has_dangerous_join_using(dpns, j->larg))
3397  return true;
3398  if (has_dangerous_join_using(dpns, j->rarg))
3399  return true;
3400  }
3401  else
3402  elog(ERROR, "unrecognized node type: %d",
3403  (int) nodeTag(jtnode));
3404  return false;
3405 }
3406 
3407 /*
3408  * set_using_names: select column aliases to be used for merged USING columns
3409  *
3410  * We do this during a recursive descent of the query jointree.
3411  * dpns->unique_using must already be set to determine the global strategy.
3412  *
3413  * Column alias info is saved in the dpns->rtable_columns list, which is
3414  * assumed to be filled with pre-zeroed deparse_columns structs.
3415  *
3416  * parentUsing is a list of all USING aliases assigned in parent joins of
3417  * the current jointree node. (The passed-in list must not be modified.)
3418  */
3419 static void
3420 set_using_names(deparse_namespace *dpns, Node *jtnode, List *parentUsing)
3421 {
3422  if (IsA(jtnode, RangeTblRef))
3423  {
3424  /* nothing to do now */
3425  }
3426  else if (IsA(jtnode, FromExpr))
3427  {
3428  FromExpr *f = (FromExpr *) jtnode;
3429  ListCell *lc;
3430 
3431  foreach(lc, f->fromlist)
3432  set_using_names(dpns, (Node *) lfirst(lc), parentUsing);
3433  }
3434  else if (IsA(jtnode, JoinExpr))
3435  {
3436  JoinExpr *j = (JoinExpr *) jtnode;
3437  RangeTblEntry *rte = rt_fetch(j->rtindex, dpns->rtable);
3438  deparse_columns *colinfo = deparse_columns_fetch(j->rtindex, dpns);
3439  int *leftattnos;
3440  int *rightattnos;
3441  deparse_columns *leftcolinfo;
3442  deparse_columns *rightcolinfo;
3443  int i;
3444  ListCell *lc;
3445 
3446  /* Get info about the shape of the join */
3447  identify_join_columns(j, rte, colinfo);
3448  leftattnos = colinfo->leftattnos;
3449  rightattnos = colinfo->rightattnos;
3450 
3451  /* Look up the not-yet-filled-in child deparse_columns structs */
3452  leftcolinfo = deparse_columns_fetch(colinfo->leftrti, dpns);
3453  rightcolinfo = deparse_columns_fetch(colinfo->rightrti, dpns);
3454 
3455  /*
3456  * If this join is unnamed, then we cannot substitute new aliases at
3457  * this level, so any name requirements pushed down to here must be
3458  * pushed down again to the children.
3459  */
3460  if (rte->alias == NULL)
3461  {
3462  for (i = 0; i < colinfo->num_cols; i++)
3463  {
3464  char *colname = colinfo->colnames[i];
3465 
3466  if (colname == NULL)
3467  continue;
3468 
3469  /* Push down to left column, unless it's a system column */
3470  if (leftattnos[i] > 0)
3471  {
3472  expand_colnames_array_to(leftcolinfo, leftattnos[i]);
3473  leftcolinfo->colnames[leftattnos[i] - 1] = colname;
3474  }
3475 
3476  /* Same on the righthand side */
3477  if (rightattnos[i] > 0)
3478  {
3479  expand_colnames_array_to(rightcolinfo, rightattnos[i]);
3480  rightcolinfo->colnames[rightattnos[i] - 1] = colname;
3481  }
3482  }
3483  }
3484 
3485  /*
3486  * If there's a USING clause, select the USING column names and push
3487  * those names down to the children. We have two strategies:
3488  *
3489  * If dpns->unique_using is TRUE, we force all USING names to be
3490  * unique across the whole query level. In principle we'd only need
3491  * the names of dangerous USING columns to be globally unique, but to
3492  * safely assign all USING names in a single pass, we have to enforce
3493  * the same uniqueness rule for all of them. However, if a USING
3494  * column's name has been pushed down from the parent, we should use
3495  * it as-is rather than making a uniqueness adjustment. This is
3496  * necessary when we're at an unnamed join, and it creates no risk of
3497  * ambiguity. Also, if there's a user-written output alias for a
3498  * merged column, we prefer to use that rather than the input name;
3499  * this simplifies the logic and seems likely to lead to less aliasing
3500  * overall.
3501  *
3502  * If dpns->unique_using is FALSE, we only need USING names to be
3503  * unique within their own join RTE. We still need to honor
3504  * pushed-down names, though.
3505  *
3506  * Though significantly different in results, these two strategies are
3507  * implemented by the same code, with only the difference of whether
3508  * to put assigned names into dpns->using_names.
3509  */
3510  if (j->usingClause)
3511  {
3512  /* Copy the input parentUsing list so we don't modify it */
3513  parentUsing = list_copy(parentUsing);
3514 
3515  /* USING names must correspond to the first join output columns */
3517  i = 0;
3518  foreach(lc, j->usingClause)
3519  {
3520  char *colname = strVal(lfirst(lc));
3521 
3522  /* Assert it's a merged column */
3523  Assert(leftattnos[i] != 0 && rightattnos[i] != 0);
3524 
3525  /* Adopt passed-down name if any, else select unique name */
3526  if (colinfo->colnames[i] != NULL)
3527  colname = colinfo->colnames[i];
3528  else
3529  {
3530  /* Prefer user-written output alias if any */
3531  if (rte->alias && i < list_length(rte->alias->colnames))
3532  colname = strVal(list_nth(rte->alias->colnames, i));
3533  /* Make it appropriately unique */
3534  colname = make_colname_unique(colname, dpns, colinfo);
3535  if (dpns->unique_using)
3536  dpns->using_names = lappend(dpns->using_names,
3537  colname);
3538  /* Save it as output column name, too */
3539  colinfo->colnames[i] = colname;
3540  }
3541 
3542  /* Remember selected names for use later */
3543  colinfo->usingNames = lappend(colinfo->usingNames, colname);
3544  parentUsing = lappend(parentUsing, colname);
3545 
3546  /* Push down to left column, unless it's a system column */
3547  if (leftattnos[i] > 0)
3548  {
3549  expand_colnames_array_to(leftcolinfo, leftattnos[i]);
3550  leftcolinfo->colnames[leftattnos[i] - 1] = colname;
3551  }
3552 
3553  /* Same on the righthand side */
3554  if (rightattnos[i] > 0)
3555  {
3556  expand_colnames_array_to(rightcolinfo, rightattnos[i]);
3557  rightcolinfo->colnames[rightattnos[i] - 1] = colname;
3558  }
3559 
3560  i++;
3561  }
3562  }
3563 
3564  /* Mark child deparse_columns structs with correct parentUsing info */
3565  leftcolinfo->parentUsing = parentUsing;
3566  rightcolinfo->parentUsing = parentUsing;
3567 
3568  /* Now recursively assign USING column names in children */
3569  set_using_names(dpns, j->larg, parentUsing);
3570  set_using_names(dpns, j->rarg, parentUsing);
3571  }
3572  else
3573  elog(ERROR, "unrecognized node type: %d",
3574  (int) nodeTag(jtnode));
3575 }
3576 
3577 /*
3578  * set_relation_column_names: select column aliases for a non-join RTE
3579  *
3580  * Column alias info is saved in *colinfo, which is assumed to be pre-zeroed.
3581  * If any colnames entries are already filled in, those override local
3582  * choices.
3583  */
3584 static void
3586  deparse_columns *colinfo)
3587 {
3588  int ncolumns;
3589  char **real_colnames;
3590  bool changed_any;
3591  int noldcolumns;
3592  int i;
3593  int j;
3594 
3595  /*
3596  * Extract the RTE's "real" column names. This is comparable to
3597  * get_rte_attribute_name, except that it's important to disregard dropped
3598  * columns. We put NULL into the array for a dropped column.
3599  */
3600  if (rte->rtekind == RTE_RELATION)
3601  {
3602  /* Relation --- look to the system catalogs for up-to-date info */
3603  Relation rel;
3604  TupleDesc tupdesc;
3605 
3606  rel = relation_open(rte->relid, AccessShareLock);
3607  tupdesc = RelationGetDescr(rel);
3608 
3609  ncolumns = tupdesc->natts;
3610  real_colnames = (char **) palloc(ncolumns * sizeof(char *));
3611 
3612  for (i = 0; i < ncolumns; i++)
3613  {
3614  if (tupdesc->attrs[i]->attisdropped)
3615  real_colnames[i] = NULL;
3616  else
3617  real_colnames[i] = pstrdup(NameStr(tupdesc->attrs[i]->attname));
3618  }
3620  }
3621  else
3622  {
3623  /* Otherwise use the column names from eref */
3624  ListCell *lc;
3625 
3626  ncolumns = list_length(rte->eref->colnames);
3627  real_colnames = (char **) palloc(ncolumns * sizeof(char *));
3628 
3629  i = 0;
3630  foreach(lc, rte->eref->colnames)
3631  {
3632  /*
3633  * If the column name shown in eref is an empty string, then it's
3634  * a column that was dropped at the time of parsing the query, so
3635  * treat it as dropped.
3636  */
3637  char *cname = strVal(lfirst(lc));
3638 
3639  if (cname[0] == '\0')
3640  cname = NULL;
3641  real_colnames[i] = cname;
3642  i++;
3643  }
3644  }
3645 
3646  /*
3647  * Ensure colinfo->colnames has a slot for each column. (It could be long
3648  * enough already, if we pushed down a name for the last column.) Note:
3649  * it's possible that there are now more columns than there were when the
3650  * query was parsed, ie colnames could be longer than rte->eref->colnames.
3651  * We must assign unique aliases to the new columns too, else there could
3652  * be unresolved conflicts when the view/rule is reloaded.
3653  */
3654  expand_colnames_array_to(colinfo, ncolumns);
3655  Assert(colinfo->num_cols == ncolumns);
3656 
3657  /*
3658  * Make sufficiently large new_colnames and is_new_col arrays, too.
3659  *
3660  * Note: because we leave colinfo->num_new_cols zero until after the loop,
3661  * colname_is_unique will not consult that array, which is fine because it
3662  * would only be duplicate effort.
3663  */
3664  colinfo->new_colnames = (char **) palloc(ncolumns * sizeof(char *));
3665  colinfo->is_new_col = (bool *) palloc(ncolumns * sizeof(bool));
3666 
3667  /*
3668  * Scan the columns, select a unique alias for each one, and store it in
3669  * colinfo->colnames and colinfo->new_colnames. The former array has NULL
3670  * entries for dropped columns, the latter omits them. Also mark
3671  * new_colnames entries as to whether they are new since parse time; this
3672  * is the case for entries beyond the length of rte->eref->colnames.
3673  */
3674  noldcolumns = list_length(rte->eref->colnames);
3675  changed_any = false;
3676  j = 0;
3677  for (i = 0; i < ncolumns; i++)
3678  {
3679  char *real_colname = real_colnames[i];
3680  char *colname = colinfo->colnames[i];
3681 
3682  /* Skip dropped columns */
3683  if (real_colname == NULL)
3684  {
3685  Assert(colname == NULL); /* colnames[i] is already NULL */
3686  continue;
3687  }
3688 
3689  /* If alias already assigned, that's what to use */
3690  if (colname == NULL)
3691  {
3692  /* If user wrote an alias, prefer that over real column name */
3693  if (rte->alias && i < list_length(rte->alias->colnames))
3694  colname = strVal(list_nth(rte->alias->colnames, i));
3695  else
3696  colname = real_colname;
3697 
3698  /* Unique-ify and insert into colinfo */
3699  colname = make_colname_unique(colname, dpns, colinfo);
3700 
3701  colinfo->colnames[i] = colname;
3702  }
3703 
3704  /* Put names of non-dropped columns in new_colnames[] too */
3705  colinfo->new_colnames[j] = colname;
3706  /* And mark them as new or not */
3707  colinfo->is_new_col[j] = (i >= noldcolumns);
3708  j++;
3709 
3710  /* Remember if any assigned aliases differ from "real" name */
3711  if (!changed_any && strcmp(colname, real_colname) != 0)
3712  changed_any = true;
3713  }
3714 
3715  /*
3716  * Set correct length for new_colnames[] array. (Note: if columns have
3717  * been added, colinfo->num_cols includes them, which is not really quite
3718  * right but is harmless, since any new columns must be at the end where
3719  * they won't affect varattnos of pre-existing columns.)
3720  */
3721  colinfo->num_new_cols = j;
3722 
3723  /*
3724  * For a relation RTE, we need only print the alias column names if any
3725  * are different from the underlying "real" names. For a function RTE,
3726  * always emit a complete column alias list; this is to protect against
3727  * possible instability of the default column names (eg, from altering
3728  * parameter names). For tablefunc RTEs, we never print aliases, because
3729  * the column names are part of the clause itself. For other RTE types,
3730  * print if we changed anything OR if there were user-written column
3731  * aliases (since the latter would be part of the underlying "reality").
3732  */
3733  if (rte->rtekind == RTE_RELATION)
3734  colinfo->printaliases = changed_any;
3735  else if (rte->rtekind == RTE_FUNCTION)
3736  colinfo->printaliases = true;
3737  else if (rte->rtekind == RTE_TABLEFUNC)
3738  colinfo->printaliases = false;
3739  else if (rte->alias && rte->alias->colnames != NIL)
3740  colinfo->printaliases = true;
3741  else
3742  colinfo->printaliases = changed_any;
3743 }
3744 
3745 /*
3746  * set_join_column_names: select column aliases for a join RTE
3747  *
3748  * Column alias info is saved in *colinfo, which is assumed to be pre-zeroed.
3749  * If any colnames entries are already filled in, those override local
3750  * choices. Also, names for USING columns were already chosen by
3751  * set_using_names(). We further expect that column alias selection has been
3752  * completed for both input RTEs.
3753  */
3754 static void
3756  deparse_columns *colinfo)
3757 {
3758  deparse_columns *leftcolinfo;
3759  deparse_columns *rightcolinfo;
3760  bool changed_any;
3761  int noldcolumns;
3762  int nnewcolumns;
3763  Bitmapset *leftmerged = NULL;
3764  Bitmapset *rightmerged = NULL;
3765  int i;
3766  int j;
3767  int ic;
3768  int jc;
3769 
3770  /* Look up the previously-filled-in child deparse_columns structs */
3771  leftcolinfo = deparse_columns_fetch(colinfo->leftrti, dpns);
3772  rightcolinfo = deparse_columns_fetch(colinfo->rightrti, dpns);
3773 
3774  /*
3775  * Ensure colinfo->colnames has a slot for each column. (It could be long
3776  * enough already, if we pushed down a name for the last column.) Note:
3777  * it's possible that one or both inputs now have more columns than there
3778  * were when the query was parsed, but we'll deal with that below. We
3779  * only need entries in colnames for pre-existing columns.
3780  */
3781  noldcolumns = list_length(rte->eref->colnames);
3782  expand_colnames_array_to(colinfo, noldcolumns);
3783  Assert(colinfo->num_cols == noldcolumns);
3784 
3785  /*
3786  * Scan the join output columns, select an alias for each one, and store
3787  * it in colinfo->colnames. If there are USING columns, set_using_names()
3788  * already selected their names, so we can start the loop at the first
3789  * non-merged column.
3790  */
3791  changed_any = false;
3792  for (i = list_length(colinfo->usingNames); i < noldcolumns; i++)
3793  {
3794  char *colname = colinfo->colnames[i];
3795  char *real_colname;
3796 
3797  /* Ignore dropped column (only possible for non-merged column) */
3798  if (colinfo->leftattnos[i] == 0 && colinfo->rightattnos[i] == 0)
3799  {
3800  Assert(colname == NULL);
3801  continue;
3802  }
3803 
3804  /* Get the child column name */
3805  if (colinfo->leftattnos[i] > 0)
3806  real_colname = leftcolinfo->colnames[colinfo->leftattnos[i] - 1];
3807  else if (colinfo->rightattnos[i] > 0)
3808  real_colname = rightcolinfo->colnames[colinfo->rightattnos[i] - 1];
3809  else
3810  {
3811  /* We're joining system columns --- use eref name */
3812  real_colname = strVal(list_nth(rte->eref->colnames, i));
3813  }
3814  Assert(real_colname != NULL);
3815 
3816  /* In an unnamed join, just report child column names as-is */
3817  if (rte->alias == NULL)
3818  {
3819  colinfo->colnames[i] = real_colname;
3820  continue;
3821  }
3822 
3823  /* If alias already assigned, that's what to use */
3824  if (colname == NULL)
3825  {
3826  /* If user wrote an alias, prefer that over real column name */
3827  if (rte->alias && i < list_length(rte->alias->colnames))
3828  colname = strVal(list_nth(rte->alias->colnames, i));
3829  else
3830  colname = real_colname;
3831 
3832  /* Unique-ify and insert into colinfo */
3833  colname = make_colname_unique(colname, dpns, colinfo);
3834 
3835  colinfo->colnames[i] = colname;
3836  }
3837 
3838  /* Remember if any assigned aliases differ from "real" name */
3839  if (!changed_any && strcmp(colname, real_colname) != 0)
3840  changed_any = true;
3841  }
3842 
3843  /*
3844  * Calculate number of columns the join would have if it were re-parsed
3845  * now, and create storage for the new_colnames and is_new_col arrays.
3846  *
3847  * Note: colname_is_unique will be consulting new_colnames[] during the
3848  * loops below, so its not-yet-filled entries must be zeroes.
3849  */
3850  nnewcolumns = leftcolinfo->num_new_cols + rightcolinfo->num_new_cols -
3851  list_length(colinfo->usingNames);
3852  colinfo->num_new_cols = nnewcolumns;
3853  colinfo->new_colnames = (char **) palloc0(nnewcolumns * sizeof(char *));
3854  colinfo->is_new_col = (bool *) palloc0(nnewcolumns * sizeof(bool));
3855 
3856  /*
3857  * Generating the new_colnames array is a bit tricky since any new columns
3858  * added since parse time must be inserted in the right places. This code
3859  * must match the parser, which will order a join's columns as merged
3860  * columns first (in USING-clause order), then non-merged columns from the
3861  * left input (in attnum order), then non-merged columns from the right
3862  * input (ditto). If one of the inputs is itself a join, its columns will
3863  * be ordered according to the same rule, which means newly-added columns
3864  * might not be at the end. We can figure out what's what by consulting
3865  * the leftattnos and rightattnos arrays plus the input is_new_col arrays.
3866  *
3867  * In these loops, i indexes leftattnos/rightattnos (so it's join varattno
3868  * less one), j indexes new_colnames/is_new_col, and ic/jc have similar
3869  * meanings for the current child RTE.
3870  */
3871 
3872  /* Handle merged columns; they are first and can't be new */
3873  i = j = 0;
3874  while (i < noldcolumns &&
3875  colinfo->leftattnos[i] != 0 &&
3876  colinfo->rightattnos[i] != 0)
3877  {
3878  /* column name is already determined and known unique */
3879  colinfo->new_colnames[j] = colinfo->colnames[i];
3880  colinfo->is_new_col[j] = false;
3881 
3882  /* build bitmapsets of child attnums of merged columns */
3883  if (colinfo->leftattnos[i] > 0)
3884  leftmerged = bms_add_member(leftmerged, colinfo->leftattnos[i]);
3885  if (colinfo->rightattnos[i] > 0)
3886  rightmerged = bms_add_member(rightmerged, colinfo->rightattnos[i]);
3887 
3888  i++, j++;
3889  }
3890 
3891  /* Handle non-merged left-child columns */
3892  ic = 0;
3893  for (jc = 0; jc < leftcolinfo->num_new_cols; jc++)
3894  {
3895  char *child_colname = leftcolinfo->new_colnames[jc];
3896 
3897  if (!leftcolinfo->is_new_col[jc])
3898  {
3899  /* Advance ic to next non-dropped old column of left child */
3900  while (ic < leftcolinfo->num_cols &&
3901  leftcolinfo->colnames[ic] == NULL)
3902  ic++;
3903  Assert(ic < leftcolinfo->num_cols);
3904  ic++;
3905  /* If it is a merged column, we already processed it */
3906  if (bms_is_member(ic, leftmerged))
3907  continue;
3908  /* Else, advance i to the corresponding existing join column */
3909  while (i < colinfo->num_cols &&
3910  colinfo->colnames[i] == NULL)
3911  i++;
3912  Assert(i < colinfo->num_cols);
3913  Assert(ic == colinfo->leftattnos[i]);
3914  /* Use the already-assigned name of this column */
3915  colinfo->new_colnames[j] = colinfo->colnames[i];
3916  i++;
3917  }
3918  else
3919  {
3920  /*
3921  * Unique-ify the new child column name and assign, unless we're
3922  * in an unnamed join, in which case just copy
3923  */
3924  if (rte->alias != NULL)
3925  {
3926  colinfo->new_colnames[j] =
3927  make_colname_unique(child_colname, dpns, colinfo);
3928  if (!changed_any &&
3929  strcmp(colinfo->new_colnames[j], child_colname) != 0)
3930  changed_any = true;
3931  }
3932  else
3933  colinfo->new_colnames[j] = child_colname;
3934  }
3935 
3936  colinfo->is_new_col[j] = leftcolinfo->is_new_col[jc];
3937  j++;
3938  }
3939 
3940  /* Handle non-merged right-child columns in exactly the same way */
3941  ic = 0;
3942  for (jc = 0; jc < rightcolinfo->num_new_cols; jc++)
3943  {
3944  char *child_colname = rightcolinfo->new_colnames[jc];
3945 
3946  if (!rightcolinfo->is_new_col[jc])
3947  {
3948  /* Advance ic to next non-dropped old column of right child */
3949  while (ic < rightcolinfo->num_cols &&
3950  rightcolinfo->colnames[ic] == NULL)
3951  ic++;
3952  Assert(ic < rightcolinfo->num_cols);
3953  ic++;
3954  /* If it is a merged column, we already processed it */
3955  if (bms_is_member(ic, rightmerged))
3956  continue;
3957  /* Else, advance i to the corresponding existing join column */
3958  while (i < colinfo->num_cols &&
3959  colinfo->colnames[i] == NULL)
3960  i++;
3961  Assert(i < colinfo->num_cols);
3962  Assert(ic == colinfo->rightattnos[i]);
3963  /* Use the already-assigned name of this column */
3964  colinfo->new_colnames[j] = colinfo->colnames[i];
3965  i++;
3966  }
3967  else
3968  {
3969  /*
3970  * Unique-ify the new child column name and assign, unless we're
3971  * in an unnamed join, in which case just copy
3972  */
3973  if (rte->alias != NULL)
3974  {
3975  colinfo->new_colnames[j] =
3976  make_colname_unique(child_colname, dpns, colinfo);
3977  if (!changed_any &&
3978  strcmp(colinfo->new_colnames[j], child_colname) != 0)
3979  changed_any = true;
3980  }
3981  else
3982  colinfo->new_colnames[j] = child_colname;
3983  }
3984 
3985  colinfo->is_new_col[j] = rightcolinfo->is_new_col[jc];
3986  j++;
3987  }
3988 
3989  /* Assert we processed the right number of columns */
3990 #ifdef USE_ASSERT_CHECKING
3991  while (i < colinfo->num_cols && colinfo->colnames[i] == NULL)
3992  i++;
3993  Assert(i == colinfo->num_cols);
3994  Assert(j == nnewcolumns);
3995 #endif
3996 
3997  /*
3998  * For a named join, print column aliases if we changed any from the child
3999  * names. Unnamed joins cannot print aliases.
4000  */
4001  if (rte->alias != NULL)
4002  colinfo->printaliases = changed_any;
4003  else
4004  colinfo->printaliases = false;
4005 }
4006 
4007 /*
4008  * colname_is_unique: is colname distinct from already-chosen column names?
4009  *
4010  * dpns is query-wide info, colinfo is for the column's RTE
4011  */
4012 static bool
4014  deparse_columns *colinfo)
4015 {
4016  int i;
4017  ListCell *lc;
4018 
4019  /* Check against already-assigned column aliases within RTE */
4020  for (i = 0; i < colinfo->num_cols; i++)
4021  {
4022  char *oldname = colinfo->colnames[i];
4023 
4024  if (oldname && strcmp(oldname, colname) == 0)
4025  return false;
4026  }
4027 
4028  /*
4029  * If we're building a new_colnames array, check that too (this will be
4030  * partially but not completely redundant with the previous checks)
4031  */
4032  for (i = 0; i < colinfo->num_new_cols; i++)
4033  {
4034  char *oldname = colinfo->new_colnames[i];
4035 
4036  if (oldname && strcmp(oldname, colname) == 0)
4037  return false;
4038  }
4039 
4040  /* Also check against USING-column names that must be globally unique */
4041  foreach(lc, dpns->using_names)
4042  {
4043  char *oldname = (char *) lfirst(lc);
4044 
4045  if (strcmp(oldname, colname) == 0)
4046  return false;
4047  }
4048 
4049  /* Also check against names already assigned for parent-join USING cols */
4050  foreach(lc, colinfo->parentUsing)
4051  {
4052  char *oldname = (char *) lfirst(lc);
4053 
4054  if (strcmp(oldname, colname) == 0)
4055  return false;
4056  }
4057 
4058  return true;
4059 }
4060 
4061 /*
4062  * make_colname_unique: modify colname if necessary to make it unique
4063  *
4064  * dpns is query-wide info, colinfo is for the column's RTE
4065  */
4066 static char *
4068  deparse_columns *colinfo)
4069 {
4070  /*
4071  * If the selected name isn't unique, append digits to make it so. For a
4072  * very long input name, we might have to truncate to stay within
4073  * NAMEDATALEN.
4074  */
4075  if (!colname_is_unique(colname, dpns, colinfo))
4076  {
4077  int colnamelen = strlen(colname);
4078  char *modname = (char *) palloc(colnamelen + 16);
4079  int i = 0;
4080 
4081  do
4082  {
4083  i++;
4084  for (;;)
4085  {
4086  /*
4087  * We avoid using %.*s here because it can misbehave if the
4088  * data is not valid in what libc thinks is the prevailing
4089  * encoding.
4090  */
4091  memcpy(modname, colname, colnamelen);
4092  sprintf(modname + colnamelen, "_%d", i);
4093  if (strlen(modname) < NAMEDATALEN)
4094  break;
4095  /* drop chars from colname to keep all the digits */
4096  colnamelen = pg_mbcliplen(colname, colnamelen,
4097  colnamelen - 1);
4098  }
4099  } while (!colname_is_unique(modname, dpns, colinfo));
4100  colname = modname;
4101  }
4102  return colname;
4103 }
4104 
4105 /*
4106  * expand_colnames_array_to: make colinfo->colnames at least n items long
4107  *
4108  * Any added array entries are initialized to zero.
4109  */
4110 static void
4112 {
4113  if (n > colinfo->num_cols)
4114  {
4115  if (colinfo->colnames == NULL)
4116  colinfo->colnames = (char **) palloc0(n * sizeof(char *));
4117  else
4118  {
4119  colinfo->colnames = (char **) repalloc(colinfo->colnames,
4120  n * sizeof(char *));
4121  memset(colinfo->colnames + colinfo->num_cols, 0,
4122  (n - colinfo->num_cols) * sizeof(char *));
4123  }
4124  colinfo->num_cols = n;
4125  }
4126 }
4127 
4128 /*
4129  * identify_join_columns: figure out where columns of a join come from
4130  *
4131  * Fills the join-specific fields of the colinfo struct, except for
4132  * usingNames which is filled later.
4133  */
4134 static void
4136  deparse_columns *colinfo)
4137 {
4138  int numjoincols;
4139  int i;
4140  ListCell *lc;
4141 
4142  /* Extract left/right child RT indexes */
4143  if (IsA(j->larg, RangeTblRef))
4144  colinfo->leftrti = ((RangeTblRef *) j->larg)->rtindex;
4145  else if (IsA(j->larg, JoinExpr))
4146  colinfo->leftrti = ((JoinExpr *) j->larg)->rtindex;
4147  else
4148  elog(ERROR, "unrecognized node type in jointree: %d",
4149  (int) nodeTag(j->larg));
4150  if (IsA(j->rarg, RangeTblRef))
4151  colinfo->rightrti = ((RangeTblRef *) j->rarg)->rtindex;
4152  else if (IsA(j->rarg, JoinExpr))
4153  colinfo->rightrti = ((JoinExpr *) j->rarg)->rtindex;
4154  else
4155  elog(ERROR, "unrecognized node type in jointree: %d",
4156  (int) nodeTag(j->rarg));
4157 
4158  /* Assert children will be processed earlier than join in second pass */
4159  Assert(colinfo->leftrti < j->rtindex);
4160  Assert(colinfo->rightrti < j->rtindex);
4161 
4162  /* Initialize result arrays with zeroes */
4163  numjoincols = list_length(jrte->joinaliasvars);
4164  Assert(numjoincols == list_length(jrte->eref->colnames));
4165  colinfo->leftattnos = (int *) palloc0(numjoincols * sizeof(int));
4166  colinfo->rightattnos = (int *) palloc0(numjoincols * sizeof(int));
4167 
4168  /* Scan the joinaliasvars list to identify simple column references */
4169  i = 0;
4170  foreach(lc, jrte->joinaliasvars)
4171  {
4172  Var *aliasvar = (Var *) lfirst(lc);
4173 
4174  /* get rid of any implicit coercion above the Var */
4175  aliasvar = (Var *) strip_implicit_coercions((Node *) aliasvar);
4176 
4177  if (aliasvar == NULL)
4178  {
4179  /* It's a dropped column; nothing to do here */
4180  }
4181  else if (IsA(aliasvar, Var))
4182  {
4183  Assert(aliasvar->varlevelsup == 0);
4184  Assert(aliasvar->varattno != 0);
4185  if (aliasvar->varno == colinfo->leftrti)
4186  colinfo->leftattnos[i] = aliasvar->varattno;
4187  else if (aliasvar->varno == colinfo->rightrti)
4188  colinfo->rightattnos[i] = aliasvar->varattno;
4189  else
4190  elog(ERROR, "unexpected varno %d in JOIN RTE",
4191  aliasvar->varno);
4192  }
4193  else if (IsA(aliasvar, CoalesceExpr))
4194  {
4195  /*
4196  * It's a merged column in FULL JOIN USING. Ignore it for now and
4197  * let the code below identify the merged columns.
4198  */
4199  }
4200  else
4201  elog(ERROR, "unrecognized node type in join alias vars: %d",
4202  (int) nodeTag(aliasvar));
4203 
4204  i++;
4205  }
4206 
4207  /*
4208  * If there's a USING clause, deconstruct the join quals to identify the
4209  * merged columns. This is a tad painful but if we cannot rely on the
4210  * column names, there is no other representation of which columns were
4211  * joined by USING. (Unless the join type is FULL, we can't tell from the
4212  * joinaliasvars list which columns are merged.) Note: we assume that the
4213  * merged columns are the first output column(s) of the join.
4214  */
4215  if (j->usingClause)
4216  {
4217  List *leftvars = NIL;
4218  List *rightvars = NIL;
4219  ListCell *lc2;
4220 
4221  /* Extract left- and right-side Vars from the qual expression */
4222  flatten_join_using_qual(j->quals, &leftvars, &rightvars);
4223  Assert(list_length(leftvars) == list_length(j->usingClause));
4224  Assert(list_length(rightvars) == list_length(j->usingClause));
4225 
4226  /* Mark the output columns accordingly */
4227  i = 0;
4228  forboth(lc, leftvars, lc2, rightvars)
4229  {
4230  Var *leftvar = (Var *) lfirst(lc);
4231  Var *rightvar = (Var *) lfirst(lc2);
4232 
4233  Assert(leftvar->varlevelsup == 0);
4234  Assert(leftvar->varattno != 0);
4235  if (leftvar->varno != colinfo->leftrti)
4236  elog(ERROR, "unexpected varno %d in JOIN USING qual",
4237  leftvar->varno);
4238  colinfo->leftattnos[i] = leftvar->varattno;
4239 
4240  Assert(rightvar->varlevelsup == 0);
4241  Assert(rightvar->varattno != 0);
4242  if (rightvar->varno != colinfo->rightrti)
4243  elog(ERROR, "unexpected varno %d in JOIN USING qual",
4244  rightvar->varno);
4245  colinfo->rightattnos[i] = rightvar->varattno;
4246 
4247  i++;
4248  }
4249  }
4250 }
4251 
4252 /*
4253  * flatten_join_using_qual: extract Vars being joined from a JOIN/USING qual
4254  *
4255  * We assume that transformJoinUsingClause won't have produced anything except
4256  * AND nodes, equality operator nodes, and possibly implicit coercions, and
4257  * that the AND node inputs match left-to-right with the original USING list.
4258  *
4259  * Caller must initialize the result lists to NIL.
4260  */
4261 static void
4262 flatten_join_using_qual(Node *qual, List **leftvars, List **rightvars)
4263 {
4264  if (IsA(qual, BoolExpr))
4265  {
4266  /* Handle AND nodes by recursion */
4267  BoolExpr *b = (BoolExpr *) qual;
4268  ListCell *lc;
4269 
4270  Assert(b->boolop == AND_EXPR);
4271  foreach(lc, b->args)
4272  {
4274  leftvars, rightvars);
4275  }
4276  }
4277  else if (IsA(qual, OpExpr))
4278  {
4279  /* Otherwise we should have an equality operator */
4280  OpExpr *op = (OpExpr *) qual;
4281  Var *var;
4282 
4283  if (list_length(op->args) != 2)
4284  elog(ERROR, "unexpected unary operator in JOIN/USING qual");
4285  /* Arguments should be Vars with perhaps implicit coercions */
4286  var = (Var *) strip_implicit_coercions((Node *) linitial(op->args));
4287  if (!IsA(var, Var))
4288  elog(ERROR, "unexpected node type in JOIN/USING qual: %d",
4289  (int) nodeTag(var));
4290  *leftvars = lappend(*leftvars, var);
4291  var = (Var *) strip_implicit_coercions((Node *) lsecond(op->args));
4292  if (!IsA(var, Var))
4293  elog(ERROR, "unexpected node type in JOIN/USING qual: %d",
4294  (int) nodeTag(var));
4295  *rightvars = lappend(*rightvars, var);
4296  }
4297  else
4298  {
4299  /* Perhaps we have an implicit coercion to boolean? */
4300  Node *q = strip_implicit_coercions(qual);
4301 
4302  if (q != qual)
4303  flatten_join_using_qual(q, leftvars, rightvars);
4304  else
4305  elog(ERROR, "unexpected node type in JOIN/USING qual: %d",
4306  (int) nodeTag(qual));
4307  }
4308 }
4309 
4310 /*
4311  * get_rtable_name: convenience function to get a previously assigned RTE alias
4312  *
4313  * The RTE must belong to the topmost namespace level in "context".
4314  */
4315 static char *
4316 get_rtable_name(int rtindex, deparse_context *context)
4317 {
4319 
4320  Assert(rtindex > 0 && rtindex <= list_length(dpns->rtable_names));
4321  return (char *) list_nth(dpns->rtable_names, rtindex - 1);
4322 }
4323 
4324 /*
4325  * set_deparse_planstate: set up deparse_namespace to parse subexpressions
4326  * of a given PlanState node
4327  *
4328  * This sets the planstate, outer_planstate, inner_planstate, outer_tlist,
4329  * inner_tlist, and index_tlist fields. Caller is responsible for adjusting
4330  * the ancestors list if necessary. Note that the rtable and ctes fields do
4331  * not need to change when shifting attention to different plan nodes in a
4332  * single plan tree.
4333  */
4334 static void
4336 {
4337  dpns->planstate = ps;
4338 
4339  /*
4340  * We special-case Append and MergeAppend to pretend that the first child
4341  * plan is the OUTER referent; we have to interpret OUTER Vars in their
4342  * tlists according to one of the children, and the first one is the most
4343  * natural choice. Likewise special-case ModifyTable to pretend that the
4344  * first child plan is the OUTER referent; this is to support RETURNING
4345  * lists containing references to non-target relations.
4346  */
4347  if (IsA(ps, AppendState))
4348  dpns->outer_planstate = ((AppendState *) ps)->appendplans[0];
4349  else if (IsA(ps, MergeAppendState))
4350  dpns->outer_planstate = ((MergeAppendState *) ps)->mergeplans[0];
4351  else if (IsA(ps, ModifyTableState))
4352  dpns->outer_planstate = ((ModifyTableState *) ps)->mt_plans[0];
4353  else
4354  dpns->outer_planstate = outerPlanState(ps);
4355 
4356  if (dpns->outer_planstate)
4357  dpns->outer_tlist = dpns->outer_planstate->plan->targetlist;
4358  else
4359  dpns->outer_tlist = NIL;
4360 
4361  /*
4362  * For a SubqueryScan, pretend the subplan is INNER referent. (We don't
4363  * use OUTER because that could someday conflict with the normal meaning.)
4364  * Likewise, for a CteScan, pretend the subquery's plan is INNER referent.
4365  * For ON CONFLICT .. UPDATE we just need the inner tlist to point to the
4366  * excluded expression's tlist. (Similar to the SubqueryScan we don't want
4367  * to reuse OUTER, it's used for RETURNING in some modify table cases,
4368  * although not INSERT .. CONFLICT).
4369  */
4370  if (IsA(ps, SubqueryScanState))
4371  dpns->inner_planstate = ((SubqueryScanState *) ps)->subplan;
4372  else if (IsA(ps, CteScanState))
4373  dpns->inner_planstate = ((CteScanState *) ps)->cteplanstate;
4374  else if (IsA(ps, ModifyTableState))
4375  dpns->inner_planstate = ps;
4376  else
4377  dpns->inner_planstate = innerPlanState(ps);
4378 
4379  if (IsA(ps, ModifyTableState))
4380  dpns->inner_tlist = ((ModifyTableState *) ps)->mt_excludedtlist;
4381  else if (dpns->inner_planstate)
4382  dpns->inner_tlist = dpns->inner_planstate->plan->targetlist;
4383  else
4384  dpns->inner_tlist = NIL;
4385 
4386  /* Set up referent for INDEX_VAR Vars, if needed */
4387  if (IsA(ps->plan, IndexOnlyScan))
4388  dpns->index_tlist = ((IndexOnlyScan *) ps->plan)->indextlist;
4389  else if (IsA(ps->plan, ForeignScan))
4390  dpns->index_tlist = ((ForeignScan *) ps->plan)->fdw_scan_tlist;
4391  else if (IsA(ps->plan, CustomScan))
4392  dpns->index_tlist = ((CustomScan *) ps->plan)->custom_scan_tlist;
4393  else
4394  dpns->index_tlist = NIL;
4395 }
4396 
4397 /*
4398  * push_child_plan: temporarily transfer deparsing attention to a child plan
4399  *
4400  * When expanding an OUTER_VAR or INNER_VAR reference, we must adjust the
4401  * deparse context in case the referenced expression itself uses
4402  * OUTER_VAR/INNER_VAR. We modify the top stack entry in-place to avoid
4403  * affecting levelsup issues (although in a Plan tree there really shouldn't
4404  * be any).
4405  *
4406  * Caller must provide a local deparse_namespace variable to save the
4407  * previous state for pop_child_plan.
4408  */
4409 static void
4411  deparse_namespace *save_dpns)
4412 {
4413  /* Save state for restoration later */
4414  *save_dpns = *dpns;
4415 
4416  /* Link current plan node into ancestors list */
4417  dpns->ancestors = lcons(dpns->planstate, dpns->ancestors);
4418 
4419  /* Set attention on selected child */
4420  set_deparse_planstate(dpns, ps);
4421 }
4422 
4423 /*
4424  * pop_child_plan: undo the effects of push_child_plan
4425  */
4426 static void
4428 {
4429  List *ancestors;
4430 
4431  /* Get rid of ancestors list cell added by push_child_plan */
4432  ancestors = list_delete_first(dpns->ancestors);
4433 
4434  /* Restore fields changed by push_child_plan */
4435  *dpns = *save_dpns;
4436 
4437  /* Make sure dpns->ancestors is right (may be unnecessary) */
4438  dpns->ancestors = ancestors;
4439 }
4440 
4441 /*
4442  * push_ancestor_plan: temporarily transfer deparsing attention to an
4443  * ancestor plan
4444  *
4445  * When expanding a Param reference, we must adjust the deparse context
4446  * to match the plan node that contains the expression being printed;
4447  * otherwise we'd fail if that expression itself contains a Param or
4448  * OUTER_VAR/INNER_VAR/INDEX_VAR variable.
4449  *
4450  * The target ancestor is conveniently identified by the ListCell holding it
4451  * in dpns->ancestors.
4452  *
4453  * Caller must provide a local deparse_namespace variable to save the
4454  * previous state for pop_ancestor_plan.
4455  */
4456 static void
4458  deparse_namespace *save_dpns)
4459 {
4460  PlanState *ps = (PlanState *) lfirst(ancestor_cell);
4461  List *ancestors;
4462 
4463  /* Save state for restoration later */
4464  *save_dpns = *dpns;
4465 
4466  /* Build a new ancestor list with just this node's ancestors */
4467  ancestors = NIL;
4468  while ((ancestor_cell = lnext(ancestor_cell)) != NULL)
4469  ancestors = lappend(ancestors, lfirst(ancestor_cell));
4470  dpns->ancestors = ancestors;
4471 
4472  /* Set attention on selected ancestor */
4473  set_deparse_planstate(dpns, ps);
4474 }
4475 
4476 /*
4477  * pop_ancestor_plan: undo the effects of push_ancestor_plan
4478  */
4479 static void
4481 {
4482  /* Free the ancestor list made in push_ancestor_plan */
4483  list_free(dpns->ancestors);
4484 
4485  /* Restore fields changed by push_ancestor_plan */
4486  *dpns = *save_dpns;
4487 }
4488 
4489 
4490 /* ----------
4491  * make_ruledef - reconstruct the CREATE RULE command
4492  * for a given pg_rewrite tuple
4493  * ----------
4494  */
4495 static void
4497  int prettyFlags)
4498 {
4499  char *rulename;
4500  char ev_type;
4501  Oid ev_class;
4502  bool is_instead;
4503  char *ev_qual;
4504  char *ev_action;
4505  List *actions = NIL;
4506  int fno;
4507  Datum dat;
4508  bool isnull;
4509 
4510  /*
4511  * Get the attribute values from the rules tuple
4512  */
4513  fno = SPI_fnumber(rulettc, "rulename");
4514  dat = SPI_getbinval(ruletup, rulettc, fno, &isnull);
4515  Assert(!isnull);
4516  rulename = NameStr(*(DatumGetName(dat)));
4517 
4518  fno = SPI_fnumber(rulettc, "ev_type");
4519  dat = SPI_getbinval(ruletup, rulettc, fno, &isnull);
4520  Assert(!isnull);
4521  ev_type = DatumGetChar(dat);
4522 
4523  fno = SPI_fnumber(rulettc, "ev_class");
4524  dat = SPI_getbinval(ruletup, rulettc, fno, &isnull);
4525  Assert(!isnull);
4526  ev_class = DatumGetObjectId(dat);
4527 
4528  fno = SPI_fnumber(rulettc, "is_instead");
4529  dat = SPI_getbinval(ruletup, rulettc, fno, &isnull);
4530  Assert(!isnull);
4531  is_instead = DatumGetBool(dat);
4532 
4533  /* these could be nulls */
4534  fno = SPI_fnumber(rulettc, "ev_qual");
4535  ev_qual = SPI_getvalue(ruletup, rulettc, fno);
4536 
4537  fno = SPI_fnumber(rulettc, "ev_action");
4538  ev_action = SPI_getvalue(ruletup, rulettc, fno);
4539  if (ev_action != NULL)
4540  actions = (List *) stringToNode(ev_action);
4541 
4542  /*
4543  * Build the rules definition text
4544  */
4545  appendStringInfo(buf, "CREATE RULE %s AS",
4546  quote_identifier(rulename));
4547 
4548  if (prettyFlags & PRETTYFLAG_INDENT)
4549  appendStringInfoString(buf, "\n ON ");
4550  else
4551  appendStringInfoString(buf, " ON ");
4552 
4553  /* The event the rule is fired for */
4554  switch (ev_type)
4555  {
4556  case '1':
4557  appendStringInfoString(buf, "SELECT");
4558  break;
4559 
4560  case '2':
4561  appendStringInfoString(buf, "UPDATE");
4562  break;
4563 
4564  case '3':
4565  appendStringInfoString(buf, "INSERT");
4566  break;
4567 
4568  case '4':
4569  appendStringInfoString(buf, "DELETE");
4570  break;
4571 
4572  default:
4573  ereport(ERROR,
4574  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4575  errmsg("rule \"%s\" has unsupported event type %d",
4576  rulename, ev_type)));
4577  break;
4578  }
4579 
4580  /* The relation the rule is fired on */
4581  appendStringInfo(buf, " TO %s", generate_relation_name(ev_class, NIL));
4582 
4583  /* If the rule has an event qualification, add it */
4584  if (ev_qual == NULL)
4585  ev_qual = "";
4586  if (strlen(ev_qual) > 0 && strcmp(ev_qual, "<>") != 0)
4587  {
4588  Node *qual;
4589  Query *query;
4590  deparse_context context;
4591  deparse_namespace dpns;
4592 
4593  if (prettyFlags & PRETTYFLAG_INDENT)
4594  appendStringInfoString(buf, "\n ");
4595  appendStringInfoString(buf, " WHERE ");
4596 
4597  qual = stringToNode(ev_qual);
4598 
4599  /*
4600  * We need to make a context for recognizing any Vars in the qual
4601  * (which can only be references to OLD and NEW). Use the rtable of
4602  * the first query in the action list for this purpose.
4603  */
4604  query = (Query *) linitial(actions);
4605 
4606  /*
4607  * If the action is INSERT...SELECT, OLD/NEW have been pushed down
4608  * into the SELECT, and that's what we need to look at. (Ugly kluge
4609  * ... try to fix this when we redesign querytrees.)
4610  */
4611  query = getInsertSelectQuery(query, NULL);
4612 
4613  /* Must acquire locks right away; see notes in get_query_def() */
4614  AcquireRewriteLocks(query, false, false);
4615 
4616  context.buf = buf;
4617  context.namespaces = list_make1(&dpns);
4618  context.windowClause = NIL;
4619  context.windowTList = NIL;
4620  context.varprefix = (list_length(query->rtable) != 1);
4621  context.prettyFlags = prettyFlags;
4622  context.wrapColumn = WRAP_COLUMN_DEFAULT;
4623  context.indentLevel = PRETTYINDENT_STD;
4624  context.special_exprkind = EXPR_KIND_NONE;
4625 
4626  set_deparse_for_query(&dpns, query, NIL);
4627 
4628  get_rule_expr(qual, &context, false);
4629  }
4630 
4631  appendStringInfoString(buf, " DO ");
4632 
4633  /* The INSTEAD keyword (if so) */
4634  if (is_instead)
4635  appendStringInfoString(buf, "INSTEAD ");
4636 
4637  /* Finally the rules actions */
4638  if (list_length(actions) > 1)
4639  {
4640  ListCell *action;
4641  Query *query;
4642 
4643  appendStringInfoChar(buf, '(');
4644  foreach(action, actions)
4645  {
4646  query = (Query *) lfirst(action);
4647  get_query_def(query, buf, NIL, NULL,
4648  prettyFlags, WRAP_COLUMN_DEFAULT, 0);
4649  if (prettyFlags)
4650  appendStringInfoString(buf, ";\n");
4651  else
4652  appendStringInfoString(buf, "; ");
4653  }
4654  appendStringInfoString(buf, ");");
4655  }
4656  else if (list_length(actions) == 0)
4657  {
4658  appendStringInfoString(buf, "NOTHING;");
4659  }
4660  else
4661  {
4662  Query *query;
4663 
4664  query = (Query *) linitial(actions);
4665  get_query_def(query, buf, NIL, NULL,
4666  prettyFlags, WRAP_COLUMN_DEFAULT, 0);
4667  appendStringInfoChar(buf, ';');
4668  }
4669 }
4670 
4671 
4672 /* ----------
4673  * make_viewdef - reconstruct the SELECT part of a
4674  * view rewrite rule
4675  * ----------
4676  */
4677 static void
4679  int prettyFlags, int wrapColumn)
4680 {
4681  Query *query;
4682  char ev_type;
4683  Oid ev_class;
4684  bool is_instead;
4685  char *ev_qual;
4686  char *ev_action;
4687  List *actions = NIL;
4688  Relation ev_relation;
4689  int fno;
4690  bool isnull;
4691 
4692  /*
4693  * Get the attribute values from the rules tuple
4694  */
4695  fno = SPI_fnumber(rulettc, "ev_type");
4696  ev_type = (char) SPI_getbinval(ruletup, rulettc, fno, &isnull);
4697 
4698  fno = SPI_fnumber(rulettc, "ev_class");
4699  ev_class = (Oid) SPI_getbinval(ruletup, rulettc, fno, &isnull);
4700 
4701  fno = SPI_fnumber(rulettc, "is_instead");
4702  is_instead = (bool) SPI_getbinval(ruletup, rulettc, fno, &isnull);
4703 
4704  fno = SPI_fnumber(rulettc, "ev_qual");
4705  ev_qual = SPI_getvalue(ruletup, rulettc, fno);
4706 
4707  fno = SPI_fnumber(rulettc, "ev_action");
4708  ev_action = SPI_getvalue(ruletup, rulettc, fno);
4709  if (ev_action != NULL)
4710  actions = (List *) stringToNode(ev_action);
4711 
4712  if (list_length(actions) != 1)
4713  {
4714  /* keep output buffer empty and leave */
4715  return;
4716  }
4717 
4718  query = (Query *) linitial(actions);
4719 
4720  if (ev_type != '1' || !is_instead ||
4721  strcmp(ev_qual, "<>") != 0 || query->commandType != CMD_SELECT)
4722  {
4723  /* keep output buffer empty and leave */
4724  return;
4725  }
4726 
4727  ev_relation = heap_open(ev_class, AccessShareLock);
4728 
4729  get_query_def(query, buf, NIL, RelationGetDescr(ev_relation),
4730  prettyFlags, wrapColumn, 0);
4731  appendStringInfoChar(buf, ';');
4732 
4733  heap_close(ev_relation, AccessShareLock);
4734 }
4735 
4736 
4737 /* ----------
4738  * get_query_def - Parse back one query parsetree
4739  *
4740  * If resultDesc is not NULL, then it is the output tuple descriptor for
4741  * the view represented by a SELECT query.
4742  * ----------
4743  */
4744 static void
4745 get_query_def(Query *query, StringInfo buf, List *parentnamespace,
4746  TupleDesc resultDesc,
4747  int prettyFlags, int wrapColumn, int startIndent)
4748 {
4749  deparse_context context;
4750  deparse_namespace dpns;
4751 
4752  /* Guard against excessively long or deeply-nested queries */
4755 
4756  /*
4757  * Before we begin to examine the query, acquire locks on referenced
4758  * relations, and fix up deleted columns in JOIN RTEs. This ensures
4759  * consistent results. Note we assume it's OK to scribble on the passed
4760  * querytree!
4761  *
4762  * We are only deparsing the query (we are not about to execute it), so we
4763  * only need AccessShareLock on the relations it mentions.
4764  */
4765  AcquireRewriteLocks(query, false, false);
4766 
4767  context.buf = buf;
4768  context.namespaces = lcons(&dpns, list_copy(parentnamespace));
4769  context.windowClause = NIL;
4770  context.windowTList = NIL;
4771  context.varprefix = (parentnamespace != NIL ||
4772  list_length(query->rtable) != 1);
4773  context.prettyFlags = prettyFlags;
4774  context.wrapColumn = wrapColumn;
4775  context.indentLevel = startIndent;
4776  context.special_exprkind = EXPR_KIND_NONE;
4777 
4778  set_deparse_for_query(&dpns, query, parentnamespace);
4779 
4780  switch (query->commandType)
4781  {
4782  case CMD_SELECT:
4783  get_select_query_def(query, &context, resultDesc);
4784  break;
4785 
4786  case CMD_UPDATE:
4787  get_update_query_def(query, &context);
4788  break;
4789 
4790  case CMD_INSERT:
4791  get_insert_query_def(query, &context);
4792  break;
4793 
4794  case CMD_DELETE:
4795  get_delete_query_def(query, &context);
4796  break;
4797 
4798  case CMD_NOTHING:
4799  appendStringInfoString(buf, "NOTHING");
4800  break;
4801 
4802  case CMD_UTILITY:
4803  get_utility_query_def(query, &context);
4804  break;
4805 
4806  default:
4807  elog(ERROR, "unrecognized query command type: %d",
4808  query->commandType);
4809  break;
4810  }
4811 }
4812 
4813 /* ----------
4814  * get_values_def - Parse back a VALUES list
4815  * ----------
4816  */
4817 static void
4818 get_values_def(List *values_lists, deparse_context *context)
4819 {
4820  StringInfo buf = context->buf;
4821  bool first_list = true;
4822  ListCell *vtl;
4823 
4824  appendStringInfoString(buf, "VALUES ");
4825 
4826  foreach(vtl, values_lists)
4827  {
4828  List *sublist = (List *) lfirst(vtl);
4829  bool first_col = true;
4830  ListCell *lc;
4831 
4832  if (first_list)
4833  first_list = false;
4834  else
4835  appendStringInfoString(buf, ", ");
4836 
4837  appendStringInfoChar(buf, '(');
4838  foreach(lc, sublist)
4839  {
4840  Node *col = (Node *) lfirst(lc);
4841 
4842  if (first_col)
4843  first_col = false;
4844  else
4845  appendStringInfoChar(buf, ',');
4846 
4847  /*
4848  * Print the value. Whole-row Vars need special treatment.
4849  */
4850  get_rule_expr_toplevel(col, context, false);
4851  }
4852  appendStringInfoChar(buf, ')');
4853  }
4854 }
4855 
4856 /* ----------
4857  * get_with_clause - Parse back a WITH clause
4858  * ----------
4859  */
4860 static void
4862 {
4863  StringInfo buf = context->buf;
4864  const char *sep;
4865  ListCell *l;
4866 
4867  if (query->cteList == NIL)
4868  return;
4869 
4870  if (PRETTY_INDENT(context))
4871  {
4872  context->indentLevel += PRETTYINDENT_STD;
4873  appendStringInfoChar(buf, ' ');
4874  }
4875 
4876  if (query->hasRecursive)
4877  sep = "WITH RECURSIVE ";
4878  else
4879  sep = "WITH ";
4880  foreach(l, query->cteList)
4881  {
4882  CommonTableExpr *cte = (CommonTableExpr *) lfirst(l);
4883 
4884  appendStringInfoString(buf, sep);
4886  if (cte->aliascolnames)
4887  {
4888  bool first = true;
4889  ListCell *col;
4890 
4891  appendStringInfoChar(buf, '(');
4892  foreach(col, cte->aliascolnames)
4893  {
4894  if (first)
4895  first = false;
4896  else
4897  appendStringInfoString(buf, ", ");
4899  quote_identifier(strVal(lfirst(col))));
4900  }
4901  appendStringInfoChar(buf, ')');
4902  }
4903  appendStringInfoString(buf, " AS (");
4904  if (PRETTY_INDENT(context))
4905  appendContextKeyword(context, "", 0, 0, 0);
4906  get_query_def((Query *) cte->ctequery, buf, context->namespaces, NULL,
4907  context->prettyFlags, context->wrapColumn,
4908  context->indentLevel);
4909  if (PRETTY_INDENT(context))
4910  appendContextKeyword(context, "", 0, 0, 0);
4911  appendStringInfoChar(buf, ')');
4912  sep = ", ";
4913  }
4914 
4915  if (PRETTY_INDENT(context))
4916  {
4917  context->indentLevel -= PRETTYINDENT_STD;
4918  appendContextKeyword(context, "", 0, 0, 0);
4919  }
4920  else
4921  appendStringInfoChar(buf, ' ');
4922 }
4923 
4924 /* ----------
4925  * get_select_query_def - Parse back a SELECT parsetree
4926  * ----------
4927  */
4928 static void
4930  TupleDesc resultDesc)
4931 {
4932  StringInfo buf = context->buf;
4933  List *save_windowclause;
4934  List *save_windowtlist;
4935  bool force_colno;
4936  ListCell *l;
4937 
4938  /* Insert the WITH clause if given */
4939  get_with_clause(query, context);
4940 
4941  /* Set up context for possible window functions */
4942  save_windowclause = context->windowClause;
4943  context->windowClause = query->windowClause;
4944  save_windowtlist = context->windowTList;
4945  context->windowTList = query->targetList;
4946 
4947  /*
4948  * If the Query node has a setOperations tree, then it's the top level of
4949  * a UNION/INTERSECT/EXCEPT query; only the WITH, ORDER BY and LIMIT
4950  * fields are interesting in the top query itself.
4951  */
4952  if (query->setOperations)
4953  {
4954  get_setop_query(query->setOperations, query, context, resultDesc);
4955  /* ORDER BY clauses must be simple in this case */
4956  force_colno = true;
4957  }
4958  else
4959  {
4960  get_basic_select_query(query, context, resultDesc);
4961  force_colno = false;
4962  }
4963 
4964  /* Add the ORDER BY clause if given */
4965  if (query->sortClause != NIL)
4966  {
4967  appendContextKeyword(context, " ORDER BY ",
4969  get_rule_orderby(query->sortClause, query->targetList,
4970  force_colno, context);
4971  }
4972 
4973  /* Add the LIMIT clause if given */
4974  if (query->limitOffset != NULL)
4975  {
4976  appendContextKeyword(context, " OFFSET ",
4978  get_rule_expr(query->limitOffset, context, false);
4979  }
4980  if (query->limitCount != NULL)
4981  {
4982  appendContextKeyword(context, " LIMIT ",
4984  if (IsA(query->limitCount, Const) &&
4985  ((Const *) query->limitCount)->constisnull)
4986  appendStringInfoString(buf, "ALL");
4987  else
4988  get_rule_expr(query->limitCount, context, false);
4989  }
4990 
4991  /* Add FOR [KEY] UPDATE/SHARE clauses if present */
4992  if (query->hasForUpdate)
4993  {
4994  foreach(l, query->rowMarks)
4995  {
4996  RowMarkClause *rc = (RowMarkClause *) lfirst(l);
4997 
4998  /* don't print implicit clauses */
4999  if (rc->pushedDown)
5000  continue;
5001 
5002  switch (rc->strength)
5003  {
5004  case LCS_NONE:
5005  /* we intentionally throw an error for LCS_NONE */
5006  elog(ERROR, "unrecognized LockClauseStrength %d",
5007  (int) rc->strength);
5008  break;
5009  case LCS_FORKEYSHARE:
5010  appendContextKeyword(context, " FOR KEY SHARE",
5012  break;
5013  case LCS_FORSHARE:
5014  appendContextKeyword(context, " FOR SHARE",
5016  break;
5017  case LCS_FORNOKEYUPDATE:
5018  appendContextKeyword(context, " FOR NO KEY UPDATE",
5020  break;
5021  case LCS_FORUPDATE:
5022  appendContextKeyword(context, " FOR UPDATE",
5024  break;
5025  }
5026 
5027  appendStringInfo(buf, " OF %s",
5029  context)));
5030  if (rc->waitPolicy == LockWaitError)
5031  appendStringInfoString(buf, " NOWAIT");
5032  else if (rc->waitPolicy == LockWaitSkip)
5033  appendStringInfoString(buf, " SKIP LOCKED");
5034  }
5035  }
5036 
5037  context->windowClause = save_windowclause;
5038  context->windowTList = save_windowtlist;
5039 }
5040 
5041 /*
5042  * Detect whether query looks like SELECT ... FROM VALUES();
5043  * if so, return the VALUES RTE. Otherwise return NULL.
5044  */
5045 static RangeTblEntry *
5047 {
5049  ListCell *lc;
5050 
5051  /*
5052  * We want to return TRUE even if the Query also contains OLD or NEW rule
5053  * RTEs. So the idea is to scan the rtable and see if there is only one
5054  * inFromCl RTE that is a VALUES RTE.
5055  */
5056  foreach(lc, query->rtable)
5057  {
5058  RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc);
5059 
5060  if (rte->rtekind == RTE_VALUES && rte->inFromCl)
5061  {
5062  if (result)
5063  return NULL; /* multiple VALUES (probably not possible) */
5064  result = rte;
5065  }
5066  else if (rte->rtekind == RTE_RELATION && !rte->inFromCl)
5067  continue; /* ignore rule entries */
5068  else
5069  return NULL; /* something else -> not simple VALUES */
5070  }
5071 
5072  /*
5073  * We don't need to check the targetlist in any great detail, because
5074  * parser/analyze.c will never generate a "bare" VALUES RTE --- they only
5075  * appear inside auto-generated sub-queries with very restricted
5076  * structure. However, DefineView might have modified the tlist by
5077  * injecting new column aliases; so compare tlist resnames against the
5078  * RTE's names to detect that.
5079  */
5080  if (result)
5081  {
5082  ListCell *lcn;
5083 
5084  if (list_length(query->targetList) != list_length(result->eref->colnames))
5085  return NULL; /* this probably cannot happen */
5086  forboth(lc, query->targetList, lcn, result->eref->colnames)
5087  {
5088  TargetEntry *tle = (TargetEntry *) lfirst(lc);
5089  char *cname = strVal(lfirst(lcn));
5090 
5091  if (tle->resjunk)
5092  return NULL; /* this probably cannot happen */
5093  if (tle->resname == NULL || strcmp(tle->resname, cname) != 0)
5094  return NULL; /* column name has been changed */
5095  }
5096  }
5097 
5098  return result;
5099 }
5100 
5101 static void
5103  TupleDesc resultDesc)
5104 {
5105  StringInfo buf = context->buf;
5106  RangeTblEntry *values_rte;
5107  char *sep;
5108  ListCell *l;
5109 
5110  if (PRETTY_INDENT(context))
5111  {
5112  context->indentLevel += PRETTYINDENT_STD;
5113  appendStringInfoChar(buf, ' ');
5114  }
5115 
5116  /*
5117  * If the query looks like SELECT * FROM (VALUES ...), then print just the
5118  * VALUES part. This reverses what transformValuesClause() did at parse
5119  * time.
5120  */
5121  values_rte = get_simple_values_rte(query);
5122  if (values_rte)
5123  {
5124  get_values_def(values_rte->values_lists, context);
5125  return;
5126  }
5127 
5128  /*
5129  * Build up the query string - first we say SELECT
5130  */
5131  appendStringInfoString(buf, "SELECT");
5132 
5133  /* Add the DISTINCT clause if given */
5134  if (query->distinctClause != NIL)
5135  {
5136  if (query->hasDistinctOn)
5137  {
5138  appendStringInfoString(buf, " DISTINCT ON (");
5139  sep = "";
5140  foreach(l, query->distinctClause)
5141  {
5142  SortGroupClause *srt = (SortGroupClause *) lfirst(l);
5143 
5144  appendStringInfoString(buf, sep);
5146  false, context);
5147  sep = ", ";
5148  }
5149  appendStringInfoChar(buf, ')');
5150  }
5151  else
5152  appendStringInfoString(buf, " DISTINCT");
5153  }
5154 
5155  /* Then we tell what to select (the targetlist) */
5156  get_target_list(query->targetList, context, resultDesc);
5157 
5158  /* Add the FROM clause if needed */
5159  get_from_clause(query, " FROM ", context);
5160 
5161  /* Add the WHERE clause if given */
5162  if (query->jointree->quals != NULL)
5163  {
5164  appendContextKeyword(context, " WHERE ",
5166  get_rule_expr(query->jointree->quals, context, false);
5167  }
5168 
5169  /* Add the GROUP BY clause if given */
5170  if (query->groupClause != NULL || query->groupingSets != NULL)
5171  {
5172  ParseExprKind save_exprkind;
5173 
5174  appendContextKeyword(context, " GROUP BY ",
5176 
5177  save_exprkind = context->special_exprkind;
5179 
5180  if (query->groupingSets == NIL)
5181  {
5182  sep = "";
5183  foreach(l, query->groupClause)
5184  {
5185  SortGroupClause *grp = (SortGroupClause *) lfirst(l);
5186 
5187  appendStringInfoString(buf, sep);
5189  false, context);
5190  sep = ", ";
5191  }
5192  }
5193  else
5194  {
5195  sep = "";
5196  foreach(l, query->groupingSets)
5197  {
5198  GroupingSet *grp = lfirst(l);
5199 
5200  appendStringInfoString(buf, sep);
5201  get_rule_groupingset(grp, query->targetList, true, context);
5202  sep = ", ";
5203  }
5204  }
5205 
5206  context->special_exprkind = save_exprkind;
5207  }
5208 
5209  /* Add the HAVING clause if given */
5210  if (query->havingQual != NULL)
5211  {
5212  appendContextKeyword(context, " HAVING ",
5214  get_rule_expr(query->havingQual, context, false);
5215  }
5216 
5217  /* Add the WINDOW clause if needed */
5218  if (query->windowClause != NIL)
5219  get_rule_windowclause(query, context);
5220 }
5221 
5222 /* ----------
5223  * get_target_list - Parse back a SELECT target list
5224  *
5225  * This is also used for RETURNING lists in INSERT/UPDATE/DELETE.
5226  * ----------
5227  */
5228 static void
5229 get_target_list(List *targetList, deparse_context *context,
5230  TupleDesc resultDesc)
5231 {
5232  StringInfo buf = context->buf;
5233  StringInfoData targetbuf;
5234  bool last_was_multiline = false;
5235  char *sep;
5236  int colno;
5237  ListCell *l;
5238 
5239  /* we use targetbuf to hold each TLE's text temporarily */
5240  initStringInfo(&targetbuf);
5241 
5242  sep = " ";
5243  colno = 0;
5244  foreach(l, targetList)
5245  {
5246  TargetEntry *tle = (TargetEntry *) lfirst(l);
5247  char *colname;
5248  char *attname;
5249 
5250  if (tle->resjunk)
5251  continue; /* ignore junk entries */
5252 
5253  appendStringInfoString(buf, sep);
5254  sep = ", ";
5255  colno++;
5256 
5257  /*
5258  * Put the new field text into targetbuf so we can decide after we've
5259  * got it whether or not it needs to go on a new line.
5260  */
5261  resetStringInfo(&targetbuf);
5262  context->buf = &targetbuf;
5263 
5264  /*
5265  * We special-case Var nodes rather than using get_rule_expr. This is
5266  * needed because get_rule_expr will display a whole-row Var as
5267  * "foo.*", which is the preferred notation in most contexts, but at
5268  * the top level of a SELECT list it's not right (the parser will
5269  * expand that notation into multiple columns, yielding behavior
5270  * different from a whole-row Var). We need to call get_variable
5271  * directly so that we can tell it to do the right thing, and so that
5272  * we can get the attribute name which is the default AS label.
5273  */
5274  if (tle->expr && (IsA(tle->expr, Var)))
5275  {
5276  attname = get_variable((Var *) tle->expr, 0, true, context);
5277  }
5278  else
5279  {
5280  get_rule_expr((Node *) tle->expr, context, true);
5281  /* We'll show the AS name unless it's this: */
5282  attname = "?column?";
5283  }
5284 
5285  /*
5286  * Figure out what the result column should be called. In the context
5287  * of a view, use the view's tuple descriptor (so as to pick up the
5288  * effects of any column RENAME that's been done on the view).
5289  * Otherwise, just use what we can find in the TLE.
5290  */
5291  if (resultDesc && colno <= resultDesc->natts)
5292  colname = NameStr(resultDesc->attrs[colno - 1]->attname);
5293  else
5294  colname = tle->resname;
5295 
5296  /* Show AS unless the column's name is correct as-is */
5297  if (colname) /* resname could be NULL */
5298  {
5299  if (attname == NULL || strcmp(attname, colname) != 0)
5300  appendStringInfo(&targetbuf, " AS %s", quote_identifier(colname));
5301  }
5302 
5303  /* Restore context's output buffer */
5304  context->buf = buf;
5305 
5306  /* Consider line-wrapping if enabled */
5307  if (PRETTY_INDENT(context) && context->wrapColumn >= 0)
5308  {
5309  int leading_nl_pos;
5310 
5311  /* Does the new field start with a new line? */
5312  if (targetbuf.len > 0 && targetbuf.data[0] == '\n')
5313  leading_nl_pos = 0;
5314  else
5315  leading_nl_pos = -1;
5316 
5317  /* If so, we shouldn't add anything */
5318  if (leading_nl_pos >= 0)
5319  {
5320  /* instead, remove any trailing spaces currently in buf */
5322  }
5323  else
5324  {
5325  char *trailing_nl;
5326 
5327  /* Locate the start of the current line in the output buffer */
5328  trailing_nl = strrchr(buf->data, '\n');
5329  if (trailing_nl == NULL)
5330  trailing_nl = buf->data;
5331  else
5332  trailing_nl++;
5333 
5334  /*
5335  * Add a newline, plus some indentation, if the new field is
5336  * not the first and either the new field would cause an
5337  * overflow or the last field used more than one line.
5338  */
5339  if (colno > 1 &&
5340  ((strlen(trailing_nl) + targetbuf.len > context->wrapColumn) ||
5341  last_was_multiline))
5342  appendContextKeyword(context, "", -PRETTYINDENT_STD,
5344  }
5345 
5346  /* Remember this field's multiline status for next iteration */
5347  last_was_multiline =
5348  (strchr(targetbuf.data + leading_nl_pos + 1, '\n') != NULL);
5349  }
5350 
5351  /* Add the new field */
5352  appendStringInfoString(buf, targetbuf.data);
5353  }
5354 
5355  /* clean up */
5356  pfree(targetbuf.data);
5357 }
5358 
5359 static void
5360 get_setop_query(Node *setOp, Query *query, deparse_context *context,
5361  TupleDesc resultDesc)
5362 {
5363  StringInfo buf = context->buf;
5364  bool need_paren;
5365 
5366  /* Guard against excessively long or deeply-nested queries */
5369 
5370  if (IsA(setOp, RangeTblRef))
5371  {
5372  RangeTblRef *rtr = (RangeTblRef *) setOp;
5373  RangeTblEntry *rte = rt_fetch(rtr->rtindex, query->rtable);
5374  Query *subquery = rte->subquery;
5375 
5376  Assert(subquery != NULL);
5377  Assert(subquery->setOperations == NULL);
5378  /* Need parens if WITH, ORDER BY, FOR UPDATE, or LIMIT; see gram.y */
5379  need_paren = (subquery->cteList ||
5380  subquery->sortClause ||
5381  subquery->rowMarks ||
5382  subquery->limitOffset ||
5383  subquery->limitCount);
5384  if (need_paren)
5385  appendStringInfoChar(buf, '(');
5386  get_query_def(subquery, buf, context->namespaces, resultDesc,
5387  context->prettyFlags, context->wrapColumn,
5388  context->indentLevel);
5389  if (need_paren)
5390  appendStringInfoChar(buf, ')');
5391  }
5392  else if (IsA(setOp, SetOperationStmt))
5393  {
5394  SetOperationStmt *op = (SetOperationStmt *) setOp;
5395  int subindent;
5396 
5397  /*
5398  * We force parens when nesting two SetOperationStmts, except when the
5399  * lefthand input is another setop of the same kind. Syntactically,
5400  * we could omit parens in rather more cases, but it seems best to use
5401  * parens to flag cases where the setop operator changes. If we use
5402  * parens, we also increase the indentation level for the child query.
5403  *
5404  * There are some cases in which parens are needed around a leaf query
5405  * too, but those are more easily handled at the next level down (see
5406  * code above).
5407  */
5408  if (IsA(op->larg, SetOperationStmt))
5409  {
5410  SetOperationStmt *lop = (SetOperationStmt *) op->larg;
5411 
5412  if (op->op == lop->op && op->all == lop->all)
5413  need_paren = false;
5414  else
5415  need_paren = true;
5416  }
5417  else
5418  need_paren = false;
5419 
5420  if (need_paren)
5421  {
5422  appendStringInfoChar(buf, '(');
5423  subindent = PRETTYINDENT_STD;
5424  appendContextKeyword(context, "", subindent, 0, 0);
5425  }
5426  else
5427  subindent = 0;
5428 
5429  get_setop_query(op->larg, query, context, resultDesc);
5430 
5431  if (need_paren)
5432  appendContextKeyword(context, ") ", -subindent, 0, 0);
5433  else if (PRETTY_INDENT(context))
5434  appendContextKeyword(context, "", -subindent, 0, 0);
5435  else
5436  appendStringInfoChar(buf, ' ');
5437 
5438  switch (op->op)
5439  {
5440  case SETOP_UNION:
5441  appendStringInfoString(buf, "UNION ");
5442  break;
5443  case SETOP_INTERSECT:
5444  appendStringInfoString(buf, "INTERSECT ");
5445  break;
5446  case SETOP_EXCEPT:
5447  appendStringInfoString(buf, "EXCEPT ");
5448  break;
5449  default:
5450  elog(ERROR, "unrecognized set op: %d",
5451  (int) op->op);
5452  }
5453  if (op->all)
5454  appendStringInfoString(buf, "ALL ");
5455 
5456  /* Always parenthesize if RHS is another setop */
5457  need_paren = IsA(op->rarg, SetOperationStmt);
5458 
5459  /*
5460  * The indentation code here is deliberately a bit different from that
5461  * for the lefthand input, because we want the line breaks in
5462  * different places.
5463  */
5464  if (need_paren)
5465  {
5466  appendStringInfoChar(buf, '(');
5467  subindent = PRETTYINDENT_STD;
5468  }
5469  else
5470  subindent = 0;
5471  appendContextKeyword(context, "", subindent, 0, 0);
5472 
5473  get_setop_query(op->rarg, query, context, resultDesc);
5474 
5475  if (PRETTY_INDENT(context))
5476  context->indentLevel -= subindent;
5477  if (need_paren)
5478  appendContextKeyword(context, ")", 0, 0, 0);
5479  }
5480  else
5481  {
5482  elog(ERROR, "unrecognized node type: %d",
5483  (int) nodeTag(setOp));
5484  }
5485 }
5486 
5487 /*
5488  * Display a sort/group clause.
5489  *
5490  * Also returns the expression tree, so caller need not find it again.
5491  */
5492 static Node *
5493 get_rule_sortgroupclause(Index ref, List *tlist, bool force_colno,
5494  deparse_context *context)
5495 {
5496  StringInfo buf = context->buf;
5497  TargetEntry *tle;
5498  Node *expr;
5499 
5500  tle = get_sortgroupref_tle(ref, tlist);
5501  expr = (Node *) tle->expr;
5502 
5503  /*
5504  * Use column-number form if requested by caller. Otherwise, if
5505  * expression is a constant, force it to be dumped with an explicit cast
5506  * as decoration --- this is because a simple integer constant is
5507  * ambiguous (and will be misinterpreted by findTargetlistEntry()) if we
5508  * dump it without any decoration. If it's anything more complex than a
5509  * simple Var, then force extra parens around it, to ensure it can't be
5510  * misinterpreted as a cube() or rollup() construct.
5511  */
5512  if (force_colno)
5513  {
5514  Assert(!tle->resjunk);
5515  appendStringInfo(buf, "%d", tle->resno);
5516  }
5517  else if (expr && IsA(expr, Const))
5518  get_const_expr((Const *) expr, context, 1);
5519  else if (!expr || IsA(expr, Var))
5520  get_rule_expr(expr, context, true);
5521  else
5522  {
5523  /*
5524  * We must force parens for function-like expressions even if
5525  * PRETTY_PAREN is off, since those are the ones in danger of
5526  * misparsing. For other expressions we need to force them only if
5527  * PRETTY_PAREN is on, since otherwise the expression will output them
5528  * itself. (We can't skip the parens.)
5529  */
5530  bool need_paren = (PRETTY_PAREN(context)
5531  || IsA(expr, FuncExpr)
5532  ||IsA(expr, Aggref)
5533  ||IsA(expr, WindowFunc));
5534 
5535  if (need_paren)
5536  appendStringInfoString(context->buf, "(");
5537  get_rule_expr(expr, context, true);
5538  if (need_paren)
5539  appendStringInfoString(context->buf, ")");
5540  }
5541 
5542  return expr;
5543 }
5544 
5545 /*
5546  * Display a GroupingSet
5547  */
5548 static void
5550  bool omit_parens, deparse_context *context)
5551 {
5552  ListCell *l;
5553  StringInfo buf = context->buf;
5554  bool omit_child_parens = true;
5555  char *sep = "";
5556 
5557  switch (gset->kind)
5558  {
5559  case GROUPING_SET_EMPTY:
5560  appendStringInfoString(buf, "()");
5561  return;
5562 
5563  case GROUPING_SET_SIMPLE:
5564  {
5565  if (!omit_parens || list_length(gset->content) != 1)
5566  appendStringInfoString(buf, "(");
5567 
5568  foreach(l, gset->content)
5569  {
5570  Index ref = lfirst_int(l);
5571 
5572  appendStringInfoString(buf, sep);
5573  get_rule_sortgroupclause(ref, targetlist,
5574  false, context);
5575  sep = ", ";
5576  }
5577 
5578  if (!omit_parens || list_length(gset->content) != 1)
5579  appendStringInfoString(buf, ")");
5580  }
5581  return;
5582 
5583  case GROUPING_SET_ROLLUP:
5584  appendStringInfoString(buf, "ROLLUP(");
5585  break;
5586  case GROUPING_SET_CUBE:
5587  appendStringInfoString(buf, "CUBE(");
5588  break;
5589  case GROUPING_SET_SETS:
5590  appendStringInfoString(buf, "GROUPING SETS (");
5591  omit_child_parens = false;
5592  break;
5593  }
5594 
5595  foreach(l, gset->content)
5596  {
5597  appendStringInfoString(buf, sep);
5598  get_rule_groupingset(lfirst(l), targetlist, omit_child_parens, context);
5599  sep = ", ";
5600  }
5601 
5602  appendStringInfoString(buf, ")");
5603 }
5604 
5605 /*
5606  * Display an ORDER BY list.
5607  */
5608 static void
5609 get_rule_orderby(List *orderList, List *targetList,
5610  bool force_colno, deparse_context *context)
5611 {
5612  StringInfo buf = context->buf;
5613  const char *sep;
5614  ListCell *l;
5615 
5616  sep = "";
5617  foreach(l, orderList)
5618  {
5619  SortGroupClause *srt = (SortGroupClause *) lfirst(l);
5620