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

Generated by: LCOV version 1.16