/src/postgres/src/backend/optimizer/util/clauses.c
Line | Count | Source (jump to first uncovered line) |
1 | | /*------------------------------------------------------------------------- |
2 | | * |
3 | | * clauses.c |
4 | | * routines to manipulate qualification clauses |
5 | | * |
6 | | * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group |
7 | | * Portions Copyright (c) 1994, Regents of the University of California |
8 | | * |
9 | | * |
10 | | * IDENTIFICATION |
11 | | * src/backend/optimizer/util/clauses.c |
12 | | * |
13 | | * HISTORY |
14 | | * AUTHOR DATE MAJOR EVENT |
15 | | * Andrew Yu Nov 3, 1994 clause.c and clauses.c combined |
16 | | * |
17 | | *------------------------------------------------------------------------- |
18 | | */ |
19 | | |
20 | | #include "postgres.h" |
21 | | |
22 | | #include "access/htup_details.h" |
23 | | #include "catalog/pg_language.h" |
24 | | #include "catalog/pg_operator.h" |
25 | | #include "catalog/pg_proc.h" |
26 | | #include "catalog/pg_type.h" |
27 | | #include "executor/executor.h" |
28 | | #include "executor/functions.h" |
29 | | #include "funcapi.h" |
30 | | #include "miscadmin.h" |
31 | | #include "nodes/makefuncs.h" |
32 | | #include "nodes/multibitmapset.h" |
33 | | #include "nodes/nodeFuncs.h" |
34 | | #include "nodes/subscripting.h" |
35 | | #include "nodes/supportnodes.h" |
36 | | #include "optimizer/clauses.h" |
37 | | #include "optimizer/cost.h" |
38 | | #include "optimizer/optimizer.h" |
39 | | #include "optimizer/plancat.h" |
40 | | #include "optimizer/planmain.h" |
41 | | #include "parser/analyze.h" |
42 | | #include "parser/parse_coerce.h" |
43 | | #include "parser/parse_collate.h" |
44 | | #include "parser/parse_func.h" |
45 | | #include "parser/parse_oper.h" |
46 | | #include "rewrite/rewriteHandler.h" |
47 | | #include "rewrite/rewriteManip.h" |
48 | | #include "tcop/tcopprot.h" |
49 | | #include "utils/acl.h" |
50 | | #include "utils/builtins.h" |
51 | | #include "utils/datum.h" |
52 | | #include "utils/fmgroids.h" |
53 | | #include "utils/json.h" |
54 | | #include "utils/jsonb.h" |
55 | | #include "utils/jsonpath.h" |
56 | | #include "utils/lsyscache.h" |
57 | | #include "utils/memutils.h" |
58 | | #include "utils/syscache.h" |
59 | | #include "utils/typcache.h" |
60 | | |
61 | | typedef struct |
62 | | { |
63 | | ParamListInfo boundParams; |
64 | | PlannerInfo *root; |
65 | | List *active_fns; |
66 | | Node *case_val; |
67 | | bool estimate; |
68 | | } eval_const_expressions_context; |
69 | | |
70 | | typedef struct |
71 | | { |
72 | | int nargs; |
73 | | List *args; |
74 | | int *usecounts; |
75 | | } substitute_actual_parameters_context; |
76 | | |
77 | | typedef struct |
78 | | { |
79 | | int nargs; |
80 | | List *args; |
81 | | int sublevels_up; |
82 | | } substitute_actual_srf_parameters_context; |
83 | | |
84 | | typedef struct |
85 | | { |
86 | | char *proname; |
87 | | char *prosrc; |
88 | | } inline_error_callback_arg; |
89 | | |
90 | | typedef struct |
91 | | { |
92 | | char max_hazard; /* worst proparallel hazard found so far */ |
93 | | char max_interesting; /* worst proparallel hazard of interest */ |
94 | | List *safe_param_ids; /* PARAM_EXEC Param IDs to treat as safe */ |
95 | | } max_parallel_hazard_context; |
96 | | |
97 | | static bool contain_agg_clause_walker(Node *node, void *context); |
98 | | static bool find_window_functions_walker(Node *node, WindowFuncLists *lists); |
99 | | static bool contain_subplans_walker(Node *node, void *context); |
100 | | static bool contain_mutable_functions_walker(Node *node, void *context); |
101 | | static bool contain_volatile_functions_walker(Node *node, void *context); |
102 | | static bool contain_volatile_functions_not_nextval_walker(Node *node, void *context); |
103 | | static bool max_parallel_hazard_walker(Node *node, |
104 | | max_parallel_hazard_context *context); |
105 | | static bool contain_nonstrict_functions_walker(Node *node, void *context); |
106 | | static bool contain_exec_param_walker(Node *node, List *param_ids); |
107 | | static bool contain_context_dependent_node(Node *clause); |
108 | | static bool contain_context_dependent_node_walker(Node *node, int *flags); |
109 | | static bool contain_leaked_vars_walker(Node *node, void *context); |
110 | | static Relids find_nonnullable_rels_walker(Node *node, bool top_level); |
111 | | static List *find_nonnullable_vars_walker(Node *node, bool top_level); |
112 | | static bool is_strict_saop(ScalarArrayOpExpr *expr, bool falseOK); |
113 | | static bool convert_saop_to_hashed_saop_walker(Node *node, void *context); |
114 | | static Node *eval_const_expressions_mutator(Node *node, |
115 | | eval_const_expressions_context *context); |
116 | | static bool contain_non_const_walker(Node *node, void *context); |
117 | | static bool ece_function_is_safe(Oid funcid, |
118 | | eval_const_expressions_context *context); |
119 | | static List *simplify_or_arguments(List *args, |
120 | | eval_const_expressions_context *context, |
121 | | bool *haveNull, bool *forceTrue); |
122 | | static List *simplify_and_arguments(List *args, |
123 | | eval_const_expressions_context *context, |
124 | | bool *haveNull, bool *forceFalse); |
125 | | static Node *simplify_boolean_equality(Oid opno, List *args); |
126 | | static Expr *simplify_function(Oid funcid, |
127 | | Oid result_type, int32 result_typmod, |
128 | | Oid result_collid, Oid input_collid, List **args_p, |
129 | | bool funcvariadic, bool process_args, bool allow_non_const, |
130 | | eval_const_expressions_context *context); |
131 | | static List *reorder_function_arguments(List *args, int pronargs, |
132 | | HeapTuple func_tuple); |
133 | | static List *add_function_defaults(List *args, int pronargs, |
134 | | HeapTuple func_tuple); |
135 | | static List *fetch_function_defaults(HeapTuple func_tuple); |
136 | | static void recheck_cast_function_args(List *args, Oid result_type, |
137 | | Oid *proargtypes, int pronargs, |
138 | | HeapTuple func_tuple); |
139 | | static Expr *evaluate_function(Oid funcid, Oid result_type, int32 result_typmod, |
140 | | Oid result_collid, Oid input_collid, List *args, |
141 | | bool funcvariadic, |
142 | | HeapTuple func_tuple, |
143 | | eval_const_expressions_context *context); |
144 | | static Expr *inline_function(Oid funcid, Oid result_type, Oid result_collid, |
145 | | Oid input_collid, List *args, |
146 | | bool funcvariadic, |
147 | | HeapTuple func_tuple, |
148 | | eval_const_expressions_context *context); |
149 | | static Node *substitute_actual_parameters(Node *expr, int nargs, List *args, |
150 | | int *usecounts); |
151 | | static Node *substitute_actual_parameters_mutator(Node *node, |
152 | | substitute_actual_parameters_context *context); |
153 | | static void sql_inline_error_callback(void *arg); |
154 | | static Query *substitute_actual_srf_parameters(Query *expr, |
155 | | int nargs, List *args); |
156 | | static Node *substitute_actual_srf_parameters_mutator(Node *node, |
157 | | substitute_actual_srf_parameters_context *context); |
158 | | static bool pull_paramids_walker(Node *node, Bitmapset **context); |
159 | | |
160 | | |
161 | | /***************************************************************************** |
162 | | * Aggregate-function clause manipulation |
163 | | *****************************************************************************/ |
164 | | |
165 | | /* |
166 | | * contain_agg_clause |
167 | | * Recursively search for Aggref/GroupingFunc nodes within a clause. |
168 | | * |
169 | | * Returns true if any aggregate found. |
170 | | * |
171 | | * This does not descend into subqueries, and so should be used only after |
172 | | * reduction of sublinks to subplans, or in contexts where it's known there |
173 | | * are no subqueries. There mustn't be outer-aggregate references either. |
174 | | * |
175 | | * (If you want something like this but able to deal with subqueries, |
176 | | * see rewriteManip.c's contain_aggs_of_level().) |
177 | | */ |
178 | | bool |
179 | | contain_agg_clause(Node *clause) |
180 | 0 | { |
181 | 0 | return contain_agg_clause_walker(clause, NULL); |
182 | 0 | } |
183 | | |
184 | | static bool |
185 | | contain_agg_clause_walker(Node *node, void *context) |
186 | 0 | { |
187 | 0 | if (node == NULL) |
188 | 0 | return false; |
189 | 0 | if (IsA(node, Aggref)) |
190 | 0 | { |
191 | 0 | Assert(((Aggref *) node)->agglevelsup == 0); |
192 | 0 | return true; /* abort the tree traversal and return true */ |
193 | 0 | } |
194 | 0 | if (IsA(node, GroupingFunc)) |
195 | 0 | { |
196 | 0 | Assert(((GroupingFunc *) node)->agglevelsup == 0); |
197 | 0 | return true; /* abort the tree traversal and return true */ |
198 | 0 | } |
199 | 0 | Assert(!IsA(node, SubLink)); |
200 | 0 | return expression_tree_walker(node, contain_agg_clause_walker, context); |
201 | 0 | } |
202 | | |
203 | | /***************************************************************************** |
204 | | * Window-function clause manipulation |
205 | | *****************************************************************************/ |
206 | | |
207 | | /* |
208 | | * contain_window_function |
209 | | * Recursively search for WindowFunc nodes within a clause. |
210 | | * |
211 | | * Since window functions don't have level fields, but are hard-wired to |
212 | | * be associated with the current query level, this is just the same as |
213 | | * rewriteManip.c's function. |
214 | | */ |
215 | | bool |
216 | | contain_window_function(Node *clause) |
217 | 0 | { |
218 | 0 | return contain_windowfuncs(clause); |
219 | 0 | } |
220 | | |
221 | | /* |
222 | | * find_window_functions |
223 | | * Locate all the WindowFunc nodes in an expression tree, and organize |
224 | | * them by winref ID number. |
225 | | * |
226 | | * Caller must provide an upper bound on the winref IDs expected in the tree. |
227 | | */ |
228 | | WindowFuncLists * |
229 | | find_window_functions(Node *clause, Index maxWinRef) |
230 | 0 | { |
231 | 0 | WindowFuncLists *lists = palloc(sizeof(WindowFuncLists)); |
232 | |
|
233 | 0 | lists->numWindowFuncs = 0; |
234 | 0 | lists->maxWinRef = maxWinRef; |
235 | 0 | lists->windowFuncs = (List **) palloc0((maxWinRef + 1) * sizeof(List *)); |
236 | 0 | (void) find_window_functions_walker(clause, lists); |
237 | 0 | return lists; |
238 | 0 | } |
239 | | |
240 | | static bool |
241 | | find_window_functions_walker(Node *node, WindowFuncLists *lists) |
242 | 0 | { |
243 | 0 | if (node == NULL) |
244 | 0 | return false; |
245 | 0 | if (IsA(node, WindowFunc)) |
246 | 0 | { |
247 | 0 | WindowFunc *wfunc = (WindowFunc *) node; |
248 | | |
249 | | /* winref is unsigned, so one-sided test is OK */ |
250 | 0 | if (wfunc->winref > lists->maxWinRef) |
251 | 0 | elog(ERROR, "WindowFunc contains out-of-range winref %u", |
252 | 0 | wfunc->winref); |
253 | | /* eliminate duplicates, so that we avoid repeated computation */ |
254 | 0 | if (!list_member(lists->windowFuncs[wfunc->winref], wfunc)) |
255 | 0 | { |
256 | 0 | lists->windowFuncs[wfunc->winref] = |
257 | 0 | lappend(lists->windowFuncs[wfunc->winref], wfunc); |
258 | 0 | lists->numWindowFuncs++; |
259 | 0 | } |
260 | | |
261 | | /* |
262 | | * We assume that the parser checked that there are no window |
263 | | * functions in the arguments or filter clause. Hence, we need not |
264 | | * recurse into them. (If either the parser or the planner screws up |
265 | | * on this point, the executor will still catch it; see ExecInitExpr.) |
266 | | */ |
267 | 0 | return false; |
268 | 0 | } |
269 | 0 | Assert(!IsA(node, SubLink)); |
270 | 0 | return expression_tree_walker(node, find_window_functions_walker, lists); |
271 | 0 | } |
272 | | |
273 | | |
274 | | /***************************************************************************** |
275 | | * Support for expressions returning sets |
276 | | *****************************************************************************/ |
277 | | |
278 | | /* |
279 | | * expression_returns_set_rows |
280 | | * Estimate the number of rows returned by a set-returning expression. |
281 | | * The result is 1 if it's not a set-returning expression. |
282 | | * |
283 | | * We should only examine the top-level function or operator; it used to be |
284 | | * appropriate to recurse, but not anymore. (Even if there are more SRFs in |
285 | | * the function's inputs, their multipliers are accounted for separately.) |
286 | | * |
287 | | * Note: keep this in sync with expression_returns_set() in nodes/nodeFuncs.c. |
288 | | */ |
289 | | double |
290 | | expression_returns_set_rows(PlannerInfo *root, Node *clause) |
291 | 0 | { |
292 | 0 | if (clause == NULL) |
293 | 0 | return 1.0; |
294 | 0 | if (IsA(clause, FuncExpr)) |
295 | 0 | { |
296 | 0 | FuncExpr *expr = (FuncExpr *) clause; |
297 | |
|
298 | 0 | if (expr->funcretset) |
299 | 0 | return clamp_row_est(get_function_rows(root, expr->funcid, clause)); |
300 | 0 | } |
301 | 0 | if (IsA(clause, OpExpr)) |
302 | 0 | { |
303 | 0 | OpExpr *expr = (OpExpr *) clause; |
304 | |
|
305 | 0 | if (expr->opretset) |
306 | 0 | { |
307 | 0 | set_opfuncid(expr); |
308 | 0 | return clamp_row_est(get_function_rows(root, expr->opfuncid, clause)); |
309 | 0 | } |
310 | 0 | } |
311 | 0 | return 1.0; |
312 | 0 | } |
313 | | |
314 | | |
315 | | /***************************************************************************** |
316 | | * Subplan clause manipulation |
317 | | *****************************************************************************/ |
318 | | |
319 | | /* |
320 | | * contain_subplans |
321 | | * Recursively search for subplan nodes within a clause. |
322 | | * |
323 | | * If we see a SubLink node, we will return true. This is only possible if |
324 | | * the expression tree hasn't yet been transformed by subselect.c. We do not |
325 | | * know whether the node will produce a true subplan or just an initplan, |
326 | | * but we make the conservative assumption that it will be a subplan. |
327 | | * |
328 | | * Returns true if any subplan found. |
329 | | */ |
330 | | bool |
331 | | contain_subplans(Node *clause) |
332 | 0 | { |
333 | 0 | return contain_subplans_walker(clause, NULL); |
334 | 0 | } |
335 | | |
336 | | static bool |
337 | | contain_subplans_walker(Node *node, void *context) |
338 | 0 | { |
339 | 0 | if (node == NULL) |
340 | 0 | return false; |
341 | 0 | if (IsA(node, SubPlan) || |
342 | 0 | IsA(node, AlternativeSubPlan) || |
343 | 0 | IsA(node, SubLink)) |
344 | 0 | return true; /* abort the tree traversal and return true */ |
345 | 0 | return expression_tree_walker(node, contain_subplans_walker, context); |
346 | 0 | } |
347 | | |
348 | | |
349 | | /***************************************************************************** |
350 | | * Check clauses for mutable functions |
351 | | *****************************************************************************/ |
352 | | |
353 | | /* |
354 | | * contain_mutable_functions |
355 | | * Recursively search for mutable functions within a clause. |
356 | | * |
357 | | * Returns true if any mutable function (or operator implemented by a |
358 | | * mutable function) is found. This test is needed so that we don't |
359 | | * mistakenly think that something like "WHERE random() < 0.5" can be treated |
360 | | * as a constant qualification. |
361 | | * |
362 | | * This will give the right answer only for clauses that have been put |
363 | | * through expression preprocessing. Callers outside the planner typically |
364 | | * should use contain_mutable_functions_after_planning() instead, for the |
365 | | * reasons given there. |
366 | | * |
367 | | * We will recursively look into Query nodes (i.e., SubLink sub-selects) |
368 | | * but not into SubPlans. See comments for contain_volatile_functions(). |
369 | | */ |
370 | | bool |
371 | | contain_mutable_functions(Node *clause) |
372 | 0 | { |
373 | 0 | return contain_mutable_functions_walker(clause, NULL); |
374 | 0 | } |
375 | | |
376 | | static bool |
377 | | contain_mutable_functions_checker(Oid func_id, void *context) |
378 | 0 | { |
379 | 0 | return (func_volatile(func_id) != PROVOLATILE_IMMUTABLE); |
380 | 0 | } |
381 | | |
382 | | static bool |
383 | | contain_mutable_functions_walker(Node *node, void *context) |
384 | 0 | { |
385 | 0 | if (node == NULL) |
386 | 0 | return false; |
387 | | /* Check for mutable functions in node itself */ |
388 | 0 | if (check_functions_in_node(node, contain_mutable_functions_checker, |
389 | 0 | context)) |
390 | 0 | return true; |
391 | | |
392 | 0 | if (IsA(node, JsonConstructorExpr)) |
393 | 0 | { |
394 | 0 | const JsonConstructorExpr *ctor = (JsonConstructorExpr *) node; |
395 | 0 | ListCell *lc; |
396 | 0 | bool is_jsonb; |
397 | |
|
398 | 0 | is_jsonb = ctor->returning->format->format_type == JS_FORMAT_JSONB; |
399 | | |
400 | | /* |
401 | | * Check argument_type => json[b] conversions specifically. We still |
402 | | * recurse to check 'args' below, but here we want to specifically |
403 | | * check whether or not the emitted clause would fail to be immutable |
404 | | * because of TimeZone, for example. |
405 | | */ |
406 | 0 | foreach(lc, ctor->args) |
407 | 0 | { |
408 | 0 | Oid typid = exprType(lfirst(lc)); |
409 | |
|
410 | 0 | if (is_jsonb ? |
411 | 0 | !to_jsonb_is_immutable(typid) : |
412 | 0 | !to_json_is_immutable(typid)) |
413 | 0 | return true; |
414 | 0 | } |
415 | | |
416 | | /* Check all subnodes */ |
417 | 0 | } |
418 | | |
419 | 0 | if (IsA(node, JsonExpr)) |
420 | 0 | { |
421 | 0 | JsonExpr *jexpr = castNode(JsonExpr, node); |
422 | 0 | Const *cnst; |
423 | |
|
424 | 0 | if (!IsA(jexpr->path_spec, Const)) |
425 | 0 | return true; |
426 | | |
427 | 0 | cnst = castNode(Const, jexpr->path_spec); |
428 | |
|
429 | 0 | Assert(cnst->consttype == JSONPATHOID); |
430 | 0 | if (cnst->constisnull) |
431 | 0 | return false; |
432 | | |
433 | 0 | if (jspIsMutable(DatumGetJsonPathP(cnst->constvalue), |
434 | 0 | jexpr->passing_names, jexpr->passing_values)) |
435 | 0 | return true; |
436 | 0 | } |
437 | | |
438 | 0 | if (IsA(node, SQLValueFunction)) |
439 | 0 | { |
440 | | /* all variants of SQLValueFunction are stable */ |
441 | 0 | return true; |
442 | 0 | } |
443 | | |
444 | 0 | if (IsA(node, NextValueExpr)) |
445 | 0 | { |
446 | | /* NextValueExpr is volatile */ |
447 | 0 | return true; |
448 | 0 | } |
449 | | |
450 | | /* |
451 | | * It should be safe to treat MinMaxExpr as immutable, because it will |
452 | | * depend on a non-cross-type btree comparison function, and those should |
453 | | * always be immutable. Treating XmlExpr as immutable is more dubious, |
454 | | * and treating CoerceToDomain as immutable is outright dangerous. But we |
455 | | * have done so historically, and changing this would probably cause more |
456 | | * problems than it would fix. In practice, if you have a non-immutable |
457 | | * domain constraint you are in for pain anyhow. |
458 | | */ |
459 | | |
460 | | /* Recurse to check arguments */ |
461 | 0 | if (IsA(node, Query)) |
462 | 0 | { |
463 | | /* Recurse into subselects */ |
464 | 0 | return query_tree_walker((Query *) node, |
465 | 0 | contain_mutable_functions_walker, |
466 | 0 | context, 0); |
467 | 0 | } |
468 | 0 | return expression_tree_walker(node, contain_mutable_functions_walker, |
469 | 0 | context); |
470 | 0 | } |
471 | | |
472 | | /* |
473 | | * contain_mutable_functions_after_planning |
474 | | * Test whether given expression contains mutable functions. |
475 | | * |
476 | | * This is a wrapper for contain_mutable_functions() that is safe to use from |
477 | | * outside the planner. The difference is that it first runs the expression |
478 | | * through expression_planner(). There are two key reasons why we need that: |
479 | | * |
480 | | * First, function default arguments will get inserted, which may affect |
481 | | * volatility (consider "default now()"). |
482 | | * |
483 | | * Second, inline-able functions will get inlined, which may allow us to |
484 | | * conclude that the function is really less volatile than it's marked. |
485 | | * As an example, polymorphic functions must be marked with the most volatile |
486 | | * behavior that they have for any input type, but once we inline the |
487 | | * function we may be able to conclude that it's not so volatile for the |
488 | | * particular input type we're dealing with. |
489 | | */ |
490 | | bool |
491 | | contain_mutable_functions_after_planning(Expr *expr) |
492 | 0 | { |
493 | | /* We assume here that expression_planner() won't scribble on its input */ |
494 | 0 | expr = expression_planner(expr); |
495 | | |
496 | | /* Now we can search for non-immutable functions */ |
497 | 0 | return contain_mutable_functions((Node *) expr); |
498 | 0 | } |
499 | | |
500 | | |
501 | | /***************************************************************************** |
502 | | * Check clauses for volatile functions |
503 | | *****************************************************************************/ |
504 | | |
505 | | /* |
506 | | * contain_volatile_functions |
507 | | * Recursively search for volatile functions within a clause. |
508 | | * |
509 | | * Returns true if any volatile function (or operator implemented by a |
510 | | * volatile function) is found. This test prevents, for example, |
511 | | * invalid conversions of volatile expressions into indexscan quals. |
512 | | * |
513 | | * This will give the right answer only for clauses that have been put |
514 | | * through expression preprocessing. Callers outside the planner typically |
515 | | * should use contain_volatile_functions_after_planning() instead, for the |
516 | | * reasons given there. |
517 | | * |
518 | | * We will recursively look into Query nodes (i.e., SubLink sub-selects) |
519 | | * but not into SubPlans. This is a bit odd, but intentional. If we are |
520 | | * looking at a SubLink, we are probably deciding whether a query tree |
521 | | * transformation is safe, and a contained sub-select should affect that; |
522 | | * for example, duplicating a sub-select containing a volatile function |
523 | | * would be bad. However, once we've got to the stage of having SubPlans, |
524 | | * subsequent planning need not consider volatility within those, since |
525 | | * the executor won't change its evaluation rules for a SubPlan based on |
526 | | * volatility. |
527 | | * |
528 | | * For some node types, for example, RestrictInfo and PathTarget, we cache |
529 | | * whether we found any volatile functions or not and reuse that value in any |
530 | | * future checks for that node. All of the logic for determining if the |
531 | | * cached value should be set to VOLATILITY_NOVOLATILE or VOLATILITY_VOLATILE |
532 | | * belongs in this function. Any code which makes changes to these nodes |
533 | | * which could change the outcome this function must set the cached value back |
534 | | * to VOLATILITY_UNKNOWN. That allows this function to redetermine the |
535 | | * correct value during the next call, should we need to redetermine if the |
536 | | * node contains any volatile functions again in the future. |
537 | | */ |
538 | | bool |
539 | | contain_volatile_functions(Node *clause) |
540 | 0 | { |
541 | 0 | return contain_volatile_functions_walker(clause, NULL); |
542 | 0 | } |
543 | | |
544 | | static bool |
545 | | contain_volatile_functions_checker(Oid func_id, void *context) |
546 | 0 | { |
547 | 0 | return (func_volatile(func_id) == PROVOLATILE_VOLATILE); |
548 | 0 | } |
549 | | |
550 | | static bool |
551 | | contain_volatile_functions_walker(Node *node, void *context) |
552 | 0 | { |
553 | 0 | if (node == NULL) |
554 | 0 | return false; |
555 | | /* Check for volatile functions in node itself */ |
556 | 0 | if (check_functions_in_node(node, contain_volatile_functions_checker, |
557 | 0 | context)) |
558 | 0 | return true; |
559 | | |
560 | 0 | if (IsA(node, NextValueExpr)) |
561 | 0 | { |
562 | | /* NextValueExpr is volatile */ |
563 | 0 | return true; |
564 | 0 | } |
565 | | |
566 | 0 | if (IsA(node, RestrictInfo)) |
567 | 0 | { |
568 | 0 | RestrictInfo *rinfo = (RestrictInfo *) node; |
569 | | |
570 | | /* |
571 | | * For RestrictInfo, check if we've checked the volatility of it |
572 | | * before. If so, we can just use the cached value and not bother |
573 | | * checking it again. Otherwise, check it and cache if whether we |
574 | | * found any volatile functions. |
575 | | */ |
576 | 0 | if (rinfo->has_volatile == VOLATILITY_NOVOLATILE) |
577 | 0 | return false; |
578 | 0 | else if (rinfo->has_volatile == VOLATILITY_VOLATILE) |
579 | 0 | return true; |
580 | 0 | else |
581 | 0 | { |
582 | 0 | bool hasvolatile; |
583 | |
|
584 | 0 | hasvolatile = contain_volatile_functions_walker((Node *) rinfo->clause, |
585 | 0 | context); |
586 | 0 | if (hasvolatile) |
587 | 0 | rinfo->has_volatile = VOLATILITY_VOLATILE; |
588 | 0 | else |
589 | 0 | rinfo->has_volatile = VOLATILITY_NOVOLATILE; |
590 | |
|
591 | 0 | return hasvolatile; |
592 | 0 | } |
593 | 0 | } |
594 | | |
595 | 0 | if (IsA(node, PathTarget)) |
596 | 0 | { |
597 | 0 | PathTarget *target = (PathTarget *) node; |
598 | | |
599 | | /* |
600 | | * We also do caching for PathTarget the same as we do above for |
601 | | * RestrictInfos. |
602 | | */ |
603 | 0 | if (target->has_volatile_expr == VOLATILITY_NOVOLATILE) |
604 | 0 | return false; |
605 | 0 | else if (target->has_volatile_expr == VOLATILITY_VOLATILE) |
606 | 0 | return true; |
607 | 0 | else |
608 | 0 | { |
609 | 0 | bool hasvolatile; |
610 | |
|
611 | 0 | hasvolatile = contain_volatile_functions_walker((Node *) target->exprs, |
612 | 0 | context); |
613 | |
|
614 | 0 | if (hasvolatile) |
615 | 0 | target->has_volatile_expr = VOLATILITY_VOLATILE; |
616 | 0 | else |
617 | 0 | target->has_volatile_expr = VOLATILITY_NOVOLATILE; |
618 | |
|
619 | 0 | return hasvolatile; |
620 | 0 | } |
621 | 0 | } |
622 | | |
623 | | /* |
624 | | * See notes in contain_mutable_functions_walker about why we treat |
625 | | * MinMaxExpr, XmlExpr, and CoerceToDomain as immutable, while |
626 | | * SQLValueFunction is stable. Hence, none of them are of interest here. |
627 | | */ |
628 | | |
629 | | /* Recurse to check arguments */ |
630 | 0 | if (IsA(node, Query)) |
631 | 0 | { |
632 | | /* Recurse into subselects */ |
633 | 0 | return query_tree_walker((Query *) node, |
634 | 0 | contain_volatile_functions_walker, |
635 | 0 | context, 0); |
636 | 0 | } |
637 | 0 | return expression_tree_walker(node, contain_volatile_functions_walker, |
638 | 0 | context); |
639 | 0 | } |
640 | | |
641 | | /* |
642 | | * contain_volatile_functions_after_planning |
643 | | * Test whether given expression contains volatile functions. |
644 | | * |
645 | | * This is a wrapper for contain_volatile_functions() that is safe to use from |
646 | | * outside the planner. The difference is that it first runs the expression |
647 | | * through expression_planner(). There are two key reasons why we need that: |
648 | | * |
649 | | * First, function default arguments will get inserted, which may affect |
650 | | * volatility (consider "default random()"). |
651 | | * |
652 | | * Second, inline-able functions will get inlined, which may allow us to |
653 | | * conclude that the function is really less volatile than it's marked. |
654 | | * As an example, polymorphic functions must be marked with the most volatile |
655 | | * behavior that they have for any input type, but once we inline the |
656 | | * function we may be able to conclude that it's not so volatile for the |
657 | | * particular input type we're dealing with. |
658 | | */ |
659 | | bool |
660 | | contain_volatile_functions_after_planning(Expr *expr) |
661 | 0 | { |
662 | | /* We assume here that expression_planner() won't scribble on its input */ |
663 | 0 | expr = expression_planner(expr); |
664 | | |
665 | | /* Now we can search for volatile functions */ |
666 | 0 | return contain_volatile_functions((Node *) expr); |
667 | 0 | } |
668 | | |
669 | | /* |
670 | | * Special purpose version of contain_volatile_functions() for use in COPY: |
671 | | * ignore nextval(), but treat all other functions normally. |
672 | | */ |
673 | | bool |
674 | | contain_volatile_functions_not_nextval(Node *clause) |
675 | 0 | { |
676 | 0 | return contain_volatile_functions_not_nextval_walker(clause, NULL); |
677 | 0 | } |
678 | | |
679 | | static bool |
680 | | contain_volatile_functions_not_nextval_checker(Oid func_id, void *context) |
681 | 0 | { |
682 | 0 | return (func_id != F_NEXTVAL && |
683 | 0 | func_volatile(func_id) == PROVOLATILE_VOLATILE); |
684 | 0 | } |
685 | | |
686 | | static bool |
687 | | contain_volatile_functions_not_nextval_walker(Node *node, void *context) |
688 | 0 | { |
689 | 0 | if (node == NULL) |
690 | 0 | return false; |
691 | | /* Check for volatile functions in node itself */ |
692 | 0 | if (check_functions_in_node(node, |
693 | 0 | contain_volatile_functions_not_nextval_checker, |
694 | 0 | context)) |
695 | 0 | return true; |
696 | | |
697 | | /* |
698 | | * See notes in contain_mutable_functions_walker about why we treat |
699 | | * MinMaxExpr, XmlExpr, and CoerceToDomain as immutable, while |
700 | | * SQLValueFunction is stable. Hence, none of them are of interest here. |
701 | | * Also, since we're intentionally ignoring nextval(), presumably we |
702 | | * should ignore NextValueExpr. |
703 | | */ |
704 | | |
705 | | /* Recurse to check arguments */ |
706 | 0 | if (IsA(node, Query)) |
707 | 0 | { |
708 | | /* Recurse into subselects */ |
709 | 0 | return query_tree_walker((Query *) node, |
710 | 0 | contain_volatile_functions_not_nextval_walker, |
711 | 0 | context, 0); |
712 | 0 | } |
713 | 0 | return expression_tree_walker(node, |
714 | 0 | contain_volatile_functions_not_nextval_walker, |
715 | 0 | context); |
716 | 0 | } |
717 | | |
718 | | |
719 | | /***************************************************************************** |
720 | | * Check queries for parallel unsafe and/or restricted constructs |
721 | | *****************************************************************************/ |
722 | | |
723 | | /* |
724 | | * max_parallel_hazard |
725 | | * Find the worst parallel-hazard level in the given query |
726 | | * |
727 | | * Returns the worst function hazard property (the earliest in this list: |
728 | | * PROPARALLEL_UNSAFE, PROPARALLEL_RESTRICTED, PROPARALLEL_SAFE) that can |
729 | | * be found in the given parsetree. We use this to find out whether the query |
730 | | * can be parallelized at all. The caller will also save the result in |
731 | | * PlannerGlobal so as to short-circuit checks of portions of the querytree |
732 | | * later, in the common case where everything is SAFE. |
733 | | */ |
734 | | char |
735 | | max_parallel_hazard(Query *parse) |
736 | 0 | { |
737 | 0 | max_parallel_hazard_context context; |
738 | |
|
739 | 0 | context.max_hazard = PROPARALLEL_SAFE; |
740 | 0 | context.max_interesting = PROPARALLEL_UNSAFE; |
741 | 0 | context.safe_param_ids = NIL; |
742 | 0 | (void) max_parallel_hazard_walker((Node *) parse, &context); |
743 | 0 | return context.max_hazard; |
744 | 0 | } |
745 | | |
746 | | /* |
747 | | * is_parallel_safe |
748 | | * Detect whether the given expr contains only parallel-safe functions |
749 | | * |
750 | | * root->glob->maxParallelHazard must previously have been set to the |
751 | | * result of max_parallel_hazard() on the whole query. |
752 | | */ |
753 | | bool |
754 | | is_parallel_safe(PlannerInfo *root, Node *node) |
755 | 0 | { |
756 | 0 | max_parallel_hazard_context context; |
757 | 0 | PlannerInfo *proot; |
758 | 0 | ListCell *l; |
759 | | |
760 | | /* |
761 | | * Even if the original querytree contained nothing unsafe, we need to |
762 | | * search the expression if we have generated any PARAM_EXEC Params while |
763 | | * planning, because those are parallel-restricted and there might be one |
764 | | * in this expression. But otherwise we don't need to look. |
765 | | */ |
766 | 0 | if (root->glob->maxParallelHazard == PROPARALLEL_SAFE && |
767 | 0 | root->glob->paramExecTypes == NIL) |
768 | 0 | return true; |
769 | | /* Else use max_parallel_hazard's search logic, but stop on RESTRICTED */ |
770 | 0 | context.max_hazard = PROPARALLEL_SAFE; |
771 | 0 | context.max_interesting = PROPARALLEL_RESTRICTED; |
772 | 0 | context.safe_param_ids = NIL; |
773 | | |
774 | | /* |
775 | | * The params that refer to the same or parent query level are considered |
776 | | * parallel-safe. The idea is that we compute such params at Gather or |
777 | | * Gather Merge node and pass their value to workers. |
778 | | */ |
779 | 0 | for (proot = root; proot != NULL; proot = proot->parent_root) |
780 | 0 | { |
781 | 0 | foreach(l, proot->init_plans) |
782 | 0 | { |
783 | 0 | SubPlan *initsubplan = (SubPlan *) lfirst(l); |
784 | |
|
785 | 0 | context.safe_param_ids = list_concat(context.safe_param_ids, |
786 | 0 | initsubplan->setParam); |
787 | 0 | } |
788 | 0 | } |
789 | |
|
790 | 0 | return !max_parallel_hazard_walker(node, &context); |
791 | 0 | } |
792 | | |
793 | | /* core logic for all parallel-hazard checks */ |
794 | | static bool |
795 | | max_parallel_hazard_test(char proparallel, max_parallel_hazard_context *context) |
796 | 0 | { |
797 | 0 | switch (proparallel) |
798 | 0 | { |
799 | 0 | case PROPARALLEL_SAFE: |
800 | | /* nothing to see here, move along */ |
801 | 0 | break; |
802 | 0 | case PROPARALLEL_RESTRICTED: |
803 | | /* increase max_hazard to RESTRICTED */ |
804 | 0 | Assert(context->max_hazard != PROPARALLEL_UNSAFE); |
805 | 0 | context->max_hazard = proparallel; |
806 | | /* done if we are not expecting any unsafe functions */ |
807 | 0 | if (context->max_interesting == proparallel) |
808 | 0 | return true; |
809 | 0 | break; |
810 | 0 | case PROPARALLEL_UNSAFE: |
811 | 0 | context->max_hazard = proparallel; |
812 | | /* we're always done at the first unsafe construct */ |
813 | 0 | return true; |
814 | 0 | default: |
815 | 0 | elog(ERROR, "unrecognized proparallel value \"%c\"", proparallel); |
816 | 0 | break; |
817 | 0 | } |
818 | 0 | return false; |
819 | 0 | } |
820 | | |
821 | | /* check_functions_in_node callback */ |
822 | | static bool |
823 | | max_parallel_hazard_checker(Oid func_id, void *context) |
824 | 0 | { |
825 | 0 | return max_parallel_hazard_test(func_parallel(func_id), |
826 | 0 | (max_parallel_hazard_context *) context); |
827 | 0 | } |
828 | | |
829 | | static bool |
830 | | max_parallel_hazard_walker(Node *node, max_parallel_hazard_context *context) |
831 | 0 | { |
832 | 0 | if (node == NULL) |
833 | 0 | return false; |
834 | | |
835 | | /* Check for hazardous functions in node itself */ |
836 | 0 | if (check_functions_in_node(node, max_parallel_hazard_checker, |
837 | 0 | context)) |
838 | 0 | return true; |
839 | | |
840 | | /* |
841 | | * It should be OK to treat MinMaxExpr as parallel-safe, since btree |
842 | | * opclass support functions are generally parallel-safe. XmlExpr is a |
843 | | * bit more dubious but we can probably get away with it. We err on the |
844 | | * side of caution by treating CoerceToDomain as parallel-restricted. |
845 | | * (Note: in principle that's wrong because a domain constraint could |
846 | | * contain a parallel-unsafe function; but useful constraints probably |
847 | | * never would have such, and assuming they do would cripple use of |
848 | | * parallel query in the presence of domain types.) SQLValueFunction |
849 | | * should be safe in all cases. NextValueExpr is parallel-unsafe. |
850 | | */ |
851 | 0 | if (IsA(node, CoerceToDomain)) |
852 | 0 | { |
853 | 0 | if (max_parallel_hazard_test(PROPARALLEL_RESTRICTED, context)) |
854 | 0 | return true; |
855 | 0 | } |
856 | | |
857 | 0 | else if (IsA(node, NextValueExpr)) |
858 | 0 | { |
859 | 0 | if (max_parallel_hazard_test(PROPARALLEL_UNSAFE, context)) |
860 | 0 | return true; |
861 | 0 | } |
862 | | |
863 | | /* |
864 | | * Treat window functions as parallel-restricted because we aren't sure |
865 | | * whether the input row ordering is fully deterministic, and the output |
866 | | * of window functions might vary across workers if not. (In some cases, |
867 | | * like where the window frame orders by a primary key, we could relax |
868 | | * this restriction. But it doesn't currently seem worth expending extra |
869 | | * effort to do so.) |
870 | | */ |
871 | 0 | else if (IsA(node, WindowFunc)) |
872 | 0 | { |
873 | 0 | if (max_parallel_hazard_test(PROPARALLEL_RESTRICTED, context)) |
874 | 0 | return true; |
875 | 0 | } |
876 | | |
877 | | /* |
878 | | * As a notational convenience for callers, look through RestrictInfo. |
879 | | */ |
880 | 0 | else if (IsA(node, RestrictInfo)) |
881 | 0 | { |
882 | 0 | RestrictInfo *rinfo = (RestrictInfo *) node; |
883 | |
|
884 | 0 | return max_parallel_hazard_walker((Node *) rinfo->clause, context); |
885 | 0 | } |
886 | | |
887 | | /* |
888 | | * Really we should not see SubLink during a max_interesting == restricted |
889 | | * scan, but if we do, return true. |
890 | | */ |
891 | 0 | else if (IsA(node, SubLink)) |
892 | 0 | { |
893 | 0 | if (max_parallel_hazard_test(PROPARALLEL_RESTRICTED, context)) |
894 | 0 | return true; |
895 | 0 | } |
896 | | |
897 | | /* |
898 | | * Only parallel-safe SubPlans can be sent to workers. Within the |
899 | | * testexpr of the SubPlan, Params representing the output columns of the |
900 | | * subplan can be treated as parallel-safe, so temporarily add their IDs |
901 | | * to the safe_param_ids list while examining the testexpr. |
902 | | */ |
903 | 0 | else if (IsA(node, SubPlan)) |
904 | 0 | { |
905 | 0 | SubPlan *subplan = (SubPlan *) node; |
906 | 0 | List *save_safe_param_ids; |
907 | |
|
908 | 0 | if (!subplan->parallel_safe && |
909 | 0 | max_parallel_hazard_test(PROPARALLEL_RESTRICTED, context)) |
910 | 0 | return true; |
911 | 0 | save_safe_param_ids = context->safe_param_ids; |
912 | 0 | context->safe_param_ids = list_concat_copy(context->safe_param_ids, |
913 | 0 | subplan->paramIds); |
914 | 0 | if (max_parallel_hazard_walker(subplan->testexpr, context)) |
915 | 0 | return true; /* no need to restore safe_param_ids */ |
916 | 0 | list_free(context->safe_param_ids); |
917 | 0 | context->safe_param_ids = save_safe_param_ids; |
918 | | /* we must also check args, but no special Param treatment there */ |
919 | 0 | if (max_parallel_hazard_walker((Node *) subplan->args, context)) |
920 | 0 | return true; |
921 | | /* don't want to recurse normally, so we're done */ |
922 | 0 | return false; |
923 | 0 | } |
924 | | |
925 | | /* |
926 | | * We can't pass Params to workers at the moment either, so they are also |
927 | | * parallel-restricted, unless they are PARAM_EXTERN Params or are |
928 | | * PARAM_EXEC Params listed in safe_param_ids, meaning they could be |
929 | | * either generated within workers or can be computed by the leader and |
930 | | * then their value can be passed to workers. |
931 | | */ |
932 | 0 | else if (IsA(node, Param)) |
933 | 0 | { |
934 | 0 | Param *param = (Param *) node; |
935 | |
|
936 | 0 | if (param->paramkind == PARAM_EXTERN) |
937 | 0 | return false; |
938 | | |
939 | 0 | if (param->paramkind != PARAM_EXEC || |
940 | 0 | !list_member_int(context->safe_param_ids, param->paramid)) |
941 | 0 | { |
942 | 0 | if (max_parallel_hazard_test(PROPARALLEL_RESTRICTED, context)) |
943 | 0 | return true; |
944 | 0 | } |
945 | 0 | return false; /* nothing to recurse to */ |
946 | 0 | } |
947 | | |
948 | | /* |
949 | | * When we're first invoked on a completely unplanned tree, we must |
950 | | * recurse into subqueries so to as to locate parallel-unsafe constructs |
951 | | * anywhere in the tree. |
952 | | */ |
953 | 0 | else if (IsA(node, Query)) |
954 | 0 | { |
955 | 0 | Query *query = (Query *) node; |
956 | | |
957 | | /* SELECT FOR UPDATE/SHARE must be treated as unsafe */ |
958 | 0 | if (query->rowMarks != NULL) |
959 | 0 | { |
960 | 0 | context->max_hazard = PROPARALLEL_UNSAFE; |
961 | 0 | return true; |
962 | 0 | } |
963 | | |
964 | | /* Recurse into subselects */ |
965 | 0 | return query_tree_walker(query, |
966 | 0 | max_parallel_hazard_walker, |
967 | 0 | context, 0); |
968 | 0 | } |
969 | | |
970 | | /* Recurse to check arguments */ |
971 | 0 | return expression_tree_walker(node, |
972 | 0 | max_parallel_hazard_walker, |
973 | 0 | context); |
974 | 0 | } |
975 | | |
976 | | |
977 | | /***************************************************************************** |
978 | | * Check clauses for nonstrict functions |
979 | | *****************************************************************************/ |
980 | | |
981 | | /* |
982 | | * contain_nonstrict_functions |
983 | | * Recursively search for nonstrict functions within a clause. |
984 | | * |
985 | | * Returns true if any nonstrict construct is found --- ie, anything that |
986 | | * could produce non-NULL output with a NULL input. |
987 | | * |
988 | | * The idea here is that the caller has verified that the expression contains |
989 | | * one or more Var or Param nodes (as appropriate for the caller's need), and |
990 | | * now wishes to prove that the expression result will be NULL if any of these |
991 | | * inputs is NULL. If we return false, then the proof succeeded. |
992 | | */ |
993 | | bool |
994 | | contain_nonstrict_functions(Node *clause) |
995 | 0 | { |
996 | 0 | return contain_nonstrict_functions_walker(clause, NULL); |
997 | 0 | } |
998 | | |
999 | | static bool |
1000 | | contain_nonstrict_functions_checker(Oid func_id, void *context) |
1001 | 0 | { |
1002 | 0 | return !func_strict(func_id); |
1003 | 0 | } |
1004 | | |
1005 | | static bool |
1006 | | contain_nonstrict_functions_walker(Node *node, void *context) |
1007 | 0 | { |
1008 | 0 | if (node == NULL) |
1009 | 0 | return false; |
1010 | 0 | if (IsA(node, Aggref)) |
1011 | 0 | { |
1012 | | /* an aggregate could return non-null with null input */ |
1013 | 0 | return true; |
1014 | 0 | } |
1015 | 0 | if (IsA(node, GroupingFunc)) |
1016 | 0 | { |
1017 | | /* |
1018 | | * A GroupingFunc doesn't evaluate its arguments, and therefore must |
1019 | | * be treated as nonstrict. |
1020 | | */ |
1021 | 0 | return true; |
1022 | 0 | } |
1023 | 0 | if (IsA(node, WindowFunc)) |
1024 | 0 | { |
1025 | | /* a window function could return non-null with null input */ |
1026 | 0 | return true; |
1027 | 0 | } |
1028 | 0 | if (IsA(node, SubscriptingRef)) |
1029 | 0 | { |
1030 | 0 | SubscriptingRef *sbsref = (SubscriptingRef *) node; |
1031 | 0 | const SubscriptRoutines *sbsroutines; |
1032 | | |
1033 | | /* Subscripting assignment is always presumed nonstrict */ |
1034 | 0 | if (sbsref->refassgnexpr != NULL) |
1035 | 0 | return true; |
1036 | | /* Otherwise we must look up the subscripting support methods */ |
1037 | 0 | sbsroutines = getSubscriptingRoutines(sbsref->refcontainertype, NULL); |
1038 | 0 | if (!(sbsroutines && sbsroutines->fetch_strict)) |
1039 | 0 | return true; |
1040 | | /* else fall through to check args */ |
1041 | 0 | } |
1042 | 0 | if (IsA(node, DistinctExpr)) |
1043 | 0 | { |
1044 | | /* IS DISTINCT FROM is inherently non-strict */ |
1045 | 0 | return true; |
1046 | 0 | } |
1047 | 0 | if (IsA(node, NullIfExpr)) |
1048 | 0 | { |
1049 | | /* NULLIF is inherently non-strict */ |
1050 | 0 | return true; |
1051 | 0 | } |
1052 | 0 | if (IsA(node, BoolExpr)) |
1053 | 0 | { |
1054 | 0 | BoolExpr *expr = (BoolExpr *) node; |
1055 | |
|
1056 | 0 | switch (expr->boolop) |
1057 | 0 | { |
1058 | 0 | case AND_EXPR: |
1059 | 0 | case OR_EXPR: |
1060 | | /* AND, OR are inherently non-strict */ |
1061 | 0 | return true; |
1062 | 0 | default: |
1063 | 0 | break; |
1064 | 0 | } |
1065 | 0 | } |
1066 | 0 | if (IsA(node, SubLink)) |
1067 | 0 | { |
1068 | | /* In some cases a sublink might be strict, but in general not */ |
1069 | 0 | return true; |
1070 | 0 | } |
1071 | 0 | if (IsA(node, SubPlan)) |
1072 | 0 | return true; |
1073 | 0 | if (IsA(node, AlternativeSubPlan)) |
1074 | 0 | return true; |
1075 | 0 | if (IsA(node, FieldStore)) |
1076 | 0 | return true; |
1077 | 0 | if (IsA(node, CoerceViaIO)) |
1078 | 0 | { |
1079 | | /* |
1080 | | * CoerceViaIO is strict regardless of whether the I/O functions are, |
1081 | | * so just go look at its argument; asking check_functions_in_node is |
1082 | | * useless expense and could deliver the wrong answer. |
1083 | | */ |
1084 | 0 | return contain_nonstrict_functions_walker((Node *) ((CoerceViaIO *) node)->arg, |
1085 | 0 | context); |
1086 | 0 | } |
1087 | 0 | if (IsA(node, ArrayCoerceExpr)) |
1088 | 0 | { |
1089 | | /* |
1090 | | * ArrayCoerceExpr is strict at the array level, regardless of what |
1091 | | * the per-element expression is; so we should ignore elemexpr and |
1092 | | * recurse only into the arg. |
1093 | | */ |
1094 | 0 | return contain_nonstrict_functions_walker((Node *) ((ArrayCoerceExpr *) node)->arg, |
1095 | 0 | context); |
1096 | 0 | } |
1097 | 0 | if (IsA(node, CaseExpr)) |
1098 | 0 | return true; |
1099 | 0 | if (IsA(node, ArrayExpr)) |
1100 | 0 | return true; |
1101 | 0 | if (IsA(node, RowExpr)) |
1102 | 0 | return true; |
1103 | 0 | if (IsA(node, RowCompareExpr)) |
1104 | 0 | return true; |
1105 | 0 | if (IsA(node, CoalesceExpr)) |
1106 | 0 | return true; |
1107 | 0 | if (IsA(node, MinMaxExpr)) |
1108 | 0 | return true; |
1109 | 0 | if (IsA(node, XmlExpr)) |
1110 | 0 | return true; |
1111 | 0 | if (IsA(node, NullTest)) |
1112 | 0 | return true; |
1113 | 0 | if (IsA(node, BooleanTest)) |
1114 | 0 | return true; |
1115 | | |
1116 | | /* Check other function-containing nodes */ |
1117 | 0 | if (check_functions_in_node(node, contain_nonstrict_functions_checker, |
1118 | 0 | context)) |
1119 | 0 | return true; |
1120 | | |
1121 | 0 | return expression_tree_walker(node, contain_nonstrict_functions_walker, |
1122 | 0 | context); |
1123 | 0 | } |
1124 | | |
1125 | | /***************************************************************************** |
1126 | | * Check clauses for Params |
1127 | | *****************************************************************************/ |
1128 | | |
1129 | | /* |
1130 | | * contain_exec_param |
1131 | | * Recursively search for PARAM_EXEC Params within a clause. |
1132 | | * |
1133 | | * Returns true if the clause contains any PARAM_EXEC Param with a paramid |
1134 | | * appearing in the given list of Param IDs. Does not descend into |
1135 | | * subqueries! |
1136 | | */ |
1137 | | bool |
1138 | | contain_exec_param(Node *clause, List *param_ids) |
1139 | 0 | { |
1140 | 0 | return contain_exec_param_walker(clause, param_ids); |
1141 | 0 | } |
1142 | | |
1143 | | static bool |
1144 | | contain_exec_param_walker(Node *node, List *param_ids) |
1145 | 0 | { |
1146 | 0 | if (node == NULL) |
1147 | 0 | return false; |
1148 | 0 | if (IsA(node, Param)) |
1149 | 0 | { |
1150 | 0 | Param *p = (Param *) node; |
1151 | |
|
1152 | 0 | if (p->paramkind == PARAM_EXEC && |
1153 | 0 | list_member_int(param_ids, p->paramid)) |
1154 | 0 | return true; |
1155 | 0 | } |
1156 | 0 | return expression_tree_walker(node, contain_exec_param_walker, param_ids); |
1157 | 0 | } |
1158 | | |
1159 | | /***************************************************************************** |
1160 | | * Check clauses for context-dependent nodes |
1161 | | *****************************************************************************/ |
1162 | | |
1163 | | /* |
1164 | | * contain_context_dependent_node |
1165 | | * Recursively search for context-dependent nodes within a clause. |
1166 | | * |
1167 | | * CaseTestExpr nodes must appear directly within the corresponding CaseExpr, |
1168 | | * not nested within another one, or they'll see the wrong test value. If one |
1169 | | * appears "bare" in the arguments of a SQL function, then we can't inline the |
1170 | | * SQL function for fear of creating such a situation. The same applies for |
1171 | | * CaseTestExpr used within the elemexpr of an ArrayCoerceExpr. |
1172 | | * |
1173 | | * CoerceToDomainValue would have the same issue if domain CHECK expressions |
1174 | | * could get inlined into larger expressions, but presently that's impossible. |
1175 | | * Still, it might be allowed in future, or other node types with similar |
1176 | | * issues might get invented. So give this function a generic name, and set |
1177 | | * up the recursion state to allow multiple flag bits. |
1178 | | */ |
1179 | | static bool |
1180 | | contain_context_dependent_node(Node *clause) |
1181 | 0 | { |
1182 | 0 | int flags = 0; |
1183 | |
|
1184 | 0 | return contain_context_dependent_node_walker(clause, &flags); |
1185 | 0 | } |
1186 | | |
1187 | 0 | #define CCDN_CASETESTEXPR_OK 0x0001 /* CaseTestExpr okay here? */ |
1188 | | |
1189 | | static bool |
1190 | | contain_context_dependent_node_walker(Node *node, int *flags) |
1191 | 0 | { |
1192 | 0 | if (node == NULL) |
1193 | 0 | return false; |
1194 | 0 | if (IsA(node, CaseTestExpr)) |
1195 | 0 | return !(*flags & CCDN_CASETESTEXPR_OK); |
1196 | 0 | else if (IsA(node, CaseExpr)) |
1197 | 0 | { |
1198 | 0 | CaseExpr *caseexpr = (CaseExpr *) node; |
1199 | | |
1200 | | /* |
1201 | | * If this CASE doesn't have a test expression, then it doesn't create |
1202 | | * a context in which CaseTestExprs should appear, so just fall |
1203 | | * through and treat it as a generic expression node. |
1204 | | */ |
1205 | 0 | if (caseexpr->arg) |
1206 | 0 | { |
1207 | 0 | int save_flags = *flags; |
1208 | 0 | bool res; |
1209 | | |
1210 | | /* |
1211 | | * Note: in principle, we could distinguish the various sub-parts |
1212 | | * of a CASE construct and set the flag bit only for some of them, |
1213 | | * since we are only expecting CaseTestExprs to appear in the |
1214 | | * "expr" subtree of the CaseWhen nodes. But it doesn't really |
1215 | | * seem worth any extra code. If there are any bare CaseTestExprs |
1216 | | * elsewhere in the CASE, something's wrong already. |
1217 | | */ |
1218 | 0 | *flags |= CCDN_CASETESTEXPR_OK; |
1219 | 0 | res = expression_tree_walker(node, |
1220 | 0 | contain_context_dependent_node_walker, |
1221 | 0 | flags); |
1222 | 0 | *flags = save_flags; |
1223 | 0 | return res; |
1224 | 0 | } |
1225 | 0 | } |
1226 | 0 | else if (IsA(node, ArrayCoerceExpr)) |
1227 | 0 | { |
1228 | 0 | ArrayCoerceExpr *ac = (ArrayCoerceExpr *) node; |
1229 | 0 | int save_flags; |
1230 | 0 | bool res; |
1231 | | |
1232 | | /* Check the array expression */ |
1233 | 0 | if (contain_context_dependent_node_walker((Node *) ac->arg, flags)) |
1234 | 0 | return true; |
1235 | | |
1236 | | /* Check the elemexpr, which is allowed to contain CaseTestExpr */ |
1237 | 0 | save_flags = *flags; |
1238 | 0 | *flags |= CCDN_CASETESTEXPR_OK; |
1239 | 0 | res = contain_context_dependent_node_walker((Node *) ac->elemexpr, |
1240 | 0 | flags); |
1241 | 0 | *flags = save_flags; |
1242 | 0 | return res; |
1243 | 0 | } |
1244 | 0 | return expression_tree_walker(node, contain_context_dependent_node_walker, |
1245 | 0 | flags); |
1246 | 0 | } |
1247 | | |
1248 | | /***************************************************************************** |
1249 | | * Check clauses for Vars passed to non-leakproof functions |
1250 | | *****************************************************************************/ |
1251 | | |
1252 | | /* |
1253 | | * contain_leaked_vars |
1254 | | * Recursively scan a clause to discover whether it contains any Var |
1255 | | * nodes (of the current query level) that are passed as arguments to |
1256 | | * leaky functions. |
1257 | | * |
1258 | | * Returns true if the clause contains any non-leakproof functions that are |
1259 | | * passed Var nodes of the current query level, and which might therefore leak |
1260 | | * data. Such clauses must be applied after any lower-level security barrier |
1261 | | * clauses. |
1262 | | */ |
1263 | | bool |
1264 | | contain_leaked_vars(Node *clause) |
1265 | 0 | { |
1266 | 0 | return contain_leaked_vars_walker(clause, NULL); |
1267 | 0 | } |
1268 | | |
1269 | | static bool |
1270 | | contain_leaked_vars_checker(Oid func_id, void *context) |
1271 | 0 | { |
1272 | 0 | return !get_func_leakproof(func_id); |
1273 | 0 | } |
1274 | | |
1275 | | static bool |
1276 | | contain_leaked_vars_walker(Node *node, void *context) |
1277 | 0 | { |
1278 | 0 | if (node == NULL) |
1279 | 0 | return false; |
1280 | | |
1281 | 0 | switch (nodeTag(node)) |
1282 | 0 | { |
1283 | 0 | case T_Var: |
1284 | 0 | case T_Const: |
1285 | 0 | case T_Param: |
1286 | 0 | case T_ArrayExpr: |
1287 | 0 | case T_FieldSelect: |
1288 | 0 | case T_FieldStore: |
1289 | 0 | case T_NamedArgExpr: |
1290 | 0 | case T_BoolExpr: |
1291 | 0 | case T_RelabelType: |
1292 | 0 | case T_CollateExpr: |
1293 | 0 | case T_CaseExpr: |
1294 | 0 | case T_CaseTestExpr: |
1295 | 0 | case T_RowExpr: |
1296 | 0 | case T_SQLValueFunction: |
1297 | 0 | case T_NullTest: |
1298 | 0 | case T_BooleanTest: |
1299 | 0 | case T_NextValueExpr: |
1300 | 0 | case T_ReturningExpr: |
1301 | 0 | case T_List: |
1302 | | |
1303 | | /* |
1304 | | * We know these node types don't contain function calls; but |
1305 | | * something further down in the node tree might. |
1306 | | */ |
1307 | 0 | break; |
1308 | | |
1309 | 0 | case T_FuncExpr: |
1310 | 0 | case T_OpExpr: |
1311 | 0 | case T_DistinctExpr: |
1312 | 0 | case T_NullIfExpr: |
1313 | 0 | case T_ScalarArrayOpExpr: |
1314 | 0 | case T_CoerceViaIO: |
1315 | 0 | case T_ArrayCoerceExpr: |
1316 | | |
1317 | | /* |
1318 | | * If node contains a leaky function call, and there's any Var |
1319 | | * underneath it, reject. |
1320 | | */ |
1321 | 0 | if (check_functions_in_node(node, contain_leaked_vars_checker, |
1322 | 0 | context) && |
1323 | 0 | contain_var_clause(node)) |
1324 | 0 | return true; |
1325 | 0 | break; |
1326 | | |
1327 | 0 | case T_SubscriptingRef: |
1328 | 0 | { |
1329 | 0 | SubscriptingRef *sbsref = (SubscriptingRef *) node; |
1330 | 0 | const SubscriptRoutines *sbsroutines; |
1331 | | |
1332 | | /* Consult the subscripting support method info */ |
1333 | 0 | sbsroutines = getSubscriptingRoutines(sbsref->refcontainertype, |
1334 | 0 | NULL); |
1335 | 0 | if (!sbsroutines || |
1336 | 0 | !(sbsref->refassgnexpr != NULL ? |
1337 | 0 | sbsroutines->store_leakproof : |
1338 | 0 | sbsroutines->fetch_leakproof)) |
1339 | 0 | { |
1340 | | /* Node is leaky, so reject if it contains Vars */ |
1341 | 0 | if (contain_var_clause(node)) |
1342 | 0 | return true; |
1343 | 0 | } |
1344 | 0 | } |
1345 | 0 | break; |
1346 | | |
1347 | 0 | case T_RowCompareExpr: |
1348 | 0 | { |
1349 | | /* |
1350 | | * It's worth special-casing this because a leaky comparison |
1351 | | * function only compromises one pair of row elements, which |
1352 | | * might not contain Vars while others do. |
1353 | | */ |
1354 | 0 | RowCompareExpr *rcexpr = (RowCompareExpr *) node; |
1355 | 0 | ListCell *opid; |
1356 | 0 | ListCell *larg; |
1357 | 0 | ListCell *rarg; |
1358 | |
|
1359 | 0 | forthree(opid, rcexpr->opnos, |
1360 | 0 | larg, rcexpr->largs, |
1361 | 0 | rarg, rcexpr->rargs) |
1362 | 0 | { |
1363 | 0 | Oid funcid = get_opcode(lfirst_oid(opid)); |
1364 | |
|
1365 | 0 | if (!get_func_leakproof(funcid) && |
1366 | 0 | (contain_var_clause((Node *) lfirst(larg)) || |
1367 | 0 | contain_var_clause((Node *) lfirst(rarg)))) |
1368 | 0 | return true; |
1369 | 0 | } |
1370 | 0 | } |
1371 | 0 | break; |
1372 | | |
1373 | 0 | case T_MinMaxExpr: |
1374 | 0 | { |
1375 | | /* |
1376 | | * MinMaxExpr is leakproof if the comparison function it calls |
1377 | | * is leakproof. |
1378 | | */ |
1379 | 0 | MinMaxExpr *minmaxexpr = (MinMaxExpr *) node; |
1380 | 0 | TypeCacheEntry *typentry; |
1381 | 0 | bool leakproof; |
1382 | | |
1383 | | /* Look up the btree comparison function for the datatype */ |
1384 | 0 | typentry = lookup_type_cache(minmaxexpr->minmaxtype, |
1385 | 0 | TYPECACHE_CMP_PROC); |
1386 | 0 | if (OidIsValid(typentry->cmp_proc)) |
1387 | 0 | leakproof = get_func_leakproof(typentry->cmp_proc); |
1388 | 0 | else |
1389 | 0 | { |
1390 | | /* |
1391 | | * The executor will throw an error, but here we just |
1392 | | * treat the missing function as leaky. |
1393 | | */ |
1394 | 0 | leakproof = false; |
1395 | 0 | } |
1396 | |
|
1397 | 0 | if (!leakproof && |
1398 | 0 | contain_var_clause((Node *) minmaxexpr->args)) |
1399 | 0 | return true; |
1400 | 0 | } |
1401 | 0 | break; |
1402 | | |
1403 | 0 | case T_CurrentOfExpr: |
1404 | | |
1405 | | /* |
1406 | | * WHERE CURRENT OF doesn't contain leaky function calls. |
1407 | | * Moreover, it is essential that this is considered non-leaky, |
1408 | | * since the planner must always generate a TID scan when CURRENT |
1409 | | * OF is present -- cf. cost_tidscan. |
1410 | | */ |
1411 | 0 | return false; |
1412 | | |
1413 | 0 | default: |
1414 | | |
1415 | | /* |
1416 | | * If we don't recognize the node tag, assume it might be leaky. |
1417 | | * This prevents an unexpected security hole if someone adds a new |
1418 | | * node type that can call a function. |
1419 | | */ |
1420 | 0 | return true; |
1421 | 0 | } |
1422 | 0 | return expression_tree_walker(node, contain_leaked_vars_walker, |
1423 | 0 | context); |
1424 | 0 | } |
1425 | | |
1426 | | /* |
1427 | | * find_nonnullable_rels |
1428 | | * Determine which base rels are forced nonnullable by given clause. |
1429 | | * |
1430 | | * Returns the set of all Relids that are referenced in the clause in such |
1431 | | * a way that the clause cannot possibly return TRUE if any of these Relids |
1432 | | * is an all-NULL row. (It is OK to err on the side of conservatism; hence |
1433 | | * the analysis here is simplistic.) |
1434 | | * |
1435 | | * The semantics here are subtly different from contain_nonstrict_functions: |
1436 | | * that function is concerned with NULL results from arbitrary expressions, |
1437 | | * but here we assume that the input is a Boolean expression, and wish to |
1438 | | * see if NULL inputs will provably cause a FALSE-or-NULL result. We expect |
1439 | | * the expression to have been AND/OR flattened and converted to implicit-AND |
1440 | | * format. |
1441 | | * |
1442 | | * Note: this function is largely duplicative of find_nonnullable_vars(). |
1443 | | * The reason not to simplify this function into a thin wrapper around |
1444 | | * find_nonnullable_vars() is that the tested conditions really are different: |
1445 | | * a clause like "t1.v1 IS NOT NULL OR t1.v2 IS NOT NULL" does not prove |
1446 | | * that either v1 or v2 can't be NULL, but it does prove that the t1 row |
1447 | | * as a whole can't be all-NULL. Also, the behavior for PHVs is different. |
1448 | | * |
1449 | | * top_level is true while scanning top-level AND/OR structure; here, showing |
1450 | | * the result is either FALSE or NULL is good enough. top_level is false when |
1451 | | * we have descended below a NOT or a strict function: now we must be able to |
1452 | | * prove that the subexpression goes to NULL. |
1453 | | * |
1454 | | * We don't use expression_tree_walker here because we don't want to descend |
1455 | | * through very many kinds of nodes; only the ones we can be sure are strict. |
1456 | | */ |
1457 | | Relids |
1458 | | find_nonnullable_rels(Node *clause) |
1459 | 0 | { |
1460 | 0 | return find_nonnullable_rels_walker(clause, true); |
1461 | 0 | } |
1462 | | |
1463 | | static Relids |
1464 | | find_nonnullable_rels_walker(Node *node, bool top_level) |
1465 | 0 | { |
1466 | 0 | Relids result = NULL; |
1467 | 0 | ListCell *l; |
1468 | |
|
1469 | 0 | if (node == NULL) |
1470 | 0 | return NULL; |
1471 | 0 | if (IsA(node, Var)) |
1472 | 0 | { |
1473 | 0 | Var *var = (Var *) node; |
1474 | |
|
1475 | 0 | if (var->varlevelsup == 0) |
1476 | 0 | result = bms_make_singleton(var->varno); |
1477 | 0 | } |
1478 | 0 | else if (IsA(node, List)) |
1479 | 0 | { |
1480 | | /* |
1481 | | * At top level, we are examining an implicit-AND list: if any of the |
1482 | | * arms produces FALSE-or-NULL then the result is FALSE-or-NULL. If |
1483 | | * not at top level, we are examining the arguments of a strict |
1484 | | * function: if any of them produce NULL then the result of the |
1485 | | * function must be NULL. So in both cases, the set of nonnullable |
1486 | | * rels is the union of those found in the arms, and we pass down the |
1487 | | * top_level flag unmodified. |
1488 | | */ |
1489 | 0 | foreach(l, (List *) node) |
1490 | 0 | { |
1491 | 0 | result = bms_join(result, |
1492 | 0 | find_nonnullable_rels_walker(lfirst(l), |
1493 | 0 | top_level)); |
1494 | 0 | } |
1495 | 0 | } |
1496 | 0 | else if (IsA(node, FuncExpr)) |
1497 | 0 | { |
1498 | 0 | FuncExpr *expr = (FuncExpr *) node; |
1499 | |
|
1500 | 0 | if (func_strict(expr->funcid)) |
1501 | 0 | result = find_nonnullable_rels_walker((Node *) expr->args, false); |
1502 | 0 | } |
1503 | 0 | else if (IsA(node, OpExpr)) |
1504 | 0 | { |
1505 | 0 | OpExpr *expr = (OpExpr *) node; |
1506 | |
|
1507 | 0 | set_opfuncid(expr); |
1508 | 0 | if (func_strict(expr->opfuncid)) |
1509 | 0 | result = find_nonnullable_rels_walker((Node *) expr->args, false); |
1510 | 0 | } |
1511 | 0 | else if (IsA(node, ScalarArrayOpExpr)) |
1512 | 0 | { |
1513 | 0 | ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node; |
1514 | |
|
1515 | 0 | if (is_strict_saop(expr, true)) |
1516 | 0 | result = find_nonnullable_rels_walker((Node *) expr->args, false); |
1517 | 0 | } |
1518 | 0 | else if (IsA(node, BoolExpr)) |
1519 | 0 | { |
1520 | 0 | BoolExpr *expr = (BoolExpr *) node; |
1521 | |
|
1522 | 0 | switch (expr->boolop) |
1523 | 0 | { |
1524 | 0 | case AND_EXPR: |
1525 | | /* At top level we can just recurse (to the List case) */ |
1526 | 0 | if (top_level) |
1527 | 0 | { |
1528 | 0 | result = find_nonnullable_rels_walker((Node *) expr->args, |
1529 | 0 | top_level); |
1530 | 0 | break; |
1531 | 0 | } |
1532 | | |
1533 | | /* |
1534 | | * Below top level, even if one arm produces NULL, the result |
1535 | | * could be FALSE (hence not NULL). However, if *all* the |
1536 | | * arms produce NULL then the result is NULL, so we can take |
1537 | | * the intersection of the sets of nonnullable rels, just as |
1538 | | * for OR. Fall through to share code. |
1539 | | */ |
1540 | | /* FALL THRU */ |
1541 | 0 | case OR_EXPR: |
1542 | | |
1543 | | /* |
1544 | | * OR is strict if all of its arms are, so we can take the |
1545 | | * intersection of the sets of nonnullable rels for each arm. |
1546 | | * This works for both values of top_level. |
1547 | | */ |
1548 | 0 | foreach(l, expr->args) |
1549 | 0 | { |
1550 | 0 | Relids subresult; |
1551 | |
|
1552 | 0 | subresult = find_nonnullable_rels_walker(lfirst(l), |
1553 | 0 | top_level); |
1554 | 0 | if (result == NULL) /* first subresult? */ |
1555 | 0 | result = subresult; |
1556 | 0 | else |
1557 | 0 | result = bms_int_members(result, subresult); |
1558 | | |
1559 | | /* |
1560 | | * If the intersection is empty, we can stop looking. This |
1561 | | * also justifies the test for first-subresult above. |
1562 | | */ |
1563 | 0 | if (bms_is_empty(result)) |
1564 | 0 | break; |
1565 | 0 | } |
1566 | 0 | break; |
1567 | 0 | case NOT_EXPR: |
1568 | | /* NOT will return null if its arg is null */ |
1569 | 0 | result = find_nonnullable_rels_walker((Node *) expr->args, |
1570 | 0 | false); |
1571 | 0 | break; |
1572 | 0 | default: |
1573 | 0 | elog(ERROR, "unrecognized boolop: %d", (int) expr->boolop); |
1574 | 0 | break; |
1575 | 0 | } |
1576 | 0 | } |
1577 | 0 | else if (IsA(node, RelabelType)) |
1578 | 0 | { |
1579 | 0 | RelabelType *expr = (RelabelType *) node; |
1580 | |
|
1581 | 0 | result = find_nonnullable_rels_walker((Node *) expr->arg, top_level); |
1582 | 0 | } |
1583 | 0 | else if (IsA(node, CoerceViaIO)) |
1584 | 0 | { |
1585 | | /* not clear this is useful, but it can't hurt */ |
1586 | 0 | CoerceViaIO *expr = (CoerceViaIO *) node; |
1587 | |
|
1588 | 0 | result = find_nonnullable_rels_walker((Node *) expr->arg, top_level); |
1589 | 0 | } |
1590 | 0 | else if (IsA(node, ArrayCoerceExpr)) |
1591 | 0 | { |
1592 | | /* ArrayCoerceExpr is strict at the array level; ignore elemexpr */ |
1593 | 0 | ArrayCoerceExpr *expr = (ArrayCoerceExpr *) node; |
1594 | |
|
1595 | 0 | result = find_nonnullable_rels_walker((Node *) expr->arg, top_level); |
1596 | 0 | } |
1597 | 0 | else if (IsA(node, ConvertRowtypeExpr)) |
1598 | 0 | { |
1599 | | /* not clear this is useful, but it can't hurt */ |
1600 | 0 | ConvertRowtypeExpr *expr = (ConvertRowtypeExpr *) node; |
1601 | |
|
1602 | 0 | result = find_nonnullable_rels_walker((Node *) expr->arg, top_level); |
1603 | 0 | } |
1604 | 0 | else if (IsA(node, CollateExpr)) |
1605 | 0 | { |
1606 | 0 | CollateExpr *expr = (CollateExpr *) node; |
1607 | |
|
1608 | 0 | result = find_nonnullable_rels_walker((Node *) expr->arg, top_level); |
1609 | 0 | } |
1610 | 0 | else if (IsA(node, NullTest)) |
1611 | 0 | { |
1612 | | /* IS NOT NULL can be considered strict, but only at top level */ |
1613 | 0 | NullTest *expr = (NullTest *) node; |
1614 | |
|
1615 | 0 | if (top_level && expr->nulltesttype == IS_NOT_NULL && !expr->argisrow) |
1616 | 0 | result = find_nonnullable_rels_walker((Node *) expr->arg, false); |
1617 | 0 | } |
1618 | 0 | else if (IsA(node, BooleanTest)) |
1619 | 0 | { |
1620 | | /* Boolean tests that reject NULL are strict at top level */ |
1621 | 0 | BooleanTest *expr = (BooleanTest *) node; |
1622 | |
|
1623 | 0 | if (top_level && |
1624 | 0 | (expr->booltesttype == IS_TRUE || |
1625 | 0 | expr->booltesttype == IS_FALSE || |
1626 | 0 | expr->booltesttype == IS_NOT_UNKNOWN)) |
1627 | 0 | result = find_nonnullable_rels_walker((Node *) expr->arg, false); |
1628 | 0 | } |
1629 | 0 | else if (IsA(node, SubPlan)) |
1630 | 0 | { |
1631 | 0 | SubPlan *splan = (SubPlan *) node; |
1632 | | |
1633 | | /* |
1634 | | * For some types of SubPlan, we can infer strictness from Vars in the |
1635 | | * testexpr (the LHS of the original SubLink). |
1636 | | * |
1637 | | * For ANY_SUBLINK, if the subquery produces zero rows, the result is |
1638 | | * always FALSE. If the subquery produces more than one row, the |
1639 | | * per-row results of the testexpr are combined using OR semantics. |
1640 | | * Hence ANY_SUBLINK can be strict only at top level, but there it's |
1641 | | * as strict as the testexpr is. |
1642 | | * |
1643 | | * For ROWCOMPARE_SUBLINK, if the subquery produces zero rows, the |
1644 | | * result is always NULL. Otherwise, the result is as strict as the |
1645 | | * testexpr is. So we can check regardless of top_level. |
1646 | | * |
1647 | | * We can't prove anything for other sublink types (in particular, |
1648 | | * note that ALL_SUBLINK will return TRUE if the subquery is empty). |
1649 | | */ |
1650 | 0 | if ((top_level && splan->subLinkType == ANY_SUBLINK) || |
1651 | 0 | splan->subLinkType == ROWCOMPARE_SUBLINK) |
1652 | 0 | result = find_nonnullable_rels_walker(splan->testexpr, top_level); |
1653 | 0 | } |
1654 | 0 | else if (IsA(node, PlaceHolderVar)) |
1655 | 0 | { |
1656 | 0 | PlaceHolderVar *phv = (PlaceHolderVar *) node; |
1657 | | |
1658 | | /* |
1659 | | * If the contained expression forces any rels non-nullable, so does |
1660 | | * the PHV. |
1661 | | */ |
1662 | 0 | result = find_nonnullable_rels_walker((Node *) phv->phexpr, top_level); |
1663 | | |
1664 | | /* |
1665 | | * If the PHV's syntactic scope is exactly one rel, it will be forced |
1666 | | * to be evaluated at that rel, and so it will behave like a Var of |
1667 | | * that rel: if the rel's entire output goes to null, so will the PHV. |
1668 | | * (If the syntactic scope is a join, we know that the PHV will go to |
1669 | | * null if the whole join does; but that is AND semantics while we |
1670 | | * need OR semantics for find_nonnullable_rels' result, so we can't do |
1671 | | * anything with the knowledge.) |
1672 | | */ |
1673 | 0 | if (phv->phlevelsup == 0 && |
1674 | 0 | bms_membership(phv->phrels) == BMS_SINGLETON) |
1675 | 0 | result = bms_add_members(result, phv->phrels); |
1676 | 0 | } |
1677 | 0 | return result; |
1678 | 0 | } |
1679 | | |
1680 | | /* |
1681 | | * find_nonnullable_vars |
1682 | | * Determine which Vars are forced nonnullable by given clause. |
1683 | | * |
1684 | | * Returns the set of all level-zero Vars that are referenced in the clause in |
1685 | | * such a way that the clause cannot possibly return TRUE if any of these Vars |
1686 | | * is NULL. (It is OK to err on the side of conservatism; hence the analysis |
1687 | | * here is simplistic.) |
1688 | | * |
1689 | | * The semantics here are subtly different from contain_nonstrict_functions: |
1690 | | * that function is concerned with NULL results from arbitrary expressions, |
1691 | | * but here we assume that the input is a Boolean expression, and wish to |
1692 | | * see if NULL inputs will provably cause a FALSE-or-NULL result. We expect |
1693 | | * the expression to have been AND/OR flattened and converted to implicit-AND |
1694 | | * format. |
1695 | | * |
1696 | | * Attnos of the identified Vars are returned in a multibitmapset (a List of |
1697 | | * Bitmapsets). List indexes correspond to relids (varnos), while the per-rel |
1698 | | * Bitmapsets hold varattnos offset by FirstLowInvalidHeapAttributeNumber. |
1699 | | * |
1700 | | * top_level is true while scanning top-level AND/OR structure; here, showing |
1701 | | * the result is either FALSE or NULL is good enough. top_level is false when |
1702 | | * we have descended below a NOT or a strict function: now we must be able to |
1703 | | * prove that the subexpression goes to NULL. |
1704 | | * |
1705 | | * We don't use expression_tree_walker here because we don't want to descend |
1706 | | * through very many kinds of nodes; only the ones we can be sure are strict. |
1707 | | */ |
1708 | | List * |
1709 | | find_nonnullable_vars(Node *clause) |
1710 | 0 | { |
1711 | 0 | return find_nonnullable_vars_walker(clause, true); |
1712 | 0 | } |
1713 | | |
1714 | | static List * |
1715 | | find_nonnullable_vars_walker(Node *node, bool top_level) |
1716 | 0 | { |
1717 | 0 | List *result = NIL; |
1718 | 0 | ListCell *l; |
1719 | |
|
1720 | 0 | if (node == NULL) |
1721 | 0 | return NIL; |
1722 | 0 | if (IsA(node, Var)) |
1723 | 0 | { |
1724 | 0 | Var *var = (Var *) node; |
1725 | |
|
1726 | 0 | if (var->varlevelsup == 0) |
1727 | 0 | result = mbms_add_member(result, |
1728 | 0 | var->varno, |
1729 | 0 | var->varattno - FirstLowInvalidHeapAttributeNumber); |
1730 | 0 | } |
1731 | 0 | else if (IsA(node, List)) |
1732 | 0 | { |
1733 | | /* |
1734 | | * At top level, we are examining an implicit-AND list: if any of the |
1735 | | * arms produces FALSE-or-NULL then the result is FALSE-or-NULL. If |
1736 | | * not at top level, we are examining the arguments of a strict |
1737 | | * function: if any of them produce NULL then the result of the |
1738 | | * function must be NULL. So in both cases, the set of nonnullable |
1739 | | * vars is the union of those found in the arms, and we pass down the |
1740 | | * top_level flag unmodified. |
1741 | | */ |
1742 | 0 | foreach(l, (List *) node) |
1743 | 0 | { |
1744 | 0 | result = mbms_add_members(result, |
1745 | 0 | find_nonnullable_vars_walker(lfirst(l), |
1746 | 0 | top_level)); |
1747 | 0 | } |
1748 | 0 | } |
1749 | 0 | else if (IsA(node, FuncExpr)) |
1750 | 0 | { |
1751 | 0 | FuncExpr *expr = (FuncExpr *) node; |
1752 | |
|
1753 | 0 | if (func_strict(expr->funcid)) |
1754 | 0 | result = find_nonnullable_vars_walker((Node *) expr->args, false); |
1755 | 0 | } |
1756 | 0 | else if (IsA(node, OpExpr)) |
1757 | 0 | { |
1758 | 0 | OpExpr *expr = (OpExpr *) node; |
1759 | |
|
1760 | 0 | set_opfuncid(expr); |
1761 | 0 | if (func_strict(expr->opfuncid)) |
1762 | 0 | result = find_nonnullable_vars_walker((Node *) expr->args, false); |
1763 | 0 | } |
1764 | 0 | else if (IsA(node, ScalarArrayOpExpr)) |
1765 | 0 | { |
1766 | 0 | ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node; |
1767 | |
|
1768 | 0 | if (is_strict_saop(expr, true)) |
1769 | 0 | result = find_nonnullable_vars_walker((Node *) expr->args, false); |
1770 | 0 | } |
1771 | 0 | else if (IsA(node, BoolExpr)) |
1772 | 0 | { |
1773 | 0 | BoolExpr *expr = (BoolExpr *) node; |
1774 | |
|
1775 | 0 | switch (expr->boolop) |
1776 | 0 | { |
1777 | 0 | case AND_EXPR: |
1778 | | |
1779 | | /* |
1780 | | * At top level we can just recurse (to the List case), since |
1781 | | * the result should be the union of what we can prove in each |
1782 | | * arm. |
1783 | | */ |
1784 | 0 | if (top_level) |
1785 | 0 | { |
1786 | 0 | result = find_nonnullable_vars_walker((Node *) expr->args, |
1787 | 0 | top_level); |
1788 | 0 | break; |
1789 | 0 | } |
1790 | | |
1791 | | /* |
1792 | | * Below top level, even if one arm produces NULL, the result |
1793 | | * could be FALSE (hence not NULL). However, if *all* the |
1794 | | * arms produce NULL then the result is NULL, so we can take |
1795 | | * the intersection of the sets of nonnullable vars, just as |
1796 | | * for OR. Fall through to share code. |
1797 | | */ |
1798 | | /* FALL THRU */ |
1799 | 0 | case OR_EXPR: |
1800 | | |
1801 | | /* |
1802 | | * OR is strict if all of its arms are, so we can take the |
1803 | | * intersection of the sets of nonnullable vars for each arm. |
1804 | | * This works for both values of top_level. |
1805 | | */ |
1806 | 0 | foreach(l, expr->args) |
1807 | 0 | { |
1808 | 0 | List *subresult; |
1809 | |
|
1810 | 0 | subresult = find_nonnullable_vars_walker(lfirst(l), |
1811 | 0 | top_level); |
1812 | 0 | if (result == NIL) /* first subresult? */ |
1813 | 0 | result = subresult; |
1814 | 0 | else |
1815 | 0 | result = mbms_int_members(result, subresult); |
1816 | | |
1817 | | /* |
1818 | | * If the intersection is empty, we can stop looking. This |
1819 | | * also justifies the test for first-subresult above. |
1820 | | */ |
1821 | 0 | if (result == NIL) |
1822 | 0 | break; |
1823 | 0 | } |
1824 | 0 | break; |
1825 | 0 | case NOT_EXPR: |
1826 | | /* NOT will return null if its arg is null */ |
1827 | 0 | result = find_nonnullable_vars_walker((Node *) expr->args, |
1828 | 0 | false); |
1829 | 0 | break; |
1830 | 0 | default: |
1831 | 0 | elog(ERROR, "unrecognized boolop: %d", (int) expr->boolop); |
1832 | 0 | break; |
1833 | 0 | } |
1834 | 0 | } |
1835 | 0 | else if (IsA(node, RelabelType)) |
1836 | 0 | { |
1837 | 0 | RelabelType *expr = (RelabelType *) node; |
1838 | |
|
1839 | 0 | result = find_nonnullable_vars_walker((Node *) expr->arg, top_level); |
1840 | 0 | } |
1841 | 0 | else if (IsA(node, CoerceViaIO)) |
1842 | 0 | { |
1843 | | /* not clear this is useful, but it can't hurt */ |
1844 | 0 | CoerceViaIO *expr = (CoerceViaIO *) node; |
1845 | |
|
1846 | 0 | result = find_nonnullable_vars_walker((Node *) expr->arg, false); |
1847 | 0 | } |
1848 | 0 | else if (IsA(node, ArrayCoerceExpr)) |
1849 | 0 | { |
1850 | | /* ArrayCoerceExpr is strict at the array level; ignore elemexpr */ |
1851 | 0 | ArrayCoerceExpr *expr = (ArrayCoerceExpr *) node; |
1852 | |
|
1853 | 0 | result = find_nonnullable_vars_walker((Node *) expr->arg, top_level); |
1854 | 0 | } |
1855 | 0 | else if (IsA(node, ConvertRowtypeExpr)) |
1856 | 0 | { |
1857 | | /* not clear this is useful, but it can't hurt */ |
1858 | 0 | ConvertRowtypeExpr *expr = (ConvertRowtypeExpr *) node; |
1859 | |
|
1860 | 0 | result = find_nonnullable_vars_walker((Node *) expr->arg, top_level); |
1861 | 0 | } |
1862 | 0 | else if (IsA(node, CollateExpr)) |
1863 | 0 | { |
1864 | 0 | CollateExpr *expr = (CollateExpr *) node; |
1865 | |
|
1866 | 0 | result = find_nonnullable_vars_walker((Node *) expr->arg, top_level); |
1867 | 0 | } |
1868 | 0 | else if (IsA(node, NullTest)) |
1869 | 0 | { |
1870 | | /* IS NOT NULL can be considered strict, but only at top level */ |
1871 | 0 | NullTest *expr = (NullTest *) node; |
1872 | |
|
1873 | 0 | if (top_level && expr->nulltesttype == IS_NOT_NULL && !expr->argisrow) |
1874 | 0 | result = find_nonnullable_vars_walker((Node *) expr->arg, false); |
1875 | 0 | } |
1876 | 0 | else if (IsA(node, BooleanTest)) |
1877 | 0 | { |
1878 | | /* Boolean tests that reject NULL are strict at top level */ |
1879 | 0 | BooleanTest *expr = (BooleanTest *) node; |
1880 | |
|
1881 | 0 | if (top_level && |
1882 | 0 | (expr->booltesttype == IS_TRUE || |
1883 | 0 | expr->booltesttype == IS_FALSE || |
1884 | 0 | expr->booltesttype == IS_NOT_UNKNOWN)) |
1885 | 0 | result = find_nonnullable_vars_walker((Node *) expr->arg, false); |
1886 | 0 | } |
1887 | 0 | else if (IsA(node, SubPlan)) |
1888 | 0 | { |
1889 | 0 | SubPlan *splan = (SubPlan *) node; |
1890 | | |
1891 | | /* See analysis in find_nonnullable_rels_walker */ |
1892 | 0 | if ((top_level && splan->subLinkType == ANY_SUBLINK) || |
1893 | 0 | splan->subLinkType == ROWCOMPARE_SUBLINK) |
1894 | 0 | result = find_nonnullable_vars_walker(splan->testexpr, top_level); |
1895 | 0 | } |
1896 | 0 | else if (IsA(node, PlaceHolderVar)) |
1897 | 0 | { |
1898 | 0 | PlaceHolderVar *phv = (PlaceHolderVar *) node; |
1899 | |
|
1900 | 0 | result = find_nonnullable_vars_walker((Node *) phv->phexpr, top_level); |
1901 | 0 | } |
1902 | 0 | return result; |
1903 | 0 | } |
1904 | | |
1905 | | /* |
1906 | | * find_forced_null_vars |
1907 | | * Determine which Vars must be NULL for the given clause to return TRUE. |
1908 | | * |
1909 | | * This is the complement of find_nonnullable_vars: find the level-zero Vars |
1910 | | * that must be NULL for the clause to return TRUE. (It is OK to err on the |
1911 | | * side of conservatism; hence the analysis here is simplistic. In fact, |
1912 | | * we only detect simple "var IS NULL" tests at the top level.) |
1913 | | * |
1914 | | * As with find_nonnullable_vars, we return the varattnos of the identified |
1915 | | * Vars in a multibitmapset. |
1916 | | */ |
1917 | | List * |
1918 | | find_forced_null_vars(Node *node) |
1919 | 0 | { |
1920 | 0 | List *result = NIL; |
1921 | 0 | Var *var; |
1922 | 0 | ListCell *l; |
1923 | |
|
1924 | 0 | if (node == NULL) |
1925 | 0 | return NIL; |
1926 | | /* Check single-clause cases using subroutine */ |
1927 | 0 | var = find_forced_null_var(node); |
1928 | 0 | if (var) |
1929 | 0 | { |
1930 | 0 | result = mbms_add_member(result, |
1931 | 0 | var->varno, |
1932 | 0 | var->varattno - FirstLowInvalidHeapAttributeNumber); |
1933 | 0 | } |
1934 | | /* Otherwise, handle AND-conditions */ |
1935 | 0 | else if (IsA(node, List)) |
1936 | 0 | { |
1937 | | /* |
1938 | | * At top level, we are examining an implicit-AND list: if any of the |
1939 | | * arms produces FALSE-or-NULL then the result is FALSE-or-NULL. |
1940 | | */ |
1941 | 0 | foreach(l, (List *) node) |
1942 | 0 | { |
1943 | 0 | result = mbms_add_members(result, |
1944 | 0 | find_forced_null_vars((Node *) lfirst(l))); |
1945 | 0 | } |
1946 | 0 | } |
1947 | 0 | else if (IsA(node, BoolExpr)) |
1948 | 0 | { |
1949 | 0 | BoolExpr *expr = (BoolExpr *) node; |
1950 | | |
1951 | | /* |
1952 | | * We don't bother considering the OR case, because it's fairly |
1953 | | * unlikely anyone would write "v1 IS NULL OR v1 IS NULL". Likewise, |
1954 | | * the NOT case isn't worth expending code on. |
1955 | | */ |
1956 | 0 | if (expr->boolop == AND_EXPR) |
1957 | 0 | { |
1958 | | /* At top level we can just recurse (to the List case) */ |
1959 | 0 | result = find_forced_null_vars((Node *) expr->args); |
1960 | 0 | } |
1961 | 0 | } |
1962 | 0 | return result; |
1963 | 0 | } |
1964 | | |
1965 | | /* |
1966 | | * find_forced_null_var |
1967 | | * Return the Var forced null by the given clause, or NULL if it's |
1968 | | * not an IS NULL-type clause. For success, the clause must enforce |
1969 | | * *only* nullness of the particular Var, not any other conditions. |
1970 | | * |
1971 | | * This is just the single-clause case of find_forced_null_vars(), without |
1972 | | * any allowance for AND conditions. It's used by initsplan.c on individual |
1973 | | * qual clauses. The reason for not just applying find_forced_null_vars() |
1974 | | * is that if an AND of an IS NULL clause with something else were to somehow |
1975 | | * survive AND/OR flattening, initsplan.c might get fooled into discarding |
1976 | | * the whole clause when only the IS NULL part of it had been proved redundant. |
1977 | | */ |
1978 | | Var * |
1979 | | find_forced_null_var(Node *node) |
1980 | 0 | { |
1981 | 0 | if (node == NULL) |
1982 | 0 | return NULL; |
1983 | 0 | if (IsA(node, NullTest)) |
1984 | 0 | { |
1985 | | /* check for var IS NULL */ |
1986 | 0 | NullTest *expr = (NullTest *) node; |
1987 | |
|
1988 | 0 | if (expr->nulltesttype == IS_NULL && !expr->argisrow) |
1989 | 0 | { |
1990 | 0 | Var *var = (Var *) expr->arg; |
1991 | |
|
1992 | 0 | if (var && IsA(var, Var) && |
1993 | 0 | var->varlevelsup == 0) |
1994 | 0 | return var; |
1995 | 0 | } |
1996 | 0 | } |
1997 | 0 | else if (IsA(node, BooleanTest)) |
1998 | 0 | { |
1999 | | /* var IS UNKNOWN is equivalent to var IS NULL */ |
2000 | 0 | BooleanTest *expr = (BooleanTest *) node; |
2001 | |
|
2002 | 0 | if (expr->booltesttype == IS_UNKNOWN) |
2003 | 0 | { |
2004 | 0 | Var *var = (Var *) expr->arg; |
2005 | |
|
2006 | 0 | if (var && IsA(var, Var) && |
2007 | 0 | var->varlevelsup == 0) |
2008 | 0 | return var; |
2009 | 0 | } |
2010 | 0 | } |
2011 | 0 | return NULL; |
2012 | 0 | } |
2013 | | |
2014 | | /* |
2015 | | * Can we treat a ScalarArrayOpExpr as strict? |
2016 | | * |
2017 | | * If "falseOK" is true, then a "false" result can be considered strict, |
2018 | | * else we need to guarantee an actual NULL result for NULL input. |
2019 | | * |
2020 | | * "foo op ALL array" is strict if the op is strict *and* we can prove |
2021 | | * that the array input isn't an empty array. We can check that |
2022 | | * for the cases of an array constant and an ARRAY[] construct. |
2023 | | * |
2024 | | * "foo op ANY array" is strict in the falseOK sense if the op is strict. |
2025 | | * If not falseOK, the test is the same as for "foo op ALL array". |
2026 | | */ |
2027 | | static bool |
2028 | | is_strict_saop(ScalarArrayOpExpr *expr, bool falseOK) |
2029 | 0 | { |
2030 | 0 | Node *rightop; |
2031 | | |
2032 | | /* The contained operator must be strict. */ |
2033 | 0 | set_sa_opfuncid(expr); |
2034 | 0 | if (!func_strict(expr->opfuncid)) |
2035 | 0 | return false; |
2036 | | /* If ANY and falseOK, that's all we need to check. */ |
2037 | 0 | if (expr->useOr && falseOK) |
2038 | 0 | return true; |
2039 | | /* Else, we have to see if the array is provably non-empty. */ |
2040 | 0 | Assert(list_length(expr->args) == 2); |
2041 | 0 | rightop = (Node *) lsecond(expr->args); |
2042 | 0 | if (rightop && IsA(rightop, Const)) |
2043 | 0 | { |
2044 | 0 | Datum arraydatum = ((Const *) rightop)->constvalue; |
2045 | 0 | bool arrayisnull = ((Const *) rightop)->constisnull; |
2046 | 0 | ArrayType *arrayval; |
2047 | 0 | int nitems; |
2048 | |
|
2049 | 0 | if (arrayisnull) |
2050 | 0 | return false; |
2051 | 0 | arrayval = DatumGetArrayTypeP(arraydatum); |
2052 | 0 | nitems = ArrayGetNItems(ARR_NDIM(arrayval), ARR_DIMS(arrayval)); |
2053 | 0 | if (nitems > 0) |
2054 | 0 | return true; |
2055 | 0 | } |
2056 | 0 | else if (rightop && IsA(rightop, ArrayExpr)) |
2057 | 0 | { |
2058 | 0 | ArrayExpr *arrayexpr = (ArrayExpr *) rightop; |
2059 | |
|
2060 | 0 | if (arrayexpr->elements != NIL && !arrayexpr->multidims) |
2061 | 0 | return true; |
2062 | 0 | } |
2063 | 0 | return false; |
2064 | 0 | } |
2065 | | |
2066 | | |
2067 | | /***************************************************************************** |
2068 | | * Check for "pseudo-constant" clauses |
2069 | | *****************************************************************************/ |
2070 | | |
2071 | | /* |
2072 | | * is_pseudo_constant_clause |
2073 | | * Detect whether an expression is "pseudo constant", ie, it contains no |
2074 | | * variables of the current query level and no uses of volatile functions. |
2075 | | * Such an expr is not necessarily a true constant: it can still contain |
2076 | | * Params and outer-level Vars, not to mention functions whose results |
2077 | | * may vary from one statement to the next. However, the expr's value |
2078 | | * will be constant over any one scan of the current query, so it can be |
2079 | | * used as, eg, an indexscan key. (Actually, the condition for indexscan |
2080 | | * keys is weaker than this; see is_pseudo_constant_for_index().) |
2081 | | * |
2082 | | * CAUTION: this function omits to test for one very important class of |
2083 | | * not-constant expressions, namely aggregates (Aggrefs). In current usage |
2084 | | * this is only applied to WHERE clauses and so a check for Aggrefs would be |
2085 | | * a waste of cycles; but be sure to also check contain_agg_clause() if you |
2086 | | * want to know about pseudo-constness in other contexts. The same goes |
2087 | | * for window functions (WindowFuncs). |
2088 | | */ |
2089 | | bool |
2090 | | is_pseudo_constant_clause(Node *clause) |
2091 | 0 | { |
2092 | | /* |
2093 | | * We could implement this check in one recursive scan. But since the |
2094 | | * check for volatile functions is both moderately expensive and unlikely |
2095 | | * to fail, it seems better to look for Vars first and only check for |
2096 | | * volatile functions if we find no Vars. |
2097 | | */ |
2098 | 0 | if (!contain_var_clause(clause) && |
2099 | 0 | !contain_volatile_functions(clause)) |
2100 | 0 | return true; |
2101 | 0 | return false; |
2102 | 0 | } |
2103 | | |
2104 | | /* |
2105 | | * is_pseudo_constant_clause_relids |
2106 | | * Same as above, except caller already has available the var membership |
2107 | | * of the expression; this lets us avoid the contain_var_clause() scan. |
2108 | | */ |
2109 | | bool |
2110 | | is_pseudo_constant_clause_relids(Node *clause, Relids relids) |
2111 | 0 | { |
2112 | 0 | if (bms_is_empty(relids) && |
2113 | 0 | !contain_volatile_functions(clause)) |
2114 | 0 | return true; |
2115 | 0 | return false; |
2116 | 0 | } |
2117 | | |
2118 | | |
2119 | | /***************************************************************************** |
2120 | | * * |
2121 | | * General clause-manipulating routines * |
2122 | | * * |
2123 | | *****************************************************************************/ |
2124 | | |
2125 | | /* |
2126 | | * NumRelids |
2127 | | * (formerly clause_relids) |
2128 | | * |
2129 | | * Returns the number of different base relations referenced in 'clause'. |
2130 | | */ |
2131 | | int |
2132 | | NumRelids(PlannerInfo *root, Node *clause) |
2133 | 0 | { |
2134 | 0 | int result; |
2135 | 0 | Relids varnos = pull_varnos(root, clause); |
2136 | |
|
2137 | 0 | varnos = bms_del_members(varnos, root->outer_join_rels); |
2138 | 0 | result = bms_num_members(varnos); |
2139 | 0 | bms_free(varnos); |
2140 | 0 | return result; |
2141 | 0 | } |
2142 | | |
2143 | | /* |
2144 | | * CommuteOpExpr: commute a binary operator clause |
2145 | | * |
2146 | | * XXX the clause is destructively modified! |
2147 | | */ |
2148 | | void |
2149 | | CommuteOpExpr(OpExpr *clause) |
2150 | 0 | { |
2151 | 0 | Oid opoid; |
2152 | 0 | Node *temp; |
2153 | | |
2154 | | /* Sanity checks: caller is at fault if these fail */ |
2155 | 0 | if (!is_opclause(clause) || |
2156 | 0 | list_length(clause->args) != 2) |
2157 | 0 | elog(ERROR, "cannot commute non-binary-operator clause"); |
2158 | | |
2159 | 0 | opoid = get_commutator(clause->opno); |
2160 | |
|
2161 | 0 | if (!OidIsValid(opoid)) |
2162 | 0 | elog(ERROR, "could not find commutator for operator %u", |
2163 | 0 | clause->opno); |
2164 | | |
2165 | | /* |
2166 | | * modify the clause in-place! |
2167 | | */ |
2168 | 0 | clause->opno = opoid; |
2169 | 0 | clause->opfuncid = InvalidOid; |
2170 | | /* opresulttype, opretset, opcollid, inputcollid need not change */ |
2171 | |
|
2172 | 0 | temp = linitial(clause->args); |
2173 | 0 | linitial(clause->args) = lsecond(clause->args); |
2174 | 0 | lsecond(clause->args) = temp; |
2175 | 0 | } |
2176 | | |
2177 | | /* |
2178 | | * Helper for eval_const_expressions: check that datatype of an attribute |
2179 | | * is still what it was when the expression was parsed. This is needed to |
2180 | | * guard against improper simplification after ALTER COLUMN TYPE. (XXX we |
2181 | | * may well need to make similar checks elsewhere?) |
2182 | | * |
2183 | | * rowtypeid may come from a whole-row Var, and therefore it can be a domain |
2184 | | * over composite, but for this purpose we only care about checking the type |
2185 | | * of a contained field. |
2186 | | */ |
2187 | | static bool |
2188 | | rowtype_field_matches(Oid rowtypeid, int fieldnum, |
2189 | | Oid expectedtype, int32 expectedtypmod, |
2190 | | Oid expectedcollation) |
2191 | 0 | { |
2192 | 0 | TupleDesc tupdesc; |
2193 | 0 | Form_pg_attribute attr; |
2194 | | |
2195 | | /* No issue for RECORD, since there is no way to ALTER such a type */ |
2196 | 0 | if (rowtypeid == RECORDOID) |
2197 | 0 | return true; |
2198 | 0 | tupdesc = lookup_rowtype_tupdesc_domain(rowtypeid, -1, false); |
2199 | 0 | if (fieldnum <= 0 || fieldnum > tupdesc->natts) |
2200 | 0 | { |
2201 | 0 | ReleaseTupleDesc(tupdesc); |
2202 | 0 | return false; |
2203 | 0 | } |
2204 | 0 | attr = TupleDescAttr(tupdesc, fieldnum - 1); |
2205 | 0 | if (attr->attisdropped || |
2206 | 0 | attr->atttypid != expectedtype || |
2207 | 0 | attr->atttypmod != expectedtypmod || |
2208 | 0 | attr->attcollation != expectedcollation) |
2209 | 0 | { |
2210 | 0 | ReleaseTupleDesc(tupdesc); |
2211 | 0 | return false; |
2212 | 0 | } |
2213 | 0 | ReleaseTupleDesc(tupdesc); |
2214 | 0 | return true; |
2215 | 0 | } |
2216 | | |
2217 | | |
2218 | | /*-------------------- |
2219 | | * eval_const_expressions |
2220 | | * |
2221 | | * Reduce any recognizably constant subexpressions of the given |
2222 | | * expression tree, for example "2 + 2" => "4". More interestingly, |
2223 | | * we can reduce certain boolean expressions even when they contain |
2224 | | * non-constant subexpressions: "x OR true" => "true" no matter what |
2225 | | * the subexpression x is. (XXX We assume that no such subexpression |
2226 | | * will have important side-effects, which is not necessarily a good |
2227 | | * assumption in the presence of user-defined functions; do we need a |
2228 | | * pg_proc flag that prevents discarding the execution of a function?) |
2229 | | * |
2230 | | * We do understand that certain functions may deliver non-constant |
2231 | | * results even with constant inputs, "nextval()" being the classic |
2232 | | * example. Functions that are not marked "immutable" in pg_proc |
2233 | | * will not be pre-evaluated here, although we will reduce their |
2234 | | * arguments as far as possible. |
2235 | | * |
2236 | | * Whenever a function is eliminated from the expression by means of |
2237 | | * constant-expression evaluation or inlining, we add the function to |
2238 | | * root->glob->invalItems. This ensures the plan is known to depend on |
2239 | | * such functions, even though they aren't referenced anymore. |
2240 | | * |
2241 | | * We assume that the tree has already been type-checked and contains |
2242 | | * only operators and functions that are reasonable to try to execute. |
2243 | | * |
2244 | | * NOTE: "root" can be passed as NULL if the caller never wants to do any |
2245 | | * Param substitutions nor receive info about inlined functions. |
2246 | | * |
2247 | | * NOTE: the planner assumes that this will always flatten nested AND and |
2248 | | * OR clauses into N-argument form. See comments in prepqual.c. |
2249 | | * |
2250 | | * NOTE: another critical effect is that any function calls that require |
2251 | | * default arguments will be expanded, and named-argument calls will be |
2252 | | * converted to positional notation. The executor won't handle either. |
2253 | | *-------------------- |
2254 | | */ |
2255 | | Node * |
2256 | | eval_const_expressions(PlannerInfo *root, Node *node) |
2257 | 0 | { |
2258 | 0 | eval_const_expressions_context context; |
2259 | |
|
2260 | 0 | if (root) |
2261 | 0 | context.boundParams = root->glob->boundParams; /* bound Params */ |
2262 | 0 | else |
2263 | 0 | context.boundParams = NULL; |
2264 | 0 | context.root = root; /* for inlined-function dependencies */ |
2265 | 0 | context.active_fns = NIL; /* nothing being recursively simplified */ |
2266 | 0 | context.case_val = NULL; /* no CASE being examined */ |
2267 | 0 | context.estimate = false; /* safe transformations only */ |
2268 | 0 | return eval_const_expressions_mutator(node, &context); |
2269 | 0 | } |
2270 | | |
2271 | 0 | #define MIN_ARRAY_SIZE_FOR_HASHED_SAOP 9 |
2272 | | /*-------------------- |
2273 | | * convert_saop_to_hashed_saop |
2274 | | * |
2275 | | * Recursively search 'node' for ScalarArrayOpExprs and fill in the hash |
2276 | | * function for any ScalarArrayOpExpr that looks like it would be useful to |
2277 | | * evaluate using a hash table rather than a linear search. |
2278 | | * |
2279 | | * We'll use a hash table if all of the following conditions are met: |
2280 | | * 1. The 2nd argument of the array contain only Consts. |
2281 | | * 2. useOr is true or there is a valid negator operator for the |
2282 | | * ScalarArrayOpExpr's opno. |
2283 | | * 3. There's valid hash function for both left and righthand operands and |
2284 | | * these hash functions are the same. |
2285 | | * 4. If the array contains enough elements for us to consider it to be |
2286 | | * worthwhile using a hash table rather than a linear search. |
2287 | | */ |
2288 | | void |
2289 | | convert_saop_to_hashed_saop(Node *node) |
2290 | 0 | { |
2291 | 0 | (void) convert_saop_to_hashed_saop_walker(node, NULL); |
2292 | 0 | } |
2293 | | |
2294 | | static bool |
2295 | | convert_saop_to_hashed_saop_walker(Node *node, void *context) |
2296 | 0 | { |
2297 | 0 | if (node == NULL) |
2298 | 0 | return false; |
2299 | | |
2300 | 0 | if (IsA(node, ScalarArrayOpExpr)) |
2301 | 0 | { |
2302 | 0 | ScalarArrayOpExpr *saop = (ScalarArrayOpExpr *) node; |
2303 | 0 | Expr *arrayarg = (Expr *) lsecond(saop->args); |
2304 | 0 | Oid lefthashfunc; |
2305 | 0 | Oid righthashfunc; |
2306 | |
|
2307 | 0 | if (arrayarg && IsA(arrayarg, Const) && |
2308 | 0 | !((Const *) arrayarg)->constisnull) |
2309 | 0 | { |
2310 | 0 | if (saop->useOr) |
2311 | 0 | { |
2312 | 0 | if (get_op_hash_functions(saop->opno, &lefthashfunc, &righthashfunc) && |
2313 | 0 | lefthashfunc == righthashfunc) |
2314 | 0 | { |
2315 | 0 | Datum arrdatum = ((Const *) arrayarg)->constvalue; |
2316 | 0 | ArrayType *arr = (ArrayType *) DatumGetPointer(arrdatum); |
2317 | 0 | int nitems; |
2318 | | |
2319 | | /* |
2320 | | * Only fill in the hash functions if the array looks |
2321 | | * large enough for it to be worth hashing instead of |
2322 | | * doing a linear search. |
2323 | | */ |
2324 | 0 | nitems = ArrayGetNItems(ARR_NDIM(arr), ARR_DIMS(arr)); |
2325 | |
|
2326 | 0 | if (nitems >= MIN_ARRAY_SIZE_FOR_HASHED_SAOP) |
2327 | 0 | { |
2328 | | /* Looks good. Fill in the hash functions */ |
2329 | 0 | saop->hashfuncid = lefthashfunc; |
2330 | 0 | } |
2331 | 0 | return false; |
2332 | 0 | } |
2333 | 0 | } |
2334 | 0 | else /* !saop->useOr */ |
2335 | 0 | { |
2336 | 0 | Oid negator = get_negator(saop->opno); |
2337 | | |
2338 | | /* |
2339 | | * Check if this is a NOT IN using an operator whose negator |
2340 | | * is hashable. If so we can still build a hash table and |
2341 | | * just ensure the lookup items are not in the hash table. |
2342 | | */ |
2343 | 0 | if (OidIsValid(negator) && |
2344 | 0 | get_op_hash_functions(negator, &lefthashfunc, &righthashfunc) && |
2345 | 0 | lefthashfunc == righthashfunc) |
2346 | 0 | { |
2347 | 0 | Datum arrdatum = ((Const *) arrayarg)->constvalue; |
2348 | 0 | ArrayType *arr = (ArrayType *) DatumGetPointer(arrdatum); |
2349 | 0 | int nitems; |
2350 | | |
2351 | | /* |
2352 | | * Only fill in the hash functions if the array looks |
2353 | | * large enough for it to be worth hashing instead of |
2354 | | * doing a linear search. |
2355 | | */ |
2356 | 0 | nitems = ArrayGetNItems(ARR_NDIM(arr), ARR_DIMS(arr)); |
2357 | |
|
2358 | 0 | if (nitems >= MIN_ARRAY_SIZE_FOR_HASHED_SAOP) |
2359 | 0 | { |
2360 | | /* Looks good. Fill in the hash functions */ |
2361 | 0 | saop->hashfuncid = lefthashfunc; |
2362 | | |
2363 | | /* |
2364 | | * Also set the negfuncid. The executor will need |
2365 | | * that to perform hashtable lookups. |
2366 | | */ |
2367 | 0 | saop->negfuncid = get_opcode(negator); |
2368 | 0 | } |
2369 | 0 | return false; |
2370 | 0 | } |
2371 | 0 | } |
2372 | 0 | } |
2373 | 0 | } |
2374 | | |
2375 | 0 | return expression_tree_walker(node, convert_saop_to_hashed_saop_walker, NULL); |
2376 | 0 | } |
2377 | | |
2378 | | |
2379 | | /*-------------------- |
2380 | | * estimate_expression_value |
2381 | | * |
2382 | | * This function attempts to estimate the value of an expression for |
2383 | | * planning purposes. It is in essence a more aggressive version of |
2384 | | * eval_const_expressions(): we will perform constant reductions that are |
2385 | | * not necessarily 100% safe, but are reasonable for estimation purposes. |
2386 | | * |
2387 | | * Currently the extra steps that are taken in this mode are: |
2388 | | * 1. Substitute values for Params, where a bound Param value has been made |
2389 | | * available by the caller of planner(), even if the Param isn't marked |
2390 | | * constant. This effectively means that we plan using the first supplied |
2391 | | * value of the Param. |
2392 | | * 2. Fold stable, as well as immutable, functions to constants. |
2393 | | * 3. Reduce PlaceHolderVar nodes to their contained expressions. |
2394 | | *-------------------- |
2395 | | */ |
2396 | | Node * |
2397 | | estimate_expression_value(PlannerInfo *root, Node *node) |
2398 | 0 | { |
2399 | 0 | eval_const_expressions_context context; |
2400 | |
|
2401 | 0 | context.boundParams = root->glob->boundParams; /* bound Params */ |
2402 | | /* we do not need to mark the plan as depending on inlined functions */ |
2403 | 0 | context.root = NULL; |
2404 | 0 | context.active_fns = NIL; /* nothing being recursively simplified */ |
2405 | 0 | context.case_val = NULL; /* no CASE being examined */ |
2406 | 0 | context.estimate = true; /* unsafe transformations OK */ |
2407 | 0 | return eval_const_expressions_mutator(node, &context); |
2408 | 0 | } |
2409 | | |
2410 | | /* |
2411 | | * The generic case in eval_const_expressions_mutator is to recurse using |
2412 | | * expression_tree_mutator, which will copy the given node unchanged but |
2413 | | * const-simplify its arguments (if any) as far as possible. If the node |
2414 | | * itself does immutable processing, and each of its arguments were reduced |
2415 | | * to a Const, we can then reduce it to a Const using evaluate_expr. (Some |
2416 | | * node types need more complicated logic; for example, a CASE expression |
2417 | | * might be reducible to a constant even if not all its subtrees are.) |
2418 | | */ |
2419 | | #define ece_generic_processing(node) \ |
2420 | 0 | expression_tree_mutator((Node *) (node), eval_const_expressions_mutator, \ |
2421 | 0 | context) |
2422 | | |
2423 | | /* |
2424 | | * Check whether all arguments of the given node were reduced to Consts. |
2425 | | * By going directly to expression_tree_walker, contain_non_const_walker |
2426 | | * is not applied to the node itself, only to its children. |
2427 | | */ |
2428 | | #define ece_all_arguments_const(node) \ |
2429 | 0 | (!expression_tree_walker((Node *) (node), contain_non_const_walker, NULL)) |
2430 | | |
2431 | | /* Generic macro for applying evaluate_expr */ |
2432 | | #define ece_evaluate_expr(node) \ |
2433 | 0 | ((Node *) evaluate_expr((Expr *) (node), \ |
2434 | 0 | exprType((Node *) (node)), \ |
2435 | 0 | exprTypmod((Node *) (node)), \ |
2436 | 0 | exprCollation((Node *) (node)))) |
2437 | | |
2438 | | /* |
2439 | | * Recursive guts of eval_const_expressions/estimate_expression_value |
2440 | | */ |
2441 | | static Node * |
2442 | | eval_const_expressions_mutator(Node *node, |
2443 | | eval_const_expressions_context *context) |
2444 | 0 | { |
2445 | | |
2446 | | /* since this function recurses, it could be driven to stack overflow */ |
2447 | 0 | check_stack_depth(); |
2448 | |
|
2449 | 0 | if (node == NULL) |
2450 | 0 | return NULL; |
2451 | 0 | switch (nodeTag(node)) |
2452 | 0 | { |
2453 | 0 | case T_Param: |
2454 | 0 | { |
2455 | 0 | Param *param = (Param *) node; |
2456 | 0 | ParamListInfo paramLI = context->boundParams; |
2457 | | |
2458 | | /* Look to see if we've been given a value for this Param */ |
2459 | 0 | if (param->paramkind == PARAM_EXTERN && |
2460 | 0 | paramLI != NULL && |
2461 | 0 | param->paramid > 0 && |
2462 | 0 | param->paramid <= paramLI->numParams) |
2463 | 0 | { |
2464 | 0 | ParamExternData *prm; |
2465 | 0 | ParamExternData prmdata; |
2466 | | |
2467 | | /* |
2468 | | * Give hook a chance in case parameter is dynamic. Tell |
2469 | | * it that this fetch is speculative, so it should avoid |
2470 | | * erroring out if parameter is unavailable. |
2471 | | */ |
2472 | 0 | if (paramLI->paramFetch != NULL) |
2473 | 0 | prm = paramLI->paramFetch(paramLI, param->paramid, |
2474 | 0 | true, &prmdata); |
2475 | 0 | else |
2476 | 0 | prm = ¶mLI->params[param->paramid - 1]; |
2477 | | |
2478 | | /* |
2479 | | * We don't just check OidIsValid, but insist that the |
2480 | | * fetched type match the Param, just in case the hook did |
2481 | | * something unexpected. No need to throw an error here |
2482 | | * though; leave that for runtime. |
2483 | | */ |
2484 | 0 | if (OidIsValid(prm->ptype) && |
2485 | 0 | prm->ptype == param->paramtype) |
2486 | 0 | { |
2487 | | /* OK to substitute parameter value? */ |
2488 | 0 | if (context->estimate || |
2489 | 0 | (prm->pflags & PARAM_FLAG_CONST)) |
2490 | 0 | { |
2491 | | /* |
2492 | | * Return a Const representing the param value. |
2493 | | * Must copy pass-by-ref datatypes, since the |
2494 | | * Param might be in a memory context |
2495 | | * shorter-lived than our output plan should be. |
2496 | | */ |
2497 | 0 | int16 typLen; |
2498 | 0 | bool typByVal; |
2499 | 0 | Datum pval; |
2500 | 0 | Const *con; |
2501 | |
|
2502 | 0 | get_typlenbyval(param->paramtype, |
2503 | 0 | &typLen, &typByVal); |
2504 | 0 | if (prm->isnull || typByVal) |
2505 | 0 | pval = prm->value; |
2506 | 0 | else |
2507 | 0 | pval = datumCopy(prm->value, typByVal, typLen); |
2508 | 0 | con = makeConst(param->paramtype, |
2509 | 0 | param->paramtypmod, |
2510 | 0 | param->paramcollid, |
2511 | 0 | (int) typLen, |
2512 | 0 | pval, |
2513 | 0 | prm->isnull, |
2514 | 0 | typByVal); |
2515 | 0 | con->location = param->location; |
2516 | 0 | return (Node *) con; |
2517 | 0 | } |
2518 | 0 | } |
2519 | 0 | } |
2520 | | |
2521 | | /* |
2522 | | * Not replaceable, so just copy the Param (no need to |
2523 | | * recurse) |
2524 | | */ |
2525 | 0 | return (Node *) copyObject(param); |
2526 | 0 | } |
2527 | 0 | case T_WindowFunc: |
2528 | 0 | { |
2529 | 0 | WindowFunc *expr = (WindowFunc *) node; |
2530 | 0 | Oid funcid = expr->winfnoid; |
2531 | 0 | List *args; |
2532 | 0 | Expr *aggfilter; |
2533 | 0 | HeapTuple func_tuple; |
2534 | 0 | WindowFunc *newexpr; |
2535 | | |
2536 | | /* |
2537 | | * We can't really simplify a WindowFunc node, but we mustn't |
2538 | | * just fall through to the default processing, because we |
2539 | | * have to apply expand_function_arguments to its argument |
2540 | | * list. That takes care of inserting default arguments and |
2541 | | * expanding named-argument notation. |
2542 | | */ |
2543 | 0 | func_tuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid)); |
2544 | 0 | if (!HeapTupleIsValid(func_tuple)) |
2545 | 0 | elog(ERROR, "cache lookup failed for function %u", funcid); |
2546 | | |
2547 | 0 | args = expand_function_arguments(expr->args, |
2548 | 0 | false, expr->wintype, |
2549 | 0 | func_tuple); |
2550 | |
|
2551 | 0 | ReleaseSysCache(func_tuple); |
2552 | | |
2553 | | /* Now, recursively simplify the args (which are a List) */ |
2554 | 0 | args = (List *) |
2555 | 0 | expression_tree_mutator((Node *) args, |
2556 | 0 | eval_const_expressions_mutator, |
2557 | 0 | context); |
2558 | | /* ... and the filter expression, which isn't */ |
2559 | 0 | aggfilter = (Expr *) |
2560 | 0 | eval_const_expressions_mutator((Node *) expr->aggfilter, |
2561 | 0 | context); |
2562 | | |
2563 | | /* And build the replacement WindowFunc node */ |
2564 | 0 | newexpr = makeNode(WindowFunc); |
2565 | 0 | newexpr->winfnoid = expr->winfnoid; |
2566 | 0 | newexpr->wintype = expr->wintype; |
2567 | 0 | newexpr->wincollid = expr->wincollid; |
2568 | 0 | newexpr->inputcollid = expr->inputcollid; |
2569 | 0 | newexpr->args = args; |
2570 | 0 | newexpr->aggfilter = aggfilter; |
2571 | 0 | newexpr->runCondition = expr->runCondition; |
2572 | 0 | newexpr->winref = expr->winref; |
2573 | 0 | newexpr->winstar = expr->winstar; |
2574 | 0 | newexpr->winagg = expr->winagg; |
2575 | 0 | newexpr->location = expr->location; |
2576 | |
|
2577 | 0 | return (Node *) newexpr; |
2578 | 0 | } |
2579 | 0 | case T_FuncExpr: |
2580 | 0 | { |
2581 | 0 | FuncExpr *expr = (FuncExpr *) node; |
2582 | 0 | List *args = expr->args; |
2583 | 0 | Expr *simple; |
2584 | 0 | FuncExpr *newexpr; |
2585 | | |
2586 | | /* |
2587 | | * Code for op/func reduction is pretty bulky, so split it out |
2588 | | * as a separate function. Note: exprTypmod normally returns |
2589 | | * -1 for a FuncExpr, but not when the node is recognizably a |
2590 | | * length coercion; we want to preserve the typmod in the |
2591 | | * eventual Const if so. |
2592 | | */ |
2593 | 0 | simple = simplify_function(expr->funcid, |
2594 | 0 | expr->funcresulttype, |
2595 | 0 | exprTypmod(node), |
2596 | 0 | expr->funccollid, |
2597 | 0 | expr->inputcollid, |
2598 | 0 | &args, |
2599 | 0 | expr->funcvariadic, |
2600 | 0 | true, |
2601 | 0 | true, |
2602 | 0 | context); |
2603 | 0 | if (simple) /* successfully simplified it */ |
2604 | 0 | return (Node *) simple; |
2605 | | |
2606 | | /* |
2607 | | * The expression cannot be simplified any further, so build |
2608 | | * and return a replacement FuncExpr node using the |
2609 | | * possibly-simplified arguments. Note that we have also |
2610 | | * converted the argument list to positional notation. |
2611 | | */ |
2612 | 0 | newexpr = makeNode(FuncExpr); |
2613 | 0 | newexpr->funcid = expr->funcid; |
2614 | 0 | newexpr->funcresulttype = expr->funcresulttype; |
2615 | 0 | newexpr->funcretset = expr->funcretset; |
2616 | 0 | newexpr->funcvariadic = expr->funcvariadic; |
2617 | 0 | newexpr->funcformat = expr->funcformat; |
2618 | 0 | newexpr->funccollid = expr->funccollid; |
2619 | 0 | newexpr->inputcollid = expr->inputcollid; |
2620 | 0 | newexpr->args = args; |
2621 | 0 | newexpr->location = expr->location; |
2622 | 0 | return (Node *) newexpr; |
2623 | 0 | } |
2624 | 0 | case T_OpExpr: |
2625 | 0 | { |
2626 | 0 | OpExpr *expr = (OpExpr *) node; |
2627 | 0 | List *args = expr->args; |
2628 | 0 | Expr *simple; |
2629 | 0 | OpExpr *newexpr; |
2630 | | |
2631 | | /* |
2632 | | * Need to get OID of underlying function. Okay to scribble |
2633 | | * on input to this extent. |
2634 | | */ |
2635 | 0 | set_opfuncid(expr); |
2636 | | |
2637 | | /* |
2638 | | * Code for op/func reduction is pretty bulky, so split it out |
2639 | | * as a separate function. |
2640 | | */ |
2641 | 0 | simple = simplify_function(expr->opfuncid, |
2642 | 0 | expr->opresulttype, -1, |
2643 | 0 | expr->opcollid, |
2644 | 0 | expr->inputcollid, |
2645 | 0 | &args, |
2646 | 0 | false, |
2647 | 0 | true, |
2648 | 0 | true, |
2649 | 0 | context); |
2650 | 0 | if (simple) /* successfully simplified it */ |
2651 | 0 | return (Node *) simple; |
2652 | | |
2653 | | /* |
2654 | | * If the operator is boolean equality or inequality, we know |
2655 | | * how to simplify cases involving one constant and one |
2656 | | * non-constant argument. |
2657 | | */ |
2658 | 0 | if (expr->opno == BooleanEqualOperator || |
2659 | 0 | expr->opno == BooleanNotEqualOperator) |
2660 | 0 | { |
2661 | 0 | simple = (Expr *) simplify_boolean_equality(expr->opno, |
2662 | 0 | args); |
2663 | 0 | if (simple) /* successfully simplified it */ |
2664 | 0 | return (Node *) simple; |
2665 | 0 | } |
2666 | | |
2667 | | /* |
2668 | | * The expression cannot be simplified any further, so build |
2669 | | * and return a replacement OpExpr node using the |
2670 | | * possibly-simplified arguments. |
2671 | | */ |
2672 | 0 | newexpr = makeNode(OpExpr); |
2673 | 0 | newexpr->opno = expr->opno; |
2674 | 0 | newexpr->opfuncid = expr->opfuncid; |
2675 | 0 | newexpr->opresulttype = expr->opresulttype; |
2676 | 0 | newexpr->opretset = expr->opretset; |
2677 | 0 | newexpr->opcollid = expr->opcollid; |
2678 | 0 | newexpr->inputcollid = expr->inputcollid; |
2679 | 0 | newexpr->args = args; |
2680 | 0 | newexpr->location = expr->location; |
2681 | 0 | return (Node *) newexpr; |
2682 | 0 | } |
2683 | 0 | case T_DistinctExpr: |
2684 | 0 | { |
2685 | 0 | DistinctExpr *expr = (DistinctExpr *) node; |
2686 | 0 | List *args; |
2687 | 0 | ListCell *arg; |
2688 | 0 | bool has_null_input = false; |
2689 | 0 | bool all_null_input = true; |
2690 | 0 | bool has_nonconst_input = false; |
2691 | 0 | Expr *simple; |
2692 | 0 | DistinctExpr *newexpr; |
2693 | | |
2694 | | /* |
2695 | | * Reduce constants in the DistinctExpr's arguments. We know |
2696 | | * args is either NIL or a List node, so we can call |
2697 | | * expression_tree_mutator directly rather than recursing to |
2698 | | * self. |
2699 | | */ |
2700 | 0 | args = (List *) expression_tree_mutator((Node *) expr->args, |
2701 | 0 | eval_const_expressions_mutator, |
2702 | 0 | context); |
2703 | | |
2704 | | /* |
2705 | | * We must do our own check for NULLs because DistinctExpr has |
2706 | | * different results for NULL input than the underlying |
2707 | | * operator does. |
2708 | | */ |
2709 | 0 | foreach(arg, args) |
2710 | 0 | { |
2711 | 0 | if (IsA(lfirst(arg), Const)) |
2712 | 0 | { |
2713 | 0 | has_null_input |= ((Const *) lfirst(arg))->constisnull; |
2714 | 0 | all_null_input &= ((Const *) lfirst(arg))->constisnull; |
2715 | 0 | } |
2716 | 0 | else |
2717 | 0 | has_nonconst_input = true; |
2718 | 0 | } |
2719 | | |
2720 | | /* all constants? then can optimize this out */ |
2721 | 0 | if (!has_nonconst_input) |
2722 | 0 | { |
2723 | | /* all nulls? then not distinct */ |
2724 | 0 | if (all_null_input) |
2725 | 0 | return makeBoolConst(false, false); |
2726 | | |
2727 | | /* one null? then distinct */ |
2728 | 0 | if (has_null_input) |
2729 | 0 | return makeBoolConst(true, false); |
2730 | | |
2731 | | /* otherwise try to evaluate the '=' operator */ |
2732 | | /* (NOT okay to try to inline it, though!) */ |
2733 | | |
2734 | | /* |
2735 | | * Need to get OID of underlying function. Okay to |
2736 | | * scribble on input to this extent. |
2737 | | */ |
2738 | 0 | set_opfuncid((OpExpr *) expr); /* rely on struct |
2739 | | * equivalence */ |
2740 | | |
2741 | | /* |
2742 | | * Code for op/func reduction is pretty bulky, so split it |
2743 | | * out as a separate function. |
2744 | | */ |
2745 | 0 | simple = simplify_function(expr->opfuncid, |
2746 | 0 | expr->opresulttype, -1, |
2747 | 0 | expr->opcollid, |
2748 | 0 | expr->inputcollid, |
2749 | 0 | &args, |
2750 | 0 | false, |
2751 | 0 | false, |
2752 | 0 | false, |
2753 | 0 | context); |
2754 | 0 | if (simple) /* successfully simplified it */ |
2755 | 0 | { |
2756 | | /* |
2757 | | * Since the underlying operator is "=", must negate |
2758 | | * its result |
2759 | | */ |
2760 | 0 | Const *csimple = castNode(Const, simple); |
2761 | |
|
2762 | 0 | csimple->constvalue = |
2763 | 0 | BoolGetDatum(!DatumGetBool(csimple->constvalue)); |
2764 | 0 | return (Node *) csimple; |
2765 | 0 | } |
2766 | 0 | } |
2767 | | |
2768 | | /* |
2769 | | * The expression cannot be simplified any further, so build |
2770 | | * and return a replacement DistinctExpr node using the |
2771 | | * possibly-simplified arguments. |
2772 | | */ |
2773 | 0 | newexpr = makeNode(DistinctExpr); |
2774 | 0 | newexpr->opno = expr->opno; |
2775 | 0 | newexpr->opfuncid = expr->opfuncid; |
2776 | 0 | newexpr->opresulttype = expr->opresulttype; |
2777 | 0 | newexpr->opretset = expr->opretset; |
2778 | 0 | newexpr->opcollid = expr->opcollid; |
2779 | 0 | newexpr->inputcollid = expr->inputcollid; |
2780 | 0 | newexpr->args = args; |
2781 | 0 | newexpr->location = expr->location; |
2782 | 0 | return (Node *) newexpr; |
2783 | 0 | } |
2784 | 0 | case T_NullIfExpr: |
2785 | 0 | { |
2786 | 0 | NullIfExpr *expr; |
2787 | 0 | ListCell *arg; |
2788 | 0 | bool has_nonconst_input = false; |
2789 | | |
2790 | | /* Copy the node and const-simplify its arguments */ |
2791 | 0 | expr = (NullIfExpr *) ece_generic_processing(node); |
2792 | | |
2793 | | /* If either argument is NULL they can't be equal */ |
2794 | 0 | foreach(arg, expr->args) |
2795 | 0 | { |
2796 | 0 | if (!IsA(lfirst(arg), Const)) |
2797 | 0 | has_nonconst_input = true; |
2798 | 0 | else if (((Const *) lfirst(arg))->constisnull) |
2799 | 0 | return (Node *) linitial(expr->args); |
2800 | 0 | } |
2801 | | |
2802 | | /* |
2803 | | * Need to get OID of underlying function before checking if |
2804 | | * the function is OK to evaluate. |
2805 | | */ |
2806 | 0 | set_opfuncid((OpExpr *) expr); |
2807 | |
|
2808 | 0 | if (!has_nonconst_input && |
2809 | 0 | ece_function_is_safe(expr->opfuncid, context)) |
2810 | 0 | return ece_evaluate_expr(expr); |
2811 | | |
2812 | 0 | return (Node *) expr; |
2813 | 0 | } |
2814 | 0 | case T_ScalarArrayOpExpr: |
2815 | 0 | { |
2816 | 0 | ScalarArrayOpExpr *saop; |
2817 | | |
2818 | | /* Copy the node and const-simplify its arguments */ |
2819 | 0 | saop = (ScalarArrayOpExpr *) ece_generic_processing(node); |
2820 | | |
2821 | | /* Make sure we know underlying function */ |
2822 | 0 | set_sa_opfuncid(saop); |
2823 | | |
2824 | | /* |
2825 | | * If all arguments are Consts, and it's a safe function, we |
2826 | | * can fold to a constant |
2827 | | */ |
2828 | 0 | if (ece_all_arguments_const(saop) && |
2829 | 0 | ece_function_is_safe(saop->opfuncid, context)) |
2830 | 0 | return ece_evaluate_expr(saop); |
2831 | 0 | return (Node *) saop; |
2832 | 0 | } |
2833 | 0 | case T_BoolExpr: |
2834 | 0 | { |
2835 | 0 | BoolExpr *expr = (BoolExpr *) node; |
2836 | |
|
2837 | 0 | switch (expr->boolop) |
2838 | 0 | { |
2839 | 0 | case OR_EXPR: |
2840 | 0 | { |
2841 | 0 | List *newargs; |
2842 | 0 | bool haveNull = false; |
2843 | 0 | bool forceTrue = false; |
2844 | |
|
2845 | 0 | newargs = simplify_or_arguments(expr->args, |
2846 | 0 | context, |
2847 | 0 | &haveNull, |
2848 | 0 | &forceTrue); |
2849 | 0 | if (forceTrue) |
2850 | 0 | return makeBoolConst(true, false); |
2851 | 0 | if (haveNull) |
2852 | 0 | newargs = lappend(newargs, |
2853 | 0 | makeBoolConst(false, true)); |
2854 | | /* If all the inputs are FALSE, result is FALSE */ |
2855 | 0 | if (newargs == NIL) |
2856 | 0 | return makeBoolConst(false, false); |
2857 | | |
2858 | | /* |
2859 | | * If only one nonconst-or-NULL input, it's the |
2860 | | * result |
2861 | | */ |
2862 | 0 | if (list_length(newargs) == 1) |
2863 | 0 | return (Node *) linitial(newargs); |
2864 | | /* Else we still need an OR node */ |
2865 | 0 | return (Node *) make_orclause(newargs); |
2866 | 0 | } |
2867 | 0 | case AND_EXPR: |
2868 | 0 | { |
2869 | 0 | List *newargs; |
2870 | 0 | bool haveNull = false; |
2871 | 0 | bool forceFalse = false; |
2872 | |
|
2873 | 0 | newargs = simplify_and_arguments(expr->args, |
2874 | 0 | context, |
2875 | 0 | &haveNull, |
2876 | 0 | &forceFalse); |
2877 | 0 | if (forceFalse) |
2878 | 0 | return makeBoolConst(false, false); |
2879 | 0 | if (haveNull) |
2880 | 0 | newargs = lappend(newargs, |
2881 | 0 | makeBoolConst(false, true)); |
2882 | | /* If all the inputs are TRUE, result is TRUE */ |
2883 | 0 | if (newargs == NIL) |
2884 | 0 | return makeBoolConst(true, false); |
2885 | | |
2886 | | /* |
2887 | | * If only one nonconst-or-NULL input, it's the |
2888 | | * result |
2889 | | */ |
2890 | 0 | if (list_length(newargs) == 1) |
2891 | 0 | return (Node *) linitial(newargs); |
2892 | | /* Else we still need an AND node */ |
2893 | 0 | return (Node *) make_andclause(newargs); |
2894 | 0 | } |
2895 | 0 | case NOT_EXPR: |
2896 | 0 | { |
2897 | 0 | Node *arg; |
2898 | |
|
2899 | 0 | Assert(list_length(expr->args) == 1); |
2900 | 0 | arg = eval_const_expressions_mutator(linitial(expr->args), |
2901 | 0 | context); |
2902 | | |
2903 | | /* |
2904 | | * Use negate_clause() to see if we can simplify |
2905 | | * away the NOT. |
2906 | | */ |
2907 | 0 | return negate_clause(arg); |
2908 | 0 | } |
2909 | 0 | default: |
2910 | 0 | elog(ERROR, "unrecognized boolop: %d", |
2911 | 0 | (int) expr->boolop); |
2912 | 0 | break; |
2913 | 0 | } |
2914 | 0 | break; |
2915 | 0 | } |
2916 | | |
2917 | 0 | case T_JsonValueExpr: |
2918 | 0 | { |
2919 | 0 | JsonValueExpr *jve = (JsonValueExpr *) node; |
2920 | 0 | Node *raw_expr = (Node *) jve->raw_expr; |
2921 | 0 | Node *formatted_expr = (Node *) jve->formatted_expr; |
2922 | | |
2923 | | /* |
2924 | | * If we can fold formatted_expr to a constant, we can elide |
2925 | | * the JsonValueExpr altogether. Otherwise we must process |
2926 | | * raw_expr too. But JsonFormat is a flat node and requires |
2927 | | * no simplification, only copying. |
2928 | | */ |
2929 | 0 | formatted_expr = eval_const_expressions_mutator(formatted_expr, |
2930 | 0 | context); |
2931 | 0 | if (formatted_expr && IsA(formatted_expr, Const)) |
2932 | 0 | return formatted_expr; |
2933 | | |
2934 | 0 | raw_expr = eval_const_expressions_mutator(raw_expr, context); |
2935 | |
|
2936 | 0 | return (Node *) makeJsonValueExpr((Expr *) raw_expr, |
2937 | 0 | (Expr *) formatted_expr, |
2938 | 0 | copyObject(jve->format)); |
2939 | 0 | } |
2940 | | |
2941 | 0 | case T_SubPlan: |
2942 | 0 | case T_AlternativeSubPlan: |
2943 | | |
2944 | | /* |
2945 | | * Return a SubPlan unchanged --- too late to do anything with it. |
2946 | | * |
2947 | | * XXX should we ereport() here instead? Probably this routine |
2948 | | * should never be invoked after SubPlan creation. |
2949 | | */ |
2950 | 0 | return node; |
2951 | 0 | case T_RelabelType: |
2952 | 0 | { |
2953 | 0 | RelabelType *relabel = (RelabelType *) node; |
2954 | 0 | Node *arg; |
2955 | | |
2956 | | /* Simplify the input ... */ |
2957 | 0 | arg = eval_const_expressions_mutator((Node *) relabel->arg, |
2958 | 0 | context); |
2959 | | /* ... and attach a new RelabelType node, if needed */ |
2960 | 0 | return applyRelabelType(arg, |
2961 | 0 | relabel->resulttype, |
2962 | 0 | relabel->resulttypmod, |
2963 | 0 | relabel->resultcollid, |
2964 | 0 | relabel->relabelformat, |
2965 | 0 | relabel->location, |
2966 | 0 | true); |
2967 | 0 | } |
2968 | 0 | case T_CoerceViaIO: |
2969 | 0 | { |
2970 | 0 | CoerceViaIO *expr = (CoerceViaIO *) node; |
2971 | 0 | List *args; |
2972 | 0 | Oid outfunc; |
2973 | 0 | bool outtypisvarlena; |
2974 | 0 | Oid infunc; |
2975 | 0 | Oid intypioparam; |
2976 | 0 | Expr *simple; |
2977 | 0 | CoerceViaIO *newexpr; |
2978 | | |
2979 | | /* Make a List so we can use simplify_function */ |
2980 | 0 | args = list_make1(expr->arg); |
2981 | | |
2982 | | /* |
2983 | | * CoerceViaIO represents calling the source type's output |
2984 | | * function then the result type's input function. So, try to |
2985 | | * simplify it as though it were a stack of two such function |
2986 | | * calls. First we need to know what the functions are. |
2987 | | * |
2988 | | * Note that the coercion functions are assumed not to care |
2989 | | * about input collation, so we just pass InvalidOid for that. |
2990 | | */ |
2991 | 0 | getTypeOutputInfo(exprType((Node *) expr->arg), |
2992 | 0 | &outfunc, &outtypisvarlena); |
2993 | 0 | getTypeInputInfo(expr->resulttype, |
2994 | 0 | &infunc, &intypioparam); |
2995 | |
|
2996 | 0 | simple = simplify_function(outfunc, |
2997 | 0 | CSTRINGOID, -1, |
2998 | 0 | InvalidOid, |
2999 | 0 | InvalidOid, |
3000 | 0 | &args, |
3001 | 0 | false, |
3002 | 0 | true, |
3003 | 0 | true, |
3004 | 0 | context); |
3005 | 0 | if (simple) /* successfully simplified output fn */ |
3006 | 0 | { |
3007 | | /* |
3008 | | * Input functions may want 1 to 3 arguments. We always |
3009 | | * supply all three, trusting that nothing downstream will |
3010 | | * complain. |
3011 | | */ |
3012 | 0 | args = list_make3(simple, |
3013 | 0 | makeConst(OIDOID, |
3014 | 0 | -1, |
3015 | 0 | InvalidOid, |
3016 | 0 | sizeof(Oid), |
3017 | 0 | ObjectIdGetDatum(intypioparam), |
3018 | 0 | false, |
3019 | 0 | true), |
3020 | 0 | makeConst(INT4OID, |
3021 | 0 | -1, |
3022 | 0 | InvalidOid, |
3023 | 0 | sizeof(int32), |
3024 | 0 | Int32GetDatum(-1), |
3025 | 0 | false, |
3026 | 0 | true)); |
3027 | |
|
3028 | 0 | simple = simplify_function(infunc, |
3029 | 0 | expr->resulttype, -1, |
3030 | 0 | expr->resultcollid, |
3031 | 0 | InvalidOid, |
3032 | 0 | &args, |
3033 | 0 | false, |
3034 | 0 | false, |
3035 | 0 | true, |
3036 | 0 | context); |
3037 | 0 | if (simple) /* successfully simplified input fn */ |
3038 | 0 | return (Node *) simple; |
3039 | 0 | } |
3040 | | |
3041 | | /* |
3042 | | * The expression cannot be simplified any further, so build |
3043 | | * and return a replacement CoerceViaIO node using the |
3044 | | * possibly-simplified argument. |
3045 | | */ |
3046 | 0 | newexpr = makeNode(CoerceViaIO); |
3047 | 0 | newexpr->arg = (Expr *) linitial(args); |
3048 | 0 | newexpr->resulttype = expr->resulttype; |
3049 | 0 | newexpr->resultcollid = expr->resultcollid; |
3050 | 0 | newexpr->coerceformat = expr->coerceformat; |
3051 | 0 | newexpr->location = expr->location; |
3052 | 0 | return (Node *) newexpr; |
3053 | 0 | } |
3054 | 0 | case T_ArrayCoerceExpr: |
3055 | 0 | { |
3056 | 0 | ArrayCoerceExpr *ac = makeNode(ArrayCoerceExpr); |
3057 | 0 | Node *save_case_val; |
3058 | | |
3059 | | /* |
3060 | | * Copy the node and const-simplify its arguments. We can't |
3061 | | * use ece_generic_processing() here because we need to mess |
3062 | | * with case_val only while processing the elemexpr. |
3063 | | */ |
3064 | 0 | memcpy(ac, node, sizeof(ArrayCoerceExpr)); |
3065 | 0 | ac->arg = (Expr *) |
3066 | 0 | eval_const_expressions_mutator((Node *) ac->arg, |
3067 | 0 | context); |
3068 | | |
3069 | | /* |
3070 | | * Set up for the CaseTestExpr node contained in the elemexpr. |
3071 | | * We must prevent it from absorbing any outer CASE value. |
3072 | | */ |
3073 | 0 | save_case_val = context->case_val; |
3074 | 0 | context->case_val = NULL; |
3075 | |
|
3076 | 0 | ac->elemexpr = (Expr *) |
3077 | 0 | eval_const_expressions_mutator((Node *) ac->elemexpr, |
3078 | 0 | context); |
3079 | |
|
3080 | 0 | context->case_val = save_case_val; |
3081 | | |
3082 | | /* |
3083 | | * If constant argument and the per-element expression is |
3084 | | * immutable, we can simplify the whole thing to a constant. |
3085 | | * Exception: although contain_mutable_functions considers |
3086 | | * CoerceToDomain immutable for historical reasons, let's not |
3087 | | * do so here; this ensures coercion to an array-over-domain |
3088 | | * does not apply the domain's constraints until runtime. |
3089 | | */ |
3090 | 0 | if (ac->arg && IsA(ac->arg, Const) && |
3091 | 0 | ac->elemexpr && !IsA(ac->elemexpr, CoerceToDomain) && |
3092 | 0 | !contain_mutable_functions((Node *) ac->elemexpr)) |
3093 | 0 | return ece_evaluate_expr(ac); |
3094 | | |
3095 | 0 | return (Node *) ac; |
3096 | 0 | } |
3097 | 0 | case T_CollateExpr: |
3098 | 0 | { |
3099 | | /* |
3100 | | * We replace CollateExpr with RelabelType, so as to improve |
3101 | | * uniformity of expression representation and thus simplify |
3102 | | * comparison of expressions. Hence this looks very nearly |
3103 | | * the same as the RelabelType case, and we can apply the same |
3104 | | * optimizations to avoid unnecessary RelabelTypes. |
3105 | | */ |
3106 | 0 | CollateExpr *collate = (CollateExpr *) node; |
3107 | 0 | Node *arg; |
3108 | | |
3109 | | /* Simplify the input ... */ |
3110 | 0 | arg = eval_const_expressions_mutator((Node *) collate->arg, |
3111 | 0 | context); |
3112 | | /* ... and attach a new RelabelType node, if needed */ |
3113 | 0 | return applyRelabelType(arg, |
3114 | 0 | exprType(arg), |
3115 | 0 | exprTypmod(arg), |
3116 | 0 | collate->collOid, |
3117 | 0 | COERCE_IMPLICIT_CAST, |
3118 | 0 | collate->location, |
3119 | 0 | true); |
3120 | 0 | } |
3121 | 0 | case T_CaseExpr: |
3122 | 0 | { |
3123 | | /*---------- |
3124 | | * CASE expressions can be simplified if there are constant |
3125 | | * condition clauses: |
3126 | | * FALSE (or NULL): drop the alternative |
3127 | | * TRUE: drop all remaining alternatives |
3128 | | * If the first non-FALSE alternative is a constant TRUE, |
3129 | | * we can simplify the entire CASE to that alternative's |
3130 | | * expression. If there are no non-FALSE alternatives, |
3131 | | * we simplify the entire CASE to the default result (ELSE). |
3132 | | * |
3133 | | * If we have a simple-form CASE with constant test |
3134 | | * expression, we substitute the constant value for contained |
3135 | | * CaseTestExpr placeholder nodes, so that we have the |
3136 | | * opportunity to reduce constant test conditions. For |
3137 | | * example this allows |
3138 | | * CASE 0 WHEN 0 THEN 1 ELSE 1/0 END |
3139 | | * to reduce to 1 rather than drawing a divide-by-0 error. |
3140 | | * Note that when the test expression is constant, we don't |
3141 | | * have to include it in the resulting CASE; for example |
3142 | | * CASE 0 WHEN x THEN y ELSE z END |
3143 | | * is transformed by the parser to |
3144 | | * CASE 0 WHEN CaseTestExpr = x THEN y ELSE z END |
3145 | | * which we can simplify to |
3146 | | * CASE WHEN 0 = x THEN y ELSE z END |
3147 | | * It is not necessary for the executor to evaluate the "arg" |
3148 | | * expression when executing the CASE, since any contained |
3149 | | * CaseTestExprs that might have referred to it will have been |
3150 | | * replaced by the constant. |
3151 | | *---------- |
3152 | | */ |
3153 | 0 | CaseExpr *caseexpr = (CaseExpr *) node; |
3154 | 0 | CaseExpr *newcase; |
3155 | 0 | Node *save_case_val; |
3156 | 0 | Node *newarg; |
3157 | 0 | List *newargs; |
3158 | 0 | bool const_true_cond; |
3159 | 0 | Node *defresult = NULL; |
3160 | 0 | ListCell *arg; |
3161 | | |
3162 | | /* Simplify the test expression, if any */ |
3163 | 0 | newarg = eval_const_expressions_mutator((Node *) caseexpr->arg, |
3164 | 0 | context); |
3165 | | |
3166 | | /* Set up for contained CaseTestExpr nodes */ |
3167 | 0 | save_case_val = context->case_val; |
3168 | 0 | if (newarg && IsA(newarg, Const)) |
3169 | 0 | { |
3170 | 0 | context->case_val = newarg; |
3171 | 0 | newarg = NULL; /* not needed anymore, see above */ |
3172 | 0 | } |
3173 | 0 | else |
3174 | 0 | context->case_val = NULL; |
3175 | | |
3176 | | /* Simplify the WHEN clauses */ |
3177 | 0 | newargs = NIL; |
3178 | 0 | const_true_cond = false; |
3179 | 0 | foreach(arg, caseexpr->args) |
3180 | 0 | { |
3181 | 0 | CaseWhen *oldcasewhen = lfirst_node(CaseWhen, arg); |
3182 | 0 | Node *casecond; |
3183 | 0 | Node *caseresult; |
3184 | | |
3185 | | /* Simplify this alternative's test condition */ |
3186 | 0 | casecond = eval_const_expressions_mutator((Node *) oldcasewhen->expr, |
3187 | 0 | context); |
3188 | | |
3189 | | /* |
3190 | | * If the test condition is constant FALSE (or NULL), then |
3191 | | * drop this WHEN clause completely, without processing |
3192 | | * the result. |
3193 | | */ |
3194 | 0 | if (casecond && IsA(casecond, Const)) |
3195 | 0 | { |
3196 | 0 | Const *const_input = (Const *) casecond; |
3197 | |
|
3198 | 0 | if (const_input->constisnull || |
3199 | 0 | !DatumGetBool(const_input->constvalue)) |
3200 | 0 | continue; /* drop alternative with FALSE cond */ |
3201 | | /* Else it's constant TRUE */ |
3202 | 0 | const_true_cond = true; |
3203 | 0 | } |
3204 | | |
3205 | | /* Simplify this alternative's result value */ |
3206 | 0 | caseresult = eval_const_expressions_mutator((Node *) oldcasewhen->result, |
3207 | 0 | context); |
3208 | | |
3209 | | /* If non-constant test condition, emit a new WHEN node */ |
3210 | 0 | if (!const_true_cond) |
3211 | 0 | { |
3212 | 0 | CaseWhen *newcasewhen = makeNode(CaseWhen); |
3213 | |
|
3214 | 0 | newcasewhen->expr = (Expr *) casecond; |
3215 | 0 | newcasewhen->result = (Expr *) caseresult; |
3216 | 0 | newcasewhen->location = oldcasewhen->location; |
3217 | 0 | newargs = lappend(newargs, newcasewhen); |
3218 | 0 | continue; |
3219 | 0 | } |
3220 | | |
3221 | | /* |
3222 | | * Found a TRUE condition, so none of the remaining |
3223 | | * alternatives can be reached. We treat the result as |
3224 | | * the default result. |
3225 | | */ |
3226 | 0 | defresult = caseresult; |
3227 | 0 | break; |
3228 | 0 | } |
3229 | | |
3230 | | /* Simplify the default result, unless we replaced it above */ |
3231 | 0 | if (!const_true_cond) |
3232 | 0 | defresult = eval_const_expressions_mutator((Node *) caseexpr->defresult, |
3233 | 0 | context); |
3234 | |
|
3235 | 0 | context->case_val = save_case_val; |
3236 | | |
3237 | | /* |
3238 | | * If no non-FALSE alternatives, CASE reduces to the default |
3239 | | * result |
3240 | | */ |
3241 | 0 | if (newargs == NIL) |
3242 | 0 | return defresult; |
3243 | | /* Otherwise we need a new CASE node */ |
3244 | 0 | newcase = makeNode(CaseExpr); |
3245 | 0 | newcase->casetype = caseexpr->casetype; |
3246 | 0 | newcase->casecollid = caseexpr->casecollid; |
3247 | 0 | newcase->arg = (Expr *) newarg; |
3248 | 0 | newcase->args = newargs; |
3249 | 0 | newcase->defresult = (Expr *) defresult; |
3250 | 0 | newcase->location = caseexpr->location; |
3251 | 0 | return (Node *) newcase; |
3252 | 0 | } |
3253 | 0 | case T_CaseTestExpr: |
3254 | 0 | { |
3255 | | /* |
3256 | | * If we know a constant test value for the current CASE |
3257 | | * construct, substitute it for the placeholder. Else just |
3258 | | * return the placeholder as-is. |
3259 | | */ |
3260 | 0 | if (context->case_val) |
3261 | 0 | return copyObject(context->case_val); |
3262 | 0 | else |
3263 | 0 | return copyObject(node); |
3264 | 0 | } |
3265 | 0 | case T_SubscriptingRef: |
3266 | 0 | case T_ArrayExpr: |
3267 | 0 | case T_RowExpr: |
3268 | 0 | case T_MinMaxExpr: |
3269 | 0 | { |
3270 | | /* |
3271 | | * Generic handling for node types whose own processing is |
3272 | | * known to be immutable, and for which we need no smarts |
3273 | | * beyond "simplify if all inputs are constants". |
3274 | | * |
3275 | | * Treating SubscriptingRef this way assumes that subscripting |
3276 | | * fetch and assignment are both immutable. This constrains |
3277 | | * type-specific subscripting implementations; maybe we should |
3278 | | * relax it someday. |
3279 | | * |
3280 | | * Treating MinMaxExpr this way amounts to assuming that the |
3281 | | * btree comparison function it calls is immutable; see the |
3282 | | * reasoning in contain_mutable_functions_walker. |
3283 | | */ |
3284 | | |
3285 | | /* Copy the node and const-simplify its arguments */ |
3286 | 0 | node = ece_generic_processing(node); |
3287 | | /* If all arguments are Consts, we can fold to a constant */ |
3288 | 0 | if (ece_all_arguments_const(node)) |
3289 | 0 | return ece_evaluate_expr(node); |
3290 | 0 | return node; |
3291 | 0 | } |
3292 | 0 | case T_CoalesceExpr: |
3293 | 0 | { |
3294 | 0 | CoalesceExpr *coalesceexpr = (CoalesceExpr *) node; |
3295 | 0 | CoalesceExpr *newcoalesce; |
3296 | 0 | List *newargs; |
3297 | 0 | ListCell *arg; |
3298 | |
|
3299 | 0 | newargs = NIL; |
3300 | 0 | foreach(arg, coalesceexpr->args) |
3301 | 0 | { |
3302 | 0 | Node *e; |
3303 | |
|
3304 | 0 | e = eval_const_expressions_mutator((Node *) lfirst(arg), |
3305 | 0 | context); |
3306 | | |
3307 | | /* |
3308 | | * We can remove null constants from the list. For a |
3309 | | * non-null constant, if it has not been preceded by any |
3310 | | * other non-null-constant expressions then it is the |
3311 | | * result. Otherwise, it's the next argument, but we can |
3312 | | * drop following arguments since they will never be |
3313 | | * reached. |
3314 | | */ |
3315 | 0 | if (IsA(e, Const)) |
3316 | 0 | { |
3317 | 0 | if (((Const *) e)->constisnull) |
3318 | 0 | continue; /* drop null constant */ |
3319 | 0 | if (newargs == NIL) |
3320 | 0 | return e; /* first expr */ |
3321 | 0 | newargs = lappend(newargs, e); |
3322 | 0 | break; |
3323 | 0 | } |
3324 | 0 | newargs = lappend(newargs, e); |
3325 | 0 | } |
3326 | | |
3327 | | /* |
3328 | | * If all the arguments were constant null, the result is just |
3329 | | * null |
3330 | | */ |
3331 | 0 | if (newargs == NIL) |
3332 | 0 | return (Node *) makeNullConst(coalesceexpr->coalescetype, |
3333 | 0 | -1, |
3334 | 0 | coalesceexpr->coalescecollid); |
3335 | | |
3336 | 0 | newcoalesce = makeNode(CoalesceExpr); |
3337 | 0 | newcoalesce->coalescetype = coalesceexpr->coalescetype; |
3338 | 0 | newcoalesce->coalescecollid = coalesceexpr->coalescecollid; |
3339 | 0 | newcoalesce->args = newargs; |
3340 | 0 | newcoalesce->location = coalesceexpr->location; |
3341 | 0 | return (Node *) newcoalesce; |
3342 | 0 | } |
3343 | 0 | case T_SQLValueFunction: |
3344 | 0 | { |
3345 | | /* |
3346 | | * All variants of SQLValueFunction are stable, so if we are |
3347 | | * estimating the expression's value, we should evaluate the |
3348 | | * current function value. Otherwise just copy. |
3349 | | */ |
3350 | 0 | SQLValueFunction *svf = (SQLValueFunction *) node; |
3351 | |
|
3352 | 0 | if (context->estimate) |
3353 | 0 | return (Node *) evaluate_expr((Expr *) svf, |
3354 | 0 | svf->type, |
3355 | 0 | svf->typmod, |
3356 | 0 | InvalidOid); |
3357 | 0 | else |
3358 | 0 | return copyObject((Node *) svf); |
3359 | 0 | } |
3360 | 0 | case T_FieldSelect: |
3361 | 0 | { |
3362 | | /* |
3363 | | * We can optimize field selection from a whole-row Var into a |
3364 | | * simple Var. (This case won't be generated directly by the |
3365 | | * parser, because ParseComplexProjection short-circuits it. |
3366 | | * But it can arise while simplifying functions.) Also, we |
3367 | | * can optimize field selection from a RowExpr construct, or |
3368 | | * of course from a constant. |
3369 | | * |
3370 | | * However, replacing a whole-row Var in this way has a |
3371 | | * pitfall: if we've already built the rel targetlist for the |
3372 | | * source relation, then the whole-row Var is scheduled to be |
3373 | | * produced by the relation scan, but the simple Var probably |
3374 | | * isn't, which will lead to a failure in setrefs.c. This is |
3375 | | * not a problem when handling simple single-level queries, in |
3376 | | * which expression simplification always happens first. It |
3377 | | * is a risk for lateral references from subqueries, though. |
3378 | | * To avoid such failures, don't optimize uplevel references. |
3379 | | * |
3380 | | * We must also check that the declared type of the field is |
3381 | | * still the same as when the FieldSelect was created --- this |
3382 | | * can change if someone did ALTER COLUMN TYPE on the rowtype. |
3383 | | * If it isn't, we skip the optimization; the case will |
3384 | | * probably fail at runtime, but that's not our problem here. |
3385 | | */ |
3386 | 0 | FieldSelect *fselect = (FieldSelect *) node; |
3387 | 0 | FieldSelect *newfselect; |
3388 | 0 | Node *arg; |
3389 | |
|
3390 | 0 | arg = eval_const_expressions_mutator((Node *) fselect->arg, |
3391 | 0 | context); |
3392 | 0 | if (arg && IsA(arg, Var) && |
3393 | 0 | ((Var *) arg)->varattno == InvalidAttrNumber && |
3394 | 0 | ((Var *) arg)->varlevelsup == 0) |
3395 | 0 | { |
3396 | 0 | if (rowtype_field_matches(((Var *) arg)->vartype, |
3397 | 0 | fselect->fieldnum, |
3398 | 0 | fselect->resulttype, |
3399 | 0 | fselect->resulttypmod, |
3400 | 0 | fselect->resultcollid)) |
3401 | 0 | { |
3402 | 0 | Var *newvar; |
3403 | |
|
3404 | 0 | newvar = makeVar(((Var *) arg)->varno, |
3405 | 0 | fselect->fieldnum, |
3406 | 0 | fselect->resulttype, |
3407 | 0 | fselect->resulttypmod, |
3408 | 0 | fselect->resultcollid, |
3409 | 0 | ((Var *) arg)->varlevelsup); |
3410 | | /* New Var has same OLD/NEW returning as old one */ |
3411 | 0 | newvar->varreturningtype = ((Var *) arg)->varreturningtype; |
3412 | | /* New Var is nullable by same rels as the old one */ |
3413 | 0 | newvar->varnullingrels = ((Var *) arg)->varnullingrels; |
3414 | 0 | return (Node *) newvar; |
3415 | 0 | } |
3416 | 0 | } |
3417 | 0 | if (arg && IsA(arg, RowExpr)) |
3418 | 0 | { |
3419 | 0 | RowExpr *rowexpr = (RowExpr *) arg; |
3420 | |
|
3421 | 0 | if (fselect->fieldnum > 0 && |
3422 | 0 | fselect->fieldnum <= list_length(rowexpr->args)) |
3423 | 0 | { |
3424 | 0 | Node *fld = (Node *) list_nth(rowexpr->args, |
3425 | 0 | fselect->fieldnum - 1); |
3426 | |
|
3427 | 0 | if (rowtype_field_matches(rowexpr->row_typeid, |
3428 | 0 | fselect->fieldnum, |
3429 | 0 | fselect->resulttype, |
3430 | 0 | fselect->resulttypmod, |
3431 | 0 | fselect->resultcollid) && |
3432 | 0 | fselect->resulttype == exprType(fld) && |
3433 | 0 | fselect->resulttypmod == exprTypmod(fld) && |
3434 | 0 | fselect->resultcollid == exprCollation(fld)) |
3435 | 0 | return fld; |
3436 | 0 | } |
3437 | 0 | } |
3438 | 0 | newfselect = makeNode(FieldSelect); |
3439 | 0 | newfselect->arg = (Expr *) arg; |
3440 | 0 | newfselect->fieldnum = fselect->fieldnum; |
3441 | 0 | newfselect->resulttype = fselect->resulttype; |
3442 | 0 | newfselect->resulttypmod = fselect->resulttypmod; |
3443 | 0 | newfselect->resultcollid = fselect->resultcollid; |
3444 | 0 | if (arg && IsA(arg, Const)) |
3445 | 0 | { |
3446 | 0 | Const *con = (Const *) arg; |
3447 | |
|
3448 | 0 | if (rowtype_field_matches(con->consttype, |
3449 | 0 | newfselect->fieldnum, |
3450 | 0 | newfselect->resulttype, |
3451 | 0 | newfselect->resulttypmod, |
3452 | 0 | newfselect->resultcollid)) |
3453 | 0 | return ece_evaluate_expr(newfselect); |
3454 | 0 | } |
3455 | 0 | return (Node *) newfselect; |
3456 | 0 | } |
3457 | 0 | case T_NullTest: |
3458 | 0 | { |
3459 | 0 | NullTest *ntest = (NullTest *) node; |
3460 | 0 | NullTest *newntest; |
3461 | 0 | Node *arg; |
3462 | |
|
3463 | 0 | arg = eval_const_expressions_mutator((Node *) ntest->arg, |
3464 | 0 | context); |
3465 | 0 | if (ntest->argisrow && arg && IsA(arg, RowExpr)) |
3466 | 0 | { |
3467 | | /* |
3468 | | * We break ROW(...) IS [NOT] NULL into separate tests on |
3469 | | * its component fields. This form is usually more |
3470 | | * efficient to evaluate, as well as being more amenable |
3471 | | * to optimization. |
3472 | | */ |
3473 | 0 | RowExpr *rarg = (RowExpr *) arg; |
3474 | 0 | List *newargs = NIL; |
3475 | 0 | ListCell *l; |
3476 | |
|
3477 | 0 | foreach(l, rarg->args) |
3478 | 0 | { |
3479 | 0 | Node *relem = (Node *) lfirst(l); |
3480 | | |
3481 | | /* |
3482 | | * A constant field refutes the whole NullTest if it's |
3483 | | * of the wrong nullness; else we can discard it. |
3484 | | */ |
3485 | 0 | if (relem && IsA(relem, Const)) |
3486 | 0 | { |
3487 | 0 | Const *carg = (Const *) relem; |
3488 | |
|
3489 | 0 | if (carg->constisnull ? |
3490 | 0 | (ntest->nulltesttype == IS_NOT_NULL) : |
3491 | 0 | (ntest->nulltesttype == IS_NULL)) |
3492 | 0 | return makeBoolConst(false, false); |
3493 | 0 | continue; |
3494 | 0 | } |
3495 | | |
3496 | | /* |
3497 | | * Else, make a scalar (argisrow == false) NullTest |
3498 | | * for this field. Scalar semantics are required |
3499 | | * because IS [NOT] NULL doesn't recurse; see comments |
3500 | | * in ExecEvalRowNullInt(). |
3501 | | */ |
3502 | 0 | newntest = makeNode(NullTest); |
3503 | 0 | newntest->arg = (Expr *) relem; |
3504 | 0 | newntest->nulltesttype = ntest->nulltesttype; |
3505 | 0 | newntest->argisrow = false; |
3506 | 0 | newntest->location = ntest->location; |
3507 | 0 | newargs = lappend(newargs, newntest); |
3508 | 0 | } |
3509 | | /* If all the inputs were constants, result is TRUE */ |
3510 | 0 | if (newargs == NIL) |
3511 | 0 | return makeBoolConst(true, false); |
3512 | | /* If only one nonconst input, it's the result */ |
3513 | 0 | if (list_length(newargs) == 1) |
3514 | 0 | return (Node *) linitial(newargs); |
3515 | | /* Else we need an AND node */ |
3516 | 0 | return (Node *) make_andclause(newargs); |
3517 | 0 | } |
3518 | 0 | if (!ntest->argisrow && arg && IsA(arg, Const)) |
3519 | 0 | { |
3520 | 0 | Const *carg = (Const *) arg; |
3521 | 0 | bool result; |
3522 | |
|
3523 | 0 | switch (ntest->nulltesttype) |
3524 | 0 | { |
3525 | 0 | case IS_NULL: |
3526 | 0 | result = carg->constisnull; |
3527 | 0 | break; |
3528 | 0 | case IS_NOT_NULL: |
3529 | 0 | result = !carg->constisnull; |
3530 | 0 | break; |
3531 | 0 | default: |
3532 | 0 | elog(ERROR, "unrecognized nulltesttype: %d", |
3533 | 0 | (int) ntest->nulltesttype); |
3534 | 0 | result = false; /* keep compiler quiet */ |
3535 | 0 | break; |
3536 | 0 | } |
3537 | | |
3538 | 0 | return makeBoolConst(result, false); |
3539 | 0 | } |
3540 | | |
3541 | 0 | newntest = makeNode(NullTest); |
3542 | 0 | newntest->arg = (Expr *) arg; |
3543 | 0 | newntest->nulltesttype = ntest->nulltesttype; |
3544 | 0 | newntest->argisrow = ntest->argisrow; |
3545 | 0 | newntest->location = ntest->location; |
3546 | 0 | return (Node *) newntest; |
3547 | 0 | } |
3548 | 0 | case T_BooleanTest: |
3549 | 0 | { |
3550 | | /* |
3551 | | * This case could be folded into the generic handling used |
3552 | | * for ArrayExpr etc. But because the simplification logic is |
3553 | | * so trivial, applying evaluate_expr() to perform it would be |
3554 | | * a heavy overhead. BooleanTest is probably common enough to |
3555 | | * justify keeping this bespoke implementation. |
3556 | | */ |
3557 | 0 | BooleanTest *btest = (BooleanTest *) node; |
3558 | 0 | BooleanTest *newbtest; |
3559 | 0 | Node *arg; |
3560 | |
|
3561 | 0 | arg = eval_const_expressions_mutator((Node *) btest->arg, |
3562 | 0 | context); |
3563 | 0 | if (arg && IsA(arg, Const)) |
3564 | 0 | { |
3565 | 0 | Const *carg = (Const *) arg; |
3566 | 0 | bool result; |
3567 | |
|
3568 | 0 | switch (btest->booltesttype) |
3569 | 0 | { |
3570 | 0 | case IS_TRUE: |
3571 | 0 | result = (!carg->constisnull && |
3572 | 0 | DatumGetBool(carg->constvalue)); |
3573 | 0 | break; |
3574 | 0 | case IS_NOT_TRUE: |
3575 | 0 | result = (carg->constisnull || |
3576 | 0 | !DatumGetBool(carg->constvalue)); |
3577 | 0 | break; |
3578 | 0 | case IS_FALSE: |
3579 | 0 | result = (!carg->constisnull && |
3580 | 0 | !DatumGetBool(carg->constvalue)); |
3581 | 0 | break; |
3582 | 0 | case IS_NOT_FALSE: |
3583 | 0 | result = (carg->constisnull || |
3584 | 0 | DatumGetBool(carg->constvalue)); |
3585 | 0 | break; |
3586 | 0 | case IS_UNKNOWN: |
3587 | 0 | result = carg->constisnull; |
3588 | 0 | break; |
3589 | 0 | case IS_NOT_UNKNOWN: |
3590 | 0 | result = !carg->constisnull; |
3591 | 0 | break; |
3592 | 0 | default: |
3593 | 0 | elog(ERROR, "unrecognized booltesttype: %d", |
3594 | 0 | (int) btest->booltesttype); |
3595 | 0 | result = false; /* keep compiler quiet */ |
3596 | 0 | break; |
3597 | 0 | } |
3598 | | |
3599 | 0 | return makeBoolConst(result, false); |
3600 | 0 | } |
3601 | | |
3602 | 0 | newbtest = makeNode(BooleanTest); |
3603 | 0 | newbtest->arg = (Expr *) arg; |
3604 | 0 | newbtest->booltesttype = btest->booltesttype; |
3605 | 0 | newbtest->location = btest->location; |
3606 | 0 | return (Node *) newbtest; |
3607 | 0 | } |
3608 | 0 | case T_CoerceToDomain: |
3609 | 0 | { |
3610 | | /* |
3611 | | * If the domain currently has no constraints, we replace the |
3612 | | * CoerceToDomain node with a simple RelabelType, which is |
3613 | | * both far faster to execute and more amenable to later |
3614 | | * optimization. We must then mark the plan as needing to be |
3615 | | * rebuilt if the domain's constraints change. |
3616 | | * |
3617 | | * Also, in estimation mode, always replace CoerceToDomain |
3618 | | * nodes, effectively assuming that the coercion will succeed. |
3619 | | */ |
3620 | 0 | CoerceToDomain *cdomain = (CoerceToDomain *) node; |
3621 | 0 | CoerceToDomain *newcdomain; |
3622 | 0 | Node *arg; |
3623 | |
|
3624 | 0 | arg = eval_const_expressions_mutator((Node *) cdomain->arg, |
3625 | 0 | context); |
3626 | 0 | if (context->estimate || |
3627 | 0 | !DomainHasConstraints(cdomain->resulttype)) |
3628 | 0 | { |
3629 | | /* Record dependency, if this isn't estimation mode */ |
3630 | 0 | if (context->root && !context->estimate) |
3631 | 0 | record_plan_type_dependency(context->root, |
3632 | 0 | cdomain->resulttype); |
3633 | | |
3634 | | /* Generate RelabelType to substitute for CoerceToDomain */ |
3635 | 0 | return applyRelabelType(arg, |
3636 | 0 | cdomain->resulttype, |
3637 | 0 | cdomain->resulttypmod, |
3638 | 0 | cdomain->resultcollid, |
3639 | 0 | cdomain->coercionformat, |
3640 | 0 | cdomain->location, |
3641 | 0 | true); |
3642 | 0 | } |
3643 | | |
3644 | 0 | newcdomain = makeNode(CoerceToDomain); |
3645 | 0 | newcdomain->arg = (Expr *) arg; |
3646 | 0 | newcdomain->resulttype = cdomain->resulttype; |
3647 | 0 | newcdomain->resulttypmod = cdomain->resulttypmod; |
3648 | 0 | newcdomain->resultcollid = cdomain->resultcollid; |
3649 | 0 | newcdomain->coercionformat = cdomain->coercionformat; |
3650 | 0 | newcdomain->location = cdomain->location; |
3651 | 0 | return (Node *) newcdomain; |
3652 | 0 | } |
3653 | 0 | case T_PlaceHolderVar: |
3654 | | |
3655 | | /* |
3656 | | * In estimation mode, just strip the PlaceHolderVar node |
3657 | | * altogether; this amounts to estimating that the contained value |
3658 | | * won't be forced to null by an outer join. In regular mode we |
3659 | | * just use the default behavior (ie, simplify the expression but |
3660 | | * leave the PlaceHolderVar node intact). |
3661 | | */ |
3662 | 0 | if (context->estimate) |
3663 | 0 | { |
3664 | 0 | PlaceHolderVar *phv = (PlaceHolderVar *) node; |
3665 | |
|
3666 | 0 | return eval_const_expressions_mutator((Node *) phv->phexpr, |
3667 | 0 | context); |
3668 | 0 | } |
3669 | 0 | break; |
3670 | 0 | case T_ConvertRowtypeExpr: |
3671 | 0 | { |
3672 | 0 | ConvertRowtypeExpr *cre = castNode(ConvertRowtypeExpr, node); |
3673 | 0 | Node *arg; |
3674 | 0 | ConvertRowtypeExpr *newcre; |
3675 | |
|
3676 | 0 | arg = eval_const_expressions_mutator((Node *) cre->arg, |
3677 | 0 | context); |
3678 | |
|
3679 | 0 | newcre = makeNode(ConvertRowtypeExpr); |
3680 | 0 | newcre->resulttype = cre->resulttype; |
3681 | 0 | newcre->convertformat = cre->convertformat; |
3682 | 0 | newcre->location = cre->location; |
3683 | | |
3684 | | /* |
3685 | | * In case of a nested ConvertRowtypeExpr, we can convert the |
3686 | | * leaf row directly to the topmost row format without any |
3687 | | * intermediate conversions. (This works because |
3688 | | * ConvertRowtypeExpr is used only for child->parent |
3689 | | * conversion in inheritance trees, which works by exact match |
3690 | | * of column name, and a column absent in an intermediate |
3691 | | * result can't be present in the final result.) |
3692 | | * |
3693 | | * No need to check more than one level deep, because the |
3694 | | * above recursion will have flattened anything else. |
3695 | | */ |
3696 | 0 | if (arg != NULL && IsA(arg, ConvertRowtypeExpr)) |
3697 | 0 | { |
3698 | 0 | ConvertRowtypeExpr *argcre = (ConvertRowtypeExpr *) arg; |
3699 | |
|
3700 | 0 | arg = (Node *) argcre->arg; |
3701 | | |
3702 | | /* |
3703 | | * Make sure an outer implicit conversion can't hide an |
3704 | | * inner explicit one. |
3705 | | */ |
3706 | 0 | if (newcre->convertformat == COERCE_IMPLICIT_CAST) |
3707 | 0 | newcre->convertformat = argcre->convertformat; |
3708 | 0 | } |
3709 | |
|
3710 | 0 | newcre->arg = (Expr *) arg; |
3711 | |
|
3712 | 0 | if (arg != NULL && IsA(arg, Const)) |
3713 | 0 | return ece_evaluate_expr((Node *) newcre); |
3714 | 0 | return (Node *) newcre; |
3715 | 0 | } |
3716 | 0 | default: |
3717 | 0 | break; |
3718 | 0 | } |
3719 | | |
3720 | | /* |
3721 | | * For any node type not handled above, copy the node unchanged but |
3722 | | * const-simplify its subexpressions. This is the correct thing for node |
3723 | | * types whose behavior might change between planning and execution, such |
3724 | | * as CurrentOfExpr. It's also a safe default for new node types not |
3725 | | * known to this routine. |
3726 | | */ |
3727 | 0 | return ece_generic_processing(node); |
3728 | 0 | } |
3729 | | |
3730 | | /* |
3731 | | * Subroutine for eval_const_expressions: check for non-Const nodes. |
3732 | | * |
3733 | | * We can abort recursion immediately on finding a non-Const node. This is |
3734 | | * critical for performance, else eval_const_expressions_mutator would take |
3735 | | * O(N^2) time on non-simplifiable trees. However, we do need to descend |
3736 | | * into List nodes since expression_tree_walker sometimes invokes the walker |
3737 | | * function directly on List subtrees. |
3738 | | */ |
3739 | | static bool |
3740 | | contain_non_const_walker(Node *node, void *context) |
3741 | 0 | { |
3742 | 0 | if (node == NULL) |
3743 | 0 | return false; |
3744 | 0 | if (IsA(node, Const)) |
3745 | 0 | return false; |
3746 | 0 | if (IsA(node, List)) |
3747 | 0 | return expression_tree_walker(node, contain_non_const_walker, context); |
3748 | | /* Otherwise, abort the tree traversal and return true */ |
3749 | 0 | return true; |
3750 | 0 | } |
3751 | | |
3752 | | /* |
3753 | | * Subroutine for eval_const_expressions: check if a function is OK to evaluate |
3754 | | */ |
3755 | | static bool |
3756 | | ece_function_is_safe(Oid funcid, eval_const_expressions_context *context) |
3757 | 0 | { |
3758 | 0 | char provolatile = func_volatile(funcid); |
3759 | | |
3760 | | /* |
3761 | | * Ordinarily we are only allowed to simplify immutable functions. But for |
3762 | | * purposes of estimation, we consider it okay to simplify functions that |
3763 | | * are merely stable; the risk that the result might change from planning |
3764 | | * time to execution time is worth taking in preference to not being able |
3765 | | * to estimate the value at all. |
3766 | | */ |
3767 | 0 | if (provolatile == PROVOLATILE_IMMUTABLE) |
3768 | 0 | return true; |
3769 | 0 | if (context->estimate && provolatile == PROVOLATILE_STABLE) |
3770 | 0 | return true; |
3771 | 0 | return false; |
3772 | 0 | } |
3773 | | |
3774 | | /* |
3775 | | * Subroutine for eval_const_expressions: process arguments of an OR clause |
3776 | | * |
3777 | | * This includes flattening of nested ORs as well as recursion to |
3778 | | * eval_const_expressions to simplify the OR arguments. |
3779 | | * |
3780 | | * After simplification, OR arguments are handled as follows: |
3781 | | * non constant: keep |
3782 | | * FALSE: drop (does not affect result) |
3783 | | * TRUE: force result to TRUE |
3784 | | * NULL: keep only one |
3785 | | * We must keep one NULL input because OR expressions evaluate to NULL when no |
3786 | | * input is TRUE and at least one is NULL. We don't actually include the NULL |
3787 | | * here, that's supposed to be done by the caller. |
3788 | | * |
3789 | | * The output arguments *haveNull and *forceTrue must be initialized false |
3790 | | * by the caller. They will be set true if a NULL constant or TRUE constant, |
3791 | | * respectively, is detected anywhere in the argument list. |
3792 | | */ |
3793 | | static List * |
3794 | | simplify_or_arguments(List *args, |
3795 | | eval_const_expressions_context *context, |
3796 | | bool *haveNull, bool *forceTrue) |
3797 | 0 | { |
3798 | 0 | List *newargs = NIL; |
3799 | 0 | List *unprocessed_args; |
3800 | | |
3801 | | /* |
3802 | | * We want to ensure that any OR immediately beneath another OR gets |
3803 | | * flattened into a single OR-list, so as to simplify later reasoning. |
3804 | | * |
3805 | | * To avoid stack overflow from recursion of eval_const_expressions, we |
3806 | | * resort to some tenseness here: we keep a list of not-yet-processed |
3807 | | * inputs, and handle flattening of nested ORs by prepending to the to-do |
3808 | | * list instead of recursing. Now that the parser generates N-argument |
3809 | | * ORs from simple lists, this complexity is probably less necessary than |
3810 | | * it once was, but we might as well keep the logic. |
3811 | | */ |
3812 | 0 | unprocessed_args = list_copy(args); |
3813 | 0 | while (unprocessed_args) |
3814 | 0 | { |
3815 | 0 | Node *arg = (Node *) linitial(unprocessed_args); |
3816 | |
|
3817 | 0 | unprocessed_args = list_delete_first(unprocessed_args); |
3818 | | |
3819 | | /* flatten nested ORs as per above comment */ |
3820 | 0 | if (is_orclause(arg)) |
3821 | 0 | { |
3822 | 0 | List *subargs = ((BoolExpr *) arg)->args; |
3823 | 0 | List *oldlist = unprocessed_args; |
3824 | |
|
3825 | 0 | unprocessed_args = list_concat_copy(subargs, unprocessed_args); |
3826 | | /* perhaps-overly-tense code to avoid leaking old lists */ |
3827 | 0 | list_free(oldlist); |
3828 | 0 | continue; |
3829 | 0 | } |
3830 | | |
3831 | | /* If it's not an OR, simplify it */ |
3832 | 0 | arg = eval_const_expressions_mutator(arg, context); |
3833 | | |
3834 | | /* |
3835 | | * It is unlikely but not impossible for simplification of a non-OR |
3836 | | * clause to produce an OR. Recheck, but don't be too tense about it |
3837 | | * since it's not a mainstream case. In particular we don't worry |
3838 | | * about const-simplifying the input twice, nor about list leakage. |
3839 | | */ |
3840 | 0 | if (is_orclause(arg)) |
3841 | 0 | { |
3842 | 0 | List *subargs = ((BoolExpr *) arg)->args; |
3843 | |
|
3844 | 0 | unprocessed_args = list_concat_copy(subargs, unprocessed_args); |
3845 | 0 | continue; |
3846 | 0 | } |
3847 | | |
3848 | | /* |
3849 | | * OK, we have a const-simplified non-OR argument. Process it per |
3850 | | * comments above. |
3851 | | */ |
3852 | 0 | if (IsA(arg, Const)) |
3853 | 0 | { |
3854 | 0 | Const *const_input = (Const *) arg; |
3855 | |
|
3856 | 0 | if (const_input->constisnull) |
3857 | 0 | *haveNull = true; |
3858 | 0 | else if (DatumGetBool(const_input->constvalue)) |
3859 | 0 | { |
3860 | 0 | *forceTrue = true; |
3861 | | |
3862 | | /* |
3863 | | * Once we detect a TRUE result we can just exit the loop |
3864 | | * immediately. However, if we ever add a notion of |
3865 | | * non-removable functions, we'd need to keep scanning. |
3866 | | */ |
3867 | 0 | return NIL; |
3868 | 0 | } |
3869 | | /* otherwise, we can drop the constant-false input */ |
3870 | 0 | continue; |
3871 | 0 | } |
3872 | | |
3873 | | /* else emit the simplified arg into the result list */ |
3874 | 0 | newargs = lappend(newargs, arg); |
3875 | 0 | } |
3876 | | |
3877 | 0 | return newargs; |
3878 | 0 | } |
3879 | | |
3880 | | /* |
3881 | | * Subroutine for eval_const_expressions: process arguments of an AND clause |
3882 | | * |
3883 | | * This includes flattening of nested ANDs as well as recursion to |
3884 | | * eval_const_expressions to simplify the AND arguments. |
3885 | | * |
3886 | | * After simplification, AND arguments are handled as follows: |
3887 | | * non constant: keep |
3888 | | * TRUE: drop (does not affect result) |
3889 | | * FALSE: force result to FALSE |
3890 | | * NULL: keep only one |
3891 | | * We must keep one NULL input because AND expressions evaluate to NULL when |
3892 | | * no input is FALSE and at least one is NULL. We don't actually include the |
3893 | | * NULL here, that's supposed to be done by the caller. |
3894 | | * |
3895 | | * The output arguments *haveNull and *forceFalse must be initialized false |
3896 | | * by the caller. They will be set true if a null constant or false constant, |
3897 | | * respectively, is detected anywhere in the argument list. |
3898 | | */ |
3899 | | static List * |
3900 | | simplify_and_arguments(List *args, |
3901 | | eval_const_expressions_context *context, |
3902 | | bool *haveNull, bool *forceFalse) |
3903 | 0 | { |
3904 | 0 | List *newargs = NIL; |
3905 | 0 | List *unprocessed_args; |
3906 | | |
3907 | | /* See comments in simplify_or_arguments */ |
3908 | 0 | unprocessed_args = list_copy(args); |
3909 | 0 | while (unprocessed_args) |
3910 | 0 | { |
3911 | 0 | Node *arg = (Node *) linitial(unprocessed_args); |
3912 | |
|
3913 | 0 | unprocessed_args = list_delete_first(unprocessed_args); |
3914 | | |
3915 | | /* flatten nested ANDs as per above comment */ |
3916 | 0 | if (is_andclause(arg)) |
3917 | 0 | { |
3918 | 0 | List *subargs = ((BoolExpr *) arg)->args; |
3919 | 0 | List *oldlist = unprocessed_args; |
3920 | |
|
3921 | 0 | unprocessed_args = list_concat_copy(subargs, unprocessed_args); |
3922 | | /* perhaps-overly-tense code to avoid leaking old lists */ |
3923 | 0 | list_free(oldlist); |
3924 | 0 | continue; |
3925 | 0 | } |
3926 | | |
3927 | | /* If it's not an AND, simplify it */ |
3928 | 0 | arg = eval_const_expressions_mutator(arg, context); |
3929 | | |
3930 | | /* |
3931 | | * It is unlikely but not impossible for simplification of a non-AND |
3932 | | * clause to produce an AND. Recheck, but don't be too tense about it |
3933 | | * since it's not a mainstream case. In particular we don't worry |
3934 | | * about const-simplifying the input twice, nor about list leakage. |
3935 | | */ |
3936 | 0 | if (is_andclause(arg)) |
3937 | 0 | { |
3938 | 0 | List *subargs = ((BoolExpr *) arg)->args; |
3939 | |
|
3940 | 0 | unprocessed_args = list_concat_copy(subargs, unprocessed_args); |
3941 | 0 | continue; |
3942 | 0 | } |
3943 | | |
3944 | | /* |
3945 | | * OK, we have a const-simplified non-AND argument. Process it per |
3946 | | * comments above. |
3947 | | */ |
3948 | 0 | if (IsA(arg, Const)) |
3949 | 0 | { |
3950 | 0 | Const *const_input = (Const *) arg; |
3951 | |
|
3952 | 0 | if (const_input->constisnull) |
3953 | 0 | *haveNull = true; |
3954 | 0 | else if (!DatumGetBool(const_input->constvalue)) |
3955 | 0 | { |
3956 | 0 | *forceFalse = true; |
3957 | | |
3958 | | /* |
3959 | | * Once we detect a FALSE result we can just exit the loop |
3960 | | * immediately. However, if we ever add a notion of |
3961 | | * non-removable functions, we'd need to keep scanning. |
3962 | | */ |
3963 | 0 | return NIL; |
3964 | 0 | } |
3965 | | /* otherwise, we can drop the constant-true input */ |
3966 | 0 | continue; |
3967 | 0 | } |
3968 | | |
3969 | | /* else emit the simplified arg into the result list */ |
3970 | 0 | newargs = lappend(newargs, arg); |
3971 | 0 | } |
3972 | | |
3973 | 0 | return newargs; |
3974 | 0 | } |
3975 | | |
3976 | | /* |
3977 | | * Subroutine for eval_const_expressions: try to simplify boolean equality |
3978 | | * or inequality condition |
3979 | | * |
3980 | | * Inputs are the operator OID and the simplified arguments to the operator. |
3981 | | * Returns a simplified expression if successful, or NULL if cannot |
3982 | | * simplify the expression. |
3983 | | * |
3984 | | * The idea here is to reduce "x = true" to "x" and "x = false" to "NOT x", |
3985 | | * or similarly "x <> true" to "NOT x" and "x <> false" to "x". |
3986 | | * This is only marginally useful in itself, but doing it in constant folding |
3987 | | * ensures that we will recognize these forms as being equivalent in, for |
3988 | | * example, partial index matching. |
3989 | | * |
3990 | | * We come here only if simplify_function has failed; therefore we cannot |
3991 | | * see two constant inputs, nor a constant-NULL input. |
3992 | | */ |
3993 | | static Node * |
3994 | | simplify_boolean_equality(Oid opno, List *args) |
3995 | 0 | { |
3996 | 0 | Node *leftop; |
3997 | 0 | Node *rightop; |
3998 | |
|
3999 | 0 | Assert(list_length(args) == 2); |
4000 | 0 | leftop = linitial(args); |
4001 | 0 | rightop = lsecond(args); |
4002 | 0 | if (leftop && IsA(leftop, Const)) |
4003 | 0 | { |
4004 | 0 | Assert(!((Const *) leftop)->constisnull); |
4005 | 0 | if (opno == BooleanEqualOperator) |
4006 | 0 | { |
4007 | 0 | if (DatumGetBool(((Const *) leftop)->constvalue)) |
4008 | 0 | return rightop; /* true = foo */ |
4009 | 0 | else |
4010 | 0 | return negate_clause(rightop); /* false = foo */ |
4011 | 0 | } |
4012 | 0 | else |
4013 | 0 | { |
4014 | 0 | if (DatumGetBool(((Const *) leftop)->constvalue)) |
4015 | 0 | return negate_clause(rightop); /* true <> foo */ |
4016 | 0 | else |
4017 | 0 | return rightop; /* false <> foo */ |
4018 | 0 | } |
4019 | 0 | } |
4020 | 0 | if (rightop && IsA(rightop, Const)) |
4021 | 0 | { |
4022 | 0 | Assert(!((Const *) rightop)->constisnull); |
4023 | 0 | if (opno == BooleanEqualOperator) |
4024 | 0 | { |
4025 | 0 | if (DatumGetBool(((Const *) rightop)->constvalue)) |
4026 | 0 | return leftop; /* foo = true */ |
4027 | 0 | else |
4028 | 0 | return negate_clause(leftop); /* foo = false */ |
4029 | 0 | } |
4030 | 0 | else |
4031 | 0 | { |
4032 | 0 | if (DatumGetBool(((Const *) rightop)->constvalue)) |
4033 | 0 | return negate_clause(leftop); /* foo <> true */ |
4034 | 0 | else |
4035 | 0 | return leftop; /* foo <> false */ |
4036 | 0 | } |
4037 | 0 | } |
4038 | 0 | return NULL; |
4039 | 0 | } |
4040 | | |
4041 | | /* |
4042 | | * Subroutine for eval_const_expressions: try to simplify a function call |
4043 | | * (which might originally have been an operator; we don't care) |
4044 | | * |
4045 | | * Inputs are the function OID, actual result type OID (which is needed for |
4046 | | * polymorphic functions), result typmod, result collation, the input |
4047 | | * collation to use for the function, the original argument list (not |
4048 | | * const-simplified yet, unless process_args is false), and some flags; |
4049 | | * also the context data for eval_const_expressions. |
4050 | | * |
4051 | | * Returns a simplified expression if successful, or NULL if cannot |
4052 | | * simplify the function call. |
4053 | | * |
4054 | | * This function is also responsible for converting named-notation argument |
4055 | | * lists into positional notation and/or adding any needed default argument |
4056 | | * expressions; which is a bit grotty, but it avoids extra fetches of the |
4057 | | * function's pg_proc tuple. For this reason, the args list is |
4058 | | * pass-by-reference. Conversion and const-simplification of the args list |
4059 | | * will be done even if simplification of the function call itself is not |
4060 | | * possible. |
4061 | | */ |
4062 | | static Expr * |
4063 | | simplify_function(Oid funcid, Oid result_type, int32 result_typmod, |
4064 | | Oid result_collid, Oid input_collid, List **args_p, |
4065 | | bool funcvariadic, bool process_args, bool allow_non_const, |
4066 | | eval_const_expressions_context *context) |
4067 | 0 | { |
4068 | 0 | List *args = *args_p; |
4069 | 0 | HeapTuple func_tuple; |
4070 | 0 | Form_pg_proc func_form; |
4071 | 0 | Expr *newexpr; |
4072 | | |
4073 | | /* |
4074 | | * We have three strategies for simplification: execute the function to |
4075 | | * deliver a constant result, use a transform function to generate a |
4076 | | * substitute node tree, or expand in-line the body of the function |
4077 | | * definition (which only works for simple SQL-language functions, but |
4078 | | * that is a common case). Each case needs access to the function's |
4079 | | * pg_proc tuple, so fetch it just once. |
4080 | | * |
4081 | | * Note: the allow_non_const flag suppresses both the second and third |
4082 | | * strategies; so if !allow_non_const, simplify_function can only return a |
4083 | | * Const or NULL. Argument-list rewriting happens anyway, though. |
4084 | | */ |
4085 | 0 | func_tuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid)); |
4086 | 0 | if (!HeapTupleIsValid(func_tuple)) |
4087 | 0 | elog(ERROR, "cache lookup failed for function %u", funcid); |
4088 | 0 | func_form = (Form_pg_proc) GETSTRUCT(func_tuple); |
4089 | | |
4090 | | /* |
4091 | | * Process the function arguments, unless the caller did it already. |
4092 | | * |
4093 | | * Here we must deal with named or defaulted arguments, and then |
4094 | | * recursively apply eval_const_expressions to the whole argument list. |
4095 | | */ |
4096 | 0 | if (process_args) |
4097 | 0 | { |
4098 | 0 | args = expand_function_arguments(args, false, result_type, func_tuple); |
4099 | 0 | args = (List *) expression_tree_mutator((Node *) args, |
4100 | 0 | eval_const_expressions_mutator, |
4101 | 0 | context); |
4102 | | /* Argument processing done, give it back to the caller */ |
4103 | 0 | *args_p = args; |
4104 | 0 | } |
4105 | | |
4106 | | /* Now attempt simplification of the function call proper. */ |
4107 | |
|
4108 | 0 | newexpr = evaluate_function(funcid, result_type, result_typmod, |
4109 | 0 | result_collid, input_collid, |
4110 | 0 | args, funcvariadic, |
4111 | 0 | func_tuple, context); |
4112 | |
|
4113 | 0 | if (!newexpr && allow_non_const && OidIsValid(func_form->prosupport)) |
4114 | 0 | { |
4115 | | /* |
4116 | | * Build a SupportRequestSimplify node to pass to the support |
4117 | | * function, pointing to a dummy FuncExpr node containing the |
4118 | | * simplified arg list. We use this approach to present a uniform |
4119 | | * interface to the support function regardless of how the target |
4120 | | * function is actually being invoked. |
4121 | | */ |
4122 | 0 | SupportRequestSimplify req; |
4123 | 0 | FuncExpr fexpr; |
4124 | |
|
4125 | 0 | fexpr.xpr.type = T_FuncExpr; |
4126 | 0 | fexpr.funcid = funcid; |
4127 | 0 | fexpr.funcresulttype = result_type; |
4128 | 0 | fexpr.funcretset = func_form->proretset; |
4129 | 0 | fexpr.funcvariadic = funcvariadic; |
4130 | 0 | fexpr.funcformat = COERCE_EXPLICIT_CALL; |
4131 | 0 | fexpr.funccollid = result_collid; |
4132 | 0 | fexpr.inputcollid = input_collid; |
4133 | 0 | fexpr.args = args; |
4134 | 0 | fexpr.location = -1; |
4135 | |
|
4136 | 0 | req.type = T_SupportRequestSimplify; |
4137 | 0 | req.root = context->root; |
4138 | 0 | req.fcall = &fexpr; |
4139 | |
|
4140 | 0 | newexpr = (Expr *) |
4141 | 0 | DatumGetPointer(OidFunctionCall1(func_form->prosupport, |
4142 | 0 | PointerGetDatum(&req))); |
4143 | | |
4144 | | /* catch a possible API misunderstanding */ |
4145 | 0 | Assert(newexpr != (Expr *) &fexpr); |
4146 | 0 | } |
4147 | |
|
4148 | 0 | if (!newexpr && allow_non_const) |
4149 | 0 | newexpr = inline_function(funcid, result_type, result_collid, |
4150 | 0 | input_collid, args, funcvariadic, |
4151 | 0 | func_tuple, context); |
4152 | |
|
4153 | 0 | ReleaseSysCache(func_tuple); |
4154 | |
|
4155 | 0 | return newexpr; |
4156 | 0 | } |
4157 | | |
4158 | | /* |
4159 | | * expand_function_arguments: convert named-notation args to positional args |
4160 | | * and/or insert default args, as needed |
4161 | | * |
4162 | | * Returns a possibly-transformed version of the args list. |
4163 | | * |
4164 | | * If include_out_arguments is true, then the args list and the result |
4165 | | * include OUT arguments. |
4166 | | * |
4167 | | * The expected result type of the call must be given, for sanity-checking |
4168 | | * purposes. Also, we ask the caller to provide the function's actual |
4169 | | * pg_proc tuple, not just its OID. |
4170 | | * |
4171 | | * If we need to change anything, the input argument list is copied, not |
4172 | | * modified. |
4173 | | * |
4174 | | * Note: this gets applied to operator argument lists too, even though the |
4175 | | * cases it handles should never occur there. This should be OK since it |
4176 | | * will fall through very quickly if there's nothing to do. |
4177 | | */ |
4178 | | List * |
4179 | | expand_function_arguments(List *args, bool include_out_arguments, |
4180 | | Oid result_type, HeapTuple func_tuple) |
4181 | 0 | { |
4182 | 0 | Form_pg_proc funcform = (Form_pg_proc) GETSTRUCT(func_tuple); |
4183 | 0 | Oid *proargtypes = funcform->proargtypes.values; |
4184 | 0 | int pronargs = funcform->pronargs; |
4185 | 0 | bool has_named_args = false; |
4186 | 0 | ListCell *lc; |
4187 | | |
4188 | | /* |
4189 | | * If we are asked to match to OUT arguments, then use the proallargtypes |
4190 | | * array (which includes those); otherwise use proargtypes (which |
4191 | | * doesn't). Of course, if proallargtypes is null, we always use |
4192 | | * proargtypes. (Fetching proallargtypes is annoyingly expensive |
4193 | | * considering that we may have nothing to do here, but fortunately the |
4194 | | * common case is include_out_arguments == false.) |
4195 | | */ |
4196 | 0 | if (include_out_arguments) |
4197 | 0 | { |
4198 | 0 | Datum proallargtypes; |
4199 | 0 | bool isNull; |
4200 | |
|
4201 | 0 | proallargtypes = SysCacheGetAttr(PROCOID, func_tuple, |
4202 | 0 | Anum_pg_proc_proallargtypes, |
4203 | 0 | &isNull); |
4204 | 0 | if (!isNull) |
4205 | 0 | { |
4206 | 0 | ArrayType *arr = DatumGetArrayTypeP(proallargtypes); |
4207 | |
|
4208 | 0 | pronargs = ARR_DIMS(arr)[0]; |
4209 | 0 | if (ARR_NDIM(arr) != 1 || |
4210 | 0 | pronargs < 0 || |
4211 | 0 | ARR_HASNULL(arr) || |
4212 | 0 | ARR_ELEMTYPE(arr) != OIDOID) |
4213 | 0 | elog(ERROR, "proallargtypes is not a 1-D Oid array or it contains nulls"); |
4214 | 0 | Assert(pronargs >= funcform->pronargs); |
4215 | 0 | proargtypes = (Oid *) ARR_DATA_PTR(arr); |
4216 | 0 | } |
4217 | 0 | } |
4218 | | |
4219 | | /* Do we have any named arguments? */ |
4220 | 0 | foreach(lc, args) |
4221 | 0 | { |
4222 | 0 | Node *arg = (Node *) lfirst(lc); |
4223 | |
|
4224 | 0 | if (IsA(arg, NamedArgExpr)) |
4225 | 0 | { |
4226 | 0 | has_named_args = true; |
4227 | 0 | break; |
4228 | 0 | } |
4229 | 0 | } |
4230 | | |
4231 | | /* If so, we must apply reorder_function_arguments */ |
4232 | 0 | if (has_named_args) |
4233 | 0 | { |
4234 | 0 | args = reorder_function_arguments(args, pronargs, func_tuple); |
4235 | | /* Recheck argument types and add casts if needed */ |
4236 | 0 | recheck_cast_function_args(args, result_type, |
4237 | 0 | proargtypes, pronargs, |
4238 | 0 | func_tuple); |
4239 | 0 | } |
4240 | 0 | else if (list_length(args) < pronargs) |
4241 | 0 | { |
4242 | | /* No named args, but we seem to be short some defaults */ |
4243 | 0 | args = add_function_defaults(args, pronargs, func_tuple); |
4244 | | /* Recheck argument types and add casts if needed */ |
4245 | 0 | recheck_cast_function_args(args, result_type, |
4246 | 0 | proargtypes, pronargs, |
4247 | 0 | func_tuple); |
4248 | 0 | } |
4249 | |
|
4250 | 0 | return args; |
4251 | 0 | } |
4252 | | |
4253 | | /* |
4254 | | * reorder_function_arguments: convert named-notation args to positional args |
4255 | | * |
4256 | | * This function also inserts default argument values as needed, since it's |
4257 | | * impossible to form a truly valid positional call without that. |
4258 | | */ |
4259 | | static List * |
4260 | | reorder_function_arguments(List *args, int pronargs, HeapTuple func_tuple) |
4261 | 0 | { |
4262 | 0 | Form_pg_proc funcform = (Form_pg_proc) GETSTRUCT(func_tuple); |
4263 | 0 | int nargsprovided = list_length(args); |
4264 | 0 | Node *argarray[FUNC_MAX_ARGS]; |
4265 | 0 | ListCell *lc; |
4266 | 0 | int i; |
4267 | |
|
4268 | 0 | Assert(nargsprovided <= pronargs); |
4269 | 0 | if (pronargs < 0 || pronargs > FUNC_MAX_ARGS) |
4270 | 0 | elog(ERROR, "too many function arguments"); |
4271 | 0 | memset(argarray, 0, pronargs * sizeof(Node *)); |
4272 | | |
4273 | | /* Deconstruct the argument list into an array indexed by argnumber */ |
4274 | 0 | i = 0; |
4275 | 0 | foreach(lc, args) |
4276 | 0 | { |
4277 | 0 | Node *arg = (Node *) lfirst(lc); |
4278 | |
|
4279 | 0 | if (!IsA(arg, NamedArgExpr)) |
4280 | 0 | { |
4281 | | /* positional argument, assumed to precede all named args */ |
4282 | 0 | Assert(argarray[i] == NULL); |
4283 | 0 | argarray[i++] = arg; |
4284 | 0 | } |
4285 | 0 | else |
4286 | 0 | { |
4287 | 0 | NamedArgExpr *na = (NamedArgExpr *) arg; |
4288 | |
|
4289 | 0 | Assert(na->argnumber >= 0 && na->argnumber < pronargs); |
4290 | 0 | Assert(argarray[na->argnumber] == NULL); |
4291 | 0 | argarray[na->argnumber] = (Node *) na->arg; |
4292 | 0 | } |
4293 | 0 | } |
4294 | | |
4295 | | /* |
4296 | | * Fetch default expressions, if needed, and insert into array at proper |
4297 | | * locations (they aren't necessarily consecutive or all used) |
4298 | | */ |
4299 | 0 | if (nargsprovided < pronargs) |
4300 | 0 | { |
4301 | 0 | List *defaults = fetch_function_defaults(func_tuple); |
4302 | |
|
4303 | 0 | i = pronargs - funcform->pronargdefaults; |
4304 | 0 | foreach(lc, defaults) |
4305 | 0 | { |
4306 | 0 | if (argarray[i] == NULL) |
4307 | 0 | argarray[i] = (Node *) lfirst(lc); |
4308 | 0 | i++; |
4309 | 0 | } |
4310 | 0 | } |
4311 | | |
4312 | | /* Now reconstruct the args list in proper order */ |
4313 | 0 | args = NIL; |
4314 | 0 | for (i = 0; i < pronargs; i++) |
4315 | 0 | { |
4316 | 0 | Assert(argarray[i] != NULL); |
4317 | 0 | args = lappend(args, argarray[i]); |
4318 | 0 | } |
4319 | |
|
4320 | 0 | return args; |
4321 | 0 | } |
4322 | | |
4323 | | /* |
4324 | | * add_function_defaults: add missing function arguments from its defaults |
4325 | | * |
4326 | | * This is used only when the argument list was positional to begin with, |
4327 | | * and so we know we just need to add defaults at the end. |
4328 | | */ |
4329 | | static List * |
4330 | | add_function_defaults(List *args, int pronargs, HeapTuple func_tuple) |
4331 | 0 | { |
4332 | 0 | int nargsprovided = list_length(args); |
4333 | 0 | List *defaults; |
4334 | 0 | int ndelete; |
4335 | | |
4336 | | /* Get all the default expressions from the pg_proc tuple */ |
4337 | 0 | defaults = fetch_function_defaults(func_tuple); |
4338 | | |
4339 | | /* Delete any unused defaults from the list */ |
4340 | 0 | ndelete = nargsprovided + list_length(defaults) - pronargs; |
4341 | 0 | if (ndelete < 0) |
4342 | 0 | elog(ERROR, "not enough default arguments"); |
4343 | 0 | if (ndelete > 0) |
4344 | 0 | defaults = list_delete_first_n(defaults, ndelete); |
4345 | | |
4346 | | /* And form the combined argument list, not modifying the input list */ |
4347 | 0 | return list_concat_copy(args, defaults); |
4348 | 0 | } |
4349 | | |
4350 | | /* |
4351 | | * fetch_function_defaults: get function's default arguments as expression list |
4352 | | */ |
4353 | | static List * |
4354 | | fetch_function_defaults(HeapTuple func_tuple) |
4355 | 0 | { |
4356 | 0 | List *defaults; |
4357 | 0 | Datum proargdefaults; |
4358 | 0 | char *str; |
4359 | |
|
4360 | 0 | proargdefaults = SysCacheGetAttrNotNull(PROCOID, func_tuple, |
4361 | 0 | Anum_pg_proc_proargdefaults); |
4362 | 0 | str = TextDatumGetCString(proargdefaults); |
4363 | 0 | defaults = castNode(List, stringToNode(str)); |
4364 | 0 | pfree(str); |
4365 | 0 | return defaults; |
4366 | 0 | } |
4367 | | |
4368 | | /* |
4369 | | * recheck_cast_function_args: recheck function args and typecast as needed |
4370 | | * after adding defaults. |
4371 | | * |
4372 | | * It is possible for some of the defaulted arguments to be polymorphic; |
4373 | | * therefore we can't assume that the default expressions have the correct |
4374 | | * data types already. We have to re-resolve polymorphics and do coercion |
4375 | | * just like the parser did. |
4376 | | * |
4377 | | * This should be a no-op if there are no polymorphic arguments, |
4378 | | * but we do it anyway to be sure. |
4379 | | * |
4380 | | * Note: if any casts are needed, the args list is modified in-place; |
4381 | | * caller should have already copied the list structure. |
4382 | | */ |
4383 | | static void |
4384 | | recheck_cast_function_args(List *args, Oid result_type, |
4385 | | Oid *proargtypes, int pronargs, |
4386 | | HeapTuple func_tuple) |
4387 | 0 | { |
4388 | 0 | Form_pg_proc funcform = (Form_pg_proc) GETSTRUCT(func_tuple); |
4389 | 0 | int nargs; |
4390 | 0 | Oid actual_arg_types[FUNC_MAX_ARGS]; |
4391 | 0 | Oid declared_arg_types[FUNC_MAX_ARGS]; |
4392 | 0 | Oid rettype; |
4393 | 0 | ListCell *lc; |
4394 | |
|
4395 | 0 | if (list_length(args) > FUNC_MAX_ARGS) |
4396 | 0 | elog(ERROR, "too many function arguments"); |
4397 | 0 | nargs = 0; |
4398 | 0 | foreach(lc, args) |
4399 | 0 | { |
4400 | 0 | actual_arg_types[nargs++] = exprType((Node *) lfirst(lc)); |
4401 | 0 | } |
4402 | 0 | Assert(nargs == pronargs); |
4403 | 0 | memcpy(declared_arg_types, proargtypes, pronargs * sizeof(Oid)); |
4404 | 0 | rettype = enforce_generic_type_consistency(actual_arg_types, |
4405 | 0 | declared_arg_types, |
4406 | 0 | nargs, |
4407 | 0 | funcform->prorettype, |
4408 | 0 | false); |
4409 | | /* let's just check we got the same answer as the parser did ... */ |
4410 | 0 | if (rettype != result_type) |
4411 | 0 | elog(ERROR, "function's resolved result type changed during planning"); |
4412 | | |
4413 | | /* perform any necessary typecasting of arguments */ |
4414 | 0 | make_fn_arguments(NULL, args, actual_arg_types, declared_arg_types); |
4415 | 0 | } |
4416 | | |
4417 | | /* |
4418 | | * evaluate_function: try to pre-evaluate a function call |
4419 | | * |
4420 | | * We can do this if the function is strict and has any constant-null inputs |
4421 | | * (just return a null constant), or if the function is immutable and has all |
4422 | | * constant inputs (call it and return the result as a Const node). In |
4423 | | * estimation mode we are willing to pre-evaluate stable functions too. |
4424 | | * |
4425 | | * Returns a simplified expression if successful, or NULL if cannot |
4426 | | * simplify the function. |
4427 | | */ |
4428 | | static Expr * |
4429 | | evaluate_function(Oid funcid, Oid result_type, int32 result_typmod, |
4430 | | Oid result_collid, Oid input_collid, List *args, |
4431 | | bool funcvariadic, |
4432 | | HeapTuple func_tuple, |
4433 | | eval_const_expressions_context *context) |
4434 | 0 | { |
4435 | 0 | Form_pg_proc funcform = (Form_pg_proc) GETSTRUCT(func_tuple); |
4436 | 0 | bool has_nonconst_input = false; |
4437 | 0 | bool has_null_input = false; |
4438 | 0 | ListCell *arg; |
4439 | 0 | FuncExpr *newexpr; |
4440 | | |
4441 | | /* |
4442 | | * Can't simplify if it returns a set. |
4443 | | */ |
4444 | 0 | if (funcform->proretset) |
4445 | 0 | return NULL; |
4446 | | |
4447 | | /* |
4448 | | * Can't simplify if it returns RECORD. The immediate problem is that it |
4449 | | * will be needing an expected tupdesc which we can't supply here. |
4450 | | * |
4451 | | * In the case where it has OUT parameters, we could build an expected |
4452 | | * tupdesc from those, but there may be other gotchas lurking. In |
4453 | | * particular, if the function were to return NULL, we would produce a |
4454 | | * null constant with no remaining indication of which concrete record |
4455 | | * type it is. For now, seems best to leave the function call unreduced. |
4456 | | */ |
4457 | 0 | if (funcform->prorettype == RECORDOID) |
4458 | 0 | return NULL; |
4459 | | |
4460 | | /* |
4461 | | * Check for constant inputs and especially constant-NULL inputs. |
4462 | | */ |
4463 | 0 | foreach(arg, args) |
4464 | 0 | { |
4465 | 0 | if (IsA(lfirst(arg), Const)) |
4466 | 0 | has_null_input |= ((Const *) lfirst(arg))->constisnull; |
4467 | 0 | else |
4468 | 0 | has_nonconst_input = true; |
4469 | 0 | } |
4470 | | |
4471 | | /* |
4472 | | * If the function is strict and has a constant-NULL input, it will never |
4473 | | * be called at all, so we can replace the call by a NULL constant, even |
4474 | | * if there are other inputs that aren't constant, and even if the |
4475 | | * function is not otherwise immutable. |
4476 | | */ |
4477 | 0 | if (funcform->proisstrict && has_null_input) |
4478 | 0 | return (Expr *) makeNullConst(result_type, result_typmod, |
4479 | 0 | result_collid); |
4480 | | |
4481 | | /* |
4482 | | * Otherwise, can simplify only if all inputs are constants. (For a |
4483 | | * non-strict function, constant NULL inputs are treated the same as |
4484 | | * constant non-NULL inputs.) |
4485 | | */ |
4486 | 0 | if (has_nonconst_input) |
4487 | 0 | return NULL; |
4488 | | |
4489 | | /* |
4490 | | * Ordinarily we are only allowed to simplify immutable functions. But for |
4491 | | * purposes of estimation, we consider it okay to simplify functions that |
4492 | | * are merely stable; the risk that the result might change from planning |
4493 | | * time to execution time is worth taking in preference to not being able |
4494 | | * to estimate the value at all. |
4495 | | */ |
4496 | 0 | if (funcform->provolatile == PROVOLATILE_IMMUTABLE) |
4497 | 0 | /* okay */ ; |
4498 | 0 | else if (context->estimate && funcform->provolatile == PROVOLATILE_STABLE) |
4499 | 0 | /* okay */ ; |
4500 | 0 | else |
4501 | 0 | return NULL; |
4502 | | |
4503 | | /* |
4504 | | * OK, looks like we can simplify this operator/function. |
4505 | | * |
4506 | | * Build a new FuncExpr node containing the already-simplified arguments. |
4507 | | */ |
4508 | 0 | newexpr = makeNode(FuncExpr); |
4509 | 0 | newexpr->funcid = funcid; |
4510 | 0 | newexpr->funcresulttype = result_type; |
4511 | 0 | newexpr->funcretset = false; |
4512 | 0 | newexpr->funcvariadic = funcvariadic; |
4513 | 0 | newexpr->funcformat = COERCE_EXPLICIT_CALL; /* doesn't matter */ |
4514 | 0 | newexpr->funccollid = result_collid; /* doesn't matter */ |
4515 | 0 | newexpr->inputcollid = input_collid; |
4516 | 0 | newexpr->args = args; |
4517 | 0 | newexpr->location = -1; |
4518 | |
|
4519 | 0 | return evaluate_expr((Expr *) newexpr, result_type, result_typmod, |
4520 | 0 | result_collid); |
4521 | 0 | } |
4522 | | |
4523 | | /* |
4524 | | * inline_function: try to expand a function call inline |
4525 | | * |
4526 | | * If the function is a sufficiently simple SQL-language function |
4527 | | * (just "SELECT expression"), then we can inline it and avoid the rather |
4528 | | * high per-call overhead of SQL functions. Furthermore, this can expose |
4529 | | * opportunities for constant-folding within the function expression. |
4530 | | * |
4531 | | * We have to beware of some special cases however. A directly or |
4532 | | * indirectly recursive function would cause us to recurse forever, |
4533 | | * so we keep track of which functions we are already expanding and |
4534 | | * do not re-expand them. Also, if a parameter is used more than once |
4535 | | * in the SQL-function body, we require it not to contain any volatile |
4536 | | * functions (volatiles might deliver inconsistent answers) nor to be |
4537 | | * unreasonably expensive to evaluate. The expensiveness check not only |
4538 | | * prevents us from doing multiple evaluations of an expensive parameter |
4539 | | * at runtime, but is a safety value to limit growth of an expression due |
4540 | | * to repeated inlining. |
4541 | | * |
4542 | | * We must also beware of changing the volatility or strictness status of |
4543 | | * functions by inlining them. |
4544 | | * |
4545 | | * Also, at the moment we can't inline functions returning RECORD. This |
4546 | | * doesn't work in the general case because it discards information such |
4547 | | * as OUT-parameter declarations. |
4548 | | * |
4549 | | * Also, context-dependent expression nodes in the argument list are trouble. |
4550 | | * |
4551 | | * Returns a simplified expression if successful, or NULL if cannot |
4552 | | * simplify the function. |
4553 | | */ |
4554 | | static Expr * |
4555 | | inline_function(Oid funcid, Oid result_type, Oid result_collid, |
4556 | | Oid input_collid, List *args, |
4557 | | bool funcvariadic, |
4558 | | HeapTuple func_tuple, |
4559 | | eval_const_expressions_context *context) |
4560 | 0 | { |
4561 | 0 | Form_pg_proc funcform = (Form_pg_proc) GETSTRUCT(func_tuple); |
4562 | 0 | char *src; |
4563 | 0 | Datum tmp; |
4564 | 0 | bool isNull; |
4565 | 0 | MemoryContext oldcxt; |
4566 | 0 | MemoryContext mycxt; |
4567 | 0 | inline_error_callback_arg callback_arg; |
4568 | 0 | ErrorContextCallback sqlerrcontext; |
4569 | 0 | FuncExpr *fexpr; |
4570 | 0 | SQLFunctionParseInfoPtr pinfo; |
4571 | 0 | TupleDesc rettupdesc; |
4572 | 0 | ParseState *pstate; |
4573 | 0 | List *raw_parsetree_list; |
4574 | 0 | List *querytree_list; |
4575 | 0 | Query *querytree; |
4576 | 0 | Node *newexpr; |
4577 | 0 | int *usecounts; |
4578 | 0 | ListCell *arg; |
4579 | 0 | int i; |
4580 | | |
4581 | | /* |
4582 | | * Forget it if the function is not SQL-language or has other showstopper |
4583 | | * properties. (The prokind and nargs checks are just paranoia.) |
4584 | | */ |
4585 | 0 | if (funcform->prolang != SQLlanguageId || |
4586 | 0 | funcform->prokind != PROKIND_FUNCTION || |
4587 | 0 | funcform->prosecdef || |
4588 | 0 | funcform->proretset || |
4589 | 0 | funcform->prorettype == RECORDOID || |
4590 | 0 | !heap_attisnull(func_tuple, Anum_pg_proc_proconfig, NULL) || |
4591 | 0 | funcform->pronargs != list_length(args)) |
4592 | 0 | return NULL; |
4593 | | |
4594 | | /* Check for recursive function, and give up trying to expand if so */ |
4595 | 0 | if (list_member_oid(context->active_fns, funcid)) |
4596 | 0 | return NULL; |
4597 | | |
4598 | | /* Check permission to call function (fail later, if not) */ |
4599 | 0 | if (object_aclcheck(ProcedureRelationId, funcid, GetUserId(), ACL_EXECUTE) != ACLCHECK_OK) |
4600 | 0 | return NULL; |
4601 | | |
4602 | | /* Check whether a plugin wants to hook function entry/exit */ |
4603 | 0 | if (FmgrHookIsNeeded(funcid)) |
4604 | 0 | return NULL; |
4605 | | |
4606 | | /* |
4607 | | * Make a temporary memory context, so that we don't leak all the stuff |
4608 | | * that parsing might create. |
4609 | | */ |
4610 | 0 | mycxt = AllocSetContextCreate(CurrentMemoryContext, |
4611 | 0 | "inline_function", |
4612 | 0 | ALLOCSET_DEFAULT_SIZES); |
4613 | 0 | oldcxt = MemoryContextSwitchTo(mycxt); |
4614 | | |
4615 | | /* |
4616 | | * We need a dummy FuncExpr node containing the already-simplified |
4617 | | * arguments. (In some cases we don't really need it, but building it is |
4618 | | * cheap enough that it's not worth contortions to avoid.) |
4619 | | */ |
4620 | 0 | fexpr = makeNode(FuncExpr); |
4621 | 0 | fexpr->funcid = funcid; |
4622 | 0 | fexpr->funcresulttype = result_type; |
4623 | 0 | fexpr->funcretset = false; |
4624 | 0 | fexpr->funcvariadic = funcvariadic; |
4625 | 0 | fexpr->funcformat = COERCE_EXPLICIT_CALL; /* doesn't matter */ |
4626 | 0 | fexpr->funccollid = result_collid; /* doesn't matter */ |
4627 | 0 | fexpr->inputcollid = input_collid; |
4628 | 0 | fexpr->args = args; |
4629 | 0 | fexpr->location = -1; |
4630 | | |
4631 | | /* Fetch the function body */ |
4632 | 0 | tmp = SysCacheGetAttrNotNull(PROCOID, func_tuple, Anum_pg_proc_prosrc); |
4633 | 0 | src = TextDatumGetCString(tmp); |
4634 | | |
4635 | | /* |
4636 | | * Setup error traceback support for ereport(). This is so that we can |
4637 | | * finger the function that bad information came from. |
4638 | | */ |
4639 | 0 | callback_arg.proname = NameStr(funcform->proname); |
4640 | 0 | callback_arg.prosrc = src; |
4641 | |
|
4642 | 0 | sqlerrcontext.callback = sql_inline_error_callback; |
4643 | 0 | sqlerrcontext.arg = &callback_arg; |
4644 | 0 | sqlerrcontext.previous = error_context_stack; |
4645 | 0 | error_context_stack = &sqlerrcontext; |
4646 | | |
4647 | | /* If we have prosqlbody, pay attention to that not prosrc */ |
4648 | 0 | tmp = SysCacheGetAttr(PROCOID, |
4649 | 0 | func_tuple, |
4650 | 0 | Anum_pg_proc_prosqlbody, |
4651 | 0 | &isNull); |
4652 | 0 | if (!isNull) |
4653 | 0 | { |
4654 | 0 | Node *n; |
4655 | 0 | List *query_list; |
4656 | |
|
4657 | 0 | n = stringToNode(TextDatumGetCString(tmp)); |
4658 | 0 | if (IsA(n, List)) |
4659 | 0 | query_list = linitial_node(List, castNode(List, n)); |
4660 | 0 | else |
4661 | 0 | query_list = list_make1(n); |
4662 | 0 | if (list_length(query_list) != 1) |
4663 | 0 | goto fail; |
4664 | 0 | querytree = linitial(query_list); |
4665 | | |
4666 | | /* |
4667 | | * Because we'll insist below that the querytree have an empty rtable |
4668 | | * and no sublinks, it cannot have any relation references that need |
4669 | | * to be locked or rewritten. So we can omit those steps. |
4670 | | */ |
4671 | 0 | } |
4672 | 0 | else |
4673 | 0 | { |
4674 | | /* Set up to handle parameters while parsing the function body. */ |
4675 | 0 | pinfo = prepare_sql_fn_parse_info(func_tuple, |
4676 | 0 | (Node *) fexpr, |
4677 | 0 | input_collid); |
4678 | | |
4679 | | /* |
4680 | | * We just do parsing and parse analysis, not rewriting, because |
4681 | | * rewriting will not affect table-free-SELECT-only queries, which is |
4682 | | * all that we care about. Also, we can punt as soon as we detect |
4683 | | * more than one command in the function body. |
4684 | | */ |
4685 | 0 | raw_parsetree_list = pg_parse_query(src); |
4686 | 0 | if (list_length(raw_parsetree_list) != 1) |
4687 | 0 | goto fail; |
4688 | | |
4689 | 0 | pstate = make_parsestate(NULL); |
4690 | 0 | pstate->p_sourcetext = src; |
4691 | 0 | sql_fn_parser_setup(pstate, pinfo); |
4692 | |
|
4693 | 0 | querytree = transformTopLevelStmt(pstate, linitial(raw_parsetree_list)); |
4694 | |
|
4695 | 0 | free_parsestate(pstate); |
4696 | 0 | } |
4697 | | |
4698 | | /* |
4699 | | * The single command must be a simple "SELECT expression". |
4700 | | * |
4701 | | * Note: if you change the tests involved in this, see also plpgsql's |
4702 | | * exec_simple_check_plan(). That generally needs to have the same idea |
4703 | | * of what's a "simple expression", so that inlining a function that |
4704 | | * previously wasn't inlined won't change plpgsql's conclusion. |
4705 | | */ |
4706 | 0 | if (!IsA(querytree, Query) || |
4707 | 0 | querytree->commandType != CMD_SELECT || |
4708 | 0 | querytree->hasAggs || |
4709 | 0 | querytree->hasWindowFuncs || |
4710 | 0 | querytree->hasTargetSRFs || |
4711 | 0 | querytree->hasSubLinks || |
4712 | 0 | querytree->cteList || |
4713 | 0 | querytree->rtable || |
4714 | 0 | querytree->jointree->fromlist || |
4715 | 0 | querytree->jointree->quals || |
4716 | 0 | querytree->groupClause || |
4717 | 0 | querytree->groupingSets || |
4718 | 0 | querytree->havingQual || |
4719 | 0 | querytree->windowClause || |
4720 | 0 | querytree->distinctClause || |
4721 | 0 | querytree->sortClause || |
4722 | 0 | querytree->limitOffset || |
4723 | 0 | querytree->limitCount || |
4724 | 0 | querytree->setOperations || |
4725 | 0 | list_length(querytree->targetList) != 1) |
4726 | 0 | goto fail; |
4727 | | |
4728 | | /* If the function result is composite, resolve it */ |
4729 | 0 | (void) get_expr_result_type((Node *) fexpr, |
4730 | 0 | NULL, |
4731 | 0 | &rettupdesc); |
4732 | | |
4733 | | /* |
4734 | | * Make sure the function (still) returns what it's declared to. This |
4735 | | * will raise an error if wrong, but that's okay since the function would |
4736 | | * fail at runtime anyway. Note that check_sql_fn_retval will also insert |
4737 | | * a coercion if needed to make the tlist expression match the declared |
4738 | | * type of the function. |
4739 | | * |
4740 | | * Note: we do not try this until we have verified that no rewriting was |
4741 | | * needed; that's probably not important, but let's be careful. |
4742 | | */ |
4743 | 0 | querytree_list = list_make1(querytree); |
4744 | 0 | if (check_sql_fn_retval(list_make1(querytree_list), |
4745 | 0 | result_type, rettupdesc, |
4746 | 0 | funcform->prokind, |
4747 | 0 | false)) |
4748 | 0 | goto fail; /* reject whole-tuple-result cases */ |
4749 | | |
4750 | | /* |
4751 | | * Given the tests above, check_sql_fn_retval shouldn't have decided to |
4752 | | * inject a projection step, but let's just make sure. |
4753 | | */ |
4754 | 0 | if (querytree != linitial(querytree_list)) |
4755 | 0 | goto fail; |
4756 | | |
4757 | | /* Now we can grab the tlist expression */ |
4758 | 0 | newexpr = (Node *) ((TargetEntry *) linitial(querytree->targetList))->expr; |
4759 | | |
4760 | | /* |
4761 | | * If the SQL function returns VOID, we can only inline it if it is a |
4762 | | * SELECT of an expression returning VOID (ie, it's just a redirection to |
4763 | | * another VOID-returning function). In all non-VOID-returning cases, |
4764 | | * check_sql_fn_retval should ensure that newexpr returns the function's |
4765 | | * declared result type, so this test shouldn't fail otherwise; but we may |
4766 | | * as well cope gracefully if it does. |
4767 | | */ |
4768 | 0 | if (exprType(newexpr) != result_type) |
4769 | 0 | goto fail; |
4770 | | |
4771 | | /* |
4772 | | * Additional validity checks on the expression. It mustn't be more |
4773 | | * volatile than the surrounding function (this is to avoid breaking hacks |
4774 | | * that involve pretending a function is immutable when it really ain't). |
4775 | | * If the surrounding function is declared strict, then the expression |
4776 | | * must contain only strict constructs and must use all of the function |
4777 | | * parameters (this is overkill, but an exact analysis is hard). |
4778 | | */ |
4779 | 0 | if (funcform->provolatile == PROVOLATILE_IMMUTABLE && |
4780 | 0 | contain_mutable_functions(newexpr)) |
4781 | 0 | goto fail; |
4782 | 0 | else if (funcform->provolatile == PROVOLATILE_STABLE && |
4783 | 0 | contain_volatile_functions(newexpr)) |
4784 | 0 | goto fail; |
4785 | | |
4786 | 0 | if (funcform->proisstrict && |
4787 | 0 | contain_nonstrict_functions(newexpr)) |
4788 | 0 | goto fail; |
4789 | | |
4790 | | /* |
4791 | | * If any parameter expression contains a context-dependent node, we can't |
4792 | | * inline, for fear of putting such a node into the wrong context. |
4793 | | */ |
4794 | 0 | if (contain_context_dependent_node((Node *) args)) |
4795 | 0 | goto fail; |
4796 | | |
4797 | | /* |
4798 | | * We may be able to do it; there are still checks on parameter usage to |
4799 | | * make, but those are most easily done in combination with the actual |
4800 | | * substitution of the inputs. So start building expression with inputs |
4801 | | * substituted. |
4802 | | */ |
4803 | 0 | usecounts = (int *) palloc0(funcform->pronargs * sizeof(int)); |
4804 | 0 | newexpr = substitute_actual_parameters(newexpr, funcform->pronargs, |
4805 | 0 | args, usecounts); |
4806 | | |
4807 | | /* Now check for parameter usage */ |
4808 | 0 | i = 0; |
4809 | 0 | foreach(arg, args) |
4810 | 0 | { |
4811 | 0 | Node *param = lfirst(arg); |
4812 | |
|
4813 | 0 | if (usecounts[i] == 0) |
4814 | 0 | { |
4815 | | /* Param not used at all: uncool if func is strict */ |
4816 | 0 | if (funcform->proisstrict) |
4817 | 0 | goto fail; |
4818 | 0 | } |
4819 | 0 | else if (usecounts[i] != 1) |
4820 | 0 | { |
4821 | | /* Param used multiple times: uncool if expensive or volatile */ |
4822 | 0 | QualCost eval_cost; |
4823 | | |
4824 | | /* |
4825 | | * We define "expensive" as "contains any subplan or more than 10 |
4826 | | * operators". Note that the subplan search has to be done |
4827 | | * explicitly, since cost_qual_eval() will barf on unplanned |
4828 | | * subselects. |
4829 | | */ |
4830 | 0 | if (contain_subplans(param)) |
4831 | 0 | goto fail; |
4832 | 0 | cost_qual_eval(&eval_cost, list_make1(param), NULL); |
4833 | 0 | if (eval_cost.startup + eval_cost.per_tuple > |
4834 | 0 | 10 * cpu_operator_cost) |
4835 | 0 | goto fail; |
4836 | | |
4837 | | /* |
4838 | | * Check volatility last since this is more expensive than the |
4839 | | * above tests |
4840 | | */ |
4841 | 0 | if (contain_volatile_functions(param)) |
4842 | 0 | goto fail; |
4843 | 0 | } |
4844 | 0 | i++; |
4845 | 0 | } |
4846 | | |
4847 | | /* |
4848 | | * Whew --- we can make the substitution. Copy the modified expression |
4849 | | * out of the temporary memory context, and clean up. |
4850 | | */ |
4851 | 0 | MemoryContextSwitchTo(oldcxt); |
4852 | |
|
4853 | 0 | newexpr = copyObject(newexpr); |
4854 | |
|
4855 | 0 | MemoryContextDelete(mycxt); |
4856 | | |
4857 | | /* |
4858 | | * If the result is of a collatable type, force the result to expose the |
4859 | | * correct collation. In most cases this does not matter, but it's |
4860 | | * possible that the function result is used directly as a sort key or in |
4861 | | * other places where we expect exprCollation() to tell the truth. |
4862 | | */ |
4863 | 0 | if (OidIsValid(result_collid)) |
4864 | 0 | { |
4865 | 0 | Oid exprcoll = exprCollation(newexpr); |
4866 | |
|
4867 | 0 | if (OidIsValid(exprcoll) && exprcoll != result_collid) |
4868 | 0 | { |
4869 | 0 | CollateExpr *newnode = makeNode(CollateExpr); |
4870 | |
|
4871 | 0 | newnode->arg = (Expr *) newexpr; |
4872 | 0 | newnode->collOid = result_collid; |
4873 | 0 | newnode->location = -1; |
4874 | |
|
4875 | 0 | newexpr = (Node *) newnode; |
4876 | 0 | } |
4877 | 0 | } |
4878 | | |
4879 | | /* |
4880 | | * Since there is now no trace of the function in the plan tree, we must |
4881 | | * explicitly record the plan's dependency on the function. |
4882 | | */ |
4883 | 0 | if (context->root) |
4884 | 0 | record_plan_function_dependency(context->root, funcid); |
4885 | | |
4886 | | /* |
4887 | | * Recursively try to simplify the modified expression. Here we must add |
4888 | | * the current function to the context list of active functions. |
4889 | | */ |
4890 | 0 | context->active_fns = lappend_oid(context->active_fns, funcid); |
4891 | 0 | newexpr = eval_const_expressions_mutator(newexpr, context); |
4892 | 0 | context->active_fns = list_delete_last(context->active_fns); |
4893 | |
|
4894 | 0 | error_context_stack = sqlerrcontext.previous; |
4895 | |
|
4896 | 0 | return (Expr *) newexpr; |
4897 | | |
4898 | | /* Here if func is not inlinable: release temp memory and return NULL */ |
4899 | 0 | fail: |
4900 | 0 | MemoryContextSwitchTo(oldcxt); |
4901 | 0 | MemoryContextDelete(mycxt); |
4902 | 0 | error_context_stack = sqlerrcontext.previous; |
4903 | |
|
4904 | 0 | return NULL; |
4905 | 0 | } |
4906 | | |
4907 | | /* |
4908 | | * Replace Param nodes by appropriate actual parameters |
4909 | | */ |
4910 | | static Node * |
4911 | | substitute_actual_parameters(Node *expr, int nargs, List *args, |
4912 | | int *usecounts) |
4913 | 0 | { |
4914 | 0 | substitute_actual_parameters_context context; |
4915 | |
|
4916 | 0 | context.nargs = nargs; |
4917 | 0 | context.args = args; |
4918 | 0 | context.usecounts = usecounts; |
4919 | |
|
4920 | 0 | return substitute_actual_parameters_mutator(expr, &context); |
4921 | 0 | } |
4922 | | |
4923 | | static Node * |
4924 | | substitute_actual_parameters_mutator(Node *node, |
4925 | | substitute_actual_parameters_context *context) |
4926 | 0 | { |
4927 | 0 | if (node == NULL) |
4928 | 0 | return NULL; |
4929 | 0 | if (IsA(node, Param)) |
4930 | 0 | { |
4931 | 0 | Param *param = (Param *) node; |
4932 | |
|
4933 | 0 | if (param->paramkind != PARAM_EXTERN) |
4934 | 0 | elog(ERROR, "unexpected paramkind: %d", (int) param->paramkind); |
4935 | 0 | if (param->paramid <= 0 || param->paramid > context->nargs) |
4936 | 0 | elog(ERROR, "invalid paramid: %d", param->paramid); |
4937 | | |
4938 | | /* Count usage of parameter */ |
4939 | 0 | context->usecounts[param->paramid - 1]++; |
4940 | | |
4941 | | /* Select the appropriate actual arg and replace the Param with it */ |
4942 | | /* We don't need to copy at this time (it'll get done later) */ |
4943 | 0 | return list_nth(context->args, param->paramid - 1); |
4944 | 0 | } |
4945 | 0 | return expression_tree_mutator(node, substitute_actual_parameters_mutator, context); |
4946 | 0 | } |
4947 | | |
4948 | | /* |
4949 | | * error context callback to let us supply a call-stack traceback |
4950 | | */ |
4951 | | static void |
4952 | | sql_inline_error_callback(void *arg) |
4953 | 0 | { |
4954 | 0 | inline_error_callback_arg *callback_arg = (inline_error_callback_arg *) arg; |
4955 | 0 | int syntaxerrposition; |
4956 | | |
4957 | | /* If it's a syntax error, convert to internal syntax error report */ |
4958 | 0 | syntaxerrposition = geterrposition(); |
4959 | 0 | if (syntaxerrposition > 0) |
4960 | 0 | { |
4961 | 0 | errposition(0); |
4962 | 0 | internalerrposition(syntaxerrposition); |
4963 | 0 | internalerrquery(callback_arg->prosrc); |
4964 | 0 | } |
4965 | |
|
4966 | 0 | errcontext("SQL function \"%s\" during inlining", callback_arg->proname); |
4967 | 0 | } |
4968 | | |
4969 | | /* |
4970 | | * evaluate_expr: pre-evaluate a constant expression |
4971 | | * |
4972 | | * We use the executor's routine ExecEvalExpr() to avoid duplication of |
4973 | | * code and ensure we get the same result as the executor would get. |
4974 | | */ |
4975 | | Expr * |
4976 | | evaluate_expr(Expr *expr, Oid result_type, int32 result_typmod, |
4977 | | Oid result_collation) |
4978 | 0 | { |
4979 | 0 | EState *estate; |
4980 | 0 | ExprState *exprstate; |
4981 | 0 | MemoryContext oldcontext; |
4982 | 0 | Datum const_val; |
4983 | 0 | bool const_is_null; |
4984 | 0 | int16 resultTypLen; |
4985 | 0 | bool resultTypByVal; |
4986 | | |
4987 | | /* |
4988 | | * To use the executor, we need an EState. |
4989 | | */ |
4990 | 0 | estate = CreateExecutorState(); |
4991 | | |
4992 | | /* We can use the estate's working context to avoid memory leaks. */ |
4993 | 0 | oldcontext = MemoryContextSwitchTo(estate->es_query_cxt); |
4994 | | |
4995 | | /* Make sure any opfuncids are filled in. */ |
4996 | 0 | fix_opfuncids((Node *) expr); |
4997 | | |
4998 | | /* |
4999 | | * Prepare expr for execution. (Note: we can't use ExecPrepareExpr |
5000 | | * because it'd result in recursively invoking eval_const_expressions.) |
5001 | | */ |
5002 | 0 | exprstate = ExecInitExpr(expr, NULL); |
5003 | | |
5004 | | /* |
5005 | | * And evaluate it. |
5006 | | * |
5007 | | * It is OK to use a default econtext because none of the ExecEvalExpr() |
5008 | | * code used in this situation will use econtext. That might seem |
5009 | | * fortuitous, but it's not so unreasonable --- a constant expression does |
5010 | | * not depend on context, by definition, n'est ce pas? |
5011 | | */ |
5012 | 0 | const_val = ExecEvalExprSwitchContext(exprstate, |
5013 | 0 | GetPerTupleExprContext(estate), |
5014 | 0 | &const_is_null); |
5015 | | |
5016 | | /* Get info needed about result datatype */ |
5017 | 0 | get_typlenbyval(result_type, &resultTypLen, &resultTypByVal); |
5018 | | |
5019 | | /* Get back to outer memory context */ |
5020 | 0 | MemoryContextSwitchTo(oldcontext); |
5021 | | |
5022 | | /* |
5023 | | * Must copy result out of sub-context used by expression eval. |
5024 | | * |
5025 | | * Also, if it's varlena, forcibly detoast it. This protects us against |
5026 | | * storing TOAST pointers into plans that might outlive the referenced |
5027 | | * data. (makeConst would handle detoasting anyway, but it's worth a few |
5028 | | * extra lines here so that we can do the copy and detoast in one step.) |
5029 | | */ |
5030 | 0 | if (!const_is_null) |
5031 | 0 | { |
5032 | 0 | if (resultTypLen == -1) |
5033 | 0 | const_val = PointerGetDatum(PG_DETOAST_DATUM_COPY(const_val)); |
5034 | 0 | else |
5035 | 0 | const_val = datumCopy(const_val, resultTypByVal, resultTypLen); |
5036 | 0 | } |
5037 | | |
5038 | | /* Release all the junk we just created */ |
5039 | 0 | FreeExecutorState(estate); |
5040 | | |
5041 | | /* |
5042 | | * Make the constant result node. |
5043 | | */ |
5044 | 0 | return (Expr *) makeConst(result_type, result_typmod, result_collation, |
5045 | 0 | resultTypLen, |
5046 | 0 | const_val, const_is_null, |
5047 | 0 | resultTypByVal); |
5048 | 0 | } |
5049 | | |
5050 | | |
5051 | | /* |
5052 | | * inline_set_returning_function |
5053 | | * Attempt to "inline" a set-returning function in the FROM clause. |
5054 | | * |
5055 | | * "rte" is an RTE_FUNCTION rangetable entry. If it represents a call of a |
5056 | | * set-returning SQL function that can safely be inlined, expand the function |
5057 | | * and return the substitute Query structure. Otherwise, return NULL. |
5058 | | * |
5059 | | * We assume that the RTE's expression has already been put through |
5060 | | * eval_const_expressions(), which among other things will take care of |
5061 | | * default arguments and named-argument notation. |
5062 | | * |
5063 | | * This has a good deal of similarity to inline_function(), but that's |
5064 | | * for the non-set-returning case, and there are enough differences to |
5065 | | * justify separate functions. |
5066 | | */ |
5067 | | Query * |
5068 | | inline_set_returning_function(PlannerInfo *root, RangeTblEntry *rte) |
5069 | 0 | { |
5070 | 0 | RangeTblFunction *rtfunc; |
5071 | 0 | FuncExpr *fexpr; |
5072 | 0 | Oid func_oid; |
5073 | 0 | HeapTuple func_tuple; |
5074 | 0 | Form_pg_proc funcform; |
5075 | 0 | char *src; |
5076 | 0 | Datum tmp; |
5077 | 0 | bool isNull; |
5078 | 0 | MemoryContext oldcxt; |
5079 | 0 | MemoryContext mycxt; |
5080 | 0 | inline_error_callback_arg callback_arg; |
5081 | 0 | ErrorContextCallback sqlerrcontext; |
5082 | 0 | SQLFunctionParseInfoPtr pinfo; |
5083 | 0 | TypeFuncClass functypclass; |
5084 | 0 | TupleDesc rettupdesc; |
5085 | 0 | List *raw_parsetree_list; |
5086 | 0 | List *querytree_list; |
5087 | 0 | Query *querytree; |
5088 | |
|
5089 | 0 | Assert(rte->rtekind == RTE_FUNCTION); |
5090 | | |
5091 | | /* |
5092 | | * It doesn't make a lot of sense for a SQL SRF to refer to itself in its |
5093 | | * own FROM clause, since that must cause infinite recursion at runtime. |
5094 | | * It will cause this code to recurse too, so check for stack overflow. |
5095 | | * (There's no need to do more.) |
5096 | | */ |
5097 | 0 | check_stack_depth(); |
5098 | | |
5099 | | /* Fail if the RTE has ORDINALITY - we don't implement that here. */ |
5100 | 0 | if (rte->funcordinality) |
5101 | 0 | return NULL; |
5102 | | |
5103 | | /* Fail if RTE isn't a single, simple FuncExpr */ |
5104 | 0 | if (list_length(rte->functions) != 1) |
5105 | 0 | return NULL; |
5106 | 0 | rtfunc = (RangeTblFunction *) linitial(rte->functions); |
5107 | |
|
5108 | 0 | if (!IsA(rtfunc->funcexpr, FuncExpr)) |
5109 | 0 | return NULL; |
5110 | 0 | fexpr = (FuncExpr *) rtfunc->funcexpr; |
5111 | |
|
5112 | 0 | func_oid = fexpr->funcid; |
5113 | | |
5114 | | /* |
5115 | | * The function must be declared to return a set, else inlining would |
5116 | | * change the results if the contained SELECT didn't return exactly one |
5117 | | * row. |
5118 | | */ |
5119 | 0 | if (!fexpr->funcretset) |
5120 | 0 | return NULL; |
5121 | | |
5122 | | /* |
5123 | | * Refuse to inline if the arguments contain any volatile functions or |
5124 | | * sub-selects. Volatile functions are rejected because inlining may |
5125 | | * result in the arguments being evaluated multiple times, risking a |
5126 | | * change in behavior. Sub-selects are rejected partly for implementation |
5127 | | * reasons (pushing them down another level might change their behavior) |
5128 | | * and partly because they're likely to be expensive and so multiple |
5129 | | * evaluation would be bad. |
5130 | | */ |
5131 | 0 | if (contain_volatile_functions((Node *) fexpr->args) || |
5132 | 0 | contain_subplans((Node *) fexpr->args)) |
5133 | 0 | return NULL; |
5134 | | |
5135 | | /* Check permission to call function (fail later, if not) */ |
5136 | 0 | if (object_aclcheck(ProcedureRelationId, func_oid, GetUserId(), ACL_EXECUTE) != ACLCHECK_OK) |
5137 | 0 | return NULL; |
5138 | | |
5139 | | /* Check whether a plugin wants to hook function entry/exit */ |
5140 | 0 | if (FmgrHookIsNeeded(func_oid)) |
5141 | 0 | return NULL; |
5142 | | |
5143 | | /* |
5144 | | * OK, let's take a look at the function's pg_proc entry. |
5145 | | */ |
5146 | 0 | func_tuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(func_oid)); |
5147 | 0 | if (!HeapTupleIsValid(func_tuple)) |
5148 | 0 | elog(ERROR, "cache lookup failed for function %u", func_oid); |
5149 | 0 | funcform = (Form_pg_proc) GETSTRUCT(func_tuple); |
5150 | | |
5151 | | /* |
5152 | | * Forget it if the function is not SQL-language or has other showstopper |
5153 | | * properties. In particular it mustn't be declared STRICT, since we |
5154 | | * couldn't enforce that. It also mustn't be VOLATILE, because that is |
5155 | | * supposed to cause it to be executed with its own snapshot, rather than |
5156 | | * sharing the snapshot of the calling query. We also disallow returning |
5157 | | * SETOF VOID, because inlining would result in exposing the actual result |
5158 | | * of the function's last SELECT, which should not happen in that case. |
5159 | | * (Rechecking prokind, proretset, and pronargs is just paranoia.) |
5160 | | */ |
5161 | 0 | if (funcform->prolang != SQLlanguageId || |
5162 | 0 | funcform->prokind != PROKIND_FUNCTION || |
5163 | 0 | funcform->proisstrict || |
5164 | 0 | funcform->provolatile == PROVOLATILE_VOLATILE || |
5165 | 0 | funcform->prorettype == VOIDOID || |
5166 | 0 | funcform->prosecdef || |
5167 | 0 | !funcform->proretset || |
5168 | 0 | list_length(fexpr->args) != funcform->pronargs || |
5169 | 0 | !heap_attisnull(func_tuple, Anum_pg_proc_proconfig, NULL)) |
5170 | 0 | { |
5171 | 0 | ReleaseSysCache(func_tuple); |
5172 | 0 | return NULL; |
5173 | 0 | } |
5174 | | |
5175 | | /* |
5176 | | * Make a temporary memory context, so that we don't leak all the stuff |
5177 | | * that parsing might create. |
5178 | | */ |
5179 | 0 | mycxt = AllocSetContextCreate(CurrentMemoryContext, |
5180 | 0 | "inline_set_returning_function", |
5181 | 0 | ALLOCSET_DEFAULT_SIZES); |
5182 | 0 | oldcxt = MemoryContextSwitchTo(mycxt); |
5183 | | |
5184 | | /* Fetch the function body */ |
5185 | 0 | tmp = SysCacheGetAttrNotNull(PROCOID, func_tuple, Anum_pg_proc_prosrc); |
5186 | 0 | src = TextDatumGetCString(tmp); |
5187 | | |
5188 | | /* |
5189 | | * Setup error traceback support for ereport(). This is so that we can |
5190 | | * finger the function that bad information came from. |
5191 | | */ |
5192 | 0 | callback_arg.proname = NameStr(funcform->proname); |
5193 | 0 | callback_arg.prosrc = src; |
5194 | |
|
5195 | 0 | sqlerrcontext.callback = sql_inline_error_callback; |
5196 | 0 | sqlerrcontext.arg = &callback_arg; |
5197 | 0 | sqlerrcontext.previous = error_context_stack; |
5198 | 0 | error_context_stack = &sqlerrcontext; |
5199 | | |
5200 | | /* If we have prosqlbody, pay attention to that not prosrc */ |
5201 | 0 | tmp = SysCacheGetAttr(PROCOID, |
5202 | 0 | func_tuple, |
5203 | 0 | Anum_pg_proc_prosqlbody, |
5204 | 0 | &isNull); |
5205 | 0 | if (!isNull) |
5206 | 0 | { |
5207 | 0 | Node *n; |
5208 | |
|
5209 | 0 | n = stringToNode(TextDatumGetCString(tmp)); |
5210 | 0 | if (IsA(n, List)) |
5211 | 0 | querytree_list = linitial_node(List, castNode(List, n)); |
5212 | 0 | else |
5213 | 0 | querytree_list = list_make1(n); |
5214 | 0 | if (list_length(querytree_list) != 1) |
5215 | 0 | goto fail; |
5216 | 0 | querytree = linitial(querytree_list); |
5217 | | |
5218 | | /* Acquire necessary locks, then apply rewriter. */ |
5219 | 0 | AcquireRewriteLocks(querytree, true, false); |
5220 | 0 | querytree_list = pg_rewrite_query(querytree); |
5221 | 0 | if (list_length(querytree_list) != 1) |
5222 | 0 | goto fail; |
5223 | 0 | querytree = linitial(querytree_list); |
5224 | 0 | } |
5225 | 0 | else |
5226 | 0 | { |
5227 | | /* |
5228 | | * Set up to handle parameters while parsing the function body. We |
5229 | | * can use the FuncExpr just created as the input for |
5230 | | * prepare_sql_fn_parse_info. |
5231 | | */ |
5232 | 0 | pinfo = prepare_sql_fn_parse_info(func_tuple, |
5233 | 0 | (Node *) fexpr, |
5234 | 0 | fexpr->inputcollid); |
5235 | | |
5236 | | /* |
5237 | | * Parse, analyze, and rewrite (unlike inline_function(), we can't |
5238 | | * skip rewriting here). We can fail as soon as we find more than one |
5239 | | * query, though. |
5240 | | */ |
5241 | 0 | raw_parsetree_list = pg_parse_query(src); |
5242 | 0 | if (list_length(raw_parsetree_list) != 1) |
5243 | 0 | goto fail; |
5244 | | |
5245 | 0 | querytree_list = pg_analyze_and_rewrite_withcb(linitial(raw_parsetree_list), |
5246 | 0 | src, |
5247 | 0 | (ParserSetupHook) sql_fn_parser_setup, |
5248 | 0 | pinfo, NULL); |
5249 | 0 | if (list_length(querytree_list) != 1) |
5250 | 0 | goto fail; |
5251 | 0 | querytree = linitial(querytree_list); |
5252 | 0 | } |
5253 | | |
5254 | | /* |
5255 | | * Also resolve the actual function result tupdesc, if composite. If we |
5256 | | * have a coldeflist, believe that; otherwise use get_expr_result_type. |
5257 | | * (This logic should match ExecInitFunctionScan.) |
5258 | | */ |
5259 | 0 | if (rtfunc->funccolnames != NIL) |
5260 | 0 | { |
5261 | 0 | functypclass = TYPEFUNC_RECORD; |
5262 | 0 | rettupdesc = BuildDescFromLists(rtfunc->funccolnames, |
5263 | 0 | rtfunc->funccoltypes, |
5264 | 0 | rtfunc->funccoltypmods, |
5265 | 0 | rtfunc->funccolcollations); |
5266 | 0 | } |
5267 | 0 | else |
5268 | 0 | functypclass = get_expr_result_type((Node *) fexpr, NULL, &rettupdesc); |
5269 | | |
5270 | | /* |
5271 | | * The single command must be a plain SELECT. |
5272 | | */ |
5273 | 0 | if (!IsA(querytree, Query) || |
5274 | 0 | querytree->commandType != CMD_SELECT) |
5275 | 0 | goto fail; |
5276 | | |
5277 | | /* |
5278 | | * Make sure the function (still) returns what it's declared to. This |
5279 | | * will raise an error if wrong, but that's okay since the function would |
5280 | | * fail at runtime anyway. Note that check_sql_fn_retval will also insert |
5281 | | * coercions if needed to make the tlist expression(s) match the declared |
5282 | | * type of the function. We also ask it to insert dummy NULL columns for |
5283 | | * any dropped columns in rettupdesc, so that the elements of the modified |
5284 | | * tlist match up to the attribute numbers. |
5285 | | * |
5286 | | * If the function returns a composite type, don't inline unless the check |
5287 | | * shows it's returning a whole tuple result; otherwise what it's |
5288 | | * returning is a single composite column which is not what we need. |
5289 | | */ |
5290 | 0 | if (!check_sql_fn_retval(list_make1(querytree_list), |
5291 | 0 | fexpr->funcresulttype, rettupdesc, |
5292 | 0 | funcform->prokind, |
5293 | 0 | true) && |
5294 | 0 | (functypclass == TYPEFUNC_COMPOSITE || |
5295 | 0 | functypclass == TYPEFUNC_COMPOSITE_DOMAIN || |
5296 | 0 | functypclass == TYPEFUNC_RECORD)) |
5297 | 0 | goto fail; /* reject not-whole-tuple-result cases */ |
5298 | | |
5299 | | /* |
5300 | | * check_sql_fn_retval might've inserted a projection step, but that's |
5301 | | * fine; just make sure we use the upper Query. |
5302 | | */ |
5303 | 0 | querytree = linitial_node(Query, querytree_list); |
5304 | | |
5305 | | /* |
5306 | | * Looks good --- substitute parameters into the query. |
5307 | | */ |
5308 | 0 | querytree = substitute_actual_srf_parameters(querytree, |
5309 | 0 | funcform->pronargs, |
5310 | 0 | fexpr->args); |
5311 | | |
5312 | | /* |
5313 | | * Copy the modified query out of the temporary memory context, and clean |
5314 | | * up. |
5315 | | */ |
5316 | 0 | MemoryContextSwitchTo(oldcxt); |
5317 | |
|
5318 | 0 | querytree = copyObject(querytree); |
5319 | |
|
5320 | 0 | MemoryContextDelete(mycxt); |
5321 | 0 | error_context_stack = sqlerrcontext.previous; |
5322 | 0 | ReleaseSysCache(func_tuple); |
5323 | | |
5324 | | /* |
5325 | | * We don't have to fix collations here because the upper query is already |
5326 | | * parsed, ie, the collations in the RTE are what count. |
5327 | | */ |
5328 | | |
5329 | | /* |
5330 | | * Since there is now no trace of the function in the plan tree, we must |
5331 | | * explicitly record the plan's dependency on the function. |
5332 | | */ |
5333 | 0 | record_plan_function_dependency(root, func_oid); |
5334 | | |
5335 | | /* |
5336 | | * We must also notice if the inserted query adds a dependency on the |
5337 | | * calling role due to RLS quals. |
5338 | | */ |
5339 | 0 | if (querytree->hasRowSecurity) |
5340 | 0 | root->glob->dependsOnRole = true; |
5341 | |
|
5342 | 0 | return querytree; |
5343 | | |
5344 | | /* Here if func is not inlinable: release temp memory and return NULL */ |
5345 | 0 | fail: |
5346 | 0 | MemoryContextSwitchTo(oldcxt); |
5347 | 0 | MemoryContextDelete(mycxt); |
5348 | 0 | error_context_stack = sqlerrcontext.previous; |
5349 | 0 | ReleaseSysCache(func_tuple); |
5350 | |
|
5351 | 0 | return NULL; |
5352 | 0 | } |
5353 | | |
5354 | | /* |
5355 | | * Replace Param nodes by appropriate actual parameters |
5356 | | * |
5357 | | * This is just enough different from substitute_actual_parameters() |
5358 | | * that it needs its own code. |
5359 | | */ |
5360 | | static Query * |
5361 | | substitute_actual_srf_parameters(Query *expr, int nargs, List *args) |
5362 | 0 | { |
5363 | 0 | substitute_actual_srf_parameters_context context; |
5364 | |
|
5365 | 0 | context.nargs = nargs; |
5366 | 0 | context.args = args; |
5367 | 0 | context.sublevels_up = 1; |
5368 | |
|
5369 | 0 | return query_tree_mutator(expr, |
5370 | 0 | substitute_actual_srf_parameters_mutator, |
5371 | 0 | &context, |
5372 | 0 | 0); |
5373 | 0 | } |
5374 | | |
5375 | | static Node * |
5376 | | substitute_actual_srf_parameters_mutator(Node *node, |
5377 | | substitute_actual_srf_parameters_context *context) |
5378 | 0 | { |
5379 | 0 | Node *result; |
5380 | |
|
5381 | 0 | if (node == NULL) |
5382 | 0 | return NULL; |
5383 | 0 | if (IsA(node, Query)) |
5384 | 0 | { |
5385 | 0 | context->sublevels_up++; |
5386 | 0 | result = (Node *) query_tree_mutator((Query *) node, |
5387 | 0 | substitute_actual_srf_parameters_mutator, |
5388 | 0 | context, |
5389 | 0 | 0); |
5390 | 0 | context->sublevels_up--; |
5391 | 0 | return result; |
5392 | 0 | } |
5393 | 0 | if (IsA(node, Param)) |
5394 | 0 | { |
5395 | 0 | Param *param = (Param *) node; |
5396 | |
|
5397 | 0 | if (param->paramkind == PARAM_EXTERN) |
5398 | 0 | { |
5399 | 0 | if (param->paramid <= 0 || param->paramid > context->nargs) |
5400 | 0 | elog(ERROR, "invalid paramid: %d", param->paramid); |
5401 | | |
5402 | | /* |
5403 | | * Since the parameter is being inserted into a subquery, we must |
5404 | | * adjust levels. |
5405 | | */ |
5406 | 0 | result = copyObject(list_nth(context->args, param->paramid - 1)); |
5407 | 0 | IncrementVarSublevelsUp(result, context->sublevels_up, 0); |
5408 | 0 | return result; |
5409 | 0 | } |
5410 | 0 | } |
5411 | 0 | return expression_tree_mutator(node, |
5412 | 0 | substitute_actual_srf_parameters_mutator, |
5413 | 0 | context); |
5414 | 0 | } |
5415 | | |
5416 | | /* |
5417 | | * pull_paramids |
5418 | | * Returns a Bitmapset containing the paramids of all Params in 'expr'. |
5419 | | */ |
5420 | | Bitmapset * |
5421 | | pull_paramids(Expr *expr) |
5422 | 0 | { |
5423 | 0 | Bitmapset *result = NULL; |
5424 | |
|
5425 | 0 | (void) pull_paramids_walker((Node *) expr, &result); |
5426 | |
|
5427 | 0 | return result; |
5428 | 0 | } |
5429 | | |
5430 | | static bool |
5431 | | pull_paramids_walker(Node *node, Bitmapset **context) |
5432 | 0 | { |
5433 | 0 | if (node == NULL) |
5434 | 0 | return false; |
5435 | 0 | if (IsA(node, Param)) |
5436 | 0 | { |
5437 | 0 | Param *param = (Param *) node; |
5438 | |
|
5439 | 0 | *context = bms_add_member(*context, param->paramid); |
5440 | 0 | return false; |
5441 | 0 | } |
5442 | 0 | return expression_tree_walker(node, pull_paramids_walker, context); |
5443 | 0 | } |
5444 | | |
5445 | | /* |
5446 | | * Build ScalarArrayOpExpr on top of 'exprs.' 'haveNonConst' indicates |
5447 | | * whether at least one of the expressions is not Const. When it's false, |
5448 | | * the array constant is built directly; otherwise, we have to build a child |
5449 | | * ArrayExpr. The 'exprs' list gets freed if not directly used in the output |
5450 | | * expression tree. |
5451 | | */ |
5452 | | ScalarArrayOpExpr * |
5453 | | make_SAOP_expr(Oid oper, Node *leftexpr, Oid coltype, Oid arraycollid, |
5454 | | Oid inputcollid, List *exprs, bool haveNonConst) |
5455 | 0 | { |
5456 | 0 | Node *arrayNode = NULL; |
5457 | 0 | ScalarArrayOpExpr *saopexpr = NULL; |
5458 | 0 | Oid arraytype = get_array_type(coltype); |
5459 | |
|
5460 | 0 | if (!OidIsValid(arraytype)) |
5461 | 0 | return NULL; |
5462 | | |
5463 | | /* |
5464 | | * Assemble an array from the list of constants. It seems more profitable |
5465 | | * to build a const array. But in the presence of other nodes, we don't |
5466 | | * have a specific value here and must employ an ArrayExpr instead. |
5467 | | */ |
5468 | 0 | if (haveNonConst) |
5469 | 0 | { |
5470 | 0 | ArrayExpr *arrayExpr = makeNode(ArrayExpr); |
5471 | | |
5472 | | /* array_collid will be set by parse_collate.c */ |
5473 | 0 | arrayExpr->element_typeid = coltype; |
5474 | 0 | arrayExpr->array_typeid = arraytype; |
5475 | 0 | arrayExpr->multidims = false; |
5476 | 0 | arrayExpr->elements = exprs; |
5477 | 0 | arrayExpr->location = -1; |
5478 | |
|
5479 | 0 | arrayNode = (Node *) arrayExpr; |
5480 | 0 | } |
5481 | 0 | else |
5482 | 0 | { |
5483 | 0 | int16 typlen; |
5484 | 0 | bool typbyval; |
5485 | 0 | char typalign; |
5486 | 0 | Datum *elems; |
5487 | 0 | bool *nulls; |
5488 | 0 | int i = 0; |
5489 | 0 | ArrayType *arrayConst; |
5490 | 0 | int dims[1] = {list_length(exprs)}; |
5491 | 0 | int lbs[1] = {1}; |
5492 | |
|
5493 | 0 | get_typlenbyvalalign(coltype, &typlen, &typbyval, &typalign); |
5494 | |
|
5495 | 0 | elems = (Datum *) palloc(sizeof(Datum) * list_length(exprs)); |
5496 | 0 | nulls = (bool *) palloc(sizeof(bool) * list_length(exprs)); |
5497 | 0 | foreach_node(Const, value, exprs) |
5498 | 0 | { |
5499 | 0 | elems[i] = value->constvalue; |
5500 | 0 | nulls[i++] = value->constisnull; |
5501 | 0 | } |
5502 | |
|
5503 | 0 | arrayConst = construct_md_array(elems, nulls, 1, dims, lbs, |
5504 | 0 | coltype, typlen, typbyval, typalign); |
5505 | 0 | arrayNode = (Node *) makeConst(arraytype, -1, arraycollid, |
5506 | 0 | -1, PointerGetDatum(arrayConst), |
5507 | 0 | false, false); |
5508 | |
|
5509 | 0 | pfree(elems); |
5510 | 0 | pfree(nulls); |
5511 | 0 | list_free(exprs); |
5512 | 0 | } |
5513 | | |
5514 | | /* Build the SAOP expression node */ |
5515 | 0 | saopexpr = makeNode(ScalarArrayOpExpr); |
5516 | 0 | saopexpr->opno = oper; |
5517 | 0 | saopexpr->opfuncid = get_opcode(oper); |
5518 | 0 | saopexpr->hashfuncid = InvalidOid; |
5519 | 0 | saopexpr->negfuncid = InvalidOid; |
5520 | 0 | saopexpr->useOr = true; |
5521 | 0 | saopexpr->inputcollid = inputcollid; |
5522 | 0 | saopexpr->args = list_make2(leftexpr, arrayNode); |
5523 | 0 | saopexpr->location = -1; |
5524 | |
|
5525 | 0 | return saopexpr; |
5526 | 0 | } |