LCOV - code coverage report
Current view: top level - src/backend/optimizer/util - clauses.c (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 88.0 % 1913 1683
Test Date: 2026-03-04 15:14:37 Functions: 98.7 % 78 77
Legend: Lines:     hit not hit

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

Generated by: LCOV version 2.0-1