LCOV - code coverage report
Current view: top level - src/backend/optimizer/util - clauses.c (source / functions) Hit Total Coverage
Test: PostgreSQL 14devel Lines: 1346 1532 87.9 %
Date: 2020-12-05 17:06:23 Functions: 67 67 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13