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