LCOV - code coverage report
Current view: top level - src/backend/optimizer/util - clauses.c (source / functions) Hit Total Coverage
Test: PostgreSQL 16beta1 Lines: 1461 1687 86.6 %
Date: 2023-05-30 23:12:14 Functions: 71 71 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.14