Line data Source code
1 : /*-------------------------------------------------------------------------
2 : *
3 : * nodeFuncs.h
4 : * Various general-purpose manipulations of Node trees
5 : *
6 : * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
7 : * Portions Copyright (c) 1994, Regents of the University of California
8 : *
9 : * src/include/nodes/nodeFuncs.h
10 : *
11 : *-------------------------------------------------------------------------
12 : */
13 : #ifndef NODEFUNCS_H
14 : #define NODEFUNCS_H
15 :
16 : #include "nodes/parsenodes.h"
17 :
18 : struct PlanState; /* avoid including execnodes.h too */
19 :
20 :
21 : /* flags bits for query_tree_walker and query_tree_mutator */
22 : #define QTW_IGNORE_RT_SUBQUERIES 0x01 /* subqueries in rtable */
23 : #define QTW_IGNORE_CTE_SUBQUERIES 0x02 /* subqueries in cteList */
24 : #define QTW_IGNORE_RC_SUBQUERIES 0x03 /* both of above */
25 : #define QTW_IGNORE_JOINALIASES 0x04 /* JOIN alias var lists */
26 : #define QTW_IGNORE_RANGE_TABLE 0x08 /* skip rangetable entirely */
27 : #define QTW_EXAMINE_RTES_BEFORE 0x10 /* examine RTE nodes before their
28 : * contents */
29 : #define QTW_EXAMINE_RTES_AFTER 0x20 /* examine RTE nodes after their
30 : * contents */
31 : #define QTW_DONT_COPY_QUERY 0x40 /* do not copy top Query */
32 : #define QTW_EXAMINE_SORTGROUP 0x80 /* include SortGroupClause lists */
33 :
34 : #define QTW_IGNORE_GROUPEXPRS 0x100 /* GROUP expressions list */
35 :
36 : /* callback function for check_functions_in_node */
37 : typedef bool (*check_function_callback) (Oid func_id, void *context);
38 :
39 : /* callback functions for tree walkers */
40 : typedef bool (*tree_walker_callback) (Node *node, void *context);
41 : typedef bool (*planstate_tree_walker_callback) (struct PlanState *planstate,
42 : void *context);
43 :
44 : /* callback functions for tree mutators */
45 : typedef Node *(*tree_mutator_callback) (Node *node, void *context);
46 :
47 :
48 : extern Oid exprType(const Node *expr);
49 : extern int32 exprTypmod(const Node *expr);
50 : extern bool exprIsLengthCoercion(const Node *expr, int32 *coercedTypmod);
51 : extern Node *applyRelabelType(Node *arg, Oid rtype, int32 rtypmod, Oid rcollid,
52 : CoercionForm rformat, int rlocation,
53 : bool overwrite_ok);
54 : extern Node *relabel_to_typmod(Node *expr, int32 typmod);
55 : extern Node *strip_implicit_coercions(Node *node);
56 : extern bool expression_returns_set(Node *clause);
57 :
58 : extern Oid exprCollation(const Node *expr);
59 : extern Oid exprInputCollation(const Node *expr);
60 : extern void exprSetCollation(Node *expr, Oid collation);
61 : extern void exprSetInputCollation(Node *expr, Oid inputcollation);
62 :
63 : extern int exprLocation(const Node *expr);
64 :
65 : extern void fix_opfuncids(Node *node);
66 : extern void set_opfuncid(OpExpr *opexpr);
67 : extern void set_sa_opfuncid(ScalarArrayOpExpr *opexpr);
68 :
69 : /* Is clause a FuncExpr clause? */
70 : static inline bool
71 66414 : is_funcclause(const void *clause)
72 : {
73 66414 : return clause != NULL && IsA(clause, FuncExpr);
74 : }
75 :
76 : /* Is clause an OpExpr clause? */
77 : static inline bool
78 4274280 : is_opclause(const void *clause)
79 : {
80 4274280 : return clause != NULL && IsA(clause, OpExpr);
81 : }
82 :
83 : /* Extract left arg of a binary opclause, or only arg of a unary opclause */
84 : static inline Node *
85 1536252 : get_leftop(const void *clause)
86 : {
87 1536252 : const OpExpr *expr = (const OpExpr *) clause;
88 :
89 1536252 : if (expr->args != NIL)
90 1536252 : return (Node *) linitial(expr->args);
91 : else
92 0 : return NULL;
93 : }
94 :
95 : /* Extract right arg of a binary opclause (NULL if it's a unary opclause) */
96 : static inline Node *
97 1460776 : get_rightop(const void *clause)
98 : {
99 1460776 : const OpExpr *expr = (const OpExpr *) clause;
100 :
101 1460776 : if (list_length(expr->args) >= 2)
102 1460776 : return (Node *) lsecond(expr->args);
103 : else
104 0 : return NULL;
105 : }
106 :
107 : /* Is clause an AND clause? */
108 : static inline bool
109 5289508 : is_andclause(const void *clause)
110 : {
111 5289508 : return (clause != NULL &&
112 5691150 : IsA(clause, BoolExpr) &&
113 401642 : ((const BoolExpr *) clause)->boolop == AND_EXPR);
114 : }
115 :
116 : /* Is clause an OR clause? */
117 : static inline bool
118 3876570 : is_orclause(const void *clause)
119 : {
120 3876570 : return (clause != NULL &&
121 4118030 : IsA(clause, BoolExpr) &&
122 241460 : ((const BoolExpr *) clause)->boolop == OR_EXPR);
123 : }
124 :
125 : /* Is clause a NOT clause? */
126 : static inline bool
127 963668 : is_notclause(const void *clause)
128 : {
129 963668 : return (clause != NULL &&
130 1010418 : IsA(clause, BoolExpr) &&
131 46750 : ((const BoolExpr *) clause)->boolop == NOT_EXPR);
132 : }
133 :
134 : /* Extract argument from a clause known to be a NOT clause */
135 : static inline Expr *
136 16098 : get_notclausearg(const void *notclause)
137 : {
138 16098 : return (Expr *) linitial(((const BoolExpr *) notclause)->args);
139 : }
140 :
141 : extern bool check_functions_in_node(Node *node, check_function_callback checker,
142 : void *context);
143 :
144 : /*
145 : * The following functions are usually passed walker or mutator callbacks
146 : * that are declared like "bool walker(Node *node, my_struct *context)"
147 : * rather than "bool walker(Node *node, void *context)" as a strict reading
148 : * of the C standard would require. Changing the callbacks' declarations
149 : * to "void *" would create serious hazards of passing them the wrong context
150 : * struct type, so we respectfully decline to support the standard's position
151 : * that a pointer to struct is incompatible with "void *". Instead, silence
152 : * related compiler warnings by inserting casts into these macro wrappers.
153 : */
154 :
155 : #define expression_tree_walker(n, w, c) \
156 : expression_tree_walker_impl(n, (tree_walker_callback) (w), c)
157 : #define expression_tree_mutator(n, m, c) \
158 : expression_tree_mutator_impl(n, (tree_mutator_callback) (m), c)
159 :
160 : #define query_tree_walker(q, w, c, f) \
161 : query_tree_walker_impl(q, (tree_walker_callback) (w), c, f)
162 : #define query_tree_mutator(q, m, c, f) \
163 : query_tree_mutator_impl(q, (tree_mutator_callback) (m), c, f)
164 :
165 : #define range_table_walker(rt, w, c, f) \
166 : range_table_walker_impl(rt, (tree_walker_callback) (w), c, f)
167 : #define range_table_mutator(rt, m, c, f) \
168 : range_table_mutator_impl(rt, (tree_mutator_callback) (m), c, f)
169 :
170 : #define range_table_entry_walker(r, w, c, f) \
171 : range_table_entry_walker_impl(r, (tree_walker_callback) (w), c, f)
172 :
173 : #define query_or_expression_tree_walker(n, w, c, f) \
174 : query_or_expression_tree_walker_impl(n, (tree_walker_callback) (w), c, f)
175 : #define query_or_expression_tree_mutator(n, m, c, f) \
176 : query_or_expression_tree_mutator_impl(n, (tree_mutator_callback) (m), c, f)
177 :
178 : #define raw_expression_tree_walker(n, w, c) \
179 : raw_expression_tree_walker_impl(n, (tree_walker_callback) (w), c)
180 :
181 : #define planstate_tree_walker(ps, w, c) \
182 : planstate_tree_walker_impl(ps, (planstate_tree_walker_callback) (w), c)
183 :
184 : extern bool expression_tree_walker_impl(Node *node,
185 : tree_walker_callback walker,
186 : void *context);
187 : extern Node *expression_tree_mutator_impl(Node *node,
188 : tree_mutator_callback mutator,
189 : void *context);
190 :
191 : extern bool query_tree_walker_impl(Query *query,
192 : tree_walker_callback walker,
193 : void *context, int flags);
194 : extern Query *query_tree_mutator_impl(Query *query,
195 : tree_mutator_callback mutator,
196 : void *context, int flags);
197 :
198 : extern bool range_table_walker_impl(List *rtable,
199 : tree_walker_callback walker,
200 : void *context, int flags);
201 : extern List *range_table_mutator_impl(List *rtable,
202 : tree_mutator_callback mutator,
203 : void *context, int flags);
204 :
205 : extern bool range_table_entry_walker_impl(RangeTblEntry *rte,
206 : tree_walker_callback walker,
207 : void *context, int flags);
208 :
209 : extern bool query_or_expression_tree_walker_impl(Node *node,
210 : tree_walker_callback walker,
211 : void *context, int flags);
212 : extern Node *query_or_expression_tree_mutator_impl(Node *node,
213 : tree_mutator_callback mutator,
214 : void *context, int flags);
215 :
216 : extern bool raw_expression_tree_walker_impl(Node *node,
217 : tree_walker_callback walker,
218 : void *context);
219 :
220 : extern bool planstate_tree_walker_impl(struct PlanState *planstate,
221 : planstate_tree_walker_callback walker,
222 : void *context);
223 :
224 : #endif /* NODEFUNCS_H */
|