1 /*-------------------------------------------------------------------------
4 * Functions to convert stored expressions/querytrees back to
7 * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
8 * Portions Copyright (c) 1994, Regents of the University of California
12 * src/backend/utils/adt/ruleutils.c
14 *-------------------------------------------------------------------------
22 #include "access/amapi.h"
23 #include "access/htup_details.h"
24 #include "access/relation.h"
25 #include "access/table.h"
26 #include "catalog/pg_aggregate.h"
27 #include "catalog/pg_am.h"
28 #include "catalog/pg_authid.h"
29 #include "catalog/pg_collation.h"
30 #include "catalog/pg_constraint.h"
31 #include "catalog/pg_depend.h"
32 #include "catalog/pg_language.h"
33 #include "catalog/pg_opclass.h"
34 #include "catalog/pg_operator.h"
35 #include "catalog/pg_partitioned_table.h"
36 #include "catalog/pg_proc.h"
37 #include "catalog/pg_statistic_ext.h"
38 #include "catalog/pg_trigger.h"
39 #include "catalog/pg_type.h"
40 #include "commands/defrem.h"
41 #include "commands/tablespace.h"
42 #include "common/keywords.h"
43 #include "executor/spi.h"
45 #include "mb/pg_wchar.h"
46 #include "miscadmin.h"
47 #include "nodes/makefuncs.h"
48 #include "nodes/nodeFuncs.h"
49 #include "nodes/pathnodes.h"
50 #include "optimizer/optimizer.h"
51 #include "parser/parse_agg.h"
52 #include "parser/parse_func.h"
53 #include "parser/parse_oper.h"
54 #include "parser/parse_relation.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/guc.h"
64 #include "utils/hsearch.h"
65 #include "utils/lsyscache.h"
66 #include "utils/partcache.h"
67 #include "utils/rel.h"
68 #include "utils/ruleutils.h"
69 #include "utils/snapmgr.h"
70 #include "utils/syscache.h"
71 #include "utils/typcache.h"
72 #include "utils/varlena.h"
73 #include "utils/xml.h"
76 * Pretty formatting constants
81 #define PRETTYINDENT_STD 8
82 #define PRETTYINDENT_JOIN 4
83 #define PRETTYINDENT_VAR 4
85 #define PRETTYINDENT_LIMIT 40 /* wrap limit */
88 #define PRETTYFLAG_PAREN 0x0001
89 #define PRETTYFLAG_INDENT 0x0002
90 #define PRETTYFLAG_SCHEMA 0x0004
92 /* Standard conversion of a "bool pretty" option to detailed flags */
93 #define GET_PRETTY_FLAGS(pretty) \
94 ((pretty) ? (PRETTYFLAG_PAREN | PRETTYFLAG_INDENT | PRETTYFLAG_SCHEMA) \
97 /* Default line length for pretty-print wrapping: 0 means wrap always */
98 #define WRAP_COLUMN_DEFAULT 0
100 /* macros to test if pretty action needed */
101 #define PRETTY_PAREN(context) ((context)->prettyFlags & PRETTYFLAG_PAREN)
102 #define PRETTY_INDENT(context) ((context)->prettyFlags & PRETTYFLAG_INDENT)
103 #define PRETTY_SCHEMA(context) ((context)->prettyFlags & PRETTYFLAG_SCHEMA)
111 /* Context info needed for invoking a recursive querytree display routine */
114 StringInfo buf
; /* output buffer to append to */
115 List
*namespaces
; /* List of deparse_namespace nodes */
116 TupleDesc resultDesc
; /* if top level of a view, the view's tupdesc */
117 List
*targetList
; /* Current query level's SELECT targetlist */
118 List
*windowClause
; /* Current query level's WINDOW clause */
119 int prettyFlags
; /* enabling of pretty-print functions */
120 int wrapColumn
; /* max line length, or -1 for no limit */
121 int indentLevel
; /* current indent level for pretty-print */
122 bool varprefix
; /* true to print prefixes on Vars */
123 bool colNamesVisible
; /* do we care about output column names? */
124 bool inGroupBy
; /* deparsing GROUP BY clause? */
125 bool varInOrderBy
; /* deparsing simple Var in ORDER BY? */
126 Bitmapset
*appendparents
; /* if not null, map child Vars of these relids
127 * back to the parent rel */
131 * Each level of query context around a subtree needs a level of Var namespace.
132 * A Var having varlevelsup=N refers to the N'th item (counting from 0) in
133 * the current context's namespaces list.
135 * rtable is the list of actual RTEs from the Query or PlannedStmt.
136 * rtable_names holds the alias name to be used for each RTE (either a C
137 * string, or NULL for nameless RTEs such as unnamed joins).
138 * rtable_columns holds the column alias names to be used for each RTE.
140 * subplans is a list of Plan trees for SubPlans and CTEs (it's only used
141 * in the PlannedStmt case).
142 * ctes is a list of CommonTableExpr nodes (only used in the Query case).
143 * appendrels, if not null (it's only used in the PlannedStmt case), is an
144 * array of AppendRelInfo nodes, indexed by child relid. We use that to map
145 * child-table Vars to their inheritance parents.
147 * In some cases we need to make names of merged JOIN USING columns unique
148 * across the whole query, not only per-RTE. If so, unique_using is true
149 * and using_names is a list of C strings representing names already assigned
152 * When deparsing plan trees, there is always just a single item in the
153 * deparse_namespace list (since a plan tree never contains Vars with
154 * varlevelsup > 0). We store the Plan node that is the immediate
155 * parent of the expression to be deparsed, as well as a list of that
156 * Plan's ancestors. In addition, we store its outer and inner subplan nodes,
157 * as well as their targetlists, and the index tlist if the current plan node
158 * might contain INDEX_VAR Vars. (These fields could be derived on-the-fly
159 * from the current Plan node, but it seems notationally clearer to set them
160 * up as separate fields.)
164 List
*rtable
; /* List of RangeTblEntry nodes */
165 List
*rtable_names
; /* Parallel list of names for RTEs */
166 List
*rtable_columns
; /* Parallel list of deparse_columns structs */
167 List
*subplans
; /* List of Plan trees for SubPlans */
168 List
*ctes
; /* List of CommonTableExpr nodes */
169 AppendRelInfo
**appendrels
; /* Array of AppendRelInfo nodes, or NULL */
170 /* Workspace for column alias assignment: */
171 bool unique_using
; /* Are we making USING names globally unique */
172 List
*using_names
; /* List of assigned names for USING columns */
173 /* Remaining fields are used only when deparsing a Plan tree: */
174 Plan
*plan
; /* immediate parent of current expression */
175 List
*ancestors
; /* ancestors of plan */
176 Plan
*outer_plan
; /* outer subnode, or NULL if none */
177 Plan
*inner_plan
; /* inner subnode, or NULL if none */
178 List
*outer_tlist
; /* referent for OUTER_VAR Vars */
179 List
*inner_tlist
; /* referent for INNER_VAR Vars */
180 List
*index_tlist
; /* referent for INDEX_VAR Vars */
181 /* Special namespace representing a function signature: */
188 * Per-relation data about column alias names.
190 * Selecting aliases is unreasonably complicated because of the need to dump
191 * rules/views whose underlying tables may have had columns added, deleted, or
192 * renamed since the query was parsed. We must nonetheless print the rule/view
193 * in a form that can be reloaded and will produce the same results as before.
195 * For each RTE used in the query, we must assign column aliases that are
196 * unique within that RTE. SQL does not require this of the original query,
197 * but due to factors such as *-expansion we need to be able to uniquely
198 * reference every column in a decompiled query. As long as we qualify all
199 * column references, per-RTE uniqueness is sufficient for that.
201 * However, we can't ensure per-column name uniqueness for unnamed join RTEs,
202 * since they just inherit column names from their input RTEs, and we can't
203 * rename the columns at the join level. Most of the time this isn't an issue
204 * because we don't need to reference the join's output columns as such; we
205 * can reference the input columns instead. That approach can fail for merged
206 * JOIN USING columns, however, so when we have one of those in an unnamed
207 * join, we have to make that column's alias globally unique across the whole
208 * query to ensure it can be referenced unambiguously.
210 * Another problem is that a JOIN USING clause requires the columns to be
211 * merged to have the same aliases in both input RTEs, and that no other
212 * columns in those RTEs or their children conflict with the USING names.
213 * To handle that, we do USING-column alias assignment in a recursive
214 * traversal of the query's jointree. When descending through a JOIN with
215 * USING, we preassign the USING column names to the child columns, overriding
216 * other rules for column alias assignment. We also mark each RTE with a list
217 * of all USING column names selected for joins containing that RTE, so that
218 * when we assign other columns' aliases later, we can avoid conflicts.
220 * Another problem is that if a JOIN's input tables have had columns added or
221 * deleted since the query was parsed, we must generate a column alias list
222 * for the join that matches the current set of input columns --- otherwise, a
223 * change in the number of columns in the left input would throw off matching
224 * of aliases to columns of the right input. Thus, positions in the printable
225 * column alias list are not necessarily one-for-one with varattnos of the
226 * JOIN, so we need a separate new_colnames[] array for printing purposes.
231 * colnames is an array containing column aliases to use for columns that
232 * existed when the query was parsed. Dropped columns have NULL entries.
233 * This array can be directly indexed by varattno to get a Var's name.
235 * Non-NULL entries are guaranteed unique within the RTE, *except* when
236 * this is for an unnamed JOIN RTE. In that case we merely copy up names
237 * from the two input RTEs.
239 * During the recursive descent in set_using_names(), forcible assignment
240 * of a child RTE's column name is represented by pre-setting that element
241 * of the child's colnames array. So at that stage, NULL entries in this
242 * array just mean that no name has been preassigned, not necessarily that
243 * the column is dropped.
245 int num_cols
; /* length of colnames[] array */
246 char **colnames
; /* array of C strings and NULLs */
249 * new_colnames is an array containing column aliases to use for columns
250 * that would exist if the query was re-parsed against the current
251 * definitions of its base tables. This is what to print as the column
252 * alias list for the RTE. This array does not include dropped columns,
253 * but it will include columns added since original parsing. Indexes in
254 * it therefore have little to do with current varattno values. As above,
255 * entries are unique unless this is for an unnamed JOIN RTE. (In such an
256 * RTE, we never actually print this array, but we must compute it anyway
257 * for possible use in computing column names of upper joins.) The
258 * parallel array is_new_col marks which of these columns are new since
259 * original parsing. Entries with is_new_col false must match the
260 * non-NULL colnames entries one-for-one.
262 int num_new_cols
; /* length of new_colnames[] array */
263 char **new_colnames
; /* array of C strings */
264 bool *is_new_col
; /* array of bool flags */
266 /* This flag tells whether we should actually print a column alias list */
269 /* This list has all names used as USING names in joins above this RTE */
270 List
*parentUsing
; /* names assigned to parent merged columns */
273 * If this struct is for a JOIN RTE, we fill these fields during the
274 * set_using_names() pass to describe its relationship to its child RTEs.
276 * leftattnos and rightattnos are arrays with one entry per existing
277 * output column of the join (hence, indexable by join varattno). For a
278 * simple reference to a column of the left child, leftattnos[i] is the
279 * child RTE's attno and rightattnos[i] is zero; and conversely for a
280 * column of the right child. But for merged columns produced by JOIN
281 * USING/NATURAL JOIN, both leftattnos[i] and rightattnos[i] are nonzero.
282 * Note that a simple reference might be to a child RTE column that's been
283 * dropped; but that's OK since the column could not be used in the query.
285 * If it's a JOIN USING, usingNames holds the alias names selected for the
286 * merged columns (these might be different from the original USING list,
287 * if we had to modify names to achieve uniqueness).
289 int leftrti
; /* rangetable index of left child */
290 int rightrti
; /* rangetable index of right child */
291 int *leftattnos
; /* left-child varattnos of join cols, or 0 */
292 int *rightattnos
; /* right-child varattnos of join cols, or 0 */
293 List
*usingNames
; /* names assigned to merged columns */
296 /* This macro is analogous to rt_fetch(), but for deparse_columns structs */
297 #define deparse_columns_fetch(rangetable_index, dpns) \
298 ((deparse_columns *) list_nth((dpns)->rtable_columns, (rangetable_index)-1))
301 * Entry in set_rtable_names' hash table
305 char name
[NAMEDATALEN
]; /* Hash key --- must be first */
306 int counter
; /* Largest addition used so far for name */
309 /* Callback signature for resolve_special_varno() */
310 typedef void (*rsv_callback
) (Node
*node
, deparse_context
*context
,
318 static SPIPlanPtr plan_getrulebyoid
= NULL
;
319 static const char *const query_getrulebyoid
= "SELECT * FROM pg_catalog.pg_rewrite WHERE oid = $1";
320 static SPIPlanPtr plan_getviewrule
= NULL
;
321 static const char *const query_getviewrule
= "SELECT * FROM pg_catalog.pg_rewrite WHERE ev_class = $1 AND rulename = $2";
324 bool quote_all_identifiers
= false;
330 * Most of these functions used to use fixed-size buffers to build their
331 * results. Now, they take an (already initialized) StringInfo object
332 * as a parameter, and append their text output to its contents.
335 static char *deparse_expression_pretty(Node
*expr
, List
*dpcontext
,
336 bool forceprefix
, bool showimplicit
,
337 int prettyFlags
, int startIndent
);
338 static char *pg_get_viewdef_worker(Oid viewoid
,
339 int prettyFlags
, int wrapColumn
);
340 static char *pg_get_triggerdef_worker(Oid trigid
, bool pretty
);
341 static int decompile_column_index_array(Datum column_index_array
, Oid relId
,
343 static char *pg_get_ruledef_worker(Oid ruleoid
, int prettyFlags
);
344 static char *pg_get_indexdef_worker(Oid indexrelid
, int colno
,
345 const Oid
*excludeOps
,
346 bool attrsOnly
, bool keysOnly
,
347 bool showTblSpc
, bool inherits
,
348 int prettyFlags
, bool missing_ok
);
349 static char *pg_get_statisticsobj_worker(Oid statextid
, bool columns_only
,
351 static char *pg_get_partkeydef_worker(Oid relid
, int prettyFlags
,
352 bool attrsOnly
, bool missing_ok
);
353 static char *pg_get_constraintdef_worker(Oid constraintId
, bool fullCommand
,
354 int prettyFlags
, bool missing_ok
);
355 static text
*pg_get_expr_worker(text
*expr
, Oid relid
, int prettyFlags
);
356 static int print_function_arguments(StringInfo buf
, HeapTuple proctup
,
357 bool print_table_args
, bool print_defaults
);
358 static void print_function_rettype(StringInfo buf
, HeapTuple proctup
);
359 static void print_function_trftypes(StringInfo buf
, HeapTuple proctup
);
360 static void print_function_sqlbody(StringInfo buf
, HeapTuple proctup
);
361 static void set_rtable_names(deparse_namespace
*dpns
, List
*parent_namespaces
,
362 Bitmapset
*rels_used
);
363 static void set_deparse_for_query(deparse_namespace
*dpns
, Query
*query
,
364 List
*parent_namespaces
);
365 static void set_simple_column_names(deparse_namespace
*dpns
);
366 static bool has_dangerous_join_using(deparse_namespace
*dpns
, Node
*jtnode
);
367 static void set_using_names(deparse_namespace
*dpns
, Node
*jtnode
,
369 static void set_relation_column_names(deparse_namespace
*dpns
,
371 deparse_columns
*colinfo
);
372 static void set_join_column_names(deparse_namespace
*dpns
, RangeTblEntry
*rte
,
373 deparse_columns
*colinfo
);
374 static bool colname_is_unique(const char *colname
, deparse_namespace
*dpns
,
375 deparse_columns
*colinfo
);
376 static char *make_colname_unique(char *colname
, deparse_namespace
*dpns
,
377 deparse_columns
*colinfo
);
378 static void expand_colnames_array_to(deparse_columns
*colinfo
, int n
);
379 static void identify_join_columns(JoinExpr
*j
, RangeTblEntry
*jrte
,
380 deparse_columns
*colinfo
);
381 static char *get_rtable_name(int rtindex
, deparse_context
*context
);
382 static void set_deparse_plan(deparse_namespace
*dpns
, Plan
*plan
);
383 static Plan
*find_recursive_union(deparse_namespace
*dpns
,
384 WorkTableScan
*wtscan
);
385 static void push_child_plan(deparse_namespace
*dpns
, Plan
*plan
,
386 deparse_namespace
*save_dpns
);
387 static void pop_child_plan(deparse_namespace
*dpns
,
388 deparse_namespace
*save_dpns
);
389 static void push_ancestor_plan(deparse_namespace
*dpns
, ListCell
*ancestor_cell
,
390 deparse_namespace
*save_dpns
);
391 static void pop_ancestor_plan(deparse_namespace
*dpns
,
392 deparse_namespace
*save_dpns
);
393 static void make_ruledef(StringInfo buf
, HeapTuple ruletup
, TupleDesc rulettc
,
395 static void make_viewdef(StringInfo buf
, HeapTuple ruletup
, TupleDesc rulettc
,
396 int prettyFlags
, int wrapColumn
);
397 static void get_query_def(Query
*query
, StringInfo buf
, List
*parentnamespace
,
398 TupleDesc resultDesc
, bool colNamesVisible
,
399 int prettyFlags
, int wrapColumn
, int startIndent
);
400 static void get_values_def(List
*values_lists
, deparse_context
*context
);
401 static void get_with_clause(Query
*query
, deparse_context
*context
);
402 static void get_select_query_def(Query
*query
, deparse_context
*context
);
403 static void get_insert_query_def(Query
*query
, deparse_context
*context
);
404 static void get_update_query_def(Query
*query
, deparse_context
*context
);
405 static void get_update_query_targetlist_def(Query
*query
, List
*targetList
,
406 deparse_context
*context
,
408 static void get_delete_query_def(Query
*query
, deparse_context
*context
);
409 static void get_merge_query_def(Query
*query
, deparse_context
*context
);
410 static void get_utility_query_def(Query
*query
, deparse_context
*context
);
411 static void get_basic_select_query(Query
*query
, deparse_context
*context
);
412 static void get_target_list(List
*targetList
, deparse_context
*context
);
413 static void get_setop_query(Node
*setOp
, Query
*query
,
414 deparse_context
*context
);
415 static Node
*get_rule_sortgroupclause(Index ref
, List
*tlist
,
417 deparse_context
*context
);
418 static void get_rule_groupingset(GroupingSet
*gset
, List
*targetlist
,
419 bool omit_parens
, deparse_context
*context
);
420 static void get_rule_orderby(List
*orderList
, List
*targetList
,
421 bool force_colno
, deparse_context
*context
);
422 static void get_rule_windowclause(Query
*query
, deparse_context
*context
);
423 static void get_rule_windowspec(WindowClause
*wc
, List
*targetList
,
424 deparse_context
*context
);
425 static char *get_variable(Var
*var
, int levelsup
, bool istoplevel
,
426 deparse_context
*context
);
427 static void get_special_variable(Node
*node
, deparse_context
*context
,
429 static void resolve_special_varno(Node
*node
, deparse_context
*context
,
430 rsv_callback callback
, void *callback_arg
);
431 static Node
*find_param_referent(Param
*param
, deparse_context
*context
,
432 deparse_namespace
**dpns_p
, ListCell
**ancestor_cell_p
);
433 static SubPlan
*find_param_generator(Param
*param
, deparse_context
*context
,
435 static SubPlan
*find_param_generator_initplan(Param
*param
, Plan
*plan
,
437 static void get_parameter(Param
*param
, deparse_context
*context
);
438 static const char *get_simple_binary_op_name(OpExpr
*expr
);
439 static bool isSimpleNode(Node
*node
, Node
*parentNode
, int prettyFlags
);
440 static void appendContextKeyword(deparse_context
*context
, const char *str
,
441 int indentBefore
, int indentAfter
, int indentPlus
);
442 static void removeStringInfoSpaces(StringInfo str
);
443 static void get_rule_expr(Node
*node
, deparse_context
*context
,
445 static void get_rule_expr_toplevel(Node
*node
, deparse_context
*context
,
447 static void get_rule_list_toplevel(List
*lst
, deparse_context
*context
,
449 static void get_rule_expr_funccall(Node
*node
, deparse_context
*context
,
451 static bool looks_like_function(Node
*node
);
452 static void get_oper_expr(OpExpr
*expr
, deparse_context
*context
);
453 static void get_func_expr(FuncExpr
*expr
, deparse_context
*context
,
455 static void get_agg_expr(Aggref
*aggref
, deparse_context
*context
,
456 Aggref
*original_aggref
);
457 static void get_agg_expr_helper(Aggref
*aggref
, deparse_context
*context
,
458 Aggref
*original_aggref
, const char *funcname
,
459 const char *options
, bool is_json_objectagg
);
460 static void get_agg_combine_expr(Node
*node
, deparse_context
*context
,
462 static void get_windowfunc_expr(WindowFunc
*wfunc
, deparse_context
*context
);
463 static void get_windowfunc_expr_helper(WindowFunc
*wfunc
, deparse_context
*context
,
464 const char *funcname
, const char *options
,
465 bool is_json_objectagg
);
466 static bool get_func_sql_syntax(FuncExpr
*expr
, deparse_context
*context
);
467 static void get_coercion_expr(Node
*arg
, deparse_context
*context
,
468 Oid resulttype
, int32 resulttypmod
,
470 static void get_const_expr(Const
*constval
, deparse_context
*context
,
472 static void get_const_collation(Const
*constval
, deparse_context
*context
);
473 static void get_json_format(JsonFormat
*format
, StringInfo buf
);
474 static void get_json_returning(JsonReturning
*returning
, StringInfo buf
,
475 bool json_format_by_default
);
476 static void get_json_constructor(JsonConstructorExpr
*ctor
,
477 deparse_context
*context
, bool showimplicit
);
478 static void get_json_constructor_options(JsonConstructorExpr
*ctor
,
480 static void get_json_agg_constructor(JsonConstructorExpr
*ctor
,
481 deparse_context
*context
,
482 const char *funcname
,
483 bool is_json_objectagg
);
484 static void simple_quote_literal(StringInfo buf
, const char *val
);
485 static void get_sublink_expr(SubLink
*sublink
, deparse_context
*context
);
486 static void get_tablefunc(TableFunc
*tf
, deparse_context
*context
,
488 static void get_from_clause(Query
*query
, const char *prefix
,
489 deparse_context
*context
);
490 static void get_from_clause_item(Node
*jtnode
, Query
*query
,
491 deparse_context
*context
);
492 static void get_rte_alias(RangeTblEntry
*rte
, int varno
, bool use_as
,
493 deparse_context
*context
);
494 static void get_column_alias_list(deparse_columns
*colinfo
,
495 deparse_context
*context
);
496 static void get_from_clause_coldeflist(RangeTblFunction
*rtfunc
,
497 deparse_columns
*colinfo
,
498 deparse_context
*context
);
499 static void get_tablesample_def(TableSampleClause
*tablesample
,
500 deparse_context
*context
);
501 static void get_opclass_name(Oid opclass
, Oid actual_datatype
,
503 static Node
*processIndirection(Node
*node
, deparse_context
*context
);
504 static void printSubscripts(SubscriptingRef
*sbsref
, deparse_context
*context
);
505 static char *get_relation_name(Oid relid
);
506 static char *generate_relation_name(Oid relid
, List
*namespaces
);
507 static char *generate_qualified_relation_name(Oid relid
);
508 static char *generate_function_name(Oid funcid
, int nargs
,
509 List
*argnames
, Oid
*argtypes
,
510 bool has_variadic
, bool *use_variadic_p
,
512 static char *generate_operator_name(Oid operid
, Oid arg1
, Oid arg2
);
513 static void add_cast_to(StringInfo buf
, Oid typid
);
514 static char *generate_qualified_type_name(Oid typid
);
515 static text
*string_to_text(char *str
);
516 static char *flatten_reloptions(Oid relid
);
517 static void get_reloptions(StringInfo buf
, Datum reloptions
);
518 static void get_json_path_spec(Node
*path_spec
, deparse_context
*context
,
520 static void get_json_table_columns(TableFunc
*tf
, JsonTablePathScan
*scan
,
521 deparse_context
*context
,
523 static void get_json_table_nested_columns(TableFunc
*tf
, JsonTablePlan
*plan
,
524 deparse_context
*context
,
528 #define only_marker(rte) ((rte)->inh ? "" : "ONLY ")
532 * pg_get_ruledef - Do it all and return a text
533 * that could be used as a statement
534 * to recreate the rule
538 pg_get_ruledef(PG_FUNCTION_ARGS
)
540 Oid ruleoid
= PG_GETARG_OID(0);
544 prettyFlags
= PRETTYFLAG_INDENT
;
546 res
= pg_get_ruledef_worker(ruleoid
, prettyFlags
);
551 PG_RETURN_TEXT_P(string_to_text(res
));
556 pg_get_ruledef_ext(PG_FUNCTION_ARGS
)
558 Oid ruleoid
= PG_GETARG_OID(0);
559 bool pretty
= PG_GETARG_BOOL(1);
563 prettyFlags
= GET_PRETTY_FLAGS(pretty
);
565 res
= pg_get_ruledef_worker(ruleoid
, prettyFlags
);
570 PG_RETURN_TEXT_P(string_to_text(res
));
575 pg_get_ruledef_worker(Oid ruleoid
, int prettyFlags
)
585 * Do this first so that string is alloc'd in outer context not SPI's.
587 initStringInfo(&buf
);
590 * Connect to SPI manager
592 if (SPI_connect() != SPI_OK_CONNECT
)
593 elog(ERROR
, "SPI_connect failed");
596 * On the first call prepare the plan to lookup pg_rewrite. We read
597 * pg_rewrite over the SPI manager instead of using the syscache to be
598 * checked for read access on pg_rewrite.
600 if (plan_getrulebyoid
== NULL
)
605 argtypes
[0] = OIDOID
;
606 plan
= SPI_prepare(query_getrulebyoid
, 1, argtypes
);
608 elog(ERROR
, "SPI_prepare failed for \"%s\"", query_getrulebyoid
);
610 plan_getrulebyoid
= plan
;
614 * Get the pg_rewrite tuple for this rule
616 args
[0] = ObjectIdGetDatum(ruleoid
);
618 spirc
= SPI_execute_plan(plan_getrulebyoid
, args
, nulls
, true, 0);
619 if (spirc
!= SPI_OK_SELECT
)
620 elog(ERROR
, "failed to get pg_rewrite tuple for rule %u", ruleoid
);
621 if (SPI_processed
!= 1)
624 * There is no tuple data available here, just keep the output buffer
631 * Get the rule's definition and put it into executor's memory
633 ruletup
= SPI_tuptable
->vals
[0];
634 rulettc
= SPI_tuptable
->tupdesc
;
635 make_ruledef(&buf
, ruletup
, rulettc
, prettyFlags
);
639 * Disconnect from SPI manager
641 if (SPI_finish() != SPI_OK_FINISH
)
642 elog(ERROR
, "SPI_finish failed");
652 * pg_get_viewdef - Mainly the same thing, but we
653 * only return the SELECT part of a view
657 pg_get_viewdef(PG_FUNCTION_ARGS
)
660 Oid viewoid
= PG_GETARG_OID(0);
664 prettyFlags
= PRETTYFLAG_INDENT
;
666 res
= pg_get_viewdef_worker(viewoid
, prettyFlags
, WRAP_COLUMN_DEFAULT
);
671 PG_RETURN_TEXT_P(string_to_text(res
));
676 pg_get_viewdef_ext(PG_FUNCTION_ARGS
)
679 Oid viewoid
= PG_GETARG_OID(0);
680 bool pretty
= PG_GETARG_BOOL(1);
684 prettyFlags
= GET_PRETTY_FLAGS(pretty
);
686 res
= pg_get_viewdef_worker(viewoid
, prettyFlags
, WRAP_COLUMN_DEFAULT
);
691 PG_RETURN_TEXT_P(string_to_text(res
));
695 pg_get_viewdef_wrap(PG_FUNCTION_ARGS
)
698 Oid viewoid
= PG_GETARG_OID(0);
699 int wrap
= PG_GETARG_INT32(1);
703 /* calling this implies we want pretty printing */
704 prettyFlags
= GET_PRETTY_FLAGS(true);
706 res
= pg_get_viewdef_worker(viewoid
, prettyFlags
, wrap
);
711 PG_RETURN_TEXT_P(string_to_text(res
));
715 pg_get_viewdef_name(PG_FUNCTION_ARGS
)
717 /* By qualified name */
718 text
*viewname
= PG_GETARG_TEXT_PP(0);
724 prettyFlags
= PRETTYFLAG_INDENT
;
726 /* Look up view name. Can't lock it - we might not have privileges. */
727 viewrel
= makeRangeVarFromNameList(textToQualifiedNameList(viewname
));
728 viewoid
= RangeVarGetRelid(viewrel
, NoLock
, false);
730 res
= pg_get_viewdef_worker(viewoid
, prettyFlags
, WRAP_COLUMN_DEFAULT
);
735 PG_RETURN_TEXT_P(string_to_text(res
));
740 pg_get_viewdef_name_ext(PG_FUNCTION_ARGS
)
742 /* By qualified name */
743 text
*viewname
= PG_GETARG_TEXT_PP(0);
744 bool pretty
= PG_GETARG_BOOL(1);
750 prettyFlags
= GET_PRETTY_FLAGS(pretty
);
752 /* Look up view name. Can't lock it - we might not have privileges. */
753 viewrel
= makeRangeVarFromNameList(textToQualifiedNameList(viewname
));
754 viewoid
= RangeVarGetRelid(viewrel
, NoLock
, false);
756 res
= pg_get_viewdef_worker(viewoid
, prettyFlags
, WRAP_COLUMN_DEFAULT
);
761 PG_RETURN_TEXT_P(string_to_text(res
));
765 * Common code for by-OID and by-name variants of pg_get_viewdef
768 pg_get_viewdef_worker(Oid viewoid
, int prettyFlags
, int wrapColumn
)
778 * Do this first so that string is alloc'd in outer context not SPI's.
780 initStringInfo(&buf
);
783 * Connect to SPI manager
785 if (SPI_connect() != SPI_OK_CONNECT
)
786 elog(ERROR
, "SPI_connect failed");
789 * On the first call prepare the plan to lookup pg_rewrite. We read
790 * pg_rewrite over the SPI manager instead of using the syscache to be
791 * checked for read access on pg_rewrite.
793 if (plan_getviewrule
== NULL
)
798 argtypes
[0] = OIDOID
;
799 argtypes
[1] = NAMEOID
;
800 plan
= SPI_prepare(query_getviewrule
, 2, argtypes
);
802 elog(ERROR
, "SPI_prepare failed for \"%s\"", query_getviewrule
);
804 plan_getviewrule
= plan
;
808 * Get the pg_rewrite tuple for the view's SELECT rule
810 args
[0] = ObjectIdGetDatum(viewoid
);
811 args
[1] = DirectFunctionCall1(namein
, CStringGetDatum(ViewSelectRuleName
));
814 spirc
= SPI_execute_plan(plan_getviewrule
, args
, nulls
, true, 0);
815 if (spirc
!= SPI_OK_SELECT
)
816 elog(ERROR
, "failed to get pg_rewrite tuple for view %u", viewoid
);
817 if (SPI_processed
!= 1)
820 * There is no tuple data available here, just keep the output buffer
827 * Get the rule's definition and put it into executor's memory
829 ruletup
= SPI_tuptable
->vals
[0];
830 rulettc
= SPI_tuptable
->tupdesc
;
831 make_viewdef(&buf
, ruletup
, rulettc
, prettyFlags
, wrapColumn
);
835 * Disconnect from SPI manager
837 if (SPI_finish() != SPI_OK_FINISH
)
838 elog(ERROR
, "SPI_finish failed");
847 * pg_get_triggerdef - Get the definition of a trigger
851 pg_get_triggerdef(PG_FUNCTION_ARGS
)
853 Oid trigid
= PG_GETARG_OID(0);
856 res
= pg_get_triggerdef_worker(trigid
, false);
861 PG_RETURN_TEXT_P(string_to_text(res
));
865 pg_get_triggerdef_ext(PG_FUNCTION_ARGS
)
867 Oid trigid
= PG_GETARG_OID(0);
868 bool pretty
= PG_GETARG_BOOL(1);
871 res
= pg_get_triggerdef_worker(trigid
, pretty
);
876 PG_RETURN_TEXT_P(string_to_text(res
));
880 pg_get_triggerdef_worker(Oid trigid
, bool pretty
)
883 Form_pg_trigger trigrec
;
896 * Fetch the pg_trigger tuple by the Oid of the trigger
898 tgrel
= table_open(TriggerRelationId
, AccessShareLock
);
900 ScanKeyInit(&skey
[0],
902 BTEqualStrategyNumber
, F_OIDEQ
,
903 ObjectIdGetDatum(trigid
));
905 tgscan
= systable_beginscan(tgrel
, TriggerOidIndexId
, true,
908 ht_trig
= systable_getnext(tgscan
);
910 if (!HeapTupleIsValid(ht_trig
))
912 systable_endscan(tgscan
);
913 table_close(tgrel
, AccessShareLock
);
917 trigrec
= (Form_pg_trigger
) GETSTRUCT(ht_trig
);
920 * Start the trigger definition. Note that the trigger's name should never
921 * be schema-qualified, but the trigger rel's name may be.
923 initStringInfo(&buf
);
925 tgname
= NameStr(trigrec
->tgname
);
926 appendStringInfo(&buf
, "CREATE %sTRIGGER %s ",
927 OidIsValid(trigrec
->tgconstraint
) ? "CONSTRAINT " : "",
928 quote_identifier(tgname
));
930 if (TRIGGER_FOR_BEFORE(trigrec
->tgtype
))
931 appendStringInfoString(&buf
, "BEFORE");
932 else if (TRIGGER_FOR_AFTER(trigrec
->tgtype
))
933 appendStringInfoString(&buf
, "AFTER");
934 else if (TRIGGER_FOR_INSTEAD(trigrec
->tgtype
))
935 appendStringInfoString(&buf
, "INSTEAD OF");
937 elog(ERROR
, "unexpected tgtype value: %d", trigrec
->tgtype
);
939 if (TRIGGER_FOR_INSERT(trigrec
->tgtype
))
941 appendStringInfoString(&buf
, " INSERT");
944 if (TRIGGER_FOR_DELETE(trigrec
->tgtype
))
947 appendStringInfoString(&buf
, " OR DELETE");
949 appendStringInfoString(&buf
, " DELETE");
952 if (TRIGGER_FOR_UPDATE(trigrec
->tgtype
))
955 appendStringInfoString(&buf
, " OR UPDATE");
957 appendStringInfoString(&buf
, " UPDATE");
959 /* tgattr is first var-width field, so OK to access directly */
960 if (trigrec
->tgattr
.dim1
> 0)
964 appendStringInfoString(&buf
, " OF ");
965 for (i
= 0; i
< trigrec
->tgattr
.dim1
; i
++)
970 appendStringInfoString(&buf
, ", ");
971 attname
= get_attname(trigrec
->tgrelid
,
972 trigrec
->tgattr
.values
[i
], false);
973 appendStringInfoString(&buf
, quote_identifier(attname
));
977 if (TRIGGER_FOR_TRUNCATE(trigrec
->tgtype
))
980 appendStringInfoString(&buf
, " OR TRUNCATE");
982 appendStringInfoString(&buf
, " TRUNCATE");
987 * In non-pretty mode, always schema-qualify the target table name for
988 * safety. In pretty mode, schema-qualify only if not visible.
990 appendStringInfo(&buf
, " ON %s ",
992 generate_relation_name(trigrec
->tgrelid
, NIL
) :
993 generate_qualified_relation_name(trigrec
->tgrelid
));
995 if (OidIsValid(trigrec
->tgconstraint
))
997 if (OidIsValid(trigrec
->tgconstrrelid
))
998 appendStringInfo(&buf
, "FROM %s ",
999 generate_relation_name(trigrec
->tgconstrrelid
, NIL
));
1000 if (!trigrec
->tgdeferrable
)
1001 appendStringInfoString(&buf
, "NOT ");
1002 appendStringInfoString(&buf
, "DEFERRABLE INITIALLY ");
1003 if (trigrec
->tginitdeferred
)
1004 appendStringInfoString(&buf
, "DEFERRED ");
1006 appendStringInfoString(&buf
, "IMMEDIATE ");
1009 value
= fastgetattr(ht_trig
, Anum_pg_trigger_tgoldtable
,
1010 tgrel
->rd_att
, &isnull
);
1012 tgoldtable
= NameStr(*DatumGetName(value
));
1015 value
= fastgetattr(ht_trig
, Anum_pg_trigger_tgnewtable
,
1016 tgrel
->rd_att
, &isnull
);
1018 tgnewtable
= NameStr(*DatumGetName(value
));
1021 if (tgoldtable
!= NULL
|| tgnewtable
!= NULL
)
1023 appendStringInfoString(&buf
, "REFERENCING ");
1024 if (tgoldtable
!= NULL
)
1025 appendStringInfo(&buf
, "OLD TABLE AS %s ",
1026 quote_identifier(tgoldtable
));
1027 if (tgnewtable
!= NULL
)
1028 appendStringInfo(&buf
, "NEW TABLE AS %s ",
1029 quote_identifier(tgnewtable
));
1032 if (TRIGGER_FOR_ROW(trigrec
->tgtype
))
1033 appendStringInfoString(&buf
, "FOR EACH ROW ");
1035 appendStringInfoString(&buf
, "FOR EACH STATEMENT ");
1037 /* If the trigger has a WHEN qualification, add that */
1038 value
= fastgetattr(ht_trig
, Anum_pg_trigger_tgqual
,
1039 tgrel
->rd_att
, &isnull
);
1044 deparse_context context
;
1045 deparse_namespace dpns
;
1046 RangeTblEntry
*oldrte
;
1047 RangeTblEntry
*newrte
;
1049 appendStringInfoString(&buf
, "WHEN (");
1051 qual
= stringToNode(TextDatumGetCString(value
));
1053 relkind
= get_rel_relkind(trigrec
->tgrelid
);
1055 /* Build minimal OLD and NEW RTEs for the rel */
1056 oldrte
= makeNode(RangeTblEntry
);
1057 oldrte
->rtekind
= RTE_RELATION
;
1058 oldrte
->relid
= trigrec
->tgrelid
;
1059 oldrte
->relkind
= relkind
;
1060 oldrte
->rellockmode
= AccessShareLock
;
1061 oldrte
->alias
= makeAlias("old", NIL
);
1062 oldrte
->eref
= oldrte
->alias
;
1063 oldrte
->lateral
= false;
1064 oldrte
->inh
= false;
1065 oldrte
->inFromCl
= true;
1067 newrte
= makeNode(RangeTblEntry
);
1068 newrte
->rtekind
= RTE_RELATION
;
1069 newrte
->relid
= trigrec
->tgrelid
;
1070 newrte
->relkind
= relkind
;
1071 newrte
->rellockmode
= AccessShareLock
;
1072 newrte
->alias
= makeAlias("new", NIL
);
1073 newrte
->eref
= newrte
->alias
;
1074 newrte
->lateral
= false;
1075 newrte
->inh
= false;
1076 newrte
->inFromCl
= true;
1078 /* Build two-element rtable */
1079 memset(&dpns
, 0, sizeof(dpns
));
1080 dpns
.rtable
= list_make2(oldrte
, newrte
);
1081 dpns
.subplans
= NIL
;
1083 dpns
.appendrels
= NULL
;
1084 set_rtable_names(&dpns
, NIL
, NULL
);
1085 set_simple_column_names(&dpns
);
1087 /* Set up context with one-deep namespace stack */
1089 context
.namespaces
= list_make1(&dpns
);
1090 context
.resultDesc
= NULL
;
1091 context
.targetList
= NIL
;
1092 context
.windowClause
= NIL
;
1093 context
.varprefix
= true;
1094 context
.prettyFlags
= GET_PRETTY_FLAGS(pretty
);
1095 context
.wrapColumn
= WRAP_COLUMN_DEFAULT
;
1096 context
.indentLevel
= PRETTYINDENT_STD
;
1097 context
.colNamesVisible
= true;
1098 context
.inGroupBy
= false;
1099 context
.varInOrderBy
= false;
1100 context
.appendparents
= NULL
;
1102 get_rule_expr(qual
, &context
, false);
1104 appendStringInfoString(&buf
, ") ");
1107 appendStringInfo(&buf
, "EXECUTE FUNCTION %s(",
1108 generate_function_name(trigrec
->tgfoid
, 0,
1110 false, NULL
, false));
1112 if (trigrec
->tgnargs
> 0)
1117 value
= fastgetattr(ht_trig
, Anum_pg_trigger_tgargs
,
1118 tgrel
->rd_att
, &isnull
);
1120 elog(ERROR
, "tgargs is null for trigger %u", trigid
);
1121 p
= (char *) VARDATA_ANY(DatumGetByteaPP(value
));
1122 for (i
= 0; i
< trigrec
->tgnargs
; i
++)
1125 appendStringInfoString(&buf
, ", ");
1126 simple_quote_literal(&buf
, p
);
1127 /* advance p to next string embedded in tgargs */
1134 /* We deliberately do not put semi-colon at end */
1135 appendStringInfoChar(&buf
, ')');
1138 systable_endscan(tgscan
);
1140 table_close(tgrel
, AccessShareLock
);
1146 * pg_get_indexdef - Get the definition of an index
1148 * In the extended version, there is a colno argument as well as pretty bool.
1149 * if colno == 0, we want a complete index definition.
1150 * if colno > 0, we only want the Nth index key's variable or expression.
1152 * Note that the SQL-function versions of this omit any info about the
1153 * index tablespace; this is intentional because pg_dump wants it that way.
1154 * However pg_get_indexdef_string() includes the index tablespace.
1158 pg_get_indexdef(PG_FUNCTION_ARGS
)
1160 Oid indexrelid
= PG_GETARG_OID(0);
1164 prettyFlags
= PRETTYFLAG_INDENT
;
1166 res
= pg_get_indexdef_worker(indexrelid
, 0, NULL
,
1174 PG_RETURN_TEXT_P(string_to_text(res
));
1178 pg_get_indexdef_ext(PG_FUNCTION_ARGS
)
1180 Oid indexrelid
= PG_GETARG_OID(0);
1181 int32 colno
= PG_GETARG_INT32(1);
1182 bool pretty
= PG_GETARG_BOOL(2);
1186 prettyFlags
= GET_PRETTY_FLAGS(pretty
);
1188 res
= pg_get_indexdef_worker(indexrelid
, colno
, NULL
,
1196 PG_RETURN_TEXT_P(string_to_text(res
));
1200 * Internal version for use by ALTER TABLE.
1201 * Includes a tablespace clause in the result.
1202 * Returns a palloc'd C string; no pretty-printing.
1205 pg_get_indexdef_string(Oid indexrelid
)
1207 return pg_get_indexdef_worker(indexrelid
, 0, NULL
,
1213 /* Internal version that just reports the key-column definitions */
1215 pg_get_indexdef_columns(Oid indexrelid
, bool pretty
)
1219 prettyFlags
= GET_PRETTY_FLAGS(pretty
);
1221 return pg_get_indexdef_worker(indexrelid
, 0, NULL
,
1224 prettyFlags
, false);
1227 /* Internal version, extensible with flags to control its behavior */
1229 pg_get_indexdef_columns_extended(Oid indexrelid
, bits16 flags
)
1231 bool pretty
= ((flags
& RULE_INDEXDEF_PRETTY
) != 0);
1232 bool keys_only
= ((flags
& RULE_INDEXDEF_KEYS_ONLY
) != 0);
1235 prettyFlags
= GET_PRETTY_FLAGS(pretty
);
1237 return pg_get_indexdef_worker(indexrelid
, 0, NULL
,
1240 prettyFlags
, false);
1244 * Internal workhorse to decompile an index definition.
1246 * This is now used for exclusion constraints as well: if excludeOps is not
1247 * NULL then it points to an array of exclusion operator OIDs.
1250 pg_get_indexdef_worker(Oid indexrelid
, int colno
,
1251 const Oid
*excludeOps
,
1252 bool attrsOnly
, bool keysOnly
,
1253 bool showTblSpc
, bool inherits
,
1254 int prettyFlags
, bool missing_ok
)
1256 /* might want a separate isConstraint parameter later */
1257 bool isConstraint
= (excludeOps
!= NULL
);
1259 HeapTuple ht_idxrel
;
1261 Form_pg_index idxrec
;
1262 Form_pg_class idxrelrec
;
1264 IndexAmRoutine
*amroutine
;
1266 ListCell
*indexpr_item
;
1271 Datum indclassDatum
;
1272 Datum indoptionDatum
;
1273 oidvector
*indcollation
;
1274 oidvector
*indclass
;
1275 int2vector
*indoption
;
1281 * Fetch the pg_index tuple by the Oid of the index
1283 ht_idx
= SearchSysCache1(INDEXRELID
, ObjectIdGetDatum(indexrelid
));
1284 if (!HeapTupleIsValid(ht_idx
))
1288 elog(ERROR
, "cache lookup failed for index %u", indexrelid
);
1290 idxrec
= (Form_pg_index
) GETSTRUCT(ht_idx
);
1292 indrelid
= idxrec
->indrelid
;
1293 Assert(indexrelid
== idxrec
->indexrelid
);
1295 /* Must get indcollation, indclass, and indoption the hard way */
1296 indcollDatum
= SysCacheGetAttrNotNull(INDEXRELID
, ht_idx
,
1297 Anum_pg_index_indcollation
);
1298 indcollation
= (oidvector
*) DatumGetPointer(indcollDatum
);
1300 indclassDatum
= SysCacheGetAttrNotNull(INDEXRELID
, ht_idx
,
1301 Anum_pg_index_indclass
);
1302 indclass
= (oidvector
*) DatumGetPointer(indclassDatum
);
1304 indoptionDatum
= SysCacheGetAttrNotNull(INDEXRELID
, ht_idx
,
1305 Anum_pg_index_indoption
);
1306 indoption
= (int2vector
*) DatumGetPointer(indoptionDatum
);
1309 * Fetch the pg_class tuple of the index relation
1311 ht_idxrel
= SearchSysCache1(RELOID
, ObjectIdGetDatum(indexrelid
));
1312 if (!HeapTupleIsValid(ht_idxrel
))
1313 elog(ERROR
, "cache lookup failed for relation %u", indexrelid
);
1314 idxrelrec
= (Form_pg_class
) GETSTRUCT(ht_idxrel
);
1317 * Fetch the pg_am tuple of the index' access method
1319 ht_am
= SearchSysCache1(AMOID
, ObjectIdGetDatum(idxrelrec
->relam
));
1320 if (!HeapTupleIsValid(ht_am
))
1321 elog(ERROR
, "cache lookup failed for access method %u",
1323 amrec
= (Form_pg_am
) GETSTRUCT(ht_am
);
1325 /* Fetch the index AM's API struct */
1326 amroutine
= GetIndexAmRoutine(amrec
->amhandler
);
1329 * Get the index expressions, if any. (NOTE: we do not use the relcache
1330 * versions of the expressions and predicate, because we want to display
1331 * non-const-folded expressions.)
1333 if (!heap_attisnull(ht_idx
, Anum_pg_index_indexprs
, NULL
))
1338 exprsDatum
= SysCacheGetAttrNotNull(INDEXRELID
, ht_idx
,
1339 Anum_pg_index_indexprs
);
1340 exprsString
= TextDatumGetCString(exprsDatum
);
1341 indexprs
= (List
*) stringToNode(exprsString
);
1347 indexpr_item
= list_head(indexprs
);
1349 context
= deparse_context_for(get_relation_name(indrelid
), indrelid
);
1352 * Start the index definition. Note that the index's name should never be
1353 * schema-qualified, but the indexed rel's name may be.
1355 initStringInfo(&buf
);
1360 appendStringInfo(&buf
, "CREATE %sINDEX %s ON %s%s USING %s (",
1361 idxrec
->indisunique
? "UNIQUE " : "",
1362 quote_identifier(NameStr(idxrelrec
->relname
)),
1363 idxrelrec
->relkind
== RELKIND_PARTITIONED_INDEX
1364 && !inherits
? "ONLY " : "",
1365 (prettyFlags
& PRETTYFLAG_SCHEMA
) ?
1366 generate_relation_name(indrelid
, NIL
) :
1367 generate_qualified_relation_name(indrelid
),
1368 quote_identifier(NameStr(amrec
->amname
)));
1369 else /* currently, must be EXCLUDE constraint */
1370 appendStringInfo(&buf
, "EXCLUDE USING %s (",
1371 quote_identifier(NameStr(amrec
->amname
)));
1375 * Report the indexed attributes
1378 for (keyno
= 0; keyno
< idxrec
->indnatts
; keyno
++)
1380 AttrNumber attnum
= idxrec
->indkey
.values
[keyno
];
1382 Oid keycolcollation
;
1385 * Ignore non-key attributes if told to.
1387 if (keysOnly
&& keyno
>= idxrec
->indnkeyatts
)
1390 /* Otherwise, print INCLUDE to divide key and non-key attrs. */
1391 if (!colno
&& keyno
== idxrec
->indnkeyatts
)
1393 appendStringInfoString(&buf
, ") INCLUDE (");
1398 appendStringInfoString(&buf
, sep
);
1403 /* Simple index column */
1407 attname
= get_attname(indrelid
, attnum
, false);
1408 if (!colno
|| colno
== keyno
+ 1)
1409 appendStringInfoString(&buf
, quote_identifier(attname
));
1410 get_atttypetypmodcoll(indrelid
, attnum
,
1411 &keycoltype
, &keycoltypmod
,
1416 /* expressional index */
1419 if (indexpr_item
== NULL
)
1420 elog(ERROR
, "too few entries in indexprs list");
1421 indexkey
= (Node
*) lfirst(indexpr_item
);
1422 indexpr_item
= lnext(indexprs
, indexpr_item
);
1424 str
= deparse_expression_pretty(indexkey
, context
, false, false,
1426 if (!colno
|| colno
== keyno
+ 1)
1428 /* Need parens if it's not a bare function call */
1429 if (looks_like_function(indexkey
))
1430 appendStringInfoString(&buf
, str
);
1432 appendStringInfo(&buf
, "(%s)", str
);
1434 keycoltype
= exprType(indexkey
);
1435 keycolcollation
= exprCollation(indexkey
);
1438 /* Print additional decoration for (selected) key columns */
1439 if (!attrsOnly
&& keyno
< idxrec
->indnkeyatts
&&
1440 (!colno
|| colno
== keyno
+ 1))
1442 int16 opt
= indoption
->values
[keyno
];
1443 Oid indcoll
= indcollation
->values
[keyno
];
1444 Datum attoptions
= get_attoptions(indexrelid
, keyno
+ 1);
1445 bool has_options
= attoptions
!= (Datum
) 0;
1447 /* Add collation, if not default for column */
1448 if (OidIsValid(indcoll
) && indcoll
!= keycolcollation
)
1449 appendStringInfo(&buf
, " COLLATE %s",
1450 generate_collation_name((indcoll
)));
1452 /* Add the operator class name, if not default */
1453 get_opclass_name(indclass
->values
[keyno
],
1454 has_options
? InvalidOid
: keycoltype
, &buf
);
1458 appendStringInfoString(&buf
, " (");
1459 get_reloptions(&buf
, attoptions
);
1460 appendStringInfoChar(&buf
, ')');
1463 /* Add options if relevant */
1464 if (amroutine
->amcanorder
)
1466 /* if it supports sort ordering, report DESC and NULLS opts */
1467 if (opt
& INDOPTION_DESC
)
1469 appendStringInfoString(&buf
, " DESC");
1470 /* NULLS FIRST is the default in this case */
1471 if (!(opt
& INDOPTION_NULLS_FIRST
))
1472 appendStringInfoString(&buf
, " NULLS LAST");
1476 if (opt
& INDOPTION_NULLS_FIRST
)
1477 appendStringInfoString(&buf
, " NULLS FIRST");
1481 /* Add the exclusion operator if relevant */
1482 if (excludeOps
!= NULL
)
1483 appendStringInfo(&buf
, " WITH %s",
1484 generate_operator_name(excludeOps
[keyno
],
1492 appendStringInfoChar(&buf
, ')');
1494 if (idxrec
->indnullsnotdistinct
)
1495 appendStringInfoString(&buf
, " NULLS NOT DISTINCT");
1498 * If it has options, append "WITH (options)"
1500 str
= flatten_reloptions(indexrelid
);
1503 appendStringInfo(&buf
, " WITH (%s)", str
);
1508 * Print tablespace, but only if requested
1514 tblspc
= get_rel_tablespace(indexrelid
);
1515 if (OidIsValid(tblspc
))
1518 appendStringInfoString(&buf
, " USING INDEX");
1519 appendStringInfo(&buf
, " TABLESPACE %s",
1520 quote_identifier(get_tablespace_name(tblspc
)));
1525 * If it's a partial index, decompile and append the predicate
1527 if (!heap_attisnull(ht_idx
, Anum_pg_index_indpred
, NULL
))
1533 /* Convert text string to node tree */
1534 predDatum
= SysCacheGetAttrNotNull(INDEXRELID
, ht_idx
,
1535 Anum_pg_index_indpred
);
1536 predString
= TextDatumGetCString(predDatum
);
1537 node
= (Node
*) stringToNode(predString
);
1541 str
= deparse_expression_pretty(node
, context
, false, false,
1544 appendStringInfo(&buf
, " WHERE (%s)", str
);
1546 appendStringInfo(&buf
, " WHERE %s", str
);
1551 ReleaseSysCache(ht_idx
);
1552 ReleaseSysCache(ht_idxrel
);
1553 ReleaseSysCache(ht_am
);
1561 * Public entry point to deparse one query parsetree.
1562 * The pretty flags are determined by GET_PRETTY_FLAGS(pretty).
1564 * The result is a palloc'd C string.
1568 pg_get_querydef(Query
*query
, bool pretty
)
1573 prettyFlags
= GET_PRETTY_FLAGS(pretty
);
1575 initStringInfo(&buf
);
1577 get_query_def(query
, &buf
, NIL
, NULL
, true,
1578 prettyFlags
, WRAP_COLUMN_DEFAULT
, 0);
1584 * pg_get_statisticsobjdef
1585 * Get the definition of an extended statistics object
1588 pg_get_statisticsobjdef(PG_FUNCTION_ARGS
)
1590 Oid statextid
= PG_GETARG_OID(0);
1593 res
= pg_get_statisticsobj_worker(statextid
, false, true);
1598 PG_RETURN_TEXT_P(string_to_text(res
));
1602 * Internal version for use by ALTER TABLE.
1603 * Includes a tablespace clause in the result.
1604 * Returns a palloc'd C string; no pretty-printing.
1607 pg_get_statisticsobjdef_string(Oid statextid
)
1609 return pg_get_statisticsobj_worker(statextid
, false, false);
1613 * pg_get_statisticsobjdef_columns
1614 * Get columns and expressions for an extended statistics object
1617 pg_get_statisticsobjdef_columns(PG_FUNCTION_ARGS
)
1619 Oid statextid
= PG_GETARG_OID(0);
1622 res
= pg_get_statisticsobj_worker(statextid
, true, true);
1627 PG_RETURN_TEXT_P(string_to_text(res
));
1631 * Internal workhorse to decompile an extended statistics object.
1634 pg_get_statisticsobj_worker(Oid statextid
, bool columns_only
, bool missing_ok
)
1636 Form_pg_statistic_ext statextrec
;
1637 HeapTuple statexttup
;
1644 bool ndistinct_enabled
;
1645 bool dependencies_enabled
;
1654 statexttup
= SearchSysCache1(STATEXTOID
, ObjectIdGetDatum(statextid
));
1656 if (!HeapTupleIsValid(statexttup
))
1660 elog(ERROR
, "cache lookup failed for statistics object %u", statextid
);
1663 /* has the statistics expressions? */
1664 has_exprs
= !heap_attisnull(statexttup
, Anum_pg_statistic_ext_stxexprs
, NULL
);
1666 statextrec
= (Form_pg_statistic_ext
) GETSTRUCT(statexttup
);
1669 * Get the statistics expressions, if any. (NOTE: we do not use the
1670 * relcache versions of the expressions, because we want to display
1671 * non-const-folded expressions.)
1678 exprsDatum
= SysCacheGetAttrNotNull(STATEXTOID
, statexttup
,
1679 Anum_pg_statistic_ext_stxexprs
);
1680 exprsString
= TextDatumGetCString(exprsDatum
);
1681 exprs
= (List
*) stringToNode(exprsString
);
1687 /* count the number of columns (attributes and expressions) */
1688 ncolumns
= statextrec
->stxkeys
.dim1
+ list_length(exprs
);
1690 initStringInfo(&buf
);
1694 nsp
= get_namespace_name_or_temp(statextrec
->stxnamespace
);
1695 appendStringInfo(&buf
, "CREATE STATISTICS %s",
1696 quote_qualified_identifier(nsp
,
1697 NameStr(statextrec
->stxname
)));
1700 * Decode the stxkind column so that we know which stats types to
1703 datum
= SysCacheGetAttrNotNull(STATEXTOID
, statexttup
,
1704 Anum_pg_statistic_ext_stxkind
);
1705 arr
= DatumGetArrayTypeP(datum
);
1706 if (ARR_NDIM(arr
) != 1 ||
1708 ARR_ELEMTYPE(arr
) != CHAROID
)
1709 elog(ERROR
, "stxkind is not a 1-D char array");
1710 enabled
= (char *) ARR_DATA_PTR(arr
);
1712 ndistinct_enabled
= false;
1713 dependencies_enabled
= false;
1714 mcv_enabled
= false;
1716 for (i
= 0; i
< ARR_DIMS(arr
)[0]; i
++)
1718 if (enabled
[i
] == STATS_EXT_NDISTINCT
)
1719 ndistinct_enabled
= true;
1720 else if (enabled
[i
] == STATS_EXT_DEPENDENCIES
)
1721 dependencies_enabled
= true;
1722 else if (enabled
[i
] == STATS_EXT_MCV
)
1725 /* ignore STATS_EXT_EXPRESSIONS (it's built automatically) */
1729 * If any option is disabled, then we'll need to append the types
1730 * clause to show which options are enabled. We omit the types clause
1731 * on purpose when all options are enabled, so a pg_dump/pg_restore
1732 * will create all statistics types on a newer postgres version, if
1733 * the statistics had all options enabled on the original version.
1735 * But if the statistics is defined on just a single column, it has to
1736 * be an expression statistics. In that case we don't need to specify
1739 if ((!ndistinct_enabled
|| !dependencies_enabled
|| !mcv_enabled
) &&
1742 bool gotone
= false;
1744 appendStringInfoString(&buf
, " (");
1746 if (ndistinct_enabled
)
1748 appendStringInfoString(&buf
, "ndistinct");
1752 if (dependencies_enabled
)
1754 appendStringInfo(&buf
, "%sdependencies", gotone
? ", " : "");
1759 appendStringInfo(&buf
, "%smcv", gotone
? ", " : "");
1761 appendStringInfoChar(&buf
, ')');
1764 appendStringInfoString(&buf
, " ON ");
1767 /* decode simple column references */
1768 for (colno
= 0; colno
< statextrec
->stxkeys
.dim1
; colno
++)
1770 AttrNumber attnum
= statextrec
->stxkeys
.values
[colno
];
1774 appendStringInfoString(&buf
, ", ");
1776 attname
= get_attname(statextrec
->stxrelid
, attnum
, false);
1778 appendStringInfoString(&buf
, quote_identifier(attname
));
1781 context
= deparse_context_for(get_relation_name(statextrec
->stxrelid
),
1782 statextrec
->stxrelid
);
1786 Node
*expr
= (Node
*) lfirst(lc
);
1788 int prettyFlags
= PRETTYFLAG_PAREN
;
1790 str
= deparse_expression_pretty(expr
, context
, false, false,
1794 appendStringInfoString(&buf
, ", ");
1796 /* Need parens if it's not a bare function call */
1797 if (looks_like_function(expr
))
1798 appendStringInfoString(&buf
, str
);
1800 appendStringInfo(&buf
, "(%s)", str
);
1806 appendStringInfo(&buf
, " FROM %s",
1807 generate_relation_name(statextrec
->stxrelid
, NIL
));
1809 ReleaseSysCache(statexttup
);
1815 * Generate text array of expressions for statistics object.
1818 pg_get_statisticsobjdef_expressions(PG_FUNCTION_ARGS
)
1820 Oid statextid
= PG_GETARG_OID(0);
1821 Form_pg_statistic_ext statextrec
;
1822 HeapTuple statexttup
;
1829 ArrayBuildState
*astate
= NULL
;
1831 statexttup
= SearchSysCache1(STATEXTOID
, ObjectIdGetDatum(statextid
));
1833 if (!HeapTupleIsValid(statexttup
))
1836 /* Does the stats object have expressions? */
1837 has_exprs
= !heap_attisnull(statexttup
, Anum_pg_statistic_ext_stxexprs
, NULL
);
1839 /* no expressions? we're done */
1842 ReleaseSysCache(statexttup
);
1846 statextrec
= (Form_pg_statistic_ext
) GETSTRUCT(statexttup
);
1849 * Get the statistics expressions, and deparse them into text values.
1851 datum
= SysCacheGetAttrNotNull(STATEXTOID
, statexttup
,
1852 Anum_pg_statistic_ext_stxexprs
);
1853 tmp
= TextDatumGetCString(datum
);
1854 exprs
= (List
*) stringToNode(tmp
);
1857 context
= deparse_context_for(get_relation_name(statextrec
->stxrelid
),
1858 statextrec
->stxrelid
);
1862 Node
*expr
= (Node
*) lfirst(lc
);
1864 int prettyFlags
= PRETTYFLAG_INDENT
;
1866 str
= deparse_expression_pretty(expr
, context
, false, false,
1869 astate
= accumArrayResult(astate
,
1870 PointerGetDatum(cstring_to_text(str
)),
1873 CurrentMemoryContext
);
1876 ReleaseSysCache(statexttup
);
1878 PG_RETURN_DATUM(makeArrayResult(astate
, CurrentMemoryContext
));
1884 * Returns the partition key specification, ie, the following:
1886 * { RANGE | LIST | HASH } (column opt_collation opt_opclass [, ...])
1889 pg_get_partkeydef(PG_FUNCTION_ARGS
)
1891 Oid relid
= PG_GETARG_OID(0);
1894 res
= pg_get_partkeydef_worker(relid
, PRETTYFLAG_INDENT
, false, true);
1899 PG_RETURN_TEXT_P(string_to_text(res
));
1902 /* Internal version that just reports the column definitions */
1904 pg_get_partkeydef_columns(Oid relid
, bool pretty
)
1908 prettyFlags
= GET_PRETTY_FLAGS(pretty
);
1910 return pg_get_partkeydef_worker(relid
, prettyFlags
, true, false);
1914 * Internal workhorse to decompile a partition key definition.
1917 pg_get_partkeydef_worker(Oid relid
, int prettyFlags
,
1918 bool attrsOnly
, bool missing_ok
)
1920 Form_pg_partitioned_table form
;
1922 oidvector
*partclass
;
1923 oidvector
*partcollation
;
1925 ListCell
*partexpr_item
;
1933 tuple
= SearchSysCache1(PARTRELID
, ObjectIdGetDatum(relid
));
1934 if (!HeapTupleIsValid(tuple
))
1938 elog(ERROR
, "cache lookup failed for partition key of %u", relid
);
1941 form
= (Form_pg_partitioned_table
) GETSTRUCT(tuple
);
1943 Assert(form
->partrelid
== relid
);
1945 /* Must get partclass and partcollation the hard way */
1946 datum
= SysCacheGetAttrNotNull(PARTRELID
, tuple
,
1947 Anum_pg_partitioned_table_partclass
);
1948 partclass
= (oidvector
*) DatumGetPointer(datum
);
1950 datum
= SysCacheGetAttrNotNull(PARTRELID
, tuple
,
1951 Anum_pg_partitioned_table_partcollation
);
1952 partcollation
= (oidvector
*) DatumGetPointer(datum
);
1956 * Get the expressions, if any. (NOTE: we do not use the relcache
1957 * versions of the expressions, because we want to display
1958 * non-const-folded expressions.)
1960 if (!heap_attisnull(tuple
, Anum_pg_partitioned_table_partexprs
, NULL
))
1965 exprsDatum
= SysCacheGetAttrNotNull(PARTRELID
, tuple
,
1966 Anum_pg_partitioned_table_partexprs
);
1967 exprsString
= TextDatumGetCString(exprsDatum
);
1968 partexprs
= (List
*) stringToNode(exprsString
);
1970 if (!IsA(partexprs
, List
))
1971 elog(ERROR
, "unexpected node type found in partexprs: %d",
1972 (int) nodeTag(partexprs
));
1979 partexpr_item
= list_head(partexprs
);
1980 context
= deparse_context_for(get_relation_name(relid
), relid
);
1982 initStringInfo(&buf
);
1984 switch (form
->partstrat
)
1986 case PARTITION_STRATEGY_HASH
:
1988 appendStringInfoString(&buf
, "HASH");
1990 case PARTITION_STRATEGY_LIST
:
1992 appendStringInfoString(&buf
, "LIST");
1994 case PARTITION_STRATEGY_RANGE
:
1996 appendStringInfoString(&buf
, "RANGE");
1999 elog(ERROR
, "unexpected partition strategy: %d",
2000 (int) form
->partstrat
);
2004 appendStringInfoString(&buf
, " (");
2006 for (keyno
= 0; keyno
< form
->partnatts
; keyno
++)
2008 AttrNumber attnum
= form
->partattrs
.values
[keyno
];
2010 Oid keycolcollation
;
2013 appendStringInfoString(&buf
, sep
);
2017 /* Simple attribute reference */
2021 attname
= get_attname(relid
, attnum
, false);
2022 appendStringInfoString(&buf
, quote_identifier(attname
));
2023 get_atttypetypmodcoll(relid
, attnum
,
2024 &keycoltype
, &keycoltypmod
,
2032 if (partexpr_item
== NULL
)
2033 elog(ERROR
, "too few entries in partexprs list");
2034 partkey
= (Node
*) lfirst(partexpr_item
);
2035 partexpr_item
= lnext(partexprs
, partexpr_item
);
2038 str
= deparse_expression_pretty(partkey
, context
, false, false,
2040 /* Need parens if it's not a bare function call */
2041 if (looks_like_function(partkey
))
2042 appendStringInfoString(&buf
, str
);
2044 appendStringInfo(&buf
, "(%s)", str
);
2046 keycoltype
= exprType(partkey
);
2047 keycolcollation
= exprCollation(partkey
);
2050 /* Add collation, if not default for column */
2051 partcoll
= partcollation
->values
[keyno
];
2052 if (!attrsOnly
&& OidIsValid(partcoll
) && partcoll
!= keycolcollation
)
2053 appendStringInfo(&buf
, " COLLATE %s",
2054 generate_collation_name((partcoll
)));
2056 /* Add the operator class name, if not default */
2058 get_opclass_name(partclass
->values
[keyno
], keycoltype
, &buf
);
2062 appendStringInfoChar(&buf
, ')');
2065 ReleaseSysCache(tuple
);
2071 * pg_get_partition_constraintdef
2073 * Returns partition constraint expression as a string for the input relation
2076 pg_get_partition_constraintdef(PG_FUNCTION_ARGS
)
2078 Oid relationId
= PG_GETARG_OID(0);
2084 constr_expr
= get_partition_qual_relid(relationId
);
2086 /* Quick exit if no partition constraint */
2087 if (constr_expr
== NULL
)
2091 * Deparse and return the constraint expression.
2093 prettyFlags
= PRETTYFLAG_INDENT
;
2094 context
= deparse_context_for(get_relation_name(relationId
), relationId
);
2095 consrc
= deparse_expression_pretty((Node
*) constr_expr
, context
, false,
2096 false, prettyFlags
, 0);
2098 PG_RETURN_TEXT_P(string_to_text(consrc
));
2102 * pg_get_partconstrdef_string
2104 * Returns the partition constraint as a C-string for the input relation, with
2105 * the given alias. No pretty-printing.
2108 pg_get_partconstrdef_string(Oid partitionId
, char *aliasname
)
2113 constr_expr
= get_partition_qual_relid(partitionId
);
2114 context
= deparse_context_for(aliasname
, partitionId
);
2116 return deparse_expression((Node
*) constr_expr
, context
, true, false);
2120 * pg_get_constraintdef
2122 * Returns the definition for the constraint, ie, everything that needs to
2123 * appear after "ALTER TABLE ... ADD CONSTRAINT <constraintname>".
2126 pg_get_constraintdef(PG_FUNCTION_ARGS
)
2128 Oid constraintId
= PG_GETARG_OID(0);
2132 prettyFlags
= PRETTYFLAG_INDENT
;
2134 res
= pg_get_constraintdef_worker(constraintId
, false, prettyFlags
, true);
2139 PG_RETURN_TEXT_P(string_to_text(res
));
2143 pg_get_constraintdef_ext(PG_FUNCTION_ARGS
)
2145 Oid constraintId
= PG_GETARG_OID(0);
2146 bool pretty
= PG_GETARG_BOOL(1);
2150 prettyFlags
= GET_PRETTY_FLAGS(pretty
);
2152 res
= pg_get_constraintdef_worker(constraintId
, false, prettyFlags
, true);
2157 PG_RETURN_TEXT_P(string_to_text(res
));
2161 * Internal version that returns a full ALTER TABLE ... ADD CONSTRAINT command
2164 pg_get_constraintdef_command(Oid constraintId
)
2166 return pg_get_constraintdef_worker(constraintId
, true, 0, false);
2170 * As of 9.4, we now use an MVCC snapshot for this.
2173 pg_get_constraintdef_worker(Oid constraintId
, bool fullCommand
,
2174 int prettyFlags
, bool missing_ok
)
2177 Form_pg_constraint conForm
;
2179 SysScanDesc scandesc
;
2180 ScanKeyData scankey
[1];
2181 Snapshot snapshot
= RegisterSnapshot(GetTransactionSnapshot());
2182 Relation relation
= table_open(ConstraintRelationId
, AccessShareLock
);
2184 ScanKeyInit(&scankey
[0],
2185 Anum_pg_constraint_oid
,
2186 BTEqualStrategyNumber
, F_OIDEQ
,
2187 ObjectIdGetDatum(constraintId
));
2189 scandesc
= systable_beginscan(relation
,
2190 ConstraintOidIndexId
,
2197 * We later use the tuple with SysCacheGetAttr() as if we had obtained it
2198 * via SearchSysCache, which works fine.
2200 tup
= systable_getnext(scandesc
);
2202 UnregisterSnapshot(snapshot
);
2204 if (!HeapTupleIsValid(tup
))
2208 systable_endscan(scandesc
);
2209 table_close(relation
, AccessShareLock
);
2212 elog(ERROR
, "could not find tuple for constraint %u", constraintId
);
2215 conForm
= (Form_pg_constraint
) GETSTRUCT(tup
);
2217 initStringInfo(&buf
);
2221 if (OidIsValid(conForm
->conrelid
))
2224 * Currently, callers want ALTER TABLE (without ONLY) for CHECK
2225 * constraints, and other types of constraints don't inherit
2226 * anyway so it doesn't matter whether we say ONLY or not. Someday
2227 * we might need to let callers specify whether to put ONLY in the
2230 appendStringInfo(&buf
, "ALTER TABLE %s ADD CONSTRAINT %s ",
2231 generate_qualified_relation_name(conForm
->conrelid
),
2232 quote_identifier(NameStr(conForm
->conname
)));
2236 /* Must be a domain constraint */
2237 Assert(OidIsValid(conForm
->contypid
));
2238 appendStringInfo(&buf
, "ALTER DOMAIN %s ADD CONSTRAINT %s ",
2239 generate_qualified_type_name(conForm
->contypid
),
2240 quote_identifier(NameStr(conForm
->conname
)));
2244 switch (conForm
->contype
)
2246 case CONSTRAINT_FOREIGN
:
2252 /* Start off the constraint definition */
2253 appendStringInfoString(&buf
, "FOREIGN KEY (");
2255 /* Fetch and build referencing-column list */
2256 val
= SysCacheGetAttrNotNull(CONSTROID
, tup
,
2257 Anum_pg_constraint_conkey
);
2259 decompile_column_index_array(val
, conForm
->conrelid
, &buf
);
2261 /* add foreign relation name */
2262 appendStringInfo(&buf
, ") REFERENCES %s(",
2263 generate_relation_name(conForm
->confrelid
,
2266 /* Fetch and build referenced-column list */
2267 val
= SysCacheGetAttrNotNull(CONSTROID
, tup
,
2268 Anum_pg_constraint_confkey
);
2270 decompile_column_index_array(val
, conForm
->confrelid
, &buf
);
2272 appendStringInfoChar(&buf
, ')');
2274 /* Add match type */
2275 switch (conForm
->confmatchtype
)
2277 case FKCONSTR_MATCH_FULL
:
2278 string
= " MATCH FULL";
2280 case FKCONSTR_MATCH_PARTIAL
:
2281 string
= " MATCH PARTIAL";
2283 case FKCONSTR_MATCH_SIMPLE
:
2287 elog(ERROR
, "unrecognized confmatchtype: %d",
2288 conForm
->confmatchtype
);
2289 string
= ""; /* keep compiler quiet */
2292 appendStringInfoString(&buf
, string
);
2294 /* Add ON UPDATE and ON DELETE clauses, if needed */
2295 switch (conForm
->confupdtype
)
2297 case FKCONSTR_ACTION_NOACTION
:
2298 string
= NULL
; /* suppress default */
2300 case FKCONSTR_ACTION_RESTRICT
:
2301 string
= "RESTRICT";
2303 case FKCONSTR_ACTION_CASCADE
:
2306 case FKCONSTR_ACTION_SETNULL
:
2307 string
= "SET NULL";
2309 case FKCONSTR_ACTION_SETDEFAULT
:
2310 string
= "SET DEFAULT";
2313 elog(ERROR
, "unrecognized confupdtype: %d",
2314 conForm
->confupdtype
);
2315 string
= NULL
; /* keep compiler quiet */
2319 appendStringInfo(&buf
, " ON UPDATE %s", string
);
2321 switch (conForm
->confdeltype
)
2323 case FKCONSTR_ACTION_NOACTION
:
2324 string
= NULL
; /* suppress default */
2326 case FKCONSTR_ACTION_RESTRICT
:
2327 string
= "RESTRICT";
2329 case FKCONSTR_ACTION_CASCADE
:
2332 case FKCONSTR_ACTION_SETNULL
:
2333 string
= "SET NULL";
2335 case FKCONSTR_ACTION_SETDEFAULT
:
2336 string
= "SET DEFAULT";
2339 elog(ERROR
, "unrecognized confdeltype: %d",
2340 conForm
->confdeltype
);
2341 string
= NULL
; /* keep compiler quiet */
2345 appendStringInfo(&buf
, " ON DELETE %s", string
);
2348 * Add columns specified to SET NULL or SET DEFAULT if
2351 val
= SysCacheGetAttr(CONSTROID
, tup
,
2352 Anum_pg_constraint_confdelsetcols
, &isnull
);
2355 appendStringInfoString(&buf
, " (");
2356 decompile_column_index_array(val
, conForm
->conrelid
, &buf
);
2357 appendStringInfoChar(&buf
, ')');
2362 case CONSTRAINT_PRIMARY
:
2363 case CONSTRAINT_UNIQUE
:
2370 /* Start off the constraint definition */
2371 if (conForm
->contype
== CONSTRAINT_PRIMARY
)
2372 appendStringInfoString(&buf
, "PRIMARY KEY ");
2374 appendStringInfoString(&buf
, "UNIQUE ");
2376 indexId
= conForm
->conindid
;
2378 indtup
= SearchSysCache1(INDEXRELID
, ObjectIdGetDatum(indexId
));
2379 if (!HeapTupleIsValid(indtup
))
2380 elog(ERROR
, "cache lookup failed for index %u", indexId
);
2381 if (conForm
->contype
== CONSTRAINT_UNIQUE
&&
2382 ((Form_pg_index
) GETSTRUCT(indtup
))->indnullsnotdistinct
)
2383 appendStringInfoString(&buf
, "NULLS NOT DISTINCT ");
2385 appendStringInfoChar(&buf
, '(');
2387 /* Fetch and build target column list */
2388 val
= SysCacheGetAttrNotNull(CONSTROID
, tup
,
2389 Anum_pg_constraint_conkey
);
2391 keyatts
= decompile_column_index_array(val
, conForm
->conrelid
, &buf
);
2393 appendStringInfoChar(&buf
, ')');
2395 /* Build including column list (from pg_index.indkeys) */
2396 val
= SysCacheGetAttrNotNull(INDEXRELID
, indtup
,
2397 Anum_pg_index_indnatts
);
2398 if (DatumGetInt32(val
) > keyatts
)
2405 appendStringInfoString(&buf
, " INCLUDE (");
2407 cols
= SysCacheGetAttrNotNull(INDEXRELID
, indtup
,
2408 Anum_pg_index_indkey
);
2410 deconstruct_array_builtin(DatumGetArrayTypeP(cols
), INT2OID
,
2411 &keys
, NULL
, &nKeys
);
2413 for (j
= keyatts
; j
< nKeys
; j
++)
2417 colName
= get_attname(conForm
->conrelid
,
2418 DatumGetInt16(keys
[j
]), false);
2420 appendStringInfoString(&buf
, ", ");
2421 appendStringInfoString(&buf
, quote_identifier(colName
));
2424 appendStringInfoChar(&buf
, ')');
2426 ReleaseSysCache(indtup
);
2428 /* XXX why do we only print these bits if fullCommand? */
2429 if (fullCommand
&& OidIsValid(indexId
))
2431 char *options
= flatten_reloptions(indexId
);
2436 appendStringInfo(&buf
, " WITH (%s)", options
);
2441 * Print the tablespace, unless it's the database default.
2442 * This is to help ALTER TABLE usage of this facility,
2443 * which needs this behavior to recreate exact catalog
2446 tblspc
= get_rel_tablespace(indexId
);
2447 if (OidIsValid(tblspc
))
2448 appendStringInfo(&buf
, " USING INDEX TABLESPACE %s",
2449 quote_identifier(get_tablespace_name(tblspc
)));
2454 case CONSTRAINT_CHECK
:
2462 /* Fetch constraint expression in parsetree form */
2463 val
= SysCacheGetAttrNotNull(CONSTROID
, tup
,
2464 Anum_pg_constraint_conbin
);
2466 conbin
= TextDatumGetCString(val
);
2467 expr
= stringToNode(conbin
);
2469 /* Set up deparsing context for Var nodes in constraint */
2470 if (conForm
->conrelid
!= InvalidOid
)
2472 /* relation constraint */
2473 context
= deparse_context_for(get_relation_name(conForm
->conrelid
),
2478 /* domain constraint --- can't have Vars */
2482 consrc
= deparse_expression_pretty(expr
, context
, false, false,
2486 * Now emit the constraint definition, adding NO INHERIT if
2489 * There are cases where the constraint expression will be
2490 * fully parenthesized and we don't need the outer parens ...
2491 * but there are other cases where we do need 'em. Be
2492 * conservative for now.
2494 * Note that simply checking for leading '(' and trailing ')'
2495 * would NOT be good enough, consider "(x > 0) AND (y > 0)".
2497 appendStringInfo(&buf
, "CHECK (%s)%s",
2499 conForm
->connoinherit
? " NO INHERIT" : "");
2502 case CONSTRAINT_TRIGGER
:
2505 * There isn't an ALTER TABLE syntax for creating a user-defined
2506 * constraint trigger, but it seems better to print something than
2507 * throw an error; if we throw error then this function couldn't
2508 * safely be applied to all rows of pg_constraint.
2510 appendStringInfoString(&buf
, "TRIGGER");
2512 case CONSTRAINT_EXCLUSION
:
2514 Oid indexOid
= conForm
->conindid
;
2521 /* Extract operator OIDs from the pg_constraint tuple */
2522 val
= SysCacheGetAttrNotNull(CONSTROID
, tup
,
2523 Anum_pg_constraint_conexclop
);
2525 deconstruct_array_builtin(DatumGetArrayTypeP(val
), OIDOID
,
2526 &elems
, NULL
, &nElems
);
2528 operators
= (Oid
*) palloc(nElems
* sizeof(Oid
));
2529 for (i
= 0; i
< nElems
; i
++)
2530 operators
[i
] = DatumGetObjectId(elems
[i
]);
2532 /* pg_get_indexdef_worker does the rest */
2533 /* suppress tablespace because pg_dump wants it that way */
2534 appendStringInfoString(&buf
,
2535 pg_get_indexdef_worker(indexOid
,
2547 elog(ERROR
, "invalid constraint type \"%c\"", conForm
->contype
);
2551 if (conForm
->condeferrable
)
2552 appendStringInfoString(&buf
, " DEFERRABLE");
2553 if (conForm
->condeferred
)
2554 appendStringInfoString(&buf
, " INITIALLY DEFERRED");
2555 if (!conForm
->convalidated
)
2556 appendStringInfoString(&buf
, " NOT VALID");
2559 systable_endscan(scandesc
);
2560 table_close(relation
, AccessShareLock
);
2567 * Convert an int16[] Datum into a comma-separated list of column names
2568 * for the indicated relation; append the list to buf. Returns the number
2572 decompile_column_index_array(Datum column_index_array
, Oid relId
,
2579 /* Extract data from array of int16 */
2580 deconstruct_array_builtin(DatumGetArrayTypeP(column_index_array
), INT2OID
,
2581 &keys
, NULL
, &nKeys
);
2583 for (j
= 0; j
< nKeys
; j
++)
2587 colName
= get_attname(relId
, DatumGetInt16(keys
[j
]), false);
2590 appendStringInfoString(buf
, quote_identifier(colName
));
2592 appendStringInfo(buf
, ", %s", quote_identifier(colName
));
2600 * pg_get_expr - Decompile an expression tree
2602 * Input: an expression tree in nodeToString form, and a relation OID
2604 * Output: reverse-listed expression
2606 * Currently, the expression can only refer to a single relation, namely
2607 * the one specified by the second parameter. This is sufficient for
2608 * partial indexes, column default expressions, etc. We also support
2609 * Var-free expressions, for which the OID can be InvalidOid.
2611 * If the OID is nonzero but not actually valid, don't throw an error,
2612 * just return NULL. This is a bit questionable, but it's what we've
2613 * done historically, and it can help avoid unwanted failures when
2614 * examining catalog entries for just-deleted relations.
2616 * We expect this function to work, or throw a reasonably clean error,
2617 * for any node tree that can appear in a catalog pg_node_tree column.
2618 * Query trees, such as those appearing in pg_rewrite.ev_action, are
2619 * not supported. Nor are expressions in more than one relation, which
2620 * can appear in places like pg_rewrite.ev_qual.
2624 pg_get_expr(PG_FUNCTION_ARGS
)
2626 text
*expr
= PG_GETARG_TEXT_PP(0);
2627 Oid relid
= PG_GETARG_OID(1);
2631 prettyFlags
= PRETTYFLAG_INDENT
;
2633 result
= pg_get_expr_worker(expr
, relid
, prettyFlags
);
2635 PG_RETURN_TEXT_P(result
);
2641 pg_get_expr_ext(PG_FUNCTION_ARGS
)
2643 text
*expr
= PG_GETARG_TEXT_PP(0);
2644 Oid relid
= PG_GETARG_OID(1);
2645 bool pretty
= PG_GETARG_BOOL(2);
2649 prettyFlags
= GET_PRETTY_FLAGS(pretty
);
2651 result
= pg_get_expr_worker(expr
, relid
, prettyFlags
);
2653 PG_RETURN_TEXT_P(result
);
2659 pg_get_expr_worker(text
*expr
, Oid relid
, int prettyFlags
)
2666 Relation rel
= NULL
;
2669 /* Convert input pg_node_tree (really TEXT) object to C string */
2670 exprstr
= text_to_cstring(expr
);
2672 /* Convert expression to node tree */
2673 node
= (Node
*) stringToNode(exprstr
);
2678 * Throw error if the input is a querytree rather than an expression tree.
2679 * While we could support queries here, there seems no very good reason
2680 * to. In most such catalog columns, we'll see a List of Query nodes, or
2681 * even nested Lists, so drill down to a non-List node before checking.
2684 while (tst
&& IsA(tst
, List
))
2685 tst
= linitial((List
*) tst
);
2686 if (tst
&& IsA(tst
, Query
))
2688 (errcode(ERRCODE_INVALID_PARAMETER_VALUE
),
2689 errmsg("input is a query, not an expression")));
2692 * Throw error if the expression contains Vars we won't be able to
2695 relids
= pull_varnos(NULL
, node
);
2696 if (OidIsValid(relid
))
2698 if (!bms_is_subset(relids
, bms_make_singleton(1)))
2700 (errcode(ERRCODE_INVALID_PARAMETER_VALUE
),
2701 errmsg("expression contains variables of more than one relation")));
2705 if (!bms_is_empty(relids
))
2707 (errcode(ERRCODE_INVALID_PARAMETER_VALUE
),
2708 errmsg("expression contains variables")));
2712 * Prepare deparse context if needed. If we are deparsing with a relid,
2713 * we need to transiently open and lock the rel, to make sure it won't go
2714 * away underneath us. (set_relation_column_names would lock it anyway,
2715 * so this isn't really introducing any new behavior.)
2717 if (OidIsValid(relid
))
2719 rel
= try_relation_open(relid
, AccessShareLock
);
2722 context
= deparse_context_for(RelationGetRelationName(rel
), relid
);
2728 str
= deparse_expression_pretty(node
, context
, false, false,
2732 relation_close(rel
, AccessShareLock
);
2734 return string_to_text(str
);
2739 * pg_get_userbyid - Get a user name by roleid and
2740 * fallback to 'unknown (OID=n)'
2744 pg_get_userbyid(PG_FUNCTION_ARGS
)
2746 Oid roleid
= PG_GETARG_OID(0);
2749 Form_pg_authid role_rec
;
2752 * Allocate space for the result
2754 result
= (Name
) palloc(NAMEDATALEN
);
2755 memset(NameStr(*result
), 0, NAMEDATALEN
);
2758 * Get the pg_authid entry and print the result
2760 roletup
= SearchSysCache1(AUTHOID
, ObjectIdGetDatum(roleid
));
2761 if (HeapTupleIsValid(roletup
))
2763 role_rec
= (Form_pg_authid
) GETSTRUCT(roletup
);
2764 *result
= role_rec
->rolname
;
2765 ReleaseSysCache(roletup
);
2768 sprintf(NameStr(*result
), "unknown (OID=%u)", roleid
);
2770 PG_RETURN_NAME(result
);
2775 * pg_get_serial_sequence
2776 * Get the name of the sequence used by an identity or serial column,
2777 * formatted suitably for passing to setval, nextval or currval.
2778 * First parameter is not treated as double-quoted, second parameter
2779 * is --- see documentation for reason.
2782 pg_get_serial_sequence(PG_FUNCTION_ARGS
)
2784 text
*tablename
= PG_GETARG_TEXT_PP(0);
2785 text
*columnname
= PG_GETARG_TEXT_PP(1);
2790 Oid sequenceId
= InvalidOid
;
2796 /* Look up table name. Can't lock it - we might not have privileges. */
2797 tablerv
= makeRangeVarFromNameList(textToQualifiedNameList(tablename
));
2798 tableOid
= RangeVarGetRelid(tablerv
, NoLock
, false);
2800 /* Get the number of the column */
2801 column
= text_to_cstring(columnname
);
2803 attnum
= get_attnum(tableOid
, column
);
2804 if (attnum
== InvalidAttrNumber
)
2806 (errcode(ERRCODE_UNDEFINED_COLUMN
),
2807 errmsg("column \"%s\" of relation \"%s\" does not exist",
2808 column
, tablerv
->relname
)));
2810 /* Search the dependency table for the dependent sequence */
2811 depRel
= table_open(DependRelationId
, AccessShareLock
);
2813 ScanKeyInit(&key
[0],
2814 Anum_pg_depend_refclassid
,
2815 BTEqualStrategyNumber
, F_OIDEQ
,
2816 ObjectIdGetDatum(RelationRelationId
));
2817 ScanKeyInit(&key
[1],
2818 Anum_pg_depend_refobjid
,
2819 BTEqualStrategyNumber
, F_OIDEQ
,
2820 ObjectIdGetDatum(tableOid
));
2821 ScanKeyInit(&key
[2],
2822 Anum_pg_depend_refobjsubid
,
2823 BTEqualStrategyNumber
, F_INT4EQ
,
2824 Int32GetDatum(attnum
));
2826 scan
= systable_beginscan(depRel
, DependReferenceIndexId
, true,
2829 while (HeapTupleIsValid(tup
= systable_getnext(scan
)))
2831 Form_pg_depend deprec
= (Form_pg_depend
) GETSTRUCT(tup
);
2834 * Look for an auto dependency (serial column) or internal dependency
2835 * (identity column) of a sequence on a column. (We need the relkind
2836 * test because indexes can also have auto dependencies on columns.)
2838 if (deprec
->classid
== RelationRelationId
&&
2839 deprec
->objsubid
== 0 &&
2840 (deprec
->deptype
== DEPENDENCY_AUTO
||
2841 deprec
->deptype
== DEPENDENCY_INTERNAL
) &&
2842 get_rel_relkind(deprec
->objid
) == RELKIND_SEQUENCE
)
2844 sequenceId
= deprec
->objid
;
2849 systable_endscan(scan
);
2850 table_close(depRel
, AccessShareLock
);
2852 if (OidIsValid(sequenceId
))
2856 result
= generate_qualified_relation_name(sequenceId
);
2858 PG_RETURN_TEXT_P(string_to_text(result
));
2866 * pg_get_functiondef
2867 * Returns the complete "CREATE OR REPLACE FUNCTION ..." statement for
2868 * the specified function.
2870 * Note: if you change the output format of this function, be careful not
2871 * to break psql's rules (in \ef and \sf) for identifying the start of the
2872 * function body. To wit: the function body starts on a line that begins with
2873 * "AS ", "BEGIN ", or "RETURN ", and no preceding line will look like that.
2876 pg_get_functiondef(PG_FUNCTION_ARGS
)
2878 Oid funcid
= PG_GETARG_OID(0);
2892 initStringInfo(&buf
);
2894 /* Look up the function */
2895 proctup
= SearchSysCache1(PROCOID
, ObjectIdGetDatum(funcid
));
2896 if (!HeapTupleIsValid(proctup
))
2899 proc
= (Form_pg_proc
) GETSTRUCT(proctup
);
2900 name
= NameStr(proc
->proname
);
2902 if (proc
->prokind
== PROKIND_AGGREGATE
)
2904 (errcode(ERRCODE_WRONG_OBJECT_TYPE
),
2905 errmsg("\"%s\" is an aggregate function", name
)));
2907 isfunction
= (proc
->prokind
!= PROKIND_PROCEDURE
);
2910 * We always qualify the function name, to ensure the right function gets
2913 nsp
= get_namespace_name_or_temp(proc
->pronamespace
);
2914 appendStringInfo(&buf
, "CREATE OR REPLACE %s %s(",
2915 isfunction
? "FUNCTION" : "PROCEDURE",
2916 quote_qualified_identifier(nsp
, name
));
2917 (void) print_function_arguments(&buf
, proctup
, false, true);
2918 appendStringInfoString(&buf
, ")\n");
2921 appendStringInfoString(&buf
, " RETURNS ");
2922 print_function_rettype(&buf
, proctup
);
2923 appendStringInfoChar(&buf
, '\n');
2926 print_function_trftypes(&buf
, proctup
);
2928 appendStringInfo(&buf
, " LANGUAGE %s\n",
2929 quote_identifier(get_language_name(proc
->prolang
, false)));
2931 /* Emit some miscellaneous options on one line */
2934 if (proc
->prokind
== PROKIND_WINDOW
)
2935 appendStringInfoString(&buf
, " WINDOW");
2936 switch (proc
->provolatile
)
2938 case PROVOLATILE_IMMUTABLE
:
2939 appendStringInfoString(&buf
, " IMMUTABLE");
2941 case PROVOLATILE_STABLE
:
2942 appendStringInfoString(&buf
, " STABLE");
2944 case PROVOLATILE_VOLATILE
:
2948 switch (proc
->proparallel
)
2950 case PROPARALLEL_SAFE
:
2951 appendStringInfoString(&buf
, " PARALLEL SAFE");
2953 case PROPARALLEL_RESTRICTED
:
2954 appendStringInfoString(&buf
, " PARALLEL RESTRICTED");
2956 case PROPARALLEL_UNSAFE
:
2960 if (proc
->proisstrict
)
2961 appendStringInfoString(&buf
, " STRICT");
2962 if (proc
->prosecdef
)
2963 appendStringInfoString(&buf
, " SECURITY DEFINER");
2964 if (proc
->proleakproof
)
2965 appendStringInfoString(&buf
, " LEAKPROOF");
2967 /* This code for the default cost and rows should match functioncmds.c */
2968 if (proc
->prolang
== INTERNALlanguageId
||
2969 proc
->prolang
== ClanguageId
)
2973 if (proc
->procost
!= procost
)
2974 appendStringInfo(&buf
, " COST %g", proc
->procost
);
2976 if (proc
->prorows
> 0 && proc
->prorows
!= 1000)
2977 appendStringInfo(&buf
, " ROWS %g", proc
->prorows
);
2979 if (proc
->prosupport
)
2984 * We should qualify the support function's name if it wouldn't be
2985 * resolved by lookup in the current search path.
2987 argtypes
[0] = INTERNALOID
;
2988 appendStringInfo(&buf
, " SUPPORT %s",
2989 generate_function_name(proc
->prosupport
, 1,
2991 false, NULL
, false));
2994 if (oldlen
!= buf
.len
)
2995 appendStringInfoChar(&buf
, '\n');
2997 /* Emit any proconfig options, one per line */
2998 tmp
= SysCacheGetAttr(PROCOID
, proctup
, Anum_pg_proc_proconfig
, &isnull
);
3001 ArrayType
*a
= DatumGetArrayTypeP(tmp
);
3004 Assert(ARR_ELEMTYPE(a
) == TEXTOID
);
3005 Assert(ARR_NDIM(a
) == 1);
3006 Assert(ARR_LBOUND(a
)[0] == 1);
3008 for (i
= 1; i
<= ARR_DIMS(a
)[0]; i
++)
3012 d
= array_ref(a
, 1, &i
,
3013 -1 /* varlenarray */ ,
3014 -1 /* TEXT's typlen */ ,
3015 false /* TEXT's typbyval */ ,
3016 TYPALIGN_INT
/* TEXT's typalign */ ,
3020 char *configitem
= TextDatumGetCString(d
);
3023 pos
= strchr(configitem
, '=');
3028 appendStringInfo(&buf
, " SET %s TO ",
3029 quote_identifier(configitem
));
3032 * Variables that are marked GUC_LIST_QUOTE were already fully
3033 * quoted by flatten_set_variable_args() before they were put
3034 * into the proconfig array. However, because the quoting
3035 * rules used there aren't exactly like SQL's, we have to
3036 * break the list value apart and then quote the elements as
3037 * string literals. (The elements may be double-quoted as-is,
3038 * but we can't just feed them to the SQL parser; it would do
3039 * the wrong thing with elements that are zero-length or
3040 * longer than NAMEDATALEN.)
3042 * Variables that are not so marked should just be emitted as
3043 * simple string literals. If the variable is not known to
3044 * guc.c, we'll do that; this makes it unsafe to use
3045 * GUC_LIST_QUOTE for extension variables.
3047 if (GetConfigOptionFlags(configitem
, true) & GUC_LIST_QUOTE
)
3052 /* Parse string into list of identifiers */
3053 if (!SplitGUCList(pos
, ',', &namelist
))
3055 /* this shouldn't fail really */
3056 elog(ERROR
, "invalid list syntax in proconfig item");
3058 foreach(lc
, namelist
)
3060 char *curname
= (char *) lfirst(lc
);
3062 simple_quote_literal(&buf
, curname
);
3063 if (lnext(namelist
, lc
))
3064 appendStringInfoString(&buf
, ", ");
3068 simple_quote_literal(&buf
, pos
);
3069 appendStringInfoChar(&buf
, '\n');
3074 /* And finally the function definition ... */
3075 (void) SysCacheGetAttr(PROCOID
, proctup
, Anum_pg_proc_prosqlbody
, &isnull
);
3076 if (proc
->prolang
== SQLlanguageId
&& !isnull
)
3078 print_function_sqlbody(&buf
, proctup
);
3082 appendStringInfoString(&buf
, "AS ");
3084 tmp
= SysCacheGetAttr(PROCOID
, proctup
, Anum_pg_proc_probin
, &isnull
);
3087 simple_quote_literal(&buf
, TextDatumGetCString(tmp
));
3088 appendStringInfoString(&buf
, ", "); /* assume prosrc isn't null */
3091 tmp
= SysCacheGetAttrNotNull(PROCOID
, proctup
, Anum_pg_proc_prosrc
);
3092 prosrc
= TextDatumGetCString(tmp
);
3095 * We always use dollar quoting. Figure out a suitable delimiter.
3097 * Since the user is likely to be editing the function body string, we
3098 * shouldn't use a short delimiter that he might easily create a
3099 * conflict with. Hence prefer "$function$"/"$procedure$", but extend
3102 initStringInfo(&dq
);
3103 appendStringInfoChar(&dq
, '$');
3104 appendStringInfoString(&dq
, (isfunction
? "function" : "procedure"));
3105 while (strstr(prosrc
, dq
.data
) != NULL
)
3106 appendStringInfoChar(&dq
, 'x');
3107 appendStringInfoChar(&dq
, '$');
3109 appendBinaryStringInfo(&buf
, dq
.data
, dq
.len
);
3110 appendStringInfoString(&buf
, prosrc
);
3111 appendBinaryStringInfo(&buf
, dq
.data
, dq
.len
);
3114 appendStringInfoChar(&buf
, '\n');
3116 ReleaseSysCache(proctup
);
3118 PG_RETURN_TEXT_P(string_to_text(buf
.data
));
3122 * pg_get_function_arguments
3123 * Get a nicely-formatted list of arguments for a function.
3124 * This is everything that would go between the parentheses in
3128 pg_get_function_arguments(PG_FUNCTION_ARGS
)
3130 Oid funcid
= PG_GETARG_OID(0);
3134 proctup
= SearchSysCache1(PROCOID
, ObjectIdGetDatum(funcid
));
3135 if (!HeapTupleIsValid(proctup
))
3138 initStringInfo(&buf
);
3140 (void) print_function_arguments(&buf
, proctup
, false, true);
3142 ReleaseSysCache(proctup
);
3144 PG_RETURN_TEXT_P(string_to_text(buf
.data
));
3148 * pg_get_function_identity_arguments
3149 * Get a formatted list of arguments for a function.
3150 * This is everything that would go between the parentheses in
3151 * ALTER FUNCTION, etc. In particular, don't print defaults.
3154 pg_get_function_identity_arguments(PG_FUNCTION_ARGS
)
3156 Oid funcid
= PG_GETARG_OID(0);
3160 proctup
= SearchSysCache1(PROCOID
, ObjectIdGetDatum(funcid
));
3161 if (!HeapTupleIsValid(proctup
))
3164 initStringInfo(&buf
);
3166 (void) print_function_arguments(&buf
, proctup
, false, false);
3168 ReleaseSysCache(proctup
);
3170 PG_RETURN_TEXT_P(string_to_text(buf
.data
));
3174 * pg_get_function_result
3175 * Get a nicely-formatted version of the result type of a function.
3176 * This is what would appear after RETURNS in CREATE FUNCTION.
3179 pg_get_function_result(PG_FUNCTION_ARGS
)
3181 Oid funcid
= PG_GETARG_OID(0);
3185 proctup
= SearchSysCache1(PROCOID
, ObjectIdGetDatum(funcid
));
3186 if (!HeapTupleIsValid(proctup
))
3189 if (((Form_pg_proc
) GETSTRUCT(proctup
))->prokind
== PROKIND_PROCEDURE
)
3191 ReleaseSysCache(proctup
);
3195 initStringInfo(&buf
);
3197 print_function_rettype(&buf
, proctup
);
3199 ReleaseSysCache(proctup
);
3201 PG_RETURN_TEXT_P(string_to_text(buf
.data
));
3205 * Guts of pg_get_function_result: append the function's return type
3206 * to the specified buffer.
3209 print_function_rettype(StringInfo buf
, HeapTuple proctup
)
3211 Form_pg_proc proc
= (Form_pg_proc
) GETSTRUCT(proctup
);
3213 StringInfoData rbuf
;
3215 initStringInfo(&rbuf
);
3217 if (proc
->proretset
)
3219 /* It might be a table function; try to print the arguments */
3220 appendStringInfoString(&rbuf
, "TABLE(");
3221 ntabargs
= print_function_arguments(&rbuf
, proctup
, true, false);
3223 appendStringInfoChar(&rbuf
, ')');
3225 resetStringInfo(&rbuf
);
3230 /* Not a table function, so do the normal thing */
3231 if (proc
->proretset
)
3232 appendStringInfoString(&rbuf
, "SETOF ");
3233 appendStringInfoString(&rbuf
, format_type_be(proc
->prorettype
));
3236 appendBinaryStringInfo(buf
, rbuf
.data
, rbuf
.len
);
3240 * Common code for pg_get_function_arguments and pg_get_function_result:
3241 * append the desired subset of arguments to buf. We print only TABLE
3242 * arguments when print_table_args is true, and all the others when it's false.
3243 * We print argument defaults only if print_defaults is true.
3244 * Function return value is the number of arguments printed.
3247 print_function_arguments(StringInfo buf
, HeapTuple proctup
,
3248 bool print_table_args
, bool print_defaults
)
3250 Form_pg_proc proc
= (Form_pg_proc
) GETSTRUCT(proctup
);
3255 int insertorderbyat
= -1;
3259 List
*argdefaults
= NIL
;
3260 ListCell
*nextargdefault
= NULL
;
3263 numargs
= get_func_arg_info(proctup
,
3264 &argtypes
, &argnames
, &argmodes
);
3266 nlackdefaults
= numargs
;
3267 if (print_defaults
&& proc
->pronargdefaults
> 0)
3269 Datum proargdefaults
;
3272 proargdefaults
= SysCacheGetAttr(PROCOID
, proctup
,
3273 Anum_pg_proc_proargdefaults
,
3279 str
= TextDatumGetCString(proargdefaults
);
3280 argdefaults
= castNode(List
, stringToNode(str
));
3282 nextargdefault
= list_head(argdefaults
);
3283 /* nlackdefaults counts only *input* arguments lacking defaults */
3284 nlackdefaults
= proc
->pronargs
- list_length(argdefaults
);
3288 /* Check for special treatment of ordered-set aggregates */
3289 if (proc
->prokind
== PROKIND_AGGREGATE
)
3292 Form_pg_aggregate agg
;
3294 aggtup
= SearchSysCache1(AGGFNOID
, ObjectIdGetDatum(proc
->oid
));
3295 if (!HeapTupleIsValid(aggtup
))
3296 elog(ERROR
, "cache lookup failed for aggregate %u",
3298 agg
= (Form_pg_aggregate
) GETSTRUCT(aggtup
);
3299 if (AGGKIND_IS_ORDERED_SET(agg
->aggkind
))
3300 insertorderbyat
= agg
->aggnumdirectargs
;
3301 ReleaseSysCache(aggtup
);
3306 for (i
= 0; i
< numargs
; i
++)
3308 Oid argtype
= argtypes
[i
];
3309 char *argname
= argnames
? argnames
[i
] : NULL
;
3310 char argmode
= argmodes
? argmodes
[i
] : PROARGMODE_IN
;
3311 const char *modename
;
3319 * For procedures, explicitly mark all argument modes, so as
3320 * to avoid ambiguity with the SQL syntax for DROP PROCEDURE.
3322 if (proc
->prokind
== PROKIND_PROCEDURE
)
3328 case PROARGMODE_INOUT
:
3329 modename
= "INOUT ";
3332 case PROARGMODE_OUT
:
3336 case PROARGMODE_VARIADIC
:
3337 modename
= "VARIADIC ";
3340 case PROARGMODE_TABLE
:
3345 elog(ERROR
, "invalid parameter mode '%c'", argmode
);
3346 modename
= NULL
; /* keep compiler quiet */
3351 inputargno
++; /* this is a 1-based counter */
3353 if (print_table_args
!= (argmode
== PROARGMODE_TABLE
))
3356 if (argsprinted
== insertorderbyat
)
3359 appendStringInfoChar(buf
, ' ');
3360 appendStringInfoString(buf
, "ORDER BY ");
3362 else if (argsprinted
)
3363 appendStringInfoString(buf
, ", ");
3365 appendStringInfoString(buf
, modename
);
3366 if (argname
&& argname
[0])
3367 appendStringInfo(buf
, "%s ", quote_identifier(argname
));
3368 appendStringInfoString(buf
, format_type_be(argtype
));
3369 if (print_defaults
&& isinput
&& inputargno
> nlackdefaults
)
3373 Assert(nextargdefault
!= NULL
);
3374 expr
= (Node
*) lfirst(nextargdefault
);
3375 nextargdefault
= lnext(argdefaults
, nextargdefault
);
3377 appendStringInfo(buf
, " DEFAULT %s",
3378 deparse_expression(expr
, NIL
, false, false));
3382 /* nasty hack: print the last arg twice for variadic ordered-set agg */
3383 if (argsprinted
== insertorderbyat
&& i
== numargs
- 1)
3386 /* aggs shouldn't have defaults anyway, but just to be sure ... */
3387 print_defaults
= false;
3395 is_input_argument(int nth
, const char *argmodes
)
3398 || argmodes
[nth
] == PROARGMODE_IN
3399 || argmodes
[nth
] == PROARGMODE_INOUT
3400 || argmodes
[nth
] == PROARGMODE_VARIADIC
);
3404 * Append used transformed types to specified buffer
3407 print_function_trftypes(StringInfo buf
, HeapTuple proctup
)
3412 ntypes
= get_func_trftypes(proctup
, &trftypes
);
3417 appendStringInfoString(buf
, " TRANSFORM ");
3418 for (i
= 0; i
< ntypes
; i
++)
3421 appendStringInfoString(buf
, ", ");
3422 appendStringInfo(buf
, "FOR TYPE %s", format_type_be(trftypes
[i
]));
3424 appendStringInfoChar(buf
, '\n');
3429 * Get textual representation of a function argument's default value. The
3430 * second argument of this function is the argument number among all arguments
3431 * (i.e. proallargtypes, *not* proargtypes), starting with 1, because that's
3432 * how information_schema.sql uses it.
3435 pg_get_function_arg_default(PG_FUNCTION_ARGS
)
3437 Oid funcid
= PG_GETARG_OID(0);
3438 int32 nth_arg
= PG_GETARG_INT32(1);
3450 Datum proargdefaults
;
3454 proctup
= SearchSysCache1(PROCOID
, ObjectIdGetDatum(funcid
));
3455 if (!HeapTupleIsValid(proctup
))
3458 numargs
= get_func_arg_info(proctup
, &argtypes
, &argnames
, &argmodes
);
3459 if (nth_arg
< 1 || nth_arg
> numargs
|| !is_input_argument(nth_arg
- 1, argmodes
))
3461 ReleaseSysCache(proctup
);
3466 for (i
= 0; i
< nth_arg
; i
++)
3467 if (is_input_argument(i
, argmodes
))
3470 proargdefaults
= SysCacheGetAttr(PROCOID
, proctup
,
3471 Anum_pg_proc_proargdefaults
,
3475 ReleaseSysCache(proctup
);
3479 str
= TextDatumGetCString(proargdefaults
);
3480 argdefaults
= castNode(List
, stringToNode(str
));
3483 proc
= (Form_pg_proc
) GETSTRUCT(proctup
);
3486 * Calculate index into proargdefaults: proargdefaults corresponds to the
3487 * last N input arguments, where N = pronargdefaults.
3489 nth_default
= nth_inputarg
- 1 - (proc
->pronargs
- proc
->pronargdefaults
);
3491 if (nth_default
< 0 || nth_default
>= list_length(argdefaults
))
3493 ReleaseSysCache(proctup
);
3496 node
= list_nth(argdefaults
, nth_default
);
3497 str
= deparse_expression(node
, NIL
, false, false);
3499 ReleaseSysCache(proctup
);
3501 PG_RETURN_TEXT_P(string_to_text(str
));
3505 print_function_sqlbody(StringInfo buf
, HeapTuple proctup
)
3511 deparse_namespace dpns
= {0};
3515 dpns
.funcname
= pstrdup(NameStr(((Form_pg_proc
) GETSTRUCT(proctup
))->proname
));
3516 numargs
= get_func_arg_info(proctup
,
3517 &argtypes
, &argnames
, &argmodes
);
3518 dpns
.numargs
= numargs
;
3519 dpns
.argnames
= argnames
;
3521 tmp
= SysCacheGetAttrNotNull(PROCOID
, proctup
, Anum_pg_proc_prosqlbody
);
3522 n
= stringToNode(TextDatumGetCString(tmp
));
3529 stmts
= linitial(castNode(List
, n
));
3531 appendStringInfoString(buf
, "BEGIN ATOMIC\n");
3535 Query
*query
= lfirst_node(Query
, lc
);
3537 /* It seems advisable to get at least AccessShareLock on rels */
3538 AcquireRewriteLocks(query
, false, false);
3539 get_query_def(query
, buf
, list_make1(&dpns
), NULL
, false,
3540 PRETTYFLAG_INDENT
, WRAP_COLUMN_DEFAULT
, 1);
3541 appendStringInfoChar(buf
, ';');
3542 appendStringInfoChar(buf
, '\n');
3545 appendStringInfoString(buf
, "END");
3549 Query
*query
= castNode(Query
, n
);
3551 /* It seems advisable to get at least AccessShareLock on rels */
3552 AcquireRewriteLocks(query
, false, false);
3553 get_query_def(query
, buf
, list_make1(&dpns
), NULL
, false,
3554 0, WRAP_COLUMN_DEFAULT
, 0);
3559 pg_get_function_sqlbody(PG_FUNCTION_ARGS
)
3561 Oid funcid
= PG_GETARG_OID(0);
3566 initStringInfo(&buf
);
3568 /* Look up the function */
3569 proctup
= SearchSysCache1(PROCOID
, ObjectIdGetDatum(funcid
));
3570 if (!HeapTupleIsValid(proctup
))
3573 (void) SysCacheGetAttr(PROCOID
, proctup
, Anum_pg_proc_prosqlbody
, &isnull
);
3576 ReleaseSysCache(proctup
);
3580 print_function_sqlbody(&buf
, proctup
);
3582 ReleaseSysCache(proctup
);
3584 PG_RETURN_TEXT_P(cstring_to_text_with_len(buf
.data
, buf
.len
));
3589 * deparse_expression - General utility for deparsing expressions
3591 * calls deparse_expression_pretty with all prettyPrinting disabled
3594 deparse_expression(Node
*expr
, List
*dpcontext
,
3595 bool forceprefix
, bool showimplicit
)
3597 return deparse_expression_pretty(expr
, dpcontext
, forceprefix
,
3598 showimplicit
, 0, 0);
3602 * deparse_expression_pretty - General utility for deparsing expressions
3604 * expr is the node tree to be deparsed. It must be a transformed expression
3605 * tree (ie, not the raw output of gram.y).
3607 * dpcontext is a list of deparse_namespace nodes representing the context
3608 * for interpreting Vars in the node tree. It can be NIL if no Vars are
3611 * forceprefix is true to force all Vars to be prefixed with their table names.
3613 * showimplicit is true to force all implicit casts to be shown explicitly.
3615 * Tries to pretty up the output according to prettyFlags and startIndent.
3617 * The result is a palloc'd string.
3621 deparse_expression_pretty(Node
*expr
, List
*dpcontext
,
3622 bool forceprefix
, bool showimplicit
,
3623 int prettyFlags
, int startIndent
)
3626 deparse_context context
;
3628 initStringInfo(&buf
);
3630 context
.namespaces
= dpcontext
;
3631 context
.resultDesc
= NULL
;
3632 context
.targetList
= NIL
;
3633 context
.windowClause
= NIL
;
3634 context
.varprefix
= forceprefix
;
3635 context
.prettyFlags
= prettyFlags
;
3636 context
.wrapColumn
= WRAP_COLUMN_DEFAULT
;
3637 context
.indentLevel
= startIndent
;
3638 context
.colNamesVisible
= true;
3639 context
.inGroupBy
= false;
3640 context
.varInOrderBy
= false;
3641 context
.appendparents
= NULL
;
3643 get_rule_expr(expr
, &context
, showimplicit
);
3649 * deparse_context_for - Build deparse context for a single relation
3651 * Given the reference name (alias) and OID of a relation, build deparsing
3652 * context for an expression referencing only that relation (as varno 1,
3653 * varlevelsup 0). This is sufficient for many uses of deparse_expression.
3657 deparse_context_for(const char *aliasname
, Oid relid
)
3659 deparse_namespace
*dpns
;
3662 dpns
= (deparse_namespace
*) palloc0(sizeof(deparse_namespace
));
3664 /* Build a minimal RTE for the rel */
3665 rte
= makeNode(RangeTblEntry
);
3666 rte
->rtekind
= RTE_RELATION
;
3668 rte
->relkind
= RELKIND_RELATION
; /* no need for exactness here */
3669 rte
->rellockmode
= AccessShareLock
;
3670 rte
->alias
= makeAlias(aliasname
, NIL
);
3671 rte
->eref
= rte
->alias
;
3672 rte
->lateral
= false;
3674 rte
->inFromCl
= true;
3676 /* Build one-element rtable */
3677 dpns
->rtable
= list_make1(rte
);
3678 dpns
->subplans
= NIL
;
3680 dpns
->appendrels
= NULL
;
3681 set_rtable_names(dpns
, NIL
, NULL
);
3682 set_simple_column_names(dpns
);
3684 /* Return a one-deep namespace stack */
3685 return list_make1(dpns
);
3689 * deparse_context_for_plan_tree - Build deparse context for a Plan tree
3691 * When deparsing an expression in a Plan tree, we use the plan's rangetable
3692 * to resolve names of simple Vars. The initialization of column names for
3693 * this is rather expensive if the rangetable is large, and it'll be the same
3694 * for every expression in the Plan tree; so we do it just once and re-use
3695 * the result of this function for each expression. (Note that the result
3696 * is not usable until set_deparse_context_plan() is applied to it.)
3698 * In addition to the PlannedStmt, pass the per-RTE alias names
3699 * assigned by a previous call to select_rtable_names_for_explain.
3702 deparse_context_for_plan_tree(PlannedStmt
*pstmt
, List
*rtable_names
)
3704 deparse_namespace
*dpns
;
3706 dpns
= (deparse_namespace
*) palloc0(sizeof(deparse_namespace
));
3708 /* Initialize fields that stay the same across the whole plan tree */
3709 dpns
->rtable
= pstmt
->rtable
;
3710 dpns
->rtable_names
= rtable_names
;
3711 dpns
->subplans
= pstmt
->subplans
;
3713 if (pstmt
->appendRelations
)
3715 /* Set up the array, indexed by child relid */
3716 int ntables
= list_length(dpns
->rtable
);
3719 dpns
->appendrels
= (AppendRelInfo
**)
3720 palloc0((ntables
+ 1) * sizeof(AppendRelInfo
*));
3721 foreach(lc
, pstmt
->appendRelations
)
3723 AppendRelInfo
*appinfo
= lfirst_node(AppendRelInfo
, lc
);
3724 Index crelid
= appinfo
->child_relid
;
3726 Assert(crelid
> 0 && crelid
<= ntables
);
3727 Assert(dpns
->appendrels
[crelid
] == NULL
);
3728 dpns
->appendrels
[crelid
] = appinfo
;
3732 dpns
->appendrels
= NULL
; /* don't need it */
3735 * Set up column name aliases. We will get rather bogus results for join
3736 * RTEs, but that doesn't matter because plan trees don't contain any join
3739 set_simple_column_names(dpns
);
3741 /* Return a one-deep namespace stack */
3742 return list_make1(dpns
);
3746 * set_deparse_context_plan - Specify Plan node containing expression
3748 * When deparsing an expression in a Plan tree, we might have to resolve
3749 * OUTER_VAR, INNER_VAR, or INDEX_VAR references. To do this, the caller must
3750 * provide the parent Plan node. Then OUTER_VAR and INNER_VAR references
3751 * can be resolved by drilling down into the left and right child plans.
3752 * Similarly, INDEX_VAR references can be resolved by reference to the
3753 * indextlist given in a parent IndexOnlyScan node, or to the scan tlist in
3754 * ForeignScan and CustomScan nodes. (Note that we don't currently support
3755 * deparsing of indexquals in regular IndexScan or BitmapIndexScan nodes;
3756 * for those, we can only deparse the indexqualorig fields, which won't
3757 * contain INDEX_VAR Vars.)
3759 * The ancestors list is a list of the Plan's parent Plan and SubPlan nodes,
3760 * the most-closely-nested first. This is needed to resolve PARAM_EXEC
3761 * Params. Note we assume that all the Plan nodes share the same rtable.
3763 * Once this function has been called, deparse_expression() can be called on
3764 * subsidiary expression(s) of the specified Plan node. To deparse
3765 * expressions of a different Plan node in the same Plan tree, re-call this
3766 * function to identify the new parent Plan node.
3768 * The result is the same List passed in; this is a notational convenience.
3771 set_deparse_context_plan(List
*dpcontext
, Plan
*plan
, List
*ancestors
)
3773 deparse_namespace
*dpns
;
3775 /* Should always have one-entry namespace list for Plan deparsing */
3776 Assert(list_length(dpcontext
) == 1);
3777 dpns
= (deparse_namespace
*) linitial(dpcontext
);
3779 /* Set our attention on the specific plan node passed in */
3780 dpns
->ancestors
= ancestors
;
3781 set_deparse_plan(dpns
, plan
);
3787 * select_rtable_names_for_explain - Select RTE aliases for EXPLAIN
3789 * Determine the relation aliases we'll use during an EXPLAIN operation.
3790 * This is just a frontend to set_rtable_names. We have to expose the aliases
3791 * to EXPLAIN because EXPLAIN needs to know the right alias names to print.
3794 select_rtable_names_for_explain(List
*rtable
, Bitmapset
*rels_used
)
3796 deparse_namespace dpns
;
3798 memset(&dpns
, 0, sizeof(dpns
));
3799 dpns
.rtable
= rtable
;
3800 dpns
.subplans
= NIL
;
3802 dpns
.appendrels
= NULL
;
3803 set_rtable_names(&dpns
, NIL
, rels_used
);
3804 /* We needn't bother computing column aliases yet */
3806 return dpns
.rtable_names
;
3810 * set_rtable_names: select RTE aliases to be used in printing a query
3812 * We fill in dpns->rtable_names with a list of names that is one-for-one with
3813 * the already-filled dpns->rtable list. Each RTE name is unique among those
3814 * in the new namespace plus any ancestor namespaces listed in
3815 * parent_namespaces.
3817 * If rels_used isn't NULL, only RTE indexes listed in it are given aliases.
3819 * Note that this function is only concerned with relation names, not column
3823 set_rtable_names(deparse_namespace
*dpns
, List
*parent_namespaces
,
3824 Bitmapset
*rels_used
)
3828 NameHashEntry
*hentry
;
3833 dpns
->rtable_names
= NIL
;
3834 /* nothing more to do if empty rtable */
3835 if (dpns
->rtable
== NIL
)
3839 * We use a hash table to hold known names, so that this process is O(N)
3840 * not O(N^2) for N names.
3842 hash_ctl
.keysize
= NAMEDATALEN
;
3843 hash_ctl
.entrysize
= sizeof(NameHashEntry
);
3844 hash_ctl
.hcxt
= CurrentMemoryContext
;
3845 names_hash
= hash_create("set_rtable_names names",
3846 list_length(dpns
->rtable
),
3848 HASH_ELEM
| HASH_STRINGS
| HASH_CONTEXT
);
3850 /* Preload the hash table with names appearing in parent_namespaces */
3851 foreach(lc
, parent_namespaces
)
3853 deparse_namespace
*olddpns
= (deparse_namespace
*) lfirst(lc
);
3856 foreach(lc2
, olddpns
->rtable_names
)
3858 char *oldname
= (char *) lfirst(lc2
);
3860 if (oldname
== NULL
)
3862 hentry
= (NameHashEntry
*) hash_search(names_hash
,
3866 /* we do not complain about duplicate names in parent namespaces */
3867 hentry
->counter
= 0;
3871 /* Now we can scan the rtable */
3873 foreach(lc
, dpns
->rtable
)
3875 RangeTblEntry
*rte
= (RangeTblEntry
*) lfirst(lc
);
3878 /* Just in case this takes an unreasonable amount of time ... */
3879 CHECK_FOR_INTERRUPTS();
3881 if (rels_used
&& !bms_is_member(rtindex
, rels_used
))
3883 /* Ignore unreferenced RTE */
3886 else if (rte
->alias
)
3888 /* If RTE has a user-defined alias, prefer that */
3889 refname
= rte
->alias
->aliasname
;
3891 else if (rte
->rtekind
== RTE_RELATION
)
3893 /* Use the current actual name of the relation */
3894 refname
= get_rel_name(rte
->relid
);
3896 else if (rte
->rtekind
== RTE_JOIN
)
3898 /* Unnamed join has no refname */
3903 /* Otherwise use whatever the parser assigned */
3904 refname
= rte
->eref
->aliasname
;
3908 * If the selected name isn't unique, append digits to make it so, and
3909 * make a new hash entry for it once we've got a unique name. For a
3910 * very long input name, we might have to truncate to stay within
3915 hentry
= (NameHashEntry
*) hash_search(names_hash
,
3921 /* Name already in use, must choose a new one */
3922 int refnamelen
= strlen(refname
);
3923 char *modname
= (char *) palloc(refnamelen
+ 16);
3924 NameHashEntry
*hentry2
;
3931 memcpy(modname
, refname
, refnamelen
);
3932 sprintf(modname
+ refnamelen
, "_%d", hentry
->counter
);
3933 if (strlen(modname
) < NAMEDATALEN
)
3935 /* drop chars from refname to keep all the digits */
3936 refnamelen
= pg_mbcliplen(refname
, refnamelen
,
3939 hentry2
= (NameHashEntry
*) hash_search(names_hash
,
3944 hentry2
->counter
= 0; /* init new hash entry */
3949 /* Name not previously used, need only initialize hentry */
3950 hentry
->counter
= 0;
3954 dpns
->rtable_names
= lappend(dpns
->rtable_names
, refname
);
3958 hash_destroy(names_hash
);
3962 * set_deparse_for_query: set up deparse_namespace for deparsing a Query tree
3964 * For convenience, this is defined to initialize the deparse_namespace struct
3968 set_deparse_for_query(deparse_namespace
*dpns
, Query
*query
,
3969 List
*parent_namespaces
)
3974 /* Initialize *dpns and fill rtable/ctes links */
3975 memset(dpns
, 0, sizeof(deparse_namespace
));
3976 dpns
->rtable
= query
->rtable
;
3977 dpns
->subplans
= NIL
;
3978 dpns
->ctes
= query
->cteList
;
3979 dpns
->appendrels
= NULL
;
3981 /* Assign a unique relation alias to each RTE */
3982 set_rtable_names(dpns
, parent_namespaces
, NULL
);
3984 /* Initialize dpns->rtable_columns to contain zeroed structs */
3985 dpns
->rtable_columns
= NIL
;
3986 while (list_length(dpns
->rtable_columns
) < list_length(dpns
->rtable
))
3987 dpns
->rtable_columns
= lappend(dpns
->rtable_columns
,
3988 palloc0(sizeof(deparse_columns
)));
3990 /* If it's a utility query, it won't have a jointree */
3991 if (query
->jointree
)
3993 /* Detect whether global uniqueness of USING names is needed */
3994 dpns
->unique_using
=
3995 has_dangerous_join_using(dpns
, (Node
*) query
->jointree
);
3998 * Select names for columns merged by USING, via a recursive pass over
3999 * the query jointree.
4001 set_using_names(dpns
, (Node
*) query
->jointree
, NIL
);
4005 * Now assign remaining column aliases for each RTE. We do this in a
4006 * linear scan of the rtable, so as to process RTEs whether or not they
4007 * are in the jointree (we mustn't miss NEW.*, INSERT target relations,
4008 * etc). JOIN RTEs must be processed after their children, but this is
4009 * okay because they appear later in the rtable list than their children
4010 * (cf Asserts in identify_join_columns()).
4012 forboth(lc
, dpns
->rtable
, lc2
, dpns
->rtable_columns
)
4014 RangeTblEntry
*rte
= (RangeTblEntry
*) lfirst(lc
);
4015 deparse_columns
*colinfo
= (deparse_columns
*) lfirst(lc2
);
4017 if (rte
->rtekind
== RTE_JOIN
)
4018 set_join_column_names(dpns
, rte
, colinfo
);
4020 set_relation_column_names(dpns
, rte
, colinfo
);
4025 * set_simple_column_names: fill in column aliases for non-query situations
4027 * This handles EXPLAIN and cases where we only have relation RTEs. Without
4028 * a join tree, we can't do anything smart about join RTEs, but we don't
4029 * need to (note that EXPLAIN should never see join alias Vars anyway).
4030 * If we do hit a join RTE we'll just process it like a non-table base RTE.
4033 set_simple_column_names(deparse_namespace
*dpns
)
4038 /* Initialize dpns->rtable_columns to contain zeroed structs */
4039 dpns
->rtable_columns
= NIL
;
4040 while (list_length(dpns
->rtable_columns
) < list_length(dpns
->rtable
))
4041 dpns
->rtable_columns
= lappend(dpns
->rtable_columns
,
4042 palloc0(sizeof(deparse_columns
)));
4044 /* Assign unique column aliases within each RTE */
4045 forboth(lc
, dpns
->rtable
, lc2
, dpns
->rtable_columns
)
4047 RangeTblEntry
*rte
= (RangeTblEntry
*) lfirst(lc
);
4048 deparse_columns
*colinfo
= (deparse_columns
*) lfirst(lc2
);
4050 set_relation_column_names(dpns
, rte
, colinfo
);
4055 * has_dangerous_join_using: search jointree for unnamed JOIN USING
4057 * Merged columns of a JOIN USING may act differently from either of the input
4058 * columns, either because they are merged with COALESCE (in a FULL JOIN) or
4059 * because an implicit coercion of the underlying input column is required.
4060 * In such a case the column must be referenced as a column of the JOIN not as
4061 * a column of either input. And this is problematic if the join is unnamed
4062 * (alias-less): we cannot qualify the column's name with an RTE name, since
4063 * there is none. (Forcibly assigning an alias to the join is not a solution,
4064 * since that will prevent legal references to tables below the join.)
4065 * To ensure that every column in the query is unambiguously referenceable,
4066 * we must assign such merged columns names that are globally unique across
4067 * the whole query, aliasing other columns out of the way as necessary.
4069 * Because the ensuing re-aliasing is fairly damaging to the readability of
4070 * the query, we don't do this unless we have to. So, we must pre-scan
4071 * the join tree to see if we have to, before starting set_using_names().
4074 has_dangerous_join_using(deparse_namespace
*dpns
, Node
*jtnode
)
4076 if (IsA(jtnode
, RangeTblRef
))
4078 /* nothing to do here */
4080 else if (IsA(jtnode
, FromExpr
))
4082 FromExpr
*f
= (FromExpr
*) jtnode
;
4085 foreach(lc
, f
->fromlist
)
4087 if (has_dangerous_join_using(dpns
, (Node
*) lfirst(lc
)))
4091 else if (IsA(jtnode
, JoinExpr
))
4093 JoinExpr
*j
= (JoinExpr
*) jtnode
;
4095 /* Is it an unnamed JOIN with USING? */
4096 if (j
->alias
== NULL
&& j
->usingClause
)
4099 * Yes, so check each join alias var to see if any of them are not
4100 * simple references to underlying columns. If so, we have a
4101 * dangerous situation and must pick unique aliases.
4103 RangeTblEntry
*jrte
= rt_fetch(j
->rtindex
, dpns
->rtable
);
4105 /* We need only examine the merged columns */
4106 for (int i
= 0; i
< jrte
->joinmergedcols
; i
++)
4108 Node
*aliasvar
= list_nth(jrte
->joinaliasvars
, i
);
4110 if (!IsA(aliasvar
, Var
))
4115 /* Nope, but inspect children */
4116 if (has_dangerous_join_using(dpns
, j
->larg
))
4118 if (has_dangerous_join_using(dpns
, j
->rarg
))
4122 elog(ERROR
, "unrecognized node type: %d",
4123 (int) nodeTag(jtnode
));
4128 * set_using_names: select column aliases to be used for merged USING columns
4130 * We do this during a recursive descent of the query jointree.
4131 * dpns->unique_using must already be set to determine the global strategy.
4133 * Column alias info is saved in the dpns->rtable_columns list, which is
4134 * assumed to be filled with pre-zeroed deparse_columns structs.
4136 * parentUsing is a list of all USING aliases assigned in parent joins of
4137 * the current jointree node. (The passed-in list must not be modified.)
4140 set_using_names(deparse_namespace
*dpns
, Node
*jtnode
, List
*parentUsing
)
4142 if (IsA(jtnode
, RangeTblRef
))
4144 /* nothing to do now */
4146 else if (IsA(jtnode
, FromExpr
))
4148 FromExpr
*f
= (FromExpr
*) jtnode
;
4151 foreach(lc
, f
->fromlist
)
4152 set_using_names(dpns
, (Node
*) lfirst(lc
), parentUsing
);
4154 else if (IsA(jtnode
, JoinExpr
))
4156 JoinExpr
*j
= (JoinExpr
*) jtnode
;
4157 RangeTblEntry
*rte
= rt_fetch(j
->rtindex
, dpns
->rtable
);
4158 deparse_columns
*colinfo
= deparse_columns_fetch(j
->rtindex
, dpns
);
4161 deparse_columns
*leftcolinfo
;
4162 deparse_columns
*rightcolinfo
;
4166 /* Get info about the shape of the join */
4167 identify_join_columns(j
, rte
, colinfo
);
4168 leftattnos
= colinfo
->leftattnos
;
4169 rightattnos
= colinfo
->rightattnos
;
4171 /* Look up the not-yet-filled-in child deparse_columns structs */
4172 leftcolinfo
= deparse_columns_fetch(colinfo
->leftrti
, dpns
);
4173 rightcolinfo
= deparse_columns_fetch(colinfo
->rightrti
, dpns
);
4176 * If this join is unnamed, then we cannot substitute new aliases at
4177 * this level, so any name requirements pushed down to here must be
4178 * pushed down again to the children.
4180 if (rte
->alias
== NULL
)
4182 for (i
= 0; i
< colinfo
->num_cols
; i
++)
4184 char *colname
= colinfo
->colnames
[i
];
4186 if (colname
== NULL
)
4189 /* Push down to left column, unless it's a system column */
4190 if (leftattnos
[i
] > 0)
4192 expand_colnames_array_to(leftcolinfo
, leftattnos
[i
]);
4193 leftcolinfo
->colnames
[leftattnos
[i
] - 1] = colname
;
4196 /* Same on the righthand side */
4197 if (rightattnos
[i
] > 0)
4199 expand_colnames_array_to(rightcolinfo
, rightattnos
[i
]);
4200 rightcolinfo
->colnames
[rightattnos
[i
] - 1] = colname
;
4206 * If there's a USING clause, select the USING column names and push
4207 * those names down to the children. We have two strategies:
4209 * If dpns->unique_using is true, we force all USING names to be
4210 * unique across the whole query level. In principle we'd only need
4211 * the names of dangerous USING columns to be globally unique, but to
4212 * safely assign all USING names in a single pass, we have to enforce
4213 * the same uniqueness rule for all of them. However, if a USING
4214 * column's name has been pushed down from the parent, we should use
4215 * it as-is rather than making a uniqueness adjustment. This is
4216 * necessary when we're at an unnamed join, and it creates no risk of
4217 * ambiguity. Also, if there's a user-written output alias for a
4218 * merged column, we prefer to use that rather than the input name;
4219 * this simplifies the logic and seems likely to lead to less aliasing
4222 * If dpns->unique_using is false, we only need USING names to be
4223 * unique within their own join RTE. We still need to honor
4224 * pushed-down names, though.
4226 * Though significantly different in results, these two strategies are
4227 * implemented by the same code, with only the difference of whether
4228 * to put assigned names into dpns->using_names.
4232 /* Copy the input parentUsing list so we don't modify it */
4233 parentUsing
= list_copy(parentUsing
);
4235 /* USING names must correspond to the first join output columns */
4236 expand_colnames_array_to(colinfo
, list_length(j
->usingClause
));
4238 foreach(lc
, j
->usingClause
)
4240 char *colname
= strVal(lfirst(lc
));
4242 /* Assert it's a merged column */
4243 Assert(leftattnos
[i
] != 0 && rightattnos
[i
] != 0);
4245 /* Adopt passed-down name if any, else select unique name */
4246 if (colinfo
->colnames
[i
] != NULL
)
4247 colname
= colinfo
->colnames
[i
];
4250 /* Prefer user-written output alias if any */
4251 if (rte
->alias
&& i
< list_length(rte
->alias
->colnames
))
4252 colname
= strVal(list_nth(rte
->alias
->colnames
, i
));
4253 /* Make it appropriately unique */
4254 colname
= make_colname_unique(colname
, dpns
, colinfo
);
4255 if (dpns
->unique_using
)
4256 dpns
->using_names
= lappend(dpns
->using_names
,
4258 /* Save it as output column name, too */
4259 colinfo
->colnames
[i
] = colname
;
4262 /* Remember selected names for use later */
4263 colinfo
->usingNames
= lappend(colinfo
->usingNames
, colname
);
4264 parentUsing
= lappend(parentUsing
, colname
);
4266 /* Push down to left column, unless it's a system column */
4267 if (leftattnos
[i
] > 0)
4269 expand_colnames_array_to(leftcolinfo
, leftattnos
[i
]);
4270 leftcolinfo
->colnames
[leftattnos
[i
] - 1] = colname
;
4273 /* Same on the righthand side */
4274 if (rightattnos
[i
] > 0)
4276 expand_colnames_array_to(rightcolinfo
, rightattnos
[i
]);
4277 rightcolinfo
->colnames
[rightattnos
[i
] - 1] = colname
;
4284 /* Mark child deparse_columns structs with correct parentUsing info */
4285 leftcolinfo
->parentUsing
= parentUsing
;
4286 rightcolinfo
->parentUsing
= parentUsing
;
4288 /* Now recursively assign USING column names in children */
4289 set_using_names(dpns
, j
->larg
, parentUsing
);
4290 set_using_names(dpns
, j
->rarg
, parentUsing
);
4293 elog(ERROR
, "unrecognized node type: %d",
4294 (int) nodeTag(jtnode
));
4298 * set_relation_column_names: select column aliases for a non-join RTE
4300 * Column alias info is saved in *colinfo, which is assumed to be pre-zeroed.
4301 * If any colnames entries are already filled in, those override local
4305 set_relation_column_names(deparse_namespace
*dpns
, RangeTblEntry
*rte
,
4306 deparse_columns
*colinfo
)
4309 char **real_colnames
;
4316 * Construct an array of the current "real" column names of the RTE.
4317 * real_colnames[] will be indexed by physical column number, with NULL
4318 * entries for dropped columns.
4320 if (rte
->rtekind
== RTE_RELATION
)
4322 /* Relation --- look to the system catalogs for up-to-date info */
4326 rel
= relation_open(rte
->relid
, AccessShareLock
);
4327 tupdesc
= RelationGetDescr(rel
);
4329 ncolumns
= tupdesc
->natts
;
4330 real_colnames
= (char **) palloc(ncolumns
* sizeof(char *));
4332 for (i
= 0; i
< ncolumns
; i
++)
4334 Form_pg_attribute attr
= TupleDescAttr(tupdesc
, i
);
4336 if (attr
->attisdropped
)
4337 real_colnames
[i
] = NULL
;
4339 real_colnames
[i
] = pstrdup(NameStr(attr
->attname
));
4341 relation_close(rel
, AccessShareLock
);
4345 /* Otherwise get the column names from eref or expandRTE() */
4350 * Functions returning composites have the annoying property that some
4351 * of the composite type's columns might have been dropped since the
4352 * query was parsed. If possible, use expandRTE() to handle that
4353 * case, since it has the tedious logic needed to find out about
4354 * dropped columns. However, if we're explaining a plan, then we
4355 * don't have rte->functions because the planner thinks that won't be
4356 * needed later, and that breaks expandRTE(). So in that case we have
4357 * to rely on rte->eref, which may lead us to report a dropped
4358 * column's old name; that seems close enough for EXPLAIN's purposes.
4360 * For non-RELATION, non-FUNCTION RTEs, we can just look at rte->eref,
4361 * which should be sufficiently up-to-date: no other RTE types can
4362 * have columns get dropped from under them after parsing.
4364 if (rte
->rtekind
== RTE_FUNCTION
&& rte
->functions
!= NIL
)
4366 /* Since we're not creating Vars, rtindex etc. don't matter */
4367 expandRTE(rte
, 1, 0, -1, true /* include dropped */ ,
4371 colnames
= rte
->eref
->colnames
;
4373 ncolumns
= list_length(colnames
);
4374 real_colnames
= (char **) palloc(ncolumns
* sizeof(char *));
4377 foreach(lc
, colnames
)
4380 * If the column name we find here is an empty string, then it's a
4381 * dropped column, so change to NULL.
4383 char *cname
= strVal(lfirst(lc
));
4385 if (cname
[0] == '\0')
4387 real_colnames
[i
] = cname
;
4393 * Ensure colinfo->colnames has a slot for each column. (It could be long
4394 * enough already, if we pushed down a name for the last column.) Note:
4395 * it's possible that there are now more columns than there were when the
4396 * query was parsed, ie colnames could be longer than rte->eref->colnames.
4397 * We must assign unique aliases to the new columns too, else there could
4398 * be unresolved conflicts when the view/rule is reloaded.
4400 expand_colnames_array_to(colinfo
, ncolumns
);
4401 Assert(colinfo
->num_cols
== ncolumns
);
4404 * Make sufficiently large new_colnames and is_new_col arrays, too.
4406 * Note: because we leave colinfo->num_new_cols zero until after the loop,
4407 * colname_is_unique will not consult that array, which is fine because it
4408 * would only be duplicate effort.
4410 colinfo
->new_colnames
= (char **) palloc(ncolumns
* sizeof(char *));
4411 colinfo
->is_new_col
= (bool *) palloc(ncolumns
* sizeof(bool));
4414 * Scan the columns, select a unique alias for each one, and store it in
4415 * colinfo->colnames and colinfo->new_colnames. The former array has NULL
4416 * entries for dropped columns, the latter omits them. Also mark
4417 * new_colnames entries as to whether they are new since parse time; this
4418 * is the case for entries beyond the length of rte->eref->colnames.
4420 noldcolumns
= list_length(rte
->eref
->colnames
);
4421 changed_any
= false;
4423 for (i
= 0; i
< ncolumns
; i
++)
4425 char *real_colname
= real_colnames
[i
];
4426 char *colname
= colinfo
->colnames
[i
];
4428 /* Skip dropped columns */
4429 if (real_colname
== NULL
)
4431 Assert(colname
== NULL
); /* colnames[i] is already NULL */
4435 /* If alias already assigned, that's what to use */
4436 if (colname
== NULL
)
4438 /* If user wrote an alias, prefer that over real column name */
4439 if (rte
->alias
&& i
< list_length(rte
->alias
->colnames
))
4440 colname
= strVal(list_nth(rte
->alias
->colnames
, i
));
4442 colname
= real_colname
;
4444 /* Unique-ify and insert into colinfo */
4445 colname
= make_colname_unique(colname
, dpns
, colinfo
);
4447 colinfo
->colnames
[i
] = colname
;
4450 /* Put names of non-dropped columns in new_colnames[] too */
4451 colinfo
->new_colnames
[j
] = colname
;
4452 /* And mark them as new or not */
4453 colinfo
->is_new_col
[j
] = (i
>= noldcolumns
);
4456 /* Remember if any assigned aliases differ from "real" name */
4457 if (!changed_any
&& strcmp(colname
, real_colname
) != 0)
4462 * Set correct length for new_colnames[] array. (Note: if columns have
4463 * been added, colinfo->num_cols includes them, which is not really quite
4464 * right but is harmless, since any new columns must be at the end where
4465 * they won't affect varattnos of pre-existing columns.)
4467 colinfo
->num_new_cols
= j
;
4470 * For a relation RTE, we need only print the alias column names if any
4471 * are different from the underlying "real" names. For a function RTE,
4472 * always emit a complete column alias list; this is to protect against
4473 * possible instability of the default column names (eg, from altering
4474 * parameter names). For tablefunc RTEs, we never print aliases, because
4475 * the column names are part of the clause itself. For other RTE types,
4476 * print if we changed anything OR if there were user-written column
4477 * aliases (since the latter would be part of the underlying "reality").
4479 if (rte
->rtekind
== RTE_RELATION
)
4480 colinfo
->printaliases
= changed_any
;
4481 else if (rte
->rtekind
== RTE_FUNCTION
)
4482 colinfo
->printaliases
= true;
4483 else if (rte
->rtekind
== RTE_TABLEFUNC
)
4484 colinfo
->printaliases
= false;
4485 else if (rte
->alias
&& rte
->alias
->colnames
!= NIL
)
4486 colinfo
->printaliases
= true;
4488 colinfo
->printaliases
= changed_any
;
4492 * set_join_column_names: select column aliases for a join RTE
4494 * Column alias info is saved in *colinfo, which is assumed to be pre-zeroed.
4495 * If any colnames entries are already filled in, those override local
4496 * choices. Also, names for USING columns were already chosen by
4497 * set_using_names(). We further expect that column alias selection has been
4498 * completed for both input RTEs.
4501 set_join_column_names(deparse_namespace
*dpns
, RangeTblEntry
*rte
,
4502 deparse_columns
*colinfo
)
4504 deparse_columns
*leftcolinfo
;
4505 deparse_columns
*rightcolinfo
;
4509 Bitmapset
*leftmerged
= NULL
;
4510 Bitmapset
*rightmerged
= NULL
;
4516 /* Look up the previously-filled-in child deparse_columns structs */
4517 leftcolinfo
= deparse_columns_fetch(colinfo
->leftrti
, dpns
);
4518 rightcolinfo
= deparse_columns_fetch(colinfo
->rightrti
, dpns
);
4521 * Ensure colinfo->colnames has a slot for each column. (It could be long
4522 * enough already, if we pushed down a name for the last column.) Note:
4523 * it's possible that one or both inputs now have more columns than there
4524 * were when the query was parsed, but we'll deal with that below. We
4525 * only need entries in colnames for pre-existing columns.
4527 noldcolumns
= list_length(rte
->eref
->colnames
);
4528 expand_colnames_array_to(colinfo
, noldcolumns
);
4529 Assert(colinfo
->num_cols
== noldcolumns
);
4532 * Scan the join output columns, select an alias for each one, and store
4533 * it in colinfo->colnames. If there are USING columns, set_using_names()
4534 * already selected their names, so we can start the loop at the first
4535 * non-merged column.
4537 changed_any
= false;
4538 for (i
= list_length(colinfo
->usingNames
); i
< noldcolumns
; i
++)
4540 char *colname
= colinfo
->colnames
[i
];
4543 /* Join column must refer to at least one input column */
4544 Assert(colinfo
->leftattnos
[i
] != 0 || colinfo
->rightattnos
[i
] != 0);
4546 /* Get the child column name */
4547 if (colinfo
->leftattnos
[i
] > 0)
4548 real_colname
= leftcolinfo
->colnames
[colinfo
->leftattnos
[i
] - 1];
4549 else if (colinfo
->rightattnos
[i
] > 0)
4550 real_colname
= rightcolinfo
->colnames
[colinfo
->rightattnos
[i
] - 1];
4553 /* We're joining system columns --- use eref name */
4554 real_colname
= strVal(list_nth(rte
->eref
->colnames
, i
));
4557 /* If child col has been dropped, no need to assign a join colname */
4558 if (real_colname
== NULL
)
4560 colinfo
->colnames
[i
] = NULL
;
4564 /* In an unnamed join, just report child column names as-is */
4565 if (rte
->alias
== NULL
)
4567 colinfo
->colnames
[i
] = real_colname
;
4571 /* If alias already assigned, that's what to use */
4572 if (colname
== NULL
)
4574 /* If user wrote an alias, prefer that over real column name */
4575 if (rte
->alias
&& i
< list_length(rte
->alias
->colnames
))
4576 colname
= strVal(list_nth(rte
->alias
->colnames
, i
));
4578 colname
= real_colname
;
4580 /* Unique-ify and insert into colinfo */
4581 colname
= make_colname_unique(colname
, dpns
, colinfo
);
4583 colinfo
->colnames
[i
] = colname
;
4586 /* Remember if any assigned aliases differ from "real" name */
4587 if (!changed_any
&& strcmp(colname
, real_colname
) != 0)
4592 * Calculate number of columns the join would have if it were re-parsed
4593 * now, and create storage for the new_colnames and is_new_col arrays.
4595 * Note: colname_is_unique will be consulting new_colnames[] during the
4596 * loops below, so its not-yet-filled entries must be zeroes.
4598 nnewcolumns
= leftcolinfo
->num_new_cols
+ rightcolinfo
->num_new_cols
-
4599 list_length(colinfo
->usingNames
);
4600 colinfo
->num_new_cols
= nnewcolumns
;
4601 colinfo
->new_colnames
= (char **) palloc0(nnewcolumns
* sizeof(char *));
4602 colinfo
->is_new_col
= (bool *) palloc0(nnewcolumns
* sizeof(bool));
4605 * Generating the new_colnames array is a bit tricky since any new columns
4606 * added since parse time must be inserted in the right places. This code
4607 * must match the parser, which will order a join's columns as merged
4608 * columns first (in USING-clause order), then non-merged columns from the
4609 * left input (in attnum order), then non-merged columns from the right
4610 * input (ditto). If one of the inputs is itself a join, its columns will
4611 * be ordered according to the same rule, which means newly-added columns
4612 * might not be at the end. We can figure out what's what by consulting
4613 * the leftattnos and rightattnos arrays plus the input is_new_col arrays.
4615 * In these loops, i indexes leftattnos/rightattnos (so it's join varattno
4616 * less one), j indexes new_colnames/is_new_col, and ic/jc have similar
4617 * meanings for the current child RTE.
4620 /* Handle merged columns; they are first and can't be new */
4622 while (i
< noldcolumns
&&
4623 colinfo
->leftattnos
[i
] != 0 &&
4624 colinfo
->rightattnos
[i
] != 0)
4626 /* column name is already determined and known unique */
4627 colinfo
->new_colnames
[j
] = colinfo
->colnames
[i
];
4628 colinfo
->is_new_col
[j
] = false;
4630 /* build bitmapsets of child attnums of merged columns */
4631 if (colinfo
->leftattnos
[i
] > 0)
4632 leftmerged
= bms_add_member(leftmerged
, colinfo
->leftattnos
[i
]);
4633 if (colinfo
->rightattnos
[i
] > 0)
4634 rightmerged
= bms_add_member(rightmerged
, colinfo
->rightattnos
[i
]);
4639 /* Handle non-merged left-child columns */
4641 for (jc
= 0; jc
< leftcolinfo
->num_new_cols
; jc
++)
4643 char *child_colname
= leftcolinfo
->new_colnames
[jc
];
4645 if (!leftcolinfo
->is_new_col
[jc
])
4647 /* Advance ic to next non-dropped old column of left child */
4648 while (ic
< leftcolinfo
->num_cols
&&
4649 leftcolinfo
->colnames
[ic
] == NULL
)
4651 Assert(ic
< leftcolinfo
->num_cols
);
4653 /* If it is a merged column, we already processed it */
4654 if (bms_is_member(ic
, leftmerged
))
4656 /* Else, advance i to the corresponding existing join column */
4657 while (i
< colinfo
->num_cols
&&
4658 colinfo
->colnames
[i
] == NULL
)
4660 Assert(i
< colinfo
->num_cols
);
4661 Assert(ic
== colinfo
->leftattnos
[i
]);
4662 /* Use the already-assigned name of this column */
4663 colinfo
->new_colnames
[j
] = colinfo
->colnames
[i
];
4669 * Unique-ify the new child column name and assign, unless we're
4670 * in an unnamed join, in which case just copy
4672 if (rte
->alias
!= NULL
)
4674 colinfo
->new_colnames
[j
] =
4675 make_colname_unique(child_colname
, dpns
, colinfo
);
4677 strcmp(colinfo
->new_colnames
[j
], child_colname
) != 0)
4681 colinfo
->new_colnames
[j
] = child_colname
;
4684 colinfo
->is_new_col
[j
] = leftcolinfo
->is_new_col
[jc
];
4688 /* Handle non-merged right-child columns in exactly the same way */
4690 for (jc
= 0; jc
< rightcolinfo
->num_new_cols
; jc
++)
4692 char *child_colname
= rightcolinfo
->new_colnames
[jc
];
4694 if (!rightcolinfo
->is_new_col
[jc
])
4696 /* Advance ic to next non-dropped old column of right child */
4697 while (ic
< rightcolinfo
->num_cols
&&
4698 rightcolinfo
->colnames
[ic
] == NULL
)
4700 Assert(ic
< rightcolinfo
->num_cols
);
4702 /* If it is a merged column, we already processed it */
4703 if (bms_is_member(ic
, rightmerged
))
4705 /* Else, advance i to the corresponding existing join column */
4706 while (i
< colinfo
->num_cols
&&
4707 colinfo
->colnames
[i
] == NULL
)
4709 Assert(i
< colinfo
->num_cols
);
4710 Assert(ic
== colinfo
->rightattnos
[i
]);
4711 /* Use the already-assigned name of this column */
4712 colinfo
->new_colnames
[j
] = colinfo
->colnames
[i
];
4718 * Unique-ify the new child column name and assign, unless we're
4719 * in an unnamed join, in which case just copy
4721 if (rte
->alias
!= NULL
)
4723 colinfo
->new_colnames
[j
] =
4724 make_colname_unique(child_colname
, dpns
, colinfo
);
4726 strcmp(colinfo
->new_colnames
[j
], child_colname
) != 0)
4730 colinfo
->new_colnames
[j
] = child_colname
;
4733 colinfo
->is_new_col
[j
] = rightcolinfo
->is_new_col
[jc
];
4737 /* Assert we processed the right number of columns */
4738 #ifdef USE_ASSERT_CHECKING
4739 while (i
< colinfo
->num_cols
&& colinfo
->colnames
[i
] == NULL
)
4741 Assert(i
== colinfo
->num_cols
);
4742 Assert(j
== nnewcolumns
);
4746 * For a named join, print column aliases if we changed any from the child
4747 * names. Unnamed joins cannot print aliases.
4749 if (rte
->alias
!= NULL
)
4750 colinfo
->printaliases
= changed_any
;
4752 colinfo
->printaliases
= false;
4756 * colname_is_unique: is colname distinct from already-chosen column names?
4758 * dpns is query-wide info, colinfo is for the column's RTE
4761 colname_is_unique(const char *colname
, deparse_namespace
*dpns
,
4762 deparse_columns
*colinfo
)
4767 /* Check against already-assigned column aliases within RTE */
4768 for (i
= 0; i
< colinfo
->num_cols
; i
++)
4770 char *oldname
= colinfo
->colnames
[i
];
4772 if (oldname
&& strcmp(oldname
, colname
) == 0)
4777 * If we're building a new_colnames array, check that too (this will be
4778 * partially but not completely redundant with the previous checks)
4780 for (i
= 0; i
< colinfo
->num_new_cols
; i
++)
4782 char *oldname
= colinfo
->new_colnames
[i
];
4784 if (oldname
&& strcmp(oldname
, colname
) == 0)
4788 /* Also check against USING-column names that must be globally unique */
4789 foreach(lc
, dpns
->using_names
)
4791 char *oldname
= (char *) lfirst(lc
);
4793 if (strcmp(oldname
, colname
) == 0)
4797 /* Also check against names already assigned for parent-join USING cols */
4798 foreach(lc
, colinfo
->parentUsing
)
4800 char *oldname
= (char *) lfirst(lc
);
4802 if (strcmp(oldname
, colname
) == 0)
4810 * make_colname_unique: modify colname if necessary to make it unique
4812 * dpns is query-wide info, colinfo is for the column's RTE
4815 make_colname_unique(char *colname
, deparse_namespace
*dpns
,
4816 deparse_columns
*colinfo
)
4819 * If the selected name isn't unique, append digits to make it so. For a
4820 * very long input name, we might have to truncate to stay within
4823 if (!colname_is_unique(colname
, dpns
, colinfo
))
4825 int colnamelen
= strlen(colname
);
4826 char *modname
= (char *) palloc(colnamelen
+ 16);
4834 memcpy(modname
, colname
, colnamelen
);
4835 sprintf(modname
+ colnamelen
, "_%d", i
);
4836 if (strlen(modname
) < NAMEDATALEN
)
4838 /* drop chars from colname to keep all the digits */
4839 colnamelen
= pg_mbcliplen(colname
, colnamelen
,
4842 } while (!colname_is_unique(modname
, dpns
, colinfo
));
4849 * expand_colnames_array_to: make colinfo->colnames at least n items long
4851 * Any added array entries are initialized to zero.
4854 expand_colnames_array_to(deparse_columns
*colinfo
, int n
)
4856 if (n
> colinfo
->num_cols
)
4858 if (colinfo
->colnames
== NULL
)
4859 colinfo
->colnames
= palloc0_array(char *, n
);
4861 colinfo
->colnames
= repalloc0_array(colinfo
->colnames
, char *, colinfo
->num_cols
, n
);
4862 colinfo
->num_cols
= n
;
4867 * identify_join_columns: figure out where columns of a join come from
4869 * Fills the join-specific fields of the colinfo struct, except for
4870 * usingNames which is filled later.
4873 identify_join_columns(JoinExpr
*j
, RangeTblEntry
*jrte
,
4874 deparse_columns
*colinfo
)
4881 /* Extract left/right child RT indexes */
4882 if (IsA(j
->larg
, RangeTblRef
))
4883 colinfo
->leftrti
= ((RangeTblRef
*) j
->larg
)->rtindex
;
4884 else if (IsA(j
->larg
, JoinExpr
))
4885 colinfo
->leftrti
= ((JoinExpr
*) j
->larg
)->rtindex
;
4887 elog(ERROR
, "unrecognized node type in jointree: %d",
4888 (int) nodeTag(j
->larg
));
4889 if (IsA(j
->rarg
, RangeTblRef
))
4890 colinfo
->rightrti
= ((RangeTblRef
*) j
->rarg
)->rtindex
;
4891 else if (IsA(j
->rarg
, JoinExpr
))
4892 colinfo
->rightrti
= ((JoinExpr
*) j
->rarg
)->rtindex
;
4894 elog(ERROR
, "unrecognized node type in jointree: %d",
4895 (int) nodeTag(j
->rarg
));
4897 /* Assert children will be processed earlier than join in second pass */
4898 Assert(colinfo
->leftrti
< j
->rtindex
);
4899 Assert(colinfo
->rightrti
< j
->rtindex
);
4901 /* Initialize result arrays with zeroes */
4902 numjoincols
= list_length(jrte
->joinaliasvars
);
4903 Assert(numjoincols
== list_length(jrte
->eref
->colnames
));
4904 colinfo
->leftattnos
= (int *) palloc0(numjoincols
* sizeof(int));
4905 colinfo
->rightattnos
= (int *) palloc0(numjoincols
* sizeof(int));
4908 * Deconstruct RTE's joinleftcols/joinrightcols into desired format.
4909 * Recall that the column(s) merged due to USING are the first column(s)
4910 * of the join output. We need not do anything special while scanning
4911 * joinleftcols, but while scanning joinrightcols we must distinguish
4912 * merged from unmerged columns.
4915 foreach(lc
, jrte
->joinleftcols
)
4917 int leftattno
= lfirst_int(lc
);
4919 colinfo
->leftattnos
[jcolno
++] = leftattno
;
4922 foreach(lc
, jrte
->joinrightcols
)
4924 int rightattno
= lfirst_int(lc
);
4926 if (rcolno
< jrte
->joinmergedcols
) /* merged column? */
4927 colinfo
->rightattnos
[rcolno
] = rightattno
;
4929 colinfo
->rightattnos
[jcolno
++] = rightattno
;
4932 Assert(jcolno
== numjoincols
);
4936 * get_rtable_name: convenience function to get a previously assigned RTE alias
4938 * The RTE must belong to the topmost namespace level in "context".
4941 get_rtable_name(int rtindex
, deparse_context
*context
)
4943 deparse_namespace
*dpns
= (deparse_namespace
*) linitial(context
->namespaces
);
4945 Assert(rtindex
> 0 && rtindex
<= list_length(dpns
->rtable_names
));
4946 return (char *) list_nth(dpns
->rtable_names
, rtindex
- 1);
4950 * set_deparse_plan: set up deparse_namespace to parse subexpressions
4951 * of a given Plan node
4953 * This sets the plan, outer_plan, inner_plan, outer_tlist, inner_tlist,
4954 * and index_tlist fields. Caller must already have adjusted the ancestors
4955 * list if necessary. Note that the rtable, subplans, and ctes fields do
4956 * not need to change when shifting attention to different plan nodes in a
4960 set_deparse_plan(deparse_namespace
*dpns
, Plan
*plan
)
4965 * We special-case Append and MergeAppend to pretend that the first child
4966 * plan is the OUTER referent; we have to interpret OUTER Vars in their
4967 * tlists according to one of the children, and the first one is the most
4970 if (IsA(plan
, Append
))
4971 dpns
->outer_plan
= linitial(((Append
*) plan
)->appendplans
);
4972 else if (IsA(plan
, MergeAppend
))
4973 dpns
->outer_plan
= linitial(((MergeAppend
*) plan
)->mergeplans
);
4975 dpns
->outer_plan
= outerPlan(plan
);
4977 if (dpns
->outer_plan
)
4978 dpns
->outer_tlist
= dpns
->outer_plan
->targetlist
;
4980 dpns
->outer_tlist
= NIL
;
4983 * For a SubqueryScan, pretend the subplan is INNER referent. (We don't
4984 * use OUTER because that could someday conflict with the normal meaning.)
4985 * Likewise, for a CteScan, pretend the subquery's plan is INNER referent.
4986 * For a WorkTableScan, locate the parent RecursiveUnion plan node and use
4987 * that as INNER referent.
4989 * For MERGE, pretend the ModifyTable's source plan (its outer plan) is
4990 * INNER referent. This is the join from the target relation to the data
4991 * source, and all INNER_VAR Vars in other parts of the query refer to its
4994 * For ON CONFLICT .. UPDATE we just need the inner tlist to point to the
4995 * excluded expression's tlist. (Similar to the SubqueryScan we don't want
4996 * to reuse OUTER, it's used for RETURNING in some modify table cases,
4997 * although not INSERT .. CONFLICT).
4999 if (IsA(plan
, SubqueryScan
))
5000 dpns
->inner_plan
= ((SubqueryScan
*) plan
)->subplan
;
5001 else if (IsA(plan
, CteScan
))
5002 dpns
->inner_plan
= list_nth(dpns
->subplans
,
5003 ((CteScan
*) plan
)->ctePlanId
- 1);
5004 else if (IsA(plan
, WorkTableScan
))
5005 dpns
->inner_plan
= find_recursive_union(dpns
,
5006 (WorkTableScan
*) plan
);
5007 else if (IsA(plan
, ModifyTable
))
5009 if (((ModifyTable
*) plan
)->operation
== CMD_MERGE
)
5010 dpns
->inner_plan
= outerPlan(plan
);
5012 dpns
->inner_plan
= plan
;
5015 dpns
->inner_plan
= innerPlan(plan
);
5017 if (IsA(plan
, ModifyTable
) && ((ModifyTable
*) plan
)->operation
== CMD_INSERT
)
5018 dpns
->inner_tlist
= ((ModifyTable
*) plan
)->exclRelTlist
;
5019 else if (dpns
->inner_plan
)
5020 dpns
->inner_tlist
= dpns
->inner_plan
->targetlist
;
5022 dpns
->inner_tlist
= NIL
;
5024 /* Set up referent for INDEX_VAR Vars, if needed */
5025 if (IsA(plan
, IndexOnlyScan
))
5026 dpns
->index_tlist
= ((IndexOnlyScan
*) plan
)->indextlist
;
5027 else if (IsA(plan
, ForeignScan
))
5028 dpns
->index_tlist
= ((ForeignScan
*) plan
)->fdw_scan_tlist
;
5029 else if (IsA(plan
, CustomScan
))
5030 dpns
->index_tlist
= ((CustomScan
*) plan
)->custom_scan_tlist
;
5032 dpns
->index_tlist
= NIL
;
5036 * Locate the ancestor plan node that is the RecursiveUnion generating
5037 * the WorkTableScan's work table. We can match on wtParam, since that
5038 * should be unique within the plan tree.
5041 find_recursive_union(deparse_namespace
*dpns
, WorkTableScan
*wtscan
)
5045 foreach(lc
, dpns
->ancestors
)
5047 Plan
*ancestor
= (Plan
*) lfirst(lc
);
5049 if (IsA(ancestor
, RecursiveUnion
) &&
5050 ((RecursiveUnion
*) ancestor
)->wtParam
== wtscan
->wtParam
)
5053 elog(ERROR
, "could not find RecursiveUnion for WorkTableScan with wtParam %d",
5059 * push_child_plan: temporarily transfer deparsing attention to a child plan
5061 * When expanding an OUTER_VAR or INNER_VAR reference, we must adjust the
5062 * deparse context in case the referenced expression itself uses
5063 * OUTER_VAR/INNER_VAR. We modify the top stack entry in-place to avoid
5064 * affecting levelsup issues (although in a Plan tree there really shouldn't
5067 * Caller must provide a local deparse_namespace variable to save the
5068 * previous state for pop_child_plan.
5071 push_child_plan(deparse_namespace
*dpns
, Plan
*plan
,
5072 deparse_namespace
*save_dpns
)
5074 /* Save state for restoration later */
5077 /* Link current plan node into ancestors list */
5078 dpns
->ancestors
= lcons(dpns
->plan
, dpns
->ancestors
);
5080 /* Set attention on selected child */
5081 set_deparse_plan(dpns
, plan
);
5085 * pop_child_plan: undo the effects of push_child_plan
5088 pop_child_plan(deparse_namespace
*dpns
, deparse_namespace
*save_dpns
)
5092 /* Get rid of ancestors list cell added by push_child_plan */
5093 ancestors
= list_delete_first(dpns
->ancestors
);
5095 /* Restore fields changed by push_child_plan */
5098 /* Make sure dpns->ancestors is right (may be unnecessary) */
5099 dpns
->ancestors
= ancestors
;
5103 * push_ancestor_plan: temporarily transfer deparsing attention to an
5106 * When expanding a Param reference, we must adjust the deparse context
5107 * to match the plan node that contains the expression being printed;
5108 * otherwise we'd fail if that expression itself contains a Param or
5109 * OUTER_VAR/INNER_VAR/INDEX_VAR variable.
5111 * The target ancestor is conveniently identified by the ListCell holding it
5112 * in dpns->ancestors.
5114 * Caller must provide a local deparse_namespace variable to save the
5115 * previous state for pop_ancestor_plan.
5118 push_ancestor_plan(deparse_namespace
*dpns
, ListCell
*ancestor_cell
,
5119 deparse_namespace
*save_dpns
)
5121 Plan
*plan
= (Plan
*) lfirst(ancestor_cell
);
5123 /* Save state for restoration later */
5126 /* Build a new ancestor list with just this node's ancestors */
5128 list_copy_tail(dpns
->ancestors
,
5129 list_cell_number(dpns
->ancestors
, ancestor_cell
) + 1);
5131 /* Set attention on selected ancestor */
5132 set_deparse_plan(dpns
, plan
);
5136 * pop_ancestor_plan: undo the effects of push_ancestor_plan
5139 pop_ancestor_plan(deparse_namespace
*dpns
, deparse_namespace
*save_dpns
)
5141 /* Free the ancestor list made in push_ancestor_plan */
5142 list_free(dpns
->ancestors
);
5144 /* Restore fields changed by push_ancestor_plan */
5150 * make_ruledef - reconstruct the CREATE RULE command
5151 * for a given pg_rewrite tuple
5155 make_ruledef(StringInfo buf
, HeapTuple ruletup
, TupleDesc rulettc
,
5165 Relation ev_relation
;
5166 TupleDesc viewResultDesc
= NULL
;
5172 * Get the attribute values from the rules tuple
5174 fno
= SPI_fnumber(rulettc
, "rulename");
5175 dat
= SPI_getbinval(ruletup
, rulettc
, fno
, &isnull
);
5177 rulename
= NameStr(*(DatumGetName(dat
)));
5179 fno
= SPI_fnumber(rulettc
, "ev_type");
5180 dat
= SPI_getbinval(ruletup
, rulettc
, fno
, &isnull
);
5182 ev_type
= DatumGetChar(dat
);
5184 fno
= SPI_fnumber(rulettc
, "ev_class");
5185 dat
= SPI_getbinval(ruletup
, rulettc
, fno
, &isnull
);
5187 ev_class
= DatumGetObjectId(dat
);
5189 fno
= SPI_fnumber(rulettc
, "is_instead");
5190 dat
= SPI_getbinval(ruletup
, rulettc
, fno
, &isnull
);
5192 is_instead
= DatumGetBool(dat
);
5194 fno
= SPI_fnumber(rulettc
, "ev_qual");
5195 ev_qual
= SPI_getvalue(ruletup
, rulettc
, fno
);
5196 Assert(ev_qual
!= NULL
);
5198 fno
= SPI_fnumber(rulettc
, "ev_action");
5199 ev_action
= SPI_getvalue(ruletup
, rulettc
, fno
);
5200 Assert(ev_action
!= NULL
);
5201 actions
= (List
*) stringToNode(ev_action
);
5203 elog(ERROR
, "invalid empty ev_action list");
5205 ev_relation
= table_open(ev_class
, AccessShareLock
);
5208 * Build the rules definition text
5210 appendStringInfo(buf
, "CREATE RULE %s AS",
5211 quote_identifier(rulename
));
5213 if (prettyFlags
& PRETTYFLAG_INDENT
)
5214 appendStringInfoString(buf
, "\n ON ");
5216 appendStringInfoString(buf
, " ON ");
5218 /* The event the rule is fired for */
5222 appendStringInfoString(buf
, "SELECT");
5223 viewResultDesc
= RelationGetDescr(ev_relation
);
5227 appendStringInfoString(buf
, "UPDATE");
5231 appendStringInfoString(buf
, "INSERT");
5235 appendStringInfoString(buf
, "DELETE");
5240 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED
),
5241 errmsg("rule \"%s\" has unsupported event type %d",
5242 rulename
, ev_type
)));
5246 /* The relation the rule is fired on */
5247 appendStringInfo(buf
, " TO %s",
5248 (prettyFlags
& PRETTYFLAG_SCHEMA
) ?
5249 generate_relation_name(ev_class
, NIL
) :
5250 generate_qualified_relation_name(ev_class
));
5252 /* If the rule has an event qualification, add it */
5253 if (strcmp(ev_qual
, "<>") != 0)
5257 deparse_context context
;
5258 deparse_namespace dpns
;
5260 if (prettyFlags
& PRETTYFLAG_INDENT
)
5261 appendStringInfoString(buf
, "\n ");
5262 appendStringInfoString(buf
, " WHERE ");
5264 qual
= stringToNode(ev_qual
);
5267 * We need to make a context for recognizing any Vars in the qual
5268 * (which can only be references to OLD and NEW). Use the rtable of
5269 * the first query in the action list for this purpose.
5271 query
= (Query
*) linitial(actions
);
5274 * If the action is INSERT...SELECT, OLD/NEW have been pushed down
5275 * into the SELECT, and that's what we need to look at. (Ugly kluge
5276 * ... try to fix this when we redesign querytrees.)
5278 query
= getInsertSelectQuery(query
, NULL
);
5280 /* Must acquire locks right away; see notes in get_query_def() */
5281 AcquireRewriteLocks(query
, false, false);
5284 context
.namespaces
= list_make1(&dpns
);
5285 context
.resultDesc
= NULL
;
5286 context
.targetList
= NIL
;
5287 context
.windowClause
= NIL
;
5288 context
.varprefix
= (list_length(query
->rtable
) != 1);
5289 context
.prettyFlags
= prettyFlags
;
5290 context
.wrapColumn
= WRAP_COLUMN_DEFAULT
;
5291 context
.indentLevel
= PRETTYINDENT_STD
;
5292 context
.colNamesVisible
= true;
5293 context
.inGroupBy
= false;
5294 context
.varInOrderBy
= false;
5295 context
.appendparents
= NULL
;
5297 set_deparse_for_query(&dpns
, query
, NIL
);
5299 get_rule_expr(qual
, &context
, false);
5302 appendStringInfoString(buf
, " DO ");
5304 /* The INSTEAD keyword (if so) */
5306 appendStringInfoString(buf
, "INSTEAD ");
5308 /* Finally the rules actions */
5309 if (list_length(actions
) > 1)
5314 appendStringInfoChar(buf
, '(');
5315 foreach(action
, actions
)
5317 query
= (Query
*) lfirst(action
);
5318 get_query_def(query
, buf
, NIL
, viewResultDesc
, true,
5319 prettyFlags
, WRAP_COLUMN_DEFAULT
, 0);
5321 appendStringInfoString(buf
, ";\n");
5323 appendStringInfoString(buf
, "; ");
5325 appendStringInfoString(buf
, ");");
5331 query
= (Query
*) linitial(actions
);
5332 get_query_def(query
, buf
, NIL
, viewResultDesc
, true,
5333 prettyFlags
, WRAP_COLUMN_DEFAULT
, 0);
5334 appendStringInfoChar(buf
, ';');
5337 table_close(ev_relation
, AccessShareLock
);
5342 * make_viewdef - reconstruct the SELECT part of a
5347 make_viewdef(StringInfo buf
, HeapTuple ruletup
, TupleDesc rulettc
,
5348 int prettyFlags
, int wrapColumn
)
5357 Relation ev_relation
;
5363 * Get the attribute values from the rules tuple
5365 fno
= SPI_fnumber(rulettc
, "ev_type");
5366 dat
= SPI_getbinval(ruletup
, rulettc
, fno
, &isnull
);
5368 ev_type
= DatumGetChar(dat
);
5370 fno
= SPI_fnumber(rulettc
, "ev_class");
5371 dat
= SPI_getbinval(ruletup
, rulettc
, fno
, &isnull
);
5373 ev_class
= DatumGetObjectId(dat
);
5375 fno
= SPI_fnumber(rulettc
, "is_instead");
5376 dat
= SPI_getbinval(ruletup
, rulettc
, fno
, &isnull
);
5378 is_instead
= DatumGetBool(dat
);
5380 fno
= SPI_fnumber(rulettc
, "ev_qual");
5381 ev_qual
= SPI_getvalue(ruletup
, rulettc
, fno
);
5382 Assert(ev_qual
!= NULL
);
5384 fno
= SPI_fnumber(rulettc
, "ev_action");
5385 ev_action
= SPI_getvalue(ruletup
, rulettc
, fno
);
5386 Assert(ev_action
!= NULL
);
5387 actions
= (List
*) stringToNode(ev_action
);
5389 if (list_length(actions
) != 1)
5391 /* keep output buffer empty and leave */
5395 query
= (Query
*) linitial(actions
);
5397 if (ev_type
!= '1' || !is_instead
||
5398 strcmp(ev_qual
, "<>") != 0 || query
->commandType
!= CMD_SELECT
)
5400 /* keep output buffer empty and leave */
5404 ev_relation
= table_open(ev_class
, AccessShareLock
);
5406 get_query_def(query
, buf
, NIL
, RelationGetDescr(ev_relation
), true,
5407 prettyFlags
, wrapColumn
, 0);
5408 appendStringInfoChar(buf
, ';');
5410 table_close(ev_relation
, AccessShareLock
);
5415 * get_query_def - Parse back one query parsetree
5417 * query: parsetree to be displayed
5418 * buf: output text is appended to buf
5419 * parentnamespace: list (initially empty) of outer-level deparse_namespace's
5420 * resultDesc: if not NULL, the output tuple descriptor for the view
5421 * represented by a SELECT query. We use the column names from it
5422 * to label SELECT output columns, in preference to names in the query
5423 * colNamesVisible: true if the surrounding context cares about the output
5424 * column names at all (as, for example, an EXISTS() context does not);
5425 * when false, we can suppress dummy column labels such as "?column?"
5426 * prettyFlags: bitmask of PRETTYFLAG_XXX options
5427 * wrapColumn: maximum line length, or -1 to disable wrapping
5428 * startIndent: initial indentation amount
5432 get_query_def(Query
*query
, StringInfo buf
, List
*parentnamespace
,
5433 TupleDesc resultDesc
, bool colNamesVisible
,
5434 int prettyFlags
, int wrapColumn
, int startIndent
)
5436 deparse_context context
;
5437 deparse_namespace dpns
;
5439 /* Guard against excessively long or deeply-nested queries */
5440 CHECK_FOR_INTERRUPTS();
5441 check_stack_depth();
5444 * Before we begin to examine the query, acquire locks on referenced
5445 * relations, and fix up deleted columns in JOIN RTEs. This ensures
5446 * consistent results. Note we assume it's OK to scribble on the passed
5449 * We are only deparsing the query (we are not about to execute it), so we
5450 * only need AccessShareLock on the relations it mentions.
5452 AcquireRewriteLocks(query
, false, false);
5455 context
.namespaces
= lcons(&dpns
, list_copy(parentnamespace
));
5456 context
.resultDesc
= NULL
;
5457 context
.targetList
= NIL
;
5458 context
.windowClause
= NIL
;
5459 context
.varprefix
= (parentnamespace
!= NIL
||
5460 list_length(query
->rtable
) != 1);
5461 context
.prettyFlags
= prettyFlags
;
5462 context
.wrapColumn
= wrapColumn
;
5463 context
.indentLevel
= startIndent
;
5464 context
.colNamesVisible
= colNamesVisible
;
5465 context
.inGroupBy
= false;
5466 context
.varInOrderBy
= false;
5467 context
.appendparents
= NULL
;
5469 set_deparse_for_query(&dpns
, query
, parentnamespace
);
5471 switch (query
->commandType
)
5474 /* We set context.resultDesc only if it's a SELECT */
5475 context
.resultDesc
= resultDesc
;
5476 get_select_query_def(query
, &context
);
5480 get_update_query_def(query
, &context
);
5484 get_insert_query_def(query
, &context
);
5488 get_delete_query_def(query
, &context
);
5492 get_merge_query_def(query
, &context
);
5496 appendStringInfoString(buf
, "NOTHING");
5500 get_utility_query_def(query
, &context
);
5504 elog(ERROR
, "unrecognized query command type: %d",
5505 query
->commandType
);
5511 * get_values_def - Parse back a VALUES list
5515 get_values_def(List
*values_lists
, deparse_context
*context
)
5517 StringInfo buf
= context
->buf
;
5518 bool first_list
= true;
5521 appendStringInfoString(buf
, "VALUES ");
5523 foreach(vtl
, values_lists
)
5525 List
*sublist
= (List
*) lfirst(vtl
);
5526 bool first_col
= true;
5532 appendStringInfoString(buf
, ", ");
5534 appendStringInfoChar(buf
, '(');
5535 foreach(lc
, sublist
)
5537 Node
*col
= (Node
*) lfirst(lc
);
5542 appendStringInfoChar(buf
, ',');
5545 * Print the value. Whole-row Vars need special treatment.
5547 get_rule_expr_toplevel(col
, context
, false);
5549 appendStringInfoChar(buf
, ')');
5554 * get_with_clause - Parse back a WITH clause
5558 get_with_clause(Query
*query
, deparse_context
*context
)
5560 StringInfo buf
= context
->buf
;
5564 if (query
->cteList
== NIL
)
5567 if (PRETTY_INDENT(context
))
5569 context
->indentLevel
+= PRETTYINDENT_STD
;
5570 appendStringInfoChar(buf
, ' ');
5573 if (query
->hasRecursive
)
5574 sep
= "WITH RECURSIVE ";
5577 foreach(l
, query
->cteList
)
5579 CommonTableExpr
*cte
= (CommonTableExpr
*) lfirst(l
);
5581 appendStringInfoString(buf
, sep
);
5582 appendStringInfoString(buf
, quote_identifier(cte
->ctename
));
5583 if (cte
->aliascolnames
)
5588 appendStringInfoChar(buf
, '(');
5589 foreach(col
, cte
->aliascolnames
)
5594 appendStringInfoString(buf
, ", ");
5595 appendStringInfoString(buf
,
5596 quote_identifier(strVal(lfirst(col
))));
5598 appendStringInfoChar(buf
, ')');
5600 appendStringInfoString(buf
, " AS ");
5601 switch (cte
->ctematerialized
)
5603 case CTEMaterializeDefault
:
5605 case CTEMaterializeAlways
:
5606 appendStringInfoString(buf
, "MATERIALIZED ");
5608 case CTEMaterializeNever
:
5609 appendStringInfoString(buf
, "NOT MATERIALIZED ");
5612 appendStringInfoChar(buf
, '(');
5613 if (PRETTY_INDENT(context
))
5614 appendContextKeyword(context
, "", 0, 0, 0);
5615 get_query_def((Query
*) cte
->ctequery
, buf
, context
->namespaces
, NULL
,
5617 context
->prettyFlags
, context
->wrapColumn
,
5618 context
->indentLevel
);
5619 if (PRETTY_INDENT(context
))
5620 appendContextKeyword(context
, "", 0, 0, 0);
5621 appendStringInfoChar(buf
, ')');
5623 if (cte
->search_clause
)
5628 appendStringInfo(buf
, " SEARCH %s FIRST BY ",
5629 cte
->search_clause
->search_breadth_first
? "BREADTH" : "DEPTH");
5631 foreach(lc
, cte
->search_clause
->search_col_list
)
5636 appendStringInfoString(buf
, ", ");
5637 appendStringInfoString(buf
,
5638 quote_identifier(strVal(lfirst(lc
))));
5641 appendStringInfo(buf
, " SET %s", quote_identifier(cte
->search_clause
->search_seq_column
));
5644 if (cte
->cycle_clause
)
5649 appendStringInfoString(buf
, " CYCLE ");
5651 foreach(lc
, cte
->cycle_clause
->cycle_col_list
)
5656 appendStringInfoString(buf
, ", ");
5657 appendStringInfoString(buf
,
5658 quote_identifier(strVal(lfirst(lc
))));
5661 appendStringInfo(buf
, " SET %s", quote_identifier(cte
->cycle_clause
->cycle_mark_column
));
5664 Const
*cmv
= castNode(Const
, cte
->cycle_clause
->cycle_mark_value
);
5665 Const
*cmd
= castNode(Const
, cte
->cycle_clause
->cycle_mark_default
);
5667 if (!(cmv
->consttype
== BOOLOID
&& !cmv
->constisnull
&& DatumGetBool(cmv
->constvalue
) == true &&
5668 cmd
->consttype
== BOOLOID
&& !cmd
->constisnull
&& DatumGetBool(cmd
->constvalue
) == false))
5670 appendStringInfoString(buf
, " TO ");
5671 get_rule_expr(cte
->cycle_clause
->cycle_mark_value
, context
, false);
5672 appendStringInfoString(buf
, " DEFAULT ");
5673 get_rule_expr(cte
->cycle_clause
->cycle_mark_default
, context
, false);
5677 appendStringInfo(buf
, " USING %s", quote_identifier(cte
->cycle_clause
->cycle_path_column
));
5683 if (PRETTY_INDENT(context
))
5685 context
->indentLevel
-= PRETTYINDENT_STD
;
5686 appendContextKeyword(context
, "", 0, 0, 0);
5689 appendStringInfoChar(buf
, ' ');
5693 * get_select_query_def - Parse back a SELECT parsetree
5697 get_select_query_def(Query
*query
, deparse_context
*context
)
5699 StringInfo buf
= context
->buf
;
5703 /* Insert the WITH clause if given */
5704 get_with_clause(query
, context
);
5706 /* Subroutines may need to consult the SELECT targetlist and windowClause */
5707 context
->targetList
= query
->targetList
;
5708 context
->windowClause
= query
->windowClause
;
5711 * If the Query node has a setOperations tree, then it's the top level of
5712 * a UNION/INTERSECT/EXCEPT query; only the WITH, ORDER BY and LIMIT
5713 * fields are interesting in the top query itself.
5715 if (query
->setOperations
)
5717 get_setop_query(query
->setOperations
, query
, context
);
5718 /* ORDER BY clauses must be simple in this case */
5723 get_basic_select_query(query
, context
);
5724 force_colno
= false;
5727 /* Add the ORDER BY clause if given */
5728 if (query
->sortClause
!= NIL
)
5730 appendContextKeyword(context
, " ORDER BY ",
5731 -PRETTYINDENT_STD
, PRETTYINDENT_STD
, 1);
5732 get_rule_orderby(query
->sortClause
, query
->targetList
,
5733 force_colno
, context
);
5737 * Add the LIMIT/OFFSET clauses if given. If non-default options, use the
5738 * standard spelling of LIMIT.
5740 if (query
->limitOffset
!= NULL
)
5742 appendContextKeyword(context
, " OFFSET ",
5743 -PRETTYINDENT_STD
, PRETTYINDENT_STD
, 0);
5744 get_rule_expr(query
->limitOffset
, context
, false);
5746 if (query
->limitCount
!= NULL
)
5748 if (query
->limitOption
== LIMIT_OPTION_WITH_TIES
)
5750 appendContextKeyword(context
, " FETCH FIRST ",
5751 -PRETTYINDENT_STD
, PRETTYINDENT_STD
, 0);
5752 get_rule_expr(query
->limitCount
, context
, false);
5753 appendStringInfoString(buf
, " ROWS WITH TIES");
5757 appendContextKeyword(context
, " LIMIT ",
5758 -PRETTYINDENT_STD
, PRETTYINDENT_STD
, 0);
5759 if (IsA(query
->limitCount
, Const
) &&
5760 ((Const
*) query
->limitCount
)->constisnull
)
5761 appendStringInfoString(buf
, "ALL");
5763 get_rule_expr(query
->limitCount
, context
, false);
5767 /* Add FOR [KEY] UPDATE/SHARE clauses if present */
5768 if (query
->hasForUpdate
)
5770 foreach(l
, query
->rowMarks
)
5772 RowMarkClause
*rc
= (RowMarkClause
*) lfirst(l
);
5774 /* don't print implicit clauses */
5778 switch (rc
->strength
)
5781 /* we intentionally throw an error for LCS_NONE */
5782 elog(ERROR
, "unrecognized LockClauseStrength %d",
5783 (int) rc
->strength
);
5785 case LCS_FORKEYSHARE
:
5786 appendContextKeyword(context
, " FOR KEY SHARE",
5787 -PRETTYINDENT_STD
, PRETTYINDENT_STD
, 0);
5790 appendContextKeyword(context
, " FOR SHARE",
5791 -PRETTYINDENT_STD
, PRETTYINDENT_STD
, 0);
5793 case LCS_FORNOKEYUPDATE
:
5794 appendContextKeyword(context
, " FOR NO KEY UPDATE",
5795 -PRETTYINDENT_STD
, PRETTYINDENT_STD
, 0);
5798 appendContextKeyword(context
, " FOR UPDATE",
5799 -PRETTYINDENT_STD
, PRETTYINDENT_STD
, 0);
5803 appendStringInfo(buf
, " OF %s",
5804 quote_identifier(get_rtable_name(rc
->rti
,
5806 if (rc
->waitPolicy
== LockWaitError
)
5807 appendStringInfoString(buf
, " NOWAIT");
5808 else if (rc
->waitPolicy
== LockWaitSkip
)
5809 appendStringInfoString(buf
, " SKIP LOCKED");
5815 * Detect whether query looks like SELECT ... FROM VALUES(),
5816 * with no need to rename the output columns of the VALUES RTE.
5817 * If so, return the VALUES RTE. Otherwise return NULL.
5819 static RangeTblEntry
*
5820 get_simple_values_rte(Query
*query
, TupleDesc resultDesc
)
5822 RangeTblEntry
*result
= NULL
;
5826 * We want to detect a match even if the Query also contains OLD or NEW
5827 * rule RTEs. So the idea is to scan the rtable and see if there is only
5828 * one inFromCl RTE that is a VALUES RTE.
5830 foreach(lc
, query
->rtable
)
5832 RangeTblEntry
*rte
= (RangeTblEntry
*) lfirst(lc
);
5834 if (rte
->rtekind
== RTE_VALUES
&& rte
->inFromCl
)
5837 return NULL
; /* multiple VALUES (probably not possible) */
5840 else if (rte
->rtekind
== RTE_RELATION
&& !rte
->inFromCl
)
5841 continue; /* ignore rule entries */
5843 return NULL
; /* something else -> not simple VALUES */
5847 * We don't need to check the targetlist in any great detail, because
5848 * parser/analyze.c will never generate a "bare" VALUES RTE --- they only
5849 * appear inside auto-generated sub-queries with very restricted
5850 * structure. However, DefineView might have modified the tlist by
5851 * injecting new column aliases, or we might have some other column
5852 * aliases forced by a resultDesc. We can only simplify if the RTE's
5853 * column names match the names that get_target_list() would select.
5860 if (list_length(query
->targetList
) != list_length(result
->eref
->colnames
))
5861 return NULL
; /* this probably cannot happen */
5863 forboth(lc
, query
->targetList
, lcn
, result
->eref
->colnames
)
5865 TargetEntry
*tle
= (TargetEntry
*) lfirst(lc
);
5866 char *cname
= strVal(lfirst(lcn
));
5870 return NULL
; /* this probably cannot happen */
5872 /* compute name that get_target_list would use for column */
5874 if (resultDesc
&& colno
<= resultDesc
->natts
)
5875 colname
= NameStr(TupleDescAttr(resultDesc
, colno
- 1)->attname
);
5877 colname
= tle
->resname
;
5879 /* does it match the VALUES RTE? */
5880 if (colname
== NULL
|| strcmp(colname
, cname
) != 0)
5881 return NULL
; /* column name has been changed */
5889 get_basic_select_query(Query
*query
, deparse_context
*context
)
5891 StringInfo buf
= context
->buf
;
5892 RangeTblEntry
*values_rte
;
5896 if (PRETTY_INDENT(context
))
5898 context
->indentLevel
+= PRETTYINDENT_STD
;
5899 appendStringInfoChar(buf
, ' ');
5903 * If the query looks like SELECT * FROM (VALUES ...), then print just the
5904 * VALUES part. This reverses what transformValuesClause() did at parse
5907 values_rte
= get_simple_values_rte(query
, context
->resultDesc
);
5910 get_values_def(values_rte
->values_lists
, context
);
5915 * Build up the query string - first we say SELECT
5917 if (query
->isReturn
)
5918 appendStringInfoString(buf
, "RETURN");
5920 appendStringInfoString(buf
, "SELECT");
5922 /* Add the DISTINCT clause if given */
5923 if (query
->distinctClause
!= NIL
)
5925 if (query
->hasDistinctOn
)
5927 appendStringInfoString(buf
, " DISTINCT ON (");
5929 foreach(l
, query
->distinctClause
)
5931 SortGroupClause
*srt
= (SortGroupClause
*) lfirst(l
);
5933 appendStringInfoString(buf
, sep
);
5934 get_rule_sortgroupclause(srt
->tleSortGroupRef
, query
->targetList
,
5938 appendStringInfoChar(buf
, ')');
5941 appendStringInfoString(buf
, " DISTINCT");
5944 /* Then we tell what to select (the targetlist) */
5945 get_target_list(query
->targetList
, context
);
5947 /* Add the FROM clause if needed */
5948 get_from_clause(query
, " FROM ", context
);
5950 /* Add the WHERE clause if given */
5951 if (query
->jointree
->quals
!= NULL
)
5953 appendContextKeyword(context
, " WHERE ",
5954 -PRETTYINDENT_STD
, PRETTYINDENT_STD
, 1);
5955 get_rule_expr(query
->jointree
->quals
, context
, false);
5958 /* Add the GROUP BY clause if given */
5959 if (query
->groupClause
!= NULL
|| query
->groupingSets
!= NULL
)
5961 bool save_ingroupby
;
5963 appendContextKeyword(context
, " GROUP BY ",
5964 -PRETTYINDENT_STD
, PRETTYINDENT_STD
, 1);
5965 if (query
->groupDistinct
)
5966 appendStringInfoString(buf
, "DISTINCT ");
5968 save_ingroupby
= context
->inGroupBy
;
5969 context
->inGroupBy
= true;
5971 if (query
->groupingSets
== NIL
)
5974 foreach(l
, query
->groupClause
)
5976 SortGroupClause
*grp
= (SortGroupClause
*) lfirst(l
);
5978 appendStringInfoString(buf
, sep
);
5979 get_rule_sortgroupclause(grp
->tleSortGroupRef
, query
->targetList
,
5987 foreach(l
, query
->groupingSets
)
5989 GroupingSet
*grp
= lfirst(l
);
5991 appendStringInfoString(buf
, sep
);
5992 get_rule_groupingset(grp
, query
->targetList
, true, context
);
5997 context
->inGroupBy
= save_ingroupby
;
6000 /* Add the HAVING clause if given */
6001 if (query
->havingQual
!= NULL
)
6003 appendContextKeyword(context
, " HAVING ",
6004 -PRETTYINDENT_STD
, PRETTYINDENT_STD
, 0);
6005 get_rule_expr(query
->havingQual
, context
, false);
6008 /* Add the WINDOW clause if needed */
6009 if (query
->windowClause
!= NIL
)
6010 get_rule_windowclause(query
, context
);
6014 * get_target_list - Parse back a SELECT target list
6016 * This is also used for RETURNING lists in INSERT/UPDATE/DELETE/MERGE.
6020 get_target_list(List
*targetList
, deparse_context
*context
)
6022 StringInfo buf
= context
->buf
;
6023 StringInfoData targetbuf
;
6024 bool last_was_multiline
= false;
6029 /* we use targetbuf to hold each TLE's text temporarily */
6030 initStringInfo(&targetbuf
);
6034 foreach(l
, targetList
)
6036 TargetEntry
*tle
= (TargetEntry
*) lfirst(l
);
6041 continue; /* ignore junk entries */
6043 appendStringInfoString(buf
, sep
);
6048 * Put the new field text into targetbuf so we can decide after we've
6049 * got it whether or not it needs to go on a new line.
6051 resetStringInfo(&targetbuf
);
6052 context
->buf
= &targetbuf
;
6055 * We special-case Var nodes rather than using get_rule_expr. This is
6056 * needed because get_rule_expr will display a whole-row Var as
6057 * "foo.*", which is the preferred notation in most contexts, but at
6058 * the top level of a SELECT list it's not right (the parser will
6059 * expand that notation into multiple columns, yielding behavior
6060 * different from a whole-row Var). We need to call get_variable
6061 * directly so that we can tell it to do the right thing, and so that
6062 * we can get the attribute name which is the default AS label.
6064 if (tle
->expr
&& (IsA(tle
->expr
, Var
)))
6066 attname
= get_variable((Var
*) tle
->expr
, 0, true, context
);
6070 get_rule_expr((Node
*) tle
->expr
, context
, true);
6073 * When colNamesVisible is true, we should always show the
6074 * assigned column name explicitly. Otherwise, show it only if
6075 * it's not FigureColname's fallback.
6077 attname
= context
->colNamesVisible
? NULL
: "?column?";
6081 * Figure out what the result column should be called. In the context
6082 * of a view, use the view's tuple descriptor (so as to pick up the
6083 * effects of any column RENAME that's been done on the view).
6084 * Otherwise, just use what we can find in the TLE.
6086 if (context
->resultDesc
&& colno
<= context
->resultDesc
->natts
)
6087 colname
= NameStr(TupleDescAttr(context
->resultDesc
,
6088 colno
- 1)->attname
);
6090 colname
= tle
->resname
;
6092 /* Show AS unless the column's name is correct as-is */
6093 if (colname
) /* resname could be NULL */
6095 if (attname
== NULL
|| strcmp(attname
, colname
) != 0)
6096 appendStringInfo(&targetbuf
, " AS %s", quote_identifier(colname
));
6099 /* Restore context's output buffer */
6102 /* Consider line-wrapping if enabled */
6103 if (PRETTY_INDENT(context
) && context
->wrapColumn
>= 0)
6107 /* Does the new field start with a new line? */
6108 if (targetbuf
.len
> 0 && targetbuf
.data
[0] == '\n')
6111 leading_nl_pos
= -1;
6113 /* If so, we shouldn't add anything */
6114 if (leading_nl_pos
>= 0)
6116 /* instead, remove any trailing spaces currently in buf */
6117 removeStringInfoSpaces(buf
);
6123 /* Locate the start of the current line in the output buffer */
6124 trailing_nl
= strrchr(buf
->data
, '\n');
6125 if (trailing_nl
== NULL
)
6126 trailing_nl
= buf
->data
;
6131 * Add a newline, plus some indentation, if the new field is
6132 * not the first and either the new field would cause an
6133 * overflow or the last field used more than one line.
6136 ((strlen(trailing_nl
) + targetbuf
.len
> context
->wrapColumn
) ||
6137 last_was_multiline
))
6138 appendContextKeyword(context
, "", -PRETTYINDENT_STD
,
6139 PRETTYINDENT_STD
, PRETTYINDENT_VAR
);
6142 /* Remember this field's multiline status for next iteration */
6143 last_was_multiline
=
6144 (strchr(targetbuf
.data
+ leading_nl_pos
+ 1, '\n') != NULL
);
6147 /* Add the new field */
6148 appendBinaryStringInfo(buf
, targetbuf
.data
, targetbuf
.len
);
6152 pfree(targetbuf
.data
);
6156 get_setop_query(Node
*setOp
, Query
*query
, deparse_context
*context
)
6158 StringInfo buf
= context
->buf
;
6161 /* Guard against excessively long or deeply-nested queries */
6162 CHECK_FOR_INTERRUPTS();
6163 check_stack_depth();
6165 if (IsA(setOp
, RangeTblRef
))
6167 RangeTblRef
*rtr
= (RangeTblRef
*) setOp
;
6168 RangeTblEntry
*rte
= rt_fetch(rtr
->rtindex
, query
->rtable
);
6169 Query
*subquery
= rte
->subquery
;
6171 Assert(subquery
!= NULL
);
6172 Assert(subquery
->setOperations
== NULL
);
6173 /* Need parens if WITH, ORDER BY, FOR UPDATE, or LIMIT; see gram.y */
6174 need_paren
= (subquery
->cteList
||
6175 subquery
->sortClause
||
6176 subquery
->rowMarks
||
6177 subquery
->limitOffset
||
6178 subquery
->limitCount
);
6180 appendStringInfoChar(buf
, '(');
6181 get_query_def(subquery
, buf
, context
->namespaces
,
6182 context
->resultDesc
, context
->colNamesVisible
,
6183 context
->prettyFlags
, context
->wrapColumn
,
6184 context
->indentLevel
);
6186 appendStringInfoChar(buf
, ')');
6188 else if (IsA(setOp
, SetOperationStmt
))
6190 SetOperationStmt
*op
= (SetOperationStmt
*) setOp
;
6192 bool save_colnamesvisible
;
6195 * We force parens when nesting two SetOperationStmts, except when the
6196 * lefthand input is another setop of the same kind. Syntactically,
6197 * we could omit parens in rather more cases, but it seems best to use
6198 * parens to flag cases where the setop operator changes. If we use
6199 * parens, we also increase the indentation level for the child query.
6201 * There are some cases in which parens are needed around a leaf query
6202 * too, but those are more easily handled at the next level down (see
6205 if (IsA(op
->larg
, SetOperationStmt
))
6207 SetOperationStmt
*lop
= (SetOperationStmt
*) op
->larg
;
6209 if (op
->op
== lop
->op
&& op
->all
== lop
->all
)
6219 appendStringInfoChar(buf
, '(');
6220 subindent
= PRETTYINDENT_STD
;
6221 appendContextKeyword(context
, "", subindent
, 0, 0);
6226 get_setop_query(op
->larg
, query
, context
);
6229 appendContextKeyword(context
, ") ", -subindent
, 0, 0);
6230 else if (PRETTY_INDENT(context
))
6231 appendContextKeyword(context
, "", -subindent
, 0, 0);
6233 appendStringInfoChar(buf
, ' ');
6238 appendStringInfoString(buf
, "UNION ");
6240 case SETOP_INTERSECT
:
6241 appendStringInfoString(buf
, "INTERSECT ");
6244 appendStringInfoString(buf
, "EXCEPT ");
6247 elog(ERROR
, "unrecognized set op: %d",
6251 appendStringInfoString(buf
, "ALL ");
6253 /* Always parenthesize if RHS is another setop */
6254 need_paren
= IsA(op
->rarg
, SetOperationStmt
);
6257 * The indentation code here is deliberately a bit different from that
6258 * for the lefthand input, because we want the line breaks in
6263 appendStringInfoChar(buf
, '(');
6264 subindent
= PRETTYINDENT_STD
;
6268 appendContextKeyword(context
, "", subindent
, 0, 0);
6271 * The output column names of the RHS sub-select don't matter.
6273 save_colnamesvisible
= context
->colNamesVisible
;
6274 context
->colNamesVisible
= false;
6276 get_setop_query(op
->rarg
, query
, context
);
6278 context
->colNamesVisible
= save_colnamesvisible
;
6280 if (PRETTY_INDENT(context
))
6281 context
->indentLevel
-= subindent
;
6283 appendContextKeyword(context
, ")", 0, 0, 0);
6287 elog(ERROR
, "unrecognized node type: %d",
6288 (int) nodeTag(setOp
));
6293 * Display a sort/group clause.
6295 * Also returns the expression tree, so caller need not find it again.
6298 get_rule_sortgroupclause(Index ref
, List
*tlist
, bool force_colno
,
6299 deparse_context
*context
)
6301 StringInfo buf
= context
->buf
;
6305 tle
= get_sortgroupref_tle(ref
, tlist
);
6306 expr
= (Node
*) tle
->expr
;
6309 * Use column-number form if requested by caller. Otherwise, if
6310 * expression is a constant, force it to be dumped with an explicit cast
6311 * as decoration --- this is because a simple integer constant is
6312 * ambiguous (and will be misinterpreted by findTargetlistEntrySQL92()) if
6313 * we dump it without any decoration. Similarly, if it's just a Var,
6314 * there is risk of misinterpretation if the column name is reassigned in
6315 * the SELECT list, so we may need to force table qualification. And, if
6316 * it's anything more complex than a simple Var, then force extra parens
6317 * around it, to ensure it can't be misinterpreted as a cube() or rollup()
6322 Assert(!tle
->resjunk
);
6323 appendStringInfo(buf
, "%d", tle
->resno
);
6326 /* do nothing, probably can't happen */ ;
6327 else if (IsA(expr
, Const
))
6328 get_const_expr((Const
*) expr
, context
, 1);
6329 else if (IsA(expr
, Var
))
6331 /* Tell get_variable to check for name conflict */
6332 bool save_varinorderby
= context
->varInOrderBy
;
6334 context
->varInOrderBy
= true;
6335 (void) get_variable((Var
*) expr
, 0, false, context
);
6336 context
->varInOrderBy
= save_varinorderby
;
6341 * We must force parens for function-like expressions even if
6342 * PRETTY_PAREN is off, since those are the ones in danger of
6343 * misparsing. For other expressions we need to force them only if
6344 * PRETTY_PAREN is on, since otherwise the expression will output them
6345 * itself. (We can't skip the parens.)
6347 bool need_paren
= (PRETTY_PAREN(context
)
6348 || IsA(expr
, FuncExpr
)
6349 || IsA(expr
, Aggref
)
6350 || IsA(expr
, WindowFunc
)
6351 || IsA(expr
, JsonConstructorExpr
));
6354 appendStringInfoChar(context
->buf
, '(');
6355 get_rule_expr(expr
, context
, true);
6357 appendStringInfoChar(context
->buf
, ')');
6364 * Display a GroupingSet
6367 get_rule_groupingset(GroupingSet
*gset
, List
*targetlist
,
6368 bool omit_parens
, deparse_context
*context
)
6371 StringInfo buf
= context
->buf
;
6372 bool omit_child_parens
= true;
6377 case GROUPING_SET_EMPTY
:
6378 appendStringInfoString(buf
, "()");
6381 case GROUPING_SET_SIMPLE
:
6383 if (!omit_parens
|| list_length(gset
->content
) != 1)
6384 appendStringInfoChar(buf
, '(');
6386 foreach(l
, gset
->content
)
6388 Index ref
= lfirst_int(l
);
6390 appendStringInfoString(buf
, sep
);
6391 get_rule_sortgroupclause(ref
, targetlist
,
6396 if (!omit_parens
|| list_length(gset
->content
) != 1)
6397 appendStringInfoChar(buf
, ')');
6401 case GROUPING_SET_ROLLUP
:
6402 appendStringInfoString(buf
, "ROLLUP(");
6404 case GROUPING_SET_CUBE
:
6405 appendStringInfoString(buf
, "CUBE(");
6407 case GROUPING_SET_SETS
:
6408 appendStringInfoString(buf
, "GROUPING SETS (");
6409 omit_child_parens
= false;
6413 foreach(l
, gset
->content
)
6415 appendStringInfoString(buf
, sep
);
6416 get_rule_groupingset(lfirst(l
), targetlist
, omit_child_parens
, context
);
6420 appendStringInfoChar(buf
, ')');
6424 * Display an ORDER BY list.
6427 get_rule_orderby(List
*orderList
, List
*targetList
,
6428 bool force_colno
, deparse_context
*context
)
6430 StringInfo buf
= context
->buf
;
6435 foreach(l
, orderList
)
6437 SortGroupClause
*srt
= (SortGroupClause
*) lfirst(l
);
6440 TypeCacheEntry
*typentry
;
6442 appendStringInfoString(buf
, sep
);
6443 sortexpr
= get_rule_sortgroupclause(srt
->tleSortGroupRef
, targetList
,
6444 force_colno
, context
);
6445 sortcoltype
= exprType(sortexpr
);
6446 /* See whether operator is default < or > for datatype */
6447 typentry
= lookup_type_cache(sortcoltype
,
6448 TYPECACHE_LT_OPR
| TYPECACHE_GT_OPR
);
6449 if (srt
->sortop
== typentry
->lt_opr
)
6451 /* ASC is default, so emit nothing for it */
6452 if (srt
->nulls_first
)
6453 appendStringInfoString(buf
, " NULLS FIRST");
6455 else if (srt
->sortop
== typentry
->gt_opr
)
6457 appendStringInfoString(buf
, " DESC");
6458 /* DESC defaults to NULLS FIRST */
6459 if (!srt
->nulls_first
)
6460 appendStringInfoString(buf
, " NULLS LAST");
6464 appendStringInfo(buf
, " USING %s",
6465 generate_operator_name(srt
->sortop
,
6468 /* be specific to eliminate ambiguity */
6469 if (srt
->nulls_first
)
6470 appendStringInfoString(buf
, " NULLS FIRST");
6472 appendStringInfoString(buf
, " NULLS LAST");
6479 * Display a WINDOW clause.
6481 * Note that the windowClause list might contain only anonymous window
6482 * specifications, in which case we should print nothing here.
6485 get_rule_windowclause(Query
*query
, deparse_context
*context
)
6487 StringInfo buf
= context
->buf
;
6492 foreach(l
, query
->windowClause
)
6494 WindowClause
*wc
= (WindowClause
*) lfirst(l
);
6496 if (wc
->name
== NULL
)
6497 continue; /* ignore anonymous windows */
6500 appendContextKeyword(context
, " WINDOW ",
6501 -PRETTYINDENT_STD
, PRETTYINDENT_STD
, 1);
6503 appendStringInfoString(buf
, sep
);
6505 appendStringInfo(buf
, "%s AS ", quote_identifier(wc
->name
));
6507 get_rule_windowspec(wc
, query
->targetList
, context
);
6514 * Display a window definition
6517 get_rule_windowspec(WindowClause
*wc
, List
*targetList
,
6518 deparse_context
*context
)
6520 StringInfo buf
= context
->buf
;
6521 bool needspace
= false;
6525 appendStringInfoChar(buf
, '(');
6528 appendStringInfoString(buf
, quote_identifier(wc
->refname
));
6531 /* partition clauses are always inherited, so only print if no refname */
6532 if (wc
->partitionClause
&& !wc
->refname
)
6535 appendStringInfoChar(buf
, ' ');
6536 appendStringInfoString(buf
, "PARTITION BY ");
6538 foreach(l
, wc
->partitionClause
)
6540 SortGroupClause
*grp
= (SortGroupClause
*) lfirst(l
);
6542 appendStringInfoString(buf
, sep
);
6543 get_rule_sortgroupclause(grp
->tleSortGroupRef
, targetList
,
6549 /* print ordering clause only if not inherited */
6550 if (wc
->orderClause
&& !wc
->copiedOrder
)
6553 appendStringInfoChar(buf
, ' ');
6554 appendStringInfoString(buf
, "ORDER BY ");
6555 get_rule_orderby(wc
->orderClause
, targetList
, false, context
);
6558 /* framing clause is never inherited, so print unless it's default */
6559 if (wc
->frameOptions
& FRAMEOPTION_NONDEFAULT
)
6562 appendStringInfoChar(buf
, ' ');
6563 if (wc
->frameOptions
& FRAMEOPTION_RANGE
)
6564 appendStringInfoString(buf
, "RANGE ");
6565 else if (wc
->frameOptions
& FRAMEOPTION_ROWS
)
6566 appendStringInfoString(buf
, "ROWS ");
6567 else if (wc
->frameOptions
& FRAMEOPTION_GROUPS
)
6568 appendStringInfoString(buf
, "GROUPS ");
6571 if (wc
->frameOptions
& FRAMEOPTION_BETWEEN
)
6572 appendStringInfoString(buf
, "BETWEEN ");
6573 if (wc
->frameOptions
& FRAMEOPTION_START_UNBOUNDED_PRECEDING
)
6574 appendStringInfoString(buf
, "UNBOUNDED PRECEDING ");
6575 else if (wc
->frameOptions
& FRAMEOPTION_START_CURRENT_ROW
)
6576 appendStringInfoString(buf
, "CURRENT ROW ");
6577 else if (wc
->frameOptions
& FRAMEOPTION_START_OFFSET
)
6579 get_rule_expr(wc
->startOffset
, context
, false);
6580 if (wc
->frameOptions
& FRAMEOPTION_START_OFFSET_PRECEDING
)
6581 appendStringInfoString(buf
, " PRECEDING ");
6582 else if (wc
->frameOptions
& FRAMEOPTION_START_OFFSET_FOLLOWING
)
6583 appendStringInfoString(buf
, " FOLLOWING ");
6589 if (wc
->frameOptions
& FRAMEOPTION_BETWEEN
)
6591 appendStringInfoString(buf
, "AND ");
6592 if (wc
->frameOptions
& FRAMEOPTION_END_UNBOUNDED_FOLLOWING
)
6593 appendStringInfoString(buf
, "UNBOUNDED FOLLOWING ");
6594 else if (wc
->frameOptions
& FRAMEOPTION_END_CURRENT_ROW
)
6595 appendStringInfoString(buf
, "CURRENT ROW ");
6596 else if (wc
->frameOptions
& FRAMEOPTION_END_OFFSET
)
6598 get_rule_expr(wc
->endOffset
, context
, false);
6599 if (wc
->frameOptions
& FRAMEOPTION_END_OFFSET_PRECEDING
)
6600 appendStringInfoString(buf
, " PRECEDING ");
6601 else if (wc
->frameOptions
& FRAMEOPTION_END_OFFSET_FOLLOWING
)
6602 appendStringInfoString(buf
, " FOLLOWING ");
6609 if (wc
->frameOptions
& FRAMEOPTION_EXCLUDE_CURRENT_ROW
)
6610 appendStringInfoString(buf
, "EXCLUDE CURRENT ROW ");
6611 else if (wc
->frameOptions
& FRAMEOPTION_EXCLUDE_GROUP
)
6612 appendStringInfoString(buf
, "EXCLUDE GROUP ");
6613 else if (wc
->frameOptions
& FRAMEOPTION_EXCLUDE_TIES
)
6614 appendStringInfoString(buf
, "EXCLUDE TIES ");
6615 /* we will now have a trailing space; remove it */
6618 appendStringInfoChar(buf
, ')');
6622 * get_insert_query_def - Parse back an INSERT parsetree
6626 get_insert_query_def(Query
*query
, deparse_context
*context
)
6628 StringInfo buf
= context
->buf
;
6629 RangeTblEntry
*select_rte
= NULL
;
6630 RangeTblEntry
*values_rte
= NULL
;
6634 List
*strippedexprs
;
6636 /* Insert the WITH clause if given */
6637 get_with_clause(query
, context
);
6640 * If it's an INSERT ... SELECT or multi-row VALUES, there will be a
6641 * single RTE for the SELECT or VALUES. Plain VALUES has neither.
6643 foreach(l
, query
->rtable
)
6645 rte
= (RangeTblEntry
*) lfirst(l
);
6647 if (rte
->rtekind
== RTE_SUBQUERY
)
6650 elog(ERROR
, "too many subquery RTEs in INSERT");
6654 if (rte
->rtekind
== RTE_VALUES
)
6657 elog(ERROR
, "too many values RTEs in INSERT");
6661 if (select_rte
&& values_rte
)
6662 elog(ERROR
, "both subquery and values RTEs in INSERT");
6665 * Start the query with INSERT INTO relname
6667 rte
= rt_fetch(query
->resultRelation
, query
->rtable
);
6668 Assert(rte
->rtekind
== RTE_RELATION
);
6670 if (PRETTY_INDENT(context
))
6672 context
->indentLevel
+= PRETTYINDENT_STD
;
6673 appendStringInfoChar(buf
, ' ');
6675 appendStringInfo(buf
, "INSERT INTO %s",
6676 generate_relation_name(rte
->relid
, NIL
));
6678 /* Print the relation alias, if needed; INSERT requires explicit AS */
6679 get_rte_alias(rte
, query
->resultRelation
, true, context
);
6681 /* always want a space here */
6682 appendStringInfoChar(buf
, ' ');
6685 * Add the insert-column-names list. Any indirection decoration needed on
6686 * the column names can be inferred from the top targetlist.
6688 strippedexprs
= NIL
;
6690 if (query
->targetList
)
6691 appendStringInfoChar(buf
, '(');
6692 foreach(l
, query
->targetList
)
6694 TargetEntry
*tle
= (TargetEntry
*) lfirst(l
);
6697 continue; /* ignore junk entries */
6699 appendStringInfoString(buf
, sep
);
6703 * Put out name of target column; look in the catalogs, not at
6704 * tle->resname, since resname will fail to track RENAME.
6706 appendStringInfoString(buf
,
6707 quote_identifier(get_attname(rte
->relid
,
6712 * Print any indirection needed (subfields or subscripts), and strip
6713 * off the top-level nodes representing the indirection assignments.
6714 * Add the stripped expressions to strippedexprs. (If it's a
6715 * single-VALUES statement, the stripped expressions are the VALUES to
6716 * print below. Otherwise they're just Vars and not really
6719 strippedexprs
= lappend(strippedexprs
,
6720 processIndirection((Node
*) tle
->expr
,
6723 if (query
->targetList
)
6724 appendStringInfoString(buf
, ") ");
6726 if (query
->override
)
6728 if (query
->override
== OVERRIDING_SYSTEM_VALUE
)
6729 appendStringInfoString(buf
, "OVERRIDING SYSTEM VALUE ");
6730 else if (query
->override
== OVERRIDING_USER_VALUE
)
6731 appendStringInfoString(buf
, "OVERRIDING USER VALUE ");
6736 /* Add the SELECT */
6737 get_query_def(select_rte
->subquery
, buf
, context
->namespaces
, NULL
,
6739 context
->prettyFlags
, context
->wrapColumn
,
6740 context
->indentLevel
);
6742 else if (values_rte
)
6744 /* Add the multi-VALUES expression lists */
6745 get_values_def(values_rte
->values_lists
, context
);
6747 else if (strippedexprs
)
6749 /* Add the single-VALUES expression list */
6750 appendContextKeyword(context
, "VALUES (",
6751 -PRETTYINDENT_STD
, PRETTYINDENT_STD
, 2);
6752 get_rule_list_toplevel(strippedexprs
, context
, false);
6753 appendStringInfoChar(buf
, ')');
6757 /* No expressions, so it must be DEFAULT VALUES */
6758 appendStringInfoString(buf
, "DEFAULT VALUES");
6761 /* Add ON CONFLICT if present */
6762 if (query
->onConflict
)
6764 OnConflictExpr
*confl
= query
->onConflict
;
6766 appendStringInfoString(buf
, " ON CONFLICT");
6768 if (confl
->arbiterElems
)
6770 /* Add the single-VALUES expression list */
6771 appendStringInfoChar(buf
, '(');
6772 get_rule_expr((Node
*) confl
->arbiterElems
, context
, false);
6773 appendStringInfoChar(buf
, ')');
6775 /* Add a WHERE clause (for partial indexes) if given */
6776 if (confl
->arbiterWhere
!= NULL
)
6778 bool save_varprefix
;
6781 * Force non-prefixing of Vars, since parser assumes that they
6782 * belong to target relation. WHERE clause does not use
6783 * InferenceElem, so this is separately required.
6785 save_varprefix
= context
->varprefix
;
6786 context
->varprefix
= false;
6788 appendContextKeyword(context
, " WHERE ",
6789 -PRETTYINDENT_STD
, PRETTYINDENT_STD
, 1);
6790 get_rule_expr(confl
->arbiterWhere
, context
, false);
6792 context
->varprefix
= save_varprefix
;
6795 else if (OidIsValid(confl
->constraint
))
6797 char *constraint
= get_constraint_name(confl
->constraint
);
6800 elog(ERROR
, "cache lookup failed for constraint %u",
6802 appendStringInfo(buf
, " ON CONSTRAINT %s",
6803 quote_identifier(constraint
));
6806 if (confl
->action
== ONCONFLICT_NOTHING
)
6808 appendStringInfoString(buf
, " DO NOTHING");
6812 appendStringInfoString(buf
, " DO UPDATE SET ");
6813 /* Deparse targetlist */
6814 get_update_query_targetlist_def(query
, confl
->onConflictSet
,
6817 /* Add a WHERE clause if given */
6818 if (confl
->onConflictWhere
!= NULL
)
6820 appendContextKeyword(context
, " WHERE ",
6821 -PRETTYINDENT_STD
, PRETTYINDENT_STD
, 1);
6822 get_rule_expr(confl
->onConflictWhere
, context
, false);
6827 /* Add RETURNING if present */
6828 if (query
->returningList
)
6830 appendContextKeyword(context
, " RETURNING",
6831 -PRETTYINDENT_STD
, PRETTYINDENT_STD
, 1);
6832 get_target_list(query
->returningList
, context
);
6838 * get_update_query_def - Parse back an UPDATE parsetree
6842 get_update_query_def(Query
*query
, deparse_context
*context
)
6844 StringInfo buf
= context
->buf
;
6847 /* Insert the WITH clause if given */
6848 get_with_clause(query
, context
);
6851 * Start the query with UPDATE relname SET
6853 rte
= rt_fetch(query
->resultRelation
, query
->rtable
);
6854 Assert(rte
->rtekind
== RTE_RELATION
);
6855 if (PRETTY_INDENT(context
))
6857 appendStringInfoChar(buf
, ' ');
6858 context
->indentLevel
+= PRETTYINDENT_STD
;
6860 appendStringInfo(buf
, "UPDATE %s%s",
6862 generate_relation_name(rte
->relid
, NIL
));
6864 /* Print the relation alias, if needed */
6865 get_rte_alias(rte
, query
->resultRelation
, false, context
);
6867 appendStringInfoString(buf
, " SET ");
6869 /* Deparse targetlist */
6870 get_update_query_targetlist_def(query
, query
->targetList
, context
, rte
);
6872 /* Add the FROM clause if needed */
6873 get_from_clause(query
, " FROM ", context
);
6875 /* Add a WHERE clause if given */
6876 if (query
->jointree
->quals
!= NULL
)
6878 appendContextKeyword(context
, " WHERE ",
6879 -PRETTYINDENT_STD
, PRETTYINDENT_STD
, 1);
6880 get_rule_expr(query
->jointree
->quals
, context
, false);
6883 /* Add RETURNING if present */
6884 if (query
->returningList
)
6886 appendContextKeyword(context
, " RETURNING",
6887 -PRETTYINDENT_STD
, PRETTYINDENT_STD
, 1);
6888 get_target_list(query
->returningList
, context
);
6894 * get_update_query_targetlist_def - Parse back an UPDATE targetlist
6898 get_update_query_targetlist_def(Query
*query
, List
*targetList
,
6899 deparse_context
*context
, RangeTblEntry
*rte
)
6901 StringInfo buf
= context
->buf
;
6903 ListCell
*next_ma_cell
;
6904 int remaining_ma_columns
;
6906 SubLink
*cur_ma_sublink
;
6910 * Prepare to deal with MULTIEXPR assignments: collect the source SubLinks
6911 * into a list. We expect them to appear, in ID order, in resjunk tlist
6915 if (query
->hasSubLinks
) /* else there can't be any */
6917 foreach(l
, targetList
)
6919 TargetEntry
*tle
= (TargetEntry
*) lfirst(l
);
6921 if (tle
->resjunk
&& IsA(tle
->expr
, SubLink
))
6923 SubLink
*sl
= (SubLink
*) tle
->expr
;
6925 if (sl
->subLinkType
== MULTIEXPR_SUBLINK
)
6927 ma_sublinks
= lappend(ma_sublinks
, sl
);
6928 Assert(sl
->subLinkId
== list_length(ma_sublinks
));
6933 next_ma_cell
= list_head(ma_sublinks
);
6934 cur_ma_sublink
= NULL
;
6935 remaining_ma_columns
= 0;
6937 /* Add the comma separated list of 'attname = value' */
6939 foreach(l
, targetList
)
6941 TargetEntry
*tle
= (TargetEntry
*) lfirst(l
);
6945 continue; /* ignore junk entries */
6947 /* Emit separator (OK whether we're in multiassignment or not) */
6948 appendStringInfoString(buf
, sep
);
6952 * Check to see if we're starting a multiassignment group: if so,
6953 * output a left paren.
6955 if (next_ma_cell
!= NULL
&& cur_ma_sublink
== NULL
)
6958 * We must dig down into the expr to see if it's a PARAM_MULTIEXPR
6959 * Param. That could be buried under FieldStores and
6960 * SubscriptingRefs and CoerceToDomains (cf processIndirection()),
6961 * and underneath those there could be an implicit type coercion.
6962 * Because we would ignore implicit type coercions anyway, we
6963 * don't need to be as careful as processIndirection() is about
6964 * descending past implicit CoerceToDomains.
6966 expr
= (Node
*) tle
->expr
;
6969 if (IsA(expr
, FieldStore
))
6971 FieldStore
*fstore
= (FieldStore
*) expr
;
6973 expr
= (Node
*) linitial(fstore
->newvals
);
6975 else if (IsA(expr
, SubscriptingRef
))
6977 SubscriptingRef
*sbsref
= (SubscriptingRef
*) expr
;
6979 if (sbsref
->refassgnexpr
== NULL
)
6982 expr
= (Node
*) sbsref
->refassgnexpr
;
6984 else if (IsA(expr
, CoerceToDomain
))
6986 CoerceToDomain
*cdomain
= (CoerceToDomain
*) expr
;
6988 if (cdomain
->coercionformat
!= COERCE_IMPLICIT_CAST
)
6990 expr
= (Node
*) cdomain
->arg
;
6995 expr
= strip_implicit_coercions(expr
);
6997 if (expr
&& IsA(expr
, Param
) &&
6998 ((Param
*) expr
)->paramkind
== PARAM_MULTIEXPR
)
7000 cur_ma_sublink
= (SubLink
*) lfirst(next_ma_cell
);
7001 next_ma_cell
= lnext(ma_sublinks
, next_ma_cell
);
7002 remaining_ma_columns
= count_nonjunk_tlist_entries(((Query
*) cur_ma_sublink
->subselect
)->targetList
);
7003 Assert(((Param
*) expr
)->paramid
==
7004 ((cur_ma_sublink
->subLinkId
<< 16) | 1));
7005 appendStringInfoChar(buf
, '(');
7010 * Put out name of target column; look in the catalogs, not at
7011 * tle->resname, since resname will fail to track RENAME.
7013 appendStringInfoString(buf
,
7014 quote_identifier(get_attname(rte
->relid
,
7019 * Print any indirection needed (subfields or subscripts), and strip
7020 * off the top-level nodes representing the indirection assignments.
7022 expr
= processIndirection((Node
*) tle
->expr
, context
);
7025 * If we're in a multiassignment, skip printing anything more, unless
7026 * this is the last column; in which case, what we print should be the
7027 * sublink, not the Param.
7029 if (cur_ma_sublink
!= NULL
)
7031 if (--remaining_ma_columns
> 0)
7032 continue; /* not the last column of multiassignment */
7033 appendStringInfoChar(buf
, ')');
7034 expr
= (Node
*) cur_ma_sublink
;
7035 cur_ma_sublink
= NULL
;
7038 appendStringInfoString(buf
, " = ");
7040 get_rule_expr(expr
, context
, false);
7046 * get_delete_query_def - Parse back a DELETE parsetree
7050 get_delete_query_def(Query
*query
, deparse_context
*context
)
7052 StringInfo buf
= context
->buf
;
7055 /* Insert the WITH clause if given */
7056 get_with_clause(query
, context
);
7059 * Start the query with DELETE FROM relname
7061 rte
= rt_fetch(query
->resultRelation
, query
->rtable
);
7062 Assert(rte
->rtekind
== RTE_RELATION
);
7063 if (PRETTY_INDENT(context
))
7065 appendStringInfoChar(buf
, ' ');
7066 context
->indentLevel
+= PRETTYINDENT_STD
;
7068 appendStringInfo(buf
, "DELETE FROM %s%s",
7070 generate_relation_name(rte
->relid
, NIL
));
7072 /* Print the relation alias, if needed */
7073 get_rte_alias(rte
, query
->resultRelation
, false, context
);
7075 /* Add the USING clause if given */
7076 get_from_clause(query
, " USING ", context
);
7078 /* Add a WHERE clause if given */
7079 if (query
->jointree
->quals
!= NULL
)
7081 appendContextKeyword(context
, " WHERE ",
7082 -PRETTYINDENT_STD
, PRETTYINDENT_STD
, 1);
7083 get_rule_expr(query
->jointree
->quals
, context
, false);
7086 /* Add RETURNING if present */
7087 if (query
->returningList
)
7089 appendContextKeyword(context
, " RETURNING",
7090 -PRETTYINDENT_STD
, PRETTYINDENT_STD
, 1);
7091 get_target_list(query
->returningList
, context
);
7097 * get_merge_query_def - Parse back a MERGE parsetree
7101 get_merge_query_def(Query
*query
, deparse_context
*context
)
7103 StringInfo buf
= context
->buf
;
7106 bool haveNotMatchedBySource
;
7108 /* Insert the WITH clause if given */
7109 get_with_clause(query
, context
);
7112 * Start the query with MERGE INTO relname
7114 rte
= rt_fetch(query
->resultRelation
, query
->rtable
);
7115 Assert(rte
->rtekind
== RTE_RELATION
);
7116 if (PRETTY_INDENT(context
))
7118 appendStringInfoChar(buf
, ' ');
7119 context
->indentLevel
+= PRETTYINDENT_STD
;
7121 appendStringInfo(buf
, "MERGE INTO %s%s",
7123 generate_relation_name(rte
->relid
, NIL
));
7125 /* Print the relation alias, if needed */
7126 get_rte_alias(rte
, query
->resultRelation
, false, context
);
7128 /* Print the source relation and join clause */
7129 get_from_clause(query
, " USING ", context
);
7130 appendContextKeyword(context
, " ON ",
7131 -PRETTYINDENT_STD
, PRETTYINDENT_STD
, 2);
7132 get_rule_expr(query
->mergeJoinCondition
, context
, false);
7135 * Test for any NOT MATCHED BY SOURCE actions. If there are none, then
7136 * any NOT MATCHED BY TARGET actions are output as "WHEN NOT MATCHED", per
7137 * SQL standard. Otherwise, we have a non-SQL-standard query, so output
7138 * "BY SOURCE" / "BY TARGET" qualifiers for all NOT MATCHED actions, to be
7141 haveNotMatchedBySource
= false;
7142 foreach(lc
, query
->mergeActionList
)
7144 MergeAction
*action
= lfirst_node(MergeAction
, lc
);
7146 if (action
->matchKind
== MERGE_WHEN_NOT_MATCHED_BY_SOURCE
)
7148 haveNotMatchedBySource
= true;
7153 /* Print each merge action */
7154 foreach(lc
, query
->mergeActionList
)
7156 MergeAction
*action
= lfirst_node(MergeAction
, lc
);
7158 appendContextKeyword(context
, " WHEN ",
7159 -PRETTYINDENT_STD
, PRETTYINDENT_STD
, 2);
7160 switch (action
->matchKind
)
7162 case MERGE_WHEN_MATCHED
:
7163 appendStringInfoString(buf
, "MATCHED");
7165 case MERGE_WHEN_NOT_MATCHED_BY_SOURCE
:
7166 appendStringInfoString(buf
, "NOT MATCHED BY SOURCE");
7168 case MERGE_WHEN_NOT_MATCHED_BY_TARGET
:
7169 if (haveNotMatchedBySource
)
7170 appendStringInfoString(buf
, "NOT MATCHED BY TARGET");
7172 appendStringInfoString(buf
, "NOT MATCHED");
7175 elog(ERROR
, "unrecognized matchKind: %d",
7176 (int) action
->matchKind
);
7181 appendContextKeyword(context
, " AND ",
7182 -PRETTYINDENT_STD
, PRETTYINDENT_STD
, 3);
7183 get_rule_expr(action
->qual
, context
, false);
7185 appendContextKeyword(context
, " THEN ",
7186 -PRETTYINDENT_STD
, PRETTYINDENT_STD
, 3);
7188 if (action
->commandType
== CMD_INSERT
)
7190 /* This generally matches get_insert_query_def() */
7191 List
*strippedexprs
= NIL
;
7192 const char *sep
= "";
7195 appendStringInfoString(buf
, "INSERT");
7197 if (action
->targetList
)
7198 appendStringInfoString(buf
, " (");
7199 foreach(lc2
, action
->targetList
)
7201 TargetEntry
*tle
= (TargetEntry
*) lfirst(lc2
);
7203 Assert(!tle
->resjunk
);
7205 appendStringInfoString(buf
, sep
);
7208 appendStringInfoString(buf
,
7209 quote_identifier(get_attname(rte
->relid
,
7212 strippedexprs
= lappend(strippedexprs
,
7213 processIndirection((Node
*) tle
->expr
,
7216 if (action
->targetList
)
7217 appendStringInfoChar(buf
, ')');
7219 if (action
->override
)
7221 if (action
->override
== OVERRIDING_SYSTEM_VALUE
)
7222 appendStringInfoString(buf
, " OVERRIDING SYSTEM VALUE");
7223 else if (action
->override
== OVERRIDING_USER_VALUE
)
7224 appendStringInfoString(buf
, " OVERRIDING USER VALUE");
7229 appendContextKeyword(context
, " VALUES (",
7230 -PRETTYINDENT_STD
, PRETTYINDENT_STD
, 4);
7231 get_rule_list_toplevel(strippedexprs
, context
, false);
7232 appendStringInfoChar(buf
, ')');
7235 appendStringInfoString(buf
, " DEFAULT VALUES");
7237 else if (action
->commandType
== CMD_UPDATE
)
7239 appendStringInfoString(buf
, "UPDATE SET ");
7240 get_update_query_targetlist_def(query
, action
->targetList
,
7243 else if (action
->commandType
== CMD_DELETE
)
7244 appendStringInfoString(buf
, "DELETE");
7245 else if (action
->commandType
== CMD_NOTHING
)
7246 appendStringInfoString(buf
, "DO NOTHING");
7249 /* Add RETURNING if present */
7250 if (query
->returningList
)
7252 appendContextKeyword(context
, " RETURNING",
7253 -PRETTYINDENT_STD
, PRETTYINDENT_STD
, 1);
7254 get_target_list(query
->returningList
, context
);
7260 * get_utility_query_def - Parse back a UTILITY parsetree
7264 get_utility_query_def(Query
*query
, deparse_context
*context
)
7266 StringInfo buf
= context
->buf
;
7268 if (query
->utilityStmt
&& IsA(query
->utilityStmt
, NotifyStmt
))
7270 NotifyStmt
*stmt
= (NotifyStmt
*) query
->utilityStmt
;
7272 appendContextKeyword(context
, "",
7273 0, PRETTYINDENT_STD
, 1);
7274 appendStringInfo(buf
, "NOTIFY %s",
7275 quote_identifier(stmt
->conditionname
));
7278 appendStringInfoString(buf
, ", ");
7279 simple_quote_literal(buf
, stmt
->payload
);
7284 /* Currently only NOTIFY utility commands can appear in rules */
7285 elog(ERROR
, "unexpected utility statement type");
7290 * Display a Var appropriately.
7292 * In some cases (currently only when recursing into an unnamed join)
7293 * the Var's varlevelsup has to be interpreted with respect to a context
7294 * above the current one; levelsup indicates the offset.
7296 * If istoplevel is true, the Var is at the top level of a SELECT's
7297 * targetlist, which means we need special treatment of whole-row Vars.
7298 * Instead of the normal "tab.*", we'll print "tab.*::typename", which is a
7299 * dirty hack to prevent "tab.*" from being expanded into multiple columns.
7300 * (The parser will strip the useless coercion, so no inefficiency is added in
7301 * dump and reload.) We used to print just "tab" in such cases, but that is
7302 * ambiguous and will yield the wrong result if "tab" is also a plain column
7303 * name in the query.
7305 * Returns the attname of the Var, or NULL if the Var has no attname (because
7306 * it is a whole-row Var or a subplan output reference).
7309 get_variable(Var
*var
, int levelsup
, bool istoplevel
, deparse_context
*context
)
7311 StringInfo buf
= context
->buf
;
7315 deparse_namespace
*dpns
;
7317 AttrNumber varattno
;
7318 deparse_columns
*colinfo
;
7323 /* Find appropriate nesting depth */
7324 netlevelsup
= var
->varlevelsup
+ levelsup
;
7325 if (netlevelsup
>= list_length(context
->namespaces
))
7326 elog(ERROR
, "bogus varlevelsup: %d offset %d",
7327 var
->varlevelsup
, levelsup
);
7328 dpns
= (deparse_namespace
*) list_nth(context
->namespaces
,
7332 * If we have a syntactic referent for the Var, and we're working from a
7333 * parse tree, prefer to use the syntactic referent. Otherwise, fall back
7334 * on the semantic referent. (Forcing use of the semantic referent when
7335 * printing plan trees is a design choice that's perhaps more motivated by
7336 * backwards compatibility than anything else. But it does have the
7337 * advantage of making plans more explicit.)
7339 if (var
->varnosyn
> 0 && dpns
->plan
== NULL
)
7341 varno
= var
->varnosyn
;
7342 varattno
= var
->varattnosyn
;
7347 varattno
= var
->varattno
;
7351 * Try to find the relevant RTE in this rtable. In a plan tree, it's
7352 * likely that varno is OUTER_VAR or INNER_VAR, in which case we must dig
7353 * down into the subplans, or INDEX_VAR, which is resolved similarly. Also
7354 * find the aliases previously assigned for this RTE.
7356 if (varno
>= 1 && varno
<= list_length(dpns
->rtable
))
7359 * We might have been asked to map child Vars to some parent relation.
7361 if (context
->appendparents
&& dpns
->appendrels
)
7364 AttrNumber pvarattno
= varattno
;
7365 AppendRelInfo
*appinfo
= dpns
->appendrels
[pvarno
];
7368 /* Only map up to inheritance parents, not UNION ALL appendrels */
7370 rt_fetch(appinfo
->parent_relid
,
7371 dpns
->rtable
)->rtekind
== RTE_RELATION
)
7374 if (pvarattno
> 0) /* system columns stay as-is */
7376 if (pvarattno
> appinfo
->num_child_cols
)
7377 break; /* safety check */
7378 pvarattno
= appinfo
->parent_colnos
[pvarattno
- 1];
7380 break; /* Var is local to child */
7383 pvarno
= appinfo
->parent_relid
;
7386 /* If the parent is itself a child, continue up. */
7387 Assert(pvarno
> 0 && pvarno
<= list_length(dpns
->rtable
));
7388 appinfo
= dpns
->appendrels
[pvarno
];
7392 * If we found an ancestral rel, and that rel is included in
7393 * appendparents, print that column not the original one.
7395 if (found
&& bms_is_member(pvarno
, context
->appendparents
))
7398 varattno
= pvarattno
;
7402 rte
= rt_fetch(varno
, dpns
->rtable
);
7403 refname
= (char *) list_nth(dpns
->rtable_names
, varno
- 1);
7404 colinfo
= deparse_columns_fetch(varno
, dpns
);
7409 resolve_special_varno((Node
*) var
, context
,
7410 get_special_variable
, NULL
);
7415 * The planner will sometimes emit Vars referencing resjunk elements of a
7416 * subquery's target list (this is currently only possible if it chooses
7417 * to generate a "physical tlist" for a SubqueryScan or CteScan node).
7418 * Although we prefer to print subquery-referencing Vars using the
7419 * subquery's alias, that's not possible for resjunk items since they have
7420 * no alias. So in that case, drill down to the subplan and print the
7421 * contents of the referenced tlist item. This works because in a plan
7422 * tree, such Vars can only occur in a SubqueryScan or CteScan node, and
7423 * we'll have set dpns->inner_plan to reference the child plan node.
7425 if ((rte
->rtekind
== RTE_SUBQUERY
|| rte
->rtekind
== RTE_CTE
) &&
7426 attnum
> list_length(rte
->eref
->colnames
) &&
7430 deparse_namespace save_dpns
;
7432 tle
= get_tle_by_resno(dpns
->inner_tlist
, attnum
);
7434 elog(ERROR
, "invalid attnum %d for relation \"%s\"",
7435 attnum
, rte
->eref
->aliasname
);
7437 Assert(netlevelsup
== 0);
7438 push_child_plan(dpns
, dpns
->inner_plan
, &save_dpns
);
7441 * Force parentheses because our caller probably assumed a Var is a
7442 * simple expression.
7444 if (!IsA(tle
->expr
, Var
))
7445 appendStringInfoChar(buf
, '(');
7446 get_rule_expr((Node
*) tle
->expr
, context
, true);
7447 if (!IsA(tle
->expr
, Var
))
7448 appendStringInfoChar(buf
, ')');
7450 pop_child_plan(dpns
, &save_dpns
);
7455 * If it's an unnamed join, look at the expansion of the alias variable.
7456 * If it's a simple reference to one of the input vars, then recursively
7457 * print the name of that var instead. When it's not a simple reference,
7458 * we have to just print the unqualified join column name. (This can only
7459 * happen with "dangerous" merged columns in a JOIN USING; we took pains
7460 * previously to make the unqualified column name unique in such cases.)
7462 * This wouldn't work in decompiling plan trees, because we don't store
7463 * joinaliasvars lists after planning; but a plan tree should never
7464 * contain a join alias variable.
7466 if (rte
->rtekind
== RTE_JOIN
&& rte
->alias
== NULL
)
7468 if (rte
->joinaliasvars
== NIL
)
7469 elog(ERROR
, "cannot decompile join alias var in plan tree");
7474 aliasvar
= (Var
*) list_nth(rte
->joinaliasvars
, attnum
- 1);
7475 /* we intentionally don't strip implicit coercions here */
7476 if (aliasvar
&& IsA(aliasvar
, Var
))
7478 return get_variable(aliasvar
, var
->varlevelsup
+ levelsup
,
7479 istoplevel
, context
);
7484 * Unnamed join has no refname. (Note: since it's unnamed, there is
7485 * no way the user could have referenced it to create a whole-row Var
7486 * for it. So we don't have to cover that case below.)
7488 Assert(refname
== NULL
);
7491 if (attnum
== InvalidAttrNumber
)
7493 else if (attnum
> 0)
7495 /* Get column name to use from the colinfo struct */
7496 if (attnum
> colinfo
->num_cols
)
7497 elog(ERROR
, "invalid attnum %d for relation \"%s\"",
7498 attnum
, rte
->eref
->aliasname
);
7499 attname
= colinfo
->colnames
[attnum
- 1];
7502 * If we find a Var referencing a dropped column, it seems better to
7503 * print something (anything) than to fail. In general this should
7504 * not happen, but it used to be possible for some cases involving
7505 * functions returning named composite types, and perhaps there are
7506 * still bugs out there.
7508 if (attname
== NULL
)
7509 attname
= "?dropped?column?";
7513 /* System column - name is fixed, get it from the catalog */
7514 attname
= get_rte_attribute_name(rte
, attnum
);
7517 need_prefix
= (context
->varprefix
|| attname
== NULL
);
7520 * If we're considering a plain Var in an ORDER BY (but not GROUP BY)
7521 * clause, we may need to add a table-name prefix to prevent
7522 * findTargetlistEntrySQL92 from misinterpreting the name as an
7523 * output-column name. To avoid cluttering the output with unnecessary
7524 * prefixes, do so only if there is a name match to a SELECT tlist item
7525 * that is different from the Var.
7527 if (context
->varInOrderBy
&& !context
->inGroupBy
&& !need_prefix
)
7531 foreach_node(TargetEntry
, tle
, context
->targetList
)
7536 continue; /* ignore junk entries */
7539 /* This must match colname-choosing logic in get_target_list() */
7540 if (context
->resultDesc
&& colno
<= context
->resultDesc
->natts
)
7541 colname
= NameStr(TupleDescAttr(context
->resultDesc
,
7542 colno
- 1)->attname
);
7544 colname
= tle
->resname
;
7546 if (colname
&& strcmp(colname
, attname
) == 0 &&
7547 !equal(var
, tle
->expr
))
7555 if (refname
&& need_prefix
)
7557 appendStringInfoString(buf
, quote_identifier(refname
));
7558 appendStringInfoChar(buf
, '.');
7561 appendStringInfoString(buf
, quote_identifier(attname
));
7564 appendStringInfoChar(buf
, '*');
7566 appendStringInfo(buf
, "::%s",
7567 format_type_with_typemod(var
->vartype
,
7575 * Deparse a Var which references OUTER_VAR, INNER_VAR, or INDEX_VAR. This
7576 * routine is actually a callback for resolve_special_varno, which handles
7577 * finding the correct TargetEntry. We get the expression contained in that
7578 * TargetEntry and just need to deparse it, a job we can throw back on
7582 get_special_variable(Node
*node
, deparse_context
*context
, void *callback_arg
)
7584 StringInfo buf
= context
->buf
;
7587 * For a non-Var referent, force parentheses because our caller probably
7588 * assumed a Var is a simple expression.
7590 if (!IsA(node
, Var
))
7591 appendStringInfoChar(buf
, '(');
7592 get_rule_expr(node
, context
, true);
7593 if (!IsA(node
, Var
))
7594 appendStringInfoChar(buf
, ')');
7598 * Chase through plan references to special varnos (OUTER_VAR, INNER_VAR,
7599 * INDEX_VAR) until we find a real Var or some kind of non-Var node; then,
7600 * invoke the callback provided.
7603 resolve_special_varno(Node
*node
, deparse_context
*context
,
7604 rsv_callback callback
, void *callback_arg
)
7607 deparse_namespace
*dpns
;
7609 /* This function is recursive, so let's be paranoid. */
7610 check_stack_depth();
7612 /* If it's not a Var, invoke the callback. */
7613 if (!IsA(node
, Var
))
7615 (*callback
) (node
, context
, callback_arg
);
7619 /* Find appropriate nesting depth */
7621 dpns
= (deparse_namespace
*) list_nth(context
->namespaces
,
7625 * If varno is special, recurse. (Don't worry about varnosyn; if we're
7626 * here, we already decided not to use that.)
7628 if (var
->varno
== OUTER_VAR
&& dpns
->outer_tlist
)
7631 deparse_namespace save_dpns
;
7632 Bitmapset
*save_appendparents
;
7634 tle
= get_tle_by_resno(dpns
->outer_tlist
, var
->varattno
);
7636 elog(ERROR
, "bogus varattno for OUTER_VAR var: %d", var
->varattno
);
7639 * If we're descending to the first child of an Append or MergeAppend,
7640 * update appendparents. This will affect deparsing of all Vars
7641 * appearing within the eventually-resolved subexpression.
7643 save_appendparents
= context
->appendparents
;
7645 if (IsA(dpns
->plan
, Append
))
7646 context
->appendparents
= bms_union(context
->appendparents
,
7647 ((Append
*) dpns
->plan
)->apprelids
);
7648 else if (IsA(dpns
->plan
, MergeAppend
))
7649 context
->appendparents
= bms_union(context
->appendparents
,
7650 ((MergeAppend
*) dpns
->plan
)->apprelids
);
7652 push_child_plan(dpns
, dpns
->outer_plan
, &save_dpns
);
7653 resolve_special_varno((Node
*) tle
->expr
, context
,
7654 callback
, callback_arg
);
7655 pop_child_plan(dpns
, &save_dpns
);
7656 context
->appendparents
= save_appendparents
;
7659 else if (var
->varno
== INNER_VAR
&& dpns
->inner_tlist
)
7662 deparse_namespace save_dpns
;
7664 tle
= get_tle_by_resno(dpns
->inner_tlist
, var
->varattno
);
7666 elog(ERROR
, "bogus varattno for INNER_VAR var: %d", var
->varattno
);
7668 push_child_plan(dpns
, dpns
->inner_plan
, &save_dpns
);
7669 resolve_special_varno((Node
*) tle
->expr
, context
,
7670 callback
, callback_arg
);
7671 pop_child_plan(dpns
, &save_dpns
);
7674 else if (var
->varno
== INDEX_VAR
&& dpns
->index_tlist
)
7678 tle
= get_tle_by_resno(dpns
->index_tlist
, var
->varattno
);
7680 elog(ERROR
, "bogus varattno for INDEX_VAR var: %d", var
->varattno
);
7682 resolve_special_varno((Node
*) tle
->expr
, context
,
7683 callback
, callback_arg
);
7686 else if (var
->varno
< 1 || var
->varno
> list_length(dpns
->rtable
))
7687 elog(ERROR
, "bogus varno: %d", var
->varno
);
7689 /* Not special. Just invoke the callback. */
7690 (*callback
) (node
, context
, callback_arg
);
7694 * Get the name of a field of an expression of composite type. The
7695 * expression is usually a Var, but we handle other cases too.
7697 * levelsup is an extra offset to interpret the Var's varlevelsup correctly.
7699 * This is fairly straightforward when the expression has a named composite
7700 * type; we need only look up the type in the catalogs. However, the type
7701 * could also be RECORD. Since no actual table or view column is allowed to
7702 * have type RECORD, a Var of type RECORD must refer to a JOIN or FUNCTION RTE
7703 * or to a subquery output. We drill down to find the ultimate defining
7704 * expression and attempt to infer the field name from it. We ereport if we
7705 * can't determine the name.
7707 * Similarly, a PARAM of type RECORD has to refer to some expression of
7708 * a determinable composite type.
7711 get_name_for_var_field(Var
*var
, int fieldno
,
7712 int levelsup
, deparse_context
*context
)
7717 deparse_namespace
*dpns
;
7719 AttrNumber varattno
;
7720 TupleDesc tupleDesc
;
7724 * If it's a RowExpr that was expanded from a whole-row Var, use the
7725 * column names attached to it. (We could let get_expr_result_tupdesc()
7726 * handle this, but it's much cheaper to just pull out the name we need.)
7728 if (IsA(var
, RowExpr
))
7730 RowExpr
*r
= (RowExpr
*) var
;
7732 if (fieldno
> 0 && fieldno
<= list_length(r
->colnames
))
7733 return strVal(list_nth(r
->colnames
, fieldno
- 1));
7737 * If it's a Param of type RECORD, try to find what the Param refers to.
7739 if (IsA(var
, Param
))
7741 Param
*param
= (Param
*) var
;
7742 ListCell
*ancestor_cell
;
7744 expr
= find_param_referent(param
, context
, &dpns
, &ancestor_cell
);
7747 /* Found a match, so recurse to decipher the field name */
7748 deparse_namespace save_dpns
;
7751 push_ancestor_plan(dpns
, ancestor_cell
, &save_dpns
);
7752 result
= get_name_for_var_field((Var
*) expr
, fieldno
,
7754 pop_ancestor_plan(dpns
, &save_dpns
);
7760 * If it's a Var of type RECORD, we have to find what the Var refers to;
7761 * if not, we can use get_expr_result_tupdesc().
7763 if (!IsA(var
, Var
) ||
7764 var
->vartype
!= RECORDOID
)
7766 tupleDesc
= get_expr_result_tupdesc((Node
*) var
, false);
7767 /* Got the tupdesc, so we can extract the field name */
7768 Assert(fieldno
>= 1 && fieldno
<= tupleDesc
->natts
);
7769 return NameStr(TupleDescAttr(tupleDesc
, fieldno
- 1)->attname
);
7772 /* Find appropriate nesting depth */
7773 netlevelsup
= var
->varlevelsup
+ levelsup
;
7774 if (netlevelsup
>= list_length(context
->namespaces
))
7775 elog(ERROR
, "bogus varlevelsup: %d offset %d",
7776 var
->varlevelsup
, levelsup
);
7777 dpns
= (deparse_namespace
*) list_nth(context
->namespaces
,
7781 * If we have a syntactic referent for the Var, and we're working from a
7782 * parse tree, prefer to use the syntactic referent. Otherwise, fall back
7783 * on the semantic referent. (See comments in get_variable().)
7785 if (var
->varnosyn
> 0 && dpns
->plan
== NULL
)
7787 varno
= var
->varnosyn
;
7788 varattno
= var
->varattnosyn
;
7793 varattno
= var
->varattno
;
7797 * Try to find the relevant RTE in this rtable. In a plan tree, it's
7798 * likely that varno is OUTER_VAR or INNER_VAR, in which case we must dig
7799 * down into the subplans, or INDEX_VAR, which is resolved similarly.
7801 * Note: unlike get_variable and resolve_special_varno, we need not worry
7802 * about inheritance mapping: a child Var should have the same datatype as
7803 * its parent, and here we're really only interested in the Var's type.
7805 if (varno
>= 1 && varno
<= list_length(dpns
->rtable
))
7807 rte
= rt_fetch(varno
, dpns
->rtable
);
7810 else if (varno
== OUTER_VAR
&& dpns
->outer_tlist
)
7813 deparse_namespace save_dpns
;
7816 tle
= get_tle_by_resno(dpns
->outer_tlist
, varattno
);
7818 elog(ERROR
, "bogus varattno for OUTER_VAR var: %d", varattno
);
7820 Assert(netlevelsup
== 0);
7821 push_child_plan(dpns
, dpns
->outer_plan
, &save_dpns
);
7823 result
= get_name_for_var_field((Var
*) tle
->expr
, fieldno
,
7826 pop_child_plan(dpns
, &save_dpns
);
7829 else if (varno
== INNER_VAR
&& dpns
->inner_tlist
)
7832 deparse_namespace save_dpns
;
7835 tle
= get_tle_by_resno(dpns
->inner_tlist
, varattno
);
7837 elog(ERROR
, "bogus varattno for INNER_VAR var: %d", varattno
);
7839 Assert(netlevelsup
== 0);
7840 push_child_plan(dpns
, dpns
->inner_plan
, &save_dpns
);
7842 result
= get_name_for_var_field((Var
*) tle
->expr
, fieldno
,
7845 pop_child_plan(dpns
, &save_dpns
);
7848 else if (varno
== INDEX_VAR
&& dpns
->index_tlist
)
7853 tle
= get_tle_by_resno(dpns
->index_tlist
, varattno
);
7855 elog(ERROR
, "bogus varattno for INDEX_VAR var: %d", varattno
);
7857 Assert(netlevelsup
== 0);
7859 result
= get_name_for_var_field((Var
*) tle
->expr
, fieldno
,
7866 elog(ERROR
, "bogus varno: %d", varno
);
7867 return NULL
; /* keep compiler quiet */
7870 if (attnum
== InvalidAttrNumber
)
7872 /* Var is whole-row reference to RTE, so select the right field */
7873 return get_rte_attribute_name(rte
, fieldno
);
7877 * This part has essentially the same logic as the parser's
7878 * expandRecordVariable() function, but we are dealing with a different
7879 * representation of the input context, and we only need one field name
7880 * not a TupleDesc. Also, we need special cases for finding subquery and
7881 * CTE subplans when deparsing Plan trees.
7883 expr
= (Node
*) var
; /* default if we can't drill down */
7885 switch (rte
->rtekind
)
7889 case RTE_NAMEDTUPLESTORE
:
7893 * This case should not occur: a column of a table, values list,
7894 * or ENR shouldn't have type RECORD. Fall through and fail (most
7895 * likely) at the bottom.
7899 /* Subselect-in-FROM: examine sub-select's output expr */
7903 TargetEntry
*ste
= get_tle_by_resno(rte
->subquery
->targetList
,
7906 if (ste
== NULL
|| ste
->resjunk
)
7907 elog(ERROR
, "subquery %s does not have attribute %d",
7908 rte
->eref
->aliasname
, attnum
);
7909 expr
= (Node
*) ste
->expr
;
7913 * Recurse into the sub-select to see what its Var
7914 * refers to. We have to build an additional level of
7915 * namespace to keep in step with varlevelsup in the
7916 * subselect; furthermore, the subquery RTE might be
7917 * from an outer query level, in which case the
7918 * namespace for the subselect must have that outer
7919 * level as parent namespace.
7921 List
*save_nslist
= context
->namespaces
;
7922 List
*parent_namespaces
;
7923 deparse_namespace mydpns
;
7926 parent_namespaces
= list_copy_tail(context
->namespaces
,
7929 set_deparse_for_query(&mydpns
, rte
->subquery
,
7932 context
->namespaces
= lcons(&mydpns
, parent_namespaces
);
7934 result
= get_name_for_var_field((Var
*) expr
, fieldno
,
7937 context
->namespaces
= save_nslist
;
7941 /* else fall through to inspect the expression */
7946 * We're deparsing a Plan tree so we don't have complete
7947 * RTE entries (in particular, rte->subquery is NULL). But
7948 * the only place we'd normally see a Var directly
7949 * referencing a SUBQUERY RTE is in a SubqueryScan plan
7950 * node, and we can look into the child plan's tlist
7951 * instead. An exception occurs if the subquery was
7952 * proven empty and optimized away: then we'd find such a
7953 * Var in a childless Result node, and there's nothing in
7954 * the plan tree that would let us figure out what it had
7955 * originally referenced. In that case, fall back on
7956 * printing "fN", analogously to the default column names
7960 deparse_namespace save_dpns
;
7963 if (!dpns
->inner_plan
)
7965 char *dummy_name
= palloc(32);
7967 Assert(dpns
->plan
&& IsA(dpns
->plan
, Result
));
7968 snprintf(dummy_name
, 32, "f%d", fieldno
);
7971 Assert(dpns
->plan
&& IsA(dpns
->plan
, SubqueryScan
));
7973 tle
= get_tle_by_resno(dpns
->inner_tlist
, attnum
);
7975 elog(ERROR
, "bogus varattno for subquery var: %d",
7977 Assert(netlevelsup
== 0);
7978 push_child_plan(dpns
, dpns
->inner_plan
, &save_dpns
);
7980 result
= get_name_for_var_field((Var
*) tle
->expr
, fieldno
,
7983 pop_child_plan(dpns
, &save_dpns
);
7989 /* Join RTE --- recursively inspect the alias variable */
7990 if (rte
->joinaliasvars
== NIL
)
7991 elog(ERROR
, "cannot decompile join alias var in plan tree");
7992 Assert(attnum
> 0 && attnum
<= list_length(rte
->joinaliasvars
));
7993 expr
= (Node
*) list_nth(rte
->joinaliasvars
, attnum
- 1);
7994 Assert(expr
!= NULL
);
7995 /* we intentionally don't strip implicit coercions here */
7997 return get_name_for_var_field((Var
*) expr
, fieldno
,
7998 var
->varlevelsup
+ levelsup
,
8000 /* else fall through to inspect the expression */
8006 * We couldn't get here unless a function is declared with one of
8007 * its result columns as RECORD, which is not allowed.
8011 /* CTE reference: examine subquery's output expr */
8013 CommonTableExpr
*cte
= NULL
;
8018 * Try to find the referenced CTE using the namespace stack.
8020 ctelevelsup
= rte
->ctelevelsup
+ netlevelsup
;
8021 if (ctelevelsup
>= list_length(context
->namespaces
))
8025 deparse_namespace
*ctedpns
;
8027 ctedpns
= (deparse_namespace
*)
8028 list_nth(context
->namespaces
, ctelevelsup
);
8029 foreach(lc
, ctedpns
->ctes
)
8031 cte
= (CommonTableExpr
*) lfirst(lc
);
8032 if (strcmp(cte
->ctename
, rte
->ctename
) == 0)
8038 Query
*ctequery
= (Query
*) cte
->ctequery
;
8039 TargetEntry
*ste
= get_tle_by_resno(GetCTETargetList(cte
),
8042 if (ste
== NULL
|| ste
->resjunk
)
8043 elog(ERROR
, "CTE %s does not have attribute %d",
8044 rte
->eref
->aliasname
, attnum
);
8045 expr
= (Node
*) ste
->expr
;
8049 * Recurse into the CTE to see what its Var refers to.
8050 * We have to build an additional level of namespace
8051 * to keep in step with varlevelsup in the CTE;
8052 * furthermore it could be an outer CTE (compare
8053 * SUBQUERY case above).
8055 List
*save_nslist
= context
->namespaces
;
8056 List
*parent_namespaces
;
8057 deparse_namespace mydpns
;
8060 parent_namespaces
= list_copy_tail(context
->namespaces
,
8063 set_deparse_for_query(&mydpns
, ctequery
,
8066 context
->namespaces
= lcons(&mydpns
, parent_namespaces
);
8068 result
= get_name_for_var_field((Var
*) expr
, fieldno
,
8071 context
->namespaces
= save_nslist
;
8075 /* else fall through to inspect the expression */
8080 * We're deparsing a Plan tree so we don't have a CTE
8081 * list. But the only places we'd normally see a Var
8082 * directly referencing a CTE RTE are in CteScan or
8083 * WorkTableScan plan nodes. For those cases,
8084 * set_deparse_plan arranged for dpns->inner_plan to be
8085 * the plan node that emits the CTE or RecursiveUnion
8086 * result, and we can look at its tlist instead. As
8087 * above, this can fail if the CTE has been proven empty,
8088 * in which case fall back to "fN".
8091 deparse_namespace save_dpns
;
8094 if (!dpns
->inner_plan
)
8096 char *dummy_name
= palloc(32);
8098 Assert(dpns
->plan
&& IsA(dpns
->plan
, Result
));
8099 snprintf(dummy_name
, 32, "f%d", fieldno
);
8102 Assert(dpns
->plan
&& (IsA(dpns
->plan
, CteScan
) ||
8103 IsA(dpns
->plan
, WorkTableScan
)));
8105 tle
= get_tle_by_resno(dpns
->inner_tlist
, attnum
);
8107 elog(ERROR
, "bogus varattno for subquery var: %d",
8109 Assert(netlevelsup
== 0);
8110 push_child_plan(dpns
, dpns
->inner_plan
, &save_dpns
);
8112 result
= get_name_for_var_field((Var
*) tle
->expr
, fieldno
,
8115 pop_child_plan(dpns
, &save_dpns
);
8123 * We now have an expression we can't expand any more, so see if
8124 * get_expr_result_tupdesc() can do anything with it.
8126 tupleDesc
= get_expr_result_tupdesc(expr
, false);
8127 /* Got the tupdesc, so we can extract the field name */
8128 Assert(fieldno
>= 1 && fieldno
<= tupleDesc
->natts
);
8129 return NameStr(TupleDescAttr(tupleDesc
, fieldno
- 1)->attname
);
8133 * Try to find the referenced expression for a PARAM_EXEC Param that might
8134 * reference a parameter supplied by an upper NestLoop or SubPlan plan node.
8136 * If successful, return the expression and set *dpns_p and *ancestor_cell_p
8137 * appropriately for calling push_ancestor_plan(). If no referent can be
8138 * found, return NULL.
8141 find_param_referent(Param
*param
, deparse_context
*context
,
8142 deparse_namespace
**dpns_p
, ListCell
**ancestor_cell_p
)
8144 /* Initialize output parameters to prevent compiler warnings */
8146 *ancestor_cell_p
= NULL
;
8149 * If it's a PARAM_EXEC parameter, look for a matching NestLoopParam or
8150 * SubPlan argument. This will necessarily be in some ancestor of the
8151 * current expression's Plan node.
8153 if (param
->paramkind
== PARAM_EXEC
)
8155 deparse_namespace
*dpns
;
8159 dpns
= (deparse_namespace
*) linitial(context
->namespaces
);
8160 child_plan
= dpns
->plan
;
8162 foreach(lc
, dpns
->ancestors
)
8164 Node
*ancestor
= (Node
*) lfirst(lc
);
8168 * NestLoops transmit params to their inner child only.
8170 if (IsA(ancestor
, NestLoop
) &&
8171 child_plan
== innerPlan(ancestor
))
8173 NestLoop
*nl
= (NestLoop
*) ancestor
;
8175 foreach(lc2
, nl
->nestParams
)
8177 NestLoopParam
*nlp
= (NestLoopParam
*) lfirst(lc2
);
8179 if (nlp
->paramno
== param
->paramid
)
8181 /* Found a match, so return it */
8183 *ancestor_cell_p
= lc
;
8184 return (Node
*) nlp
->paramval
;
8190 * If ancestor is a SubPlan, check the arguments it provides.
8192 if (IsA(ancestor
, SubPlan
))
8194 SubPlan
*subplan
= (SubPlan
*) ancestor
;
8198 forboth(lc3
, subplan
->parParam
, lc4
, subplan
->args
)
8200 int paramid
= lfirst_int(lc3
);
8201 Node
*arg
= (Node
*) lfirst(lc4
);
8203 if (paramid
== param
->paramid
)
8206 * Found a match, so return it. But, since Vars in
8207 * the arg are to be evaluated in the surrounding
8208 * context, we have to point to the next ancestor item
8209 * that is *not* a SubPlan.
8213 for_each_cell(rest
, dpns
->ancestors
,
8214 lnext(dpns
->ancestors
, lc
))
8216 Node
*ancestor2
= (Node
*) lfirst(rest
);
8218 if (!IsA(ancestor2
, SubPlan
))
8221 *ancestor_cell_p
= rest
;
8225 elog(ERROR
, "SubPlan cannot be outermost ancestor");
8229 /* SubPlan isn't a kind of Plan, so skip the rest */
8234 * We need not consider the ancestor's initPlan list, since
8235 * initplans never have any parParams.
8238 /* No luck, crawl up to next ancestor */
8239 child_plan
= (Plan
*) ancestor
;
8243 /* No referent found */
8248 * Try to find a subplan/initplan that emits the value for a PARAM_EXEC Param.
8250 * If successful, return the generating subplan/initplan and set *column_p
8251 * to the subplan's 0-based output column number.
8252 * Otherwise, return NULL.
8255 find_param_generator(Param
*param
, deparse_context
*context
, int *column_p
)
8257 /* Initialize output parameter to prevent compiler warnings */
8261 * If it's a PARAM_EXEC parameter, search the current plan node as well as
8262 * ancestor nodes looking for a subplan or initplan that emits the value
8263 * for the Param. It could appear in the setParams of an initplan or
8264 * MULTIEXPR_SUBLINK subplan, or in the paramIds of an ancestral SubPlan.
8266 if (param
->paramkind
== PARAM_EXEC
)
8269 deparse_namespace
*dpns
;
8272 dpns
= (deparse_namespace
*) linitial(context
->namespaces
);
8274 /* First check the innermost plan node's initplans */
8275 result
= find_param_generator_initplan(param
, dpns
->plan
, column_p
);
8280 * The plan's targetlist might contain MULTIEXPR_SUBLINK SubPlans,
8281 * which can be referenced by Params elsewhere in the targetlist.
8282 * (Such Params should always be in the same targetlist, so there's no
8283 * need to do this work at upper plan nodes.)
8285 foreach_node(TargetEntry
, tle
, dpns
->plan
->targetlist
)
8287 if (tle
->expr
&& IsA(tle
->expr
, SubPlan
))
8289 SubPlan
*subplan
= (SubPlan
*) tle
->expr
;
8291 if (subplan
->subLinkType
== MULTIEXPR_SUBLINK
)
8293 foreach_int(paramid
, subplan
->setParam
)
8295 if (paramid
== param
->paramid
)
8297 /* Found a match, so return it. */
8298 *column_p
= foreach_current_index(paramid
);
8306 /* No luck, so check the ancestor nodes */
8307 foreach(lc
, dpns
->ancestors
)
8309 Node
*ancestor
= (Node
*) lfirst(lc
);
8312 * If ancestor is a SubPlan, check the paramIds it provides.
8314 if (IsA(ancestor
, SubPlan
))
8316 SubPlan
*subplan
= (SubPlan
*) ancestor
;
8318 foreach_int(paramid
, subplan
->paramIds
)
8320 if (paramid
== param
->paramid
)
8322 /* Found a match, so return it. */
8323 *column_p
= foreach_current_index(paramid
);
8328 /* SubPlan isn't a kind of Plan, so skip the rest */
8333 * Otherwise, it's some kind of Plan node, so check its initplans.
8335 result
= find_param_generator_initplan(param
, (Plan
*) ancestor
,
8340 /* No luck, crawl up to next ancestor */
8344 /* No generator found */
8349 * Subroutine for find_param_generator: search one Plan node's initplans
8352 find_param_generator_initplan(Param
*param
, Plan
*plan
, int *column_p
)
8354 foreach_node(SubPlan
, subplan
, plan
->initPlan
)
8356 foreach_int(paramid
, subplan
->setParam
)
8358 if (paramid
== param
->paramid
)
8360 /* Found a match, so return it. */
8361 *column_p
= foreach_current_index(paramid
);
8370 * Display a Param appropriately.
8373 get_parameter(Param
*param
, deparse_context
*context
)
8376 deparse_namespace
*dpns
;
8377 ListCell
*ancestor_cell
;
8382 * If it's a PARAM_EXEC parameter, try to locate the expression from which
8383 * the parameter was computed. This stanza handles only cases in which
8384 * the Param represents an input to the subplan we are currently in.
8386 expr
= find_param_referent(param
, context
, &dpns
, &ancestor_cell
);
8389 /* Found a match, so print it */
8390 deparse_namespace save_dpns
;
8391 bool save_varprefix
;
8394 /* Switch attention to the ancestor plan node */
8395 push_ancestor_plan(dpns
, ancestor_cell
, &save_dpns
);
8398 * Force prefixing of Vars, since they won't belong to the relation
8399 * being scanned in the original plan node.
8401 save_varprefix
= context
->varprefix
;
8402 context
->varprefix
= true;
8405 * A Param's expansion is typically a Var, Aggref, GroupingFunc, or
8406 * upper-level Param, which wouldn't need extra parentheses.
8407 * Otherwise, insert parens to ensure the expression looks atomic.
8409 need_paren
= !(IsA(expr
, Var
) ||
8410 IsA(expr
, Aggref
) ||
8411 IsA(expr
, GroupingFunc
) ||
8414 appendStringInfoChar(context
->buf
, '(');
8416 get_rule_expr(expr
, context
, false);
8419 appendStringInfoChar(context
->buf
, ')');
8421 context
->varprefix
= save_varprefix
;
8423 pop_ancestor_plan(dpns
, &save_dpns
);
8429 * Alternatively, maybe it's a subplan output, which we print as a
8430 * reference to the subplan. (We could drill down into the subplan and
8431 * print the relevant targetlist expression, but that has been deemed too
8432 * confusing since it would violate normal SQL scope rules. Also, we're
8433 * relying on this reference to show that the testexpr containing the
8434 * Param has anything to do with that subplan at all.)
8436 subplan
= find_param_generator(param
, context
, &column
);
8439 appendStringInfo(context
->buf
, "(%s%s).col%d",
8440 subplan
->useHashTable
? "hashed " : "",
8441 subplan
->plan_name
, column
+ 1);
8447 * If it's an external parameter, see if the outermost namespace provides
8448 * function argument names.
8450 if (param
->paramkind
== PARAM_EXTERN
&& context
->namespaces
!= NIL
)
8452 dpns
= llast(context
->namespaces
);
8453 if (dpns
->argnames
&&
8454 param
->paramid
> 0 &&
8455 param
->paramid
<= dpns
->numargs
)
8457 char *argname
= dpns
->argnames
[param
->paramid
- 1];
8461 bool should_qualify
= false;
8465 * Qualify the parameter name if there are any other deparse
8466 * namespaces with range tables. This avoids qualifying in
8467 * trivial cases like "RETURN a + b", but makes it safe in all
8470 foreach(lc
, context
->namespaces
)
8472 deparse_namespace
*depns
= lfirst(lc
);
8474 if (depns
->rtable_names
!= NIL
)
8476 should_qualify
= true;
8482 appendStringInfoString(context
->buf
, quote_identifier(dpns
->funcname
));
8483 appendStringInfoChar(context
->buf
, '.');
8486 appendStringInfoString(context
->buf
, quote_identifier(argname
));
8493 * Not PARAM_EXEC, or couldn't find referent: just print $N.
8495 * It's a bug if we get here for anything except PARAM_EXTERN Params, but
8496 * in production builds printing $N seems more useful than failing.
8498 Assert(param
->paramkind
== PARAM_EXTERN
);
8500 appendStringInfo(context
->buf
, "$%d", param
->paramid
);
8504 * get_simple_binary_op_name
8506 * helper function for isSimpleNode
8507 * will return single char binary operator name, or NULL if it's not
8510 get_simple_binary_op_name(OpExpr
*expr
)
8512 List
*args
= expr
->args
;
8514 if (list_length(args
) == 2)
8516 /* binary operator */
8517 Node
*arg1
= (Node
*) linitial(args
);
8518 Node
*arg2
= (Node
*) lsecond(args
);
8521 op
= generate_operator_name(expr
->opno
, exprType(arg1
), exprType(arg2
));
8522 if (strlen(op
) == 1)
8530 * isSimpleNode - check if given node is simple (doesn't need parenthesizing)
8532 * true : simple in the context of parent node's type
8533 * false : not simple
8536 isSimpleNode(Node
*node
, Node
*parentNode
, int prettyFlags
)
8541 switch (nodeTag(node
))
8546 case T_CoerceToDomainValue
:
8547 case T_SetToDefault
:
8548 case T_CurrentOfExpr
:
8549 /* single words: always simple */
8552 case T_SubscriptingRef
:
8555 case T_CoalesceExpr
:
8557 case T_SQLValueFunction
:
8559 case T_NextValueExpr
:
8562 case T_GroupingFunc
:
8564 case T_MergeSupportFunc
:
8566 case T_JsonConstructorExpr
:
8568 /* function-like: name(..) or name[..] */
8571 /* CASE keywords act as parentheses */
8578 * appears simple since . has top precedence, unless parent is
8579 * T_FieldSelect itself!
8581 return !IsA(parentNode
, FieldSelect
);
8586 * treat like FieldSelect (probably doesn't matter)
8588 return !IsA(parentNode
, FieldStore
);
8590 case T_CoerceToDomain
:
8591 /* maybe simple, check args */
8592 return isSimpleNode((Node
*) ((CoerceToDomain
*) node
)->arg
,
8595 return isSimpleNode((Node
*) ((RelabelType
*) node
)->arg
,
8598 return isSimpleNode((Node
*) ((CoerceViaIO
*) node
)->arg
,
8600 case T_ArrayCoerceExpr
:
8601 return isSimpleNode((Node
*) ((ArrayCoerceExpr
*) node
)->arg
,
8603 case T_ConvertRowtypeExpr
:
8604 return isSimpleNode((Node
*) ((ConvertRowtypeExpr
*) node
)->arg
,
8609 /* depends on parent node type; needs further checking */
8610 if (prettyFlags
& PRETTYFLAG_PAREN
&& IsA(parentNode
, OpExpr
))
8613 const char *parentOp
;
8616 bool is_lopriparent
;
8617 bool is_hipriparent
;
8619 op
= get_simple_binary_op_name((OpExpr
*) node
);
8623 /* We know only the basic operators + - and * / % */
8624 is_lopriop
= (strchr("+-", *op
) != NULL
);
8625 is_hipriop
= (strchr("*/%", *op
) != NULL
);
8626 if (!(is_lopriop
|| is_hipriop
))
8629 parentOp
= get_simple_binary_op_name((OpExpr
*) parentNode
);
8633 is_lopriparent
= (strchr("+-", *parentOp
) != NULL
);
8634 is_hipriparent
= (strchr("*/%", *parentOp
) != NULL
);
8635 if (!(is_lopriparent
|| is_hipriparent
))
8638 if (is_hipriop
&& is_lopriparent
)
8639 return true; /* op binds tighter than parent */
8641 if (is_lopriop
&& is_hipriparent
)
8645 * Operators are same priority --- can skip parens only if
8646 * we have (a - b) - c, not a - (b - c).
8648 if (node
== (Node
*) linitial(((OpExpr
*) parentNode
)->args
))
8653 /* else do the same stuff as for T_SubLink et al. */
8660 case T_DistinctExpr
:
8661 case T_JsonIsPredicate
:
8662 switch (nodeTag(parentNode
))
8666 /* special handling for casts and COERCE_SQL_SYNTAX */
8667 CoercionForm type
= ((FuncExpr
*) parentNode
)->funcformat
;
8669 if (type
== COERCE_EXPLICIT_CAST
||
8670 type
== COERCE_IMPLICIT_CAST
||
8671 type
== COERCE_SQL_SYNTAX
)
8673 return true; /* own parentheses */
8675 case T_BoolExpr
: /* lower precedence */
8676 case T_SubscriptingRef
: /* other separators */
8677 case T_ArrayExpr
: /* other separators */
8678 case T_RowExpr
: /* other separators */
8679 case T_CoalesceExpr
: /* own parentheses */
8680 case T_MinMaxExpr
: /* own parentheses */
8681 case T_XmlExpr
: /* own parentheses */
8682 case T_NullIfExpr
: /* other separators */
8683 case T_Aggref
: /* own parentheses */
8684 case T_GroupingFunc
: /* own parentheses */
8685 case T_WindowFunc
: /* own parentheses */
8686 case T_CaseExpr
: /* other separators */
8693 switch (nodeTag(parentNode
))
8696 if (prettyFlags
& PRETTYFLAG_PAREN
)
8699 BoolExprType parentType
;
8701 type
= ((BoolExpr
*) node
)->boolop
;
8702 parentType
= ((BoolExpr
*) parentNode
)->boolop
;
8707 if (parentType
== AND_EXPR
|| parentType
== OR_EXPR
)
8711 if (parentType
== OR_EXPR
)
8719 /* special handling for casts and COERCE_SQL_SYNTAX */
8720 CoercionForm type
= ((FuncExpr
*) parentNode
)->funcformat
;
8722 if (type
== COERCE_EXPLICIT_CAST
||
8723 type
== COERCE_IMPLICIT_CAST
||
8724 type
== COERCE_SQL_SYNTAX
)
8726 return true; /* own parentheses */
8728 case T_SubscriptingRef
: /* other separators */
8729 case T_ArrayExpr
: /* other separators */
8730 case T_RowExpr
: /* other separators */
8731 case T_CoalesceExpr
: /* own parentheses */
8732 case T_MinMaxExpr
: /* own parentheses */
8733 case T_XmlExpr
: /* own parentheses */
8734 case T_NullIfExpr
: /* other separators */
8735 case T_Aggref
: /* own parentheses */
8736 case T_GroupingFunc
: /* own parentheses */
8737 case T_WindowFunc
: /* own parentheses */
8738 case T_CaseExpr
: /* other separators */
8739 case T_JsonExpr
: /* own parentheses */
8745 case T_JsonValueExpr
:
8746 /* maybe simple, check args */
8747 return isSimpleNode((Node
*) ((JsonValueExpr
*) node
)->raw_expr
,
8753 /* those we don't know: in dubio complexo */
8759 * appendContextKeyword - append a keyword to buffer
8761 * If prettyPrint is enabled, perform a line break, and adjust indentation.
8762 * Otherwise, just append the keyword.
8765 appendContextKeyword(deparse_context
*context
, const char *str
,
8766 int indentBefore
, int indentAfter
, int indentPlus
)
8768 StringInfo buf
= context
->buf
;
8770 if (PRETTY_INDENT(context
))
8774 context
->indentLevel
+= indentBefore
;
8776 /* remove any trailing spaces currently in the buffer ... */
8777 removeStringInfoSpaces(buf
);
8778 /* ... then add a newline and some spaces */
8779 appendStringInfoChar(buf
, '\n');
8781 if (context
->indentLevel
< PRETTYINDENT_LIMIT
)
8782 indentAmount
= Max(context
->indentLevel
, 0) + indentPlus
;
8786 * If we're indented more than PRETTYINDENT_LIMIT characters, try
8787 * to conserve horizontal space by reducing the per-level
8788 * indentation. For best results the scale factor here should
8789 * divide all the indent amounts that get added to indentLevel
8790 * (PRETTYINDENT_STD, etc). It's important that the indentation
8791 * not grow unboundedly, else deeply-nested trees use O(N^2)
8792 * whitespace; so we also wrap modulo PRETTYINDENT_LIMIT.
8794 indentAmount
= PRETTYINDENT_LIMIT
+
8795 (context
->indentLevel
- PRETTYINDENT_LIMIT
) /
8796 (PRETTYINDENT_STD
/ 2);
8797 indentAmount
%= PRETTYINDENT_LIMIT
;
8798 /* scale/wrap logic affects indentLevel, but not indentPlus */
8799 indentAmount
+= indentPlus
;
8801 appendStringInfoSpaces(buf
, indentAmount
);
8803 appendStringInfoString(buf
, str
);
8805 context
->indentLevel
+= indentAfter
;
8806 if (context
->indentLevel
< 0)
8807 context
->indentLevel
= 0;
8810 appendStringInfoString(buf
, str
);
8814 * removeStringInfoSpaces - delete trailing spaces from a buffer.
8816 * Possibly this should move to stringinfo.c at some point.
8819 removeStringInfoSpaces(StringInfo str
)
8821 while (str
->len
> 0 && str
->data
[str
->len
- 1] == ' ')
8822 str
->data
[--(str
->len
)] = '\0';
8827 * get_rule_expr_paren - deparse expr using get_rule_expr,
8828 * embracing the string with parentheses if necessary for prettyPrint.
8830 * Never embrace if prettyFlags=0, because it's done in the calling node.
8832 * Any node that does *not* embrace its argument node by sql syntax (with
8833 * parentheses, non-operator keywords like CASE/WHEN/ON, or comma etc) should
8834 * use get_rule_expr_paren instead of get_rule_expr so parentheses can be
8838 get_rule_expr_paren(Node
*node
, deparse_context
*context
,
8839 bool showimplicit
, Node
*parentNode
)
8843 need_paren
= PRETTY_PAREN(context
) &&
8844 !isSimpleNode(node
, parentNode
, context
->prettyFlags
);
8847 appendStringInfoChar(context
->buf
, '(');
8849 get_rule_expr(node
, context
, showimplicit
);
8852 appendStringInfoChar(context
->buf
, ')');
8856 get_json_behavior(JsonBehavior
*behavior
, deparse_context
*context
,
8860 * The order of array elements must correspond to the order of
8861 * JsonBehaviorType members.
8863 const char *behavior_names
[] =
8876 if ((int) behavior
->btype
< 0 || behavior
->btype
>= lengthof(behavior_names
))
8877 elog(ERROR
, "invalid json behavior type: %d", behavior
->btype
);
8879 appendStringInfoString(context
->buf
, behavior_names
[behavior
->btype
]);
8881 if (behavior
->btype
== JSON_BEHAVIOR_DEFAULT
)
8882 get_rule_expr(behavior
->expr
, context
, false);
8884 appendStringInfo(context
->buf
, " ON %s", on
);
8888 * get_json_expr_options
8890 * Parse back common options for JSON_QUERY, JSON_VALUE, JSON_EXISTS and
8891 * JSON_TABLE columns.
8894 get_json_expr_options(JsonExpr
*jsexpr
, deparse_context
*context
,
8895 JsonBehaviorType default_behavior
)
8897 if (jsexpr
->op
== JSON_QUERY_OP
)
8899 if (jsexpr
->wrapper
== JSW_CONDITIONAL
)
8900 appendStringInfoString(context
->buf
, " WITH CONDITIONAL WRAPPER");
8901 else if (jsexpr
->wrapper
== JSW_UNCONDITIONAL
)
8902 appendStringInfoString(context
->buf
, " WITH UNCONDITIONAL WRAPPER");
8904 else if (jsexpr
->wrapper
== JSW_NONE
|| jsexpr
->wrapper
== JSW_UNSPEC
)
8905 appendStringInfoString(context
->buf
, " WITHOUT WRAPPER");
8907 if (jsexpr
->omit_quotes
)
8908 appendStringInfoString(context
->buf
, " OMIT QUOTES");
8911 appendStringInfoString(context
->buf
, " KEEP QUOTES");
8914 if (jsexpr
->on_empty
&& jsexpr
->on_empty
->btype
!= default_behavior
)
8915 get_json_behavior(jsexpr
->on_empty
, context
, "EMPTY");
8917 if (jsexpr
->on_error
&& jsexpr
->on_error
->btype
!= default_behavior
)
8918 get_json_behavior(jsexpr
->on_error
, context
, "ERROR");
8922 * get_rule_expr - Parse back an expression
8924 * Note: showimplicit determines whether we display any implicit cast that
8925 * is present at the top of the expression tree. It is a passed argument,
8926 * not a field of the context struct, because we change the value as we
8927 * recurse down into the expression. In general we suppress implicit casts
8928 * when the result type is known with certainty (eg, the arguments of an
8929 * OR must be boolean). We display implicit casts for arguments of functions
8930 * and operators, since this is needed to be certain that the same function
8931 * or operator will be chosen when the expression is re-parsed.
8935 get_rule_expr(Node
*node
, deparse_context
*context
,
8938 StringInfo buf
= context
->buf
;
8943 /* Guard against excessively long or deeply-nested queries */
8944 CHECK_FOR_INTERRUPTS();
8945 check_stack_depth();
8948 * Each level of get_rule_expr must emit an indivisible term
8949 * (parenthesized if necessary) to ensure result is reparsed into the same
8950 * expression tree. The only exception is that when the input is a List,
8951 * we emit the component items comma-separated with no surrounding
8952 * decoration; this is convenient for most callers.
8954 switch (nodeTag(node
))
8957 (void) get_variable((Var
*) node
, 0, false, context
);
8961 get_const_expr((Const
*) node
, context
, 0);
8965 get_parameter((Param
*) node
, context
);
8969 get_agg_expr((Aggref
*) node
, context
, (Aggref
*) node
);
8972 case T_GroupingFunc
:
8974 GroupingFunc
*gexpr
= (GroupingFunc
*) node
;
8976 appendStringInfoString(buf
, "GROUPING(");
8977 get_rule_expr((Node
*) gexpr
->args
, context
, true);
8978 appendStringInfoChar(buf
, ')');
8983 get_windowfunc_expr((WindowFunc
*) node
, context
);
8986 case T_MergeSupportFunc
:
8987 appendStringInfoString(buf
, "MERGE_ACTION()");
8990 case T_SubscriptingRef
:
8992 SubscriptingRef
*sbsref
= (SubscriptingRef
*) node
;
8996 * If the argument is a CaseTestExpr, we must be inside a
8997 * FieldStore, ie, we are assigning to an element of an array
8998 * within a composite column. Since we already punted on
8999 * displaying the FieldStore's target information, just punt
9000 * here too, and display only the assignment source
9003 if (IsA(sbsref
->refexpr
, CaseTestExpr
))
9005 Assert(sbsref
->refassgnexpr
);
9006 get_rule_expr((Node
*) sbsref
->refassgnexpr
,
9007 context
, showimplicit
);
9012 * Parenthesize the argument unless it's a simple Var or a
9013 * FieldSelect. (In particular, if it's another
9014 * SubscriptingRef, we *must* parenthesize to avoid
9017 need_parens
= !IsA(sbsref
->refexpr
, Var
) &&
9018 !IsA(sbsref
->refexpr
, FieldSelect
);
9020 appendStringInfoChar(buf
, '(');
9021 get_rule_expr((Node
*) sbsref
->refexpr
, context
, showimplicit
);
9023 appendStringInfoChar(buf
, ')');
9026 * If there's a refassgnexpr, we want to print the node in the
9027 * format "container[subscripts] := refassgnexpr". This is
9028 * not legal SQL, so decompilation of INSERT or UPDATE
9029 * statements should always use processIndirection as part of
9030 * the statement-level syntax. We should only see this when
9031 * EXPLAIN tries to print the targetlist of a plan resulting
9032 * from such a statement.
9034 if (sbsref
->refassgnexpr
)
9039 * Use processIndirection to print this node's subscripts
9040 * as well as any additional field selections or
9041 * subscripting in immediate descendants. It returns the
9042 * RHS expr that is actually being "assigned".
9044 refassgnexpr
= processIndirection(node
, context
);
9045 appendStringInfoString(buf
, " := ");
9046 get_rule_expr(refassgnexpr
, context
, showimplicit
);
9050 /* Just an ordinary container fetch, so print subscripts */
9051 printSubscripts(sbsref
, context
);
9057 get_func_expr((FuncExpr
*) node
, context
, showimplicit
);
9060 case T_NamedArgExpr
:
9062 NamedArgExpr
*na
= (NamedArgExpr
*) node
;
9064 appendStringInfo(buf
, "%s => ", quote_identifier(na
->name
));
9065 get_rule_expr((Node
*) na
->arg
, context
, showimplicit
);
9070 get_oper_expr((OpExpr
*) node
, context
);
9073 case T_DistinctExpr
:
9075 DistinctExpr
*expr
= (DistinctExpr
*) node
;
9076 List
*args
= expr
->args
;
9077 Node
*arg1
= (Node
*) linitial(args
);
9078 Node
*arg2
= (Node
*) lsecond(args
);
9080 if (!PRETTY_PAREN(context
))
9081 appendStringInfoChar(buf
, '(');
9082 get_rule_expr_paren(arg1
, context
, true, node
);
9083 appendStringInfoString(buf
, " IS DISTINCT FROM ");
9084 get_rule_expr_paren(arg2
, context
, true, node
);
9085 if (!PRETTY_PAREN(context
))
9086 appendStringInfoChar(buf
, ')');
9092 NullIfExpr
*nullifexpr
= (NullIfExpr
*) node
;
9094 appendStringInfoString(buf
, "NULLIF(");
9095 get_rule_expr((Node
*) nullifexpr
->args
, context
, true);
9096 appendStringInfoChar(buf
, ')');
9100 case T_ScalarArrayOpExpr
:
9102 ScalarArrayOpExpr
*expr
= (ScalarArrayOpExpr
*) node
;
9103 List
*args
= expr
->args
;
9104 Node
*arg1
= (Node
*) linitial(args
);
9105 Node
*arg2
= (Node
*) lsecond(args
);
9107 if (!PRETTY_PAREN(context
))
9108 appendStringInfoChar(buf
, '(');
9109 get_rule_expr_paren(arg1
, context
, true, node
);
9110 appendStringInfo(buf
, " %s %s (",
9111 generate_operator_name(expr
->opno
,
9113 get_base_element_type(exprType(arg2
))),
9114 expr
->useOr
? "ANY" : "ALL");
9115 get_rule_expr_paren(arg2
, context
, true, node
);
9118 * There's inherent ambiguity in "x op ANY/ALL (y)" when y is
9119 * a bare sub-SELECT. Since we're here, the sub-SELECT must
9120 * be meant as a scalar sub-SELECT yielding an array value to
9121 * be used in ScalarArrayOpExpr; but the grammar will
9122 * preferentially interpret such a construct as an ANY/ALL
9123 * SubLink. To prevent misparsing the output that way, insert
9124 * a dummy coercion (which will be stripped by parse analysis,
9125 * so no inefficiency is added in dump and reload). This is
9126 * indeed most likely what the user wrote to get the construct
9127 * accepted in the first place.
9129 if (IsA(arg2
, SubLink
) &&
9130 ((SubLink
*) arg2
)->subLinkType
== EXPR_SUBLINK
)
9131 appendStringInfo(buf
, "::%s",
9132 format_type_with_typemod(exprType(arg2
),
9134 appendStringInfoChar(buf
, ')');
9135 if (!PRETTY_PAREN(context
))
9136 appendStringInfoChar(buf
, ')');
9142 BoolExpr
*expr
= (BoolExpr
*) node
;
9143 Node
*first_arg
= linitial(expr
->args
);
9146 switch (expr
->boolop
)
9149 if (!PRETTY_PAREN(context
))
9150 appendStringInfoChar(buf
, '(');
9151 get_rule_expr_paren(first_arg
, context
,
9153 for_each_from(arg
, expr
->args
, 1)
9155 appendStringInfoString(buf
, " AND ");
9156 get_rule_expr_paren((Node
*) lfirst(arg
), context
,
9159 if (!PRETTY_PAREN(context
))
9160 appendStringInfoChar(buf
, ')');
9164 if (!PRETTY_PAREN(context
))
9165 appendStringInfoChar(buf
, '(');
9166 get_rule_expr_paren(first_arg
, context
,
9168 for_each_from(arg
, expr
->args
, 1)
9170 appendStringInfoString(buf
, " OR ");
9171 get_rule_expr_paren((Node
*) lfirst(arg
), context
,
9174 if (!PRETTY_PAREN(context
))
9175 appendStringInfoChar(buf
, ')');
9179 if (!PRETTY_PAREN(context
))
9180 appendStringInfoChar(buf
, '(');
9181 appendStringInfoString(buf
, "NOT ");
9182 get_rule_expr_paren(first_arg
, context
,
9184 if (!PRETTY_PAREN(context
))
9185 appendStringInfoChar(buf
, ')');
9189 elog(ERROR
, "unrecognized boolop: %d",
9190 (int) expr
->boolop
);
9196 get_sublink_expr((SubLink
*) node
, context
);
9201 SubPlan
*subplan
= (SubPlan
*) node
;
9204 * We cannot see an already-planned subplan in rule deparsing,
9205 * only while EXPLAINing a query plan. We don't try to
9206 * reconstruct the original SQL, just reference the subplan
9207 * that appears elsewhere in EXPLAIN's result. It does seem
9208 * useful to show the subLinkType and testexpr (if any), and
9209 * we also note whether the subplan will be hashed.
9211 switch (subplan
->subLinkType
)
9213 case EXISTS_SUBLINK
:
9214 appendStringInfoString(buf
, "EXISTS(");
9215 Assert(subplan
->testexpr
== NULL
);
9218 appendStringInfoString(buf
, "(ALL ");
9219 Assert(subplan
->testexpr
!= NULL
);
9222 appendStringInfoString(buf
, "(ANY ");
9223 Assert(subplan
->testexpr
!= NULL
);
9225 case ROWCOMPARE_SUBLINK
:
9226 /* Parenthesizing the testexpr seems sufficient */
9227 appendStringInfoChar(buf
, '(');
9228 Assert(subplan
->testexpr
!= NULL
);
9231 /* No need to decorate these subplan references */
9232 appendStringInfoChar(buf
, '(');
9233 Assert(subplan
->testexpr
== NULL
);
9235 case MULTIEXPR_SUBLINK
:
9236 /* MULTIEXPR isn't executed in the normal way */
9237 appendStringInfoString(buf
, "(rescan ");
9238 Assert(subplan
->testexpr
== NULL
);
9241 appendStringInfoString(buf
, "ARRAY(");
9242 Assert(subplan
->testexpr
== NULL
);
9245 /* This case is unreachable within expressions */
9246 appendStringInfoString(buf
, "CTE(");
9247 Assert(subplan
->testexpr
== NULL
);
9251 if (subplan
->testexpr
!= NULL
)
9253 deparse_namespace
*dpns
;
9256 * Push SubPlan into ancestors list while deparsing
9257 * testexpr, so that we can handle PARAM_EXEC references
9258 * to the SubPlan's paramIds. (This makes it look like
9259 * the SubPlan is an "ancestor" of the current plan node,
9260 * which is a little weird, but it does no harm.) In this
9261 * path, we don't need to mention the SubPlan explicitly,
9262 * because the referencing Params will show its existence.
9264 dpns
= (deparse_namespace
*) linitial(context
->namespaces
);
9265 dpns
->ancestors
= lcons(subplan
, dpns
->ancestors
);
9267 get_rule_expr(subplan
->testexpr
, context
, showimplicit
);
9268 appendStringInfoChar(buf
, ')');
9270 dpns
->ancestors
= list_delete_first(dpns
->ancestors
);
9274 /* No referencing Params, so show the SubPlan's name */
9275 if (subplan
->useHashTable
)
9276 appendStringInfo(buf
, "hashed %s)", subplan
->plan_name
);
9278 appendStringInfo(buf
, "%s)", subplan
->plan_name
);
9283 case T_AlternativeSubPlan
:
9285 AlternativeSubPlan
*asplan
= (AlternativeSubPlan
*) node
;
9289 * This case cannot be reached in normal usage, since no
9290 * AlternativeSubPlan can appear either in parsetrees or
9291 * finished plan trees. We keep it just in case somebody
9292 * wants to use this code to print planner data structures.
9294 appendStringInfoString(buf
, "(alternatives: ");
9295 foreach(lc
, asplan
->subplans
)
9297 SubPlan
*splan
= lfirst_node(SubPlan
, lc
);
9299 if (splan
->useHashTable
)
9300 appendStringInfo(buf
, "hashed %s", splan
->plan_name
);
9302 appendStringInfoString(buf
, splan
->plan_name
);
9303 if (lnext(asplan
->subplans
, lc
))
9304 appendStringInfoString(buf
, " or ");
9306 appendStringInfoChar(buf
, ')');
9312 FieldSelect
*fselect
= (FieldSelect
*) node
;
9313 Node
*arg
= (Node
*) fselect
->arg
;
9314 int fno
= fselect
->fieldnum
;
9315 const char *fieldname
;
9319 * Parenthesize the argument unless it's an SubscriptingRef or
9320 * another FieldSelect. Note in particular that it would be
9321 * WRONG to not parenthesize a Var argument; simplicity is not
9322 * the issue here, having the right number of names is.
9324 need_parens
= !IsA(arg
, SubscriptingRef
) &&
9325 !IsA(arg
, FieldSelect
);
9327 appendStringInfoChar(buf
, '(');
9328 get_rule_expr(arg
, context
, true);
9330 appendStringInfoChar(buf
, ')');
9333 * Get and print the field name.
9335 fieldname
= get_name_for_var_field((Var
*) arg
, fno
,
9337 appendStringInfo(buf
, ".%s", quote_identifier(fieldname
));
9343 FieldStore
*fstore
= (FieldStore
*) node
;
9347 * There is no good way to represent a FieldStore as real SQL,
9348 * so decompilation of INSERT or UPDATE statements should
9349 * always use processIndirection as part of the
9350 * statement-level syntax. We should only get here when
9351 * EXPLAIN tries to print the targetlist of a plan resulting
9352 * from such a statement. The plan case is even harder than
9353 * ordinary rules would be, because the planner tries to
9354 * collapse multiple assignments to the same field or subfield
9355 * into one FieldStore; so we can see a list of target fields
9356 * not just one, and the arguments could be FieldStores
9357 * themselves. We don't bother to try to print the target
9358 * field names; we just print the source arguments, with a
9359 * ROW() around them if there's more than one. This isn't
9360 * terribly complete, but it's probably good enough for
9361 * EXPLAIN's purposes; especially since anything more would be
9362 * either hopelessly confusing or an even poorer
9363 * representation of what the plan is actually doing.
9365 need_parens
= (list_length(fstore
->newvals
) != 1);
9367 appendStringInfoString(buf
, "ROW(");
9368 get_rule_expr((Node
*) fstore
->newvals
, context
, showimplicit
);
9370 appendStringInfoChar(buf
, ')');
9376 RelabelType
*relabel
= (RelabelType
*) node
;
9377 Node
*arg
= (Node
*) relabel
->arg
;
9379 if (relabel
->relabelformat
== COERCE_IMPLICIT_CAST
&&
9382 /* don't show the implicit cast */
9383 get_rule_expr_paren(arg
, context
, false, node
);
9387 get_coercion_expr(arg
, context
,
9388 relabel
->resulttype
,
9389 relabel
->resulttypmod
,
9397 CoerceViaIO
*iocoerce
= (CoerceViaIO
*) node
;
9398 Node
*arg
= (Node
*) iocoerce
->arg
;
9400 if (iocoerce
->coerceformat
== COERCE_IMPLICIT_CAST
&&
9403 /* don't show the implicit cast */
9404 get_rule_expr_paren(arg
, context
, false, node
);
9408 get_coercion_expr(arg
, context
,
9409 iocoerce
->resulttype
,
9416 case T_ArrayCoerceExpr
:
9418 ArrayCoerceExpr
*acoerce
= (ArrayCoerceExpr
*) node
;
9419 Node
*arg
= (Node
*) acoerce
->arg
;
9421 if (acoerce
->coerceformat
== COERCE_IMPLICIT_CAST
&&
9424 /* don't show the implicit cast */
9425 get_rule_expr_paren(arg
, context
, false, node
);
9429 get_coercion_expr(arg
, context
,
9430 acoerce
->resulttype
,
9431 acoerce
->resulttypmod
,
9437 case T_ConvertRowtypeExpr
:
9439 ConvertRowtypeExpr
*convert
= (ConvertRowtypeExpr
*) node
;
9440 Node
*arg
= (Node
*) convert
->arg
;
9442 if (convert
->convertformat
== COERCE_IMPLICIT_CAST
&&
9445 /* don't show the implicit cast */
9446 get_rule_expr_paren(arg
, context
, false, node
);
9450 get_coercion_expr(arg
, context
,
9451 convert
->resulttype
, -1,
9459 CollateExpr
*collate
= (CollateExpr
*) node
;
9460 Node
*arg
= (Node
*) collate
->arg
;
9462 if (!PRETTY_PAREN(context
))
9463 appendStringInfoChar(buf
, '(');
9464 get_rule_expr_paren(arg
, context
, showimplicit
, node
);
9465 appendStringInfo(buf
, " COLLATE %s",
9466 generate_collation_name(collate
->collOid
));
9467 if (!PRETTY_PAREN(context
))
9468 appendStringInfoChar(buf
, ')');
9474 CaseExpr
*caseexpr
= (CaseExpr
*) node
;
9477 appendContextKeyword(context
, "CASE",
9478 0, PRETTYINDENT_VAR
, 0);
9481 appendStringInfoChar(buf
, ' ');
9482 get_rule_expr((Node
*) caseexpr
->arg
, context
, true);
9484 foreach(temp
, caseexpr
->args
)
9486 CaseWhen
*when
= (CaseWhen
*) lfirst(temp
);
9487 Node
*w
= (Node
*) when
->expr
;
9492 * The parser should have produced WHEN clauses of the
9493 * form "CaseTestExpr = RHS", possibly with an
9494 * implicit coercion inserted above the CaseTestExpr.
9495 * For accurate decompilation of rules it's essential
9496 * that we show just the RHS. However in an
9497 * expression that's been through the optimizer, the
9498 * WHEN clause could be almost anything (since the
9499 * equality operator could have been expanded into an
9500 * inline function). If we don't recognize the form
9501 * of the WHEN clause, just punt and display it as-is.
9505 List
*args
= ((OpExpr
*) w
)->args
;
9507 if (list_length(args
) == 2 &&
9508 IsA(strip_implicit_coercions(linitial(args
)),
9510 w
= (Node
*) lsecond(args
);
9514 if (!PRETTY_INDENT(context
))
9515 appendStringInfoChar(buf
, ' ');
9516 appendContextKeyword(context
, "WHEN ",
9518 get_rule_expr(w
, context
, false);
9519 appendStringInfoString(buf
, " THEN ");
9520 get_rule_expr((Node
*) when
->result
, context
, true);
9522 if (!PRETTY_INDENT(context
))
9523 appendStringInfoChar(buf
, ' ');
9524 appendContextKeyword(context
, "ELSE ",
9526 get_rule_expr((Node
*) caseexpr
->defresult
, context
, true);
9527 if (!PRETTY_INDENT(context
))
9528 appendStringInfoChar(buf
, ' ');
9529 appendContextKeyword(context
, "END",
9530 -PRETTYINDENT_VAR
, 0, 0);
9534 case T_CaseTestExpr
:
9537 * Normally we should never get here, since for expressions
9538 * that can contain this node type we attempt to avoid
9539 * recursing to it. But in an optimized expression we might
9540 * be unable to avoid that (see comments for CaseExpr). If we
9541 * do see one, print it as CASE_TEST_EXPR.
9543 appendStringInfoString(buf
, "CASE_TEST_EXPR");
9549 ArrayExpr
*arrayexpr
= (ArrayExpr
*) node
;
9551 appendStringInfoString(buf
, "ARRAY[");
9552 get_rule_expr((Node
*) arrayexpr
->elements
, context
, true);
9553 appendStringInfoChar(buf
, ']');
9556 * If the array isn't empty, we assume its elements are
9557 * coerced to the desired type. If it's empty, though, we
9558 * need an explicit coercion to the array type.
9560 if (arrayexpr
->elements
== NIL
)
9561 appendStringInfo(buf
, "::%s",
9562 format_type_with_typemod(arrayexpr
->array_typeid
, -1));
9568 RowExpr
*rowexpr
= (RowExpr
*) node
;
9569 TupleDesc tupdesc
= NULL
;
9575 * If it's a named type and not RECORD, we may have to skip
9576 * dropped columns and/or claim there are NULLs for added
9579 if (rowexpr
->row_typeid
!= RECORDOID
)
9581 tupdesc
= lookup_rowtype_tupdesc(rowexpr
->row_typeid
, -1);
9582 Assert(list_length(rowexpr
->args
) <= tupdesc
->natts
);
9586 * SQL99 allows "ROW" to be omitted when there is more than
9587 * one column, but for simplicity we always print it.
9589 appendStringInfoString(buf
, "ROW(");
9592 foreach(arg
, rowexpr
->args
)
9594 Node
*e
= (Node
*) lfirst(arg
);
9596 if (tupdesc
== NULL
||
9597 !TupleDescAttr(tupdesc
, i
)->attisdropped
)
9599 appendStringInfoString(buf
, sep
);
9600 /* Whole-row Vars need special treatment here */
9601 get_rule_expr_toplevel(e
, context
, true);
9606 if (tupdesc
!= NULL
)
9608 while (i
< tupdesc
->natts
)
9610 if (!TupleDescAttr(tupdesc
, i
)->attisdropped
)
9612 appendStringInfoString(buf
, sep
);
9613 appendStringInfoString(buf
, "NULL");
9619 ReleaseTupleDesc(tupdesc
);
9621 appendStringInfoChar(buf
, ')');
9622 if (rowexpr
->row_format
== COERCE_EXPLICIT_CAST
)
9623 appendStringInfo(buf
, "::%s",
9624 format_type_with_typemod(rowexpr
->row_typeid
, -1));
9628 case T_RowCompareExpr
:
9630 RowCompareExpr
*rcexpr
= (RowCompareExpr
*) node
;
9633 * SQL99 allows "ROW" to be omitted when there is more than
9634 * one column, but for simplicity we always print it. Within
9635 * a ROW expression, whole-row Vars need special treatment, so
9636 * use get_rule_list_toplevel.
9638 appendStringInfoString(buf
, "(ROW(");
9639 get_rule_list_toplevel(rcexpr
->largs
, context
, true);
9642 * We assume that the name of the first-column operator will
9643 * do for all the rest too. This is definitely open to
9644 * failure, eg if some but not all operators were renamed
9645 * since the construct was parsed, but there seems no way to
9648 appendStringInfo(buf
, ") %s ROW(",
9649 generate_operator_name(linitial_oid(rcexpr
->opnos
),
9650 exprType(linitial(rcexpr
->largs
)),
9651 exprType(linitial(rcexpr
->rargs
))));
9652 get_rule_list_toplevel(rcexpr
->rargs
, context
, true);
9653 appendStringInfoString(buf
, "))");
9657 case T_CoalesceExpr
:
9659 CoalesceExpr
*coalesceexpr
= (CoalesceExpr
*) node
;
9661 appendStringInfoString(buf
, "COALESCE(");
9662 get_rule_expr((Node
*) coalesceexpr
->args
, context
, true);
9663 appendStringInfoChar(buf
, ')');
9669 MinMaxExpr
*minmaxexpr
= (MinMaxExpr
*) node
;
9671 switch (minmaxexpr
->op
)
9674 appendStringInfoString(buf
, "GREATEST(");
9677 appendStringInfoString(buf
, "LEAST(");
9680 get_rule_expr((Node
*) minmaxexpr
->args
, context
, true);
9681 appendStringInfoChar(buf
, ')');
9685 case T_SQLValueFunction
:
9687 SQLValueFunction
*svf
= (SQLValueFunction
*) node
;
9690 * Note: this code knows that typmod for time, timestamp, and
9691 * timestamptz just prints as integer.
9695 case SVFOP_CURRENT_DATE
:
9696 appendStringInfoString(buf
, "CURRENT_DATE");
9698 case SVFOP_CURRENT_TIME
:
9699 appendStringInfoString(buf
, "CURRENT_TIME");
9701 case SVFOP_CURRENT_TIME_N
:
9702 appendStringInfo(buf
, "CURRENT_TIME(%d)", svf
->typmod
);
9704 case SVFOP_CURRENT_TIMESTAMP
:
9705 appendStringInfoString(buf
, "CURRENT_TIMESTAMP");
9707 case SVFOP_CURRENT_TIMESTAMP_N
:
9708 appendStringInfo(buf
, "CURRENT_TIMESTAMP(%d)",
9711 case SVFOP_LOCALTIME
:
9712 appendStringInfoString(buf
, "LOCALTIME");
9714 case SVFOP_LOCALTIME_N
:
9715 appendStringInfo(buf
, "LOCALTIME(%d)", svf
->typmod
);
9717 case SVFOP_LOCALTIMESTAMP
:
9718 appendStringInfoString(buf
, "LOCALTIMESTAMP");
9720 case SVFOP_LOCALTIMESTAMP_N
:
9721 appendStringInfo(buf
, "LOCALTIMESTAMP(%d)",
9724 case SVFOP_CURRENT_ROLE
:
9725 appendStringInfoString(buf
, "CURRENT_ROLE");
9727 case SVFOP_CURRENT_USER
:
9728 appendStringInfoString(buf
, "CURRENT_USER");
9731 appendStringInfoString(buf
, "USER");
9733 case SVFOP_SESSION_USER
:
9734 appendStringInfoString(buf
, "SESSION_USER");
9736 case SVFOP_CURRENT_CATALOG
:
9737 appendStringInfoString(buf
, "CURRENT_CATALOG");
9739 case SVFOP_CURRENT_SCHEMA
:
9740 appendStringInfoString(buf
, "CURRENT_SCHEMA");
9748 XmlExpr
*xexpr
= (XmlExpr
*) node
;
9749 bool needcomma
= false;
9757 appendStringInfoString(buf
, "XMLCONCAT(");
9760 appendStringInfoString(buf
, "XMLELEMENT(");
9763 appendStringInfoString(buf
, "XMLFOREST(");
9766 appendStringInfoString(buf
, "XMLPARSE(");
9769 appendStringInfoString(buf
, "XMLPI(");
9772 appendStringInfoString(buf
, "XMLROOT(");
9774 case IS_XMLSERIALIZE
:
9775 appendStringInfoString(buf
, "XMLSERIALIZE(");
9780 if (xexpr
->op
== IS_XMLPARSE
|| xexpr
->op
== IS_XMLSERIALIZE
)
9782 if (xexpr
->xmloption
== XMLOPTION_DOCUMENT
)
9783 appendStringInfoString(buf
, "DOCUMENT ");
9785 appendStringInfoString(buf
, "CONTENT ");
9789 appendStringInfo(buf
, "NAME %s",
9790 quote_identifier(map_xml_name_to_sql_identifier(xexpr
->name
)));
9793 if (xexpr
->named_args
)
9795 if (xexpr
->op
!= IS_XMLFOREST
)
9798 appendStringInfoString(buf
, ", ");
9799 appendStringInfoString(buf
, "XMLATTRIBUTES(");
9802 forboth(arg
, xexpr
->named_args
, narg
, xexpr
->arg_names
)
9804 Node
*e
= (Node
*) lfirst(arg
);
9805 char *argname
= strVal(lfirst(narg
));
9808 appendStringInfoString(buf
, ", ");
9809 get_rule_expr((Node
*) e
, context
, true);
9810 appendStringInfo(buf
, " AS %s",
9811 quote_identifier(map_xml_name_to_sql_identifier(argname
)));
9814 if (xexpr
->op
!= IS_XMLFOREST
)
9815 appendStringInfoChar(buf
, ')');
9820 appendStringInfoString(buf
, ", ");
9827 case IS_XMLSERIALIZE
:
9828 /* no extra decoration needed */
9829 get_rule_expr((Node
*) xexpr
->args
, context
, true);
9832 Assert(list_length(xexpr
->args
) == 2);
9834 get_rule_expr((Node
*) linitial(xexpr
->args
),
9837 con
= lsecond_node(Const
, xexpr
->args
);
9838 Assert(!con
->constisnull
);
9839 if (DatumGetBool(con
->constvalue
))
9840 appendStringInfoString(buf
,
9841 " PRESERVE WHITESPACE");
9843 appendStringInfoString(buf
,
9844 " STRIP WHITESPACE");
9847 Assert(list_length(xexpr
->args
) == 3);
9849 get_rule_expr((Node
*) linitial(xexpr
->args
),
9852 appendStringInfoString(buf
, ", VERSION ");
9853 con
= (Const
*) lsecond(xexpr
->args
);
9854 if (IsA(con
, Const
) &&
9856 appendStringInfoString(buf
, "NO VALUE");
9858 get_rule_expr((Node
*) con
, context
, false);
9860 con
= lthird_node(Const
, xexpr
->args
);
9861 if (con
->constisnull
)
9862 /* suppress STANDALONE NO VALUE */ ;
9865 switch (DatumGetInt32(con
->constvalue
))
9867 case XML_STANDALONE_YES
:
9868 appendStringInfoString(buf
,
9869 ", STANDALONE YES");
9871 case XML_STANDALONE_NO
:
9872 appendStringInfoString(buf
,
9875 case XML_STANDALONE_NO_VALUE
:
9876 appendStringInfoString(buf
,
9877 ", STANDALONE NO VALUE");
9885 get_rule_expr_paren((Node
*) xexpr
->args
, context
, false, node
);
9889 if (xexpr
->op
== IS_XMLSERIALIZE
)
9890 appendStringInfo(buf
, " AS %s",
9891 format_type_with_typemod(xexpr
->type
,
9893 if (xexpr
->op
== IS_DOCUMENT
)
9894 appendStringInfoString(buf
, " IS DOCUMENT");
9896 appendStringInfoChar(buf
, ')');
9902 NullTest
*ntest
= (NullTest
*) node
;
9904 if (!PRETTY_PAREN(context
))
9905 appendStringInfoChar(buf
, '(');
9906 get_rule_expr_paren((Node
*) ntest
->arg
, context
, true, node
);
9909 * For scalar inputs, we prefer to print as IS [NOT] NULL,
9910 * which is shorter and traditional. If it's a rowtype input
9911 * but we're applying a scalar test, must print IS [NOT]
9912 * DISTINCT FROM NULL to be semantically correct.
9914 if (ntest
->argisrow
||
9915 !type_is_rowtype(exprType((Node
*) ntest
->arg
)))
9917 switch (ntest
->nulltesttype
)
9920 appendStringInfoString(buf
, " IS NULL");
9923 appendStringInfoString(buf
, " IS NOT NULL");
9926 elog(ERROR
, "unrecognized nulltesttype: %d",
9927 (int) ntest
->nulltesttype
);
9932 switch (ntest
->nulltesttype
)
9935 appendStringInfoString(buf
, " IS NOT DISTINCT FROM NULL");
9938 appendStringInfoString(buf
, " IS DISTINCT FROM NULL");
9941 elog(ERROR
, "unrecognized nulltesttype: %d",
9942 (int) ntest
->nulltesttype
);
9945 if (!PRETTY_PAREN(context
))
9946 appendStringInfoChar(buf
, ')');
9952 BooleanTest
*btest
= (BooleanTest
*) node
;
9954 if (!PRETTY_PAREN(context
))
9955 appendStringInfoChar(buf
, '(');
9956 get_rule_expr_paren((Node
*) btest
->arg
, context
, false, node
);
9957 switch (btest
->booltesttype
)
9960 appendStringInfoString(buf
, " IS TRUE");
9963 appendStringInfoString(buf
, " IS NOT TRUE");
9966 appendStringInfoString(buf
, " IS FALSE");
9969 appendStringInfoString(buf
, " IS NOT FALSE");
9972 appendStringInfoString(buf
, " IS UNKNOWN");
9974 case IS_NOT_UNKNOWN
:
9975 appendStringInfoString(buf
, " IS NOT UNKNOWN");
9978 elog(ERROR
, "unrecognized booltesttype: %d",
9979 (int) btest
->booltesttype
);
9981 if (!PRETTY_PAREN(context
))
9982 appendStringInfoChar(buf
, ')');
9986 case T_CoerceToDomain
:
9988 CoerceToDomain
*ctest
= (CoerceToDomain
*) node
;
9989 Node
*arg
= (Node
*) ctest
->arg
;
9991 if (ctest
->coercionformat
== COERCE_IMPLICIT_CAST
&&
9994 /* don't show the implicit cast */
9995 get_rule_expr(arg
, context
, false);
9999 get_coercion_expr(arg
, context
,
10001 ctest
->resulttypmod
,
10007 case T_CoerceToDomainValue
:
10008 appendStringInfoString(buf
, "VALUE");
10011 case T_SetToDefault
:
10012 appendStringInfoString(buf
, "DEFAULT");
10015 case T_CurrentOfExpr
:
10017 CurrentOfExpr
*cexpr
= (CurrentOfExpr
*) node
;
10019 if (cexpr
->cursor_name
)
10020 appendStringInfo(buf
, "CURRENT OF %s",
10021 quote_identifier(cexpr
->cursor_name
));
10023 appendStringInfo(buf
, "CURRENT OF $%d",
10024 cexpr
->cursor_param
);
10028 case T_NextValueExpr
:
10030 NextValueExpr
*nvexpr
= (NextValueExpr
*) node
;
10033 * This isn't exactly nextval(), but that seems close enough
10034 * for EXPLAIN's purposes.
10036 appendStringInfoString(buf
, "nextval(");
10037 simple_quote_literal(buf
,
10038 generate_relation_name(nvexpr
->seqid
,
10040 appendStringInfoChar(buf
, ')');
10044 case T_InferenceElem
:
10046 InferenceElem
*iexpr
= (InferenceElem
*) node
;
10047 bool save_varprefix
;
10051 * InferenceElem can only refer to target relation, so a
10052 * prefix is not useful, and indeed would cause parse errors.
10054 save_varprefix
= context
->varprefix
;
10055 context
->varprefix
= false;
10058 * Parenthesize the element unless it's a simple Var or a bare
10059 * function call. Follows pg_get_indexdef_worker().
10061 need_parens
= !IsA(iexpr
->expr
, Var
);
10062 if (IsA(iexpr
->expr
, FuncExpr
) &&
10063 ((FuncExpr
*) iexpr
->expr
)->funcformat
==
10064 COERCE_EXPLICIT_CALL
)
10065 need_parens
= false;
10068 appendStringInfoChar(buf
, '(');
10069 get_rule_expr((Node
*) iexpr
->expr
,
10072 appendStringInfoChar(buf
, ')');
10074 context
->varprefix
= save_varprefix
;
10076 if (iexpr
->infercollid
)
10077 appendStringInfo(buf
, " COLLATE %s",
10078 generate_collation_name(iexpr
->infercollid
));
10080 /* Add the operator class name, if not default */
10081 if (iexpr
->inferopclass
)
10083 Oid inferopclass
= iexpr
->inferopclass
;
10084 Oid inferopcinputtype
= get_opclass_input_type(iexpr
->inferopclass
);
10086 get_opclass_name(inferopclass
, inferopcinputtype
, buf
);
10091 case T_PartitionBoundSpec
:
10093 PartitionBoundSpec
*spec
= (PartitionBoundSpec
*) node
;
10097 if (spec
->is_default
)
10099 appendStringInfoString(buf
, "DEFAULT");
10103 switch (spec
->strategy
)
10105 case PARTITION_STRATEGY_HASH
:
10106 Assert(spec
->modulus
> 0 && spec
->remainder
>= 0);
10107 Assert(spec
->modulus
> spec
->remainder
);
10109 appendStringInfoString(buf
, "FOR VALUES");
10110 appendStringInfo(buf
, " WITH (modulus %d, remainder %d)",
10111 spec
->modulus
, spec
->remainder
);
10114 case PARTITION_STRATEGY_LIST
:
10115 Assert(spec
->listdatums
!= NIL
);
10117 appendStringInfoString(buf
, "FOR VALUES IN (");
10119 foreach(cell
, spec
->listdatums
)
10121 Const
*val
= lfirst_node(Const
, cell
);
10123 appendStringInfoString(buf
, sep
);
10124 get_const_expr(val
, context
, -1);
10128 appendStringInfoChar(buf
, ')');
10131 case PARTITION_STRATEGY_RANGE
:
10132 Assert(spec
->lowerdatums
!= NIL
&&
10133 spec
->upperdatums
!= NIL
&&
10134 list_length(spec
->lowerdatums
) ==
10135 list_length(spec
->upperdatums
));
10137 appendStringInfo(buf
, "FOR VALUES FROM %s TO %s",
10138 get_range_partbound_string(spec
->lowerdatums
),
10139 get_range_partbound_string(spec
->upperdatums
));
10143 elog(ERROR
, "unrecognized partition strategy: %d",
10144 (int) spec
->strategy
);
10150 case T_JsonValueExpr
:
10152 JsonValueExpr
*jve
= (JsonValueExpr
*) node
;
10154 get_rule_expr((Node
*) jve
->raw_expr
, context
, false);
10155 get_json_format(jve
->format
, context
->buf
);
10159 case T_JsonConstructorExpr
:
10160 get_json_constructor((JsonConstructorExpr
*) node
, context
, false);
10163 case T_JsonIsPredicate
:
10165 JsonIsPredicate
*pred
= (JsonIsPredicate
*) node
;
10167 if (!PRETTY_PAREN(context
))
10168 appendStringInfoChar(context
->buf
, '(');
10170 get_rule_expr_paren(pred
->expr
, context
, true, node
);
10172 appendStringInfoString(context
->buf
, " IS JSON");
10174 /* TODO: handle FORMAT clause */
10176 switch (pred
->item_type
)
10178 case JS_TYPE_SCALAR
:
10179 appendStringInfoString(context
->buf
, " SCALAR");
10181 case JS_TYPE_ARRAY
:
10182 appendStringInfoString(context
->buf
, " ARRAY");
10184 case JS_TYPE_OBJECT
:
10185 appendStringInfoString(context
->buf
, " OBJECT");
10191 if (pred
->unique_keys
)
10192 appendStringInfoString(context
->buf
, " WITH UNIQUE KEYS");
10194 if (!PRETTY_PAREN(context
))
10195 appendStringInfoChar(context
->buf
, ')');
10201 JsonExpr
*jexpr
= (JsonExpr
*) node
;
10205 case JSON_EXISTS_OP
:
10206 appendStringInfoString(buf
, "JSON_EXISTS(");
10208 case JSON_QUERY_OP
:
10209 appendStringInfoString(buf
, "JSON_QUERY(");
10211 case JSON_VALUE_OP
:
10212 appendStringInfoString(buf
, "JSON_VALUE(");
10215 elog(ERROR
, "unrecognized JsonExpr op: %d",
10219 get_rule_expr(jexpr
->formatted_expr
, context
, showimplicit
);
10221 appendStringInfoString(buf
, ", ");
10223 get_json_path_spec(jexpr
->path_spec
, context
, showimplicit
);
10225 if (jexpr
->passing_values
)
10229 bool needcomma
= false;
10231 appendStringInfoString(buf
, " PASSING ");
10233 forboth(lc1
, jexpr
->passing_names
,
10234 lc2
, jexpr
->passing_values
)
10237 appendStringInfoString(buf
, ", ");
10240 get_rule_expr((Node
*) lfirst(lc2
), context
, showimplicit
);
10241 appendStringInfo(buf
, " AS %s",
10242 ((String
*) lfirst_node(String
, lc1
))->sval
);
10246 if (jexpr
->op
!= JSON_EXISTS_OP
||
10247 jexpr
->returning
->typid
!= BOOLOID
)
10248 get_json_returning(jexpr
->returning
, context
->buf
,
10249 jexpr
->op
== JSON_QUERY_OP
);
10251 get_json_expr_options(jexpr
, context
,
10252 jexpr
->op
!= JSON_EXISTS_OP
?
10253 JSON_BEHAVIOR_NULL
:
10254 JSON_BEHAVIOR_FALSE
);
10256 appendStringInfoChar(buf
, ')');
10266 foreach(l
, (List
*) node
)
10268 appendStringInfoString(buf
, sep
);
10269 get_rule_expr((Node
*) lfirst(l
), context
, showimplicit
);
10276 get_tablefunc((TableFunc
*) node
, context
, showimplicit
);
10280 elog(ERROR
, "unrecognized node type: %d", (int) nodeTag(node
));
10286 * get_rule_expr_toplevel - Parse back a toplevel expression
10288 * Same as get_rule_expr(), except that if the expr is just a Var, we pass
10289 * istoplevel = true not false to get_variable(). This causes whole-row Vars
10290 * to get printed with decoration that will prevent expansion of "*".
10291 * We need to use this in contexts such as ROW() and VALUES(), where the
10292 * parser would expand "foo.*" appearing at top level. (In principle we'd
10293 * use this in get_target_list() too, but that has additional worries about
10294 * whether to print AS, so it needs to invoke get_variable() directly anyway.)
10297 get_rule_expr_toplevel(Node
*node
, deparse_context
*context
,
10300 if (node
&& IsA(node
, Var
))
10301 (void) get_variable((Var
*) node
, 0, true, context
);
10303 get_rule_expr(node
, context
, showimplicit
);
10307 * get_rule_list_toplevel - Parse back a list of toplevel expressions
10309 * Apply get_rule_expr_toplevel() to each element of a List.
10311 * This adds commas between the expressions, but caller is responsible
10312 * for printing surrounding decoration.
10315 get_rule_list_toplevel(List
*lst
, deparse_context
*context
,
10324 Node
*e
= (Node
*) lfirst(lc
);
10326 appendStringInfoString(context
->buf
, sep
);
10327 get_rule_expr_toplevel(e
, context
, showimplicit
);
10333 * get_rule_expr_funccall - Parse back a function-call expression
10335 * Same as get_rule_expr(), except that we guarantee that the output will
10336 * look like a function call, or like one of the things the grammar treats as
10337 * equivalent to a function call (see the func_expr_windowless production).
10338 * This is needed in places where the grammar uses func_expr_windowless and
10339 * you can't substitute a parenthesized a_expr. If what we have isn't going
10340 * to look like a function call, wrap it in a dummy CAST() expression, which
10341 * will satisfy the grammar --- and, indeed, is likely what the user wrote to
10342 * produce such a thing.
10345 get_rule_expr_funccall(Node
*node
, deparse_context
*context
,
10348 if (looks_like_function(node
))
10349 get_rule_expr(node
, context
, showimplicit
);
10352 StringInfo buf
= context
->buf
;
10354 appendStringInfoString(buf
, "CAST(");
10355 /* no point in showing any top-level implicit cast */
10356 get_rule_expr(node
, context
, false);
10357 appendStringInfo(buf
, " AS %s)",
10358 format_type_with_typemod(exprType(node
),
10359 exprTypmod(node
)));
10364 * Helper function to identify node types that satisfy func_expr_windowless.
10365 * If in doubt, "false" is always a safe answer.
10368 looks_like_function(Node
*node
)
10371 return false; /* probably shouldn't happen */
10372 switch (nodeTag(node
))
10375 /* OK, unless it's going to deparse as a cast */
10376 return (((FuncExpr
*) node
)->funcformat
== COERCE_EXPLICIT_CALL
||
10377 ((FuncExpr
*) node
)->funcformat
== COERCE_SQL_SYNTAX
);
10379 case T_CoalesceExpr
:
10381 case T_SQLValueFunction
:
10384 /* these are all accepted by func_expr_common_subexpr */
10394 * get_oper_expr - Parse back an OpExpr node
10397 get_oper_expr(OpExpr
*expr
, deparse_context
*context
)
10399 StringInfo buf
= context
->buf
;
10400 Oid opno
= expr
->opno
;
10401 List
*args
= expr
->args
;
10403 if (!PRETTY_PAREN(context
))
10404 appendStringInfoChar(buf
, '(');
10405 if (list_length(args
) == 2)
10407 /* binary operator */
10408 Node
*arg1
= (Node
*) linitial(args
);
10409 Node
*arg2
= (Node
*) lsecond(args
);
10411 get_rule_expr_paren(arg1
, context
, true, (Node
*) expr
);
10412 appendStringInfo(buf
, " %s ",
10413 generate_operator_name(opno
,
10416 get_rule_expr_paren(arg2
, context
, true, (Node
*) expr
);
10420 /* prefix operator */
10421 Node
*arg
= (Node
*) linitial(args
);
10423 appendStringInfo(buf
, "%s ",
10424 generate_operator_name(opno
,
10427 get_rule_expr_paren(arg
, context
, true, (Node
*) expr
);
10429 if (!PRETTY_PAREN(context
))
10430 appendStringInfoChar(buf
, ')');
10434 * get_func_expr - Parse back a FuncExpr node
10437 get_func_expr(FuncExpr
*expr
, deparse_context
*context
,
10440 StringInfo buf
= context
->buf
;
10441 Oid funcoid
= expr
->funcid
;
10442 Oid argtypes
[FUNC_MAX_ARGS
];
10449 * If the function call came from an implicit coercion, then just show the
10450 * first argument --- unless caller wants to see implicit coercions.
10452 if (expr
->funcformat
== COERCE_IMPLICIT_CAST
&& !showimplicit
)
10454 get_rule_expr_paren((Node
*) linitial(expr
->args
), context
,
10455 false, (Node
*) expr
);
10460 * If the function call came from a cast, then show the first argument
10461 * plus an explicit cast operation.
10463 if (expr
->funcformat
== COERCE_EXPLICIT_CAST
||
10464 expr
->funcformat
== COERCE_IMPLICIT_CAST
)
10466 Node
*arg
= linitial(expr
->args
);
10467 Oid rettype
= expr
->funcresulttype
;
10468 int32 coercedTypmod
;
10470 /* Get the typmod if this is a length-coercion function */
10471 (void) exprIsLengthCoercion((Node
*) expr
, &coercedTypmod
);
10473 get_coercion_expr(arg
, context
,
10474 rettype
, coercedTypmod
,
10481 * If the function was called using one of the SQL spec's random special
10482 * syntaxes, try to reproduce that. If we don't recognize the function,
10485 if (expr
->funcformat
== COERCE_SQL_SYNTAX
)
10487 if (get_func_sql_syntax(expr
, context
))
10492 * Normal function: display as proname(args). First we need to extract
10493 * the argument datatypes.
10495 if (list_length(expr
->args
) > FUNC_MAX_ARGS
)
10497 (errcode(ERRCODE_TOO_MANY_ARGUMENTS
),
10498 errmsg("too many arguments")));
10501 foreach(l
, expr
->args
)
10503 Node
*arg
= (Node
*) lfirst(l
);
10505 if (IsA(arg
, NamedArgExpr
))
10506 argnames
= lappend(argnames
, ((NamedArgExpr
*) arg
)->name
);
10507 argtypes
[nargs
] = exprType(arg
);
10511 appendStringInfo(buf
, "%s(",
10512 generate_function_name(funcoid
, nargs
,
10513 argnames
, argtypes
,
10514 expr
->funcvariadic
,
10516 context
->inGroupBy
));
10518 foreach(l
, expr
->args
)
10521 appendStringInfoString(buf
, ", ");
10522 if (use_variadic
&& lnext(expr
->args
, l
) == NULL
)
10523 appendStringInfoString(buf
, "VARIADIC ");
10524 get_rule_expr((Node
*) lfirst(l
), context
, true);
10526 appendStringInfoChar(buf
, ')');
10530 * get_agg_expr - Parse back an Aggref node
10533 get_agg_expr(Aggref
*aggref
, deparse_context
*context
,
10534 Aggref
*original_aggref
)
10536 get_agg_expr_helper(aggref
, context
, original_aggref
, NULL
, NULL
,
10541 * get_agg_expr_helper - subroutine for get_agg_expr and
10542 * get_json_agg_constructor
10545 get_agg_expr_helper(Aggref
*aggref
, deparse_context
*context
,
10546 Aggref
*original_aggref
, const char *funcname
,
10547 const char *options
, bool is_json_objectagg
)
10549 StringInfo buf
= context
->buf
;
10550 Oid argtypes
[FUNC_MAX_ARGS
];
10552 bool use_variadic
= false;
10555 * For a combining aggregate, we look up and deparse the corresponding
10556 * partial aggregate instead. This is necessary because our input
10557 * argument list has been replaced; the new argument list always has just
10558 * one element, which will point to a partial Aggref that supplies us with
10559 * transition states to combine.
10561 if (DO_AGGSPLIT_COMBINE(aggref
->aggsplit
))
10565 Assert(list_length(aggref
->args
) == 1);
10566 tle
= linitial_node(TargetEntry
, aggref
->args
);
10567 resolve_special_varno((Node
*) tle
->expr
, context
,
10568 get_agg_combine_expr
, original_aggref
);
10573 * Mark as PARTIAL, if appropriate. We look to the original aggref so as
10574 * to avoid printing this when recursing from the code just above.
10576 if (DO_AGGSPLIT_SKIPFINAL(original_aggref
->aggsplit
))
10577 appendStringInfoString(buf
, "PARTIAL ");
10579 /* Extract the argument types as seen by the parser */
10580 nargs
= get_aggregate_argtypes(aggref
, argtypes
);
10583 funcname
= generate_function_name(aggref
->aggfnoid
, nargs
, NIL
,
10584 argtypes
, aggref
->aggvariadic
,
10586 context
->inGroupBy
);
10588 /* Print the aggregate name, schema-qualified if needed */
10589 appendStringInfo(buf
, "%s(%s", funcname
,
10590 (aggref
->aggdistinct
!= NIL
) ? "DISTINCT " : "");
10592 if (AGGKIND_IS_ORDERED_SET(aggref
->aggkind
))
10595 * Ordered-set aggregates do not use "*" syntax. Also, we needn't
10596 * worry about inserting VARIADIC. So we can just dump the direct
10599 Assert(!aggref
->aggvariadic
);
10600 get_rule_expr((Node
*) aggref
->aggdirectargs
, context
, true);
10601 Assert(aggref
->aggorder
!= NIL
);
10602 appendStringInfoString(buf
, ") WITHIN GROUP (ORDER BY ");
10603 get_rule_orderby(aggref
->aggorder
, aggref
->args
, false, context
);
10607 /* aggstar can be set only in zero-argument aggregates */
10608 if (aggref
->aggstar
)
10609 appendStringInfoChar(buf
, '*');
10616 foreach(l
, aggref
->args
)
10618 TargetEntry
*tle
= (TargetEntry
*) lfirst(l
);
10619 Node
*arg
= (Node
*) tle
->expr
;
10621 Assert(!IsA(arg
, NamedArgExpr
));
10626 if (is_json_objectagg
)
10629 * the ABSENT ON NULL and WITH UNIQUE args are printed
10630 * separately, so ignore them here
10635 appendStringInfoString(buf
, " : ");
10638 appendStringInfoString(buf
, ", ");
10640 if (use_variadic
&& i
== nargs
)
10641 appendStringInfoString(buf
, "VARIADIC ");
10642 get_rule_expr(arg
, context
, true);
10646 if (aggref
->aggorder
!= NIL
)
10648 appendStringInfoString(buf
, " ORDER BY ");
10649 get_rule_orderby(aggref
->aggorder
, aggref
->args
, false, context
);
10654 appendStringInfoString(buf
, options
);
10656 if (aggref
->aggfilter
!= NULL
)
10658 appendStringInfoString(buf
, ") FILTER (WHERE ");
10659 get_rule_expr((Node
*) aggref
->aggfilter
, context
, false);
10662 appendStringInfoChar(buf
, ')');
10666 * This is a helper function for get_agg_expr(). It's used when we deparse
10667 * a combining Aggref; resolve_special_varno locates the corresponding partial
10668 * Aggref and then calls this.
10671 get_agg_combine_expr(Node
*node
, deparse_context
*context
, void *callback_arg
)
10674 Aggref
*original_aggref
= callback_arg
;
10676 if (!IsA(node
, Aggref
))
10677 elog(ERROR
, "combining Aggref does not point to an Aggref");
10679 aggref
= (Aggref
*) node
;
10680 get_agg_expr(aggref
, context
, original_aggref
);
10684 * get_windowfunc_expr - Parse back a WindowFunc node
10687 get_windowfunc_expr(WindowFunc
*wfunc
, deparse_context
*context
)
10689 get_windowfunc_expr_helper(wfunc
, context
, NULL
, NULL
, false);
10694 * get_windowfunc_expr_helper - subroutine for get_windowfunc_expr and
10695 * get_json_agg_constructor
10698 get_windowfunc_expr_helper(WindowFunc
*wfunc
, deparse_context
*context
,
10699 const char *funcname
, const char *options
,
10700 bool is_json_objectagg
)
10702 StringInfo buf
= context
->buf
;
10703 Oid argtypes
[FUNC_MAX_ARGS
];
10708 if (list_length(wfunc
->args
) > FUNC_MAX_ARGS
)
10710 (errcode(ERRCODE_TOO_MANY_ARGUMENTS
),
10711 errmsg("too many arguments")));
10714 foreach(l
, wfunc
->args
)
10716 Node
*arg
= (Node
*) lfirst(l
);
10718 if (IsA(arg
, NamedArgExpr
))
10719 argnames
= lappend(argnames
, ((NamedArgExpr
*) arg
)->name
);
10720 argtypes
[nargs
] = exprType(arg
);
10725 funcname
= generate_function_name(wfunc
->winfnoid
, nargs
, argnames
,
10726 argtypes
, false, NULL
,
10727 context
->inGroupBy
);
10729 appendStringInfo(buf
, "%s(", funcname
);
10731 /* winstar can be set only in zero-argument aggregates */
10732 if (wfunc
->winstar
)
10733 appendStringInfoChar(buf
, '*');
10736 if (is_json_objectagg
)
10738 get_rule_expr((Node
*) linitial(wfunc
->args
), context
, false);
10739 appendStringInfoString(buf
, " : ");
10740 get_rule_expr((Node
*) lsecond(wfunc
->args
), context
, false);
10743 get_rule_expr((Node
*) wfunc
->args
, context
, true);
10747 appendStringInfoString(buf
, options
);
10749 if (wfunc
->aggfilter
!= NULL
)
10751 appendStringInfoString(buf
, ") FILTER (WHERE ");
10752 get_rule_expr((Node
*) wfunc
->aggfilter
, context
, false);
10755 appendStringInfoString(buf
, ") OVER ");
10757 foreach(l
, context
->windowClause
)
10759 WindowClause
*wc
= (WindowClause
*) lfirst(l
);
10761 if (wc
->winref
== wfunc
->winref
)
10764 appendStringInfoString(buf
, quote_identifier(wc
->name
));
10766 get_rule_windowspec(wc
, context
->targetList
, context
);
10772 if (context
->windowClause
)
10773 elog(ERROR
, "could not find window clause for winref %u",
10777 * In EXPLAIN, we don't have window context information available, so
10778 * we have to settle for this:
10780 appendStringInfoString(buf
, "(?)");
10785 * get_func_sql_syntax - Parse back a SQL-syntax function call
10787 * Returns true if we successfully deparsed, false if we did not
10788 * recognize the function.
10791 get_func_sql_syntax(FuncExpr
*expr
, deparse_context
*context
)
10793 StringInfo buf
= context
->buf
;
10794 Oid funcoid
= expr
->funcid
;
10798 case F_TIMEZONE_INTERVAL_TIMESTAMP
:
10799 case F_TIMEZONE_INTERVAL_TIMESTAMPTZ
:
10800 case F_TIMEZONE_INTERVAL_TIMETZ
:
10801 case F_TIMEZONE_TEXT_TIMESTAMP
:
10802 case F_TIMEZONE_TEXT_TIMESTAMPTZ
:
10803 case F_TIMEZONE_TEXT_TIMETZ
:
10804 /* AT TIME ZONE ... note reversed argument order */
10805 appendStringInfoChar(buf
, '(');
10806 get_rule_expr_paren((Node
*) lsecond(expr
->args
), context
, false,
10808 appendStringInfoString(buf
, " AT TIME ZONE ");
10809 get_rule_expr_paren((Node
*) linitial(expr
->args
), context
, false,
10811 appendStringInfoChar(buf
, ')');
10814 case F_TIMEZONE_TIMESTAMP
:
10815 case F_TIMEZONE_TIMESTAMPTZ
:
10816 case F_TIMEZONE_TIMETZ
:
10818 appendStringInfoChar(buf
, '(');
10819 get_rule_expr_paren((Node
*) linitial(expr
->args
), context
, false,
10821 appendStringInfoString(buf
, " AT LOCAL)");
10824 case F_OVERLAPS_TIMESTAMPTZ_INTERVAL_TIMESTAMPTZ_INTERVAL
:
10825 case F_OVERLAPS_TIMESTAMPTZ_INTERVAL_TIMESTAMPTZ_TIMESTAMPTZ
:
10826 case F_OVERLAPS_TIMESTAMPTZ_TIMESTAMPTZ_TIMESTAMPTZ_INTERVAL
:
10827 case F_OVERLAPS_TIMESTAMPTZ_TIMESTAMPTZ_TIMESTAMPTZ_TIMESTAMPTZ
:
10828 case F_OVERLAPS_TIMESTAMP_INTERVAL_TIMESTAMP_INTERVAL
:
10829 case F_OVERLAPS_TIMESTAMP_INTERVAL_TIMESTAMP_TIMESTAMP
:
10830 case F_OVERLAPS_TIMESTAMP_TIMESTAMP_TIMESTAMP_INTERVAL
:
10831 case F_OVERLAPS_TIMESTAMP_TIMESTAMP_TIMESTAMP_TIMESTAMP
:
10832 case F_OVERLAPS_TIMETZ_TIMETZ_TIMETZ_TIMETZ
:
10833 case F_OVERLAPS_TIME_INTERVAL_TIME_INTERVAL
:
10834 case F_OVERLAPS_TIME_INTERVAL_TIME_TIME
:
10835 case F_OVERLAPS_TIME_TIME_TIME_INTERVAL
:
10836 case F_OVERLAPS_TIME_TIME_TIME_TIME
:
10837 /* (x1, x2) OVERLAPS (y1, y2) */
10838 appendStringInfoString(buf
, "((");
10839 get_rule_expr((Node
*) linitial(expr
->args
), context
, false);
10840 appendStringInfoString(buf
, ", ");
10841 get_rule_expr((Node
*) lsecond(expr
->args
), context
, false);
10842 appendStringInfoString(buf
, ") OVERLAPS (");
10843 get_rule_expr((Node
*) lthird(expr
->args
), context
, false);
10844 appendStringInfoString(buf
, ", ");
10845 get_rule_expr((Node
*) lfourth(expr
->args
), context
, false);
10846 appendStringInfoString(buf
, "))");
10849 case F_EXTRACT_TEXT_DATE
:
10850 case F_EXTRACT_TEXT_TIME
:
10851 case F_EXTRACT_TEXT_TIMETZ
:
10852 case F_EXTRACT_TEXT_TIMESTAMP
:
10853 case F_EXTRACT_TEXT_TIMESTAMPTZ
:
10854 case F_EXTRACT_TEXT_INTERVAL
:
10855 /* EXTRACT (x FROM y) */
10856 appendStringInfoString(buf
, "EXTRACT(");
10858 Const
*con
= (Const
*) linitial(expr
->args
);
10860 Assert(IsA(con
, Const
) &&
10861 con
->consttype
== TEXTOID
&&
10862 !con
->constisnull
);
10863 appendStringInfoString(buf
, TextDatumGetCString(con
->constvalue
));
10865 appendStringInfoString(buf
, " FROM ");
10866 get_rule_expr((Node
*) lsecond(expr
->args
), context
, false);
10867 appendStringInfoChar(buf
, ')');
10870 case F_IS_NORMALIZED
:
10871 /* IS xxx NORMALIZED */
10872 appendStringInfoChar(buf
, '(');
10873 get_rule_expr_paren((Node
*) linitial(expr
->args
), context
, false,
10875 appendStringInfoString(buf
, " IS");
10876 if (list_length(expr
->args
) == 2)
10878 Const
*con
= (Const
*) lsecond(expr
->args
);
10880 Assert(IsA(con
, Const
) &&
10881 con
->consttype
== TEXTOID
&&
10882 !con
->constisnull
);
10883 appendStringInfo(buf
, " %s",
10884 TextDatumGetCString(con
->constvalue
));
10886 appendStringInfoString(buf
, " NORMALIZED)");
10889 case F_PG_COLLATION_FOR
:
10890 /* COLLATION FOR */
10891 appendStringInfoString(buf
, "COLLATION FOR (");
10892 get_rule_expr((Node
*) linitial(expr
->args
), context
, false);
10893 appendStringInfoChar(buf
, ')');
10898 appendStringInfoString(buf
, "NORMALIZE(");
10899 get_rule_expr((Node
*) linitial(expr
->args
), context
, false);
10900 if (list_length(expr
->args
) == 2)
10902 Const
*con
= (Const
*) lsecond(expr
->args
);
10904 Assert(IsA(con
, Const
) &&
10905 con
->consttype
== TEXTOID
&&
10906 !con
->constisnull
);
10907 appendStringInfo(buf
, ", %s",
10908 TextDatumGetCString(con
->constvalue
));
10910 appendStringInfoChar(buf
, ')');
10913 case F_OVERLAY_BIT_BIT_INT4
:
10914 case F_OVERLAY_BIT_BIT_INT4_INT4
:
10915 case F_OVERLAY_BYTEA_BYTEA_INT4
:
10916 case F_OVERLAY_BYTEA_BYTEA_INT4_INT4
:
10917 case F_OVERLAY_TEXT_TEXT_INT4
:
10918 case F_OVERLAY_TEXT_TEXT_INT4_INT4
:
10920 appendStringInfoString(buf
, "OVERLAY(");
10921 get_rule_expr((Node
*) linitial(expr
->args
), context
, false);
10922 appendStringInfoString(buf
, " PLACING ");
10923 get_rule_expr((Node
*) lsecond(expr
->args
), context
, false);
10924 appendStringInfoString(buf
, " FROM ");
10925 get_rule_expr((Node
*) lthird(expr
->args
), context
, false);
10926 if (list_length(expr
->args
) == 4)
10928 appendStringInfoString(buf
, " FOR ");
10929 get_rule_expr((Node
*) lfourth(expr
->args
), context
, false);
10931 appendStringInfoChar(buf
, ')');
10934 case F_POSITION_BIT_BIT
:
10935 case F_POSITION_BYTEA_BYTEA
:
10936 case F_POSITION_TEXT_TEXT
:
10937 /* POSITION() ... extra parens since args are b_expr not a_expr */
10938 appendStringInfoString(buf
, "POSITION((");
10939 get_rule_expr((Node
*) lsecond(expr
->args
), context
, false);
10940 appendStringInfoString(buf
, ") IN (");
10941 get_rule_expr((Node
*) linitial(expr
->args
), context
, false);
10942 appendStringInfoString(buf
, "))");
10945 case F_SUBSTRING_BIT_INT4
:
10946 case F_SUBSTRING_BIT_INT4_INT4
:
10947 case F_SUBSTRING_BYTEA_INT4
:
10948 case F_SUBSTRING_BYTEA_INT4_INT4
:
10949 case F_SUBSTRING_TEXT_INT4
:
10950 case F_SUBSTRING_TEXT_INT4_INT4
:
10951 /* SUBSTRING FROM/FOR (i.e., integer-position variants) */
10952 appendStringInfoString(buf
, "SUBSTRING(");
10953 get_rule_expr((Node
*) linitial(expr
->args
), context
, false);
10954 appendStringInfoString(buf
, " FROM ");
10955 get_rule_expr((Node
*) lsecond(expr
->args
), context
, false);
10956 if (list_length(expr
->args
) == 3)
10958 appendStringInfoString(buf
, " FOR ");
10959 get_rule_expr((Node
*) lthird(expr
->args
), context
, false);
10961 appendStringInfoChar(buf
, ')');
10964 case F_SUBSTRING_TEXT_TEXT_TEXT
:
10965 /* SUBSTRING SIMILAR/ESCAPE */
10966 appendStringInfoString(buf
, "SUBSTRING(");
10967 get_rule_expr((Node
*) linitial(expr
->args
), context
, false);
10968 appendStringInfoString(buf
, " SIMILAR ");
10969 get_rule_expr((Node
*) lsecond(expr
->args
), context
, false);
10970 appendStringInfoString(buf
, " ESCAPE ");
10971 get_rule_expr((Node
*) lthird(expr
->args
), context
, false);
10972 appendStringInfoChar(buf
, ')');
10975 case F_BTRIM_BYTEA_BYTEA
:
10977 case F_BTRIM_TEXT_TEXT
:
10979 appendStringInfoString(buf
, "TRIM(BOTH");
10980 if (list_length(expr
->args
) == 2)
10982 appendStringInfoChar(buf
, ' ');
10983 get_rule_expr((Node
*) lsecond(expr
->args
), context
, false);
10985 appendStringInfoString(buf
, " FROM ");
10986 get_rule_expr((Node
*) linitial(expr
->args
), context
, false);
10987 appendStringInfoChar(buf
, ')');
10990 case F_LTRIM_BYTEA_BYTEA
:
10992 case F_LTRIM_TEXT_TEXT
:
10994 appendStringInfoString(buf
, "TRIM(LEADING");
10995 if (list_length(expr
->args
) == 2)
10997 appendStringInfoChar(buf
, ' ');
10998 get_rule_expr((Node
*) lsecond(expr
->args
), context
, false);
11000 appendStringInfoString(buf
, " FROM ");
11001 get_rule_expr((Node
*) linitial(expr
->args
), context
, false);
11002 appendStringInfoChar(buf
, ')');
11005 case F_RTRIM_BYTEA_BYTEA
:
11007 case F_RTRIM_TEXT_TEXT
:
11009 appendStringInfoString(buf
, "TRIM(TRAILING");
11010 if (list_length(expr
->args
) == 2)
11012 appendStringInfoChar(buf
, ' ');
11013 get_rule_expr((Node
*) lsecond(expr
->args
), context
, false);
11015 appendStringInfoString(buf
, " FROM ");
11016 get_rule_expr((Node
*) linitial(expr
->args
), context
, false);
11017 appendStringInfoChar(buf
, ')');
11020 case F_SYSTEM_USER
:
11021 appendStringInfoString(buf
, "SYSTEM_USER");
11025 /* XMLEXISTS ... extra parens because args are c_expr */
11026 appendStringInfoString(buf
, "XMLEXISTS((");
11027 get_rule_expr((Node
*) linitial(expr
->args
), context
, false);
11028 appendStringInfoString(buf
, ") PASSING (");
11029 get_rule_expr((Node
*) lsecond(expr
->args
), context
, false);
11030 appendStringInfoString(buf
, "))");
11037 * get_coercion_expr
11039 * Make a string representation of a value coerced to a specific type
11043 get_coercion_expr(Node
*arg
, deparse_context
*context
,
11044 Oid resulttype
, int32 resulttypmod
,
11047 StringInfo buf
= context
->buf
;
11050 * Since parse_coerce.c doesn't immediately collapse application of
11051 * length-coercion functions to constants, what we'll typically see in
11052 * such cases is a Const with typmod -1 and a length-coercion function
11053 * right above it. Avoid generating redundant output. However, beware of
11054 * suppressing casts when the user actually wrote something like
11055 * 'foo'::text::char(3).
11057 * Note: it might seem that we are missing the possibility of needing to
11058 * print a COLLATE clause for such a Const. However, a Const could only
11059 * have nondefault collation in a post-constant-folding tree, in which the
11060 * length coercion would have been folded too. See also the special
11061 * handling of CollateExpr in coerce_to_target_type(): any collation
11062 * marking will be above the coercion node, not below it.
11064 if (arg
&& IsA(arg
, Const
) &&
11065 ((Const
*) arg
)->consttype
== resulttype
&&
11066 ((Const
*) arg
)->consttypmod
== -1)
11068 /* Show the constant without normal ::typename decoration */
11069 get_const_expr((Const
*) arg
, context
, -1);
11073 if (!PRETTY_PAREN(context
))
11074 appendStringInfoChar(buf
, '(');
11075 get_rule_expr_paren(arg
, context
, false, parentNode
);
11076 if (!PRETTY_PAREN(context
))
11077 appendStringInfoChar(buf
, ')');
11081 * Never emit resulttype(arg) functional notation. A pg_proc entry could
11082 * take precedence, and a resulttype in pg_temp would require schema
11083 * qualification that format_type_with_typemod() would usually omit. We've
11084 * standardized on arg::resulttype, but CAST(arg AS resulttype) notation
11087 appendStringInfo(buf
, "::%s",
11088 format_type_with_typemod(resulttype
, resulttypmod
));
11094 * Make a string representation of a Const
11096 * showtype can be -1 to never show "::typename" decoration, or +1 to always
11097 * show it, or 0 to show it only if the constant wouldn't be assumed to be
11098 * the right type by default.
11100 * If the Const's collation isn't default for its type, show that too.
11101 * We mustn't do this when showtype is -1 (since that means the caller will
11102 * print "::typename", and we can't put a COLLATE clause in between). It's
11103 * caller's responsibility that collation isn't missed in such cases.
11107 get_const_expr(Const
*constval
, deparse_context
*context
, int showtype
)
11109 StringInfo buf
= context
->buf
;
11113 bool needlabel
= false;
11115 if (constval
->constisnull
)
11118 * Always label the type of a NULL constant to prevent misdecisions
11119 * about type when reparsing.
11121 appendStringInfoString(buf
, "NULL");
11124 appendStringInfo(buf
, "::%s",
11125 format_type_with_typemod(constval
->consttype
,
11126 constval
->consttypmod
));
11127 get_const_collation(constval
, context
);
11132 getTypeOutputInfo(constval
->consttype
,
11133 &typoutput
, &typIsVarlena
);
11135 extval
= OidOutputFunctionCall(typoutput
, constval
->constvalue
);
11137 switch (constval
->consttype
)
11142 * INT4 can be printed without any decoration, unless it is
11143 * negative; in that case print it as '-nnn'::integer to ensure
11144 * that the output will re-parse as a constant, not as a constant
11145 * plus operator. In most cases we could get away with printing
11146 * (-nnn) instead, because of the way that gram.y handles negative
11147 * literals; but that doesn't work for INT_MIN, and it doesn't
11148 * seem that much prettier anyway.
11150 if (extval
[0] != '-')
11151 appendStringInfoString(buf
, extval
);
11154 appendStringInfo(buf
, "'%s'", extval
);
11155 needlabel
= true; /* we must attach a cast */
11162 * NUMERIC can be printed without quotes if it looks like a float
11163 * constant (not an integer, and not Infinity or NaN) and doesn't
11164 * have a leading sign (for the same reason as for INT4).
11166 if (isdigit((unsigned char) extval
[0]) &&
11167 strcspn(extval
, "eE.") != strlen(extval
))
11169 appendStringInfoString(buf
, extval
);
11173 appendStringInfo(buf
, "'%s'", extval
);
11174 needlabel
= true; /* we must attach a cast */
11179 if (strcmp(extval
, "t") == 0)
11180 appendStringInfoString(buf
, "true");
11182 appendStringInfoString(buf
, "false");
11186 simple_quote_literal(buf
, extval
);
11196 * For showtype == 0, append ::typename unless the constant will be
11197 * implicitly typed as the right type when it is read in.
11199 * XXX this code has to be kept in sync with the behavior of the parser,
11200 * especially make_const.
11202 switch (constval
->consttype
)
11206 /* These types can be left unlabeled */
11210 /* We determined above whether a label is needed */
11215 * Float-looking constants will be typed as numeric, which we
11216 * checked above; but if there's a nondefault typmod we need to
11219 needlabel
|= (constval
->consttypmod
>= 0);
11225 if (needlabel
|| showtype
> 0)
11226 appendStringInfo(buf
, "::%s",
11227 format_type_with_typemod(constval
->consttype
,
11228 constval
->consttypmod
));
11230 get_const_collation(constval
, context
);
11234 * helper for get_const_expr: append COLLATE if needed
11237 get_const_collation(Const
*constval
, deparse_context
*context
)
11239 StringInfo buf
= context
->buf
;
11241 if (OidIsValid(constval
->constcollid
))
11243 Oid typcollation
= get_typcollation(constval
->consttype
);
11245 if (constval
->constcollid
!= typcollation
)
11247 appendStringInfo(buf
, " COLLATE %s",
11248 generate_collation_name(constval
->constcollid
));
11254 * get_json_path_spec - Parse back a JSON path specification
11257 get_json_path_spec(Node
*path_spec
, deparse_context
*context
, bool showimplicit
)
11259 if (IsA(path_spec
, Const
))
11260 get_const_expr((Const
*) path_spec
, context
, -1);
11262 get_rule_expr(path_spec
, context
, showimplicit
);
11266 * get_json_format - Parse back a JsonFormat node
11269 get_json_format(JsonFormat
*format
, StringInfo buf
)
11271 if (format
->format_type
== JS_FORMAT_DEFAULT
)
11274 appendStringInfoString(buf
,
11275 format
->format_type
== JS_FORMAT_JSONB
?
11276 " FORMAT JSONB" : " FORMAT JSON");
11278 if (format
->encoding
!= JS_ENC_DEFAULT
)
11280 const char *encoding
;
11283 format
->encoding
== JS_ENC_UTF16
? "UTF16" :
11284 format
->encoding
== JS_ENC_UTF32
? "UTF32" : "UTF8";
11286 appendStringInfo(buf
, " ENCODING %s", encoding
);
11291 * get_json_returning - Parse back a JsonReturning structure
11294 get_json_returning(JsonReturning
*returning
, StringInfo buf
,
11295 bool json_format_by_default
)
11297 if (!OidIsValid(returning
->typid
))
11300 appendStringInfo(buf
, " RETURNING %s",
11301 format_type_with_typemod(returning
->typid
,
11302 returning
->typmod
));
11304 if (!json_format_by_default
||
11305 returning
->format
->format_type
!=
11306 (returning
->typid
== JSONBOID
? JS_FORMAT_JSONB
: JS_FORMAT_JSON
))
11307 get_json_format(returning
->format
, buf
);
11311 * get_json_constructor - Parse back a JsonConstructorExpr node
11314 get_json_constructor(JsonConstructorExpr
*ctor
, deparse_context
*context
,
11317 StringInfo buf
= context
->buf
;
11318 const char *funcname
;
11319 bool is_json_object
;
11323 if (ctor
->type
== JSCTOR_JSON_OBJECTAGG
)
11325 get_json_agg_constructor(ctor
, context
, "JSON_OBJECTAGG", true);
11328 else if (ctor
->type
== JSCTOR_JSON_ARRAYAGG
)
11330 get_json_agg_constructor(ctor
, context
, "JSON_ARRAYAGG", false);
11334 switch (ctor
->type
)
11336 case JSCTOR_JSON_OBJECT
:
11337 funcname
= "JSON_OBJECT";
11339 case JSCTOR_JSON_ARRAY
:
11340 funcname
= "JSON_ARRAY";
11342 case JSCTOR_JSON_PARSE
:
11345 case JSCTOR_JSON_SCALAR
:
11346 funcname
= "JSON_SCALAR";
11348 case JSCTOR_JSON_SERIALIZE
:
11349 funcname
= "JSON_SERIALIZE";
11352 elog(ERROR
, "invalid JsonConstructorType %d", ctor
->type
);
11355 appendStringInfo(buf
, "%s(", funcname
);
11357 is_json_object
= ctor
->type
== JSCTOR_JSON_OBJECT
;
11358 foreach(lc
, ctor
->args
)
11360 curridx
= foreach_current_index(lc
);
11365 sep
= (is_json_object
&& (curridx
% 2) != 0) ? " : " : ", ";
11366 appendStringInfoString(buf
, sep
);
11369 get_rule_expr((Node
*) lfirst(lc
), context
, true);
11372 get_json_constructor_options(ctor
, buf
);
11373 appendStringInfoChar(buf
, ')');
11377 * Append options, if any, to the JSON constructor being deparsed
11380 get_json_constructor_options(JsonConstructorExpr
*ctor
, StringInfo buf
)
11382 if (ctor
->absent_on_null
)
11384 if (ctor
->type
== JSCTOR_JSON_OBJECT
||
11385 ctor
->type
== JSCTOR_JSON_OBJECTAGG
)
11386 appendStringInfoString(buf
, " ABSENT ON NULL");
11390 if (ctor
->type
== JSCTOR_JSON_ARRAY
||
11391 ctor
->type
== JSCTOR_JSON_ARRAYAGG
)
11392 appendStringInfoString(buf
, " NULL ON NULL");
11396 appendStringInfoString(buf
, " WITH UNIQUE KEYS");
11399 * Append RETURNING clause if needed; JSON() and JSON_SCALAR() don't
11402 if (ctor
->type
!= JSCTOR_JSON_PARSE
&& ctor
->type
!= JSCTOR_JSON_SCALAR
)
11403 get_json_returning(ctor
->returning
, buf
, true);
11407 * get_json_agg_constructor - Parse back an aggregate JsonConstructorExpr node
11410 get_json_agg_constructor(JsonConstructorExpr
*ctor
, deparse_context
*context
,
11411 const char *funcname
, bool is_json_objectagg
)
11413 StringInfoData options
;
11415 initStringInfo(&options
);
11416 get_json_constructor_options(ctor
, &options
);
11418 if (IsA(ctor
->func
, Aggref
))
11419 get_agg_expr_helper((Aggref
*) ctor
->func
, context
,
11420 (Aggref
*) ctor
->func
,
11421 funcname
, options
.data
, is_json_objectagg
);
11422 else if (IsA(ctor
->func
, WindowFunc
))
11423 get_windowfunc_expr_helper((WindowFunc
*) ctor
->func
, context
,
11424 funcname
, options
.data
,
11425 is_json_objectagg
);
11427 elog(ERROR
, "invalid JsonConstructorExpr underlying node type: %d",
11428 nodeTag(ctor
->func
));
11432 * simple_quote_literal - Format a string as a SQL literal, append to buf
11435 simple_quote_literal(StringInfo buf
, const char *val
)
11437 const char *valptr
;
11440 * We form the string literal according to the prevailing setting of
11441 * standard_conforming_strings; we never use E''. User is responsible for
11442 * making sure result is used correctly.
11444 appendStringInfoChar(buf
, '\'');
11445 for (valptr
= val
; *valptr
; valptr
++)
11449 if (SQL_STR_DOUBLE(ch
, !standard_conforming_strings
))
11450 appendStringInfoChar(buf
, ch
);
11451 appendStringInfoChar(buf
, ch
);
11453 appendStringInfoChar(buf
, '\'');
11458 * get_sublink_expr - Parse back a sublink
11462 get_sublink_expr(SubLink
*sublink
, deparse_context
*context
)
11464 StringInfo buf
= context
->buf
;
11465 Query
*query
= (Query
*) (sublink
->subselect
);
11466 char *opname
= NULL
;
11469 if (sublink
->subLinkType
== ARRAY_SUBLINK
)
11470 appendStringInfoString(buf
, "ARRAY(");
11472 appendStringInfoChar(buf
, '(');
11475 * Note that we print the name of only the first operator, when there are
11476 * multiple combining operators. This is an approximation that could go
11477 * wrong in various scenarios (operators in different schemas, renamed
11478 * operators, etc) but there is not a whole lot we can do about it, since
11479 * the syntax allows only one operator to be shown.
11481 if (sublink
->testexpr
)
11483 if (IsA(sublink
->testexpr
, OpExpr
))
11485 /* single combining operator */
11486 OpExpr
*opexpr
= (OpExpr
*) sublink
->testexpr
;
11488 get_rule_expr(linitial(opexpr
->args
), context
, true);
11489 opname
= generate_operator_name(opexpr
->opno
,
11490 exprType(linitial(opexpr
->args
)),
11491 exprType(lsecond(opexpr
->args
)));
11493 else if (IsA(sublink
->testexpr
, BoolExpr
))
11495 /* multiple combining operators, = or <> cases */
11499 appendStringInfoChar(buf
, '(');
11501 foreach(l
, ((BoolExpr
*) sublink
->testexpr
)->args
)
11503 OpExpr
*opexpr
= lfirst_node(OpExpr
, l
);
11505 appendStringInfoString(buf
, sep
);
11506 get_rule_expr(linitial(opexpr
->args
), context
, true);
11508 opname
= generate_operator_name(opexpr
->opno
,
11509 exprType(linitial(opexpr
->args
)),
11510 exprType(lsecond(opexpr
->args
)));
11513 appendStringInfoChar(buf
, ')');
11515 else if (IsA(sublink
->testexpr
, RowCompareExpr
))
11517 /* multiple combining operators, < <= > >= cases */
11518 RowCompareExpr
*rcexpr
= (RowCompareExpr
*) sublink
->testexpr
;
11520 appendStringInfoChar(buf
, '(');
11521 get_rule_expr((Node
*) rcexpr
->largs
, context
, true);
11522 opname
= generate_operator_name(linitial_oid(rcexpr
->opnos
),
11523 exprType(linitial(rcexpr
->largs
)),
11524 exprType(linitial(rcexpr
->rargs
)));
11525 appendStringInfoChar(buf
, ')');
11528 elog(ERROR
, "unrecognized testexpr type: %d",
11529 (int) nodeTag(sublink
->testexpr
));
11534 switch (sublink
->subLinkType
)
11536 case EXISTS_SUBLINK
:
11537 appendStringInfoString(buf
, "EXISTS ");
11541 if (strcmp(opname
, "=") == 0) /* Represent = ANY as IN */
11542 appendStringInfoString(buf
, " IN ");
11544 appendStringInfo(buf
, " %s ANY ", opname
);
11548 appendStringInfo(buf
, " %s ALL ", opname
);
11551 case ROWCOMPARE_SUBLINK
:
11552 appendStringInfo(buf
, " %s ", opname
);
11556 case MULTIEXPR_SUBLINK
:
11557 case ARRAY_SUBLINK
:
11558 need_paren
= false;
11561 case CTE_SUBLINK
: /* shouldn't occur in a SubLink */
11563 elog(ERROR
, "unrecognized sublink type: %d",
11564 (int) sublink
->subLinkType
);
11569 appendStringInfoChar(buf
, '(');
11571 get_query_def(query
, buf
, context
->namespaces
, NULL
, false,
11572 context
->prettyFlags
, context
->wrapColumn
,
11573 context
->indentLevel
);
11576 appendStringInfoString(buf
, "))");
11578 appendStringInfoChar(buf
, ')');
11583 * get_xmltable - Parse back a XMLTABLE function
11587 get_xmltable(TableFunc
*tf
, deparse_context
*context
, bool showimplicit
)
11589 StringInfo buf
= context
->buf
;
11591 appendStringInfoString(buf
, "XMLTABLE(");
11593 if (tf
->ns_uris
!= NIL
)
11599 appendStringInfoString(buf
, "XMLNAMESPACES (");
11600 forboth(lc1
, tf
->ns_uris
, lc2
, tf
->ns_names
)
11602 Node
*expr
= (Node
*) lfirst(lc1
);
11603 String
*ns_node
= lfirst_node(String
, lc2
);
11606 appendStringInfoString(buf
, ", ");
11610 if (ns_node
!= NULL
)
11612 get_rule_expr(expr
, context
, showimplicit
);
11613 appendStringInfo(buf
, " AS %s", strVal(ns_node
));
11617 appendStringInfoString(buf
, "DEFAULT ");
11618 get_rule_expr(expr
, context
, showimplicit
);
11621 appendStringInfoString(buf
, "), ");
11624 appendStringInfoChar(buf
, '(');
11625 get_rule_expr((Node
*) tf
->rowexpr
, context
, showimplicit
);
11626 appendStringInfoString(buf
, ") PASSING (");
11627 get_rule_expr((Node
*) tf
->docexpr
, context
, showimplicit
);
11628 appendStringInfoChar(buf
, ')');
11630 if (tf
->colexprs
!= NIL
)
11639 appendStringInfoString(buf
, " COLUMNS ");
11640 forfive(l1
, tf
->colnames
, l2
, tf
->coltypes
, l3
, tf
->coltypmods
,
11641 l4
, tf
->colexprs
, l5
, tf
->coldefexprs
)
11643 char *colname
= strVal(lfirst(l1
));
11644 Oid typid
= lfirst_oid(l2
);
11645 int32 typmod
= lfirst_int(l3
);
11646 Node
*colexpr
= (Node
*) lfirst(l4
);
11647 Node
*coldefexpr
= (Node
*) lfirst(l5
);
11648 bool ordinality
= (tf
->ordinalitycol
== colnum
);
11649 bool notnull
= bms_is_member(colnum
, tf
->notnulls
);
11652 appendStringInfoString(buf
, ", ");
11655 appendStringInfo(buf
, "%s %s", quote_identifier(colname
),
11656 ordinality
? "FOR ORDINALITY" :
11657 format_type_with_typemod(typid
, typmod
));
11661 if (coldefexpr
!= NULL
)
11663 appendStringInfoString(buf
, " DEFAULT (");
11664 get_rule_expr((Node
*) coldefexpr
, context
, showimplicit
);
11665 appendStringInfoChar(buf
, ')');
11667 if (colexpr
!= NULL
)
11669 appendStringInfoString(buf
, " PATH (");
11670 get_rule_expr((Node
*) colexpr
, context
, showimplicit
);
11671 appendStringInfoChar(buf
, ')');
11674 appendStringInfoString(buf
, " NOT NULL");
11678 appendStringInfoChar(buf
, ')');
11682 * get_json_table_nested_columns - Parse back nested JSON_TABLE columns
11685 get_json_table_nested_columns(TableFunc
*tf
, JsonTablePlan
*plan
,
11686 deparse_context
*context
, bool showimplicit
,
11689 if (IsA(plan
, JsonTablePathScan
))
11691 JsonTablePathScan
*scan
= castNode(JsonTablePathScan
, plan
);
11694 appendStringInfoChar(context
->buf
, ',');
11696 appendStringInfoChar(context
->buf
, ' ');
11697 appendContextKeyword(context
, "NESTED PATH ", 0, 0, 0);
11698 get_const_expr(scan
->path
->value
, context
, -1);
11699 appendStringInfo(context
->buf
, " AS %s", quote_identifier(scan
->path
->name
));
11700 get_json_table_columns(tf
, scan
, context
, showimplicit
);
11702 else if (IsA(plan
, JsonTableSiblingJoin
))
11704 JsonTableSiblingJoin
*join
= (JsonTableSiblingJoin
*) plan
;
11706 get_json_table_nested_columns(tf
, join
->lplan
, context
, showimplicit
,
11708 get_json_table_nested_columns(tf
, join
->rplan
, context
, showimplicit
,
11714 * get_json_table_columns - Parse back JSON_TABLE columns
11717 get_json_table_columns(TableFunc
*tf
, JsonTablePathScan
*scan
,
11718 deparse_context
*context
,
11721 StringInfo buf
= context
->buf
;
11722 JsonExpr
*jexpr
= castNode(JsonExpr
, tf
->docexpr
);
11723 ListCell
*lc_colname
;
11724 ListCell
*lc_coltype
;
11725 ListCell
*lc_coltypmod
;
11726 ListCell
*lc_colvalexpr
;
11729 appendStringInfoChar(buf
, ' ');
11730 appendContextKeyword(context
, "COLUMNS (", 0, 0, 0);
11732 if (PRETTY_INDENT(context
))
11733 context
->indentLevel
+= PRETTYINDENT_VAR
;
11735 forfour(lc_colname
, tf
->colnames
,
11736 lc_coltype
, tf
->coltypes
,
11737 lc_coltypmod
, tf
->coltypmods
,
11738 lc_colvalexpr
, tf
->colvalexprs
)
11740 char *colname
= strVal(lfirst(lc_colname
));
11745 JsonBehaviorType default_behavior
;
11747 typid
= lfirst_oid(lc_coltype
);
11748 typmod
= lfirst_int(lc_coltypmod
);
11749 colexpr
= castNode(JsonExpr
, lfirst(lc_colvalexpr
));
11751 /* Skip columns that don't belong to this scan. */
11752 if (scan
->colMin
< 0 || colnum
< scan
->colMin
)
11757 if (colnum
> scan
->colMax
)
11760 if (colnum
> scan
->colMin
)
11761 appendStringInfoString(buf
, ", ");
11765 ordinality
= !colexpr
;
11767 appendContextKeyword(context
, "", 0, 0, 0);
11769 appendStringInfo(buf
, "%s %s", quote_identifier(colname
),
11770 ordinality
? "FOR ORDINALITY" :
11771 format_type_with_typemod(typid
, typmod
));
11775 if (colexpr
->op
== JSON_EXISTS_OP
)
11777 appendStringInfoString(buf
, " EXISTS");
11778 default_behavior
= JSON_BEHAVIOR_FALSE
;
11782 if (colexpr
->op
== JSON_QUERY_OP
)
11785 bool typispreferred
;
11787 get_type_category_preferred(typid
, &typcategory
, &typispreferred
);
11789 if (typcategory
== TYPCATEGORY_STRING
)
11790 appendStringInfoString(buf
,
11791 colexpr
->format
->format_type
== JS_FORMAT_JSONB
?
11792 " FORMAT JSONB" : " FORMAT JSON");
11795 default_behavior
= JSON_BEHAVIOR_NULL
;
11798 if (jexpr
->on_error
->btype
== JSON_BEHAVIOR_ERROR
)
11799 default_behavior
= JSON_BEHAVIOR_ERROR
;
11801 appendStringInfoString(buf
, " PATH ");
11803 get_json_path_spec(colexpr
->path_spec
, context
, showimplicit
);
11805 get_json_expr_options(colexpr
, context
, default_behavior
);
11809 get_json_table_nested_columns(tf
, scan
->child
, context
, showimplicit
,
11810 scan
->colMin
>= 0);
11812 if (PRETTY_INDENT(context
))
11813 context
->indentLevel
-= PRETTYINDENT_VAR
;
11815 appendContextKeyword(context
, ")", 0, 0, 0);
11819 * get_json_table - Parse back a JSON_TABLE function
11823 get_json_table(TableFunc
*tf
, deparse_context
*context
, bool showimplicit
)
11825 StringInfo buf
= context
->buf
;
11826 JsonExpr
*jexpr
= castNode(JsonExpr
, tf
->docexpr
);
11827 JsonTablePathScan
*root
= castNode(JsonTablePathScan
, tf
->plan
);
11829 appendStringInfoString(buf
, "JSON_TABLE(");
11831 if (PRETTY_INDENT(context
))
11832 context
->indentLevel
+= PRETTYINDENT_VAR
;
11834 appendContextKeyword(context
, "", 0, 0, 0);
11836 get_rule_expr(jexpr
->formatted_expr
, context
, showimplicit
);
11838 appendStringInfoString(buf
, ", ");
11840 get_const_expr(root
->path
->value
, context
, -1);
11842 appendStringInfo(buf
, " AS %s", quote_identifier(root
->path
->name
));
11844 if (jexpr
->passing_values
)
11848 bool needcomma
= false;
11850 appendStringInfoChar(buf
, ' ');
11851 appendContextKeyword(context
, "PASSING ", 0, 0, 0);
11853 if (PRETTY_INDENT(context
))
11854 context
->indentLevel
+= PRETTYINDENT_VAR
;
11856 forboth(lc1
, jexpr
->passing_names
,
11857 lc2
, jexpr
->passing_values
)
11860 appendStringInfoString(buf
, ", ");
11863 appendContextKeyword(context
, "", 0, 0, 0);
11865 get_rule_expr((Node
*) lfirst(lc2
), context
, false);
11866 appendStringInfo(buf
, " AS %s",
11867 quote_identifier((lfirst_node(String
, lc1
))->sval
)
11871 if (PRETTY_INDENT(context
))
11872 context
->indentLevel
-= PRETTYINDENT_VAR
;
11875 get_json_table_columns(tf
, castNode(JsonTablePathScan
, tf
->plan
), context
,
11878 if (jexpr
->on_error
->btype
!= JSON_BEHAVIOR_EMPTY
)
11879 get_json_behavior(jexpr
->on_error
, context
, "ERROR");
11881 if (PRETTY_INDENT(context
))
11882 context
->indentLevel
-= PRETTYINDENT_VAR
;
11884 appendContextKeyword(context
, ")", 0, 0, 0);
11888 * get_tablefunc - Parse back a table function
11892 get_tablefunc(TableFunc
*tf
, deparse_context
*context
, bool showimplicit
)
11894 /* XMLTABLE and JSON_TABLE are the only existing implementations. */
11896 if (tf
->functype
== TFT_XMLTABLE
)
11897 get_xmltable(tf
, context
, showimplicit
);
11898 else if (tf
->functype
== TFT_JSON_TABLE
)
11899 get_json_table(tf
, context
, showimplicit
);
11903 * get_from_clause - Parse back a FROM clause
11905 * "prefix" is the keyword that denotes the start of the list of FROM
11906 * elements. It is FROM when used to parse back SELECT and UPDATE, but
11907 * is USING when parsing back DELETE.
11911 get_from_clause(Query
*query
, const char *prefix
, deparse_context
*context
)
11913 StringInfo buf
= context
->buf
;
11918 * We use the query's jointree as a guide to what to print. However, we
11919 * must ignore auto-added RTEs that are marked not inFromCl. (These can
11920 * only appear at the top level of the jointree, so it's sufficient to
11921 * check here.) This check also ensures we ignore the rule pseudo-RTEs
11924 foreach(l
, query
->jointree
->fromlist
)
11926 Node
*jtnode
= (Node
*) lfirst(l
);
11928 if (IsA(jtnode
, RangeTblRef
))
11930 int varno
= ((RangeTblRef
*) jtnode
)->rtindex
;
11931 RangeTblEntry
*rte
= rt_fetch(varno
, query
->rtable
);
11933 if (!rte
->inFromCl
)
11939 appendContextKeyword(context
, prefix
,
11940 -PRETTYINDENT_STD
, PRETTYINDENT_STD
, 2);
11943 get_from_clause_item(jtnode
, query
, context
);
11947 StringInfoData itembuf
;
11949 appendStringInfoString(buf
, ", ");
11952 * Put the new FROM item's text into itembuf so we can decide
11953 * after we've got it whether or not it needs to go on a new line.
11955 initStringInfo(&itembuf
);
11956 context
->buf
= &itembuf
;
11958 get_from_clause_item(jtnode
, query
, context
);
11960 /* Restore context's output buffer */
11961 context
->buf
= buf
;
11963 /* Consider line-wrapping if enabled */
11964 if (PRETTY_INDENT(context
) && context
->wrapColumn
>= 0)
11966 /* Does the new item start with a new line? */
11967 if (itembuf
.len
> 0 && itembuf
.data
[0] == '\n')
11969 /* If so, we shouldn't add anything */
11970 /* instead, remove any trailing spaces currently in buf */
11971 removeStringInfoSpaces(buf
);
11977 /* Locate the start of the current line in the buffer */
11978 trailing_nl
= strrchr(buf
->data
, '\n');
11979 if (trailing_nl
== NULL
)
11980 trailing_nl
= buf
->data
;
11985 * Add a newline, plus some indentation, if the new item
11986 * would cause an overflow.
11988 if (strlen(trailing_nl
) + itembuf
.len
> context
->wrapColumn
)
11989 appendContextKeyword(context
, "", -PRETTYINDENT_STD
,
11995 /* Add the new item */
11996 appendBinaryStringInfo(buf
, itembuf
.data
, itembuf
.len
);
11999 pfree(itembuf
.data
);
12005 get_from_clause_item(Node
*jtnode
, Query
*query
, deparse_context
*context
)
12007 StringInfo buf
= context
->buf
;
12008 deparse_namespace
*dpns
= (deparse_namespace
*) linitial(context
->namespaces
);
12010 if (IsA(jtnode
, RangeTblRef
))
12012 int varno
= ((RangeTblRef
*) jtnode
)->rtindex
;
12013 RangeTblEntry
*rte
= rt_fetch(varno
, query
->rtable
);
12014 deparse_columns
*colinfo
= deparse_columns_fetch(varno
, dpns
);
12015 RangeTblFunction
*rtfunc1
= NULL
;
12018 appendStringInfoString(buf
, "LATERAL ");
12020 /* Print the FROM item proper */
12021 switch (rte
->rtekind
)
12024 /* Normal relation RTE */
12025 appendStringInfo(buf
, "%s%s",
12027 generate_relation_name(rte
->relid
,
12028 context
->namespaces
));
12032 appendStringInfoChar(buf
, '(');
12033 get_query_def(rte
->subquery
, buf
, context
->namespaces
, NULL
,
12035 context
->prettyFlags
, context
->wrapColumn
,
12036 context
->indentLevel
);
12037 appendStringInfoChar(buf
, ')');
12041 rtfunc1
= (RangeTblFunction
*) linitial(rte
->functions
);
12044 * Omit ROWS FROM() syntax for just one function, unless it
12045 * has both a coldeflist and WITH ORDINALITY. If it has both,
12046 * we must use ROWS FROM() syntax to avoid ambiguity about
12047 * whether the coldeflist includes the ordinality column.
12049 if (list_length(rte
->functions
) == 1 &&
12050 (rtfunc1
->funccolnames
== NIL
|| !rte
->funcordinality
))
12052 get_rule_expr_funccall(rtfunc1
->funcexpr
, context
, true);
12053 /* we'll print the coldeflist below, if it has one */
12061 * If all the function calls in the list are to unnest,
12062 * and none need a coldeflist, then collapse the list back
12063 * down to UNNEST(args). (If we had more than one
12064 * built-in unnest function, this would get more
12067 * XXX This is pretty ugly, since it makes not-terribly-
12068 * future-proof assumptions about what the parser would do
12069 * with the output; but the alternative is to emit our
12070 * nonstandard ROWS FROM() notation for what might have
12071 * been a perfectly spec-compliant multi-argument
12075 foreach(lc
, rte
->functions
)
12077 RangeTblFunction
*rtfunc
= (RangeTblFunction
*) lfirst(lc
);
12079 if (!IsA(rtfunc
->funcexpr
, FuncExpr
) ||
12080 ((FuncExpr
*) rtfunc
->funcexpr
)->funcid
!= F_UNNEST_ANYARRAY
||
12081 rtfunc
->funccolnames
!= NIL
)
12083 all_unnest
= false;
12090 List
*allargs
= NIL
;
12092 foreach(lc
, rte
->functions
)
12094 RangeTblFunction
*rtfunc
= (RangeTblFunction
*) lfirst(lc
);
12095 List
*args
= ((FuncExpr
*) rtfunc
->funcexpr
)->args
;
12097 allargs
= list_concat(allargs
, args
);
12100 appendStringInfoString(buf
, "UNNEST(");
12101 get_rule_expr((Node
*) allargs
, context
, true);
12102 appendStringInfoChar(buf
, ')');
12108 appendStringInfoString(buf
, "ROWS FROM(");
12109 foreach(lc
, rte
->functions
)
12111 RangeTblFunction
*rtfunc
= (RangeTblFunction
*) lfirst(lc
);
12114 appendStringInfoString(buf
, ", ");
12115 get_rule_expr_funccall(rtfunc
->funcexpr
, context
, true);
12116 if (rtfunc
->funccolnames
!= NIL
)
12118 /* Reconstruct the column definition list */
12119 appendStringInfoString(buf
, " AS ");
12120 get_from_clause_coldeflist(rtfunc
,
12126 appendStringInfoChar(buf
, ')');
12128 /* prevent printing duplicate coldeflist below */
12131 if (rte
->funcordinality
)
12132 appendStringInfoString(buf
, " WITH ORDINALITY");
12134 case RTE_TABLEFUNC
:
12135 get_tablefunc(rte
->tablefunc
, context
, true);
12138 /* Values list RTE */
12139 appendStringInfoChar(buf
, '(');
12140 get_values_def(rte
->values_lists
, context
);
12141 appendStringInfoChar(buf
, ')');
12144 appendStringInfoString(buf
, quote_identifier(rte
->ctename
));
12147 elog(ERROR
, "unrecognized RTE kind: %d", (int) rte
->rtekind
);
12151 /* Print the relation alias, if needed */
12152 get_rte_alias(rte
, varno
, false, context
);
12154 /* Print the column definitions or aliases, if needed */
12155 if (rtfunc1
&& rtfunc1
->funccolnames
!= NIL
)
12157 /* Reconstruct the columndef list, which is also the aliases */
12158 get_from_clause_coldeflist(rtfunc1
, colinfo
, context
);
12162 /* Else print column aliases as needed */
12163 get_column_alias_list(colinfo
, context
);
12166 /* Tablesample clause must go after any alias */
12167 if (rte
->rtekind
== RTE_RELATION
&& rte
->tablesample
)
12168 get_tablesample_def(rte
->tablesample
, context
);
12170 else if (IsA(jtnode
, JoinExpr
))
12172 JoinExpr
*j
= (JoinExpr
*) jtnode
;
12173 deparse_columns
*colinfo
= deparse_columns_fetch(j
->rtindex
, dpns
);
12174 bool need_paren_on_right
;
12176 need_paren_on_right
= PRETTY_PAREN(context
) &&
12177 !IsA(j
->rarg
, RangeTblRef
) &&
12178 !(IsA(j
->rarg
, JoinExpr
) && ((JoinExpr
*) j
->rarg
)->alias
!= NULL
);
12180 if (!PRETTY_PAREN(context
) || j
->alias
!= NULL
)
12181 appendStringInfoChar(buf
, '(');
12183 get_from_clause_item(j
->larg
, query
, context
);
12185 switch (j
->jointype
)
12189 appendContextKeyword(context
, " JOIN ",
12192 PRETTYINDENT_JOIN
);
12194 appendContextKeyword(context
, " CROSS JOIN ",
12197 PRETTYINDENT_JOIN
);
12200 appendContextKeyword(context
, " LEFT JOIN ",
12203 PRETTYINDENT_JOIN
);
12206 appendContextKeyword(context
, " FULL JOIN ",
12209 PRETTYINDENT_JOIN
);
12212 appendContextKeyword(context
, " RIGHT JOIN ",
12215 PRETTYINDENT_JOIN
);
12218 elog(ERROR
, "unrecognized join type: %d",
12219 (int) j
->jointype
);
12222 if (need_paren_on_right
)
12223 appendStringInfoChar(buf
, '(');
12224 get_from_clause_item(j
->rarg
, query
, context
);
12225 if (need_paren_on_right
)
12226 appendStringInfoChar(buf
, ')');
12228 if (j
->usingClause
)
12233 appendStringInfoString(buf
, " USING (");
12234 /* Use the assigned names, not what's in usingClause */
12235 foreach(lc
, colinfo
->usingNames
)
12237 char *colname
= (char *) lfirst(lc
);
12242 appendStringInfoString(buf
, ", ");
12243 appendStringInfoString(buf
, quote_identifier(colname
));
12245 appendStringInfoChar(buf
, ')');
12247 if (j
->join_using_alias
)
12248 appendStringInfo(buf
, " AS %s",
12249 quote_identifier(j
->join_using_alias
->aliasname
));
12253 appendStringInfoString(buf
, " ON ");
12254 if (!PRETTY_PAREN(context
))
12255 appendStringInfoChar(buf
, '(');
12256 get_rule_expr(j
->quals
, context
, false);
12257 if (!PRETTY_PAREN(context
))
12258 appendStringInfoChar(buf
, ')');
12260 else if (j
->jointype
!= JOIN_INNER
)
12262 /* If we didn't say CROSS JOIN above, we must provide an ON */
12263 appendStringInfoString(buf
, " ON TRUE");
12266 if (!PRETTY_PAREN(context
) || j
->alias
!= NULL
)
12267 appendStringInfoChar(buf
, ')');
12269 /* Yes, it's correct to put alias after the right paren ... */
12270 if (j
->alias
!= NULL
)
12273 * Note that it's correct to emit an alias clause if and only if
12274 * there was one originally. Otherwise we'd be converting a named
12275 * join to unnamed or vice versa, which creates semantic
12276 * subtleties we don't want. However, we might print a different
12277 * alias name than was there originally.
12279 appendStringInfo(buf
, " %s",
12280 quote_identifier(get_rtable_name(j
->rtindex
,
12282 get_column_alias_list(colinfo
, context
);
12286 elog(ERROR
, "unrecognized node type: %d",
12287 (int) nodeTag(jtnode
));
12291 * get_rte_alias - print the relation's alias, if needed
12293 * If printed, the alias is preceded by a space, or by " AS " if use_as is true.
12296 get_rte_alias(RangeTblEntry
*rte
, int varno
, bool use_as
,
12297 deparse_context
*context
)
12299 deparse_namespace
*dpns
= (deparse_namespace
*) linitial(context
->namespaces
);
12300 char *refname
= get_rtable_name(varno
, context
);
12301 deparse_columns
*colinfo
= deparse_columns_fetch(varno
, dpns
);
12302 bool printalias
= false;
12304 if (rte
->alias
!= NULL
)
12306 /* Always print alias if user provided one */
12309 else if (colinfo
->printaliases
)
12311 /* Always print alias if we need to print column aliases */
12314 else if (rte
->rtekind
== RTE_RELATION
)
12317 * No need to print alias if it's same as relation name (this would
12318 * normally be the case, but not if set_rtable_names had to resolve a
12321 if (strcmp(refname
, get_relation_name(rte
->relid
)) != 0)
12324 else if (rte
->rtekind
== RTE_FUNCTION
)
12327 * For a function RTE, always print alias. This covers possible
12328 * renaming of the function and/or instability of the FigureColname
12329 * rules for things that aren't simple functions. Note we'd need to
12330 * force it anyway for the columndef list case.
12334 else if (rte
->rtekind
== RTE_SUBQUERY
||
12335 rte
->rtekind
== RTE_VALUES
)
12338 * For a subquery, always print alias. This makes the output
12339 * SQL-spec-compliant, even though we allow such aliases to be omitted
12344 else if (rte
->rtekind
== RTE_CTE
)
12347 * No need to print alias if it's same as CTE name (this would
12348 * normally be the case, but not if set_rtable_names had to resolve a
12351 if (strcmp(refname
, rte
->ctename
) != 0)
12356 appendStringInfo(context
->buf
, "%s%s",
12357 use_as
? " AS " : " ",
12358 quote_identifier(refname
));
12362 * get_column_alias_list - print column alias list for an RTE
12364 * Caller must already have printed the relation's alias name.
12367 get_column_alias_list(deparse_columns
*colinfo
, deparse_context
*context
)
12369 StringInfo buf
= context
->buf
;
12373 /* Don't print aliases if not needed */
12374 if (!colinfo
->printaliases
)
12377 for (i
= 0; i
< colinfo
->num_new_cols
; i
++)
12379 char *colname
= colinfo
->new_colnames
[i
];
12383 appendStringInfoChar(buf
, '(');
12387 appendStringInfoString(buf
, ", ");
12388 appendStringInfoString(buf
, quote_identifier(colname
));
12391 appendStringInfoChar(buf
, ')');
12395 * get_from_clause_coldeflist - reproduce FROM clause coldeflist
12397 * When printing a top-level coldeflist (which is syntactically also the
12398 * relation's column alias list), use column names from colinfo. But when
12399 * printing a coldeflist embedded inside ROWS FROM(), we prefer to use the
12400 * original coldeflist's names, which are available in rtfunc->funccolnames.
12401 * Pass NULL for colinfo to select the latter behavior.
12403 * The coldeflist is appended immediately (no space) to buf. Caller is
12404 * responsible for ensuring that an alias or AS is present before it.
12407 get_from_clause_coldeflist(RangeTblFunction
*rtfunc
,
12408 deparse_columns
*colinfo
,
12409 deparse_context
*context
)
12411 StringInfo buf
= context
->buf
;
12418 appendStringInfoChar(buf
, '(');
12421 forfour(l1
, rtfunc
->funccoltypes
,
12422 l2
, rtfunc
->funccoltypmods
,
12423 l3
, rtfunc
->funccolcollations
,
12424 l4
, rtfunc
->funccolnames
)
12426 Oid atttypid
= lfirst_oid(l1
);
12427 int32 atttypmod
= lfirst_int(l2
);
12428 Oid attcollation
= lfirst_oid(l3
);
12432 attname
= colinfo
->colnames
[i
];
12434 attname
= strVal(lfirst(l4
));
12436 Assert(attname
); /* shouldn't be any dropped columns here */
12439 appendStringInfoString(buf
, ", ");
12440 appendStringInfo(buf
, "%s %s",
12441 quote_identifier(attname
),
12442 format_type_with_typemod(atttypid
, atttypmod
));
12443 if (OidIsValid(attcollation
) &&
12444 attcollation
!= get_typcollation(atttypid
))
12445 appendStringInfo(buf
, " COLLATE %s",
12446 generate_collation_name(attcollation
));
12451 appendStringInfoChar(buf
, ')');
12455 * get_tablesample_def - print a TableSampleClause
12458 get_tablesample_def(TableSampleClause
*tablesample
, deparse_context
*context
)
12460 StringInfo buf
= context
->buf
;
12466 * We should qualify the handler's function name if it wouldn't be
12467 * resolved by lookup in the current search path.
12469 argtypes
[0] = INTERNALOID
;
12470 appendStringInfo(buf
, " TABLESAMPLE %s (",
12471 generate_function_name(tablesample
->tsmhandler
, 1,
12473 false, NULL
, false));
12476 foreach(l
, tablesample
->args
)
12479 appendStringInfoString(buf
, ", ");
12480 get_rule_expr((Node
*) lfirst(l
), context
, false);
12482 appendStringInfoChar(buf
, ')');
12484 if (tablesample
->repeatable
!= NULL
)
12486 appendStringInfoString(buf
, " REPEATABLE (");
12487 get_rule_expr((Node
*) tablesample
->repeatable
, context
, false);
12488 appendStringInfoChar(buf
, ')');
12493 * get_opclass_name - fetch name of an index operator class
12495 * The opclass name is appended (after a space) to buf.
12497 * Output is suppressed if the opclass is the default for the given
12498 * actual_datatype. (If you don't want this behavior, just pass
12499 * InvalidOid for actual_datatype.)
12502 get_opclass_name(Oid opclass
, Oid actual_datatype
,
12506 Form_pg_opclass opcrec
;
12510 ht_opc
= SearchSysCache1(CLAOID
, ObjectIdGetDatum(opclass
));
12511 if (!HeapTupleIsValid(ht_opc
))
12512 elog(ERROR
, "cache lookup failed for opclass %u", opclass
);
12513 opcrec
= (Form_pg_opclass
) GETSTRUCT(ht_opc
);
12515 if (!OidIsValid(actual_datatype
) ||
12516 GetDefaultOpClass(actual_datatype
, opcrec
->opcmethod
) != opclass
)
12518 /* Okay, we need the opclass name. Do we need to qualify it? */
12519 opcname
= NameStr(opcrec
->opcname
);
12520 if (OpclassIsVisible(opclass
))
12521 appendStringInfo(buf
, " %s", quote_identifier(opcname
));
12524 nspname
= get_namespace_name_or_temp(opcrec
->opcnamespace
);
12525 appendStringInfo(buf
, " %s.%s",
12526 quote_identifier(nspname
),
12527 quote_identifier(opcname
));
12530 ReleaseSysCache(ht_opc
);
12534 * generate_opclass_name
12535 * Compute the name to display for an opclass specified by OID
12537 * The result includes all necessary quoting and schema-prefixing.
12540 generate_opclass_name(Oid opclass
)
12542 StringInfoData buf
;
12544 initStringInfo(&buf
);
12545 get_opclass_name(opclass
, InvalidOid
, &buf
);
12547 return &buf
.data
[1]; /* get_opclass_name() prepends space */
12551 * processIndirection - take care of array and subfield assignment
12553 * We strip any top-level FieldStore or assignment SubscriptingRef nodes that
12554 * appear in the input, printing them as decoration for the base column
12555 * name (which we assume the caller just printed). We might also need to
12556 * strip CoerceToDomain nodes, but only ones that appear above assignment
12559 * Returns the subexpression that's to be assigned.
12562 processIndirection(Node
*node
, deparse_context
*context
)
12564 StringInfo buf
= context
->buf
;
12565 CoerceToDomain
*cdomain
= NULL
;
12571 if (IsA(node
, FieldStore
))
12573 FieldStore
*fstore
= (FieldStore
*) node
;
12577 /* lookup tuple type */
12578 typrelid
= get_typ_typrelid(fstore
->resulttype
);
12579 if (!OidIsValid(typrelid
))
12580 elog(ERROR
, "argument type %s of FieldStore is not a tuple type",
12581 format_type_be(fstore
->resulttype
));
12584 * Print the field name. There should only be one target field in
12585 * stored rules. There could be more than that in executable
12586 * target lists, but this function cannot be used for that case.
12588 Assert(list_length(fstore
->fieldnums
) == 1);
12589 fieldname
= get_attname(typrelid
,
12590 linitial_int(fstore
->fieldnums
), false);
12591 appendStringInfo(buf
, ".%s", quote_identifier(fieldname
));
12594 * We ignore arg since it should be an uninteresting reference to
12595 * the target column or subcolumn.
12597 node
= (Node
*) linitial(fstore
->newvals
);
12599 else if (IsA(node
, SubscriptingRef
))
12601 SubscriptingRef
*sbsref
= (SubscriptingRef
*) node
;
12603 if (sbsref
->refassgnexpr
== NULL
)
12606 printSubscripts(sbsref
, context
);
12609 * We ignore refexpr since it should be an uninteresting reference
12610 * to the target column or subcolumn.
12612 node
= (Node
*) sbsref
->refassgnexpr
;
12614 else if (IsA(node
, CoerceToDomain
))
12616 cdomain
= (CoerceToDomain
*) node
;
12617 /* If it's an explicit domain coercion, we're done */
12618 if (cdomain
->coercionformat
!= COERCE_IMPLICIT_CAST
)
12620 /* Tentatively descend past the CoerceToDomain */
12621 node
= (Node
*) cdomain
->arg
;
12628 * If we descended past a CoerceToDomain whose argument turned out not to
12629 * be a FieldStore or array assignment, back up to the CoerceToDomain.
12630 * (This is not enough to be fully correct if there are nested implicit
12631 * CoerceToDomains, but such cases shouldn't ever occur.)
12633 if (cdomain
&& node
== (Node
*) cdomain
->arg
)
12634 node
= (Node
*) cdomain
;
12640 printSubscripts(SubscriptingRef
*sbsref
, deparse_context
*context
)
12642 StringInfo buf
= context
->buf
;
12643 ListCell
*lowlist_item
;
12644 ListCell
*uplist_item
;
12646 lowlist_item
= list_head(sbsref
->reflowerindexpr
); /* could be NULL */
12647 foreach(uplist_item
, sbsref
->refupperindexpr
)
12649 appendStringInfoChar(buf
, '[');
12652 /* If subexpression is NULL, get_rule_expr prints nothing */
12653 get_rule_expr((Node
*) lfirst(lowlist_item
), context
, false);
12654 appendStringInfoChar(buf
, ':');
12655 lowlist_item
= lnext(sbsref
->reflowerindexpr
, lowlist_item
);
12657 /* If subexpression is NULL, get_rule_expr prints nothing */
12658 get_rule_expr((Node
*) lfirst(uplist_item
), context
, false);
12659 appendStringInfoChar(buf
, ']');
12664 * quote_identifier - Quote an identifier only if needed
12666 * When quotes are needed, we palloc the required space; slightly
12667 * space-wasteful but well worth it for notational simplicity.
12670 quote_identifier(const char *ident
)
12673 * Can avoid quoting if ident starts with a lowercase letter or underscore
12674 * and contains only lowercase letters, digits, and underscores, *and* is
12675 * not any SQL keyword. Otherwise, supply quotes.
12684 * would like to use <ctype.h> macros here, but they might yield unwanted
12685 * locale-specific results...
12687 safe
= ((ident
[0] >= 'a' && ident
[0] <= 'z') || ident
[0] == '_');
12689 for (ptr
= ident
; *ptr
; ptr
++)
12693 if ((ch
>= 'a' && ch
<= 'z') ||
12694 (ch
>= '0' && ch
<= '9') ||
12707 if (quote_all_identifiers
)
12713 * Check for keyword. We quote keywords except for unreserved ones.
12714 * (In some cases we could avoid quoting a col_name or type_func_name
12715 * keyword, but it seems much harder than it's worth to tell that.)
12717 * Note: ScanKeywordLookup() does case-insensitive comparison, but
12718 * that's fine, since we already know we have all-lower-case.
12720 int kwnum
= ScanKeywordLookup(ident
, &ScanKeywords
);
12722 if (kwnum
>= 0 && ScanKeywordCategories
[kwnum
] != UNRESERVED_KEYWORD
)
12727 return ident
; /* no change needed */
12729 result
= (char *) palloc(strlen(ident
) + nquotes
+ 2 + 1);
12733 for (ptr
= ident
; *ptr
; ptr
++)
12748 * quote_qualified_identifier - Quote a possibly-qualified identifier
12750 * Return a name of the form qualifier.ident, or just ident if qualifier
12751 * is NULL, quoting each component if necessary. The result is palloc'd.
12754 quote_qualified_identifier(const char *qualifier
,
12757 StringInfoData buf
;
12759 initStringInfo(&buf
);
12761 appendStringInfo(&buf
, "%s.", quote_identifier(qualifier
));
12762 appendStringInfoString(&buf
, quote_identifier(ident
));
12767 * get_relation_name
12768 * Get the unqualified name of a relation specified by OID
12770 * This differs from the underlying get_rel_name() function in that it will
12771 * throw error instead of silently returning NULL if the OID is bad.
12774 get_relation_name(Oid relid
)
12776 char *relname
= get_rel_name(relid
);
12779 elog(ERROR
, "cache lookup failed for relation %u", relid
);
12784 * generate_relation_name
12785 * Compute the name to display for a relation specified by OID
12787 * The result includes all necessary quoting and schema-prefixing.
12789 * If namespaces isn't NIL, it must be a list of deparse_namespace nodes.
12790 * We will forcibly qualify the relation name if it equals any CTE name
12791 * visible in the namespace list.
12794 generate_relation_name(Oid relid
, List
*namespaces
)
12797 Form_pg_class reltup
;
12804 tp
= SearchSysCache1(RELOID
, ObjectIdGetDatum(relid
));
12805 if (!HeapTupleIsValid(tp
))
12806 elog(ERROR
, "cache lookup failed for relation %u", relid
);
12807 reltup
= (Form_pg_class
) GETSTRUCT(tp
);
12808 relname
= NameStr(reltup
->relname
);
12810 /* Check for conflicting CTE name */
12812 foreach(nslist
, namespaces
)
12814 deparse_namespace
*dpns
= (deparse_namespace
*) lfirst(nslist
);
12817 foreach(ctlist
, dpns
->ctes
)
12819 CommonTableExpr
*cte
= (CommonTableExpr
*) lfirst(ctlist
);
12821 if (strcmp(cte
->ctename
, relname
) == 0)
12831 /* Otherwise, qualify the name if not visible in search path */
12833 need_qual
= !RelationIsVisible(relid
);
12836 nspname
= get_namespace_name_or_temp(reltup
->relnamespace
);
12840 result
= quote_qualified_identifier(nspname
, relname
);
12842 ReleaseSysCache(tp
);
12848 * generate_qualified_relation_name
12849 * Compute the name to display for a relation specified by OID
12851 * As above, but unconditionally schema-qualify the name.
12854 generate_qualified_relation_name(Oid relid
)
12857 Form_pg_class reltup
;
12862 tp
= SearchSysCache1(RELOID
, ObjectIdGetDatum(relid
));
12863 if (!HeapTupleIsValid(tp
))
12864 elog(ERROR
, "cache lookup failed for relation %u", relid
);
12865 reltup
= (Form_pg_class
) GETSTRUCT(tp
);
12866 relname
= NameStr(reltup
->relname
);
12868 nspname
= get_namespace_name_or_temp(reltup
->relnamespace
);
12870 elog(ERROR
, "cache lookup failed for namespace %u",
12871 reltup
->relnamespace
);
12873 result
= quote_qualified_identifier(nspname
, relname
);
12875 ReleaseSysCache(tp
);
12881 * generate_function_name
12882 * Compute the name to display for a function specified by OID,
12883 * given that it is being called with the specified actual arg names and
12884 * types. (Those matter because of ambiguous-function resolution rules.)
12886 * If we're dealing with a potentially variadic function (in practice, this
12887 * means a FuncExpr or Aggref, not some other way of calling a function), then
12888 * has_variadic must specify whether variadic arguments have been merged,
12889 * and *use_variadic_p will be set to indicate whether to print VARIADIC in
12890 * the output. For non-FuncExpr cases, has_variadic should be false and
12891 * use_variadic_p can be NULL.
12893 * inGroupBy must be true if we're deparsing a GROUP BY clause.
12895 * The result includes all necessary quoting and schema-prefixing.
12898 generate_function_name(Oid funcid
, int nargs
, List
*argnames
, Oid
*argtypes
,
12899 bool has_variadic
, bool *use_variadic_p
,
12904 Form_pg_proc procform
;
12908 FuncDetailCode p_result
;
12914 Oid
*p_true_typeids
;
12915 bool force_qualify
= false;
12917 proctup
= SearchSysCache1(PROCOID
, ObjectIdGetDatum(funcid
));
12918 if (!HeapTupleIsValid(proctup
))
12919 elog(ERROR
, "cache lookup failed for function %u", funcid
);
12920 procform
= (Form_pg_proc
) GETSTRUCT(proctup
);
12921 proname
= NameStr(procform
->proname
);
12924 * Due to parser hacks to avoid needing to reserve CUBE, we need to force
12925 * qualification of some function names within GROUP BY.
12929 if (strcmp(proname
, "cube") == 0 || strcmp(proname
, "rollup") == 0)
12930 force_qualify
= true;
12934 * Determine whether VARIADIC should be printed. We must do this first
12935 * since it affects the lookup rules in func_get_detail().
12937 * We always print VARIADIC if the function has a merged variadic-array
12938 * argument. Note that this is always the case for functions taking a
12939 * VARIADIC argument type other than VARIADIC ANY. If we omitted VARIADIC
12940 * and printed the array elements as separate arguments, the call could
12941 * match a newer non-VARIADIC function.
12943 if (use_variadic_p
)
12945 /* Parser should not have set funcvariadic unless fn is variadic */
12946 Assert(!has_variadic
|| OidIsValid(procform
->provariadic
));
12947 use_variadic
= has_variadic
;
12948 *use_variadic_p
= use_variadic
;
12952 Assert(!has_variadic
);
12953 use_variadic
= false;
12957 * The idea here is to schema-qualify only if the parser would fail to
12958 * resolve the correct function given the unqualified func name with the
12959 * specified argtypes and VARIADIC flag. But if we already decided to
12960 * force qualification, then we can skip the lookup and pretend we didn't
12963 if (!force_qualify
)
12964 p_result
= func_get_detail(list_make1(makeString(proname
)),
12965 NIL
, argnames
, nargs
, argtypes
,
12966 !use_variadic
, true, false,
12967 &p_funcid
, &p_rettype
,
12968 &p_retset
, &p_nvargs
, &p_vatype
,
12969 &p_true_typeids
, NULL
);
12972 p_result
= FUNCDETAIL_NOTFOUND
;
12973 p_funcid
= InvalidOid
;
12976 if ((p_result
== FUNCDETAIL_NORMAL
||
12977 p_result
== FUNCDETAIL_AGGREGATE
||
12978 p_result
== FUNCDETAIL_WINDOWFUNC
) &&
12979 p_funcid
== funcid
)
12982 nspname
= get_namespace_name_or_temp(procform
->pronamespace
);
12984 result
= quote_qualified_identifier(nspname
, proname
);
12986 ReleaseSysCache(proctup
);
12992 * generate_operator_name
12993 * Compute the name to display for an operator specified by OID,
12994 * given that it is being called with the specified actual arg types.
12995 * (Arg types matter because of ambiguous-operator resolution rules.
12996 * Pass InvalidOid for unused arg of a unary operator.)
12998 * The result includes all necessary quoting and schema-prefixing,
12999 * plus the OPERATOR() decoration needed to use a qualified operator name
13000 * in an expression.
13003 generate_operator_name(Oid operid
, Oid arg1
, Oid arg2
)
13005 StringInfoData buf
;
13007 Form_pg_operator operform
;
13012 initStringInfo(&buf
);
13014 opertup
= SearchSysCache1(OPEROID
, ObjectIdGetDatum(operid
));
13015 if (!HeapTupleIsValid(opertup
))
13016 elog(ERROR
, "cache lookup failed for operator %u", operid
);
13017 operform
= (Form_pg_operator
) GETSTRUCT(opertup
);
13018 oprname
= NameStr(operform
->oprname
);
13021 * The idea here is to schema-qualify only if the parser would fail to
13022 * resolve the correct operator given the unqualified op name with the
13023 * specified argtypes.
13025 switch (operform
->oprkind
)
13028 p_result
= oper(NULL
, list_make1(makeString(oprname
)), arg1
, arg2
,
13032 p_result
= left_oper(NULL
, list_make1(makeString(oprname
)), arg2
,
13036 elog(ERROR
, "unrecognized oprkind: %d", operform
->oprkind
);
13037 p_result
= NULL
; /* keep compiler quiet */
13041 if (p_result
!= NULL
&& oprid(p_result
) == operid
)
13045 nspname
= get_namespace_name_or_temp(operform
->oprnamespace
);
13046 appendStringInfo(&buf
, "OPERATOR(%s.", quote_identifier(nspname
));
13049 appendStringInfoString(&buf
, oprname
);
13052 appendStringInfoChar(&buf
, ')');
13054 if (p_result
!= NULL
)
13055 ReleaseSysCache(p_result
);
13057 ReleaseSysCache(opertup
);
13063 * generate_operator_clause --- generate a binary-operator WHERE clause
13065 * This is used for internally-generated-and-executed SQL queries, where
13066 * precision is essential and readability is secondary. The basic
13067 * requirement is to append "leftop op rightop" to buf, where leftop and
13068 * rightop are given as strings and are assumed to yield types leftoptype
13069 * and rightoptype; the operator is identified by OID. The complexity
13070 * comes from needing to be sure that the parser will select the desired
13071 * operator when the query is parsed. We always name the operator using
13072 * OPERATOR(schema.op) syntax, so as to avoid search-path uncertainties.
13073 * We have to emit casts too, if either input isn't already the input type
13074 * of the operator; else we are at the mercy of the parser's heuristics for
13075 * ambiguous-operator resolution. The caller must ensure that leftop and
13076 * rightop are suitable arguments for a cast operation; it's best to insert
13077 * parentheses if they aren't just variables or parameters.
13080 generate_operator_clause(StringInfo buf
,
13081 const char *leftop
, Oid leftoptype
,
13083 const char *rightop
, Oid rightoptype
)
13086 Form_pg_operator operform
;
13090 opertup
= SearchSysCache1(OPEROID
, ObjectIdGetDatum(opoid
));
13091 if (!HeapTupleIsValid(opertup
))
13092 elog(ERROR
, "cache lookup failed for operator %u", opoid
);
13093 operform
= (Form_pg_operator
) GETSTRUCT(opertup
);
13094 Assert(operform
->oprkind
== 'b');
13095 oprname
= NameStr(operform
->oprname
);
13097 nspname
= get_namespace_name(operform
->oprnamespace
);
13099 appendStringInfoString(buf
, leftop
);
13100 if (leftoptype
!= operform
->oprleft
)
13101 add_cast_to(buf
, operform
->oprleft
);
13102 appendStringInfo(buf
, " OPERATOR(%s.", quote_identifier(nspname
));
13103 appendStringInfoString(buf
, oprname
);
13104 appendStringInfo(buf
, ") %s", rightop
);
13105 if (rightoptype
!= operform
->oprright
)
13106 add_cast_to(buf
, operform
->oprright
);
13108 ReleaseSysCache(opertup
);
13112 * Add a cast specification to buf. We spell out the type name the hard way,
13113 * intentionally not using format_type_be(). This is to avoid corner cases
13114 * for CHARACTER, BIT, and perhaps other types, where specifying the type
13115 * using SQL-standard syntax results in undesirable data truncation. By
13116 * doing it this way we can be certain that the cast will have default (-1)
13120 add_cast_to(StringInfo buf
, Oid typid
)
13123 Form_pg_type typform
;
13127 typetup
= SearchSysCache1(TYPEOID
, ObjectIdGetDatum(typid
));
13128 if (!HeapTupleIsValid(typetup
))
13129 elog(ERROR
, "cache lookup failed for type %u", typid
);
13130 typform
= (Form_pg_type
) GETSTRUCT(typetup
);
13132 typname
= NameStr(typform
->typname
);
13133 nspname
= get_namespace_name_or_temp(typform
->typnamespace
);
13135 appendStringInfo(buf
, "::%s.%s",
13136 quote_identifier(nspname
), quote_identifier(typname
));
13138 ReleaseSysCache(typetup
);
13142 * generate_qualified_type_name
13143 * Compute the name to display for a type specified by OID
13145 * This is different from format_type_be() in that we unconditionally
13146 * schema-qualify the name. That also means no special syntax for
13147 * SQL-standard type names ... although in current usage, this should
13148 * only get used for domains, so such cases wouldn't occur anyway.
13151 generate_qualified_type_name(Oid typid
)
13154 Form_pg_type typtup
;
13159 tp
= SearchSysCache1(TYPEOID
, ObjectIdGetDatum(typid
));
13160 if (!HeapTupleIsValid(tp
))
13161 elog(ERROR
, "cache lookup failed for type %u", typid
);
13162 typtup
= (Form_pg_type
) GETSTRUCT(tp
);
13163 typname
= NameStr(typtup
->typname
);
13165 nspname
= get_namespace_name_or_temp(typtup
->typnamespace
);
13167 elog(ERROR
, "cache lookup failed for namespace %u",
13168 typtup
->typnamespace
);
13170 result
= quote_qualified_identifier(nspname
, typname
);
13172 ReleaseSysCache(tp
);
13178 * generate_collation_name
13179 * Compute the name to display for a collation specified by OID
13181 * The result includes all necessary quoting and schema-prefixing.
13184 generate_collation_name(Oid collid
)
13187 Form_pg_collation colltup
;
13192 tp
= SearchSysCache1(COLLOID
, ObjectIdGetDatum(collid
));
13193 if (!HeapTupleIsValid(tp
))
13194 elog(ERROR
, "cache lookup failed for collation %u", collid
);
13195 colltup
= (Form_pg_collation
) GETSTRUCT(tp
);
13196 collname
= NameStr(colltup
->collname
);
13198 if (!CollationIsVisible(collid
))
13199 nspname
= get_namespace_name_or_temp(colltup
->collnamespace
);
13203 result
= quote_qualified_identifier(nspname
, collname
);
13205 ReleaseSysCache(tp
);
13211 * Given a C string, produce a TEXT datum.
13213 * We assume that the input was palloc'd and may be freed.
13216 string_to_text(char *str
)
13220 result
= cstring_to_text(str
);
13226 * Generate a C string representing a relation options from text[] datum.
13229 get_reloptions(StringInfo buf
, Datum reloptions
)
13235 deconstruct_array_builtin(DatumGetArrayTypeP(reloptions
), TEXTOID
,
13236 &options
, NULL
, &noptions
);
13238 for (i
= 0; i
< noptions
; i
++)
13240 char *option
= TextDatumGetCString(options
[i
]);
13246 * Each array element should have the form name=value. If the "=" is
13247 * missing for some reason, treat it like an empty value.
13250 separator
= strchr(option
, '=');
13254 value
= separator
+ 1;
13260 appendStringInfoString(buf
, ", ");
13261 appendStringInfo(buf
, "%s=", quote_identifier(name
));
13264 * In general we need to quote the value; but to avoid unnecessary
13265 * clutter, do not quote if it is an identifier that would not need
13266 * quoting. (We could also allow numbers, but that is a bit trickier
13267 * than it looks --- for example, are leading zeroes significant? We
13268 * don't want to assume very much here about what custom reloptions
13271 if (quote_identifier(value
) == value
)
13272 appendStringInfoString(buf
, value
);
13274 simple_quote_literal(buf
, value
);
13281 * Generate a C string representing a relation's reloptions, or NULL if none.
13284 flatten_reloptions(Oid relid
)
13286 char *result
= NULL
;
13291 tuple
= SearchSysCache1(RELOID
, ObjectIdGetDatum(relid
));
13292 if (!HeapTupleIsValid(tuple
))
13293 elog(ERROR
, "cache lookup failed for relation %u", relid
);
13295 reloptions
= SysCacheGetAttr(RELOID
, tuple
,
13296 Anum_pg_class_reloptions
, &isnull
);
13299 StringInfoData buf
;
13301 initStringInfo(&buf
);
13302 get_reloptions(&buf
, reloptions
);
13307 ReleaseSysCache(tuple
);
13313 * get_range_partbound_string
13314 * A C string representation of one range partition bound
13317 get_range_partbound_string(List
*bound_datums
)
13319 deparse_context context
;
13320 StringInfo buf
= makeStringInfo();
13324 memset(&context
, 0, sizeof(deparse_context
));
13327 appendStringInfoChar(buf
, '(');
13329 foreach(cell
, bound_datums
)
13331 PartitionRangeDatum
*datum
=
13332 lfirst_node(PartitionRangeDatum
, cell
);
13334 appendStringInfoString(buf
, sep
);
13335 if (datum
->kind
== PARTITION_RANGE_DATUM_MINVALUE
)
13336 appendStringInfoString(buf
, "MINVALUE");
13337 else if (datum
->kind
== PARTITION_RANGE_DATUM_MAXVALUE
)
13338 appendStringInfoString(buf
, "MAXVALUE");
13341 Const
*val
= castNode(Const
, datum
->value
);
13343 get_const_expr(val
, &context
, -1);
13347 appendStringInfoChar(buf
, ')');