Age Owner Branch data TLA Line data Source code
1 : : /*-------------------------------------------------------------------------
2 : : *
3 : : * nodeFuncs.h
4 : : * Various general-purpose manipulations of Node trees
5 : : *
6 : : * Portions Copyright (c) 1996-2025, 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
2412 tgl@sss.pgh.pa.us 71 :CBC 37393 : is_funcclause(const void *clause)
72 : : {
73 [ + - + + ]: 37393 : return clause != NULL && IsA(clause, FuncExpr);
74 : : }
75 : :
76 : : /* Is clause an OpExpr clause? */
77 : : static inline bool
78 : 2607180 : is_opclause(const void *clause)
79 : : {
80 [ + - + + ]: 2607180 : 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 : 897944 : get_leftop(const void *clause)
86 : : {
87 : 897944 : const OpExpr *expr = (const OpExpr *) clause;
88 : :
89 [ + - ]: 897944 : if (expr->args != NIL)
90 : 897944 : return (Node *) linitial(expr->args);
91 : : else
2412 tgl@sss.pgh.pa.us 92 :UBC 0 : return NULL;
93 : : }
94 : :
95 : : /* Extract right arg of a binary opclause (NULL if it's a unary opclause) */
96 : : static inline Node *
2412 tgl@sss.pgh.pa.us 97 :CBC 841991 : get_rightop(const void *clause)
98 : : {
99 : 841991 : const OpExpr *expr = (const OpExpr *) clause;
100 : :
101 [ + - ]: 841991 : if (list_length(expr->args) >= 2)
102 : 841991 : return (Node *) lsecond(expr->args);
103 : : else
2412 tgl@sss.pgh.pa.us 104 :UBC 0 : return NULL;
105 : : }
106 : :
107 : : /* Is clause an AND clause? */
108 : : static inline bool
2412 tgl@sss.pgh.pa.us 109 :CBC 3331846 : is_andclause(const void *clause)
110 : : {
111 : 3331846 : return (clause != NULL &&
112 [ + - + + ]: 3569150 : IsA(clause, BoolExpr) &&
113 [ + + ]: 237304 : ((const BoolExpr *) clause)->boolop == AND_EXPR);
114 : : }
115 : :
116 : : /* Is clause an OR clause? */
117 : : static inline bool
118 : 2212146 : is_orclause(const void *clause)
119 : : {
120 : 2212146 : return (clause != NULL &&
121 [ + - + + ]: 2359910 : IsA(clause, BoolExpr) &&
122 [ + + ]: 147764 : ((const BoolExpr *) clause)->boolop == OR_EXPR);
123 : : }
124 : :
125 : : /* Is clause a NOT clause? */
126 : : static inline bool
127 : 549078 : is_notclause(const void *clause)
128 : : {
129 : 549078 : return (clause != NULL &&
130 [ + - + + ]: 578509 : IsA(clause, BoolExpr) &&
131 [ + + ]: 29431 : ((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 : 9435 : get_notclausearg(const void *notclause)
137 : : {
138 : 9435 : 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 */
|