PostgreSQL Source Code git master
Loading...
Searching...
No Matches
clauses.c File Reference
#include "postgres.h"
#include "access/htup_details.h"
#include "catalog/pg_class.h"
#include "catalog/pg_inherits.h"
#include "catalog/pg_language.h"
#include "catalog/pg_operator.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_type.h"
#include "executor/executor.h"
#include "executor/functions.h"
#include "funcapi.h"
#include "miscadmin.h"
#include "nodes/makefuncs.h"
#include "nodes/multibitmapset.h"
#include "nodes/nodeFuncs.h"
#include "nodes/subscripting.h"
#include "nodes/supportnodes.h"
#include "optimizer/clauses.h"
#include "optimizer/cost.h"
#include "optimizer/optimizer.h"
#include "optimizer/pathnode.h"
#include "optimizer/plancat.h"
#include "optimizer/planmain.h"
#include "parser/analyze.h"
#include "parser/parse_coerce.h"
#include "parser/parse_collate.h"
#include "parser/parse_func.h"
#include "parser/parse_oper.h"
#include "parser/parsetree.h"
#include "rewrite/rewriteHandler.h"
#include "rewrite/rewriteManip.h"
#include "tcop/tcopprot.h"
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/datum.h"
#include "utils/fmgroids.h"
#include "utils/json.h"
#include "utils/jsonb.h"
#include "utils/jsonpath.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
#include "utils/syscache.h"
#include "utils/typcache.h"
Include dependency graph for clauses.c:

Go to the source code of this file.

Data Structures

struct  eval_const_expressions_context
 
struct  substitute_actual_parameters_context
 
struct  substitute_actual_parameters_in_from_context
 
struct  inline_error_callback_arg
 
struct  max_parallel_hazard_context
 

Macros

#define CCDN_CASETESTEXPR_OK   0x0001 /* CaseTestExpr okay here? */
 
#define MIN_ARRAY_SIZE_FOR_HASHED_SAOP   9
 
#define ece_generic_processing(node)
 
#define ece_all_arguments_const(node)    (!expression_tree_walker((Node *) (node), contain_non_const_walker, NULL))
 
#define ece_evaluate_expr(node)
 

Functions

static bool contain_agg_clause_walker (Node *node, void *context)
 
static bool find_window_functions_walker (Node *node, WindowFuncLists *lists)
 
static bool contain_subplans_walker (Node *node, void *context)
 
static bool contain_mutable_functions_walker (Node *node, void *context)
 
static bool contain_volatile_functions_walker (Node *node, void *context)
 
static bool contain_volatile_functions_not_nextval_walker (Node *node, void *context)
 
static bool max_parallel_hazard_walker (Node *node, max_parallel_hazard_context *context)
 
static bool contain_nonstrict_functions_walker (Node *node, void *context)
 
static bool contain_exec_param_walker (Node *node, List *param_ids)
 
static bool contain_context_dependent_node (Node *clause)
 
static bool contain_context_dependent_node_walker (Node *node, int *flags)
 
static bool contain_leaked_vars_walker (Node *node, void *context)
 
static Relids find_nonnullable_rels_walker (Node *node, bool top_level)
 
static Listfind_nonnullable_vars_walker (Node *node, bool top_level)
 
static void find_subquery_safe_quals (Node *jtnode, List **safe_quals)
 
static bool is_strict_saop (ScalarArrayOpExpr *expr, bool falseOK)
 
static bool convert_saop_to_hashed_saop_walker (Node *node, void *context)
 
static Nodeeval_const_expressions_mutator (Node *node, eval_const_expressions_context *context)
 
static bool contain_non_const_walker (Node *node, void *context)
 
static bool ece_function_is_safe (Oid funcid, eval_const_expressions_context *context)
 
static Listsimplify_or_arguments (List *args, eval_const_expressions_context *context, bool *haveNull, bool *forceTrue)
 
static Listsimplify_and_arguments (List *args, eval_const_expressions_context *context, bool *haveNull, bool *forceFalse)
 
static Nodesimplify_boolean_equality (Oid opno, List *args)
 
static Exprsimplify_function (Oid funcid, Oid result_type, int32 result_typmod, Oid result_collid, Oid input_collid, List **args_p, bool funcvariadic, bool process_args, bool allow_non_const, eval_const_expressions_context *context)
 
static Nodesimplify_aggref (Aggref *aggref, eval_const_expressions_context *context)
 
static Listreorder_function_arguments (List *args, int pronargs, HeapTuple func_tuple)
 
static Listadd_function_defaults (List *args, int pronargs, HeapTuple func_tuple)
 
static Listfetch_function_defaults (HeapTuple func_tuple)
 
static void recheck_cast_function_args (List *args, Oid result_type, Oid *proargtypes, int pronargs, HeapTuple func_tuple)
 
static Exprevaluate_function (Oid funcid, Oid result_type, int32 result_typmod, Oid result_collid, Oid input_collid, List *args, bool funcvariadic, HeapTuple func_tuple, eval_const_expressions_context *context)
 
static Exprinline_function (Oid funcid, Oid result_type, Oid result_collid, Oid input_collid, List *args, bool funcvariadic, HeapTuple func_tuple, eval_const_expressions_context *context)
 
static Nodesubstitute_actual_parameters (Node *expr, int nargs, List *args, int *usecounts)
 
static Nodesubstitute_actual_parameters_mutator (Node *node, substitute_actual_parameters_context *context)
 
static void sql_inline_error_callback (void *arg)
 
static Queryinline_sql_function_in_from (PlannerInfo *root, RangeTblFunction *rtfunc, FuncExpr *fexpr, HeapTuple func_tuple, Form_pg_proc funcform, const char *src)
 
static Querysubstitute_actual_parameters_in_from (Query *expr, int nargs, List *args)
 
static Nodesubstitute_actual_parameters_in_from_mutator (Node *node, substitute_actual_parameters_in_from_context *context)
 
static bool pull_paramids_walker (Node *node, Bitmapset **context)
 
bool contain_agg_clause (Node *clause)
 
bool contain_window_function (Node *clause)
 
WindowFuncListsfind_window_functions (Node *clause, Index maxWinRef)
 
double expression_returns_set_rows (PlannerInfo *root, Node *clause)
 
bool contain_subplans (Node *clause)
 
bool contain_mutable_functions (Node *clause)
 
static bool contain_mutable_functions_checker (Oid func_id, void *context)
 
bool contain_mutable_functions_after_planning (Expr *expr)
 
bool contain_volatile_functions (Node *clause)
 
static bool contain_volatile_functions_checker (Oid func_id, void *context)
 
bool contain_volatile_functions_after_planning (Expr *expr)
 
bool contain_volatile_functions_not_nextval (Node *clause)
 
static bool contain_volatile_functions_not_nextval_checker (Oid func_id, void *context)
 
char max_parallel_hazard (Query *parse)
 
bool is_parallel_safe (PlannerInfo *root, Node *node)
 
static bool max_parallel_hazard_test (char proparallel, max_parallel_hazard_context *context)
 
static bool max_parallel_hazard_checker (Oid func_id, void *context)
 
bool contain_nonstrict_functions (Node *clause)
 
static bool contain_nonstrict_functions_checker (Oid func_id, void *context)
 
bool contain_exec_param (Node *clause, List *param_ids)
 
bool contain_leaked_vars (Node *clause)
 
static bool contain_leaked_vars_checker (Oid func_id, void *context)
 
Relids find_nonnullable_rels (Node *clause)
 
Listfind_nonnullable_vars (Node *clause)
 
Listfind_forced_null_vars (Node *node)
 
Varfind_forced_null_var (Node *node)
 
bool query_outputs_are_not_nullable (Query *query)
 
bool is_pseudo_constant_clause (Node *clause)
 
bool is_pseudo_constant_clause_relids (Node *clause, Relids relids)
 
int NumRelids (PlannerInfo *root, Node *clause)
 
void CommuteOpExpr (OpExpr *clause)
 
static bool rowtype_field_matches (Oid rowtypeid, int fieldnum, Oid expectedtype, int32 expectedtypmod, Oid expectedcollation)
 
Nodeeval_const_expressions (PlannerInfo *root, Node *node)
 
void convert_saop_to_hashed_saop (Node *node)
 
Nodeestimate_expression_value (PlannerInfo *root, Node *node)
 
bool var_is_nonnullable (PlannerInfo *root, Var *var, NotNullSource source)
 
bool expr_is_nonnullable (PlannerInfo *root, Expr *expr, NotNullSource source)
 
Listexpand_function_arguments (List *args, bool include_out_arguments, Oid result_type, HeapTuple func_tuple)
 
Exprevaluate_expr (Expr *expr, Oid result_type, int32 result_typmod, Oid result_collation)
 
Queryinline_function_in_from (PlannerInfo *root, RangeTblEntry *rte)
 
Bitmapsetpull_paramids (Expr *expr)
 
ScalarArrayOpExprmake_SAOP_expr (Oid oper, Node *leftexpr, Oid coltype, Oid arraycollid, Oid inputcollid, List *exprs, bool haveNonConst)
 

Macro Definition Documentation

◆ CCDN_CASETESTEXPR_OK

#define CCDN_CASETESTEXPR_OK   0x0001 /* CaseTestExpr okay here? */

Definition at line 1199 of file clauses.c.

◆ ece_all_arguments_const

#define ece_all_arguments_const (   node)     (!expression_tree_walker((Node *) (node), contain_non_const_walker, NULL))

Definition at line 2670 of file clauses.c.

2685{
2686
2687 /* since this function recurses, it could be driven to stack overflow */
2689
2690 if (node == NULL)
2691 return NULL;
2692 switch (nodeTag(node))
2693 {
2694 case T_Param:
2695 {
2696 Param *param = (Param *) node;
2697 ParamListInfo paramLI = context->boundParams;
2698
2699 /* Look to see if we've been given a value for this Param */
2700 if (param->paramkind == PARAM_EXTERN &&
2701 paramLI != NULL &&
2702 param->paramid > 0 &&
2703 param->paramid <= paramLI->numParams)
2704 {
2707
2708 /*
2709 * Give hook a chance in case parameter is dynamic. Tell
2710 * it that this fetch is speculative, so it should avoid
2711 * erroring out if parameter is unavailable.
2712 */
2713 if (paramLI->paramFetch != NULL)
2714 prm = paramLI->paramFetch(paramLI, param->paramid,
2715 true, &prmdata);
2716 else
2717 prm = &paramLI->params[param->paramid - 1];
2718
2719 /*
2720 * We don't just check OidIsValid, but insist that the
2721 * fetched type match the Param, just in case the hook did
2722 * something unexpected. No need to throw an error here
2723 * though; leave that for runtime.
2724 */
2725 if (OidIsValid(prm->ptype) &&
2726 prm->ptype == param->paramtype)
2727 {
2728 /* OK to substitute parameter value? */
2729 if (context->estimate ||
2730 (prm->pflags & PARAM_FLAG_CONST))
2731 {
2732 /*
2733 * Return a Const representing the param value.
2734 * Must copy pass-by-ref datatypes, since the
2735 * Param might be in a memory context
2736 * shorter-lived than our output plan should be.
2737 */
2738 int16 typLen;
2739 bool typByVal;
2740 Datum pval;
2741 Const *con;
2742
2744 &typLen, &typByVal);
2745 if (prm->isnull || typByVal)
2746 pval = prm->value;
2747 else
2748 pval = datumCopy(prm->value, typByVal, typLen);
2749 con = makeConst(param->paramtype,
2750 param->paramtypmod,
2751 param->paramcollid,
2752 (int) typLen,
2753 pval,
2754 prm->isnull,
2755 typByVal);
2756 con->location = param->location;
2757 return (Node *) con;
2758 }
2759 }
2760 }
2761
2762 /*
2763 * Not replaceable, so just copy the Param (no need to
2764 * recurse)
2765 */
2766 return (Node *) copyObject(param);
2767 }
2768 case T_WindowFunc:
2769 {
2770 WindowFunc *expr = (WindowFunc *) node;
2771 Oid funcid = expr->winfnoid;
2772 List *args;
2773 Expr *aggfilter;
2776
2777 /*
2778 * We can't really simplify a WindowFunc node, but we mustn't
2779 * just fall through to the default processing, because we
2780 * have to apply expand_function_arguments to its argument
2781 * list. That takes care of inserting default arguments and
2782 * expanding named-argument notation.
2783 */
2786 elog(ERROR, "cache lookup failed for function %u", funcid);
2787
2789 false, expr->wintype,
2790 func_tuple);
2791
2793
2794 /* Now, recursively simplify the args (which are a List) */
2795 args = (List *)
2798 context);
2799 /* ... and the filter expression, which isn't */
2800 aggfilter = (Expr *)
2802 context);
2803
2804 /* And build the replacement WindowFunc node */
2806 newexpr->winfnoid = expr->winfnoid;
2807 newexpr->wintype = expr->wintype;
2808 newexpr->wincollid = expr->wincollid;
2809 newexpr->inputcollid = expr->inputcollid;
2810 newexpr->args = args;
2811 newexpr->aggfilter = aggfilter;
2812 newexpr->runCondition = expr->runCondition;
2813 newexpr->winref = expr->winref;
2814 newexpr->winstar = expr->winstar;
2815 newexpr->winagg = expr->winagg;
2817 newexpr->location = expr->location;
2818
2819 return (Node *) newexpr;
2820 }
2821 case T_FuncExpr:
2822 {
2823 FuncExpr *expr = (FuncExpr *) node;
2824 List *args = expr->args;
2825 Expr *simple;
2827
2828 /*
2829 * Code for op/func reduction is pretty bulky, so split it out
2830 * as a separate function. Note: exprTypmod normally returns
2831 * -1 for a FuncExpr, but not when the node is recognizably a
2832 * length coercion; we want to preserve the typmod in the
2833 * eventual Const if so.
2834 */
2835 simple = simplify_function(expr->funcid,
2836 expr->funcresulttype,
2837 exprTypmod(node),
2838 expr->funccollid,
2839 expr->inputcollid,
2840 &args,
2841 expr->funcvariadic,
2842 true,
2843 true,
2844 context);
2845 if (simple) /* successfully simplified it */
2846 return (Node *) simple;
2847
2848 /*
2849 * The expression cannot be simplified any further, so build
2850 * and return a replacement FuncExpr node using the
2851 * possibly-simplified arguments. Note that we have also
2852 * converted the argument list to positional notation.
2853 */
2855 newexpr->funcid = expr->funcid;
2856 newexpr->funcresulttype = expr->funcresulttype;
2857 newexpr->funcretset = expr->funcretset;
2858 newexpr->funcvariadic = expr->funcvariadic;
2859 newexpr->funcformat = expr->funcformat;
2860 newexpr->funccollid = expr->funccollid;
2861 newexpr->inputcollid = expr->inputcollid;
2862 newexpr->args = args;
2863 newexpr->location = expr->location;
2864 return (Node *) newexpr;
2865 }
2866 case T_Aggref:
2867 node = ece_generic_processing(node);
2868 if (context->root != NULL)
2869 return simplify_aggref((Aggref *) node, context);
2870 return node;
2871 case T_OpExpr:
2872 {
2873 OpExpr *expr = (OpExpr *) node;
2874 List *args = expr->args;
2875 Expr *simple;
2876 OpExpr *newexpr;
2877
2878 /*
2879 * Need to get OID of underlying function. Okay to scribble
2880 * on input to this extent.
2881 */
2882 set_opfuncid(expr);
2883
2884 /*
2885 * Code for op/func reduction is pretty bulky, so split it out
2886 * as a separate function.
2887 */
2888 simple = simplify_function(expr->opfuncid,
2889 expr->opresulttype, -1,
2890 expr->opcollid,
2891 expr->inputcollid,
2892 &args,
2893 false,
2894 true,
2895 true,
2896 context);
2897 if (simple) /* successfully simplified it */
2898 return (Node *) simple;
2899
2900 /*
2901 * If the operator is boolean equality or inequality, we know
2902 * how to simplify cases involving one constant and one
2903 * non-constant argument.
2904 */
2905 if (expr->opno == BooleanEqualOperator ||
2907 {
2908 simple = (Expr *) simplify_boolean_equality(expr->opno,
2909 args);
2910 if (simple) /* successfully simplified it */
2911 return (Node *) simple;
2912 }
2913
2914 /*
2915 * The expression cannot be simplified any further, so build
2916 * and return a replacement OpExpr node using the
2917 * possibly-simplified arguments.
2918 */
2920 newexpr->opno = expr->opno;
2921 newexpr->opfuncid = expr->opfuncid;
2922 newexpr->opresulttype = expr->opresulttype;
2923 newexpr->opretset = expr->opretset;
2924 newexpr->opcollid = expr->opcollid;
2925 newexpr->inputcollid = expr->inputcollid;
2926 newexpr->args = args;
2927 newexpr->location = expr->location;
2928 return (Node *) newexpr;
2929 }
2930 case T_DistinctExpr:
2931 {
2932 DistinctExpr *expr = (DistinctExpr *) node;
2933 List *args;
2934 ListCell *arg;
2935 bool has_null_input = false;
2936 bool all_null_input = true;
2937 bool has_nonconst_input = false;
2938 bool has_nullable_nonconst = false;
2939 Expr *simple;
2941
2942 /*
2943 * Reduce constants in the DistinctExpr's arguments. We know
2944 * args is either NIL or a List node, so we can call
2945 * expression_tree_mutator directly rather than recursing to
2946 * self.
2947 */
2948 args = (List *) expression_tree_mutator((Node *) expr->args,
2950 context);
2951
2952 /*
2953 * We must do our own check for NULLs because DistinctExpr has
2954 * different results for NULL input than the underlying
2955 * operator does. We also check if any non-constant input is
2956 * potentially nullable.
2957 */
2958 foreach(arg, args)
2959 {
2960 if (IsA(lfirst(arg), Const))
2961 {
2964 }
2965 else
2966 {
2967 has_nonconst_input = true;
2968 all_null_input = false;
2969
2970 if (!has_nullable_nonconst &&
2971 !expr_is_nonnullable(context->root,
2972 (Expr *) lfirst(arg),
2974 has_nullable_nonconst = true;
2975 }
2976 }
2977
2978 if (!has_nonconst_input)
2979 {
2980 /*
2981 * All inputs are constants. We can optimize this out
2982 * completely.
2983 */
2984
2985 /* all nulls? then not distinct */
2986 if (all_null_input)
2987 return makeBoolConst(false, false);
2988
2989 /* one null? then distinct */
2990 if (has_null_input)
2991 return makeBoolConst(true, false);
2992
2993 /* otherwise try to evaluate the '=' operator */
2994 /* (NOT okay to try to inline it, though!) */
2995
2996 /*
2997 * Need to get OID of underlying function. Okay to
2998 * scribble on input to this extent.
2999 */
3000 set_opfuncid((OpExpr *) expr); /* rely on struct
3001 * equivalence */
3002
3003 /*
3004 * Code for op/func reduction is pretty bulky, so split it
3005 * out as a separate function.
3006 */
3007 simple = simplify_function(expr->opfuncid,
3008 expr->opresulttype, -1,
3009 expr->opcollid,
3010 expr->inputcollid,
3011 &args,
3012 false,
3013 false,
3014 false,
3015 context);
3016 if (simple) /* successfully simplified it */
3017 {
3018 /*
3019 * Since the underlying operator is "=", must negate
3020 * its result
3021 */
3022 Const *csimple = castNode(Const, simple);
3023
3024 csimple->constvalue =
3025 BoolGetDatum(!DatumGetBool(csimple->constvalue));
3026 return (Node *) csimple;
3027 }
3028 }
3029 else if (!has_nullable_nonconst)
3030 {
3031 /*
3032 * There are non-constant inputs, but since all of them
3033 * are proven non-nullable, "IS DISTINCT FROM" semantics
3034 * are much simpler.
3035 */
3036
3037 OpExpr *eqexpr;
3038
3039 /*
3040 * If one input is an explicit NULL constant, and the
3041 * other is a non-nullable expression, the result is
3042 * always TRUE.
3043 */
3044 if (has_null_input)
3045 return makeBoolConst(true, false);
3046
3047 /*
3048 * Otherwise, both inputs are known non-nullable. In this
3049 * case, "IS DISTINCT FROM" is equivalent to the standard
3050 * inequality operator (usually "<>"). We convert this to
3051 * an OpExpr, which is a more efficient representation for
3052 * the planner. It can enable the use of partial indexes
3053 * and constraint exclusion. Furthermore, if the clause
3054 * is negated (ie, "IS NOT DISTINCT FROM"), the resulting
3055 * "=" operator can allow the planner to use index scans,
3056 * merge joins, hash joins, and EC-based qual deductions.
3057 */
3059 eqexpr->opno = expr->opno;
3060 eqexpr->opfuncid = expr->opfuncid;
3061 eqexpr->opresulttype = BOOLOID;
3062 eqexpr->opretset = expr->opretset;
3063 eqexpr->opcollid = expr->opcollid;
3064 eqexpr->inputcollid = expr->inputcollid;
3065 eqexpr->args = args;
3066 eqexpr->location = expr->location;
3067
3069 context);
3070 }
3071 else if (has_null_input)
3072 {
3073 /*
3074 * One input is a nullable non-constant expression, and
3075 * the other is an explicit NULL constant. We can
3076 * transform this to a NullTest with !argisrow, which is
3077 * much more amenable to optimization.
3078 */
3079
3081
3082 nt->arg = (Expr *) (IsA(linitial(args), Const) ?
3083 lsecond(args) : linitial(args));
3084 nt->nulltesttype = IS_NOT_NULL;
3085
3086 /*
3087 * argisrow = false is correct whether or not arg is
3088 * composite
3089 */
3090 nt->argisrow = false;
3091 nt->location = expr->location;
3092
3093 return eval_const_expressions_mutator((Node *) nt, context);
3094 }
3095
3096 /*
3097 * The expression cannot be simplified any further, so build
3098 * and return a replacement DistinctExpr node using the
3099 * possibly-simplified arguments.
3100 */
3102 newexpr->opno = expr->opno;
3103 newexpr->opfuncid = expr->opfuncid;
3104 newexpr->opresulttype = expr->opresulttype;
3105 newexpr->opretset = expr->opretset;
3106 newexpr->opcollid = expr->opcollid;
3107 newexpr->inputcollid = expr->inputcollid;
3108 newexpr->args = args;
3109 newexpr->location = expr->location;
3110 return (Node *) newexpr;
3111 }
3112 case T_NullIfExpr:
3113 {
3114 NullIfExpr *expr;
3115 ListCell *arg;
3116 bool has_nonconst_input = false;
3117
3118 /* Copy the node and const-simplify its arguments */
3119 expr = (NullIfExpr *) ece_generic_processing(node);
3120
3121 /* If either argument is NULL they can't be equal */
3122 foreach(arg, expr->args)
3123 {
3124 if (!IsA(lfirst(arg), Const))
3125 has_nonconst_input = true;
3126 else if (((Const *) lfirst(arg))->constisnull)
3127 return (Node *) linitial(expr->args);
3128 }
3129
3130 /*
3131 * Need to get OID of underlying function before checking if
3132 * the function is OK to evaluate.
3133 */
3134 set_opfuncid((OpExpr *) expr);
3135
3136 if (!has_nonconst_input &&
3137 ece_function_is_safe(expr->opfuncid, context))
3138 return ece_evaluate_expr(expr);
3139
3140 return (Node *) expr;
3141 }
3143 {
3144 ScalarArrayOpExpr *saop;
3145
3146 /* Copy the node and const-simplify its arguments */
3148
3149 /* Make sure we know underlying function */
3150 set_sa_opfuncid(saop);
3151
3152 /*
3153 * If all arguments are Consts, and it's a safe function, we
3154 * can fold to a constant
3155 */
3156 if (ece_all_arguments_const(saop) &&
3157 ece_function_is_safe(saop->opfuncid, context))
3158 return ece_evaluate_expr(saop);
3159 return (Node *) saop;
3160 }
3161 case T_BoolExpr:
3162 {
3163 BoolExpr *expr = (BoolExpr *) node;
3164
3165 switch (expr->boolop)
3166 {
3167 case OR_EXPR:
3168 {
3169 List *newargs;
3170 bool haveNull = false;
3171 bool forceTrue = false;
3172
3174 context,
3175 &haveNull,
3176 &forceTrue);
3177 if (forceTrue)
3178 return makeBoolConst(true, false);
3179 if (haveNull)
3181 makeBoolConst(false, true));
3182 /* If all the inputs are FALSE, result is FALSE */
3183 if (newargs == NIL)
3184 return makeBoolConst(false, false);
3185
3186 /*
3187 * If only one nonconst-or-NULL input, it's the
3188 * result
3189 */
3190 if (list_length(newargs) == 1)
3191 return (Node *) linitial(newargs);
3192 /* Else we still need an OR node */
3193 return (Node *) make_orclause(newargs);
3194 }
3195 case AND_EXPR:
3196 {
3197 List *newargs;
3198 bool haveNull = false;
3199 bool forceFalse = false;
3200
3202 context,
3203 &haveNull,
3204 &forceFalse);
3205 if (forceFalse)
3206 return makeBoolConst(false, false);
3207 if (haveNull)
3209 makeBoolConst(false, true));
3210 /* If all the inputs are TRUE, result is TRUE */
3211 if (newargs == NIL)
3212 return makeBoolConst(true, false);
3213
3214 /*
3215 * If only one nonconst-or-NULL input, it's the
3216 * result
3217 */
3218 if (list_length(newargs) == 1)
3219 return (Node *) linitial(newargs);
3220 /* Else we still need an AND node */
3221 return (Node *) make_andclause(newargs);
3222 }
3223 case NOT_EXPR:
3224 {
3225 Node *arg;
3226
3227 Assert(list_length(expr->args) == 1);
3229 context);
3230
3231 /*
3232 * Use negate_clause() to see if we can simplify
3233 * away the NOT.
3234 */
3235 return negate_clause(arg);
3236 }
3237 default:
3238 elog(ERROR, "unrecognized boolop: %d",
3239 (int) expr->boolop);
3240 break;
3241 }
3242 break;
3243 }
3244
3245 case T_JsonValueExpr:
3246 {
3247 JsonValueExpr *jve = (JsonValueExpr *) node;
3248 Node *raw_expr = (Node *) jve->raw_expr;
3249 Node *formatted_expr = (Node *) jve->formatted_expr;
3250
3251 /*
3252 * If we can fold formatted_expr to a constant, we can elide
3253 * the JsonValueExpr altogether. Otherwise we must process
3254 * raw_expr too. But JsonFormat is a flat node and requires
3255 * no simplification, only copying.
3256 */
3257 formatted_expr = eval_const_expressions_mutator(formatted_expr,
3258 context);
3259 if (formatted_expr && IsA(formatted_expr, Const))
3260 return formatted_expr;
3261
3262 raw_expr = eval_const_expressions_mutator(raw_expr, context);
3263
3264 return (Node *) makeJsonValueExpr((Expr *) raw_expr,
3265 (Expr *) formatted_expr,
3266 copyObject(jve->format));
3267 }
3268
3269 case T_SubPlan:
3271
3272 /*
3273 * Return a SubPlan unchanged --- too late to do anything with it.
3274 *
3275 * XXX should we ereport() here instead? Probably this routine
3276 * should never be invoked after SubPlan creation.
3277 */
3278 return node;
3279 case T_RelabelType:
3280 {
3281 RelabelType *relabel = (RelabelType *) node;
3282 Node *arg;
3283
3284 /* Simplify the input ... */
3286 context);
3287 /* ... and attach a new RelabelType node, if needed */
3288 return applyRelabelType(arg,
3289 relabel->resulttype,
3290 relabel->resulttypmod,
3291 relabel->resultcollid,
3292 relabel->relabelformat,
3293 relabel->location,
3294 true);
3295 }
3296 case T_CoerceViaIO:
3297 {
3298 CoerceViaIO *expr = (CoerceViaIO *) node;
3299 List *args;
3300 Oid outfunc;
3301 bool outtypisvarlena;
3302 Oid infunc;
3304 Expr *simple;
3306
3307 /* Make a List so we can use simplify_function */
3308 args = list_make1(expr->arg);
3309
3310 /*
3311 * CoerceViaIO represents calling the source type's output
3312 * function then the result type's input function. So, try to
3313 * simplify it as though it were a stack of two such function
3314 * calls. First we need to know what the functions are.
3315 *
3316 * Note that the coercion functions are assumed not to care
3317 * about input collation, so we just pass InvalidOid for that.
3318 */
3322 &infunc, &intypioparam);
3323
3324 simple = simplify_function(outfunc,
3325 CSTRINGOID, -1,
3326 InvalidOid,
3327 InvalidOid,
3328 &args,
3329 false,
3330 true,
3331 true,
3332 context);
3333 if (simple) /* successfully simplified output fn */
3334 {
3335 /*
3336 * Input functions may want 1 to 3 arguments. We always
3337 * supply all three, trusting that nothing downstream will
3338 * complain.
3339 */
3340 args = list_make3(simple,
3342 -1,
3343 InvalidOid,
3344 sizeof(Oid),
3346 false,
3347 true),
3349 -1,
3350 InvalidOid,
3351 sizeof(int32),
3352 Int32GetDatum(-1),
3353 false,
3354 true));
3355
3356 simple = simplify_function(infunc,
3357 expr->resulttype, -1,
3358 expr->resultcollid,
3359 InvalidOid,
3360 &args,
3361 false,
3362 false,
3363 true,
3364 context);
3365 if (simple) /* successfully simplified input fn */
3366 return (Node *) simple;
3367 }
3368
3369 /*
3370 * The expression cannot be simplified any further, so build
3371 * and return a replacement CoerceViaIO node using the
3372 * possibly-simplified argument.
3373 */
3375 newexpr->arg = (Expr *) linitial(args);
3376 newexpr->resulttype = expr->resulttype;
3377 newexpr->resultcollid = expr->resultcollid;
3378 newexpr->coerceformat = expr->coerceformat;
3379 newexpr->location = expr->location;
3380 return (Node *) newexpr;
3381 }
3382 case T_ArrayCoerceExpr:
3383 {
3386
3387 /*
3388 * Copy the node and const-simplify its arguments. We can't
3389 * use ece_generic_processing() here because we need to mess
3390 * with case_val only while processing the elemexpr.
3391 */
3392 memcpy(ac, node, sizeof(ArrayCoerceExpr));
3393 ac->arg = (Expr *)
3395 context);
3396
3397 /*
3398 * Set up for the CaseTestExpr node contained in the elemexpr.
3399 * We must prevent it from absorbing any outer CASE value.
3400 */
3401 save_case_val = context->case_val;
3402 context->case_val = NULL;
3403
3404 ac->elemexpr = (Expr *)
3406 context);
3407
3408 context->case_val = save_case_val;
3409
3410 /*
3411 * If constant argument and the per-element expression is
3412 * immutable, we can simplify the whole thing to a constant.
3413 * Exception: although contain_mutable_functions considers
3414 * CoerceToDomain immutable for historical reasons, let's not
3415 * do so here; this ensures coercion to an array-over-domain
3416 * does not apply the domain's constraints until runtime.
3417 */
3418 if (ac->arg && IsA(ac->arg, Const) &&
3419 ac->elemexpr && !IsA(ac->elemexpr, CoerceToDomain) &&
3420 !contain_mutable_functions((Node *) ac->elemexpr))
3421 return ece_evaluate_expr(ac);
3422
3423 return (Node *) ac;
3424 }
3425 case T_CollateExpr:
3426 {
3427 /*
3428 * We replace CollateExpr with RelabelType, so as to improve
3429 * uniformity of expression representation and thus simplify
3430 * comparison of expressions. Hence this looks very nearly
3431 * the same as the RelabelType case, and we can apply the same
3432 * optimizations to avoid unnecessary RelabelTypes.
3433 */
3434 CollateExpr *collate = (CollateExpr *) node;
3435 Node *arg;
3436
3437 /* Simplify the input ... */
3439 context);
3440 /* ... and attach a new RelabelType node, if needed */
3441 return applyRelabelType(arg,
3442 exprType(arg),
3443 exprTypmod(arg),
3444 collate->collOid,
3446 collate->location,
3447 true);
3448 }
3449 case T_CaseExpr:
3450 {
3451 /*----------
3452 * CASE expressions can be simplified if there are constant
3453 * condition clauses:
3454 * FALSE (or NULL): drop the alternative
3455 * TRUE: drop all remaining alternatives
3456 * If the first non-FALSE alternative is a constant TRUE,
3457 * we can simplify the entire CASE to that alternative's
3458 * expression. If there are no non-FALSE alternatives,
3459 * we simplify the entire CASE to the default result (ELSE).
3460 *
3461 * If we have a simple-form CASE with constant test
3462 * expression, we substitute the constant value for contained
3463 * CaseTestExpr placeholder nodes, so that we have the
3464 * opportunity to reduce constant test conditions. For
3465 * example this allows
3466 * CASE 0 WHEN 0 THEN 1 ELSE 1/0 END
3467 * to reduce to 1 rather than drawing a divide-by-0 error.
3468 * Note that when the test expression is constant, we don't
3469 * have to include it in the resulting CASE; for example
3470 * CASE 0 WHEN x THEN y ELSE z END
3471 * is transformed by the parser to
3472 * CASE 0 WHEN CaseTestExpr = x THEN y ELSE z END
3473 * which we can simplify to
3474 * CASE WHEN 0 = x THEN y ELSE z END
3475 * It is not necessary for the executor to evaluate the "arg"
3476 * expression when executing the CASE, since any contained
3477 * CaseTestExprs that might have referred to it will have been
3478 * replaced by the constant.
3479 *----------
3480 */
3481 CaseExpr *caseexpr = (CaseExpr *) node;
3484 Node *newarg;
3485 List *newargs;
3486 bool const_true_cond;
3487 Node *defresult = NULL;
3488 ListCell *arg;
3489
3490 /* Simplify the test expression, if any */
3492 context);
3493
3494 /* Set up for contained CaseTestExpr nodes */
3495 save_case_val = context->case_val;
3496 if (newarg && IsA(newarg, Const))
3497 {
3498 context->case_val = newarg;
3499 newarg = NULL; /* not needed anymore, see above */
3500 }
3501 else
3502 context->case_val = NULL;
3503
3504 /* Simplify the WHEN clauses */
3505 newargs = NIL;
3506 const_true_cond = false;
3507 foreach(arg, caseexpr->args)
3508 {
3510 Node *casecond;
3512
3513 /* Simplify this alternative's test condition */
3515 context);
3516
3517 /*
3518 * If the test condition is constant FALSE (or NULL), then
3519 * drop this WHEN clause completely, without processing
3520 * the result.
3521 */
3522 if (casecond && IsA(casecond, Const))
3523 {
3525
3526 if (const_input->constisnull ||
3527 !DatumGetBool(const_input->constvalue))
3528 continue; /* drop alternative with FALSE cond */
3529 /* Else it's constant TRUE */
3530 const_true_cond = true;
3531 }
3532
3533 /* Simplify this alternative's result value */
3535 context);
3536
3537 /* If non-constant test condition, emit a new WHEN node */
3538 if (!const_true_cond)
3539 {
3541
3542 newcasewhen->expr = (Expr *) casecond;
3543 newcasewhen->result = (Expr *) caseresult;
3544 newcasewhen->location = oldcasewhen->location;
3546 continue;
3547 }
3548
3549 /*
3550 * Found a TRUE condition, so none of the remaining
3551 * alternatives can be reached. We treat the result as
3552 * the default result.
3553 */
3554 defresult = caseresult;
3555 break;
3556 }
3557
3558 /* Simplify the default result, unless we replaced it above */
3559 if (!const_true_cond)
3560 defresult = eval_const_expressions_mutator((Node *) caseexpr->defresult,
3561 context);
3562
3563 context->case_val = save_case_val;
3564
3565 /*
3566 * If no non-FALSE alternatives, CASE reduces to the default
3567 * result
3568 */
3569 if (newargs == NIL)
3570 return defresult;
3571 /* Otherwise we need a new CASE node */
3573 newcase->casetype = caseexpr->casetype;
3574 newcase->casecollid = caseexpr->casecollid;
3575 newcase->arg = (Expr *) newarg;
3576 newcase->args = newargs;
3577 newcase->defresult = (Expr *) defresult;
3578 newcase->location = caseexpr->location;
3579 return (Node *) newcase;
3580 }
3581 case T_CaseTestExpr:
3582 {
3583 /*
3584 * If we know a constant test value for the current CASE
3585 * construct, substitute it for the placeholder. Else just
3586 * return the placeholder as-is.
3587 */
3588 if (context->case_val)
3589 return copyObject(context->case_val);
3590 else
3591 return copyObject(node);
3592 }
3593 case T_SubscriptingRef:
3594 case T_ArrayExpr:
3595 case T_RowExpr:
3596 case T_MinMaxExpr:
3597 {
3598 /*
3599 * Generic handling for node types whose own processing is
3600 * known to be immutable, and for which we need no smarts
3601 * beyond "simplify if all inputs are constants".
3602 *
3603 * Treating SubscriptingRef this way assumes that subscripting
3604 * fetch and assignment are both immutable. This constrains
3605 * type-specific subscripting implementations; maybe we should
3606 * relax it someday.
3607 *
3608 * Treating MinMaxExpr this way amounts to assuming that the
3609 * btree comparison function it calls is immutable; see the
3610 * reasoning in contain_mutable_functions_walker.
3611 */
3612
3613 /* Copy the node and const-simplify its arguments */
3614 node = ece_generic_processing(node);
3615 /* If all arguments are Consts, we can fold to a constant */
3616 if (ece_all_arguments_const(node))
3617 return ece_evaluate_expr(node);
3618 return node;
3619 }
3620 case T_CoalesceExpr:
3621 {
3624 List *newargs;
3625 ListCell *arg;
3626
3627 newargs = NIL;
3628 foreach(arg, coalesceexpr->args)
3629 {
3630 Node *e;
3631
3633 context);
3634
3635 /*
3636 * We can remove null constants from the list. For a
3637 * nonnullable expression, if it has not been preceded by
3638 * any non-null-constant expressions then it is the
3639 * result. Otherwise, it's the next argument, but we can
3640 * drop following arguments since they will never be
3641 * reached.
3642 */
3643 if (IsA(e, Const))
3644 {
3645 if (((Const *) e)->constisnull)
3646 continue; /* drop null constant */
3647 if (newargs == NIL)
3648 return e; /* first expr */
3650 break;
3651 }
3652 if (expr_is_nonnullable(context->root, (Expr *) e,
3654 {
3655 if (newargs == NIL)
3656 return e; /* first expr */
3658 break;
3659 }
3660
3662 }
3663
3664 /*
3665 * If all the arguments were constant null, the result is just
3666 * null
3667 */
3668 if (newargs == NIL)
3669 return (Node *) makeNullConst(coalesceexpr->coalescetype,
3670 -1,
3671 coalesceexpr->coalescecollid);
3672
3673 /*
3674 * If there's exactly one surviving argument, we no longer
3675 * need COALESCE at all: the result is that argument
3676 */
3677 if (list_length(newargs) == 1)
3678 return (Node *) linitial(newargs);
3679
3681 newcoalesce->coalescetype = coalesceexpr->coalescetype;
3682 newcoalesce->coalescecollid = coalesceexpr->coalescecollid;
3683 newcoalesce->args = newargs;
3684 newcoalesce->location = coalesceexpr->location;
3685 return (Node *) newcoalesce;
3686 }
3687 case T_SQLValueFunction:
3688 {
3689 /*
3690 * All variants of SQLValueFunction are stable, so if we are
3691 * estimating the expression's value, we should evaluate the
3692 * current function value. Otherwise just copy.
3693 */
3694 SQLValueFunction *svf = (SQLValueFunction *) node;
3695
3696 if (context->estimate)
3697 return (Node *) evaluate_expr((Expr *) svf,
3698 svf->type,
3699 svf->typmod,
3700 InvalidOid);
3701 else
3702 return copyObject((Node *) svf);
3703 }
3704 case T_FieldSelect:
3705 {
3706 /*
3707 * We can optimize field selection from a whole-row Var into a
3708 * simple Var. (This case won't be generated directly by the
3709 * parser, because ParseComplexProjection short-circuits it.
3710 * But it can arise while simplifying functions.) Also, we
3711 * can optimize field selection from a RowExpr construct, or
3712 * of course from a constant.
3713 *
3714 * However, replacing a whole-row Var in this way has a
3715 * pitfall: if we've already built the rel targetlist for the
3716 * source relation, then the whole-row Var is scheduled to be
3717 * produced by the relation scan, but the simple Var probably
3718 * isn't, which will lead to a failure in setrefs.c. This is
3719 * not a problem when handling simple single-level queries, in
3720 * which expression simplification always happens first. It
3721 * is a risk for lateral references from subqueries, though.
3722 * To avoid such failures, don't optimize uplevel references.
3723 *
3724 * We must also check that the declared type of the field is
3725 * still the same as when the FieldSelect was created --- this
3726 * can change if someone did ALTER COLUMN TYPE on the rowtype.
3727 * If it isn't, we skip the optimization; the case will
3728 * probably fail at runtime, but that's not our problem here.
3729 */
3730 FieldSelect *fselect = (FieldSelect *) node;
3732 Node *arg;
3733
3735 context);
3736 if (arg && IsA(arg, Var) &&
3737 ((Var *) arg)->varattno == InvalidAttrNumber &&
3738 ((Var *) arg)->varlevelsup == 0)
3739 {
3740 if (rowtype_field_matches(((Var *) arg)->vartype,
3741 fselect->fieldnum,
3742 fselect->resulttype,
3743 fselect->resulttypmod,
3744 fselect->resultcollid))
3745 {
3746 Var *newvar;
3747
3748 newvar = makeVar(((Var *) arg)->varno,
3749 fselect->fieldnum,
3750 fselect->resulttype,
3751 fselect->resulttypmod,
3752 fselect->resultcollid,
3753 ((Var *) arg)->varlevelsup);
3754 /* New Var has same OLD/NEW returning as old one */
3755 newvar->varreturningtype = ((Var *) arg)->varreturningtype;
3756 /* New Var is nullable by same rels as the old one */
3757 newvar->varnullingrels = ((Var *) arg)->varnullingrels;
3758 return (Node *) newvar;
3759 }
3760 }
3761 if (arg && IsA(arg, RowExpr))
3762 {
3763 RowExpr *rowexpr = (RowExpr *) arg;
3764
3765 if (fselect->fieldnum > 0 &&
3766 fselect->fieldnum <= list_length(rowexpr->args))
3767 {
3768 Node *fld = (Node *) list_nth(rowexpr->args,
3769 fselect->fieldnum - 1);
3770
3771 if (rowtype_field_matches(rowexpr->row_typeid,
3772 fselect->fieldnum,
3773 fselect->resulttype,
3774 fselect->resulttypmod,
3775 fselect->resultcollid) &&
3776 fselect->resulttype == exprType(fld) &&
3777 fselect->resulttypmod == exprTypmod(fld) &&
3778 fselect->resultcollid == exprCollation(fld))
3779 return fld;
3780 }
3781 }
3783 newfselect->arg = (Expr *) arg;
3784 newfselect->fieldnum = fselect->fieldnum;
3785 newfselect->resulttype = fselect->resulttype;
3786 newfselect->resulttypmod = fselect->resulttypmod;
3787 newfselect->resultcollid = fselect->resultcollid;
3788 if (arg && IsA(arg, Const))
3789 {
3790 Const *con = (Const *) arg;
3791
3793 newfselect->fieldnum,
3794 newfselect->resulttype,
3795 newfselect->resulttypmod,
3796 newfselect->resultcollid))
3798 }
3799 return (Node *) newfselect;
3800 }
3801 case T_NullTest:
3802 {
3803 NullTest *ntest = (NullTest *) node;
3805 Node *arg;
3806
3808 context);
3809 if (ntest->argisrow && arg && IsA(arg, RowExpr))
3810 {
3811 /*
3812 * We break ROW(...) IS [NOT] NULL into separate tests on
3813 * its component fields. This form is usually more
3814 * efficient to evaluate, as well as being more amenable
3815 * to optimization.
3816 */
3817 RowExpr *rarg = (RowExpr *) arg;
3818 List *newargs = NIL;
3819 ListCell *l;
3820
3821 foreach(l, rarg->args)
3822 {
3823 Node *relem = (Node *) lfirst(l);
3824
3825 /*
3826 * A constant field refutes the whole NullTest if it's
3827 * of the wrong nullness; else we can discard it.
3828 */
3829 if (relem && IsA(relem, Const))
3830 {
3831 Const *carg = (Const *) relem;
3832
3833 if (carg->constisnull ?
3834 (ntest->nulltesttype == IS_NOT_NULL) :
3835 (ntest->nulltesttype == IS_NULL))
3836 return makeBoolConst(false, false);
3837 continue;
3838 }
3839
3840 /*
3841 * A proven non-nullable field refutes the whole
3842 * NullTest if the test is IS NULL; else we can
3843 * discard it.
3844 */
3845 if (relem &&
3846 expr_is_nonnullable(context->root, (Expr *) relem,
3848 {
3849 if (ntest->nulltesttype == IS_NULL)
3850 return makeBoolConst(false, false);
3851 continue;
3852 }
3853
3854 /*
3855 * Else, make a scalar (argisrow == false) NullTest
3856 * for this field. Scalar semantics are required
3857 * because IS [NOT] NULL doesn't recurse; see comments
3858 * in ExecEvalRowNullInt().
3859 */
3861 newntest->arg = (Expr *) relem;
3862 newntest->nulltesttype = ntest->nulltesttype;
3863 newntest->argisrow = false;
3864 newntest->location = ntest->location;
3866 }
3867 /* If all the inputs were constants, result is TRUE */
3868 if (newargs == NIL)
3869 return makeBoolConst(true, false);
3870 /* If only one nonconst input, it's the result */
3871 if (list_length(newargs) == 1)
3872 return (Node *) linitial(newargs);
3873 /* Else we need an AND node */
3874 return (Node *) make_andclause(newargs);
3875 }
3876 if (!ntest->argisrow && arg && IsA(arg, Const))
3877 {
3878 Const *carg = (Const *) arg;
3879 bool result;
3880
3881 switch (ntest->nulltesttype)
3882 {
3883 case IS_NULL:
3884 result = carg->constisnull;
3885 break;
3886 case IS_NOT_NULL:
3887 result = !carg->constisnull;
3888 break;
3889 default:
3890 elog(ERROR, "unrecognized nulltesttype: %d",
3891 (int) ntest->nulltesttype);
3892 result = false; /* keep compiler quiet */
3893 break;
3894 }
3895
3896 return makeBoolConst(result, false);
3897 }
3898 if (!ntest->argisrow && arg &&
3899 expr_is_nonnullable(context->root, (Expr *) arg,
3901 {
3902 bool result;
3903
3904 switch (ntest->nulltesttype)
3905 {
3906 case IS_NULL:
3907 result = false;
3908 break;
3909 case IS_NOT_NULL:
3910 result = true;
3911 break;
3912 default:
3913 elog(ERROR, "unrecognized nulltesttype: %d",
3914 (int) ntest->nulltesttype);
3915 result = false; /* keep compiler quiet */
3916 break;
3917 }
3918
3919 return makeBoolConst(result, false);
3920 }
3921
3923 newntest->arg = (Expr *) arg;
3924 newntest->nulltesttype = ntest->nulltesttype;
3925 newntest->argisrow = ntest->argisrow;
3926 newntest->location = ntest->location;
3927 return (Node *) newntest;
3928 }
3929 case T_BooleanTest:
3930 {
3931 /*
3932 * This case could be folded into the generic handling used
3933 * for ArrayExpr etc. But because the simplification logic is
3934 * so trivial, applying evaluate_expr() to perform it would be
3935 * a heavy overhead. BooleanTest is probably common enough to
3936 * justify keeping this bespoke implementation.
3937 */
3938 BooleanTest *btest = (BooleanTest *) node;
3940 Node *arg;
3941
3943 context);
3944 if (arg && IsA(arg, Const))
3945 {
3946 /*
3947 * If arg is Const, simplify to constant.
3948 */
3949 Const *carg = (Const *) arg;
3950 bool result;
3951
3952 switch (btest->booltesttype)
3953 {
3954 case IS_TRUE:
3955 result = (!carg->constisnull &&
3956 DatumGetBool(carg->constvalue));
3957 break;
3958 case IS_NOT_TRUE:
3959 result = (carg->constisnull ||
3960 !DatumGetBool(carg->constvalue));
3961 break;
3962 case IS_FALSE:
3963 result = (!carg->constisnull &&
3964 !DatumGetBool(carg->constvalue));
3965 break;
3966 case IS_NOT_FALSE:
3967 result = (carg->constisnull ||
3968 DatumGetBool(carg->constvalue));
3969 break;
3970 case IS_UNKNOWN:
3971 result = carg->constisnull;
3972 break;
3973 case IS_NOT_UNKNOWN:
3974 result = !carg->constisnull;
3975 break;
3976 default:
3977 elog(ERROR, "unrecognized booltesttype: %d",
3978 (int) btest->booltesttype);
3979 result = false; /* keep compiler quiet */
3980 break;
3981 }
3982
3983 return makeBoolConst(result, false);
3984 }
3985 if (arg &&
3986 expr_is_nonnullable(context->root, (Expr *) arg,
3988 {
3989 /*
3990 * If arg is proven non-nullable, simplify to boolean
3991 * expression or constant.
3992 */
3993 switch (btest->booltesttype)
3994 {
3995 case IS_TRUE:
3996 case IS_NOT_FALSE:
3997 return arg;
3998
3999 case IS_FALSE:
4000 case IS_NOT_TRUE:
4001 return (Node *) make_notclause((Expr *) arg);
4002
4003 case IS_UNKNOWN:
4004 return makeBoolConst(false, false);
4005
4006 case IS_NOT_UNKNOWN:
4007 return makeBoolConst(true, false);
4008
4009 default:
4010 elog(ERROR, "unrecognized booltesttype: %d",
4011 (int) btest->booltesttype);
4012 break;
4013 }
4014 }
4015
4017 newbtest->arg = (Expr *) arg;
4018 newbtest->booltesttype = btest->booltesttype;
4019 newbtest->location = btest->location;
4020 return (Node *) newbtest;
4021 }
4022 case T_CoerceToDomain:
4023 {
4024 /*
4025 * If the domain currently has no constraints, we replace the
4026 * CoerceToDomain node with a simple RelabelType, which is
4027 * both far faster to execute and more amenable to later
4028 * optimization. We must then mark the plan as needing to be
4029 * rebuilt if the domain's constraints change.
4030 *
4031 * Also, in estimation mode, always replace CoerceToDomain
4032 * nodes, effectively assuming that the coercion will succeed.
4033 */
4036 Node *arg;
4037
4039 context);
4040 if (context->estimate ||
4041 !DomainHasConstraints(cdomain->resulttype))
4042 {
4043 /* Record dependency, if this isn't estimation mode */
4044 if (context->root && !context->estimate)
4045 record_plan_type_dependency(context->root,
4046 cdomain->resulttype);
4047
4048 /* Generate RelabelType to substitute for CoerceToDomain */
4049 return applyRelabelType(arg,
4050 cdomain->resulttype,
4051 cdomain->resulttypmod,
4052 cdomain->resultcollid,
4053 cdomain->coercionformat,
4054 cdomain->location,
4055 true);
4056 }
4057
4059 newcdomain->arg = (Expr *) arg;
4060 newcdomain->resulttype = cdomain->resulttype;
4061 newcdomain->resulttypmod = cdomain->resulttypmod;
4062 newcdomain->resultcollid = cdomain->resultcollid;
4063 newcdomain->coercionformat = cdomain->coercionformat;
4064 newcdomain->location = cdomain->location;
4065 return (Node *) newcdomain;
4066 }
4067 case T_PlaceHolderVar:
4068
4069 /*
4070 * In estimation mode, just strip the PlaceHolderVar node
4071 * altogether; this amounts to estimating that the contained value
4072 * won't be forced to null by an outer join. In regular mode we
4073 * just use the default behavior (ie, simplify the expression but
4074 * leave the PlaceHolderVar node intact).
4075 */
4076 if (context->estimate)
4077 {
4078 PlaceHolderVar *phv = (PlaceHolderVar *) node;
4079
4080 return eval_const_expressions_mutator((Node *) phv->phexpr,
4081 context);
4082 }
4083 break;
4085 {
4087 Node *arg;
4089
4091 context);
4092
4094 newcre->resulttype = cre->resulttype;
4095 newcre->convertformat = cre->convertformat;
4096 newcre->location = cre->location;
4097
4098 /*
4099 * In case of a nested ConvertRowtypeExpr, we can convert the
4100 * leaf row directly to the topmost row format without any
4101 * intermediate conversions. (This works because
4102 * ConvertRowtypeExpr is used only for child->parent
4103 * conversion in inheritance trees, which works by exact match
4104 * of column name, and a column absent in an intermediate
4105 * result can't be present in the final result.)
4106 *
4107 * No need to check more than one level deep, because the
4108 * above recursion will have flattened anything else.
4109 */
4110 if (arg != NULL && IsA(arg, ConvertRowtypeExpr))
4111 {
4113
4114 arg = (Node *) argcre->arg;
4115
4116 /*
4117 * Make sure an outer implicit conversion can't hide an
4118 * inner explicit one.
4119 */
4120 if (newcre->convertformat == COERCE_IMPLICIT_CAST)
4121 newcre->convertformat = argcre->convertformat;
4122 }
4123
4124 newcre->arg = (Expr *) arg;
4125
4126 if (arg != NULL && IsA(arg, Const))
4127 return ece_evaluate_expr((Node *) newcre);
4128 return (Node *) newcre;
4129 }
4130 default:
4131 break;
4132 }
4133
4134 /*
4135 * For any node type not handled above, copy the node unchanged but
4136 * const-simplify its subexpressions. This is the correct thing for node
4137 * types whose behavior might change between planning and execution, such
4138 * as CurrentOfExpr. It's also a safe default for new node types not
4139 * known to this routine.
4140 */
4141 return ece_generic_processing(node);
4142}
4143
4144/*
4145 * Subroutine for eval_const_expressions: check for non-Const nodes.
4146 *
4147 * We can abort recursion immediately on finding a non-Const node. This is
4148 * critical for performance, else eval_const_expressions_mutator would take
4149 * O(N^2) time on non-simplifiable trees. However, we do need to descend
4150 * into List nodes since expression_tree_walker sometimes invokes the walker
4151 * function directly on List subtrees.
4152 */
4153static bool
4154contain_non_const_walker(Node *node, void *context)
4155{
4156 if (node == NULL)
4157 return false;
4158 if (IsA(node, Const))
4159 return false;
4160 if (IsA(node, List))
4161 return expression_tree_walker(node, contain_non_const_walker, context);
4162 /* Otherwise, abort the tree traversal and return true */
4163 return true;
4164}
4165
4166/*
4167 * Subroutine for eval_const_expressions: check if a function is OK to evaluate
4168 */
4169static bool
4171{
4172 char provolatile = func_volatile(funcid);
4173
4174 /*
4175 * Ordinarily we are only allowed to simplify immutable functions. But for
4176 * purposes of estimation, we consider it okay to simplify functions that
4177 * are merely stable; the risk that the result might change from planning
4178 * time to execution time is worth taking in preference to not being able
4179 * to estimate the value at all.
4180 */
4182 return true;
4183 if (context->estimate && provolatile == PROVOLATILE_STABLE)
4184 return true;
4185 return false;
4186}
4187
4188/*
4189 * Subroutine for eval_const_expressions: process arguments of an OR clause
4190 *
4191 * This includes flattening of nested ORs as well as recursion to
4192 * eval_const_expressions to simplify the OR arguments.
4193 *
4194 * After simplification, OR arguments are handled as follows:
4195 * non constant: keep
4196 * FALSE: drop (does not affect result)
4197 * TRUE: force result to TRUE
4198 * NULL: keep only one
4199 * We must keep one NULL input because OR expressions evaluate to NULL when no
4200 * input is TRUE and at least one is NULL. We don't actually include the NULL
4201 * here, that's supposed to be done by the caller.
4202 *
4203 * The output arguments *haveNull and *forceTrue must be initialized false
4204 * by the caller. They will be set true if a NULL constant or TRUE constant,
4205 * respectively, is detected anywhere in the argument list.
4206 */
4207static List *
4210 bool *haveNull, bool *forceTrue)
4211{
4212 List *newargs = NIL;
4214
4215 /*
4216 * We want to ensure that any OR immediately beneath another OR gets
4217 * flattened into a single OR-list, so as to simplify later reasoning.
4218 *
4219 * To avoid stack overflow from recursion of eval_const_expressions, we
4220 * resort to some tenseness here: we keep a list of not-yet-processed
4221 * inputs, and handle flattening of nested ORs by prepending to the to-do
4222 * list instead of recursing. Now that the parser generates N-argument
4223 * ORs from simple lists, this complexity is probably less necessary than
4224 * it once was, but we might as well keep the logic.
4225 */
4227 while (unprocessed_args)
4228 {
4230
4232
4233 /* flatten nested ORs as per above comment */
4234 if (is_orclause(arg))
4235 {
4236 List *subargs = ((BoolExpr *) arg)->args;
4238
4240 /* perhaps-overly-tense code to avoid leaking old lists */
4242 continue;
4243 }
4244
4245 /* If it's not an OR, simplify it */
4247
4248 /*
4249 * It is unlikely but not impossible for simplification of a non-OR
4250 * clause to produce an OR. Recheck, but don't be too tense about it
4251 * since it's not a mainstream case. In particular we don't worry
4252 * about const-simplifying the input twice, nor about list leakage.
4253 */
4254 if (is_orclause(arg))
4255 {
4256 List *subargs = ((BoolExpr *) arg)->args;
4257
4259 continue;
4260 }
4261
4262 /*
4263 * OK, we have a const-simplified non-OR argument. Process it per
4264 * comments above.
4265 */
4266 if (IsA(arg, Const))
4267 {
4268 Const *const_input = (Const *) arg;
4269
4270 if (const_input->constisnull)
4271 *haveNull = true;
4272 else if (DatumGetBool(const_input->constvalue))
4273 {
4274 *forceTrue = true;
4275
4276 /*
4277 * Once we detect a TRUE result we can just exit the loop
4278 * immediately. However, if we ever add a notion of
4279 * non-removable functions, we'd need to keep scanning.
4280 */
4281 return NIL;
4282 }
4283 /* otherwise, we can drop the constant-false input */
4284 continue;
4285 }
4286
4287 /* else emit the simplified arg into the result list */
4289 }
4290
4291 return newargs;
4292}
4293
4294/*
4295 * Subroutine for eval_const_expressions: process arguments of an AND clause
4296 *
4297 * This includes flattening of nested ANDs as well as recursion to
4298 * eval_const_expressions to simplify the AND arguments.
4299 *
4300 * After simplification, AND arguments are handled as follows:
4301 * non constant: keep
4302 * TRUE: drop (does not affect result)
4303 * FALSE: force result to FALSE
4304 * NULL: keep only one
4305 * We must keep one NULL input because AND expressions evaluate to NULL when
4306 * no input is FALSE and at least one is NULL. We don't actually include the
4307 * NULL here, that's supposed to be done by the caller.
4308 *
4309 * The output arguments *haveNull and *forceFalse must be initialized false
4310 * by the caller. They will be set true if a null constant or false constant,
4311 * respectively, is detected anywhere in the argument list.
4312 */
4313static List *
4316 bool *haveNull, bool *forceFalse)
4317{
4318 List *newargs = NIL;
4320
4321 /* See comments in simplify_or_arguments */
4323 while (unprocessed_args)
4324 {
4326
4328
4329 /* flatten nested ANDs as per above comment */
4330 if (is_andclause(arg))
4331 {
4332 List *subargs = ((BoolExpr *) arg)->args;
4334
4336 /* perhaps-overly-tense code to avoid leaking old lists */
4338 continue;
4339 }
4340
4341 /* If it's not an AND, simplify it */
4343
4344 /*
4345 * It is unlikely but not impossible for simplification of a non-AND
4346 * clause to produce an AND. Recheck, but don't be too tense about it
4347 * since it's not a mainstream case. In particular we don't worry
4348 * about const-simplifying the input twice, nor about list leakage.
4349 */
4350 if (is_andclause(arg))
4351 {
4352 List *subargs = ((BoolExpr *) arg)->args;
4353
4355 continue;
4356 }
4357
4358 /*
4359 * OK, we have a const-simplified non-AND argument. Process it per
4360 * comments above.
4361 */
4362 if (IsA(arg, Const))
4363 {
4364 Const *const_input = (Const *) arg;
4365
4366 if (const_input->constisnull)
4367 *haveNull = true;
4368 else if (!DatumGetBool(const_input->constvalue))
4369 {
4370 *forceFalse = true;
4371
4372 /*
4373 * Once we detect a FALSE result we can just exit the loop
4374 * immediately. However, if we ever add a notion of
4375 * non-removable functions, we'd need to keep scanning.
4376 */
4377 return NIL;
4378 }
4379 /* otherwise, we can drop the constant-true input */
4380 continue;
4381 }
4382
4383 /* else emit the simplified arg into the result list */
4385 }
4386
4387 return newargs;
4388}
4389
4390/*
4391 * Subroutine for eval_const_expressions: try to simplify boolean equality
4392 * or inequality condition
4393 *
4394 * Inputs are the operator OID and the simplified arguments to the operator.
4395 * Returns a simplified expression if successful, or NULL if cannot
4396 * simplify the expression.
4397 *
4398 * The idea here is to reduce "x = true" to "x" and "x = false" to "NOT x",
4399 * or similarly "x <> true" to "NOT x" and "x <> false" to "x".
4400 * This is only marginally useful in itself, but doing it in constant folding
4401 * ensures that we will recognize these forms as being equivalent in, for
4402 * example, partial index matching.
4403 *
4404 * We come here only if simplify_function has failed; therefore we cannot
4405 * see two constant inputs, nor a constant-NULL input.
4406 */
4407static Node *
4409{
4410 Node *leftop;
4411 Node *rightop;
4412
4413 Assert(list_length(args) == 2);
4414 leftop = linitial(args);
4415 rightop = lsecond(args);
4416 if (leftop && IsA(leftop, Const))
4417 {
4418 Assert(!((Const *) leftop)->constisnull);
4419 if (opno == BooleanEqualOperator)
4420 {
4421 if (DatumGetBool(((Const *) leftop)->constvalue))
4422 return rightop; /* true = foo */
4423 else
4424 return negate_clause(rightop); /* false = foo */
4425 }
4426 else
4427 {
4428 if (DatumGetBool(((Const *) leftop)->constvalue))
4429 return negate_clause(rightop); /* true <> foo */
4430 else
4431 return rightop; /* false <> foo */
4432 }
4433 }
4434 if (rightop && IsA(rightop, Const))
4435 {
4437 if (opno == BooleanEqualOperator)
4438 {
4440 return leftop; /* foo = true */
4441 else
4442 return negate_clause(leftop); /* foo = false */
4443 }
4444 else
4445 {
4447 return negate_clause(leftop); /* foo <> true */
4448 else
4449 return leftop; /* foo <> false */
4450 }
4451 }
4452 return NULL;
4453}
4454
4455/*
4456 * Subroutine for eval_const_expressions: try to simplify a function call
4457 * (which might originally have been an operator; we don't care)
4458 *
4459 * Inputs are the function OID, actual result type OID (which is needed for
4460 * polymorphic functions), result typmod, result collation, the input
4461 * collation to use for the function, the original argument list (not
4462 * const-simplified yet, unless process_args is false), and some flags;
4463 * also the context data for eval_const_expressions.
4464 *
4465 * Returns a simplified expression if successful, or NULL if cannot
4466 * simplify the function call.
4467 *
4468 * This function is also responsible for converting named-notation argument
4469 * lists into positional notation and/or adding any needed default argument
4470 * expressions; which is a bit grotty, but it avoids extra fetches of the
4471 * function's pg_proc tuple. For this reason, the args list is
4472 * pass-by-reference. Conversion and const-simplification of the args list
4473 * will be done even if simplification of the function call itself is not
4474 * possible.
4475 */
4476static Expr *
4477simplify_function(Oid funcid, Oid result_type, int32 result_typmod,
4479 bool funcvariadic, bool process_args, bool allow_non_const,
4481{
4482 List *args = *args_p;
4485 Expr *newexpr;
4486
4487 /*
4488 * We have three strategies for simplification: execute the function to
4489 * deliver a constant result, use a transform function to generate a
4490 * substitute node tree, or expand in-line the body of the function
4491 * definition (which only works for simple SQL-language functions, but
4492 * that is a common case). Each case needs access to the function's
4493 * pg_proc tuple, so fetch it just once.
4494 *
4495 * Note: the allow_non_const flag suppresses both the second and third
4496 * strategies; so if !allow_non_const, simplify_function can only return a
4497 * Const or NULL. Argument-list rewriting happens anyway, though.
4498 */
4501 elog(ERROR, "cache lookup failed for function %u", funcid);
4503
4504 /*
4505 * Process the function arguments, unless the caller did it already.
4506 *
4507 * Here we must deal with named or defaulted arguments, and then
4508 * recursively apply eval_const_expressions to the whole argument list.
4509 */
4510 if (process_args)
4511 {
4512 args = expand_function_arguments(args, false, result_type, func_tuple);
4515 context);
4516 /* Argument processing done, give it back to the caller */
4517 *args_p = args;
4518 }
4519
4520 /* Now attempt simplification of the function call proper. */
4521
4522 newexpr = evaluate_function(funcid, result_type, result_typmod,
4524 args, funcvariadic,
4525 func_tuple, context);
4526
4527 if (!newexpr && allow_non_const && OidIsValid(func_form->prosupport))
4528 {
4529 /*
4530 * Build a SupportRequestSimplify node to pass to the support
4531 * function, pointing to a dummy FuncExpr node containing the
4532 * simplified arg list. We use this approach to present a uniform
4533 * interface to the support function regardless of how the target
4534 * function is actually being invoked.
4535 */
4538
4539 fexpr.xpr.type = T_FuncExpr;
4540 fexpr.funcid = funcid;
4541 fexpr.funcresulttype = result_type;
4542 fexpr.funcretset = func_form->proretset;
4543 fexpr.funcvariadic = funcvariadic;
4544 fexpr.funcformat = COERCE_EXPLICIT_CALL;
4545 fexpr.funccollid = result_collid;
4546 fexpr.inputcollid = input_collid;
4547 fexpr.args = args;
4548 fexpr.location = -1;
4549
4551 req.root = context->root;
4552 req.fcall = &fexpr;
4553
4554 newexpr = (Expr *)
4556 PointerGetDatum(&req)));
4557
4558 /* catch a possible API misunderstanding */
4559 Assert(newexpr != (Expr *) &fexpr);
4560 }
4561
4562 if (!newexpr && allow_non_const)
4563 newexpr = inline_function(funcid, result_type, result_collid,
4565 func_tuple, context);
4566
4568
4569 return newexpr;
4570}
4571
4572/*
4573 * simplify_aggref
4574 * Call the Aggref.aggfnoid's prosupport function to allow it to
4575 * determine if simplification of the Aggref is possible. Returns the
4576 * newly simplified node if conversion took place; otherwise, returns the
4577 * original Aggref.
4578 *
4579 * See SupportRequestSimplifyAggref comments in supportnodes.h for further
4580 * details.
4581 */
4582static Node *
4584{
4586
4588 {
4590 Node *newnode;
4591
4592 /*
4593 * Build a SupportRequestSimplifyAggref node to pass to the support
4594 * function.
4595 */
4597 req.root = context->root;
4598 req.aggref = aggref;
4599
4601 PointerGetDatum(&req)));
4602
4603 /*
4604 * We expect the support function to return either a new Node or NULL
4605 * (when simplification isn't possible).
4606 */
4607 Assert(newnode != (Node *) aggref || newnode == NULL);
4608
4609 if (newnode != NULL)
4610 return newnode;
4611 }
4612
4613 return (Node *) aggref;
4614}
4615
4616/*
4617 * var_is_nonnullable: check to see if the Var cannot be NULL
4618 *
4619 * If the Var is defined NOT NULL and meanwhile is not nulled by any outer
4620 * joins or grouping sets, then we can know that it cannot be NULL.
4621 *
4622 * "source" specifies where we should look for NOT NULL proofs.
4623 */
4624bool
4626{
4627 Assert(IsA(var, Var));
4628
4629 /* skip upper-level Vars */
4630 if (var->varlevelsup != 0)
4631 return false;
4632
4633 /* could the Var be nulled by any outer joins or grouping sets? */
4634 if (!bms_is_empty(var->varnullingrels))
4635 return false;
4636
4637 /* system columns cannot be NULL */
4638 if (var->varattno < 0)
4639 return true;
4640
4641 /* we don't trust whole-row Vars */
4642 if (var->varattno == 0)
4643 return false;
4644
4645 /* Check if the Var is defined as NOT NULL. */
4646 switch (source)
4647 {
4649 {
4650 /*
4651 * We retrieve the column NOT NULL constraint information from
4652 * the corresponding RelOptInfo.
4653 */
4654 RelOptInfo *rel;
4655 Bitmapset *notnullattnums;
4656
4657 rel = find_base_rel(root, var->varno);
4658 notnullattnums = rel->notnullattnums;
4659
4660 return bms_is_member(var->varattno, notnullattnums);
4661 }
4663 {
4664 /*
4665 * We retrieve the column NOT NULL constraint information from
4666 * the hash table.
4667 */
4669 Bitmapset *notnullattnums;
4670
4671 rte = planner_rt_fetch(var->varno, root);
4672
4673 /* We can only reason about ordinary relations */
4674 if (rte->rtekind != RTE_RELATION)
4675 return false;
4676
4677 /*
4678 * We must skip inheritance parent tables, as some child
4679 * tables may have a NOT NULL constraint for a column while
4680 * others may not. This cannot happen with partitioned
4681 * tables, though.
4682 */
4683 if (rte->inh && rte->relkind != RELKIND_PARTITIONED_TABLE)
4684 return false;
4685
4686 notnullattnums = find_relation_notnullatts(root, rte->relid);
4687
4688 return bms_is_member(var->varattno, notnullattnums);
4689 }
4691 {
4692 /*
4693 * We look up the "attnotnull" field in the attribute
4694 * relation.
4695 */
4697
4698 rte = planner_rt_fetch(var->varno, root);
4699
4700 /* We can only reason about ordinary relations */
4701 if (rte->rtekind != RTE_RELATION)
4702 return false;
4703
4704 /*
4705 * We must skip inheritance parent tables, as some child
4706 * tables may have a NOT NULL constraint for a column while
4707 * others may not. This cannot happen with partitioned
4708 * tables, though.
4709 *
4710 * Note that we need to check if the relation actually has any
4711 * children, as we might not have done that yet.
4712 */
4713 if (rte->inh && has_subclass(rte->relid) &&
4714 rte->relkind != RELKIND_PARTITIONED_TABLE)
4715 return false;
4716
4717 return get_attnotnull(rte->relid, var->varattno);
4718 }
4719 default:
4720 elog(ERROR, "unrecognized NotNullSource: %d",
4721 (int) source);
4722 break;
4723 }
4724
4725 return false;
4726}
4727
4728/*
4729 * expr_is_nonnullable: check to see if the Expr cannot be NULL
4730 *
4731 * Returns true iff the given 'expr' cannot produce SQL NULLs.
4732 *
4733 * source: specifies where we should look for NOT NULL proofs for Vars.
4734 * - NOTNULL_SOURCE_RELOPT: Used when RelOptInfos have been generated. We
4735 * retrieve nullability information directly from the RelOptInfo corresponding
4736 * to the Var.
4737 * - NOTNULL_SOURCE_HASHTABLE: Used when RelOptInfos are not yet available,
4738 * but we have already collected relation-level not-null constraints into the
4739 * global hash table.
4740 * - NOTNULL_SOURCE_SYSCACHE: Used for raw parse trees where neither
4741 * RelOptInfos nor the hash table are available. In this case, we have to
4742 * look up the 'attnotnull' field directly in the system catalogs.
4743 *
4744 * For now, we support only a limited set of expression types. Support for
4745 * additional node types can be added in the future.
4746 */
4747bool
4749{
4750 /* since this function recurses, it could be driven to stack overflow */
4752
4753 switch (nodeTag(expr))
4754 {
4755 case T_Var:
4756 {
4757 if (root)
4758 return var_is_nonnullable(root, (Var *) expr, source);
4759 }
4760 break;
4761 case T_Const:
4762 return !((Const *) expr)->constisnull;
4763 case T_CoalesceExpr:
4764 {
4765 /*
4766 * A CoalesceExpr returns NULL if and only if all its
4767 * arguments are NULL. Therefore, we can determine that a
4768 * CoalesceExpr cannot be NULL if at least one of its
4769 * arguments can be proven non-nullable.
4770 */
4772
4774 {
4776 return true;
4777 }
4778 }
4779 break;
4780 case T_MinMaxExpr:
4781 {
4782 /*
4783 * Like CoalesceExpr, a MinMaxExpr returns NULL only if all
4784 * its arguments evaluate to NULL.
4785 */
4786 MinMaxExpr *minmaxexpr = (MinMaxExpr *) expr;
4787
4789 {
4791 return true;
4792 }
4793 }
4794 break;
4795 case T_CaseExpr:
4796 {
4797 /*
4798 * A CASE expression is non-nullable if all branch results are
4799 * non-nullable. We must also verify that the default result
4800 * (ELSE) exists and is non-nullable.
4801 */
4802 CaseExpr *caseexpr = (CaseExpr *) expr;
4803
4804 /* The default result must be present and non-nullable */
4805 if (caseexpr->defresult == NULL ||
4806 !expr_is_nonnullable(root, caseexpr->defresult, source))
4807 return false;
4808
4809 /* All branch results must be non-nullable */
4811 {
4812 if (!expr_is_nonnullable(root, casewhen->result, source))
4813 return false;
4814 }
4815
4816 return true;
4817 }
4818 break;
4819 case T_ArrayExpr:
4820 {
4821 /*
4822 * An ARRAY[] expression always returns a valid Array object,
4823 * even if it is empty (ARRAY[]) or contains NULLs
4824 * (ARRAY[NULL]). It never evaluates to a SQL NULL.
4825 */
4826 return true;
4827 }
4828 case T_NullTest:
4829 {
4830 /*
4831 * An IS NULL / IS NOT NULL expression always returns a
4832 * boolean value. It never returns SQL NULL.
4833 */
4834 return true;
4835 }
4836 case T_BooleanTest:
4837 {
4838 /*
4839 * A BooleanTest expression always evaluates to a boolean
4840 * value. It never returns SQL NULL.
4841 */
4842 return true;
4843 }
4844 case T_DistinctExpr:
4845 {
4846 /*
4847 * IS DISTINCT FROM never returns NULL, effectively acting as
4848 * though NULL were a normal data value.
4849 */
4850 return true;
4851 }
4852 case T_RelabelType:
4853 {
4854 /*
4855 * RelabelType does not change the nullability of the data.
4856 * The result is non-nullable if and only if the argument is
4857 * non-nullable.
4858 */
4859 return expr_is_nonnullable(root, ((RelabelType *) expr)->arg,
4860 source);
4861 }
4862 default:
4863 break;
4864 }
4865
4866 return false;
4867}
4868
4869/*
4870 * expand_function_arguments: convert named-notation args to positional args
4871 * and/or insert default args, as needed
4872 *
4873 * Returns a possibly-transformed version of the args list.
4874 *
4875 * If include_out_arguments is true, then the args list and the result
4876 * include OUT arguments.
4877 *
4878 * The expected result type of the call must be given, for sanity-checking
4879 * purposes. Also, we ask the caller to provide the function's actual
4880 * pg_proc tuple, not just its OID.
4881 *
4882 * If we need to change anything, the input argument list is copied, not
4883 * modified.
4884 *
4885 * Note: this gets applied to operator argument lists too, even though the
4886 * cases it handles should never occur there. This should be OK since it
4887 * will fall through very quickly if there's nothing to do.
4888 */
4889List *
4891 Oid result_type, HeapTuple func_tuple)
4892{
4894 Oid *proargtypes = funcform->proargtypes.values;
4895 int pronargs = funcform->pronargs;
4896 bool has_named_args = false;
4897 ListCell *lc;
4898
4899 /*
4900 * If we are asked to match to OUT arguments, then use the proallargtypes
4901 * array (which includes those); otherwise use proargtypes (which
4902 * doesn't). Of course, if proallargtypes is null, we always use
4903 * proargtypes. (Fetching proallargtypes is annoyingly expensive
4904 * considering that we may have nothing to do here, but fortunately the
4905 * common case is include_out_arguments == false.)
4906 */
4908 {
4910 bool isNull;
4911
4914 &isNull);
4915 if (!isNull)
4916 {
4918
4919 pronargs = ARR_DIMS(arr)[0];
4920 if (ARR_NDIM(arr) != 1 ||
4921 pronargs < 0 ||
4922 ARR_HASNULL(arr) ||
4923 ARR_ELEMTYPE(arr) != OIDOID)
4924 elog(ERROR, "proallargtypes is not a 1-D Oid array or it contains nulls");
4925 Assert(pronargs >= funcform->pronargs);
4926 proargtypes = (Oid *) ARR_DATA_PTR(arr);
4927 }
4928 }
4929
4930 /* Do we have any named arguments? */
4931 foreach(lc, args)
4932 {
4933 Node *arg = (Node *) lfirst(lc);
4934
4935 if (IsA(arg, NamedArgExpr))
4936 {
4937 has_named_args = true;
4938 break;
4939 }
4940 }
4941
4942 /* If so, we must apply reorder_function_arguments */
4943 if (has_named_args)
4944 {
4946 /* Recheck argument types and add casts if needed */
4947 recheck_cast_function_args(args, result_type,
4949 func_tuple);
4950 }
4951 else if (list_length(args) < pronargs)
4952 {
4953 /* No named args, but we seem to be short some defaults */
4955 /* Recheck argument types and add casts if needed */
4956 recheck_cast_function_args(args, result_type,
4958 func_tuple);
4959 }
4960
4961 return args;
4962}
4963
4964/*
4965 * reorder_function_arguments: convert named-notation args to positional args
4966 *
4967 * This function also inserts default argument values as needed, since it's
4968 * impossible to form a truly valid positional call without that.
4969 */
4970static List *
4972{
4974 int nargsprovided = list_length(args);
4976 ListCell *lc;
4977 int i;
4978
4981 elog(ERROR, "too many function arguments");
4982 memset(argarray, 0, pronargs * sizeof(Node *));
4983
4984 /* Deconstruct the argument list into an array indexed by argnumber */
4985 i = 0;
4986 foreach(lc, args)
4987 {
4988 Node *arg = (Node *) lfirst(lc);
4989
4990 if (!IsA(arg, NamedArgExpr))
4991 {
4992 /* positional argument, assumed to precede all named args */
4993 Assert(argarray[i] == NULL);
4994 argarray[i++] = arg;
4995 }
4996 else
4997 {
4999
5000 Assert(na->argnumber >= 0 && na->argnumber < pronargs);
5001 Assert(argarray[na->argnumber] == NULL);
5002 argarray[na->argnumber] = (Node *) na->arg;
5003 }
5004 }
5005
5006 /*
5007 * Fetch default expressions, if needed, and insert into array at proper
5008 * locations (they aren't necessarily consecutive or all used)
5009 */
5010 if (nargsprovided < pronargs)
5011 {
5013
5014 i = pronargs - funcform->pronargdefaults;
5015 foreach(lc, defaults)
5016 {
5017 if (argarray[i] == NULL)
5018 argarray[i] = (Node *) lfirst(lc);
5019 i++;
5020 }
5021 }
5022
5023 /* Now reconstruct the args list in proper order */
5024 args = NIL;
5025 for (i = 0; i < pronargs; i++)
5026 {
5027 Assert(argarray[i] != NULL);
5028 args = lappend(args, argarray[i]);
5029 }
5030
5031 return args;
5032}
5033
5034/*
5035 * add_function_defaults: add missing function arguments from its defaults
5036 *
5037 * This is used only when the argument list was positional to begin with,
5038 * and so we know we just need to add defaults at the end.
5039 */
5040static List *
5042{
5043 int nargsprovided = list_length(args);
5044 List *defaults;
5045 int ndelete;
5046
5047 /* Get all the default expressions from the pg_proc tuple */
5049
5050 /* Delete any unused defaults from the list */
5051 ndelete = nargsprovided + list_length(defaults) - pronargs;
5052 if (ndelete < 0)
5053 elog(ERROR, "not enough default arguments");
5054 if (ndelete > 0)
5055 defaults = list_delete_first_n(defaults, ndelete);
5056
5057 /* And form the combined argument list, not modifying the input list */
5058 return list_concat_copy(args, defaults);
5059}
5060
5061/*
5062 * fetch_function_defaults: get function's default arguments as expression list
5063 */
5064static List *
5066{
5067 List *defaults;
5069 char *str;
5070
5074 defaults = castNode(List, stringToNode(str));
5075 pfree(str);
5076 return defaults;
5077}
5078
5079/*
5080 * recheck_cast_function_args: recheck function args and typecast as needed
5081 * after adding defaults.
5082 *
5083 * It is possible for some of the defaulted arguments to be polymorphic;
5084 * therefore we can't assume that the default expressions have the correct
5085 * data types already. We have to re-resolve polymorphics and do coercion
5086 * just like the parser did.
5087 *
5088 * This should be a no-op if there are no polymorphic arguments,
5089 * but we do it anyway to be sure.
5090 *
5091 * Note: if any casts are needed, the args list is modified in-place;
5092 * caller should have already copied the list structure.
5093 */
5094static void
5095recheck_cast_function_args(List *args, Oid result_type,
5096 Oid *proargtypes, int pronargs,
5098{
5100 int nargs;
5103 Oid rettype;
5104 ListCell *lc;
5105
5106 if (list_length(args) > FUNC_MAX_ARGS)
5107 elog(ERROR, "too many function arguments");
5108 nargs = 0;
5109 foreach(lc, args)
5110 {
5111 actual_arg_types[nargs++] = exprType((Node *) lfirst(lc));
5112 }
5113 Assert(nargs == pronargs);
5117 nargs,
5118 funcform->prorettype,
5119 false);
5120 /* let's just check we got the same answer as the parser did ... */
5121 if (rettype != result_type)
5122 elog(ERROR, "function's resolved result type changed during planning");
5123
5124 /* perform any necessary typecasting of arguments */
5126}
5127
5128/*
5129 * evaluate_function: try to pre-evaluate a function call
5130 *
5131 * We can do this if the function is strict and has any constant-null inputs
5132 * (just return a null constant), or if the function is immutable and has all
5133 * constant inputs (call it and return the result as a Const node). In
5134 * estimation mode we are willing to pre-evaluate stable functions too.
5135 *
5136 * Returns a simplified expression if successful, or NULL if cannot
5137 * simplify the function.
5138 */
5139static Expr *
5140evaluate_function(Oid funcid, Oid result_type, int32 result_typmod,
5142 bool funcvariadic,
5145{
5147 bool has_nonconst_input = false;
5148 bool has_null_input = false;
5149 ListCell *arg;
5151
5152 /*
5153 * Can't simplify if it returns a set.
5154 */
5155 if (funcform->proretset)
5156 return NULL;
5157
5158 /*
5159 * Can't simplify if it returns RECORD. The immediate problem is that it
5160 * will be needing an expected tupdesc which we can't supply here.
5161 *
5162 * In the case where it has OUT parameters, we could build an expected
5163 * tupdesc from those, but there may be other gotchas lurking. In
5164 * particular, if the function were to return NULL, we would produce a
5165 * null constant with no remaining indication of which concrete record
5166 * type it is. For now, seems best to leave the function call unreduced.
5167 */
5168 if (funcform->prorettype == RECORDOID)
5169 return NULL;
5170
5171 /*
5172 * Check for constant inputs and especially constant-NULL inputs.
5173 */
5174 foreach(arg, args)
5175 {
5176 if (IsA(lfirst(arg), Const))
5178 else
5179 has_nonconst_input = true;
5180 }
5181
5182 /*
5183 * If the function is strict and has a constant-NULL input, it will never
5184 * be called at all, so we can replace the call by a NULL constant, even
5185 * if there are other inputs that aren't constant, and even if the
5186 * function is not otherwise immutable.
5187 */
5188 if (funcform->proisstrict && has_null_input)
5189 return (Expr *) makeNullConst(result_type, result_typmod,
5191
5192 /*
5193 * Otherwise, can simplify only if all inputs are constants. (For a
5194 * non-strict function, constant NULL inputs are treated the same as
5195 * constant non-NULL inputs.)
5196 */
5198 return NULL;
5199
5200 /*
5201 * Ordinarily we are only allowed to simplify immutable functions. But for
5202 * purposes of estimation, we consider it okay to simplify functions that
5203 * are merely stable; the risk that the result might change from planning
5204 * time to execution time is worth taking in preference to not being able
5205 * to estimate the value at all.
5206 */
5207 if (funcform->provolatile == PROVOLATILE_IMMUTABLE)
5208 /* okay */ ;
5209 else if (context->estimate && funcform->provolatile == PROVOLATILE_STABLE)
5210 /* okay */ ;
5211 else
5212 return NULL;
5213
5214 /*
5215 * OK, looks like we can simplify this operator/function.
5216 *
5217 * Build a new FuncExpr node containing the already-simplified arguments.
5218 */
5220 newexpr->funcid = funcid;
5221 newexpr->funcresulttype = result_type;
5222 newexpr->funcretset = false;
5223 newexpr->funcvariadic = funcvariadic;
5224 newexpr->funcformat = COERCE_EXPLICIT_CALL; /* doesn't matter */
5225 newexpr->funccollid = result_collid; /* doesn't matter */
5226 newexpr->inputcollid = input_collid;
5227 newexpr->args = args;
5228 newexpr->location = -1;
5229
5230 return evaluate_expr((Expr *) newexpr, result_type, result_typmod,
5232}
5233
5234/*
5235 * inline_function: try to expand a function call inline
5236 *
5237 * If the function is a sufficiently simple SQL-language function
5238 * (just "SELECT expression"), then we can inline it and avoid the rather
5239 * high per-call overhead of SQL functions. Furthermore, this can expose
5240 * opportunities for constant-folding within the function expression.
5241 *
5242 * We have to beware of some special cases however. A directly or
5243 * indirectly recursive function would cause us to recurse forever,
5244 * so we keep track of which functions we are already expanding and
5245 * do not re-expand them. Also, if a parameter is used more than once
5246 * in the SQL-function body, we require it not to contain any volatile
5247 * functions (volatiles might deliver inconsistent answers) nor to be
5248 * unreasonably expensive to evaluate. The expensiveness check not only
5249 * prevents us from doing multiple evaluations of an expensive parameter
5250 * at runtime, but is a safety value to limit growth of an expression due
5251 * to repeated inlining.
5252 *
5253 * We must also beware of changing the volatility or strictness status of
5254 * functions by inlining them.
5255 *
5256 * Also, at the moment we can't inline functions returning RECORD. This
5257 * doesn't work in the general case because it discards information such
5258 * as OUT-parameter declarations.
5259 *
5260 * Also, context-dependent expression nodes in the argument list are trouble.
5261 *
5262 * Returns a simplified expression if successful, or NULL if cannot
5263 * simplify the function.
5264 */
5265static Expr *
5266inline_function(Oid funcid, Oid result_type, Oid result_collid,
5267 Oid input_collid, List *args,
5268 bool funcvariadic,
5271{
5273 char *src;
5274 Datum tmp;
5275 bool isNull;
5278 inline_error_callback_arg callback_arg;
5280 FuncExpr *fexpr;
5282 TupleDesc rettupdesc;
5283 ParseState *pstate;
5287 Node *newexpr;
5288 int *usecounts;
5289 ListCell *arg;
5290 int i;
5291
5292 /*
5293 * Forget it if the function is not SQL-language or has other showstopper
5294 * properties. (The prokind and nargs checks are just paranoia.)
5295 */
5296 if (funcform->prolang != SQLlanguageId ||
5297 funcform->prokind != PROKIND_FUNCTION ||
5298 funcform->prosecdef ||
5299 funcform->proretset ||
5300 funcform->prorettype == RECORDOID ||
5302 funcform->pronargs != list_length(args))
5303 return NULL;
5304
5305 /* Check for recursive function, and give up trying to expand if so */
5306 if (list_member_oid(context->active_fns, funcid))
5307 return NULL;
5308
5309 /* Check permission to call function (fail later, if not) */
5311 return NULL;
5312
5313 /* Check whether a plugin wants to hook function entry/exit */
5314 if (FmgrHookIsNeeded(funcid))
5315 return NULL;
5316
5317 /*
5318 * Make a temporary memory context, so that we don't leak all the stuff
5319 * that parsing might create.
5320 */
5322 "inline_function",
5325
5326 /*
5327 * We need a dummy FuncExpr node containing the already-simplified
5328 * arguments. (In some cases we don't really need it, but building it is
5329 * cheap enough that it's not worth contortions to avoid.)
5330 */
5332 fexpr->funcid = funcid;
5333 fexpr->funcresulttype = result_type;
5334 fexpr->funcretset = false;
5335 fexpr->funcvariadic = funcvariadic;
5336 fexpr->funcformat = COERCE_EXPLICIT_CALL; /* doesn't matter */
5337 fexpr->funccollid = result_collid; /* doesn't matter */
5338 fexpr->inputcollid = input_collid;
5339 fexpr->args = args;
5340 fexpr->location = -1;
5341
5342 /* Fetch the function body */
5344 src = TextDatumGetCString(tmp);
5345
5346 /*
5347 * Setup error traceback support for ereport(). This is so that we can
5348 * finger the function that bad information came from.
5349 */
5350 callback_arg.proname = NameStr(funcform->proname);
5351 callback_arg.prosrc = src;
5352
5354 sqlerrcontext.arg = &callback_arg;
5357
5358 /* If we have prosqlbody, pay attention to that not prosrc */
5360 func_tuple,
5362 &isNull);
5363 if (!isNull)
5364 {
5365 Node *n;
5366 List *query_list;
5367
5369 if (IsA(n, List))
5370 query_list = linitial_node(List, castNode(List, n));
5371 else
5372 query_list = list_make1(n);
5373 if (list_length(query_list) != 1)
5374 goto fail;
5375 querytree = linitial(query_list);
5376
5377 /*
5378 * Because we'll insist below that the querytree have an empty rtable
5379 * and no sublinks, it cannot have any relation references that need
5380 * to be locked or rewritten. So we can omit those steps.
5381 */
5382 }
5383 else
5384 {
5385 /* Set up to handle parameters while parsing the function body. */
5387 (Node *) fexpr,
5388 input_collid);
5389
5390 /*
5391 * We just do parsing and parse analysis, not rewriting, because
5392 * rewriting will not affect table-free-SELECT-only queries, which is
5393 * all that we care about. Also, we can punt as soon as we detect
5394 * more than one command in the function body.
5395 */
5398 goto fail;
5399
5400 pstate = make_parsestate(NULL);
5401 pstate->p_sourcetext = src;
5402 sql_fn_parser_setup(pstate, pinfo);
5403
5405
5406 free_parsestate(pstate);
5407 }
5408
5409 /*
5410 * The single command must be a simple "SELECT expression".
5411 *
5412 * Note: if you change the tests involved in this, see also plpgsql's
5413 * exec_simple_check_plan(). That generally needs to have the same idea
5414 * of what's a "simple expression", so that inlining a function that
5415 * previously wasn't inlined won't change plpgsql's conclusion.
5416 */
5417 if (!IsA(querytree, Query) ||
5418 querytree->commandType != CMD_SELECT ||
5419 querytree->hasAggs ||
5420 querytree->hasWindowFuncs ||
5421 querytree->hasTargetSRFs ||
5422 querytree->hasSubLinks ||
5423 querytree->cteList ||
5424 querytree->rtable ||
5425 querytree->jointree->fromlist ||
5426 querytree->jointree->quals ||
5427 querytree->groupClause ||
5428 querytree->groupingSets ||
5429 querytree->havingQual ||
5430 querytree->windowClause ||
5431 querytree->distinctClause ||
5432 querytree->sortClause ||
5433 querytree->limitOffset ||
5434 querytree->limitCount ||
5435 querytree->setOperations ||
5436 list_length(querytree->targetList) != 1)
5437 goto fail;
5438
5439 /* If the function result is composite, resolve it */
5441 NULL,
5442 &rettupdesc);
5443
5444 /*
5445 * Make sure the function (still) returns what it's declared to. This
5446 * will raise an error if wrong, but that's okay since the function would
5447 * fail at runtime anyway. Note that check_sql_fn_retval will also insert
5448 * a coercion if needed to make the tlist expression match the declared
5449 * type of the function.
5450 *
5451 * Note: we do not try this until we have verified that no rewriting was
5452 * needed; that's probably not important, but let's be careful.
5453 */
5456 result_type, rettupdesc,
5457 funcform->prokind,
5458 false))
5459 goto fail; /* reject whole-tuple-result cases */
5460
5461 /*
5462 * Given the tests above, check_sql_fn_retval shouldn't have decided to
5463 * inject a projection step, but let's just make sure.
5464 */
5466 goto fail;
5467
5468 /* Now we can grab the tlist expression */
5469 newexpr = (Node *) ((TargetEntry *) linitial(querytree->targetList))->expr;
5470
5471 /*
5472 * If the SQL function returns VOID, we can only inline it if it is a
5473 * SELECT of an expression returning VOID (ie, it's just a redirection to
5474 * another VOID-returning function). In all non-VOID-returning cases,
5475 * check_sql_fn_retval should ensure that newexpr returns the function's
5476 * declared result type, so this test shouldn't fail otherwise; but we may
5477 * as well cope gracefully if it does.
5478 */
5479 if (exprType(newexpr) != result_type)
5480 goto fail;
5481
5482 /*
5483 * Additional validity checks on the expression. It mustn't be more
5484 * volatile than the surrounding function (this is to avoid breaking hacks
5485 * that involve pretending a function is immutable when it really ain't).
5486 * If the surrounding function is declared strict, then the expression
5487 * must contain only strict constructs and must use all of the function
5488 * parameters (this is overkill, but an exact analysis is hard).
5489 */
5490 if (funcform->provolatile == PROVOLATILE_IMMUTABLE &&
5492 goto fail;
5493 else if (funcform->provolatile == PROVOLATILE_STABLE &&
5495 goto fail;
5496
5497 if (funcform->proisstrict &&
5499 goto fail;
5500
5501 /*
5502 * If any parameter expression contains a context-dependent node, we can't
5503 * inline, for fear of putting such a node into the wrong context.
5504 */
5506 goto fail;
5507
5508 /*
5509 * We may be able to do it; there are still checks on parameter usage to
5510 * make, but those are most easily done in combination with the actual
5511 * substitution of the inputs. So start building expression with inputs
5512 * substituted.
5513 */
5514 usecounts = (int *) palloc0(funcform->pronargs * sizeof(int));
5516 args, usecounts);
5517
5518 /* Now check for parameter usage */
5519 i = 0;
5520 foreach(arg, args)
5521 {
5522 Node *param = lfirst(arg);
5523
5524 if (usecounts[i] == 0)
5525 {
5526 /* Param not used at all: uncool if func is strict */
5527 if (funcform->proisstrict)
5528 goto fail;
5529 }
5530 else if (usecounts[i] != 1)
5531 {
5532 /* Param used multiple times: uncool if expensive or volatile */
5534
5535 /*
5536 * We define "expensive" as "contains any subplan or more than 10
5537 * operators". Note that the subplan search has to be done
5538 * explicitly, since cost_qual_eval() will barf on unplanned
5539 * subselects.
5540 */
5541 if (contain_subplans(param))
5542 goto fail;
5544 if (eval_cost.startup + eval_cost.per_tuple >
5545 10 * cpu_operator_cost)
5546 goto fail;
5547
5548 /*
5549 * Check volatility last since this is more expensive than the
5550 * above tests
5551 */
5552 if (contain_volatile_functions(param))
5553 goto fail;
5554 }
5555 i++;
5556 }
5557
5558 /*
5559 * Whew --- we can make the substitution. Copy the modified expression
5560 * out of the temporary memory context, and clean up.
5561 */
5563
5565
5567
5568 /*
5569 * If the result is of a collatable type, force the result to expose the
5570 * correct collation. In most cases this does not matter, but it's
5571 * possible that the function result is used directly as a sort key or in
5572 * other places where we expect exprCollation() to tell the truth.
5573 */
5575 {
5577
5579 {
5581
5582 newnode->arg = (Expr *) newexpr;
5583 newnode->collOid = result_collid;
5584 newnode->location = -1;
5585
5586 newexpr = (Node *) newnode;
5587 }
5588 }
5589
5590 /*
5591 * Since there is now no trace of the function in the plan tree, we must
5592 * explicitly record the plan's dependency on the function.
5593 */
5594 if (context->root)
5595 record_plan_function_dependency(context->root, funcid);
5596
5597 /*
5598 * Recursively try to simplify the modified expression. Here we must add
5599 * the current function to the context list of active functions.
5600 */
5601 context->active_fns = lappend_oid(context->active_fns, funcid);
5603 context->active_fns = list_delete_last(context->active_fns);
5604
5606
5607 return (Expr *) newexpr;
5608
5609 /* Here if func is not inlinable: release temp memory and return NULL */
5610fail:
5614
5615 return NULL;
5616}
5617
5618/*
5619 * Replace Param nodes by appropriate actual parameters
5620 */
5621static Node *
5622substitute_actual_parameters(Node *expr, int nargs, List *args,
5623 int *usecounts)
5624{
5626
5627 context.nargs = nargs;
5628 context.args = args;
5629 context.usecounts = usecounts;
5630
5631 return substitute_actual_parameters_mutator(expr, &context);
5632}
5633
5634static Node *
5637{
5638 if (node == NULL)
5639 return NULL;
5640 if (IsA(node, Param))
5641 {
5642 Param *param = (Param *) node;
5643
5644 if (param->paramkind != PARAM_EXTERN)
5645 elog(ERROR, "unexpected paramkind: %d", (int) param->paramkind);
5646 if (param->paramid <= 0 || param->paramid > context->nargs)
5647 elog(ERROR, "invalid paramid: %d", param->paramid);
5648
5649 /* Count usage of parameter */
5650 context->usecounts[param->paramid - 1]++;
5651
5652 /* Select the appropriate actual arg and replace the Param with it */
5653 /* We don't need to copy at this time (it'll get done later) */
5654 return list_nth(context->args, param->paramid - 1);
5655 }
5657}
5658
5659/*
5660 * error context callback to let us supply a call-stack traceback
5661 */
5662static void
5664{
5667
5668 /* If it's a syntax error, convert to internal syntax error report */
5670 if (syntaxerrposition > 0)
5671 {
5672 errposition(0);
5674 internalerrquery(callback_arg->prosrc);
5675 }
5676
5677 errcontext("SQL function \"%s\" during inlining", callback_arg->proname);
5678}
5679
5680/*
5681 * evaluate_expr: pre-evaluate a constant expression
5682 *
5683 * We use the executor's routine ExecEvalExpr() to avoid duplication of
5684 * code and ensure we get the same result as the executor would get.
5685 */
5686Expr *
5687evaluate_expr(Expr *expr, Oid result_type, int32 result_typmod,
5689{
5690 EState *estate;
5691 ExprState *exprstate;
5692 MemoryContext oldcontext;
5694 bool const_is_null;
5696 bool resultTypByVal;
5697
5698 /*
5699 * To use the executor, we need an EState.
5700 */
5701 estate = CreateExecutorState();
5702
5703 /* We can use the estate's working context to avoid memory leaks. */
5704 oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
5705
5706 /* Make sure any opfuncids are filled in. */
5707 fix_opfuncids((Node *) expr);
5708
5709 /*
5710 * Prepare expr for execution. (Note: we can't use ExecPrepareExpr
5711 * because it'd result in recursively invoking eval_const_expressions.)
5712 */
5713 exprstate = ExecInitExpr(expr, NULL);
5714
5715 /*
5716 * And evaluate it.
5717 *
5718 * It is OK to use a default econtext because none of the ExecEvalExpr()
5719 * code used in this situation will use econtext. That might seem
5720 * fortuitous, but it's not so unreasonable --- a constant expression does
5721 * not depend on context, by definition, n'est ce pas?
5722 */
5724 GetPerTupleExprContext(estate),
5725 &const_is_null);
5726
5727 /* Get info needed about result datatype */
5729
5730 /* Get back to outer memory context */
5731 MemoryContextSwitchTo(oldcontext);
5732
5733 /*
5734 * Must copy result out of sub-context used by expression eval.
5735 *
5736 * Also, if it's varlena, forcibly detoast it. This protects us against
5737 * storing TOAST pointers into plans that might outlive the referenced
5738 * data. (makeConst would handle detoasting anyway, but it's worth a few
5739 * extra lines here so that we can do the copy and detoast in one step.)
5740 */
5741 if (!const_is_null)
5742 {
5743 if (resultTypLen == -1)
5745 else
5747 }
5748
5749 /* Release all the junk we just created */
5750 FreeExecutorState(estate);
5751
5752 /*
5753 * Make the constant result node.
5754 */
5755 return (Expr *) makeConst(result_type, result_typmod, result_collation,
5759}
5760
5761
5762/*
5763 * inline_function_in_from
5764 * Attempt to "inline" a function in the FROM clause.
5765 *
5766 * "rte" is an RTE_FUNCTION rangetable entry. If it represents a call of a
5767 * function that can be inlined, expand the function and return the
5768 * substitute Query structure. Otherwise, return NULL.
5769 *
5770 * We assume that the RTE's expression has already been put through
5771 * eval_const_expressions(), which among other things will take care of
5772 * default arguments and named-argument notation.
5773 *
5774 * This has a good deal of similarity to inline_function(), but that's
5775 * for the general-expression case, and there are enough differences to
5776 * justify separate functions.
5777 */
5778Query *
5780{
5781 RangeTblFunction *rtfunc;
5782 FuncExpr *fexpr;
5783 Oid func_oid;
5788 Datum tmp;
5789 char *src;
5790 inline_error_callback_arg callback_arg;
5792 Query *querytree = NULL;
5793
5794 Assert(rte->rtekind == RTE_FUNCTION);
5795
5796 /*
5797 * Guard against infinite recursion during expansion by checking for stack
5798 * overflow. (There's no need to do more.)
5799 */
5801
5802 /* Fail if the RTE has ORDINALITY - we don't implement that here. */
5803 if (rte->funcordinality)
5804 return NULL;
5805
5806 /* Fail if RTE isn't a single, simple FuncExpr */
5807 if (list_length(rte->functions) != 1)
5808 return NULL;
5809 rtfunc = (RangeTblFunction *) linitial(rte->functions);
5810
5811 if (!IsA(rtfunc->funcexpr, FuncExpr))
5812 return NULL;
5813 fexpr = (FuncExpr *) rtfunc->funcexpr;
5814
5815 func_oid = fexpr->funcid;
5816
5817 /*
5818 * Refuse to inline if the arguments contain any volatile functions or
5819 * sub-selects. Volatile functions are rejected because inlining may
5820 * result in the arguments being evaluated multiple times, risking a
5821 * change in behavior. Sub-selects are rejected partly for implementation
5822 * reasons (pushing them down another level might change their behavior)
5823 * and partly because they're likely to be expensive and so multiple
5824 * evaluation would be bad.
5825 */
5826 if (contain_volatile_functions((Node *) fexpr->args) ||
5827 contain_subplans((Node *) fexpr->args))
5828 return NULL;
5829
5830 /* Check permission to call function (fail later, if not) */
5832 return NULL;
5833
5834 /* Check whether a plugin wants to hook function entry/exit */
5836 return NULL;
5837
5838 /*
5839 * OK, let's take a look at the function's pg_proc entry.
5840 */
5843 elog(ERROR, "cache lookup failed for function %u", func_oid);
5845
5846 /*
5847 * If the function SETs any configuration parameters, inlining would cause
5848 * us to miss making those changes.
5849 */
5851 {
5853 return NULL;
5854 }
5855
5856 /*
5857 * Make a temporary memory context, so that we don't leak all the stuff
5858 * that parsing and rewriting might create. If we succeed, we'll copy
5859 * just the finished query tree back up to the caller's context.
5860 */
5862 "inline_function_in_from",
5865
5866 /* Fetch the function body */
5868 src = TextDatumGetCString(tmp);
5869
5870 /*
5871 * If the function has an attached support function that can handle
5872 * SupportRequestInlineInFrom, then attempt to inline with that.
5873 */
5874 if (funcform->prosupport)
5875 {
5877
5879 req.root = root;
5880 req.rtfunc = rtfunc;
5881 req.proc = func_tuple;
5882
5883 querytree = (Query *)
5885 PointerGetDatum(&req)));
5886 }
5887
5888 /*
5889 * Setup error traceback support for ereport(). This is so that we can
5890 * finger the function that bad information came from. We don't install
5891 * this while running the support function, since it'd be likely to do the
5892 * wrong thing: any parse errors reported during that are very likely not
5893 * against the raw function source text.
5894 */
5895 callback_arg.proname = NameStr(funcform->proname);
5896 callback_arg.prosrc = src;
5897
5899 sqlerrcontext.arg = &callback_arg;
5902
5903 /*
5904 * If SupportRequestInlineInFrom didn't work, try our built-in inlining
5905 * mechanism.
5906 */
5907 if (!querytree)
5909 func_tuple, funcform, src);
5910
5911 if (!querytree)
5912 goto fail; /* no luck there either, fail */
5913
5914 /*
5915 * The result had better be a SELECT Query.
5916 */
5918 Assert(querytree->commandType == CMD_SELECT);
5919
5920 /*
5921 * Looks good --- substitute parameters into the query.
5922 */
5924 funcform->pronargs,
5925 fexpr->args);
5926
5927 /*
5928 * Copy the modified query out of the temporary memory context, and clean
5929 * up.
5930 */
5932
5934
5938
5939 /*
5940 * We don't have to fix collations here because the upper query is already
5941 * parsed, ie, the collations in the RTE are what count.
5942 */
5943
5944 /*
5945 * Since there is now no trace of the function in the plan tree, we must
5946 * explicitly record the plan's dependency on the function.
5947 */
5949
5950 /*
5951 * We must also notice if the inserted query adds a dependency on the
5952 * calling role due to RLS quals.
5953 */
5954 if (querytree->hasRowSecurity)
5955 root->glob->dependsOnRole = true;
5956
5957 return querytree;
5958
5959 /* Here if func is not inlinable: release temp memory and return NULL */
5960fail:
5965
5966 return NULL;
5967}
5968
5969/*
5970 * inline_sql_function_in_from
5971 *
5972 * This implements inline_function_in_from for SQL-language functions.
5973 * Returns NULL if the function couldn't be inlined.
5974 *
5975 * The division of labor between here and inline_function_in_from is based
5976 * on the rule that inline_function_in_from should make all checks that are
5977 * certain to be required in both this case and the support-function case.
5978 * Support functions might also want to make checks analogous to the ones
5979 * made here, but then again they might not, or they might just assume that
5980 * the function they are attached to can validly be inlined.
5981 */
5982static Query *
5984 RangeTblFunction *rtfunc,
5985 FuncExpr *fexpr,
5988 const char *src)
5989{
5990 Datum sqlbody;
5991 bool isNull;
5995 TupleDesc rettupdesc;
5996
5997 /*
5998 * The function must be declared to return a set, else inlining would
5999 * change the results if the contained SELECT didn't return exactly one
6000 * row.
6001 */
6002 if (!fexpr->funcretset)
6003 return NULL;
6004
6005 /*
6006 * Forget it if the function is not SQL-language or has other showstopper
6007 * properties. In particular it mustn't be declared STRICT, since we
6008 * couldn't enforce that. It also mustn't be VOLATILE, because that is
6009 * supposed to cause it to be executed with its own snapshot, rather than
6010 * sharing the snapshot of the calling query. We also disallow returning
6011 * SETOF VOID, because inlining would result in exposing the actual result
6012 * of the function's last SELECT, which should not happen in that case.
6013 * (Rechecking prokind, proretset, and pronargs is just paranoia.)
6014 */
6015 if (funcform->prolang != SQLlanguageId ||
6016 funcform->prokind != PROKIND_FUNCTION ||
6017 funcform->proisstrict ||
6018 funcform->provolatile == PROVOLATILE_VOLATILE ||
6019 funcform->prorettype == VOIDOID ||
6020 funcform->prosecdef ||
6021 !funcform->proretset ||
6022 list_length(fexpr->args) != funcform->pronargs)
6023 return NULL;
6024
6025 /* If we have prosqlbody, pay attention to that not prosrc */
6027 func_tuple,
6029 &isNull);
6030 if (!isNull)
6031 {
6032 Node *n;
6033
6035 if (IsA(n, List))
6037 else
6039 if (list_length(querytree_list) != 1)
6040 return NULL;
6042
6043 /* Acquire necessary locks, then apply rewriter. */
6044 AcquireRewriteLocks(querytree, true, false);
6046 if (list_length(querytree_list) != 1)
6047 return NULL;
6049 }
6050 else
6051 {
6054
6055 /*
6056 * Set up to handle parameters while parsing the function body. We
6057 * can use the FuncExpr just created as the input for
6058 * prepare_sql_fn_parse_info.
6059 */
6061 (Node *) fexpr,
6062 fexpr->inputcollid);
6063
6064 /*
6065 * Parse, analyze, and rewrite (unlike inline_function(), we can't
6066 * skip rewriting here). We can fail as soon as we find more than one
6067 * query, though.
6068 */
6071 return NULL;
6072
6074 src,
6076 pinfo, NULL);
6077 if (list_length(querytree_list) != 1)
6078 return NULL;
6080 }
6081
6082 /*
6083 * Also resolve the actual function result tupdesc, if composite. If we
6084 * have a coldeflist, believe that; otherwise use get_expr_result_type.
6085 * (This logic should match ExecInitFunctionScan.)
6086 */
6087 if (rtfunc->funccolnames != NIL)
6088 {
6090 rettupdesc = BuildDescFromLists(rtfunc->funccolnames,
6091 rtfunc->funccoltypes,
6092 rtfunc->funccoltypmods,
6093 rtfunc->funccolcollations);
6094 }
6095 else
6096 functypclass = get_expr_result_type((Node *) fexpr, NULL, &rettupdesc);
6097
6098 /*
6099 * The single command must be a plain SELECT.
6100 */
6101 if (!IsA(querytree, Query) ||
6102 querytree->commandType != CMD_SELECT)
6103 return NULL;
6104
6105 /*
6106 * Make sure the function (still) returns what it's declared to. This
6107 * will raise an error if wrong, but that's okay since the function would
6108 * fail at runtime anyway. Note that check_sql_fn_retval will also insert
6109 * coercions if needed to make the tlist expression(s) match the declared
6110 * type of the function. We also ask it to insert dummy NULL columns for
6111 * any dropped columns in rettupdesc, so that the elements of the modified
6112 * tlist match up to the attribute numbers.
6113 *
6114 * If the function returns a composite type, don't inline unless the check
6115 * shows it's returning a whole tuple result; otherwise what it's
6116 * returning is a single composite column which is not what we need.
6117 */
6119 fexpr->funcresulttype, rettupdesc,
6120 funcform->prokind,
6121 true) &&
6125 return NULL; /* reject not-whole-tuple-result cases */
6126
6127 /*
6128 * check_sql_fn_retval might've inserted a projection step, but that's
6129 * fine; just make sure we use the upper Query.
6130 */
6132
6133 return querytree;
6134}
6135
6136/*
6137 * Replace Param nodes by appropriate actual parameters
6138 *
6139 * This is just enough different from substitute_actual_parameters()
6140 * that it needs its own code.
6141 */
6142static Query *
6143substitute_actual_parameters_in_from(Query *expr, int nargs, List *args)
6144{
6146
6147 context.nargs = nargs;
6148 context.args = args;
6149 context.sublevels_up = 1;
6150
6151 return query_tree_mutator(expr,
6153 &context,
6154 0);
6155}
6156
6157static Node *
6160{
6161 Node *result;
6162
6163 if (node == NULL)
6164 return NULL;
6165 if (IsA(node, Query))
6166 {
6167 context->sublevels_up++;
6168 result = (Node *) query_tree_mutator((Query *) node,
6170 context,
6171 0);
6172 context->sublevels_up--;
6173 return result;
6174 }
6175 if (IsA(node, Param))
6176 {
6177 Param *param = (Param *) node;
6178
6179 if (param->paramkind == PARAM_EXTERN)
6180 {
6181 if (param->paramid <= 0 || param->paramid > context->nargs)
6182 elog(ERROR, "invalid paramid: %d", param->paramid);
6183
6184 /*
6185 * Since the parameter is being inserted into a subquery, we must
6186 * adjust levels.
6187 */
6188 result = copyObject(list_nth(context->args, param->paramid - 1));
6189 IncrementVarSublevelsUp(result, context->sublevels_up, 0);
6190 return result;
6191 }
6192 }
6193 return expression_tree_mutator(node,
6195 context);
6196}
6197
6198/*
6199 * pull_paramids
6200 * Returns a Bitmapset containing the paramids of all Params in 'expr'.
6201 */
6202Bitmapset *
6203pull_paramids(Expr *expr)
6204{
6205 Bitmapset *result = NULL;
6206
6207 (void) pull_paramids_walker((Node *) expr, &result);
6208
6209 return result;
6210}
6211
6212static bool
6213pull_paramids_walker(Node *node, Bitmapset **context)
6214{
6215 if (node == NULL)
6216 return false;
6217 if (IsA(node, Param))
6218 {
6219 Param *param = (Param *) node;
6220
6221 *context = bms_add_member(*context, param->paramid);
6222 return false;
6223 }
6224 return expression_tree_walker(node, pull_paramids_walker, context);
6225}
6226
6227/*
6228 * Build ScalarArrayOpExpr on top of 'exprs.' 'haveNonConst' indicates
6229 * whether at least one of the expressions is not Const. When it's false,
6230 * the array constant is built directly; otherwise, we have to build a child
6231 * ArrayExpr. The 'exprs' list gets freed if not directly used in the output
6232 * expression tree.
6233 */
6236 Oid inputcollid, List *exprs, bool haveNonConst)
6237{
6238 Node *arrayNode = NULL;
6240 Oid arraytype = get_array_type(coltype);
6241
6242 if (!OidIsValid(arraytype))
6243 return NULL;
6244
6245 /*
6246 * Assemble an array from the list of constants. It seems more profitable
6247 * to build a const array. But in the presence of other nodes, we don't
6248 * have a specific value here and must employ an ArrayExpr instead.
6249 */
6250 if (haveNonConst)
6251 {
6253
6254 /* array_collid will be set by parse_collate.c */
6255 arrayExpr->element_typeid = coltype;
6256 arrayExpr->array_typeid = arraytype;
6257 arrayExpr->multidims = false;
6258 arrayExpr->elements = exprs;
6259 arrayExpr->location = -1;
6260
6261 arrayNode = (Node *) arrayExpr;
6262 }
6263 else
6264 {
6265 int16 typlen;
6266 bool typbyval;
6267 char typalign;
6268 Datum *elems;
6269 bool *nulls;
6270 int i = 0;
6272 int dims[1] = {list_length(exprs)};
6273 int lbs[1] = {1};
6274
6275 get_typlenbyvalalign(coltype, &typlen, &typbyval, &typalign);
6276
6277 elems = palloc_array(Datum, list_length(exprs));
6278 nulls = palloc_array(bool, list_length(exprs));
6279 foreach_node(Const, value, exprs)
6280 {
6281 elems[i] = value->constvalue;
6282 nulls[i++] = value->constisnull;
6283 }
6284
6285 arrayConst = construct_md_array(elems, nulls, 1, dims, lbs,
6286 coltype, typlen, typbyval, typalign);
6289 false, false);
6290
6291 pfree(elems);
6292 pfree(nulls);
6293 list_free(exprs);
6294 }
6295
6296 /* Build the SAOP expression node */
6298 saopexpr->opno = oper;
6299 saopexpr->opfuncid = get_opcode(oper);
6300 saopexpr->hashfuncid = InvalidOid;
6301 saopexpr->negfuncid = InvalidOid;
6302 saopexpr->useOr = true;
6303 saopexpr->inputcollid = inputcollid;
6305 saopexpr->location = -1;
6306
6307 return saopexpr;
6308}
Datum querytree(PG_FUNCTION_ARGS)
Definition _int_bool.c:665
@ ACLCHECK_OK
Definition acl.h:183
AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)
Definition aclchk.c:3854
#define ARR_NDIM(a)
Definition array.h:290
#define ARR_DATA_PTR(a)
Definition array.h:322
#define DatumGetArrayTypeP(X)
Definition array.h:261
#define ARR_ELEMTYPE(a)
Definition array.h:292
#define ARR_DIMS(a)
Definition array.h:294
#define ARR_HASNULL(a)
Definition array.h:291
ArrayType * construct_md_array(Datum *elems, bool *nulls, int ndims, int *dims, int *lbs, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
#define InvalidAttrNumber
Definition attnum.h:23
bool bms_is_member(int x, const Bitmapset *a)
Definition bitmapset.c:510
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition bitmapset.c:799
#define bms_is_empty(a)
Definition bitmapset.h:118
#define TextDatumGetCString(d)
Definition builtins.h:99
#define NameStr(name)
Definition c.h:807
#define Assert(condition)
Definition c.h:915
int16_t int16
Definition c.h:583
int32_t int32
Definition c.h:584
#define OidIsValid(objectId)
Definition c.h:830
static List * simplify_or_arguments(List *args, eval_const_expressions_context *context, bool *haveNull, bool *forceTrue)
Definition clauses.c:4209
static bool rowtype_field_matches(Oid rowtypeid, int fieldnum, Oid expectedtype, int32 expectedtypmod, Oid expectedcollation)
Definition clauses.c:2429
Query * inline_function_in_from(PlannerInfo *root, RangeTblEntry *rte)
Definition clauses.c:5780
static List * add_function_defaults(List *args, int pronargs, HeapTuple func_tuple)
Definition clauses.c:5042
#define ece_all_arguments_const(node)
Definition clauses.c:2670
#define ece_evaluate_expr(node)
Definition clauses.c:2674
bool contain_mutable_functions(Node *clause)
Definition clauses.c:381
#define ece_generic_processing(node)
Definition clauses.c:2661
static Expr * evaluate_function(Oid funcid, Oid result_type, int32 result_typmod, Oid result_collid, Oid input_collid, List *args, bool funcvariadic, HeapTuple func_tuple, eval_const_expressions_context *context)
Definition clauses.c:5141
static Node * substitute_actual_parameters_mutator(Node *node, substitute_actual_parameters_context *context)
Definition clauses.c:5636
static bool ece_function_is_safe(Oid funcid, eval_const_expressions_context *context)
Definition clauses.c:4171
static List * simplify_and_arguments(List *args, eval_const_expressions_context *context, bool *haveNull, bool *forceFalse)
Definition clauses.c:4315
static Expr * simplify_function(Oid funcid, Oid result_type, int32 result_typmod, Oid result_collid, Oid input_collid, List **args_p, bool funcvariadic, bool process_args, bool allow_non_const, eval_const_expressions_context *context)
Definition clauses.c:4478
static Expr * inline_function(Oid funcid, Oid result_type, Oid result_collid, Oid input_collid, List *args, bool funcvariadic, HeapTuple func_tuple, eval_const_expressions_context *context)
Definition clauses.c:5267
static List * reorder_function_arguments(List *args, int pronargs, HeapTuple func_tuple)
Definition clauses.c:4972
static Node * simplify_aggref(Aggref *aggref, eval_const_expressions_context *context)
Definition clauses.c:4584
static Node * substitute_actual_parameters(Node *expr, int nargs, List *args, int *usecounts)
Definition clauses.c:5623
static Query * substitute_actual_parameters_in_from(Query *expr, int nargs, List *args)
Definition clauses.c:6144
bool expr_is_nonnullable(PlannerInfo *root, Expr *expr, NotNullSource source)
Definition clauses.c:4749
static void sql_inline_error_callback(void *arg)
Definition clauses.c:5664
static bool contain_non_const_walker(Node *node, void *context)
Definition clauses.c:4155
static bool contain_context_dependent_node(Node *clause)
Definition clauses.c:1192
static void recheck_cast_function_args(List *args, Oid result_type, Oid *proargtypes, int pronargs, HeapTuple func_tuple)
Definition clauses.c:5096
List * expand_function_arguments(List *args, bool include_out_arguments, Oid result_type, HeapTuple func_tuple)
Definition clauses.c:4891
bool contain_nonstrict_functions(Node *clause)
Definition clauses.c:1004
static Node * substitute_actual_parameters_in_from_mutator(Node *node, substitute_actual_parameters_in_from_context *context)
Definition clauses.c:6159
static Query * inline_sql_function_in_from(PlannerInfo *root, RangeTblFunction *rtfunc, FuncExpr *fexpr, HeapTuple func_tuple, Form_pg_proc funcform, const char *src)
Definition clauses.c:5984
bool contain_subplans(Node *clause)
Definition clauses.c:341
static Node * simplify_boolean_equality(Oid opno, List *args)
Definition clauses.c:4409
Bitmapset * pull_paramids(Expr *expr)
Definition clauses.c:6204
ScalarArrayOpExpr * make_SAOP_expr(Oid oper, Node *leftexpr, Oid coltype, Oid arraycollid, Oid inputcollid, List *exprs, bool haveNonConst)
Definition clauses.c:6236
bool var_is_nonnullable(PlannerInfo *root, Var *var, NotNullSource source)
Definition clauses.c:4626
static Node * eval_const_expressions_mutator(Node *node, eval_const_expressions_context *context)
Definition clauses.c:2684
static bool pull_paramids_walker(Node *node, Bitmapset **context)
Definition clauses.c:6214
Expr * evaluate_expr(Expr *expr, Oid result_type, int32 result_typmod, Oid result_collation)
Definition clauses.c:5688
static List * fetch_function_defaults(HeapTuple func_tuple)
Definition clauses.c:5066
bool contain_volatile_functions(Node *clause)
Definition clauses.c:549
double cpu_operator_cost
Definition costsize.c:134
void cost_qual_eval(QualCost *cost, List *quals, PlannerInfo *root)
Definition costsize.c:4898
Datum datumCopy(Datum value, bool typByVal, int typLen)
Definition datum.c:132
Datum arg
Definition elog.c:1322
ErrorContextCallback * error_context_stack
Definition elog.c:99
#define errcontext
Definition elog.h:198
int internalerrquery(const char *query)
int internalerrposition(int cursorpos)
#define ERROR
Definition elog.h:39
int geterrposition(void)
#define elog(elevel,...)
Definition elog.h:226
int errposition(int cursorpos)
ExprState * ExecInitExpr(Expr *node, PlanState *parent)
Definition execExpr.c:143
void FreeExecutorState(EState *estate)
Definition execUtils.c:192
EState * CreateExecutorState(void)
Definition execUtils.c:88
#define GetPerTupleExprContext(estate)
Definition executor.h:656
static Datum ExecEvalExprSwitchContext(ExprState *state, ExprContext *econtext, bool *isNull)
Definition executor.h:436
#define palloc_array(type, count)
Definition fe_memutils.h:76
#define OidFunctionCall1(functionId, arg1)
Definition fmgr.h:722
#define PG_DETOAST_DATUM_COPY(datum)
Definition fmgr.h:242
#define FmgrHookIsNeeded(fn_oid)
Definition fmgr.h:850
TypeFuncClass get_expr_result_type(Node *expr, Oid *resultTypeId, TupleDesc *resultTupleDesc)
Definition funcapi.c:299
TypeFuncClass
Definition funcapi.h:147
@ TYPEFUNC_COMPOSITE
Definition funcapi.h:149
@ TYPEFUNC_RECORD
Definition funcapi.h:151
@ TYPEFUNC_COMPOSITE_DOMAIN
Definition funcapi.h:150
bool check_sql_fn_retval(List *queryTreeLists, Oid rettype, TupleDesc rettupdesc, char prokind, bool insertDroppedCols)
Definition functions.c:2116
void sql_fn_parser_setup(struct ParseState *pstate, SQLFunctionParseInfoPtr pinfo)
Definition functions.c:340
SQLFunctionParseInfoPtr prepare_sql_fn_parse_info(HeapTuple procedureTuple, Node *call_expr, Oid inputCollation)
Definition functions.c:251
const char * str
bool heap_attisnull(HeapTuple tup, int attnum, TupleDesc tupleDesc)
Definition heaptuple.c:456
#define HeapTupleIsValid(tuple)
Definition htup.h:78
static void * GETSTRUCT(const HeapTupleData *tuple)
static struct @174 value
int i
Definition isn.c:77
List * lappend(List *list, void *datum)
Definition list.c:339
List * list_delete_first(List *list)
Definition list.c:943
List * list_concat_copy(const List *list1, const List *list2)
Definition list.c:598
List * list_copy(const List *oldlist)
Definition list.c:1573
List * lappend_oid(List *list, Oid datum)
Definition list.c:375
List * list_delete_last(List *list)
Definition list.c:957
void list_free(List *list)
Definition list.c:1546
bool list_member_oid(const List *list, Oid datum)
Definition list.c:722
List * list_delete_first_n(List *list, int n)
Definition list.c:983
RegProcedure get_func_support(Oid funcid)
Definition lsyscache.c:2076
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition lsyscache.c:3127
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
Definition lsyscache.c:2489
void get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval)
Definition lsyscache.c:2469
bool get_attnotnull(Oid relid, AttrNumber attnum)
Definition lsyscache.c:1122
RegProcedure get_opcode(Oid opno)
Definition lsyscache.c:1503
void getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)
Definition lsyscache.c:3094
char func_volatile(Oid funcid)
Definition lsyscache.c:1998
Oid get_array_type(Oid typid)
Definition lsyscache.c:3007
Expr * make_orclause(List *orclauses)
Definition makefuncs.c:743
Var * makeVar(int varno, AttrNumber varattno, Oid vartype, int32 vartypmod, Oid varcollid, Index varlevelsup)
Definition makefuncs.c:66
Const * makeNullConst(Oid consttype, int32 consttypmod, Oid constcollid)
Definition makefuncs.c:388
Node * makeBoolConst(bool value, bool isnull)
Definition makefuncs.c:408
Expr * make_andclause(List *andclauses)
Definition makefuncs.c:727
Expr * make_notclause(Expr *notclause)
Definition makefuncs.c:759
JsonValueExpr * makeJsonValueExpr(Expr *raw_expr, Expr *formatted_expr, JsonFormat *format)
Definition makefuncs.c:938
Const * makeConst(Oid consttype, int32 consttypmod, Oid constcollid, int constlen, Datum constvalue, bool constisnull, bool constbyval)
Definition makefuncs.c:350
void pfree(void *pointer)
Definition mcxt.c:1616
void * palloc0(Size size)
Definition mcxt.c:1417
MemoryContext CurrentMemoryContext
Definition mcxt.c:160
void MemoryContextDelete(MemoryContext context)
Definition mcxt.c:472
#define AllocSetContextCreate
Definition memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition memutils.h:160
Oid GetUserId(void)
Definition miscinit.c:470
Oid exprType(const Node *expr)
Definition nodeFuncs.c:42
int32 exprTypmod(const Node *expr)
Definition nodeFuncs.c:301
Oid exprCollation(const Node *expr)
Definition nodeFuncs.c:821
Node * applyRelabelType(Node *arg, Oid rtype, int32 rtypmod, Oid rcollid, CoercionForm rformat, int rlocation, bool overwrite_ok)
Definition nodeFuncs.c:636
void fix_opfuncids(Node *node)
Definition nodeFuncs.c:1840
void set_sa_opfuncid(ScalarArrayOpExpr *opexpr)
Definition nodeFuncs.c:1882
void set_opfuncid(OpExpr *opexpr)
Definition nodeFuncs.c:1871
#define expression_tree_mutator(n, m, c)
Definition nodeFuncs.h:155
static bool is_andclause(const void *clause)
Definition nodeFuncs.h:107
static bool is_orclause(const void *clause)
Definition nodeFuncs.h:116
#define expression_tree_walker(n, w, c)
Definition nodeFuncs.h:153
#define query_tree_mutator(q, m, c, f)
Definition nodeFuncs.h:160
#define IsA(nodeptr, _type_)
Definition nodes.h:164
#define copyObject(obj)
Definition nodes.h:232
#define nodeTag(nodeptr)
Definition nodes.h:139
@ CMD_SELECT
Definition nodes.h:275
#define makeNode(_type_)
Definition nodes.h:161
#define castNode(_type_, nodeptr)
Definition nodes.h:182
NotNullSource
Definition optimizer.h:135
@ NOTNULL_SOURCE_HASHTABLE
Definition optimizer.h:137
@ NOTNULL_SOURCE_SYSCACHE
Definition optimizer.h:138
@ NOTNULL_SOURCE_RELOPT
Definition optimizer.h:136
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition palloc.h:124
#define PARAM_FLAG_CONST
Definition params.h:87
void(* ParserSetupHook)(ParseState *pstate, void *arg)
Definition params.h:107
Oid enforce_generic_type_consistency(const Oid *actual_arg_types, Oid *declared_arg_types, int nargs, Oid rettype, bool allow_poly)
void make_fn_arguments(ParseState *pstate, List *fargs, Oid *actual_arg_types, Oid *declared_arg_types)
void free_parsestate(ParseState *pstate)
Definition parse_node.c:72
ParseState * make_parsestate(ParseState *parentParseState)
Definition parse_node.c:39
Operator oper(ParseState *pstate, List *opname, Oid ltypeId, Oid rtypeId, bool noError, int location)
Definition parse_oper.c:372
@ RTE_FUNCTION
@ RTE_RELATION
#define ACL_EXECUTE
Definition parsenodes.h:83
Query * transformTopLevelStmt(ParseState *pstate, RawStmt *parseTree)
Definition analyze.c:261
#define planner_rt_fetch(rti, root)
Definition pathnodes.h:692
#define FUNC_MAX_ARGS
bool has_subclass(Oid relationId)
#define lfirst(lc)
Definition pg_list.h:172
#define lfirst_node(type, lc)
Definition pg_list.h:176
static int list_length(const List *l)
Definition pg_list.h:152
#define linitial_node(type, l)
Definition pg_list.h:181
#define NIL
Definition pg_list.h:68
#define list_make1(x1)
Definition pg_list.h:212
#define foreach_ptr(type, var, lst)
Definition pg_list.h:469
static void * list_nth(const List *list, int n)
Definition pg_list.h:299
#define linitial(l)
Definition pg_list.h:178
#define list_make3(x1, x2, x3)
Definition pg_list.h:216
#define lsecond(l)
Definition pg_list.h:183
#define foreach_node(type, var, lst)
Definition pg_list.h:496
#define list_make2(x1, x2)
Definition pg_list.h:214
int16 pronargs
Definition pg_proc.h:83
END_CATALOG_STRUCT typedef FormData_pg_proc * Form_pg_proc
Definition pg_proc.h:140
static rewind_source * source
Definition pg_rewind.c:89
char typalign
Definition pg_type.h:178
Bitmapset * find_relation_notnullatts(PlannerInfo *root, Oid relid)
Definition plancat.c:763
List * pg_analyze_and_rewrite_withcb(RawStmt *parsetree, const char *query_string, ParserSetupHook parserSetup, void *parserSetupArg, QueryEnvironment *queryEnv)
Definition postgres.c:762
List * pg_parse_query(const char *query_string)
Definition postgres.c:603
List * pg_rewrite_query(Query *query)
Definition postgres.c:802
static bool DatumGetBool(Datum X)
Definition postgres.h:100
static Datum PointerGetDatum(const void *X)
Definition postgres.h:342
static Datum BoolGetDatum(bool X)
Definition postgres.h:112
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:252
uint64_t Datum
Definition postgres.h:70
static Pointer DatumGetPointer(Datum X)
Definition postgres.h:332
static Datum Int32GetDatum(int32 X)
Definition postgres.h:212
#define InvalidOid
unsigned int Oid
Node * negate_clause(Node *node)
Definition prepqual.c:73
e
static int fb(int x)
@ IS_NOT_TRUE
Definition primnodes.h:2002
@ IS_NOT_FALSE
Definition primnodes.h:2002
@ IS_NOT_UNKNOWN
Definition primnodes.h:2002
@ IS_TRUE
Definition primnodes.h:2002
@ IS_UNKNOWN
Definition primnodes.h:2002
@ IS_FALSE
Definition primnodes.h:2002
@ AND_EXPR
Definition primnodes.h:964
@ OR_EXPR
Definition primnodes.h:964
@ NOT_EXPR
Definition primnodes.h:964
@ PARAM_EXTERN
Definition primnodes.h:385
@ COERCE_IMPLICIT_CAST
Definition primnodes.h:769
@ COERCE_EXPLICIT_CALL
Definition primnodes.h:767
@ IS_NULL
Definition primnodes.h:1978
@ IS_NOT_NULL
Definition primnodes.h:1978
tree ctl root
Definition radixtree.h:1857
void * stringToNode(const char *str)
Definition read.c:90
RelOptInfo * find_base_rel(PlannerInfo *root, int relid)
Definition relnode.c:544
void AcquireRewriteLocks(Query *parsetree, bool forExecute, bool forUpdatePushedDown)
void IncrementVarSublevelsUp(Node *node, int delta_sublevels_up, int min_sublevels_up)
void record_plan_type_dependency(PlannerInfo *root, Oid typid)
Definition setrefs.c:3666
void record_plan_function_dependency(PlannerInfo *root, Oid funcid)
Definition setrefs.c:3626
void check_stack_depth(void)
Definition stack_depth.c:95
Oid aggfnoid
Definition primnodes.h:464
BoolExprType boolop
Definition primnodes.h:972
List * args
Definition primnodes.h:973
ParseLoc location
Definition primnodes.h:1248
ParseLoc location
Definition primnodes.h:1315
Oid consttype
Definition primnodes.h:330
MemoryContext es_query_cxt
Definition execnodes.h:713
struct ErrorContextCallback * previous
Definition elog.h:297
Expr xpr
Definition primnodes.h:781
ParseLoc location
Definition primnodes.h:803
Oid funcid
Definition primnodes.h:783
List * args
Definition primnodes.h:801
Definition pg_list.h:54
Definition nodes.h:135
NodeTag type
Definition nodes.h:136
Oid opno
Definition primnodes.h:851
List * args
Definition primnodes.h:869
ParseLoc location
Definition primnodes.h:872
ParamExternData params[FLEXIBLE_ARRAY_MEMBER]
Definition params.h:124
ParamFetchHook paramFetch
Definition params.h:111
ParseLoc location
Definition primnodes.h:404
int32 paramtypmod
Definition primnodes.h:400
int paramid
Definition primnodes.h:397
Oid paramtype
Definition primnodes.h:398
ParamKind paramkind
Definition primnodes.h:396
Oid paramcollid
Definition primnodes.h:402
const char * p_sourcetext
Definition parse_node.h:191
Bitmapset * notnullattnums
Definition pathnodes.h:1071
List * args
Definition primnodes.h:1449
AttrNumber varattno
Definition primnodes.h:275
int varno
Definition primnodes.h:270
Index varlevelsup
Definition primnodes.h:295
List * args
Definition primnodes.h:606
Index winref
Definition primnodes.h:612
Expr * aggfilter
Definition primnodes.h:608
ParseLoc location
Definition primnodes.h:620
int ignore_nulls
Definition primnodes.h:618
void ReleaseSysCache(HeapTuple tuple)
Definition syscache.c:264
Datum SysCacheGetAttrNotNull(SysCacheIdentifier cacheId, HeapTuple tup, AttrNumber attributeNumber)
Definition syscache.c:625
HeapTuple SearchSysCache1(SysCacheIdentifier cacheId, Datum key1)
Definition syscache.c:220
Datum SysCacheGetAttr(SysCacheIdentifier cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition syscache.c:595
TupleDesc BuildDescFromLists(const List *names, const List *types, const List *typmods, const List *collations)
Definition tupdesc.c:1034
bool DomainHasConstraints(Oid type_id)
Definition typcache.c:1491

◆ ece_evaluate_expr

#define ece_evaluate_expr (   node)
Value:
((Node *) evaluate_expr((Expr *) (node), \
exprType((Node *) (node)), \
exprTypmod((Node *) (node)), \
exprCollation((Node *) (node))))

Definition at line 2674 of file clauses.c.

◆ ece_generic_processing

#define ece_generic_processing (   node)
Value:

Definition at line 2661 of file clauses.c.

◆ MIN_ARRAY_SIZE_FOR_HASHED_SAOP

#define MIN_ARRAY_SIZE_FOR_HASHED_SAOP   9

Definition at line 2513 of file clauses.c.

Function Documentation

◆ add_function_defaults()

static List * add_function_defaults ( List args,
int  pronargs,
HeapTuple  func_tuple 
)
static

Definition at line 5042 of file clauses.c.

5043{
5044 int nargsprovided = list_length(args);
5045 List *defaults;
5046 int ndelete;
5047
5048 /* Get all the default expressions from the pg_proc tuple */
5050
5051 /* Delete any unused defaults from the list */
5052 ndelete = nargsprovided + list_length(defaults) - pronargs;
5053 if (ndelete < 0)
5054 elog(ERROR, "not enough default arguments");
5055 if (ndelete > 0)
5056 defaults = list_delete_first_n(defaults, ndelete);
5057
5058 /* And form the combined argument list, not modifying the input list */
5059 return list_concat_copy(args, defaults);
5060}

References elog, ERROR, fb(), fetch_function_defaults(), list_concat_copy(), list_delete_first_n(), list_length(), and pronargs.

Referenced by expand_function_arguments().

◆ CommuteOpExpr()

void CommuteOpExpr ( OpExpr clause)

Definition at line 2390 of file clauses.c.

2391{
2392 Oid opoid;
2393 Node *temp;
2394
2395 /* Sanity checks: caller is at fault if these fail */
2396 if (!is_opclause(clause) ||
2397 list_length(clause->args) != 2)
2398 elog(ERROR, "cannot commute non-binary-operator clause");
2399
2400 opoid = get_commutator(clause->opno);
2401
2402 if (!OidIsValid(opoid))
2403 elog(ERROR, "could not find commutator for operator %u",
2404 clause->opno);
2405
2406 /*
2407 * modify the clause in-place!
2408 */
2409 clause->opno = opoid;
2410 clause->opfuncid = InvalidOid;
2411 /* opresulttype, opretset, opcollid, inputcollid need not change */
2412
2413 temp = linitial(clause->args);
2414 linitial(clause->args) = lsecond(clause->args);
2415 lsecond(clause->args) = temp;
2416}
Oid get_commutator(Oid opno)
Definition lsyscache.c:1727
static bool is_opclause(const void *clause)
Definition nodeFuncs.h:76

References OpExpr::args, elog, ERROR, fb(), get_commutator(), InvalidOid, is_opclause(), linitial, list_length(), lsecond, OidIsValid, and OpExpr::opno.

Referenced by get_switched_clauses().

◆ contain_agg_clause()

bool contain_agg_clause ( Node clause)

Definition at line 192 of file clauses.c.

193{
194 return contain_agg_clause_walker(clause, NULL);
195}
static bool contain_agg_clause_walker(Node *node, void *context)
Definition clauses.c:198

References contain_agg_clause_walker(), and fb().

Referenced by get_eclass_for_sort_expr(), mark_nullable_by_grouping(), and subquery_planner().

◆ contain_agg_clause_walker()

static bool contain_agg_clause_walker ( Node node,
void context 
)
static

Definition at line 198 of file clauses.c.

199{
200 if (node == NULL)
201 return false;
202 if (IsA(node, Aggref))
203 {
204 Assert(((Aggref *) node)->agglevelsup == 0);
205 return true; /* abort the tree traversal and return true */
206 }
207 if (IsA(node, GroupingFunc))
208 {
209 Assert(((GroupingFunc *) node)->agglevelsup == 0);
210 return true; /* abort the tree traversal and return true */
211 }
212 Assert(!IsA(node, SubLink));
214}

References Assert, contain_agg_clause_walker(), expression_tree_walker, fb(), and IsA.

Referenced by contain_agg_clause(), and contain_agg_clause_walker().

◆ contain_context_dependent_node()

static bool contain_context_dependent_node ( Node clause)
static

Definition at line 1192 of file clauses.c.

1193{
1194 int flags = 0;
1195
1196 return contain_context_dependent_node_walker(clause, &flags);
1197}
static bool contain_context_dependent_node_walker(Node *node, int *flags)
Definition clauses.c:1202

References contain_context_dependent_node_walker().

Referenced by inline_function().

◆ contain_context_dependent_node_walker()

static bool contain_context_dependent_node_walker ( Node node,
int flags 
)
static

Definition at line 1202 of file clauses.c.

1203{
1204 if (node == NULL)
1205 return false;
1206 if (IsA(node, CaseTestExpr))
1207 return !(*flags & CCDN_CASETESTEXPR_OK);
1208 else if (IsA(node, CaseExpr))
1209 {
1210 CaseExpr *caseexpr = (CaseExpr *) node;
1211
1212 /*
1213 * If this CASE doesn't have a test expression, then it doesn't create
1214 * a context in which CaseTestExprs should appear, so just fall
1215 * through and treat it as a generic expression node.
1216 */
1217 if (caseexpr->arg)
1218 {
1219 int save_flags = *flags;
1220 bool res;
1221
1222 /*
1223 * Note: in principle, we could distinguish the various sub-parts
1224 * of a CASE construct and set the flag bit only for some of them,
1225 * since we are only expecting CaseTestExprs to appear in the
1226 * "expr" subtree of the CaseWhen nodes. But it doesn't really
1227 * seem worth any extra code. If there are any bare CaseTestExprs
1228 * elsewhere in the CASE, something's wrong already.
1229 */
1230 *flags |= CCDN_CASETESTEXPR_OK;
1231 res = expression_tree_walker(node,
1233 flags);
1234 *flags = save_flags;
1235 return res;
1236 }
1237 }
1238 else if (IsA(node, ArrayCoerceExpr))
1239 {
1241 int save_flags;
1242 bool res;
1243
1244 /* Check the array expression */
1245 if (contain_context_dependent_node_walker((Node *) ac->arg, flags))
1246 return true;
1247
1248 /* Check the elemexpr, which is allowed to contain CaseTestExpr */
1249 save_flags = *flags;
1250 *flags |= CCDN_CASETESTEXPR_OK;
1251 res = contain_context_dependent_node_walker((Node *) ac->elemexpr,
1252 flags);
1253 *flags = save_flags;
1254 return res;
1255 }
1257 flags);
1258}
#define CCDN_CASETESTEXPR_OK
Definition clauses.c:1199

References CCDN_CASETESTEXPR_OK, contain_context_dependent_node_walker(), expression_tree_walker, fb(), and IsA.

Referenced by contain_context_dependent_node(), and contain_context_dependent_node_walker().

◆ contain_exec_param()

bool contain_exec_param ( Node clause,
List param_ids 
)

Definition at line 1150 of file clauses.c.

1151{
1152 return contain_exec_param_walker(clause, param_ids);
1153}
static bool contain_exec_param_walker(Node *node, List *param_ids)
Definition clauses.c:1156

References contain_exec_param_walker(), and fb().

Referenced by test_opexpr_is_hashable().

◆ contain_exec_param_walker()

static bool contain_exec_param_walker ( Node node,
List param_ids 
)
static

Definition at line 1156 of file clauses.c.

1157{
1158 if (node == NULL)
1159 return false;
1160 if (IsA(node, Param))
1161 {
1162 Param *p = (Param *) node;
1163
1164 if (p->paramkind == PARAM_EXEC &&
1166 return true;
1167 }
1169}
bool list_member_int(const List *list, int datum)
Definition list.c:702
@ PARAM_EXEC
Definition primnodes.h:386

References contain_exec_param_walker(), expression_tree_walker, fb(), IsA, list_member_int(), PARAM_EXEC, Param::paramid, and Param::paramkind.

Referenced by contain_exec_param(), and contain_exec_param_walker().

◆ contain_leaked_vars()

bool contain_leaked_vars ( Node clause)

Definition at line 1276 of file clauses.c.

1277{
1278 return contain_leaked_vars_walker(clause, NULL);
1279}
static bool contain_leaked_vars_walker(Node *node, void *context)
Definition clauses.c:1288

References contain_leaked_vars_walker(), and fb().

Referenced by make_plain_restrictinfo(), and qual_is_pushdown_safe().

◆ contain_leaked_vars_checker()

static bool contain_leaked_vars_checker ( Oid  func_id,
void context 
)
static

Definition at line 1282 of file clauses.c.

1283{
1284 return !get_func_leakproof(func_id);
1285}
bool get_func_leakproof(Oid funcid)
Definition lsyscache.c:2055

References fb(), and get_func_leakproof().

Referenced by contain_leaked_vars_walker().

◆ contain_leaked_vars_walker()

static bool contain_leaked_vars_walker ( Node node,
void context 
)
static

Definition at line 1288 of file clauses.c.

1289{
1290 if (node == NULL)
1291 return false;
1292
1293 switch (nodeTag(node))
1294 {
1295 case T_Var:
1296 case T_Const:
1297 case T_Param:
1298 case T_ArrayExpr:
1299 case T_FieldSelect:
1300 case T_FieldStore:
1301 case T_NamedArgExpr:
1302 case T_BoolExpr:
1303 case T_RelabelType:
1304 case T_CollateExpr:
1305 case T_CaseExpr:
1306 case T_CaseTestExpr:
1307 case T_RowExpr:
1308 case T_SQLValueFunction:
1309 case T_NullTest:
1310 case T_BooleanTest:
1311 case T_NextValueExpr:
1312 case T_ReturningExpr:
1313 case T_List:
1314
1315 /*
1316 * We know these node types don't contain function calls; but
1317 * something further down in the node tree might.
1318 */
1319 break;
1320
1321 case T_FuncExpr:
1322 case T_OpExpr:
1323 case T_DistinctExpr:
1324 case T_NullIfExpr:
1326 case T_CoerceViaIO:
1327 case T_ArrayCoerceExpr:
1328
1329 /*
1330 * If node contains a leaky function call, and there's any Var
1331 * underneath it, reject.
1332 */
1334 context) &&
1335 contain_var_clause(node))
1336 return true;
1337 break;
1338
1339 case T_SubscriptingRef:
1340 {
1341 SubscriptingRef *sbsref = (SubscriptingRef *) node;
1343
1344 /* Consult the subscripting support method info */
1345 sbsroutines = getSubscriptingRoutines(sbsref->refcontainertype,
1346 NULL);
1347 if (!sbsroutines ||
1348 !(sbsref->refassgnexpr != NULL ?
1349 sbsroutines->store_leakproof :
1350 sbsroutines->fetch_leakproof))
1351 {
1352 /* Node is leaky, so reject if it contains Vars */
1353 if (contain_var_clause(node))
1354 return true;
1355 }
1356 }
1357 break;
1358
1359 case T_RowCompareExpr:
1360 {
1361 /*
1362 * It's worth special-casing this because a leaky comparison
1363 * function only compromises one pair of row elements, which
1364 * might not contain Vars while others do.
1365 */
1367 ListCell *opid;
1368 ListCell *larg;
1369 ListCell *rarg;
1370
1371 forthree(opid, rcexpr->opnos,
1372 larg, rcexpr->largs,
1373 rarg, rcexpr->rargs)
1374 {
1375 Oid funcid = get_opcode(lfirst_oid(opid));
1376
1377 if (!get_func_leakproof(funcid) &&
1378 (contain_var_clause((Node *) lfirst(larg)) ||
1379 contain_var_clause((Node *) lfirst(rarg))))
1380 return true;
1381 }
1382 }
1383 break;
1384
1385 case T_MinMaxExpr:
1386 {
1387 /*
1388 * MinMaxExpr is leakproof if the comparison function it calls
1389 * is leakproof.
1390 */
1391 MinMaxExpr *minmaxexpr = (MinMaxExpr *) node;
1392 TypeCacheEntry *typentry;
1393 bool leakproof;
1394
1395 /* Look up the btree comparison function for the datatype */
1396 typentry = lookup_type_cache(minmaxexpr->minmaxtype,
1398 if (OidIsValid(typentry->cmp_proc))
1400 else
1401 {
1402 /*
1403 * The executor will throw an error, but here we just
1404 * treat the missing function as leaky.
1405 */
1406 leakproof = false;
1407 }
1408
1409 if (!leakproof &&
1411 return true;
1412 }
1413 break;
1414
1415 case T_CurrentOfExpr:
1416
1417 /*
1418 * WHERE CURRENT OF doesn't contain leaky function calls.
1419 * Moreover, it is essential that this is considered non-leaky,
1420 * since the planner must always generate a TID scan when CURRENT
1421 * OF is present -- cf. cost_tidscan.
1422 */
1423 return false;
1424
1425 default:
1426
1427 /*
1428 * If we don't recognize the node tag, assume it might be leaky.
1429 * This prevents an unexpected security hole if someone adds a new
1430 * node type that can call a function.
1431 */
1432 return true;
1433 }
1435 context);
1436}
static bool contain_leaked_vars_checker(Oid func_id, void *context)
Definition clauses.c:1282
const struct SubscriptRoutines * getSubscriptingRoutines(Oid typid, Oid *typelemp)
Definition lsyscache.c:3350
bool check_functions_in_node(Node *node, check_function_callback checker, void *context)
Definition nodeFuncs.c:1909
#define forthree(cell1, list1, cell2, list2, cell3, list3)
Definition pg_list.h:563
#define lfirst_oid(lc)
Definition pg_list.h:174
Expr * refassgnexpr
Definition primnodes.h:736
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
Definition typcache.c:389
#define TYPECACHE_CMP_PROC
Definition typcache.h:141
bool contain_var_clause(Node *node)
Definition var.c:406

References check_functions_in_node(), TypeCacheEntry::cmp_proc, contain_leaked_vars_checker(), contain_leaked_vars_walker(), contain_var_clause(), expression_tree_walker, fb(), forthree, get_func_leakproof(), get_opcode(), getSubscriptingRoutines(), lfirst, lfirst_oid, lookup_type_cache(), nodeTag, OidIsValid, SubscriptingRef::refassgnexpr, and TYPECACHE_CMP_PROC.

Referenced by contain_leaked_vars(), and contain_leaked_vars_walker().

◆ contain_mutable_functions()

◆ contain_mutable_functions_after_planning()

bool contain_mutable_functions_after_planning ( Expr expr)

Definition at line 501 of file clauses.c.

502{
503 /* We assume here that expression_planner() won't scribble on its input */
504 expr = expression_planner(expr);
505
506 /* Now we can search for non-immutable functions */
507 return contain_mutable_functions((Node *) expr);
508}
Expr * expression_planner(Expr *expr)
Definition planner.c:6819

References contain_mutable_functions(), and expression_planner().

Referenced by CheckPredicate(), ComputeIndexAttrs(), and cookDefault().

◆ contain_mutable_functions_checker()

static bool contain_mutable_functions_checker ( Oid  func_id,
void context 
)
static

Definition at line 387 of file clauses.c.

388{
390}

References fb(), and func_volatile().

Referenced by contain_mutable_functions_walker().

◆ contain_mutable_functions_walker()

static bool contain_mutable_functions_walker ( Node node,
void context 
)
static

Definition at line 393 of file clauses.c.

394{
395 if (node == NULL)
396 return false;
397 /* Check for mutable functions in node itself */
399 context))
400 return true;
401
402 if (IsA(node, JsonConstructorExpr))
403 {
405 ListCell *lc;
406 bool is_jsonb;
407
408 is_jsonb = ctor->returning->format->format_type == JS_FORMAT_JSONB;
409
410 /*
411 * Check argument_type => json[b] conversions specifically. We still
412 * recurse to check 'args' below, but here we want to specifically
413 * check whether or not the emitted clause would fail to be immutable
414 * because of TimeZone, for example.
415 */
416 foreach(lc, ctor->args)
417 {
418 Oid typid = exprType(lfirst(lc));
419
420 if (is_jsonb ?
421 !to_jsonb_is_immutable(typid) :
422 !to_json_is_immutable(typid))
423 return true;
424 }
425
426 /* Check all subnodes */
427 }
428
429 if (IsA(node, JsonExpr))
430 {
432 Const *cnst;
433
434 if (!IsA(jexpr->path_spec, Const))
435 return true;
436
437 cnst = castNode(Const, jexpr->path_spec);
438
439 Assert(cnst->consttype == JSONPATHOID);
440 if (cnst->constisnull)
441 return false;
442
443 if (jspIsMutable(DatumGetJsonPathP(cnst->constvalue),
444 jexpr->passing_names, jexpr->passing_values))
445 return true;
446 }
447
448 if (IsA(node, SQLValueFunction))
449 {
450 /* all variants of SQLValueFunction are stable */
451 return true;
452 }
453
454 if (IsA(node, NextValueExpr))
455 {
456 /* NextValueExpr is volatile */
457 return true;
458 }
459
460 /*
461 * It should be safe to treat MinMaxExpr as immutable, because it will
462 * depend on a non-cross-type btree comparison function, and those should
463 * always be immutable. Treating XmlExpr as immutable is more dubious,
464 * and treating CoerceToDomain as immutable is outright dangerous. But we
465 * have done so historically, and changing this would probably cause more
466 * problems than it would fix. In practice, if you have a non-immutable
467 * domain constraint you are in for pain anyhow.
468 */
469
470 /* Recurse to check arguments */
471 if (IsA(node, Query))
472 {
473 /* Recurse into subselects */
474 return query_tree_walker((Query *) node,
476 context, 0);
477 }
479 context);
480}
static bool contain_mutable_functions_checker(Oid func_id, void *context)
Definition clauses.c:387
return true
Definition isn.c:130
bool to_json_is_immutable(Oid typoid)
Definition json.c:701
bool to_jsonb_is_immutable(Oid typoid)
Definition jsonb.c:1086
bool jspIsMutable(JsonPath *path, List *varnames, List *varexprs)
Definition jsonpath.c:1280
static JsonPath * DatumGetJsonPathP(Datum d)
Definition jsonpath.h:35
#define query_tree_walker(q, w, c, f)
Definition nodeFuncs.h:158
@ JS_FORMAT_JSONB
Definition primnodes.h:1666

References Assert, castNode, check_functions_in_node(), contain_mutable_functions_checker(), contain_mutable_functions_walker(), DatumGetJsonPathP(), expression_tree_walker, exprType(), fb(), IsA, JS_FORMAT_JSONB, jspIsMutable(), lfirst, query_tree_walker, to_json_is_immutable(), and to_jsonb_is_immutable().

Referenced by contain_mutable_functions(), and contain_mutable_functions_walker().

◆ contain_non_const_walker()

static bool contain_non_const_walker ( Node node,
void context 
)
static

Definition at line 4155 of file clauses.c.

4156{
4157 if (node == NULL)
4158 return false;
4159 if (IsA(node, Const))
4160 return false;
4161 if (IsA(node, List))
4162 return expression_tree_walker(node, contain_non_const_walker, context);
4163 /* Otherwise, abort the tree traversal and return true */
4164 return true;
4165}

References contain_non_const_walker(), expression_tree_walker, fb(), and IsA.

Referenced by contain_non_const_walker().

◆ contain_nonstrict_functions()

bool contain_nonstrict_functions ( Node clause)

Definition at line 1004 of file clauses.c.

1005{
1007}
static bool contain_nonstrict_functions_walker(Node *node, void *context)
Definition clauses.c:1016

References contain_nonstrict_functions_walker(), and fb().

Referenced by inline_function(), and pullup_replace_vars_callback().

◆ contain_nonstrict_functions_checker()

static bool contain_nonstrict_functions_checker ( Oid  func_id,
void context 
)
static

Definition at line 1010 of file clauses.c.

1011{
1012 return !func_strict(func_id);
1013}
bool func_strict(Oid funcid)
Definition lsyscache.c:1979

References fb(), and func_strict().

Referenced by contain_nonstrict_functions_walker().

◆ contain_nonstrict_functions_walker()

static bool contain_nonstrict_functions_walker ( Node node,
void context 
)
static

Definition at line 1016 of file clauses.c.

1017{
1018 if (node == NULL)
1019 return false;
1020 if (IsA(node, Aggref))
1021 {
1022 /* an aggregate could return non-null with null input */
1023 return true;
1024 }
1025 if (IsA(node, GroupingFunc))
1026 {
1027 /*
1028 * A GroupingFunc doesn't evaluate its arguments, and therefore must
1029 * be treated as nonstrict.
1030 */
1031 return true;
1032 }
1033 if (IsA(node, WindowFunc))
1034 {
1035 /* a window function could return non-null with null input */
1036 return true;
1037 }
1038 if (IsA(node, SubscriptingRef))
1039 {
1040 SubscriptingRef *sbsref = (SubscriptingRef *) node;
1042
1043 /* Subscripting assignment is always presumed nonstrict */
1044 if (sbsref->refassgnexpr != NULL)
1045 return true;
1046 /* Otherwise we must look up the subscripting support methods */
1047 sbsroutines = getSubscriptingRoutines(sbsref->refcontainertype, NULL);
1048 if (!(sbsroutines && sbsroutines->fetch_strict))
1049 return true;
1050 /* else fall through to check args */
1051 }
1052 if (IsA(node, DistinctExpr))
1053 {
1054 /* IS DISTINCT FROM is inherently non-strict */
1055 return true;
1056 }
1057 if (IsA(node, NullIfExpr))
1058 {
1059 /* NULLIF is inherently non-strict */
1060 return true;
1061 }
1062 if (IsA(node, BoolExpr))
1063 {
1064 BoolExpr *expr = (BoolExpr *) node;
1065
1066 switch (expr->boolop)
1067 {
1068 case AND_EXPR:
1069 case OR_EXPR:
1070 /* AND, OR are inherently non-strict */
1071 return true;
1072 default:
1073 break;
1074 }
1075 }
1076 if (IsA(node, SubLink))
1077 {
1078 /* In some cases a sublink might be strict, but in general not */
1079 return true;
1080 }
1081 if (IsA(node, SubPlan))
1082 return true;
1083 if (IsA(node, AlternativeSubPlan))
1084 return true;
1085 if (IsA(node, FieldStore))
1086 return true;
1087 if (IsA(node, CoerceViaIO))
1088 {
1089 /*
1090 * CoerceViaIO is strict regardless of whether the I/O functions are,
1091 * so just go look at its argument; asking check_functions_in_node is
1092 * useless expense and could deliver the wrong answer.
1093 */
1095 context);
1096 }
1097 if (IsA(node, ArrayCoerceExpr))
1098 {
1099 /*
1100 * ArrayCoerceExpr is strict at the array level, regardless of what
1101 * the per-element expression is; so we should ignore elemexpr and
1102 * recurse only into the arg.
1103 */
1105 context);
1106 }
1107 if (IsA(node, CaseExpr))
1108 return true;
1109 if (IsA(node, ArrayExpr))
1110 return true;
1111 if (IsA(node, RowExpr))
1112 return true;
1113 if (IsA(node, RowCompareExpr))
1114 return true;
1115 if (IsA(node, CoalesceExpr))
1116 return true;
1117 if (IsA(node, MinMaxExpr))
1118 return true;
1119 if (IsA(node, XmlExpr))
1120 return true;
1121 if (IsA(node, NullTest))
1122 return true;
1123 if (IsA(node, BooleanTest))
1124 return true;
1125 if (IsA(node, JsonConstructorExpr))
1126 return true;
1127
1128 /* Check other function-containing nodes */
1130 context))
1131 return true;
1132
1134 context);
1135}
static bool contain_nonstrict_functions_checker(Oid func_id, void *context)
Definition clauses.c:1010

References AND_EXPR, arg, BoolExpr::boolop, check_functions_in_node(), contain_nonstrict_functions_checker(), contain_nonstrict_functions_walker(), expression_tree_walker, fb(), getSubscriptingRoutines(), IsA, OR_EXPR, and SubscriptingRef::refassgnexpr.

Referenced by contain_nonstrict_functions(), and contain_nonstrict_functions_walker().

◆ contain_subplans()

bool contain_subplans ( Node clause)

◆ contain_subplans_walker()

static bool contain_subplans_walker ( Node node,
void context 
)
static

Definition at line 347 of file clauses.c.

348{
349 if (node == NULL)
350 return false;
351 if (IsA(node, SubPlan) ||
352 IsA(node, AlternativeSubPlan) ||
353 IsA(node, SubLink))
354 return true; /* abort the tree traversal and return true */
355 return expression_tree_walker(node, contain_subplans_walker, context);
356}

References contain_subplans_walker(), expression_tree_walker, fb(), and IsA.

Referenced by contain_subplans(), and contain_subplans_walker().

◆ contain_volatile_functions()

bool contain_volatile_functions ( Node clause)

Definition at line 549 of file clauses.c.

550{
552}
static bool contain_volatile_functions_walker(Node *node, void *context)
Definition clauses.c:561

References contain_volatile_functions_walker(), and fb().

Referenced by apply_child_basequals(), ATExecAddColumn(), check_hashjoinable(), check_mergejoinable(), check_output_expressions(), compute_semijoin_info(), contain_volatile_functions_after_planning(), convert_ANY_sublink_to_join(), convert_EXISTS_sublink_to_join(), convert_EXISTS_to_ANY(), convert_VALUES_to_ANY(), CopyFrom(), distribute_qual_to_rels(), estimate_num_groups(), ExecInitWindowAgg(), expand_indexqual_rowcompare(), find_compatible_agg(), find_simplified_clause(), get_eclass_for_sort_expr(), get_memoize_path(), group_similar_or_args(), initialize_peragg(), inline_function(), inline_function_in_from(), is_pseudo_constant_clause(), is_pseudo_constant_clause_relids(), is_pseudo_constant_for_index(), is_safe_restriction_clause_for(), is_simple_subquery(), is_simple_values(), IsBinaryTidClause(), IsTidEqualAnyClause(), make_sort_input_target(), mark_nullable_by_grouping(), match_clause_to_ordering_op(), match_clause_to_partition_key(), match_opclause_to_indexcol(), match_orclause_to_indexcol(), match_rowcompare_to_indexcol(), match_saopclause_to_indexcol(), paraminfo_get_equal_hashops(), qual_is_pushdown_safe(), remove_unused_subquery_outputs(), SS_process_ctes(), and subquery_planner().

◆ contain_volatile_functions_after_planning()

bool contain_volatile_functions_after_planning ( Expr expr)

Definition at line 670 of file clauses.c.

671{
672 /* We assume here that expression_planner() won't scribble on its input */
673 expr = expression_planner(expr);
674
675 /* Now we can search for volatile functions */
676 return contain_volatile_functions((Node *) expr);
677}

References contain_volatile_functions(), and expression_planner().

◆ contain_volatile_functions_checker()

static bool contain_volatile_functions_checker ( Oid  func_id,
void context 
)
static

Definition at line 555 of file clauses.c.

556{
558}

References fb(), and func_volatile().

Referenced by contain_volatile_functions_walker().

◆ contain_volatile_functions_not_nextval()

bool contain_volatile_functions_not_nextval ( Node clause)

Definition at line 684 of file clauses.c.

685{
687}
static bool contain_volatile_functions_not_nextval_walker(Node *node, void *context)
Definition clauses.c:697

References contain_volatile_functions_not_nextval_walker(), and fb().

Referenced by BeginCopyFrom().

◆ contain_volatile_functions_not_nextval_checker()

static bool contain_volatile_functions_not_nextval_checker ( Oid  func_id,
void context 
)
static

Definition at line 690 of file clauses.c.

691{
692 return (func_id != F_NEXTVAL &&
694}

References fb(), and func_volatile().

Referenced by contain_volatile_functions_not_nextval_walker().

◆ contain_volatile_functions_not_nextval_walker()

static bool contain_volatile_functions_not_nextval_walker ( Node node,
void context 
)
static

Definition at line 697 of file clauses.c.

698{
699 if (node == NULL)
700 return false;
701 /* Check for volatile functions in node itself */
704 context))
705 return true;
706
707 /*
708 * See notes in contain_mutable_functions_walker about why we treat
709 * MinMaxExpr, XmlExpr, and CoerceToDomain as immutable, while
710 * SQLValueFunction is stable. Hence, none of them are of interest here.
711 * Also, since we're intentionally ignoring nextval(), presumably we
712 * should ignore NextValueExpr.
713 */
714
715 /* Recurse to check arguments */
716 if (IsA(node, Query))
717 {
718 /* Recurse into subselects */
719 return query_tree_walker((Query *) node,
721 context, 0);
722 }
723 return expression_tree_walker(node,
725 context);
726}
static bool contain_volatile_functions_not_nextval_checker(Oid func_id, void *context)
Definition clauses.c:690

References check_functions_in_node(), contain_volatile_functions_not_nextval_checker(), contain_volatile_functions_not_nextval_walker(), expression_tree_walker, fb(), IsA, and query_tree_walker.

Referenced by contain_volatile_functions_not_nextval(), and contain_volatile_functions_not_nextval_walker().

◆ contain_volatile_functions_walker()

static bool contain_volatile_functions_walker ( Node node,
void context 
)
static

Definition at line 561 of file clauses.c.

562{
563 if (node == NULL)
564 return false;
565 /* Check for volatile functions in node itself */
567 context))
568 return true;
569
570 if (IsA(node, NextValueExpr))
571 {
572 /* NextValueExpr is volatile */
573 return true;
574 }
575
576 if (IsA(node, RestrictInfo))
577 {
578 RestrictInfo *rinfo = (RestrictInfo *) node;
579
580 /*
581 * For RestrictInfo, check if we've checked the volatility of it
582 * before. If so, we can just use the cached value and not bother
583 * checking it again. Otherwise, check it and cache if whether we
584 * found any volatile functions.
585 */
586 if (rinfo->has_volatile == VOLATILITY_NOVOLATILE)
587 return false;
588 else if (rinfo->has_volatile == VOLATILITY_VOLATILE)
589 return true;
590 else
591 {
592 bool hasvolatile;
593
595 context);
596 if (hasvolatile)
597 rinfo->has_volatile = VOLATILITY_VOLATILE;
598 else
599 rinfo->has_volatile = VOLATILITY_NOVOLATILE;
600
601 return hasvolatile;
602 }
603 }
604
605 if (IsA(node, PathTarget))
606 {
607 PathTarget *target = (PathTarget *) node;
608
609 /*
610 * We also do caching for PathTarget the same as we do above for
611 * RestrictInfos.
612 */
614 return false;
615 else if (target->has_volatile_expr == VOLATILITY_VOLATILE)
616 return true;
617 else
618 {
619 bool hasvolatile;
620
622 context);
623
624 if (hasvolatile)
626 else
628
629 return hasvolatile;
630 }
631 }
632
633 /*
634 * See notes in contain_mutable_functions_walker about why we treat
635 * MinMaxExpr, XmlExpr, and CoerceToDomain as immutable, while
636 * SQLValueFunction is stable. Hence, none of them are of interest here.
637 */
638
639 /* Recurse to check arguments */
640 if (IsA(node, Query))
641 {
642 /* Recurse into subselects */
643 return query_tree_walker((Query *) node,
645 context, 0);
646 }
648 context);
649}
static bool contain_volatile_functions_checker(Oid func_id, void *context)
Definition clauses.c:555
@ VOLATILITY_NOVOLATILE
Definition pathnodes.h:1833
@ VOLATILITY_VOLATILE
Definition pathnodes.h:1832
VolatileFunctionStatus has_volatile_expr
Definition pathnodes.h:1878
List * exprs
Definition pathnodes.h:1866
Expr * clause
Definition pathnodes.h:2888

References check_functions_in_node(), RestrictInfo::clause, contain_volatile_functions_checker(), contain_volatile_functions_walker(), expression_tree_walker, PathTarget::exprs, fb(), PathTarget::has_volatile_expr, IsA, query_tree_walker, VOLATILITY_NOVOLATILE, and VOLATILITY_VOLATILE.

Referenced by contain_volatile_functions(), and contain_volatile_functions_walker().

◆ contain_window_function()

bool contain_window_function ( Node clause)

Definition at line 229 of file clauses.c.

230{
231 return contain_windowfuncs(clause);
232}
bool contain_windowfuncs(Node *node)

References contain_windowfuncs().

Referenced by get_eclass_for_sort_expr(), and mark_nullable_by_grouping().

◆ convert_saop_to_hashed_saop()

void convert_saop_to_hashed_saop ( Node node)

Definition at line 2531 of file clauses.c.

2532{
2534}
static bool convert_saop_to_hashed_saop_walker(Node *node, void *context)
Definition clauses.c:2537

References convert_saop_to_hashed_saop_walker(), and fb().

Referenced by preprocess_expression().

◆ convert_saop_to_hashed_saop_walker()

static bool convert_saop_to_hashed_saop_walker ( Node node,
void context 
)
static

Definition at line 2537 of file clauses.c.

2538{
2539 if (node == NULL)
2540 return false;
2541
2542 if (IsA(node, ScalarArrayOpExpr))
2543 {
2544 ScalarArrayOpExpr *saop = (ScalarArrayOpExpr *) node;
2545 Expr *arrayarg = (Expr *) lsecond(saop->args);
2548
2549 if (arrayarg && IsA(arrayarg, Const) &&
2550 !((Const *) arrayarg)->constisnull)
2551 {
2552 if (saop->useOr)
2553 {
2556 {
2557 Datum arrdatum = ((Const *) arrayarg)->constvalue;
2559 int nitems;
2560
2561 /*
2562 * Only fill in the hash functions if the array looks
2563 * large enough for it to be worth hashing instead of
2564 * doing a linear search.
2565 */
2566 nitems = ArrayGetNItems(ARR_NDIM(arr), ARR_DIMS(arr));
2567
2569 {
2570 /* Looks good. Fill in the hash functions */
2571 saop->hashfuncid = lefthashfunc;
2572 }
2573 return false;
2574 }
2575 }
2576 else /* !saop->useOr */
2577 {
2578 Oid negator = get_negator(saop->opno);
2579
2580 /*
2581 * Check if this is a NOT IN using an operator whose negator
2582 * is hashable. If so we can still build a hash table and
2583 * just ensure the lookup items are not in the hash table.
2584 */
2585 if (OidIsValid(negator) &&
2588 {
2589 Datum arrdatum = ((Const *) arrayarg)->constvalue;
2591 int nitems;
2592
2593 /*
2594 * Only fill in the hash functions if the array looks
2595 * large enough for it to be worth hashing instead of
2596 * doing a linear search.
2597 */
2598 nitems = ArrayGetNItems(ARR_NDIM(arr), ARR_DIMS(arr));
2599
2601 {
2602 /* Looks good. Fill in the hash functions */
2603 saop->hashfuncid = lefthashfunc;
2604
2605 /*
2606 * Also set the negfuncid. The executor will need
2607 * that to perform hashtable lookups.
2608 */
2609 saop->negfuncid = get_opcode(negator);
2610 }
2611 return false;
2612 }
2613 }
2614 }
2615 }
2616
2618}
int ArrayGetNItems(int ndim, const int *dims)
Definition arrayutils.c:57
#define MIN_ARRAY_SIZE_FOR_HASHED_SAOP
Definition clauses.c:2513
#define nitems(x)
Definition indent.h:31
bool get_op_hash_functions(Oid opno, RegProcedure *lhs_procno, RegProcedure *rhs_procno)
Definition lsyscache.c:575
Oid get_negator(Oid opno)
Definition lsyscache.c:1751

References ScalarArrayOpExpr::args, ARR_DIMS, ARR_NDIM, ArrayGetNItems(), convert_saop_to_hashed_saop_walker(), DatumGetPointer(), expression_tree_walker, fb(), get_negator(), get_op_hash_functions(), get_opcode(), IsA, lsecond, MIN_ARRAY_SIZE_FOR_HASHED_SAOP, nitems, OidIsValid, ScalarArrayOpExpr::opno, and ScalarArrayOpExpr::useOr.

Referenced by convert_saop_to_hashed_saop(), and convert_saop_to_hashed_saop_walker().

◆ ece_function_is_safe()

static bool ece_function_is_safe ( Oid  funcid,
eval_const_expressions_context context 
)
static

Definition at line 4171 of file clauses.c.

4172{
4173 char provolatile = func_volatile(funcid);
4174
4175 /*
4176 * Ordinarily we are only allowed to simplify immutable functions. But for
4177 * purposes of estimation, we consider it okay to simplify functions that
4178 * are merely stable; the risk that the result might change from planning
4179 * time to execution time is worth taking in preference to not being able
4180 * to estimate the value at all.
4181 */
4183 return true;
4184 if (context->estimate && provolatile == PROVOLATILE_STABLE)
4185 return true;
4186 return false;
4187}

References eval_const_expressions_context::estimate, fb(), and func_volatile().

Referenced by eval_const_expressions_mutator().

◆ estimate_expression_value()

Node * estimate_expression_value ( PlannerInfo root,
Node node 
)

◆ eval_const_expressions()

Node * eval_const_expressions ( PlannerInfo root,
Node node 
)

Definition at line 2498 of file clauses.c.

2499{
2501
2502 if (root)
2503 context.boundParams = root->glob->boundParams; /* bound Params */
2504 else
2505 context.boundParams = NULL;
2506 context.root = root; /* for inlined-function dependencies */
2507 context.active_fns = NIL; /* nothing being recursively simplified */
2508 context.case_val = NULL; /* no CASE being examined */
2509 context.estimate = false; /* safe transformations only */
2510 return eval_const_expressions_mutator(node, &context);
2511}

References eval_const_expressions_context::active_fns, eval_const_expressions_context::boundParams, eval_const_expressions_context::case_val, eval_const_expressions_context::estimate, eval_const_expressions_mutator(), fb(), NIL, eval_const_expressions_context::root, and root.

Referenced by apply_child_basequals(), ATExecAttachPartition(), ConstraintImpliedByRelConstraint(), convert_EXISTS_to_ANY(), convert_VALUES_to_ANY(), DoCopy(), expand_insert_targetlist(), expression_planner(), expression_planner_with_deps(), extended_statistics_update(), fetch_statentries_for_relation(), get_proposed_default_constraint(), get_relation_constraints(), get_relation_info(), get_relation_statistics(), infer_arbiter_indexes(), preprocess_expression(), preprocess_function_rtes(), process_implied_equality(), RelationBuildPartitionKey(), RelationGetIndexExpressions(), RelationGetIndexPredicate(), simplify_EXISTS_query(), and SplitPartitionMoveRows().

◆ eval_const_expressions_mutator()

static Node * eval_const_expressions_mutator ( Node node,
eval_const_expressions_context context 
)
static

Definition at line 2684 of file clauses.c.

2686{
2687
2688 /* since this function recurses, it could be driven to stack overflow */
2690
2691 if (node == NULL)
2692 return NULL;
2693 switch (nodeTag(node))
2694 {
2695 case T_Param:
2696 {
2697 Param *param = (Param *) node;
2698 ParamListInfo paramLI = context->boundParams;
2699
2700 /* Look to see if we've been given a value for this Param */
2701 if (param->paramkind == PARAM_EXTERN &&
2702 paramLI != NULL &&
2703 param->paramid > 0 &&
2704 param->paramid <= paramLI->numParams)
2705 {
2708
2709 /*
2710 * Give hook a chance in case parameter is dynamic. Tell
2711 * it that this fetch is speculative, so it should avoid
2712 * erroring out if parameter is unavailable.
2713 */
2714 if (paramLI->paramFetch != NULL)
2715 prm = paramLI->paramFetch(paramLI, param->paramid,
2716 true, &prmdata);
2717 else
2718 prm = &paramLI->params[param->paramid - 1];
2719
2720 /*
2721 * We don't just check OidIsValid, but insist that the
2722 * fetched type match the Param, just in case the hook did
2723 * something unexpected. No need to throw an error here
2724 * though; leave that for runtime.
2725 */
2726 if (OidIsValid(prm->ptype) &&
2727 prm->ptype == param->paramtype)
2728 {
2729 /* OK to substitute parameter value? */
2730 if (context->estimate ||
2731 (prm->pflags & PARAM_FLAG_CONST))
2732 {
2733 /*
2734 * Return a Const representing the param value.
2735 * Must copy pass-by-ref datatypes, since the
2736 * Param might be in a memory context
2737 * shorter-lived than our output plan should be.
2738 */
2739 int16 typLen;
2740 bool typByVal;
2741 Datum pval;
2742 Const *con;
2743
2745 &typLen, &typByVal);
2746 if (prm->isnull || typByVal)
2747 pval = prm->value;
2748 else
2749 pval = datumCopy(prm->value, typByVal, typLen);
2750 con = makeConst(param->paramtype,
2751 param->paramtypmod,
2752 param->paramcollid,
2753 (int) typLen,
2754 pval,
2755 prm->isnull,
2756 typByVal);
2757 con->location = param->location;
2758 return (Node *) con;
2759 }
2760 }
2761 }
2762
2763 /*
2764 * Not replaceable, so just copy the Param (no need to
2765 * recurse)
2766 */
2767 return (Node *) copyObject(param);
2768 }
2769 case T_WindowFunc:
2770 {
2771 WindowFunc *expr = (WindowFunc *) node;
2772 Oid funcid = expr->winfnoid;
2773 List *args;
2774 Expr *aggfilter;
2777
2778 /*
2779 * We can't really simplify a WindowFunc node, but we mustn't
2780 * just fall through to the default processing, because we
2781 * have to apply expand_function_arguments to its argument
2782 * list. That takes care of inserting default arguments and
2783 * expanding named-argument notation.
2784 */
2787 elog(ERROR, "cache lookup failed for function %u", funcid);
2788
2790 false, expr->wintype,
2791 func_tuple);
2792
2794
2795 /* Now, recursively simplify the args (which are a List) */
2796 args = (List *)
2799 context);
2800 /* ... and the filter expression, which isn't */
2801 aggfilter = (Expr *)
2803 context);
2804
2805 /* And build the replacement WindowFunc node */
2807 newexpr->winfnoid = expr->winfnoid;
2808 newexpr->wintype = expr->wintype;
2809 newexpr->wincollid = expr->wincollid;
2810 newexpr->inputcollid = expr->inputcollid;
2811 newexpr->args = args;
2812 newexpr->aggfilter = aggfilter;
2813 newexpr->runCondition = expr->runCondition;
2814 newexpr->winref = expr->winref;
2815 newexpr->winstar = expr->winstar;
2816 newexpr->winagg = expr->winagg;
2818 newexpr->location = expr->location;
2819
2820 return (Node *) newexpr;
2821 }
2822 case T_FuncExpr:
2823 {
2824 FuncExpr *expr = (FuncExpr *) node;
2825 List *args = expr->args;
2826 Expr *simple;
2828
2829 /*
2830 * Code for op/func reduction is pretty bulky, so split it out
2831 * as a separate function. Note: exprTypmod normally returns
2832 * -1 for a FuncExpr, but not when the node is recognizably a
2833 * length coercion; we want to preserve the typmod in the
2834 * eventual Const if so.
2835 */
2836 simple = simplify_function(expr->funcid,
2837 expr->funcresulttype,
2838 exprTypmod(node),
2839 expr->funccollid,
2840 expr->inputcollid,
2841 &args,
2842 expr->funcvariadic,
2843 true,
2844 true,
2845 context);
2846 if (simple) /* successfully simplified it */
2847 return (Node *) simple;
2848
2849 /*
2850 * The expression cannot be simplified any further, so build
2851 * and return a replacement FuncExpr node using the
2852 * possibly-simplified arguments. Note that we have also
2853 * converted the argument list to positional notation.
2854 */
2856 newexpr->funcid = expr->funcid;
2857 newexpr->funcresulttype = expr->funcresulttype;
2858 newexpr->funcretset = expr->funcretset;
2859 newexpr->funcvariadic = expr->funcvariadic;
2860 newexpr->funcformat = expr->funcformat;
2861 newexpr->funccollid = expr->funccollid;
2862 newexpr->inputcollid = expr->inputcollid;
2863 newexpr->args = args;
2864 newexpr->location = expr->location;
2865 return (Node *) newexpr;
2866 }
2867 case T_Aggref:
2868 node = ece_generic_processing(node);
2869 if (context->root != NULL)
2870 return simplify_aggref((Aggref *) node, context);
2871 return node;
2872 case T_OpExpr:
2873 {
2874 OpExpr *expr = (OpExpr *) node;
2875 List *args = expr->args;
2876 Expr *simple;
2877 OpExpr *newexpr;
2878
2879 /*
2880 * Need to get OID of underlying function. Okay to scribble
2881 * on input to this extent.
2882 */
2883 set_opfuncid(expr);
2884
2885 /*
2886 * Code for op/func reduction is pretty bulky, so split it out
2887 * as a separate function.
2888 */
2889 simple = simplify_function(expr->opfuncid,
2890 expr->opresulttype, -1,
2891 expr->opcollid,
2892 expr->inputcollid,
2893 &args,
2894 false,
2895 true,
2896 true,
2897 context);
2898 if (simple) /* successfully simplified it */
2899 return (Node *) simple;
2900
2901 /*
2902 * If the operator is boolean equality or inequality, we know
2903 * how to simplify cases involving one constant and one
2904 * non-constant argument.
2905 */
2906 if (expr->opno == BooleanEqualOperator ||
2908 {
2909 simple = (Expr *) simplify_boolean_equality(expr->opno,
2910 args);
2911 if (simple) /* successfully simplified it */
2912 return (Node *) simple;
2913 }
2914
2915 /*
2916 * The expression cannot be simplified any further, so build
2917 * and return a replacement OpExpr node using the
2918 * possibly-simplified arguments.
2919 */
2921 newexpr->opno = expr->opno;
2922 newexpr->opfuncid = expr->opfuncid;
2923 newexpr->opresulttype = expr->opresulttype;
2924 newexpr->opretset = expr->opretset;
2925 newexpr->opcollid = expr->opcollid;
2926 newexpr->inputcollid = expr->inputcollid;
2927 newexpr->args = args;
2928 newexpr->location = expr->location;
2929 return (Node *) newexpr;
2930 }
2931 case T_DistinctExpr:
2932 {
2933 DistinctExpr *expr = (DistinctExpr *) node;
2934 List *args;
2935 ListCell *arg;
2936 bool has_null_input = false;
2937 bool all_null_input = true;
2938 bool has_nonconst_input = false;
2939 bool has_nullable_nonconst = false;
2940 Expr *simple;
2942
2943 /*
2944 * Reduce constants in the DistinctExpr's arguments. We know
2945 * args is either NIL or a List node, so we can call
2946 * expression_tree_mutator directly rather than recursing to
2947 * self.
2948 */
2949 args = (List *) expression_tree_mutator((Node *) expr->args,
2951 context);
2952
2953 /*
2954 * We must do our own check for NULLs because DistinctExpr has
2955 * different results for NULL input than the underlying
2956 * operator does. We also check if any non-constant input is
2957 * potentially nullable.
2958 */
2959 foreach(arg, args)
2960 {
2961 if (IsA(lfirst(arg), Const))
2962 {
2965 }
2966 else
2967 {
2968 has_nonconst_input = true;
2969 all_null_input = false;
2970
2971 if (!has_nullable_nonconst &&
2972 !expr_is_nonnullable(context->root,
2973 (Expr *) lfirst(arg),
2975 has_nullable_nonconst = true;
2976 }
2977 }
2978
2979 if (!has_nonconst_input)
2980 {
2981 /*
2982 * All inputs are constants. We can optimize this out
2983 * completely.
2984 */
2985
2986 /* all nulls? then not distinct */
2987 if (all_null_input)
2988 return makeBoolConst(false, false);
2989
2990 /* one null? then distinct */
2991 if (has_null_input)
2992 return makeBoolConst(true, false);
2993
2994 /* otherwise try to evaluate the '=' operator */
2995 /* (NOT okay to try to inline it, though!) */
2996
2997 /*
2998 * Need to get OID of underlying function. Okay to
2999 * scribble on input to this extent.
3000 */
3001 set_opfuncid((OpExpr *) expr); /* rely on struct
3002 * equivalence */
3003
3004 /*
3005 * Code for op/func reduction is pretty bulky, so split it
3006 * out as a separate function.
3007 */
3008 simple = simplify_function(expr->opfuncid,
3009 expr->opresulttype, -1,
3010 expr->opcollid,
3011 expr->inputcollid,
3012 &args,
3013 false,
3014 false,
3015 false,
3016 context);
3017 if (simple) /* successfully simplified it */
3018 {
3019 /*
3020 * Since the underlying operator is "=", must negate
3021 * its result
3022 */
3023 Const *csimple = castNode(Const, simple);
3024
3025 csimple->constvalue =
3026 BoolGetDatum(!DatumGetBool(csimple->constvalue));
3027 return (Node *) csimple;
3028 }
3029 }
3030 else if (!has_nullable_nonconst)
3031 {
3032 /*
3033 * There are non-constant inputs, but since all of them
3034 * are proven non-nullable, "IS DISTINCT FROM" semantics
3035 * are much simpler.
3036 */
3037
3038 OpExpr *eqexpr;
3039
3040 /*
3041 * If one input is an explicit NULL constant, and the
3042 * other is a non-nullable expression, the result is
3043 * always TRUE.
3044 */
3045 if (has_null_input)
3046 return makeBoolConst(true, false);
3047
3048 /*
3049 * Otherwise, both inputs are known non-nullable. In this
3050 * case, "IS DISTINCT FROM" is equivalent to the standard
3051 * inequality operator (usually "<>"). We convert this to
3052 * an OpExpr, which is a more efficient representation for
3053 * the planner. It can enable the use of partial indexes
3054 * and constraint exclusion. Furthermore, if the clause
3055 * is negated (ie, "IS NOT DISTINCT FROM"), the resulting
3056 * "=" operator can allow the planner to use index scans,
3057 * merge joins, hash joins, and EC-based qual deductions.
3058 */
3060 eqexpr->opno = expr->opno;
3061 eqexpr->opfuncid = expr->opfuncid;
3062 eqexpr->opresulttype = BOOLOID;
3063 eqexpr->opretset = expr->opretset;
3064 eqexpr->opcollid = expr->opcollid;
3065 eqexpr->inputcollid = expr->inputcollid;
3066 eqexpr->args = args;
3067 eqexpr->location = expr->location;
3068
3070 context);
3071 }
3072 else if (has_null_input)
3073 {
3074 /*
3075 * One input is a nullable non-constant expression, and
3076 * the other is an explicit NULL constant. We can
3077 * transform this to a NullTest with !argisrow, which is
3078 * much more amenable to optimization.
3079 */
3080
3082
3083 nt->arg = (Expr *) (IsA(linitial(args), Const) ?
3084 lsecond(args) : linitial(args));
3085 nt->nulltesttype = IS_NOT_NULL;
3086
3087 /*
3088 * argisrow = false is correct whether or not arg is
3089 * composite
3090 */
3091 nt->argisrow = false;
3092 nt->location = expr->location;
3093
3094 return eval_const_expressions_mutator((Node *) nt, context);
3095 }
3096
3097 /*
3098 * The expression cannot be simplified any further, so build
3099 * and return a replacement DistinctExpr node using the
3100 * possibly-simplified arguments.
3101 */
3103 newexpr->opno = expr->opno;
3104 newexpr->opfuncid = expr->opfuncid;
3105 newexpr->opresulttype = expr->opresulttype;
3106 newexpr->opretset = expr->opretset;
3107 newexpr->opcollid = expr->opcollid;
3108 newexpr->inputcollid = expr->inputcollid;
3109 newexpr->args = args;
3110 newexpr->location = expr->location;
3111 return (Node *) newexpr;
3112 }
3113 case T_NullIfExpr:
3114 {
3115 NullIfExpr *expr;
3116 ListCell *arg;
3117 bool has_nonconst_input = false;
3118
3119 /* Copy the node and const-simplify its arguments */
3120 expr = (NullIfExpr *) ece_generic_processing(node);
3121
3122 /* If either argument is NULL they can't be equal */
3123 foreach(arg, expr->args)
3124 {
3125 if (!IsA(lfirst(arg), Const))
3126 has_nonconst_input = true;
3127 else if (((Const *) lfirst(arg))->constisnull)
3128 return (Node *) linitial(expr->args);
3129 }
3130
3131 /*
3132 * Need to get OID of underlying function before checking if
3133 * the function is OK to evaluate.
3134 */
3135 set_opfuncid((OpExpr *) expr);
3136
3137 if (!has_nonconst_input &&
3138 ece_function_is_safe(expr->opfuncid, context))
3139 return ece_evaluate_expr(expr);
3140
3141 return (Node *) expr;
3142 }
3144 {
3145 ScalarArrayOpExpr *saop;
3146
3147 /* Copy the node and const-simplify its arguments */
3149
3150 /* Make sure we know underlying function */
3151 set_sa_opfuncid(saop);
3152
3153 /*
3154 * If all arguments are Consts, and it's a safe function, we
3155 * can fold to a constant
3156 */
3157 if (ece_all_arguments_const(saop) &&
3158 ece_function_is_safe(saop->opfuncid, context))
3159 return ece_evaluate_expr(saop);
3160 return (Node *) saop;
3161 }
3162 case T_BoolExpr:
3163 {
3164 BoolExpr *expr = (BoolExpr *) node;
3165
3166 switch (expr->boolop)
3167 {
3168 case OR_EXPR:
3169 {
3170 List *newargs;
3171 bool haveNull = false;
3172 bool forceTrue = false;
3173
3175 context,
3176 &haveNull,
3177 &forceTrue);
3178 if (forceTrue)
3179 return makeBoolConst(true, false);
3180 if (haveNull)
3182 makeBoolConst(false, true));
3183 /* If all the inputs are FALSE, result is FALSE */
3184 if (newargs == NIL)
3185 return makeBoolConst(false, false);
3186
3187 /*
3188 * If only one nonconst-or-NULL input, it's the
3189 * result
3190 */
3191 if (list_length(newargs) == 1)
3192 return (Node *) linitial(newargs);
3193 /* Else we still need an OR node */
3194 return (Node *) make_orclause(newargs);
3195 }
3196 case AND_EXPR:
3197 {
3198 List *newargs;
3199 bool haveNull = false;
3200 bool forceFalse = false;
3201
3203 context,
3204 &haveNull,
3205 &forceFalse);
3206 if (forceFalse)
3207 return makeBoolConst(false, false);
3208 if (haveNull)
3210 makeBoolConst(false, true));
3211 /* If all the inputs are TRUE, result is TRUE */
3212 if (newargs == NIL)
3213 return makeBoolConst(true, false);
3214
3215 /*
3216 * If only one nonconst-or-NULL input, it's the
3217 * result
3218 */
3219 if (list_length(newargs) == 1)
3220 return (Node *) linitial(newargs);
3221 /* Else we still need an AND node */
3222 return (Node *) make_andclause(newargs);
3223 }
3224 case NOT_EXPR:
3225 {
3226 Node *arg;
3227
3228 Assert(list_length(expr->args) == 1);
3230 context);
3231
3232 /*
3233 * Use negate_clause() to see if we can simplify
3234 * away the NOT.
3235 */
3236 return negate_clause(arg);
3237 }
3238 default:
3239 elog(ERROR, "unrecognized boolop: %d",
3240 (int) expr->boolop);
3241 break;
3242 }
3243 break;
3244 }
3245
3246 case T_JsonValueExpr:
3247 {
3248 JsonValueExpr *jve = (JsonValueExpr *) node;
3249 Node *raw_expr = (Node *) jve->raw_expr;
3250 Node *formatted_expr = (Node *) jve->formatted_expr;
3251
3252 /*
3253 * If we can fold formatted_expr to a constant, we can elide
3254 * the JsonValueExpr altogether. Otherwise we must process
3255 * raw_expr too. But JsonFormat is a flat node and requires
3256 * no simplification, only copying.
3257 */
3258 formatted_expr = eval_const_expressions_mutator(formatted_expr,
3259 context);
3260 if (formatted_expr && IsA(formatted_expr, Const))
3261 return formatted_expr;
3262
3263 raw_expr = eval_const_expressions_mutator(raw_expr, context);
3264
3265 return (Node *) makeJsonValueExpr((Expr *) raw_expr,
3266 (Expr *) formatted_expr,
3267 copyObject(jve->format));
3268 }
3269
3270 case T_SubPlan:
3272
3273 /*
3274 * Return a SubPlan unchanged --- too late to do anything with it.
3275 *
3276 * XXX should we ereport() here instead? Probably this routine
3277 * should never be invoked after SubPlan creation.
3278 */
3279 return node;
3280 case T_RelabelType:
3281 {
3282 RelabelType *relabel = (RelabelType *) node;
3283 Node *arg;
3284
3285 /* Simplify the input ... */
3287 context);
3288 /* ... and attach a new RelabelType node, if needed */
3289 return applyRelabelType(arg,
3290 relabel->resulttype,
3291 relabel->resulttypmod,
3292 relabel->resultcollid,
3293 relabel->relabelformat,
3294 relabel->location,
3295 true);
3296 }
3297 case T_CoerceViaIO:
3298 {
3299 CoerceViaIO *expr = (CoerceViaIO *) node;
3300 List *args;
3301 Oid outfunc;
3302 bool outtypisvarlena;
3303 Oid infunc;
3305 Expr *simple;
3307
3308 /* Make a List so we can use simplify_function */
3309 args = list_make1(expr->arg);
3310
3311 /*
3312 * CoerceViaIO represents calling the source type's output
3313 * function then the result type's input function. So, try to
3314 * simplify it as though it were a stack of two such function
3315 * calls. First we need to know what the functions are.
3316 *
3317 * Note that the coercion functions are assumed not to care
3318 * about input collation, so we just pass InvalidOid for that.
3319 */
3323 &infunc, &intypioparam);
3324
3325 simple = simplify_function(outfunc,
3326 CSTRINGOID, -1,
3327 InvalidOid,
3328 InvalidOid,
3329 &args,
3330 false,
3331 true,
3332 true,
3333 context);
3334 if (simple) /* successfully simplified output fn */
3335 {
3336 /*
3337 * Input functions may want 1 to 3 arguments. We always
3338 * supply all three, trusting that nothing downstream will
3339 * complain.
3340 */
3341 args = list_make3(simple,
3343 -1,
3344 InvalidOid,
3345 sizeof(Oid),
3347 false,
3348 true),
3350 -1,
3351 InvalidOid,
3352 sizeof(int32),
3353 Int32GetDatum(-1),
3354 false,
3355 true));
3356
3357 simple = simplify_function(infunc,
3358 expr->resulttype, -1,
3359 expr->resultcollid,
3360 InvalidOid,
3361 &args,
3362 false,
3363 false,
3364 true,
3365 context);
3366 if (simple) /* successfully simplified input fn */
3367 return (Node *) simple;
3368 }
3369
3370 /*
3371 * The expression cannot be simplified any further, so build
3372 * and return a replacement CoerceViaIO node using the
3373 * possibly-simplified argument.
3374 */
3376 newexpr->arg = (Expr *) linitial(args);
3377 newexpr->resulttype = expr->resulttype;
3378 newexpr->resultcollid = expr->resultcollid;
3379 newexpr->coerceformat = expr->coerceformat;
3380 newexpr->location = expr->location;
3381 return (Node *) newexpr;
3382 }
3383 case T_ArrayCoerceExpr:
3384 {
3387
3388 /*
3389 * Copy the node and const-simplify its arguments. We can't
3390 * use ece_generic_processing() here because we need to mess
3391 * with case_val only while processing the elemexpr.
3392 */
3393 memcpy(ac, node, sizeof(ArrayCoerceExpr));
3394 ac->arg = (Expr *)
3396 context);
3397
3398 /*
3399 * Set up for the CaseTestExpr node contained in the elemexpr.
3400 * We must prevent it from absorbing any outer CASE value.
3401 */
3402 save_case_val = context->case_val;
3403 context->case_val = NULL;
3404
3405 ac->elemexpr = (Expr *)
3407 context);
3408
3409 context->case_val = save_case_val;
3410
3411 /*
3412 * If constant argument and the per-element expression is
3413 * immutable, we can simplify the whole thing to a constant.
3414 * Exception: although contain_mutable_functions considers
3415 * CoerceToDomain immutable for historical reasons, let's not
3416 * do so here; this ensures coercion to an array-over-domain
3417 * does not apply the domain's constraints until runtime.
3418 */
3419 if (ac->arg && IsA(ac->arg, Const) &&
3420 ac->elemexpr && !IsA(ac->elemexpr, CoerceToDomain) &&
3421 !contain_mutable_functions((Node *) ac->elemexpr))
3422 return ece_evaluate_expr(ac);
3423
3424 return (Node *) ac;
3425 }
3426 case T_CollateExpr:
3427 {
3428 /*
3429 * We replace CollateExpr with RelabelType, so as to improve
3430 * uniformity of expression representation and thus simplify
3431 * comparison of expressions. Hence this looks very nearly
3432 * the same as the RelabelType case, and we can apply the same
3433 * optimizations to avoid unnecessary RelabelTypes.
3434 */
3435 CollateExpr *collate = (CollateExpr *) node;
3436 Node *arg;
3437
3438 /* Simplify the input ... */
3440 context);
3441 /* ... and attach a new RelabelType node, if needed */
3442 return applyRelabelType(arg,
3443 exprType(arg),
3444 exprTypmod(arg),
3445 collate->collOid,
3447 collate->location,
3448 true);
3449 }
3450 case T_CaseExpr:
3451 {
3452 /*----------
3453 * CASE expressions can be simplified if there are constant
3454 * condition clauses:
3455 * FALSE (or NULL): drop the alternative
3456 * TRUE: drop all remaining alternatives
3457 * If the first non-FALSE alternative is a constant TRUE,
3458 * we can simplify the entire CASE to that alternative's
3459 * expression. If there are no non-FALSE alternatives,
3460 * we simplify the entire CASE to the default result (ELSE).
3461 *
3462 * If we have a simple-form CASE with constant test
3463 * expression, we substitute the constant value for contained
3464 * CaseTestExpr placeholder nodes, so that we have the
3465 * opportunity to reduce constant test conditions. For
3466 * example this allows
3467 * CASE 0 WHEN 0 THEN 1 ELSE 1/0 END
3468 * to reduce to 1 rather than drawing a divide-by-0 error.
3469 * Note that when the test expression is constant, we don't
3470 * have to include it in the resulting CASE; for example
3471 * CASE 0 WHEN x THEN y ELSE z END
3472 * is transformed by the parser to
3473 * CASE 0 WHEN CaseTestExpr = x THEN y ELSE z END
3474 * which we can simplify to
3475 * CASE WHEN 0 = x THEN y ELSE z END
3476 * It is not necessary for the executor to evaluate the "arg"
3477 * expression when executing the CASE, since any contained
3478 * CaseTestExprs that might have referred to it will have been
3479 * replaced by the constant.
3480 *----------
3481 */
3482 CaseExpr *caseexpr = (CaseExpr *) node;
3485 Node *newarg;
3486 List *newargs;
3487 bool const_true_cond;
3488 Node *defresult = NULL;
3489 ListCell *arg;
3490
3491 /* Simplify the test expression, if any */
3493 context);
3494
3495 /* Set up for contained CaseTestExpr nodes */
3496 save_case_val = context->case_val;
3497 if (newarg && IsA(newarg, Const))
3498 {
3499 context->case_val = newarg;
3500 newarg = NULL; /* not needed anymore, see above */
3501 }
3502 else
3503 context->case_val = NULL;
3504
3505 /* Simplify the WHEN clauses */
3506 newargs = NIL;
3507 const_true_cond = false;
3508 foreach(arg, caseexpr->args)
3509 {
3511 Node *casecond;
3513
3514 /* Simplify this alternative's test condition */
3516 context);
3517
3518 /*
3519 * If the test condition is constant FALSE (or NULL), then
3520 * drop this WHEN clause completely, without processing
3521 * the result.
3522 */
3523 if (casecond && IsA(casecond, Const))
3524 {
3526
3527 if (const_input->constisnull ||
3528 !DatumGetBool(const_input->constvalue))
3529 continue; /* drop alternative with FALSE cond */
3530 /* Else it's constant TRUE */
3531 const_true_cond = true;
3532 }
3533
3534 /* Simplify this alternative's result value */
3536 context);
3537
3538 /* If non-constant test condition, emit a new WHEN node */
3539 if (!const_true_cond)
3540 {
3542
3543 newcasewhen->expr = (Expr *) casecond;
3544 newcasewhen->result = (Expr *) caseresult;
3545 newcasewhen->location = oldcasewhen->location;
3547 continue;
3548 }
3549
3550 /*
3551 * Found a TRUE condition, so none of the remaining
3552 * alternatives can be reached. We treat the result as
3553 * the default result.
3554 */
3555 defresult = caseresult;
3556 break;
3557 }
3558
3559 /* Simplify the default result, unless we replaced it above */
3560 if (!const_true_cond)
3561 defresult = eval_const_expressions_mutator((Node *) caseexpr->defresult,
3562 context);
3563
3564 context->case_val = save_case_val;
3565
3566 /*
3567 * If no non-FALSE alternatives, CASE reduces to the default
3568 * result
3569 */
3570 if (newargs == NIL)
3571 return defresult;
3572 /* Otherwise we need a new CASE node */
3574 newcase->casetype = caseexpr->casetype;
3575 newcase->casecollid = caseexpr->casecollid;
3576 newcase->arg = (Expr *) newarg;
3577 newcase->args = newargs;
3578 newcase->defresult = (Expr *) defresult;
3579 newcase->location = caseexpr->location;
3580 return (Node *) newcase;
3581 }
3582 case T_CaseTestExpr:
3583 {
3584 /*
3585 * If we know a constant test value for the current CASE
3586 * construct, substitute it for the placeholder. Else just
3587 * return the placeholder as-is.
3588 */
3589 if (context->case_val)
3590 return copyObject(context->case_val);
3591 else
3592 return copyObject(node);
3593 }
3594 case T_SubscriptingRef:
3595 case T_ArrayExpr:
3596 case T_RowExpr:
3597 case T_MinMaxExpr:
3598 {
3599 /*
3600 * Generic handling for node types whose own processing is
3601 * known to be immutable, and for which we need no smarts
3602 * beyond "simplify if all inputs are constants".
3603 *
3604 * Treating SubscriptingRef this way assumes that subscripting
3605 * fetch and assignment are both immutable. This constrains
3606 * type-specific subscripting implementations; maybe we should
3607 * relax it someday.
3608 *
3609 * Treating MinMaxExpr this way amounts to assuming that the
3610 * btree comparison function it calls is immutable; see the
3611 * reasoning in contain_mutable_functions_walker.
3612 */
3613
3614 /* Copy the node and const-simplify its arguments */
3615 node = ece_generic_processing(node);
3616 /* If all arguments are Consts, we can fold to a constant */
3617 if (ece_all_arguments_const(node))
3618 return ece_evaluate_expr(node);
3619 return node;
3620 }
3621 case T_CoalesceExpr:
3622 {
3625 List *newargs;
3626 ListCell *arg;
3627
3628 newargs = NIL;
3629 foreach(arg, coalesceexpr->args)
3630 {
3631 Node *e;
3632
3634 context);
3635
3636 /*
3637 * We can remove null constants from the list. For a
3638 * nonnullable expression, if it has not been preceded by
3639 * any non-null-constant expressions then it is the
3640 * result. Otherwise, it's the next argument, but we can
3641 * drop following arguments since they will never be
3642 * reached.
3643 */
3644 if (IsA(e, Const))
3645 {
3646 if (((Const *) e)->constisnull)
3647 continue; /* drop null constant */
3648 if (newargs == NIL)
3649 return e; /* first expr */
3651 break;
3652 }
3653 if (expr_is_nonnullable(context->root, (Expr *) e,
3655 {
3656 if (newargs == NIL)
3657 return e; /* first expr */
3659 break;
3660 }
3661
3663 }
3664
3665 /*
3666 * If all the arguments were constant null, the result is just
3667 * null
3668 */
3669 if (newargs == NIL)
3670 return (Node *) makeNullConst(coalesceexpr->coalescetype,
3671 -1,
3672 coalesceexpr->coalescecollid);
3673
3674 /*
3675 * If there's exactly one surviving argument, we no longer
3676 * need COALESCE at all: the result is that argument
3677 */
3678 if (list_length(newargs) == 1)
3679 return (Node *) linitial(newargs);
3680
3682 newcoalesce->coalescetype = coalesceexpr->coalescetype;
3683 newcoalesce->coalescecollid = coalesceexpr->coalescecollid;
3684 newcoalesce->args = newargs;
3685 newcoalesce->location = coalesceexpr->location;
3686 return (Node *) newcoalesce;
3687 }
3688 case T_SQLValueFunction:
3689 {
3690 /*
3691 * All variants of SQLValueFunction are stable, so if we are
3692 * estimating the expression's value, we should evaluate the
3693 * current function value. Otherwise just copy.
3694 */
3695 SQLValueFunction *svf = (SQLValueFunction *) node;
3696
3697 if (context->estimate)
3698 return (Node *) evaluate_expr((Expr *) svf,
3699 svf->type,
3700 svf->typmod,
3701 InvalidOid);
3702 else
3703 return copyObject((Node *) svf);
3704 }
3705 case T_FieldSelect:
3706 {
3707 /*
3708 * We can optimize field selection from a whole-row Var into a
3709 * simple Var. (This case won't be generated directly by the
3710 * parser, because ParseComplexProjection short-circuits it.
3711 * But it can arise while simplifying functions.) Also, we
3712 * can optimize field selection from a RowExpr construct, or
3713 * of course from a constant.
3714 *
3715 * However, replacing a whole-row Var in this way has a
3716 * pitfall: if we've already built the rel targetlist for the
3717 * source relation, then the whole-row Var is scheduled to be
3718 * produced by the relation scan, but the simple Var probably
3719 * isn't, which will lead to a failure in setrefs.c. This is
3720 * not a problem when handling simple single-level queries, in
3721 * which expression simplification always happens first. It
3722 * is a risk for lateral references from subqueries, though.
3723 * To avoid such failures, don't optimize uplevel references.
3724 *
3725 * We must also check that the declared type of the field is
3726 * still the same as when the FieldSelect was created --- this
3727 * can change if someone did ALTER COLUMN TYPE on the rowtype.
3728 * If it isn't, we skip the optimization; the case will
3729 * probably fail at runtime, but that's not our problem here.
3730 */
3731 FieldSelect *fselect = (FieldSelect *) node;
3733 Node *arg;
3734
3736 context);
3737 if (arg && IsA(arg, Var) &&
3738 ((Var *) arg)->varattno == InvalidAttrNumber &&
3739 ((Var *) arg)->varlevelsup == 0)
3740 {
3741 if (rowtype_field_matches(((Var *) arg)->vartype,
3742 fselect->fieldnum,
3743 fselect->resulttype,
3744 fselect->resulttypmod,
3745 fselect->resultcollid))
3746 {
3747 Var *newvar;
3748
3749 newvar = makeVar(((Var *) arg)->varno,
3750 fselect->fieldnum,
3751 fselect->resulttype,
3752 fselect->resulttypmod,
3753 fselect->resultcollid,
3754 ((Var *) arg)->varlevelsup);
3755 /* New Var has same OLD/NEW returning as old one */
3756 newvar->varreturningtype = ((Var *) arg)->varreturningtype;
3757 /* New Var is nullable by same rels as the old one */
3758 newvar->varnullingrels = ((Var *) arg)->varnullingrels;
3759 return (Node *) newvar;
3760 }
3761 }
3762 if (arg && IsA(arg, RowExpr))
3763 {
3764 RowExpr *rowexpr = (RowExpr *) arg;
3765
3766 if (fselect->fieldnum > 0 &&
3767 fselect->fieldnum <= list_length(rowexpr->args))
3768 {
3769 Node *fld = (Node *) list_nth(rowexpr->args,
3770 fselect->fieldnum - 1);
3771
3772 if (rowtype_field_matches(rowexpr->row_typeid,
3773 fselect->fieldnum,
3774 fselect->resulttype,
3775 fselect->resulttypmod,
3776 fselect->resultcollid) &&
3777 fselect->resulttype == exprType(fld) &&
3778 fselect->resulttypmod == exprTypmod(fld) &&
3779 fselect->resultcollid == exprCollation(fld))
3780 return fld;
3781 }
3782 }
3784 newfselect->arg = (Expr *) arg;
3785 newfselect->fieldnum = fselect->fieldnum;
3786 newfselect->resulttype = fselect->resulttype;
3787 newfselect->resulttypmod = fselect->resulttypmod;
3788 newfselect->resultcollid = fselect->resultcollid;
3789 if (arg && IsA(arg, Const))
3790 {
3791 Const *con = (Const *) arg;
3792
3794 newfselect->fieldnum,
3795 newfselect->resulttype,
3796 newfselect->resulttypmod,
3797 newfselect->resultcollid))
3799 }
3800 return (Node *) newfselect;
3801 }
3802 case T_NullTest:
3803 {
3804 NullTest *ntest = (NullTest *) node;
3806 Node *arg;
3807
3809 context);
3810 if (ntest->argisrow && arg && IsA(arg, RowExpr))
3811 {
3812 /*
3813 * We break ROW(...) IS [NOT] NULL into separate tests on
3814 * its component fields. This form is usually more
3815 * efficient to evaluate, as well as being more amenable
3816 * to optimization.
3817 */
3818 RowExpr *rarg = (RowExpr *) arg;
3819 List *newargs = NIL;
3820 ListCell *l;
3821
3822 foreach(l, rarg->args)
3823 {
3824 Node *relem = (Node *) lfirst(l);
3825
3826 /*
3827 * A constant field refutes the whole NullTest if it's
3828 * of the wrong nullness; else we can discard it.
3829 */
3830 if (relem && IsA(relem, Const))
3831 {
3832 Const *carg = (Const *) relem;
3833
3834 if (carg->constisnull ?
3835 (ntest->nulltesttype == IS_NOT_NULL) :
3836 (ntest->nulltesttype == IS_NULL))
3837 return makeBoolConst(false, false);
3838 continue;
3839 }
3840
3841 /*
3842 * A proven non-nullable field refutes the whole
3843 * NullTest if the test is IS NULL; else we can
3844 * discard it.
3845 */
3846 if (relem &&
3847 expr_is_nonnullable(context->root, (Expr *) relem,
3849 {
3850 if (ntest->nulltesttype == IS_NULL)
3851 return makeBoolConst(false, false);
3852 continue;
3853 }
3854
3855 /*
3856 * Else, make a scalar (argisrow == false) NullTest
3857 * for this field. Scalar semantics are required
3858 * because IS [NOT] NULL doesn't recurse; see comments
3859 * in ExecEvalRowNullInt().
3860 */
3862 newntest->arg = (Expr *) relem;
3863 newntest->nulltesttype = ntest->nulltesttype;
3864 newntest->argisrow = false;
3865 newntest->location = ntest->location;
3867 }
3868 /* If all the inputs were constants, result is TRUE */
3869 if (newargs == NIL)
3870 return makeBoolConst(true, false);
3871 /* If only one nonconst input, it's the result */
3872 if (list_length(newargs) == 1)
3873 return (Node *) linitial(newargs);
3874 /* Else we need an AND node */
3875 return (Node *) make_andclause(newargs);
3876 }
3877 if (!ntest->argisrow && arg && IsA(arg, Const))
3878 {
3879 Const *carg = (Const *) arg;
3880 bool result;
3881
3882 switch (ntest->nulltesttype)
3883 {
3884 case IS_NULL:
3885 result = carg->constisnull;
3886 break;
3887 case IS_NOT_NULL:
3888 result = !carg->constisnull;
3889 break;
3890 default:
3891 elog(ERROR, "unrecognized nulltesttype: %d",
3892 (int) ntest->nulltesttype);
3893 result = false; /* keep compiler quiet */
3894 break;
3895 }
3896
3897 return makeBoolConst(result, false);
3898 }
3899 if (!ntest->argisrow && arg &&
3900 expr_is_nonnullable(context->root, (Expr *) arg,
3902 {
3903 bool result;
3904
3905 switch (ntest->nulltesttype)
3906 {
3907 case IS_NULL:
3908 result = false;
3909 break;
3910 case IS_NOT_NULL:
3911 result = true;
3912 break;
3913 default:
3914 elog(ERROR, "unrecognized nulltesttype: %d",
3915 (int) ntest->nulltesttype);
3916 result = false; /* keep compiler quiet */
3917 break;
3918 }
3919
3920 return makeBoolConst(result, false);
3921 }
3922
3924 newntest->arg = (Expr *) arg;
3925 newntest->nulltesttype = ntest->nulltesttype;
3926 newntest->argisrow = ntest->argisrow;
3927 newntest->location = ntest->location;
3928 return (Node *) newntest;
3929 }
3930 case T_BooleanTest:
3931 {
3932 /*
3933 * This case could be folded into the generic handling used
3934 * for ArrayExpr etc. But because the simplification logic is
3935 * so trivial, applying evaluate_expr() to perform it would be
3936 * a heavy overhead. BooleanTest is probably common enough to
3937 * justify keeping this bespoke implementation.
3938 */
3939 BooleanTest *btest = (BooleanTest *) node;
3941 Node *arg;
3942
3944 context);
3945 if (arg && IsA(arg, Const))
3946 {
3947 /*
3948 * If arg is Const, simplify to constant.
3949 */
3950 Const *carg = (Const *) arg;
3951 bool result;
3952
3953 switch (btest->booltesttype)
3954 {
3955 case IS_TRUE:
3956 result = (!carg->constisnull &&
3957 DatumGetBool(carg->constvalue));
3958 break;
3959 case IS_NOT_TRUE:
3960 result = (carg->constisnull ||
3961 !DatumGetBool(carg->constvalue));
3962 break;
3963 case IS_FALSE:
3964 result = (!carg->constisnull &&
3965 !DatumGetBool(carg->constvalue));
3966 break;
3967 case IS_NOT_FALSE:
3968 result = (carg->constisnull ||
3969 DatumGetBool(carg->constvalue));
3970 break;
3971 case IS_UNKNOWN:
3972 result = carg->constisnull;
3973 break;
3974 case IS_NOT_UNKNOWN:
3975 result = !carg->constisnull;
3976 break;
3977 default:
3978 elog(ERROR, "unrecognized booltesttype: %d",
3979 (int) btest->booltesttype);
3980 result = false; /* keep compiler quiet */
3981 break;
3982 }
3983
3984 return makeBoolConst(result, false);
3985 }
3986 if (arg &&
3987 expr_is_nonnullable(context->root, (Expr *) arg,
3989 {
3990 /*
3991 * If arg is proven non-nullable, simplify to boolean
3992 * expression or constant.
3993 */
3994 switch (btest->booltesttype)
3995 {
3996 case IS_TRUE:
3997 case IS_NOT_FALSE:
3998 return arg;
3999
4000 case IS_FALSE:
4001 case IS_NOT_TRUE:
4002 return (Node *) make_notclause((Expr *) arg);
4003
4004 case IS_UNKNOWN:
4005 return makeBoolConst(false, false);
4006
4007 case IS_NOT_UNKNOWN:
4008 return makeBoolConst(true, false);
4009
4010 default:
4011 elog(ERROR, "unrecognized booltesttype: %d",
4012 (int) btest->booltesttype);
4013 break;
4014 }
4015 }
4016
4018 newbtest->arg = (Expr *) arg;
4019 newbtest->booltesttype = btest->booltesttype;
4020 newbtest->location = btest->location;
4021 return (Node *) newbtest;
4022 }
4023 case T_CoerceToDomain:
4024 {
4025 /*
4026 * If the domain currently has no constraints, we replace the
4027 * CoerceToDomain node with a simple RelabelType, which is
4028 * both far faster to execute and more amenable to later
4029 * optimization. We must then mark the plan as needing to be
4030 * rebuilt if the domain's constraints change.
4031 *
4032 * Also, in estimation mode, always replace CoerceToDomain
4033 * nodes, effectively assuming that the coercion will succeed.
4034 */
4037 Node *arg;
4038
4040 context);
4041 if (context->estimate ||
4042 !DomainHasConstraints(cdomain->resulttype))
4043 {
4044 /* Record dependency, if this isn't estimation mode */
4045 if (context->root && !context->estimate)
4047 cdomain->resulttype);
4048
4049 /* Generate RelabelType to substitute for CoerceToDomain */
4050 return applyRelabelType(arg,
4051 cdomain->resulttype,
4052 cdomain->resulttypmod,
4053 cdomain->resultcollid,
4054 cdomain->coercionformat,
4055 cdomain->location,
4056 true);
4057 }
4058
4060 newcdomain->arg = (Expr *) arg;
4061 newcdomain->resulttype = cdomain->resulttype;
4062 newcdomain->resulttypmod = cdomain->resulttypmod;
4063 newcdomain->resultcollid = cdomain->resultcollid;
4064 newcdomain->coercionformat = cdomain->coercionformat;
4065 newcdomain->location = cdomain->location;
4066 return (Node *) newcdomain;
4067 }
4068 case T_PlaceHolderVar:
4069
4070 /*
4071 * In estimation mode, just strip the PlaceHolderVar node
4072 * altogether; this amounts to estimating that the contained value
4073 * won't be forced to null by an outer join. In regular mode we
4074 * just use the default behavior (ie, simplify the expression but
4075 * leave the PlaceHolderVar node intact).
4076 */
4077 if (context->estimate)
4078 {
4079 PlaceHolderVar *phv = (PlaceHolderVar *) node;
4080
4081 return eval_const_expressions_mutator((Node *) phv->phexpr,
4082 context);
4083 }
4084 break;
4086 {
4088 Node *arg;
4090
4092 context);
4093
4095 newcre->resulttype = cre->resulttype;
4096 newcre->convertformat = cre->convertformat;
4097 newcre->location = cre->location;
4098
4099 /*
4100 * In case of a nested ConvertRowtypeExpr, we can convert the
4101 * leaf row directly to the topmost row format without any
4102 * intermediate conversions. (This works because
4103 * ConvertRowtypeExpr is used only for child->parent
4104 * conversion in inheritance trees, which works by exact match
4105 * of column name, and a column absent in an intermediate
4106 * result can't be present in the final result.)
4107 *
4108 * No need to check more than one level deep, because the
4109 * above recursion will have flattened anything else.
4110 */
4111 if (arg != NULL && IsA(arg, ConvertRowtypeExpr))
4112 {
4114
4115 arg = (Node *) argcre->arg;
4116
4117 /*
4118 * Make sure an outer implicit conversion can't hide an
4119 * inner explicit one.
4120 */
4121 if (newcre->convertformat == COERCE_IMPLICIT_CAST)
4122 newcre->convertformat = argcre->convertformat;
4123 }
4124
4125 newcre->arg = (Expr *) arg;
4126
4127 if (arg != NULL && IsA(arg, Const))
4128 return ece_evaluate_expr((Node *) newcre);
4129 return (Node *) newcre;
4130 }
4131 default:
4132 break;
4133 }
4134
4135 /*
4136 * For any node type not handled above, copy the node unchanged but
4137 * const-simplify its subexpressions. This is the correct thing for node
4138 * types whose behavior might change between planning and execution, such
4139 * as CurrentOfExpr. It's also a safe default for new node types not
4140 * known to this routine.
4141 */
4142 return ece_generic_processing(node);
4143}

References WindowFunc::aggfilter, AND_EXPR, applyRelabelType(), arg, CoerceViaIO::arg, ConvertRowtypeExpr::arg, CollateExpr::arg, WindowFunc::args, FuncExpr::args, OpExpr::args, BoolExpr::args, RowExpr::args, Assert, BoolGetDatum(), BoolExpr::boolop, eval_const_expressions_context::boundParams, eval_const_expressions_context::case_val, castNode, check_stack_depth(), COERCE_IMPLICIT_CAST, CollateExpr::collOid, Const::consttype, contain_mutable_functions(), copyObject, datumCopy(), DatumGetBool(), DomainHasConstraints(), ece_all_arguments_const, ece_evaluate_expr, ece_function_is_safe(), ece_generic_processing, elog, ERROR, eval_const_expressions_context::estimate, eval_const_expressions_mutator(), evaluate_expr(), expand_function_arguments(), expr_is_nonnullable(), exprCollation(), expression_tree_mutator, exprType(), exprTypmod(), fb(), FuncExpr::funcid, get_typlenbyval(), getTypeInputInfo(), getTypeOutputInfo(), HeapTupleIsValid, WindowFunc::ignore_nulls, Int32GetDatum(), InvalidAttrNumber, InvalidOid, IS_FALSE, IS_NOT_FALSE, IS_NOT_NULL, IS_NOT_TRUE, IS_NOT_UNKNOWN, IS_NULL, IS_TRUE, IS_UNKNOWN, IsA, lappend(), lfirst, lfirst_node, linitial, list_length(), list_make1, list_make3, list_nth(), Param::location, WindowFunc::location, FuncExpr::location, OpExpr::location, CoerceViaIO::location, CollateExpr::location, lsecond, make_andclause(), make_notclause(), make_orclause(), makeBoolConst(), makeConst(), makeJsonValueExpr(), makeNode, makeNullConst(), makeVar(), negate_clause(), NIL, nodeTag, NOT_EXPR, NOTNULL_SOURCE_HASHTABLE, ParamListInfoData::numParams, ObjectIdGetDatum(), OidIsValid, OpExpr::opno, OR_EXPR, PARAM_EXTERN, PARAM_FLAG_CONST, Param::paramcollid, ParamListInfoData::paramFetch, Param::paramid, Param::paramkind, ParamListInfoData::params, Param::paramtype, Param::paramtypmod, record_plan_type_dependency(), ReleaseSysCache(), CoerceViaIO::resulttype, eval_const_expressions_context::root, rowtype_field_matches(), SearchSysCache1(), set_opfuncid(), set_sa_opfuncid(), simplify_aggref(), simplify_and_arguments(), simplify_boolean_equality(), simplify_function(), simplify_or_arguments(), SQLValueFunction::typmod, WindowFunc::winfnoid, and WindowFunc::winref.

Referenced by estimate_expression_value(), eval_const_expressions(), eval_const_expressions_mutator(), inline_function(), simplify_and_arguments(), simplify_function(), and simplify_or_arguments().

◆ evaluate_expr()

Expr * evaluate_expr ( Expr expr,
Oid  result_type,
int32  result_typmod,
Oid  result_collation 
)

Definition at line 5688 of file clauses.c.

5690{
5691 EState *estate;
5692 ExprState *exprstate;
5693 MemoryContext oldcontext;
5695 bool const_is_null;
5697 bool resultTypByVal;
5698
5699 /*
5700 * To use the executor, we need an EState.
5701 */
5702 estate = CreateExecutorState();
5703
5704 /* We can use the estate's working context to avoid memory leaks. */
5705 oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
5706
5707 /* Make sure any opfuncids are filled in. */
5708 fix_opfuncids((Node *) expr);
5709
5710 /*
5711 * Prepare expr for execution. (Note: we can't use ExecPrepareExpr
5712 * because it'd result in recursively invoking eval_const_expressions.)
5713 */
5714 exprstate = ExecInitExpr(expr, NULL);
5715
5716 /*
5717 * And evaluate it.
5718 *
5719 * It is OK to use a default econtext because none of the ExecEvalExpr()
5720 * code used in this situation will use econtext. That might seem
5721 * fortuitous, but it's not so unreasonable --- a constant expression does
5722 * not depend on context, by definition, n'est ce pas?
5723 */
5725 GetPerTupleExprContext(estate),
5726 &const_is_null);
5727
5728 /* Get info needed about result datatype */
5730
5731 /* Get back to outer memory context */
5732 MemoryContextSwitchTo(oldcontext);
5733
5734 /*
5735 * Must copy result out of sub-context used by expression eval.
5736 *
5737 * Also, if it's varlena, forcibly detoast it. This protects us against
5738 * storing TOAST pointers into plans that might outlive the referenced
5739 * data. (makeConst would handle detoasting anyway, but it's worth a few
5740 * extra lines here so that we can do the copy and detoast in one step.)
5741 */
5742 if (!const_is_null)
5743 {
5744 if (resultTypLen == -1)
5746 else
5748 }
5749
5750 /* Release all the junk we just created */
5751 FreeExecutorState(estate);
5752
5753 /*
5754 * Make the constant result node.
5755 */
5756 return (Expr *) makeConst(result_type, result_typmod, result_collation,
5760}

References CreateExecutorState(), datumCopy(), EState::es_query_cxt, ExecEvalExprSwitchContext(), ExecInitExpr(), fb(), fix_opfuncids(), FreeExecutorState(), get_typlenbyval(), GetPerTupleExprContext, makeConst(), MemoryContextSwitchTo(), PG_DETOAST_DATUM_COPY, and PointerGetDatum().

Referenced by eval_const_expressions_mutator(), evaluate_function(), and transformPartitionBoundValue().

◆ evaluate_function()

static Expr * evaluate_function ( Oid  funcid,
Oid  result_type,
int32  result_typmod,
Oid  result_collid,
Oid  input_collid,
List args,
bool  funcvariadic,
HeapTuple  func_tuple,
eval_const_expressions_context context 
)
static

Definition at line 5141 of file clauses.c.

5146{
5148 bool has_nonconst_input = false;
5149 bool has_null_input = false;
5150 ListCell *arg;
5152
5153 /*
5154 * Can't simplify if it returns a set.
5155 */
5156 if (funcform->proretset)
5157 return NULL;
5158
5159 /*
5160 * Can't simplify if it returns RECORD. The immediate problem is that it
5161 * will be needing an expected tupdesc which we can't supply here.
5162 *
5163 * In the case where it has OUT parameters, we could build an expected
5164 * tupdesc from those, but there may be other gotchas lurking. In
5165 * particular, if the function were to return NULL, we would produce a
5166 * null constant with no remaining indication of which concrete record
5167 * type it is. For now, seems best to leave the function call unreduced.
5168 */
5169 if (funcform->prorettype == RECORDOID)
5170 return NULL;
5171
5172 /*
5173 * Check for constant inputs and especially constant-NULL inputs.
5174 */
5175 foreach(arg, args)
5176 {
5177 if (IsA(lfirst(arg), Const))
5179 else
5180 has_nonconst_input = true;
5181 }
5182
5183 /*
5184 * If the function is strict and has a constant-NULL input, it will never
5185 * be called at all, so we can replace the call by a NULL constant, even
5186 * if there are other inputs that aren't constant, and even if the
5187 * function is not otherwise immutable.
5188 */
5189 if (funcform->proisstrict && has_null_input)
5190 return (Expr *) makeNullConst(result_type, result_typmod,
5192
5193 /*
5194 * Otherwise, can simplify only if all inputs are constants. (For a
5195 * non-strict function, constant NULL inputs are treated the same as
5196 * constant non-NULL inputs.)
5197 */
5199 return NULL;
5200
5201 /*
5202 * Ordinarily we are only allowed to simplify immutable functions. But for
5203 * purposes of estimation, we consider it okay to simplify functions that
5204 * are merely stable; the risk that the result might change from planning
5205 * time to execution time is worth taking in preference to not being able
5206 * to estimate the value at all.
5207 */
5208 if (funcform->provolatile == PROVOLATILE_IMMUTABLE)
5209 /* okay */ ;
5210 else if (context->estimate && funcform->provolatile == PROVOLATILE_STABLE)
5211 /* okay */ ;
5212 else
5213 return NULL;
5214
5215 /*
5216 * OK, looks like we can simplify this operator/function.
5217 *
5218 * Build a new FuncExpr node containing the already-simplified arguments.
5219 */
5221 newexpr->funcid = funcid;
5222 newexpr->funcresulttype = result_type;
5223 newexpr->funcretset = false;
5224 newexpr->funcvariadic = funcvariadic;
5225 newexpr->funcformat = COERCE_EXPLICIT_CALL; /* doesn't matter */
5226 newexpr->funccollid = result_collid; /* doesn't matter */
5227 newexpr->inputcollid = input_collid;
5228 newexpr->args = args;
5229 newexpr->location = -1;
5230
5231 return evaluate_expr((Expr *) newexpr, result_type, result_typmod,
5233}

References arg, COERCE_EXPLICIT_CALL, eval_const_expressions_context::estimate, evaluate_expr(), fb(), Form_pg_proc, GETSTRUCT(), IsA, lfirst, makeNode, and makeNullConst().

Referenced by simplify_function().

◆ expand_function_arguments()

List * expand_function_arguments ( List args,
bool  include_out_arguments,
Oid  result_type,
HeapTuple  func_tuple 
)

Definition at line 4891 of file clauses.c.

4893{
4895 Oid *proargtypes = funcform->proargtypes.values;
4896 int pronargs = funcform->pronargs;
4897 bool has_named_args = false;
4898 ListCell *lc;
4899
4900 /*
4901 * If we are asked to match to OUT arguments, then use the proallargtypes
4902 * array (which includes those); otherwise use proargtypes (which
4903 * doesn't). Of course, if proallargtypes is null, we always use
4904 * proargtypes. (Fetching proallargtypes is annoyingly expensive
4905 * considering that we may have nothing to do here, but fortunately the
4906 * common case is include_out_arguments == false.)
4907 */
4909 {
4911 bool isNull;
4912
4915 &isNull);
4916 if (!isNull)
4917 {
4919
4920 pronargs = ARR_DIMS(arr)[0];
4921 if (ARR_NDIM(arr) != 1 ||
4922 pronargs < 0 ||
4923 ARR_HASNULL(arr) ||
4924 ARR_ELEMTYPE(arr) != OIDOID)
4925 elog(ERROR, "proallargtypes is not a 1-D Oid array or it contains nulls");
4926 Assert(pronargs >= funcform->pronargs);
4927 proargtypes = (Oid *) ARR_DATA_PTR(arr);
4928 }
4929 }
4930
4931 /* Do we have any named arguments? */
4932 foreach(lc, args)
4933 {
4934 Node *arg = (Node *) lfirst(lc);
4935
4936 if (IsA(arg, NamedArgExpr))
4937 {
4938 has_named_args = true;
4939 break;
4940 }
4941 }
4942
4943 /* If so, we must apply reorder_function_arguments */
4944 if (has_named_args)
4945 {
4947 /* Recheck argument types and add casts if needed */
4948 recheck_cast_function_args(args, result_type,
4950 func_tuple);
4951 }
4952 else if (list_length(args) < pronargs)
4953 {
4954 /* No named args, but we seem to be short some defaults */
4956 /* Recheck argument types and add casts if needed */
4957 recheck_cast_function_args(args, result_type,
4959 func_tuple);
4960 }
4961
4962 return args;
4963}

References add_function_defaults(), arg, ARR_DATA_PTR, ARR_DIMS, ARR_ELEMTYPE, ARR_HASNULL, ARR_NDIM, Assert, DatumGetArrayTypeP, elog, ERROR, fb(), Form_pg_proc, GETSTRUCT(), IsA, lfirst, list_length(), pronargs, recheck_cast_function_args(), reorder_function_arguments(), and SysCacheGetAttr().

Referenced by eval_const_expressions_mutator(), simplify_function(), and transformCallStmt().

◆ expr_is_nonnullable()

bool expr_is_nonnullable ( PlannerInfo root,
Expr expr,
NotNullSource  source 
)

Definition at line 4749 of file clauses.c.

4750{
4751 /* since this function recurses, it could be driven to stack overflow */
4753
4754 switch (nodeTag(expr))
4755 {
4756 case T_Var:
4757 {
4758 if (root)
4759 return var_is_nonnullable(root, (Var *) expr, source);
4760 }
4761 break;
4762 case T_Const:
4763 return !((Const *) expr)->constisnull;
4764 case T_CoalesceExpr:
4765 {
4766 /*
4767 * A CoalesceExpr returns NULL if and only if all its
4768 * arguments are NULL. Therefore, we can determine that a
4769 * CoalesceExpr cannot be NULL if at least one of its
4770 * arguments can be proven non-nullable.
4771 */
4773
4775 {
4777 return true;
4778 }
4779 }
4780 break;
4781 case T_MinMaxExpr:
4782 {
4783 /*
4784 * Like CoalesceExpr, a MinMaxExpr returns NULL only if all
4785 * its arguments evaluate to NULL.
4786 */
4787 MinMaxExpr *minmaxexpr = (MinMaxExpr *) expr;
4788
4790 {
4792 return true;
4793 }
4794 }
4795 break;
4796 case T_CaseExpr:
4797 {
4798 /*
4799 * A CASE expression is non-nullable if all branch results are
4800 * non-nullable. We must also verify that the default result
4801 * (ELSE) exists and is non-nullable.
4802 */
4803 CaseExpr *caseexpr = (CaseExpr *) expr;
4804
4805 /* The default result must be present and non-nullable */
4806 if (caseexpr->defresult == NULL ||
4807 !expr_is_nonnullable(root, caseexpr->defresult, source))
4808 return false;
4809
4810 /* All branch results must be non-nullable */
4812 {
4813 if (!expr_is_nonnullable(root, casewhen->result, source))
4814 return false;
4815 }
4816
4817 return true;
4818 }
4819 break;
4820 case T_ArrayExpr:
4821 {
4822 /*
4823 * An ARRAY[] expression always returns a valid Array object,
4824 * even if it is empty (ARRAY[]) or contains NULLs
4825 * (ARRAY[NULL]). It never evaluates to a SQL NULL.
4826 */
4827 return true;
4828 }
4829 case T_NullTest:
4830 {
4831 /*
4832 * An IS NULL / IS NOT NULL expression always returns a
4833 * boolean value. It never returns SQL NULL.
4834 */
4835 return true;
4836 }
4837 case T_BooleanTest:
4838 {
4839 /*
4840 * A BooleanTest expression always evaluates to a boolean
4841 * value. It never returns SQL NULL.
4842 */
4843 return true;
4844 }
4845 case T_DistinctExpr:
4846 {
4847 /*
4848 * IS DISTINCT FROM never returns NULL, effectively acting as
4849 * though NULL were a normal data value.
4850 */
4851 return true;
4852 }
4853 case T_RelabelType:
4854 {
4855 /*
4856 * RelabelType does not change the nullability of the data.
4857 * The result is non-nullable if and only if the argument is
4858 * non-nullable.
4859 */
4860 return expr_is_nonnullable(root, ((RelabelType *) expr)->arg,
4861 source);
4862 }
4863 default:
4864 break;
4865 }
4866
4867 return false;
4868}

References arg, check_stack_depth(), expr_is_nonnullable(), fb(), foreach_ptr, nodeTag, root, source, and var_is_nonnullable().

Referenced by eval_const_expressions_mutator(), expr_is_nonnullable(), int8inc_support(), query_outputs_are_not_nullable(), restriction_is_always_false(), restriction_is_always_true(), and sublink_testexpr_is_not_nullable().

◆ expression_returns_set_rows()

double expression_returns_set_rows ( PlannerInfo root,
Node clause 
)

Definition at line 300 of file clauses.c.

301{
302 if (clause == NULL)
303 return 1.0;
304 if (IsA(clause, FuncExpr))
305 {
306 FuncExpr *expr = (FuncExpr *) clause;
307
308 if (expr->funcretset)
309 return clamp_row_est(get_function_rows(root, expr->funcid, clause));
310 }
311 if (IsA(clause, OpExpr))
312 {
313 OpExpr *expr = (OpExpr *) clause;
314
315 if (expr->opretset)
316 {
317 set_opfuncid(expr);
318 return clamp_row_est(get_function_rows(root, expr->opfuncid, clause));
319 }
320 }
321 return 1.0;
322}
double clamp_row_est(double nrows)
Definition costsize.c:213
double get_function_rows(PlannerInfo *root, Oid funcid, Node *node)
Definition plancat.c:2416

References clamp_row_est(), fb(), FuncExpr::funcid, get_function_rows(), IsA, root, and set_opfuncid().

Referenced by create_set_projection_path(), estimate_num_groups(), and set_function_size_estimates().

◆ fetch_function_defaults()

static List * fetch_function_defaults ( HeapTuple  func_tuple)
static

Definition at line 5066 of file clauses.c.

5067{
5068 List *defaults;
5070 char *str;
5071
5075 defaults = castNode(List, stringToNode(str));
5076 pfree(str);
5077 return defaults;
5078}

References castNode, fb(), pfree(), str, stringToNode(), SysCacheGetAttrNotNull(), and TextDatumGetCString.

Referenced by add_function_defaults(), and reorder_function_arguments().

◆ find_forced_null_var()

Var * find_forced_null_var ( Node node)

Definition at line 1995 of file clauses.c.

1996{
1997 if (node == NULL)
1998 return NULL;
1999 if (IsA(node, NullTest))
2000 {
2001 /* check for var IS NULL */
2002 NullTest *expr = (NullTest *) node;
2003
2004 if (expr->nulltesttype == IS_NULL && !expr->argisrow)
2005 {
2006 Var *var = (Var *) expr->arg;
2007
2008 if (var && IsA(var, Var) &&
2009 var->varlevelsup == 0)
2010 return var;
2011 }
2012 }
2013 else if (IsA(node, BooleanTest))
2014 {
2015 /* var IS UNKNOWN is equivalent to var IS NULL */
2016 BooleanTest *expr = (BooleanTest *) node;
2017
2018 if (expr->booltesttype == IS_UNKNOWN)
2019 {
2020 Var *var = (Var *) expr->arg;
2021
2022 if (var && IsA(var, Var) &&
2023 var->varlevelsup == 0)
2024 return var;
2025 }
2026 }
2027 return NULL;
2028}
BoolTestType booltesttype
Definition primnodes.h:2009
NullTestType nulltesttype
Definition primnodes.h:1985
Expr * arg
Definition primnodes.h:1984

References NullTest::arg, BooleanTest::arg, BooleanTest::booltesttype, fb(), IS_NULL, IS_UNKNOWN, IsA, NullTest::nulltesttype, and Var::varlevelsup.

Referenced by check_redundant_nullability_qual(), and find_forced_null_vars().

◆ find_forced_null_vars()

List * find_forced_null_vars ( Node node)

Definition at line 1934 of file clauses.c.

1935{
1936 List *result = NIL;
1937 Var *var;
1938 ListCell *l;
1939
1940 if (node == NULL)
1941 return NIL;
1942 /* Check single-clause cases using subroutine */
1943 var = find_forced_null_var(node);
1944 if (var)
1945 {
1946 result = mbms_add_member(result,
1947 var->varno,
1949 }
1950 /* Otherwise, handle AND-conditions */
1951 else if (IsA(node, List))
1952 {
1953 /*
1954 * At top level, we are examining an implicit-AND list: if any of the
1955 * arms produces FALSE-or-NULL then the result is FALSE-or-NULL.
1956 */
1957 foreach(l, (List *) node)
1958 {
1959 result = mbms_add_members(result,
1961 }
1962 }
1963 else if (IsA(node, BoolExpr))
1964 {
1965 BoolExpr *expr = (BoolExpr *) node;
1966
1967 /*
1968 * We don't bother considering the OR case, because it's fairly
1969 * unlikely anyone would write "v1 IS NULL OR v1 IS NULL". Likewise,
1970 * the NOT case isn't worth expending code on.
1971 */
1972 if (expr->boolop == AND_EXPR)
1973 {
1974 /* At top level we can just recurse (to the List case) */
1975 result = find_forced_null_vars((Node *) expr->args);
1976 }
1977 }
1978 return result;
1979}
List * find_forced_null_vars(Node *node)
Definition clauses.c:1934
Var * find_forced_null_var(Node *node)
Definition clauses.c:1995
List * mbms_add_members(List *a, const List *b)
List * mbms_add_member(List *a, int listidx, int bitidx)
#define FirstLowInvalidHeapAttributeNumber
Definition sysattr.h:27

References AND_EXPR, BoolExpr::args, BoolExpr::boolop, fb(), find_forced_null_var(), find_forced_null_vars(), FirstLowInvalidHeapAttributeNumber, IsA, lfirst, mbms_add_member(), mbms_add_members(), NIL, Var::varattno, and Var::varno.

Referenced by find_forced_null_vars(), and reduce_outer_joins_pass2().

◆ find_nonnullable_rels()

Relids find_nonnullable_rels ( Node clause)

Definition at line 1474 of file clauses.c.

1475{
1476 return find_nonnullable_rels_walker(clause, true);
1477}
static Relids find_nonnullable_rels_walker(Node *node, bool top_level)
Definition clauses.c:1480

References find_nonnullable_rels_walker().

Referenced by make_outerjoininfo(), and reduce_outer_joins_pass2().

◆ find_nonnullable_rels_walker()

static Relids find_nonnullable_rels_walker ( Node node,
bool  top_level 
)
static

Definition at line 1480 of file clauses.c.

1481{
1482 Relids result = NULL;
1483 ListCell *l;
1484
1485 if (node == NULL)
1486 return NULL;
1487 if (IsA(node, Var))
1488 {
1489 Var *var = (Var *) node;
1490
1491 if (var->varlevelsup == 0)
1492 result = bms_make_singleton(var->varno);
1493 }
1494 else if (IsA(node, List))
1495 {
1496 /*
1497 * At top level, we are examining an implicit-AND list: if any of the
1498 * arms produces FALSE-or-NULL then the result is FALSE-or-NULL. If
1499 * not at top level, we are examining the arguments of a strict
1500 * function: if any of them produce NULL then the result of the
1501 * function must be NULL. So in both cases, the set of nonnullable
1502 * rels is the union of those found in the arms, and we pass down the
1503 * top_level flag unmodified.
1504 */
1505 foreach(l, (List *) node)
1506 {
1507 result = bms_join(result,
1509 top_level));
1510 }
1511 }
1512 else if (IsA(node, FuncExpr))
1513 {
1514 FuncExpr *expr = (FuncExpr *) node;
1515
1516 if (func_strict(expr->funcid))
1517 result = find_nonnullable_rels_walker((Node *) expr->args, false);
1518 }
1519 else if (IsA(node, OpExpr))
1520 {
1521 OpExpr *expr = (OpExpr *) node;
1522
1523 set_opfuncid(expr);
1524 if (func_strict(expr->opfuncid))
1525 result = find_nonnullable_rels_walker((Node *) expr->args, false);
1526 }
1527 else if (IsA(node, ScalarArrayOpExpr))
1528 {
1529 ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node;
1530
1531 if (is_strict_saop(expr, true))
1532 result = find_nonnullable_rels_walker((Node *) expr->args, false);
1533 }
1534 else if (IsA(node, BoolExpr))
1535 {
1536 BoolExpr *expr = (BoolExpr *) node;
1537
1538 switch (expr->boolop)
1539 {
1540 case AND_EXPR:
1541 /* At top level we can just recurse (to the List case) */
1542 if (top_level)
1543 {
1544 result = find_nonnullable_rels_walker((Node *) expr->args,
1545 top_level);
1546 break;
1547 }
1548
1549 /*
1550 * Below top level, even if one arm produces NULL, the result
1551 * could be FALSE (hence not NULL). However, if *all* the
1552 * arms produce NULL then the result is NULL, so we can take
1553 * the intersection of the sets of nonnullable rels, just as
1554 * for OR. Fall through to share code.
1555 */
1557 case OR_EXPR:
1558
1559 /*
1560 * OR is strict if all of its arms are, so we can take the
1561 * intersection of the sets of nonnullable rels for each arm.
1562 * This works for both values of top_level.
1563 */
1564 foreach(l, expr->args)
1565 {
1567
1569 top_level);
1570 if (result == NULL) /* first subresult? */
1571 result = subresult;
1572 else
1573 result = bms_int_members(result, subresult);
1574
1575 /*
1576 * If the intersection is empty, we can stop looking. This
1577 * also justifies the test for first-subresult above.
1578 */
1579 if (bms_is_empty(result))
1580 break;
1581 }
1582 break;
1583 case NOT_EXPR:
1584 /* NOT will return null if its arg is null */
1585 result = find_nonnullable_rels_walker((Node *) expr->args,
1586 false);
1587 break;
1588 default:
1589 elog(ERROR, "unrecognized boolop: %d", (int) expr->boolop);
1590 break;
1591 }
1592 }
1593 else if (IsA(node, RelabelType))
1594 {
1595 RelabelType *expr = (RelabelType *) node;
1596
1597 result = find_nonnullable_rels_walker((Node *) expr->arg, top_level);
1598 }
1599 else if (IsA(node, CoerceViaIO))
1600 {
1601 /* not clear this is useful, but it can't hurt */
1602 CoerceViaIO *expr = (CoerceViaIO *) node;
1603
1604 result = find_nonnullable_rels_walker((Node *) expr->arg, top_level);
1605 }
1606 else if (IsA(node, ArrayCoerceExpr))
1607 {
1608 /* ArrayCoerceExpr is strict at the array level; ignore elemexpr */
1609 ArrayCoerceExpr *expr = (ArrayCoerceExpr *) node;
1610
1611 result = find_nonnullable_rels_walker((Node *) expr->arg, top_level);
1612 }
1613 else if (IsA(node, ConvertRowtypeExpr))
1614 {
1615 /* not clear this is useful, but it can't hurt */
1616 ConvertRowtypeExpr *expr = (ConvertRowtypeExpr *) node;
1617
1618 result = find_nonnullable_rels_walker((Node *) expr->arg, top_level);
1619 }
1620 else if (IsA(node, CollateExpr))
1621 {
1622 CollateExpr *expr = (CollateExpr *) node;
1623
1624 result = find_nonnullable_rels_walker((Node *) expr->arg, top_level);
1625 }
1626 else if (IsA(node, NullTest))
1627 {
1628 /* IS NOT NULL can be considered strict, but only at top level */
1629 NullTest *expr = (NullTest *) node;
1630
1631 if (top_level && expr->nulltesttype == IS_NOT_NULL && !expr->argisrow)
1632 result = find_nonnullable_rels_walker((Node *) expr->arg, false);
1633 }
1634 else if (IsA(node, BooleanTest))
1635 {
1636 /* Boolean tests that reject NULL are strict at top level */
1637 BooleanTest *expr = (BooleanTest *) node;
1638
1639 if (top_level &&
1640 (expr->booltesttype == IS_TRUE ||
1641 expr->booltesttype == IS_FALSE ||
1642 expr->booltesttype == IS_NOT_UNKNOWN))
1643 result = find_nonnullable_rels_walker((Node *) expr->arg, false);
1644 }
1645 else if (IsA(node, SubPlan))
1646 {
1647 SubPlan *splan = (SubPlan *) node;
1648
1649 /*
1650 * For some types of SubPlan, we can infer strictness from Vars in the
1651 * testexpr (the LHS of the original SubLink).
1652 *
1653 * For ANY_SUBLINK, if the subquery produces zero rows, the result is
1654 * always FALSE. If the subquery produces more than one row, the
1655 * per-row results of the testexpr are combined using OR semantics.
1656 * Hence ANY_SUBLINK can be strict only at top level, but there it's
1657 * as strict as the testexpr is.
1658 *
1659 * For ROWCOMPARE_SUBLINK, if the subquery produces zero rows, the
1660 * result is always NULL. Otherwise, the result is as strict as the
1661 * testexpr is. So we can check regardless of top_level.
1662 *
1663 * We can't prove anything for other sublink types (in particular,
1664 * note that ALL_SUBLINK will return TRUE if the subquery is empty).
1665 */
1666 if ((top_level && splan->subLinkType == ANY_SUBLINK) ||
1668 result = find_nonnullable_rels_walker(splan->testexpr, top_level);
1669 }
1670 else if (IsA(node, PlaceHolderVar))
1671 {
1672 PlaceHolderVar *phv = (PlaceHolderVar *) node;
1673
1674 /*
1675 * If the contained expression forces any rels non-nullable, so does
1676 * the PHV.
1677 */
1678 result = find_nonnullable_rels_walker((Node *) phv->phexpr, top_level);
1679
1680 /*
1681 * If the PHV's syntactic scope is exactly one rel, it will be forced
1682 * to be evaluated at that rel, and so it will behave like a Var of
1683 * that rel: if the rel's entire output goes to null, so will the PHV.
1684 * (If the syntactic scope is a join, we know that the PHV will go to
1685 * null if the whole join does; but that is AND semantics while we
1686 * need OR semantics for find_nonnullable_rels' result, so we can't do
1687 * anything with the knowledge.)
1688 */
1689 if (phv->phlevelsup == 0 &&
1690 bms_membership(phv->phrels) == BMS_SINGLETON)
1691 result = bms_add_members(result, phv->phrels);
1692 }
1693 return result;
1694}
Bitmapset * bms_make_singleton(int x)
Definition bitmapset.c:216
Bitmapset * bms_int_members(Bitmapset *a, const Bitmapset *b)
Definition bitmapset.c:1093
Bitmapset * bms_add_members(Bitmapset *a, const Bitmapset *b)
Definition bitmapset.c:901
BMS_Membership bms_membership(const Bitmapset *a)
Definition bitmapset.c:765
Bitmapset * bms_join(Bitmapset *a, Bitmapset *b)
Definition bitmapset.c:1214
@ BMS_SINGLETON
Definition bitmapset.h:72
#define pg_fallthrough
Definition c.h:152
static bool is_strict_saop(ScalarArrayOpExpr *expr, bool falseOK)
Definition clauses.c:2269
@ ANY_SUBLINK
Definition primnodes.h:1032
@ ROWCOMPARE_SUBLINK
Definition primnodes.h:1033
Node * testexpr
Definition primnodes.h:1100
SubLinkType subLinkType
Definition primnodes.h:1098

References AND_EXPR, ANY_SUBLINK, RelabelType::arg, CoerceViaIO::arg, ArrayCoerceExpr::arg, ConvertRowtypeExpr::arg, CollateExpr::arg, NullTest::arg, BooleanTest::arg, FuncExpr::args, OpExpr::args, ScalarArrayOpExpr::args, BoolExpr::args, bms_add_members(), bms_int_members(), bms_is_empty, bms_join(), bms_make_singleton(), bms_membership(), BMS_SINGLETON, BoolExpr::boolop, BooleanTest::booltesttype, elog, ERROR, fb(), find_nonnullable_rels_walker(), func_strict(), FuncExpr::funcid, IS_FALSE, IS_NOT_NULL, IS_NOT_UNKNOWN, is_strict_saop(), IS_TRUE, IsA, lfirst, NOT_EXPR, NullTest::nulltesttype, OR_EXPR, pg_fallthrough, ROWCOMPARE_SUBLINK, set_opfuncid(), SubPlan::subLinkType, SubPlan::testexpr, Var::varlevelsup, and Var::varno.

Referenced by find_nonnullable_rels(), and find_nonnullable_rels_walker().

◆ find_nonnullable_vars()

List * find_nonnullable_vars ( Node clause)

Definition at line 1725 of file clauses.c.

1726{
1727 return find_nonnullable_vars_walker(clause, true);
1728}
static List * find_nonnullable_vars_walker(Node *node, bool top_level)
Definition clauses.c:1731

References find_nonnullable_vars_walker().

Referenced by query_outputs_are_not_nullable(), and reduce_outer_joins_pass2().

◆ find_nonnullable_vars_walker()

static List * find_nonnullable_vars_walker ( Node node,
bool  top_level 
)
static

Definition at line 1731 of file clauses.c.

1732{
1733 List *result = NIL;
1734 ListCell *l;
1735
1736 if (node == NULL)
1737 return NIL;
1738 if (IsA(node, Var))
1739 {
1740 Var *var = (Var *) node;
1741
1742 if (var->varlevelsup == 0)
1743 result = mbms_add_member(result,
1744 var->varno,
1746 }
1747 else if (IsA(node, List))
1748 {
1749 /*
1750 * At top level, we are examining an implicit-AND list: if any of the
1751 * arms produces FALSE-or-NULL then the result is FALSE-or-NULL. If
1752 * not at top level, we are examining the arguments of a strict
1753 * function: if any of them produce NULL then the result of the
1754 * function must be NULL. So in both cases, the set of nonnullable
1755 * vars is the union of those found in the arms, and we pass down the
1756 * top_level flag unmodified.
1757 */
1758 foreach(l, (List *) node)
1759 {
1760 result = mbms_add_members(result,
1762 top_level));
1763 }
1764 }
1765 else if (IsA(node, FuncExpr))
1766 {
1767 FuncExpr *expr = (FuncExpr *) node;
1768
1769 if (func_strict(expr->funcid))
1770 result = find_nonnullable_vars_walker((Node *) expr->args, false);
1771 }
1772 else if (IsA(node, OpExpr))
1773 {
1774 OpExpr *expr = (OpExpr *) node;
1775
1776 set_opfuncid(expr);
1777 if (func_strict(expr->opfuncid))
1778 result = find_nonnullable_vars_walker((Node *) expr->args, false);
1779 }
1780 else if (IsA(node, ScalarArrayOpExpr))
1781 {
1782 ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node;
1783
1784 if (is_strict_saop(expr, true))
1785 result = find_nonnullable_vars_walker((Node *) expr->args, false);
1786 }
1787 else if (IsA(node, BoolExpr))
1788 {
1789 BoolExpr *expr = (BoolExpr *) node;
1790
1791 switch (expr->boolop)
1792 {
1793 case AND_EXPR:
1794
1795 /*
1796 * At top level we can just recurse (to the List case), since
1797 * the result should be the union of what we can prove in each
1798 * arm.
1799 */
1800 if (top_level)
1801 {
1802 result = find_nonnullable_vars_walker((Node *) expr->args,
1803 top_level);
1804 break;
1805 }
1806
1807 /*
1808 * Below top level, even if one arm produces NULL, the result
1809 * could be FALSE (hence not NULL). However, if *all* the
1810 * arms produce NULL then the result is NULL, so we can take
1811 * the intersection of the sets of nonnullable vars, just as
1812 * for OR. Fall through to share code.
1813 */
1815 case OR_EXPR:
1816
1817 /*
1818 * OR is strict if all of its arms are, so we can take the
1819 * intersection of the sets of nonnullable vars for each arm.
1820 * This works for both values of top_level.
1821 */
1822 foreach(l, expr->args)
1823 {
1824 List *subresult;
1825
1827 top_level);
1828 if (result == NIL) /* first subresult? */
1829 result = subresult;
1830 else
1831 result = mbms_int_members(result, subresult);
1832
1833 /*
1834 * If the intersection is empty, we can stop looking. This
1835 * also justifies the test for first-subresult above.
1836 */
1837 if (result == NIL)
1838 break;
1839 }
1840 break;
1841 case NOT_EXPR:
1842 /* NOT will return null if its arg is null */
1843 result = find_nonnullable_vars_walker((Node *) expr->args,
1844 false);
1845 break;
1846 default:
1847 elog(ERROR, "unrecognized boolop: %d", (int) expr->boolop);
1848 break;
1849 }
1850 }
1851 else if (IsA(node, RelabelType))
1852 {
1853 RelabelType *expr = (RelabelType *) node;
1854
1855 result = find_nonnullable_vars_walker((Node *) expr->arg, top_level);
1856 }
1857 else if (IsA(node, CoerceViaIO))
1858 {
1859 /* not clear this is useful, but it can't hurt */
1860 CoerceViaIO *expr = (CoerceViaIO *) node;
1861
1862 result = find_nonnullable_vars_walker((Node *) expr->arg, false);
1863 }
1864 else if (IsA(node, ArrayCoerceExpr))
1865 {
1866 /* ArrayCoerceExpr is strict at the array level; ignore elemexpr */
1867 ArrayCoerceExpr *expr = (ArrayCoerceExpr *) node;
1868
1869 result = find_nonnullable_vars_walker((Node *) expr->arg, top_level);
1870 }
1871 else if (IsA(node, ConvertRowtypeExpr))
1872 {
1873 /* not clear this is useful, but it can't hurt */
1874 ConvertRowtypeExpr *expr = (ConvertRowtypeExpr *) node;
1875
1876 result = find_nonnullable_vars_walker((Node *) expr->arg, top_level);
1877 }
1878 else if (IsA(node, CollateExpr))
1879 {
1880 CollateExpr *expr = (CollateExpr *) node;
1881
1882 result = find_nonnullable_vars_walker((Node *) expr->arg, top_level);
1883 }
1884 else if (IsA(node, NullTest))
1885 {
1886 /* IS NOT NULL can be considered strict, but only at top level */
1887 NullTest *expr = (NullTest *) node;
1888
1889 if (top_level && expr->nulltesttype == IS_NOT_NULL && !expr->argisrow)
1890 result = find_nonnullable_vars_walker((Node *) expr->arg, false);
1891 }
1892 else if (IsA(node, BooleanTest))
1893 {
1894 /* Boolean tests that reject NULL are strict at top level */
1895 BooleanTest *expr = (BooleanTest *) node;
1896
1897 if (top_level &&
1898 (expr->booltesttype == IS_TRUE ||
1899 expr->booltesttype == IS_FALSE ||
1900 expr->booltesttype == IS_NOT_UNKNOWN))
1901 result = find_nonnullable_vars_walker((Node *) expr->arg, false);
1902 }
1903 else if (IsA(node, SubPlan))
1904 {
1905 SubPlan *splan = (SubPlan *) node;
1906
1907 /* See analysis in find_nonnullable_rels_walker */
1908 if ((top_level && splan->subLinkType == ANY_SUBLINK) ||
1910 result = find_nonnullable_vars_walker(splan->testexpr, top_level);
1911 }
1912 else if (IsA(node, PlaceHolderVar))
1913 {
1914 PlaceHolderVar *phv = (PlaceHolderVar *) node;
1915
1916 result = find_nonnullable_vars_walker((Node *) phv->phexpr, top_level);
1917 }
1918 return result;
1919}
List * mbms_int_members(List *a, const List *b)

References AND_EXPR, ANY_SUBLINK, RelabelType::arg, CoerceViaIO::arg, ArrayCoerceExpr::arg, ConvertRowtypeExpr::arg, CollateExpr::arg, NullTest::arg, BooleanTest::arg, FuncExpr::args, OpExpr::args, ScalarArrayOpExpr::args, BoolExpr::args, BoolExpr::boolop, BooleanTest::booltesttype, elog, ERROR, fb(), find_nonnullable_vars_walker(), FirstLowInvalidHeapAttributeNumber, func_strict(), FuncExpr::funcid, IS_FALSE, IS_NOT_NULL, IS_NOT_UNKNOWN, is_strict_saop(), IS_TRUE, IsA, lfirst, mbms_add_member(), mbms_add_members(), mbms_int_members(), NIL, NOT_EXPR, NullTest::nulltesttype, OR_EXPR, pg_fallthrough, ROWCOMPARE_SUBLINK, set_opfuncid(), SubPlan::subLinkType, SubPlan::testexpr, Var::varattno, Var::varlevelsup, and Var::varno.

Referenced by find_nonnullable_vars(), and find_nonnullable_vars_walker().

◆ find_subquery_safe_quals()

static void find_subquery_safe_quals ( Node jtnode,
List **  safe_quals 
)
static

Definition at line 2187 of file clauses.c.

2188{
2189 if (jtnode == NULL)
2190 return;
2191 if (IsA(jtnode, RangeTblRef))
2192 {
2193 /* Leaf node: nothing to do */
2194 return;
2195 }
2196 else if (IsA(jtnode, FromExpr))
2197 {
2198 FromExpr *f = (FromExpr *) jtnode;
2199
2200 /* All elements of the FROM list are allowable */
2203 /* ... and its WHERE quals are too */
2204 if (f->quals)
2205 *safe_quals = lappend(*safe_quals, f->quals);
2206 }
2207 else if (IsA(jtnode, JoinExpr))
2208 {
2209 JoinExpr *j = (JoinExpr *) jtnode;
2210
2211 switch (j->jointype)
2212 {
2213 case JOIN_INNER:
2214 /* visit both children */
2217 /* and grab the ON quals too */
2218 if (j->quals)
2219 *safe_quals = lappend(*safe_quals, j->quals);
2220 break;
2221
2222 case JOIN_LEFT:
2223 case JOIN_SEMI:
2224 case JOIN_ANTI:
2225
2226 /*
2227 * Only the left input is possibly non-nullable; furthermore,
2228 * the quals of this join don't constrain the left input.
2229 * Note: we probably can't see SEMI or ANTI joins at this
2230 * point, but if we do, we can treat them like LEFT joins.
2231 */
2233 break;
2234
2235 case JOIN_RIGHT:
2236 /* Reverse of the above case */
2238 break;
2239
2240 case JOIN_FULL:
2241 /* Neither side is non-nullable, so stop descending */
2242 break;
2243
2244 default:
2245 elog(ERROR, "unrecognized join type: %d",
2246 (int) j->jointype);
2247 break;
2248 }
2249 }
2250 else
2251 elog(ERROR, "unrecognized node type: %d",
2252 (int) nodeTag(jtnode));
2253}
static void find_subquery_safe_quals(Node *jtnode, List **safe_quals)
Definition clauses.c:2187
if(enc< 0)
int j
Definition isn.c:78
@ JOIN_SEMI
Definition nodes.h:317
@ JOIN_FULL
Definition nodes.h:305
@ JOIN_INNER
Definition nodes.h:303
@ JOIN_RIGHT
Definition nodes.h:306
@ JOIN_LEFT
Definition nodes.h:304
@ JOIN_ANTI
Definition nodes.h:318
List * fromlist
Definition primnodes.h:2358

References elog, ERROR, fb(), find_subquery_safe_quals(), foreach_ptr, FromExpr::fromlist, IsA, j, JOIN_ANTI, JOIN_FULL, JOIN_INNER, JOIN_LEFT, JOIN_RIGHT, JOIN_SEMI, lappend(), nodeTag, and FromExpr::quals.

Referenced by find_subquery_safe_quals(), and query_outputs_are_not_nullable().

◆ find_window_functions()

WindowFuncLists * find_window_functions ( Node clause,
Index  maxWinRef 
)

Definition at line 242 of file clauses.c.

243{
245
246 lists->numWindowFuncs = 0;
247 lists->maxWinRef = maxWinRef;
248 lists->windowFuncs = (List **) palloc0((maxWinRef + 1) * sizeof(List *));
250 return lists;
251}
static bool find_window_functions_walker(Node *node, WindowFuncLists *lists)
Definition clauses.c:254
#define palloc_object(type)
Definition fe_memutils.h:74

References fb(), find_window_functions_walker(), palloc0(), and palloc_object.

Referenced by grouping_planner().

◆ find_window_functions_walker()

static bool find_window_functions_walker ( Node node,
WindowFuncLists lists 
)
static

Definition at line 254 of file clauses.c.

255{
256 if (node == NULL)
257 return false;
258 if (IsA(node, WindowFunc))
259 {
260 WindowFunc *wfunc = (WindowFunc *) node;
261
262 /* winref is unsigned, so one-sided test is OK */
263 if (wfunc->winref > lists->maxWinRef)
264 elog(ERROR, "WindowFunc contains out-of-range winref %u",
265 wfunc->winref);
266
267 lists->windowFuncs[wfunc->winref] =
268 lappend(lists->windowFuncs[wfunc->winref], wfunc);
269 lists->numWindowFuncs++;
270
271 /*
272 * We assume that the parser checked that there are no window
273 * functions in the arguments or filter clause. Hence, we need not
274 * recurse into them. (If either the parser or the planner screws up
275 * on this point, the executor will still catch it; see ExecInitExpr.)
276 */
277 return false;
278 }
279 Assert(!IsA(node, SubLink));
281}

References Assert, elog, ERROR, expression_tree_walker, fb(), find_window_functions_walker(), IsA, lappend(), and WindowFunc::winref.

Referenced by find_window_functions(), and find_window_functions_walker().

◆ inline_function()

static Expr * inline_function ( Oid  funcid,
Oid  result_type,
Oid  result_collid,
Oid  input_collid,
List args,
bool  funcvariadic,
HeapTuple  func_tuple,
eval_const_expressions_context context 
)
static

Definition at line 5267 of file clauses.c.

5272{
5274 char *src;
5275 Datum tmp;
5276 bool isNull;
5279 inline_error_callback_arg callback_arg;
5281 FuncExpr *fexpr;
5283 TupleDesc rettupdesc;
5284 ParseState *pstate;
5288 Node *newexpr;
5289 int *usecounts;
5290 ListCell *arg;
5291 int i;
5292
5293 /*
5294 * Forget it if the function is not SQL-language or has other showstopper
5295 * properties. (The prokind and nargs checks are just paranoia.)
5296 */
5297 if (funcform->prolang != SQLlanguageId ||
5298 funcform->prokind != PROKIND_FUNCTION ||
5299 funcform->prosecdef ||
5300 funcform->proretset ||
5301 funcform->prorettype == RECORDOID ||
5303 funcform->pronargs != list_length(args))
5304 return NULL;
5305
5306 /* Check for recursive function, and give up trying to expand if so */
5307 if (list_member_oid(context->active_fns, funcid))
5308 return NULL;
5309
5310 /* Check permission to call function (fail later, if not) */
5312 return NULL;
5313
5314 /* Check whether a plugin wants to hook function entry/exit */
5315 if (FmgrHookIsNeeded(funcid))
5316 return NULL;
5317
5318 /*
5319 * Make a temporary memory context, so that we don't leak all the stuff
5320 * that parsing might create.
5321 */
5323 "inline_function",
5326
5327 /*
5328 * We need a dummy FuncExpr node containing the already-simplified
5329 * arguments. (In some cases we don't really need it, but building it is
5330 * cheap enough that it's not worth contortions to avoid.)
5331 */
5333 fexpr->funcid = funcid;
5334 fexpr->funcresulttype = result_type;
5335 fexpr->funcretset = false;
5336 fexpr->funcvariadic = funcvariadic;
5337 fexpr->funcformat = COERCE_EXPLICIT_CALL; /* doesn't matter */
5338 fexpr->funccollid = result_collid; /* doesn't matter */
5339 fexpr->inputcollid = input_collid;
5340 fexpr->args = args;
5341 fexpr->location = -1;
5342
5343 /* Fetch the function body */
5345 src = TextDatumGetCString(tmp);
5346
5347 /*
5348 * Setup error traceback support for ereport(). This is so that we can
5349 * finger the function that bad information came from.
5350 */
5351 callback_arg.proname = NameStr(funcform->proname);
5352 callback_arg.prosrc = src;
5353
5355 sqlerrcontext.arg = &callback_arg;
5358
5359 /* If we have prosqlbody, pay attention to that not prosrc */
5361 func_tuple,
5363 &isNull);
5364 if (!isNull)
5365 {
5366 Node *n;
5367 List *query_list;
5368
5370 if (IsA(n, List))
5371 query_list = linitial_node(List, castNode(List, n));
5372 else
5373 query_list = list_make1(n);
5374 if (list_length(query_list) != 1)
5375 goto fail;
5376 querytree = linitial(query_list);
5377
5378 /*
5379 * Because we'll insist below that the querytree have an empty rtable
5380 * and no sublinks, it cannot have any relation references that need
5381 * to be locked or rewritten. So we can omit those steps.
5382 */
5383 }
5384 else
5385 {
5386 /* Set up to handle parameters while parsing the function body. */
5388 (Node *) fexpr,
5389 input_collid);
5390
5391 /*
5392 * We just do parsing and parse analysis, not rewriting, because
5393 * rewriting will not affect table-free-SELECT-only queries, which is
5394 * all that we care about. Also, we can punt as soon as we detect
5395 * more than one command in the function body.
5396 */
5399 goto fail;
5400
5401 pstate = make_parsestate(NULL);
5402 pstate->p_sourcetext = src;
5403 sql_fn_parser_setup(pstate, pinfo);
5404
5406
5407 free_parsestate(pstate);
5408 }
5409
5410 /*
5411 * The single command must be a simple "SELECT expression".
5412 *
5413 * Note: if you change the tests involved in this, see also plpgsql's
5414 * exec_simple_check_plan(). That generally needs to have the same idea
5415 * of what's a "simple expression", so that inlining a function that
5416 * previously wasn't inlined won't change plpgsql's conclusion.
5417 */
5418 if (!IsA(querytree, Query) ||
5419 querytree->commandType != CMD_SELECT ||
5420 querytree->hasAggs ||
5421 querytree->hasWindowFuncs ||
5422 querytree->hasTargetSRFs ||
5423 querytree->hasSubLinks ||
5424 querytree->cteList ||
5425 querytree->rtable ||
5426 querytree->jointree->fromlist ||
5427 querytree->jointree->quals ||
5428 querytree->groupClause ||
5429 querytree->groupingSets ||
5430 querytree->havingQual ||
5431 querytree->windowClause ||
5432 querytree->distinctClause ||
5433 querytree->sortClause ||
5434 querytree->limitOffset ||
5435 querytree->limitCount ||
5436 querytree->setOperations ||
5437 list_length(querytree->targetList) != 1)
5438 goto fail;
5439
5440 /* If the function result is composite, resolve it */
5442 NULL,
5443 &rettupdesc);
5444
5445 /*
5446 * Make sure the function (still) returns what it's declared to. This
5447 * will raise an error if wrong, but that's okay since the function would
5448 * fail at runtime anyway. Note that check_sql_fn_retval will also insert
5449 * a coercion if needed to make the tlist expression match the declared
5450 * type of the function.
5451 *
5452 * Note: we do not try this until we have verified that no rewriting was
5453 * needed; that's probably not important, but let's be careful.
5454 */
5457 result_type, rettupdesc,
5458 funcform->prokind,
5459 false))
5460 goto fail; /* reject whole-tuple-result cases */
5461
5462 /*
5463 * Given the tests above, check_sql_fn_retval shouldn't have decided to
5464 * inject a projection step, but let's just make sure.
5465 */
5467 goto fail;
5468
5469 /* Now we can grab the tlist expression */
5470 newexpr = (Node *) ((TargetEntry *) linitial(querytree->targetList))->expr;
5471
5472 /*
5473 * If the SQL function returns VOID, we can only inline it if it is a
5474 * SELECT of an expression returning VOID (ie, it's just a redirection to
5475 * another VOID-returning function). In all non-VOID-returning cases,
5476 * check_sql_fn_retval should ensure that newexpr returns the function's
5477 * declared result type, so this test shouldn't fail otherwise; but we may
5478 * as well cope gracefully if it does.
5479 */
5480 if (exprType(newexpr) != result_type)
5481 goto fail;
5482
5483 /*
5484 * Additional validity checks on the expression. It mustn't be more
5485 * volatile than the surrounding function (this is to avoid breaking hacks
5486 * that involve pretending a function is immutable when it really ain't).
5487 * If the surrounding function is declared strict, then the expression
5488 * must contain only strict constructs and must use all of the function
5489 * parameters (this is overkill, but an exact analysis is hard).
5490 */
5491 if (funcform->provolatile == PROVOLATILE_IMMUTABLE &&
5493 goto fail;
5494 else if (funcform->provolatile == PROVOLATILE_STABLE &&
5496 goto fail;
5497
5498 if (funcform->proisstrict &&
5500 goto fail;
5501
5502 /*
5503 * If any parameter expression contains a context-dependent node, we can't
5504 * inline, for fear of putting such a node into the wrong context.
5505 */
5507 goto fail;
5508
5509 /*
5510 * We may be able to do it; there are still checks on parameter usage to
5511 * make, but those are most easily done in combination with the actual
5512 * substitution of the inputs. So start building expression with inputs
5513 * substituted.
5514 */
5515 usecounts = (int *) palloc0(funcform->pronargs * sizeof(int));
5517 args, usecounts);
5518
5519 /* Now check for parameter usage */
5520 i = 0;
5521 foreach(arg, args)
5522 {
5523 Node *param = lfirst(arg);
5524
5525 if (usecounts[i] == 0)
5526 {
5527 /* Param not used at all: uncool if func is strict */
5528 if (funcform->proisstrict)
5529 goto fail;
5530 }
5531 else if (usecounts[i] != 1)
5532 {
5533 /* Param used multiple times: uncool if expensive or volatile */
5535
5536 /*
5537 * We define "expensive" as "contains any subplan or more than 10
5538 * operators". Note that the subplan search has to be done
5539 * explicitly, since cost_qual_eval() will barf on unplanned
5540 * subselects.
5541 */
5542 if (contain_subplans(param))
5543 goto fail;
5545 if (eval_cost.startup + eval_cost.per_tuple >
5546 10 * cpu_operator_cost)
5547 goto fail;
5548
5549 /*
5550 * Check volatility last since this is more expensive than the
5551 * above tests
5552 */
5553 if (contain_volatile_functions(param))
5554 goto fail;
5555 }
5556 i++;
5557 }
5558
5559 /*
5560 * Whew --- we can make the substitution. Copy the modified expression
5561 * out of the temporary memory context, and clean up.
5562 */
5564
5566
5568
5569 /*
5570 * If the result is of a collatable type, force the result to expose the
5571 * correct collation. In most cases this does not matter, but it's
5572 * possible that the function result is used directly as a sort key or in
5573 * other places where we expect exprCollation() to tell the truth.
5574 */
5576 {
5578
5580 {
5582
5583 newnode->arg = (Expr *) newexpr;
5584 newnode->collOid = result_collid;
5585 newnode->location = -1;
5586
5587 newexpr = (Node *) newnode;
5588 }
5589 }
5590
5591 /*
5592 * Since there is now no trace of the function in the plan tree, we must
5593 * explicitly record the plan's dependency on the function.
5594 */
5595 if (context->root)
5596 record_plan_function_dependency(context->root, funcid);
5597
5598 /*
5599 * Recursively try to simplify the modified expression. Here we must add
5600 * the current function to the context list of active functions.
5601 */
5602 context->active_fns = lappend_oid(context->active_fns, funcid);
5604 context->active_fns = list_delete_last(context->active_fns);
5605
5607
5608 return (Expr *) newexpr;
5609
5610 /* Here if func is not inlinable: release temp memory and return NULL */
5611fail:
5615
5616 return NULL;
5617}

References ACL_EXECUTE, ACLCHECK_OK, eval_const_expressions_context::active_fns, ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, arg, castNode, check_sql_fn_retval(), CMD_SELECT, COERCE_EXPLICIT_CALL, contain_context_dependent_node(), contain_mutable_functions(), contain_nonstrict_functions(), contain_subplans(), contain_volatile_functions(), copyObject, cost_qual_eval(), cpu_operator_cost, CurrentMemoryContext, error_context_stack, eval_const_expressions_mutator(), exprCollation(), exprType(), fb(), FmgrHookIsNeeded, Form_pg_proc, free_parsestate(), get_expr_result_type(), GETSTRUCT(), GetUserId(), heap_attisnull(), i, IsA, lappend_oid(), lfirst, linitial, linitial_node, list_delete_last(), list_length(), list_make1, list_member_oid(), make_parsestate(), makeNode, MemoryContextDelete(), MemoryContextSwitchTo(), NameStr, object_aclcheck(), OidIsValid, ParseState::p_sourcetext, palloc0(), pg_parse_query(), prepare_sql_fn_parse_info(), ErrorContextCallback::previous, inline_error_callback_arg::proname, inline_error_callback_arg::prosrc, querytree(), record_plan_function_dependency(), eval_const_expressions_context::root, sql_fn_parser_setup(), sql_inline_error_callback(), stringToNode(), substitute_actual_parameters(), SysCacheGetAttr(), SysCacheGetAttrNotNull(), TextDatumGetCString, and transformTopLevelStmt().

Referenced by simplify_function().

◆ inline_function_in_from()

Query * inline_function_in_from ( PlannerInfo root,
RangeTblEntry rte 
)

Definition at line 5780 of file clauses.c.

5781{
5782 RangeTblFunction *rtfunc;
5783 FuncExpr *fexpr;
5784 Oid func_oid;
5789 Datum tmp;
5790 char *src;
5791 inline_error_callback_arg callback_arg;
5793 Query *querytree = NULL;
5794
5795 Assert(rte->rtekind == RTE_FUNCTION);
5796
5797 /*
5798 * Guard against infinite recursion during expansion by checking for stack
5799 * overflow. (There's no need to do more.)
5800 */
5802
5803 /* Fail if the RTE has ORDINALITY - we don't implement that here. */
5804 if (rte->funcordinality)
5805 return NULL;
5806
5807 /* Fail if RTE isn't a single, simple FuncExpr */
5808 if (list_length(rte->functions) != 1)
5809 return NULL;
5810 rtfunc = (RangeTblFunction *) linitial(rte->functions);
5811
5812 if (!IsA(rtfunc->funcexpr, FuncExpr))
5813 return NULL;
5814 fexpr = (FuncExpr *) rtfunc->funcexpr;
5815
5816 func_oid = fexpr->funcid;
5817
5818 /*
5819 * Refuse to inline if the arguments contain any volatile functions or
5820 * sub-selects. Volatile functions are rejected because inlining may
5821 * result in the arguments being evaluated multiple times, risking a
5822 * change in behavior. Sub-selects are rejected partly for implementation
5823 * reasons (pushing them down another level might change their behavior)
5824 * and partly because they're likely to be expensive and so multiple
5825 * evaluation would be bad.
5826 */
5827 if (contain_volatile_functions((Node *) fexpr->args) ||
5828 contain_subplans((Node *) fexpr->args))
5829 return NULL;
5830
5831 /* Check permission to call function (fail later, if not) */
5833 return NULL;
5834
5835 /* Check whether a plugin wants to hook function entry/exit */
5837 return NULL;
5838
5839 /*
5840 * OK, let's take a look at the function's pg_proc entry.
5841 */
5844 elog(ERROR, "cache lookup failed for function %u", func_oid);
5846
5847 /*
5848 * If the function SETs any configuration parameters, inlining would cause
5849 * us to miss making those changes.
5850 */
5852 {
5854 return NULL;
5855 }
5856
5857 /*
5858 * Make a temporary memory context, so that we don't leak all the stuff
5859 * that parsing and rewriting might create. If we succeed, we'll copy
5860 * just the finished query tree back up to the caller's context.
5861 */
5863 "inline_function_in_from",
5866
5867 /* Fetch the function body */
5869 src = TextDatumGetCString(tmp);
5870
5871 /*
5872 * If the function has an attached support function that can handle
5873 * SupportRequestInlineInFrom, then attempt to inline with that.
5874 */
5875 if (funcform->prosupport)
5876 {
5878
5880 req.root = root;
5881 req.rtfunc = rtfunc;
5882 req.proc = func_tuple;
5883
5884 querytree = (Query *)
5886 PointerGetDatum(&req)));
5887 }
5888
5889 /*
5890 * Setup error traceback support for ereport(). This is so that we can
5891 * finger the function that bad information came from. We don't install
5892 * this while running the support function, since it'd be likely to do the
5893 * wrong thing: any parse errors reported during that are very likely not
5894 * against the raw function source text.
5895 */
5896 callback_arg.proname = NameStr(funcform->proname);
5897 callback_arg.prosrc = src;
5898
5900 sqlerrcontext.arg = &callback_arg;
5903
5904 /*
5905 * If SupportRequestInlineInFrom didn't work, try our built-in inlining
5906 * mechanism.
5907 */
5908 if (!querytree)
5910 func_tuple, funcform, src);
5911
5912 if (!querytree)
5913 goto fail; /* no luck there either, fail */
5914
5915 /*
5916 * The result had better be a SELECT Query.
5917 */
5919 Assert(querytree->commandType == CMD_SELECT);
5920
5921 /*
5922 * Looks good --- substitute parameters into the query.
5923 */
5925 funcform->pronargs,
5926 fexpr->args);
5927
5928 /*
5929 * Copy the modified query out of the temporary memory context, and clean
5930 * up.
5931 */
5933
5935
5939
5940 /*
5941 * We don't have to fix collations here because the upper query is already
5942 * parsed, ie, the collations in the RTE are what count.
5943 */
5944
5945 /*
5946 * Since there is now no trace of the function in the plan tree, we must
5947 * explicitly record the plan's dependency on the function.
5948 */
5950
5951 /*
5952 * We must also notice if the inserted query adds a dependency on the
5953 * calling role due to RLS quals.
5954 */
5955 if (querytree->hasRowSecurity)
5956 root->glob->dependsOnRole = true;
5957
5958 return querytree;
5959
5960 /* Here if func is not inlinable: release temp memory and return NULL */
5961fail:
5966
5967 return NULL;
5968}

References ACL_EXECUTE, ACLCHECK_OK, ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, Assert, check_stack_depth(), CMD_SELECT, contain_subplans(), contain_volatile_functions(), copyObject, CurrentMemoryContext, DatumGetPointer(), elog, ERROR, error_context_stack, fb(), FmgrHookIsNeeded, Form_pg_proc, RangeTblFunction::funcexpr, GETSTRUCT(), GetUserId(), heap_attisnull(), HeapTupleIsValid, inline_sql_function_in_from(), IsA, linitial, list_length(), MemoryContextDelete(), MemoryContextSwitchTo(), NameStr, object_aclcheck(), ObjectIdGetDatum(), OidFunctionCall1, PointerGetDatum(), ErrorContextCallback::previous, inline_error_callback_arg::proname, inline_error_callback_arg::prosrc, querytree(), record_plan_function_dependency(), ReleaseSysCache(), root, RTE_FUNCTION, SearchSysCache1(), sql_inline_error_callback(), substitute_actual_parameters_in_from(), SysCacheGetAttrNotNull(), TextDatumGetCString, and SupportRequestInlineInFrom::type.

Referenced by preprocess_function_rtes().

◆ inline_sql_function_in_from()

static Query * inline_sql_function_in_from ( PlannerInfo root,
RangeTblFunction rtfunc,
FuncExpr fexpr,
HeapTuple  func_tuple,
Form_pg_proc  funcform,
const char src 
)
static

Definition at line 5984 of file clauses.c.

5990{
5991 Datum sqlbody;
5992 bool isNull;
5996 TupleDesc rettupdesc;
5997
5998 /*
5999 * The function must be declared to return a set, else inlining would
6000 * change the results if the contained SELECT didn't return exactly one
6001 * row.
6002 */
6003 if (!fexpr->funcretset)
6004 return NULL;
6005
6006 /*
6007 * Forget it if the function is not SQL-language or has other showstopper
6008 * properties. In particular it mustn't be declared STRICT, since we
6009 * couldn't enforce that. It also mustn't be VOLATILE, because that is
6010 * supposed to cause it to be executed with its own snapshot, rather than
6011 * sharing the snapshot of the calling query. We also disallow returning
6012 * SETOF VOID, because inlining would result in exposing the actual result
6013 * of the function's last SELECT, which should not happen in that case.
6014 * (Rechecking prokind, proretset, and pronargs is just paranoia.)
6015 */
6016 if (funcform->prolang != SQLlanguageId ||
6017 funcform->prokind != PROKIND_FUNCTION ||
6018 funcform->proisstrict ||
6019 funcform->provolatile == PROVOLATILE_VOLATILE ||
6020 funcform->prorettype == VOIDOID ||
6021 funcform->prosecdef ||
6022 !funcform->proretset ||
6023 list_length(fexpr->args) != funcform->pronargs)
6024 return NULL;
6025
6026 /* If we have prosqlbody, pay attention to that not prosrc */
6028 func_tuple,
6030 &isNull);
6031 if (!isNull)
6032 {
6033 Node *n;
6034
6036 if (IsA(n, List))
6038 else
6040 if (list_length(querytree_list) != 1)
6041 return NULL;
6043
6044 /* Acquire necessary locks, then apply rewriter. */
6045 AcquireRewriteLocks(querytree, true, false);
6047 if (list_length(querytree_list) != 1)
6048 return NULL;
6050 }
6051 else
6052 {
6055
6056 /*
6057 * Set up to handle parameters while parsing the function body. We
6058 * can use the FuncExpr just created as the input for
6059 * prepare_sql_fn_parse_info.
6060 */
6062 (Node *) fexpr,
6063 fexpr->inputcollid);
6064
6065 /*
6066 * Parse, analyze, and rewrite (unlike inline_function(), we can't
6067 * skip rewriting here). We can fail as soon as we find more than one
6068 * query, though.
6069 */
6072 return NULL;
6073
6075 src,
6077 pinfo, NULL);
6078 if (list_length(querytree_list) != 1)
6079 return NULL;
6081 }
6082
6083 /*
6084 * Also resolve the actual function result tupdesc, if composite. If we
6085 * have a coldeflist, believe that; otherwise use get_expr_result_type.
6086 * (This logic should match ExecInitFunctionScan.)
6087 */
6088 if (rtfunc->funccolnames != NIL)
6089 {
6091 rettupdesc = BuildDescFromLists(rtfunc->funccolnames,
6092 rtfunc->funccoltypes,
6093 rtfunc->funccoltypmods,
6094 rtfunc->funccolcollations);
6095 }
6096 else
6097 functypclass = get_expr_result_type((Node *) fexpr, NULL, &rettupdesc);
6098
6099 /*
6100 * The single command must be a plain SELECT.
6101 */
6102 if (!IsA(querytree, Query) ||
6103 querytree->commandType != CMD_SELECT)
6104 return NULL;
6105
6106 /*
6107 * Make sure the function (still) returns what it's declared to. This
6108 * will raise an error if wrong, but that's okay since the function would
6109 * fail at runtime anyway. Note that check_sql_fn_retval will also insert
6110 * coercions if needed to make the tlist expression(s) match the declared
6111 * type of the function. We also ask it to insert dummy NULL columns for
6112 * any dropped columns in rettupdesc, so that the elements of the modified
6113 * tlist match up to the attribute numbers.
6114 *
6115 * If the function returns a composite type, don't inline unless the check
6116 * shows it's returning a whole tuple result; otherwise what it's
6117 * returning is a single composite column which is not what we need.
6118 */
6120 fexpr->funcresulttype, rettupdesc,
6121 funcform->prokind,
6122 true) &&
6126 return NULL; /* reject not-whole-tuple-result cases */
6127
6128 /*
6129 * check_sql_fn_retval might've inserted a projection step, but that's
6130 * fine; just make sure we use the upper Query.
6131 */
6133
6134 return querytree;
6135}

References AcquireRewriteLocks(), BuildDescFromLists(), castNode, check_sql_fn_retval(), CMD_SELECT, fb(), get_expr_result_type(), IsA, linitial, linitial_node, list_length(), list_make1, NIL, pg_analyze_and_rewrite_withcb(), pg_parse_query(), pg_rewrite_query(), prepare_sql_fn_parse_info(), querytree(), sql_fn_parser_setup(), stringToNode(), SysCacheGetAttr(), TextDatumGetCString, TYPEFUNC_COMPOSITE, TYPEFUNC_COMPOSITE_DOMAIN, and TYPEFUNC_RECORD.

Referenced by inline_function_in_from().

◆ is_parallel_safe()

bool is_parallel_safe ( PlannerInfo root,
Node node 
)

Definition at line 764 of file clauses.c.

765{
768 ListCell *l;
769
770 /*
771 * Even if the original querytree contained nothing unsafe, we need to
772 * search the expression if we have generated any PARAM_EXEC Params while
773 * planning, because those are parallel-restricted and there might be one
774 * in this expression. But otherwise we don't need to look.
775 */
776 if (root->glob->maxParallelHazard == PROPARALLEL_SAFE &&
777 root->glob->paramExecTypes == NIL)
778 return true;
779 /* Else use max_parallel_hazard's search logic, but stop on RESTRICTED */
782 context.safe_param_ids = NIL;
783
784 /*
785 * The params that refer to the same or parent query level are considered
786 * parallel-safe. The idea is that we compute such params at Gather or
787 * Gather Merge node and pass their value to workers.
788 */
789 for (proot = root; proot != NULL; proot = proot->parent_root)
790 {
791 foreach(l, proot->init_plans)
792 {
794
795 context.safe_param_ids = list_concat(context.safe_param_ids,
796 initsubplan->setParam);
797 }
798 }
799
800 return !max_parallel_hazard_walker(node, &context);
801}
static bool max_parallel_hazard_walker(Node *node, max_parallel_hazard_context *context)
Definition clauses.c:840
List * list_concat(List *list1, const List *list2)
Definition list.c:561

References fb(), lfirst, list_concat(), max_parallel_hazard_context::max_hazard, max_parallel_hazard_context::max_interesting, max_parallel_hazard_walker(), NIL, root, and max_parallel_hazard_context::safe_param_ids.

Referenced by apply_projection_to_path(), build_join_rel(), create_minmaxagg_path(), create_nestloop_plan(), create_partial_unique_paths(), create_projection_path(), create_set_projection_path(), create_window_paths(), find_computable_ec_member(), grouping_planner(), make_grouping_rel(), plan_create_index_workers(), query_planner(), relation_can_be_sorted_early(), and set_rel_consider_parallel().

◆ is_pseudo_constant_clause()

bool is_pseudo_constant_clause ( Node clause)

Definition at line 2331 of file clauses.c.

2332{
2333 /*
2334 * We could implement this check in one recursive scan. But since the
2335 * check for volatile functions is both moderately expensive and unlikely
2336 * to fail, it seems better to look for Vars first and only check for
2337 * volatile functions if we find no Vars.
2338 */
2339 if (!contain_var_clause(clause) &&
2341 return true;
2342 return false;
2343}

References contain_var_clause(), and contain_volatile_functions().

Referenced by clauselist_selectivity_ext(), dependency_is_compatible_clause(), dependency_is_compatible_expression(), and find_window_run_conditions().

◆ is_pseudo_constant_clause_relids()

bool is_pseudo_constant_clause_relids ( Node clause,
Relids  relids 
)

Definition at line 2351 of file clauses.c.

2352{
2353 if (bms_is_empty(relids) &&
2355 return true;
2356 return false;
2357}

References bms_is_empty, and contain_volatile_functions().

Referenced by clauselist_selectivity_ext().

◆ is_strict_saop()

static bool is_strict_saop ( ScalarArrayOpExpr expr,
bool  falseOK 
)
static

Definition at line 2269 of file clauses.c.

2270{
2271 Node *rightop;
2272
2273 /* The contained operator must be strict. */
2274 set_sa_opfuncid(expr);
2275 if (!func_strict(expr->opfuncid))
2276 return false;
2277 /* If ANY and falseOK, that's all we need to check. */
2278 if (expr->useOr && falseOK)
2279 return true;
2280 /* Else, we have to see if the array is provably non-empty. */
2281 Assert(list_length(expr->args) == 2);
2282 rightop = (Node *) lsecond(expr->args);
2283 if (rightop && IsA(rightop, Const))
2284 {
2285 Datum arraydatum = ((Const *) rightop)->constvalue;
2286 bool arrayisnull = ((Const *) rightop)->constisnull;
2288 int nitems;
2289
2290 if (arrayisnull)
2291 return false;
2294 if (nitems > 0)
2295 return true;
2296 }
2297 else if (rightop && IsA(rightop, ArrayExpr))
2298 {
2299 ArrayExpr *arrayexpr = (ArrayExpr *) rightop;
2300
2301 if (arrayexpr->elements != NIL && !arrayexpr->multidims)
2302 return true;
2303 }
2304 return false;
2305}

References ScalarArrayOpExpr::args, ARR_DIMS, ARR_NDIM, ArrayGetNItems(), Assert, DatumGetArrayTypeP, fb(), func_strict(), IsA, list_length(), lsecond, NIL, nitems, set_sa_opfuncid(), and ScalarArrayOpExpr::useOr.

Referenced by find_nonnullable_rels_walker(), and find_nonnullable_vars_walker().

◆ make_SAOP_expr()

ScalarArrayOpExpr * make_SAOP_expr ( Oid  oper,
Node leftexpr,
Oid  coltype,
Oid  arraycollid,
Oid  inputcollid,
List exprs,
bool  haveNonConst 
)

Definition at line 6236 of file clauses.c.

6238{
6239 Node *arrayNode = NULL;
6241 Oid arraytype = get_array_type(coltype);
6242
6243 if (!OidIsValid(arraytype))
6244 return NULL;
6245
6246 /*
6247 * Assemble an array from the list of constants. It seems more profitable
6248 * to build a const array. But in the presence of other nodes, we don't
6249 * have a specific value here and must employ an ArrayExpr instead.
6250 */
6251 if (haveNonConst)
6252 {
6254
6255 /* array_collid will be set by parse_collate.c */
6256 arrayExpr->element_typeid = coltype;
6257 arrayExpr->array_typeid = arraytype;
6258 arrayExpr->multidims = false;
6259 arrayExpr->elements = exprs;
6260 arrayExpr->location = -1;
6261
6262 arrayNode = (Node *) arrayExpr;
6263 }
6264 else
6265 {
6266 int16 typlen;
6267 bool typbyval;
6268 char typalign;
6269 Datum *elems;
6270 bool *nulls;
6271 int i = 0;
6273 int dims[1] = {list_length(exprs)};
6274 int lbs[1] = {1};
6275
6276 get_typlenbyvalalign(coltype, &typlen, &typbyval, &typalign);
6277
6278 elems = palloc_array(Datum, list_length(exprs));
6279 nulls = palloc_array(bool, list_length(exprs));
6280 foreach_node(Const, value, exprs)
6281 {
6282 elems[i] = value->constvalue;
6283 nulls[i++] = value->constisnull;
6284 }
6285
6286 arrayConst = construct_md_array(elems, nulls, 1, dims, lbs,
6287 coltype, typlen, typbyval, typalign);
6290 false, false);
6291
6292 pfree(elems);
6293 pfree(nulls);
6294 list_free(exprs);
6295 }
6296
6297 /* Build the SAOP expression node */
6299 saopexpr->opno = oper;
6300 saopexpr->opfuncid = get_opcode(oper);
6301 saopexpr->hashfuncid = InvalidOid;
6302 saopexpr->negfuncid = InvalidOid;
6303 saopexpr->useOr = true;
6304 saopexpr->inputcollid = inputcollid;
6306 saopexpr->location = -1;
6307
6308 return saopexpr;
6309}

References construct_md_array(), fb(), foreach_node, get_array_type(), get_opcode(), get_typlenbyvalalign(), i, InvalidOid, list_free(), list_length(), list_make2, makeConst(), makeNode, OidIsValid, oper(), palloc_array, pfree(), PointerGetDatum(), typalign, and value.

Referenced by convert_VALUES_to_ANY(), and match_orclause_to_indexcol().

◆ max_parallel_hazard()

char max_parallel_hazard ( Query parse)

◆ max_parallel_hazard_checker()

static bool max_parallel_hazard_checker ( Oid  func_id,
void context 
)
static

Definition at line 833 of file clauses.c.

834{
836 (max_parallel_hazard_context *) context);
837}
static bool max_parallel_hazard_test(char proparallel, max_parallel_hazard_context *context)
Definition clauses.c:805
char func_parallel(Oid funcid)
Definition lsyscache.c:2017

References fb(), func_parallel(), and max_parallel_hazard_test().

Referenced by max_parallel_hazard_walker().

◆ max_parallel_hazard_test()

static bool max_parallel_hazard_test ( char  proparallel,
max_parallel_hazard_context context 
)
static

Definition at line 805 of file clauses.c.

806{
807 switch (proparallel)
808 {
809 case PROPARALLEL_SAFE:
810 /* nothing to see here, move along */
811 break;
813 /* increase max_hazard to RESTRICTED */
815 context->max_hazard = proparallel;
816 /* done if we are not expecting any unsafe functions */
817 if (context->max_interesting == proparallel)
818 return true;
819 break;
821 context->max_hazard = proparallel;
822 /* we're always done at the first unsafe construct */
823 return true;
824 default:
825 elog(ERROR, "unrecognized proparallel value \"%c\"", proparallel);
826 break;
827 }
828 return false;
829}

References Assert, elog, ERROR, fb(), max_parallel_hazard_context::max_hazard, and max_parallel_hazard_context::max_interesting.

Referenced by max_parallel_hazard_checker(), and max_parallel_hazard_walker().

◆ max_parallel_hazard_walker()

static bool max_parallel_hazard_walker ( Node node,
max_parallel_hazard_context context 
)
static

Definition at line 840 of file clauses.c.

841{
842 if (node == NULL)
843 return false;
844
845 /* Check for hazardous functions in node itself */
847 context))
848 return true;
849
850 /*
851 * It should be OK to treat MinMaxExpr as parallel-safe, since btree
852 * opclass support functions are generally parallel-safe. XmlExpr is a
853 * bit more dubious but we can probably get away with it. We err on the
854 * side of caution by treating CoerceToDomain as parallel-restricted.
855 * (Note: in principle that's wrong because a domain constraint could
856 * contain a parallel-unsafe function; but useful constraints probably
857 * never would have such, and assuming they do would cripple use of
858 * parallel query in the presence of domain types.) SQLValueFunction
859 * should be safe in all cases. NextValueExpr is parallel-unsafe.
860 */
861 if (IsA(node, CoerceToDomain))
862 {
864 return true;
865 }
866
867 else if (IsA(node, NextValueExpr))
868 {
870 return true;
871 }
872
873 /*
874 * Treat window functions as parallel-restricted because we aren't sure
875 * whether the input row ordering is fully deterministic, and the output
876 * of window functions might vary across workers if not. (In some cases,
877 * like where the window frame orders by a primary key, we could relax
878 * this restriction. But it doesn't currently seem worth expending extra
879 * effort to do so.)
880 */
881 else if (IsA(node, WindowFunc))
882 {
884 return true;
885 }
886
887 /*
888 * As a notational convenience for callers, look through RestrictInfo.
889 */
890 else if (IsA(node, RestrictInfo))
891 {
892 RestrictInfo *rinfo = (RestrictInfo *) node;
893
894 return max_parallel_hazard_walker((Node *) rinfo->clause, context);
895 }
896
897 /*
898 * Really we should not see SubLink during a max_interesting == restricted
899 * scan, but if we do, return true.
900 */
901 else if (IsA(node, SubLink))
902 {
904 return true;
905 }
906
907 /*
908 * Only parallel-safe SubPlans can be sent to workers. Within the
909 * testexpr of the SubPlan, Params representing the output columns of the
910 * subplan can be treated as parallel-safe, so temporarily add their IDs
911 * to the safe_param_ids list while examining the testexpr.
912 */
913 else if (IsA(node, SubPlan))
914 {
915 SubPlan *subplan = (SubPlan *) node;
917
918 if (!subplan->parallel_safe &&
920 return true;
923 subplan->paramIds);
924 if (max_parallel_hazard_walker(subplan->testexpr, context))
925 return true; /* no need to restore safe_param_ids */
926 list_free(context->safe_param_ids);
928 /* we must also check args, but no special Param treatment there */
929 if (max_parallel_hazard_walker((Node *) subplan->args, context))
930 return true;
931 /* don't want to recurse normally, so we're done */
932 return false;
933 }
934
935 /*
936 * We can't pass Params to workers at the moment either, so they are also
937 * parallel-restricted, unless they are PARAM_EXTERN Params or are
938 * PARAM_EXEC Params listed in safe_param_ids, meaning they could be
939 * either generated within workers or can be computed by the leader and
940 * then their value can be passed to workers.
941 */
942 else if (IsA(node, Param))
943 {
944 Param *param = (Param *) node;
945
946 if (param->paramkind == PARAM_EXTERN)
947 return false;
948
949 if (param->paramkind != PARAM_EXEC ||
950 !list_member_int(context->safe_param_ids, param->paramid))
951 {
953 return true;
954 }
955 return false; /* nothing to recurse to */
956 }
957
958 /*
959 * When we're first invoked on a completely unplanned tree, we must
960 * recurse into subqueries so to as to locate parallel-unsafe constructs
961 * anywhere in the tree.
962 */
963 else if (IsA(node, Query))
964 {
965 Query *query = (Query *) node;
966
967 /* SELECT FOR UPDATE/SHARE must be treated as unsafe */
968 if (query->rowMarks != NULL)
969 {
971 return true;
972 }
973
974 /* Recurse into subselects */
975 return query_tree_walker(query,
977 context, 0);
978 }
979
980 /* Recurse to check arguments */
981 return expression_tree_walker(node,
983 context);
984}
static bool max_parallel_hazard_checker(Oid func_id, void *context)
Definition clauses.c:833
List * rowMarks
Definition parsenodes.h:234
List * args
Definition primnodes.h:1125
List * paramIds
Definition primnodes.h:1101
bool parallel_safe
Definition primnodes.h:1118

References SubPlan::args, check_functions_in_node(), RestrictInfo::clause, expression_tree_walker, fb(), IsA, list_concat_copy(), list_free(), list_member_int(), max_parallel_hazard_context::max_hazard, max_parallel_hazard_checker(), max_parallel_hazard_test(), max_parallel_hazard_walker(), SubPlan::parallel_safe, PARAM_EXEC, PARAM_EXTERN, Param::paramid, SubPlan::paramIds, Param::paramkind, query_tree_walker, Query::rowMarks, max_parallel_hazard_context::safe_param_ids, and SubPlan::testexpr.

Referenced by is_parallel_safe(), max_parallel_hazard(), and max_parallel_hazard_walker().

◆ NumRelids()

int NumRelids ( PlannerInfo root,
Node clause 
)

Definition at line 2373 of file clauses.c.

2374{
2375 int result;
2376 Relids varnos = pull_varnos(root, clause);
2377
2378 varnos = bms_del_members(varnos, root->outer_join_rels);
2379 result = bms_num_members(varnos);
2380 bms_free(varnos);
2381 return result;
2382}
Bitmapset * bms_del_members(Bitmapset *a, const Bitmapset *b)
Definition bitmapset.c:1145
void bms_free(Bitmapset *a)
Definition bitmapset.c:239
int bms_num_members(const Bitmapset *a)
Definition bitmapset.c:744
Relids pull_varnos(PlannerInfo *root, Node *node)
Definition var.c:114

References bms_del_members(), bms_free(), bms_num_members(), pull_varnos(), and root.

Referenced by clauselist_selectivity_ext(), rowcomparesel(), and treat_as_join_clause().

◆ pull_paramids()

Bitmapset * pull_paramids ( Expr expr)

Definition at line 6204 of file clauses.c.

6205{
6206 Bitmapset *result = NULL;
6207
6208 (void) pull_paramids_walker((Node *) expr, &result);
6209
6210 return result;
6211}

References fb(), and pull_paramids_walker().

Referenced by create_memoize_plan().

◆ pull_paramids_walker()

static bool pull_paramids_walker ( Node node,
Bitmapset **  context 
)
static

Definition at line 6214 of file clauses.c.

6215{
6216 if (node == NULL)
6217 return false;
6218 if (IsA(node, Param))
6219 {
6220 Param *param = (Param *) node;
6221
6222 *context = bms_add_member(*context, param->paramid);
6223 return false;
6224 }
6225 return expression_tree_walker(node, pull_paramids_walker, context);
6226}

References bms_add_member(), expression_tree_walker, fb(), IsA, Param::paramid, and pull_paramids_walker().

Referenced by pull_paramids(), and pull_paramids_walker().

◆ query_outputs_are_not_nullable()

bool query_outputs_are_not_nullable ( Query query)

Definition at line 2049 of file clauses.c.

2050{
2051 PlannerInfo subroot;
2052 List *safe_quals = NIL;
2054 bool computed_nonnullable_vars = false;
2055
2056 /*
2057 * If the query contains set operations, punt. The set ops themselves
2058 * couldn't introduce nulls that weren't in their inputs, but the tlist
2059 * present in the top-level query is just dummy and won't give us useful
2060 * info. We could get an answer by recursing to examine each leaf query,
2061 * but for the moment it doesn't seem worth the extra complication.
2062 */
2063 if (query->setOperations)
2064 return false;
2065
2066 /*
2067 * If the query contains grouping sets, punt. Grouping sets can introduce
2068 * NULL values, and we currently lack the PlannerInfo needed to flatten
2069 * grouping Vars in the query's outputs.
2070 */
2071 if (query->groupingSets)
2072 return false;
2073
2074 /*
2075 * We need a PlannerInfo to pass to expr_is_nonnullable. Fortunately, we
2076 * can cons up an entirely dummy one, because only the "parse" link in the
2077 * struct is used by expr_is_nonnullable.
2078 */
2079 MemSet(&subroot, 0, sizeof(subroot));
2080 subroot.parse = query;
2081
2082 /*
2083 * Examine each targetlist entry to prove that it can't produce NULL.
2084 */
2086 {
2087 Expr *expr = tle->expr;
2088
2089 /* Resjunk columns can be ignored: they don't produce output values */
2090 if (tle->resjunk)
2091 continue;
2092
2093 /*
2094 * Look through binary relabelings, since we know those don't
2095 * introduce nulls.
2096 */
2097 while (expr && IsA(expr, RelabelType))
2098 expr = ((RelabelType *) expr)->arg;
2099
2100 if (expr == NULL) /* paranoia */
2101 return false;
2102
2103 /*
2104 * Since the subquery hasn't yet been through expression
2105 * preprocessing, we must explicitly flatten grouping Vars and join
2106 * alias Vars in the given expression. Note that flatten_group_exprs
2107 * must be applied before flatten_join_alias_vars, as grouping Vars
2108 * can wrap join alias Vars.
2109 *
2110 * We must also apply flatten_join_alias_vars to the quals extracted
2111 * by find_subquery_safe_quals. We do not need to apply
2112 * flatten_group_exprs to these quals, though, because grouping Vars
2113 * cannot appear in jointree quals.
2114 */
2115
2116 /*
2117 * We have verified that the query does not contain grouping sets,
2118 * meaning the grouping Vars will not have varnullingrels that need
2119 * preserving, so it's safe to use NULL as the root here.
2120 */
2121 if (query->hasGroupRTE)
2122 expr = (Expr *) flatten_group_exprs(NULL, query, (Node *) expr);
2123
2124 /*
2125 * We won't be dealing with arbitrary expressions, so it's safe to use
2126 * NULL as the root, so long as adjust_standard_join_alias_expression
2127 * can handle everything the parser would make as a join alias
2128 * expression.
2129 */
2130 expr = (Expr *) flatten_join_alias_vars(NULL, query, (Node *) expr);
2131
2132 /*
2133 * Check to see if the expr cannot be NULL. Since we're on a raw
2134 * parse tree, we need to look up the not-null constraints from the
2135 * system catalogs.
2136 */
2137 if (expr_is_nonnullable(&subroot, expr, NOTNULL_SOURCE_SYSCACHE))
2138 continue;
2139
2140 if (IsA(expr, Var))
2141 {
2142 Var *var = (Var *) expr;
2143
2144 /*
2145 * For a plain Var, even if that didn't work, we can conclude that
2146 * the Var is not nullable if find_nonnullable_vars can find a
2147 * "var IS NOT NULL" or similarly strict condition among the quals
2148 * on non-outerjoined-rels. Compute the list of Vars having such
2149 * quals if we didn't already.
2150 */
2152 {
2154 safe_quals = (List *)
2158 }
2159
2160 if (!mbms_is_member(var->varno,
2163 return false; /* we failed to prove the Var non-null */
2164 }
2165 else
2166 {
2167 /* Punt otherwise */
2168 return false;
2169 }
2170 }
2171
2172 return true;
2173}
#define MemSet(start, val, len)
Definition c.h:1079
List * find_nonnullable_vars(Node *clause)
Definition clauses.c:1725
bool mbms_is_member(int listidx, int bitidx, const List *a)
Query * parse
Definition pathnodes.h:309
FromExpr * jointree
Definition parsenodes.h:182
Node * setOperations
Definition parsenodes.h:236
List * targetList
Definition parsenodes.h:198
List * groupingSets
Definition parsenodes.h:220
Node * flatten_group_exprs(PlannerInfo *root, Query *query, Node *node)
Definition var.c:999
Node * flatten_join_alias_vars(PlannerInfo *root, Query *query, Node *node)
Definition var.c:781

References expr_is_nonnullable(), fb(), find_nonnullable_vars(), find_subquery_safe_quals(), FirstLowInvalidHeapAttributeNumber, flatten_group_exprs(), flatten_join_alias_vars(), foreach_node, Query::groupingSets, IsA, Query::jointree, mbms_is_member(), MemSet, NIL, NOTNULL_SOURCE_SYSCACHE, PlannerInfo::parse, Query::setOperations, Query::targetList, Var::varattno, and Var::varno.

Referenced by convert_ANY_sublink_to_join().

◆ recheck_cast_function_args()

static void recheck_cast_function_args ( List args,
Oid  result_type,
Oid proargtypes,
int  pronargs,
HeapTuple  func_tuple 
)
static

Definition at line 5096 of file clauses.c.

5099{
5101 int nargs;
5104 Oid rettype;
5105 ListCell *lc;
5106
5107 if (list_length(args) > FUNC_MAX_ARGS)
5108 elog(ERROR, "too many function arguments");
5109 nargs = 0;
5110 foreach(lc, args)
5111 {
5112 actual_arg_types[nargs++] = exprType((Node *) lfirst(lc));
5113 }
5114 Assert(nargs == pronargs);
5118 nargs,
5119 funcform->prorettype,
5120 false);
5121 /* let's just check we got the same answer as the parser did ... */
5122 if (rettype != result_type)
5123 elog(ERROR, "function's resolved result type changed during planning");
5124
5125 /* perform any necessary typecasting of arguments */
5127}

References Assert, elog, enforce_generic_type_consistency(), ERROR, exprType(), fb(), Form_pg_proc, FUNC_MAX_ARGS, GETSTRUCT(), lfirst, list_length(), make_fn_arguments(), and pronargs.

Referenced by expand_function_arguments().

◆ reorder_function_arguments()

static List * reorder_function_arguments ( List args,
int  pronargs,
HeapTuple  func_tuple 
)
static

Definition at line 4972 of file clauses.c.

4973{
4975 int nargsprovided = list_length(args);
4977 ListCell *lc;
4978 int i;
4979
4982 elog(ERROR, "too many function arguments");
4983 memset(argarray, 0, pronargs * sizeof(Node *));
4984
4985 /* Deconstruct the argument list into an array indexed by argnumber */
4986 i = 0;
4987 foreach(lc, args)
4988 {
4989 Node *arg = (Node *) lfirst(lc);
4990
4991 if (!IsA(arg, NamedArgExpr))
4992 {
4993 /* positional argument, assumed to precede all named args */
4994 Assert(argarray[i] == NULL);
4995 argarray[i++] = arg;
4996 }
4997 else
4998 {
5000
5001 Assert(na->argnumber >= 0 && na->argnumber < pronargs);
5002 Assert(argarray[na->argnumber] == NULL);
5003 argarray[na->argnumber] = (Node *) na->arg;
5004 }
5005 }
5006
5007 /*
5008 * Fetch default expressions, if needed, and insert into array at proper
5009 * locations (they aren't necessarily consecutive or all used)
5010 */
5011 if (nargsprovided < pronargs)
5012 {
5014
5015 i = pronargs - funcform->pronargdefaults;
5016 foreach(lc, defaults)
5017 {
5018 if (argarray[i] == NULL)
5019 argarray[i] = (Node *) lfirst(lc);
5020 i++;
5021 }
5022 }
5023
5024 /* Now reconstruct the args list in proper order */
5025 args = NIL;
5026 for (i = 0; i < pronargs; i++)
5027 {
5028 Assert(argarray[i] != NULL);
5029 args = lappend(args, argarray[i]);
5030 }
5031
5032 return args;
5033}

References arg, Assert, elog, ERROR, fb(), fetch_function_defaults(), Form_pg_proc, FUNC_MAX_ARGS, GETSTRUCT(), i, IsA, lappend(), lfirst, list_length(), NIL, and pronargs.

Referenced by expand_function_arguments().

◆ rowtype_field_matches()

static bool rowtype_field_matches ( Oid  rowtypeid,
int  fieldnum,
Oid  expectedtype,
int32  expectedtypmod,
Oid  expectedcollation 
)
static

Definition at line 2429 of file clauses.c.

2432{
2433 TupleDesc tupdesc;
2434 Form_pg_attribute attr;
2435
2436 /* No issue for RECORD, since there is no way to ALTER such a type */
2437 if (rowtypeid == RECORDOID)
2438 return true;
2439 tupdesc = lookup_rowtype_tupdesc_domain(rowtypeid, -1, false);
2441 {
2442 ReleaseTupleDesc(tupdesc);
2443 return false;
2444 }
2445 attr = TupleDescAttr(tupdesc, fieldnum - 1);
2446 if (attr->attisdropped ||
2447 attr->atttypid != expectedtype ||
2448 attr->atttypmod != expectedtypmod ||
2449 attr->attcollation != expectedcollation)
2450 {
2451 ReleaseTupleDesc(tupdesc);
2452 return false;
2453 }
2454 ReleaseTupleDesc(tupdesc);
2455 return true;
2456}
FormData_pg_attribute * Form_pg_attribute
#define ReleaseTupleDesc(tupdesc)
Definition tupdesc.h:219
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
Definition tupdesc.h:160
TupleDesc lookup_rowtype_tupdesc_domain(Oid type_id, int32 typmod, bool noError)
Definition typcache.c:1980

References fb(), lookup_rowtype_tupdesc_domain(), TupleDescData::natts, ReleaseTupleDesc, and TupleDescAttr().

Referenced by eval_const_expressions_mutator().

◆ simplify_aggref()

static Node * simplify_aggref ( Aggref aggref,
eval_const_expressions_context context 
)
static

Definition at line 4584 of file clauses.c.

4585{
4587
4589 {
4591 Node *newnode;
4592
4593 /*
4594 * Build a SupportRequestSimplifyAggref node to pass to the support
4595 * function.
4596 */
4598 req.root = context->root;
4599 req.aggref = aggref;
4600
4602 PointerGetDatum(&req)));
4603
4604 /*
4605 * We expect the support function to return either a new Node or NULL
4606 * (when simplification isn't possible).
4607 */
4608 Assert(newnode != (Node *) aggref || newnode == NULL);
4609
4610 if (newnode != NULL)
4611 return newnode;
4612 }
4613
4614 return (Node *) aggref;
4615}

References Aggref::aggfnoid, Assert, DatumGetPointer(), fb(), get_func_support(), OidFunctionCall1, OidIsValid, PointerGetDatum(), eval_const_expressions_context::root, and Node::type.

Referenced by eval_const_expressions_mutator().

◆ simplify_and_arguments()

static List * simplify_and_arguments ( List args,
eval_const_expressions_context context,
bool haveNull,
bool forceFalse 
)
static

Definition at line 4315 of file clauses.c.

4318{
4319 List *newargs = NIL;
4321
4322 /* See comments in simplify_or_arguments */
4324 while (unprocessed_args)
4325 {
4327
4329
4330 /* flatten nested ANDs as per above comment */
4331 if (is_andclause(arg))
4332 {
4333 List *subargs = ((BoolExpr *) arg)->args;
4335
4337 /* perhaps-overly-tense code to avoid leaking old lists */
4339 continue;
4340 }
4341
4342 /* If it's not an AND, simplify it */
4344
4345 /*
4346 * It is unlikely but not impossible for simplification of a non-AND
4347 * clause to produce an AND. Recheck, but don't be too tense about it
4348 * since it's not a mainstream case. In particular we don't worry
4349 * about const-simplifying the input twice, nor about list leakage.
4350 */
4351 if (is_andclause(arg))
4352 {
4353 List *subargs = ((BoolExpr *) arg)->args;
4354
4356 continue;
4357 }
4358
4359 /*
4360 * OK, we have a const-simplified non-AND argument. Process it per
4361 * comments above.
4362 */
4363 if (IsA(arg, Const))
4364 {
4365 Const *const_input = (Const *) arg;
4366
4367 if (const_input->constisnull)
4368 *haveNull = true;
4369 else if (!DatumGetBool(const_input->constvalue))
4370 {
4371 *forceFalse = true;
4372
4373 /*
4374 * Once we detect a FALSE result we can just exit the loop
4375 * immediately. However, if we ever add a notion of
4376 * non-removable functions, we'd need to keep scanning.
4377 */
4378 return NIL;
4379 }
4380 /* otherwise, we can drop the constant-true input */
4381 continue;
4382 }
4383
4384 /* else emit the simplified arg into the result list */
4386 }
4387
4388 return newargs;
4389}

References arg, DatumGetBool(), eval_const_expressions_mutator(), fb(), is_andclause(), IsA, lappend(), linitial, list_concat_copy(), list_copy(), list_delete_first(), list_free(), and NIL.

Referenced by eval_const_expressions_mutator().

◆ simplify_boolean_equality()

static Node * simplify_boolean_equality ( Oid  opno,
List args 
)
static

Definition at line 4409 of file clauses.c.

4410{
4411 Node *leftop;
4412 Node *rightop;
4413
4414 Assert(list_length(args) == 2);
4415 leftop = linitial(args);
4416 rightop = lsecond(args);
4417 if (leftop && IsA(leftop, Const))
4418 {
4419 Assert(!((Const *) leftop)->constisnull);
4420 if (opno == BooleanEqualOperator)
4421 {
4422 if (DatumGetBool(((Const *) leftop)->constvalue))
4423 return rightop; /* true = foo */
4424 else
4425 return negate_clause(rightop); /* false = foo */
4426 }
4427 else
4428 {
4429 if (DatumGetBool(((Const *) leftop)->constvalue))
4430 return negate_clause(rightop); /* true <> foo */
4431 else
4432 return rightop; /* false <> foo */
4433 }
4434 }
4435 if (rightop && IsA(rightop, Const))
4436 {
4438 if (opno == BooleanEqualOperator)
4439 {
4441 return leftop; /* foo = true */
4442 else
4443 return negate_clause(leftop); /* foo = false */
4444 }
4445 else
4446 {
4448 return negate_clause(leftop); /* foo <> true */
4449 else
4450 return leftop; /* foo <> false */
4451 }
4452 }
4453 return NULL;
4454}

References Assert, DatumGetBool(), fb(), IsA, linitial, list_length(), lsecond, and negate_clause().

Referenced by eval_const_expressions_mutator().

◆ simplify_function()

static Expr * simplify_function ( Oid  funcid,
Oid  result_type,
int32  result_typmod,
Oid  result_collid,
Oid  input_collid,
List **  args_p,
bool  funcvariadic,
bool  process_args,
bool  allow_non_const,
eval_const_expressions_context context 
)
static

Definition at line 4478 of file clauses.c.

4482{
4483 List *args = *args_p;
4486 Expr *newexpr;
4487
4488 /*
4489 * We have three strategies for simplification: execute the function to
4490 * deliver a constant result, use a transform function to generate a
4491 * substitute node tree, or expand in-line the body of the function
4492 * definition (which only works for simple SQL-language functions, but
4493 * that is a common case). Each case needs access to the function's
4494 * pg_proc tuple, so fetch it just once.
4495 *
4496 * Note: the allow_non_const flag suppresses both the second and third
4497 * strategies; so if !allow_non_const, simplify_function can only return a
4498 * Const or NULL. Argument-list rewriting happens anyway, though.
4499 */
4502 elog(ERROR, "cache lookup failed for function %u", funcid);
4504
4505 /*
4506 * Process the function arguments, unless the caller did it already.
4507 *
4508 * Here we must deal with named or defaulted arguments, and then
4509 * recursively apply eval_const_expressions to the whole argument list.
4510 */
4511 if (process_args)
4512 {
4513 args = expand_function_arguments(args, false, result_type, func_tuple);
4516 context);
4517 /* Argument processing done, give it back to the caller */
4518 *args_p = args;
4519 }
4520
4521 /* Now attempt simplification of the function call proper. */
4522
4523 newexpr = evaluate_function(funcid, result_type, result_typmod,
4525 args, funcvariadic,
4526 func_tuple, context);
4527
4528 if (!newexpr && allow_non_const && OidIsValid(func_form->prosupport))
4529 {
4530 /*
4531 * Build a SupportRequestSimplify node to pass to the support
4532 * function, pointing to a dummy FuncExpr node containing the
4533 * simplified arg list. We use this approach to present a uniform
4534 * interface to the support function regardless of how the target
4535 * function is actually being invoked.
4536 */
4539
4540 fexpr.xpr.type = T_FuncExpr;
4541 fexpr.funcid = funcid;
4542 fexpr.funcresulttype = result_type;
4543 fexpr.funcretset = func_form->proretset;
4544 fexpr.funcvariadic = funcvariadic;
4545 fexpr.funcformat = COERCE_EXPLICIT_CALL;
4546 fexpr.funccollid = result_collid;
4547 fexpr.inputcollid = input_collid;
4548 fexpr.args = args;
4549 fexpr.location = -1;
4550
4552 req.root = context->root;
4553 req.fcall = &fexpr;
4554
4555 newexpr = (Expr *)
4557 PointerGetDatum(&req)));
4558
4559 /* catch a possible API misunderstanding */
4560 Assert(newexpr != (Expr *) &fexpr);
4561 }
4562
4563 if (!newexpr && allow_non_const)
4564 newexpr = inline_function(funcid, result_type, result_collid,
4566 func_tuple, context);
4567
4569
4570 return newexpr;
4571}

References Assert, COERCE_EXPLICIT_CALL, DatumGetPointer(), elog, ERROR, eval_const_expressions_mutator(), evaluate_function(), expand_function_arguments(), expression_tree_mutator, fb(), Form_pg_proc, GETSTRUCT(), HeapTupleIsValid, inline_function(), ObjectIdGetDatum(), OidFunctionCall1, OidIsValid, PointerGetDatum(), ReleaseSysCache(), eval_const_expressions_context::root, SearchSysCache1(), and FuncExpr::xpr.

Referenced by eval_const_expressions_mutator().

◆ simplify_or_arguments()

static List * simplify_or_arguments ( List args,
eval_const_expressions_context context,
bool haveNull,
bool forceTrue 
)
static

Definition at line 4209 of file clauses.c.

4212{
4213 List *newargs = NIL;
4215
4216 /*
4217 * We want to ensure that any OR immediately beneath another OR gets
4218 * flattened into a single OR-list, so as to simplify later reasoning.
4219 *
4220 * To avoid stack overflow from recursion of eval_const_expressions, we
4221 * resort to some tenseness here: we keep a list of not-yet-processed
4222 * inputs, and handle flattening of nested ORs by prepending to the to-do
4223 * list instead of recursing. Now that the parser generates N-argument
4224 * ORs from simple lists, this complexity is probably less necessary than
4225 * it once was, but we might as well keep the logic.
4226 */
4228 while (unprocessed_args)
4229 {
4231
4233
4234 /* flatten nested ORs as per above comment */
4235 if (is_orclause(arg))
4236 {
4237 List *subargs = ((BoolExpr *) arg)->args;
4239
4241 /* perhaps-overly-tense code to avoid leaking old lists */
4243 continue;
4244 }
4245
4246 /* If it's not an OR, simplify it */
4248
4249 /*
4250 * It is unlikely but not impossible for simplification of a non-OR
4251 * clause to produce an OR. Recheck, but don't be too tense about it
4252 * since it's not a mainstream case. In particular we don't worry
4253 * about const-simplifying the input twice, nor about list leakage.
4254 */
4255 if (is_orclause(arg))
4256 {
4257 List *subargs = ((BoolExpr *) arg)->args;
4258
4260 continue;
4261 }
4262
4263 /*
4264 * OK, we have a const-simplified non-OR argument. Process it per
4265 * comments above.
4266 */
4267 if (IsA(arg, Const))
4268 {
4269 Const *const_input = (Const *) arg;
4270
4271 if (const_input->constisnull)
4272 *haveNull = true;
4273 else if (DatumGetBool(const_input->constvalue))
4274 {
4275 *forceTrue = true;
4276
4277 /*
4278 * Once we detect a TRUE result we can just exit the loop
4279 * immediately. However, if we ever add a notion of
4280 * non-removable functions, we'd need to keep scanning.
4281 */
4282 return NIL;
4283 }
4284 /* otherwise, we can drop the constant-false input */
4285 continue;
4286 }
4287
4288 /* else emit the simplified arg into the result list */
4290 }
4291
4292 return newargs;
4293}

References arg, DatumGetBool(), eval_const_expressions_mutator(), fb(), is_orclause(), IsA, lappend(), linitial, list_concat_copy(), list_copy(), list_delete_first(), list_free(), and NIL.

Referenced by eval_const_expressions_mutator().

◆ sql_inline_error_callback()

static void sql_inline_error_callback ( void arg)
static

Definition at line 5664 of file clauses.c.

5665{
5668
5669 /* If it's a syntax error, convert to internal syntax error report */
5671 if (syntaxerrposition > 0)
5672 {
5673 errposition(0);
5675 internalerrquery(callback_arg->prosrc);
5676 }
5677
5678 errcontext("SQL function \"%s\" during inlining", callback_arg->proname);
5679}

References arg, errcontext, errposition(), fb(), geterrposition(), internalerrposition(), internalerrquery(), inline_error_callback_arg::proname, and inline_error_callback_arg::prosrc.

Referenced by inline_function(), and inline_function_in_from().

◆ substitute_actual_parameters()

static Node * substitute_actual_parameters ( Node expr,
int  nargs,
List args,
int usecounts 
)
static

Definition at line 5623 of file clauses.c.

5625{
5627
5628 context.nargs = nargs;
5629 context.args = args;
5630 context.usecounts = usecounts;
5631
5632 return substitute_actual_parameters_mutator(expr, &context);
5633}

References substitute_actual_parameters_context::args, substitute_actual_parameters_context::nargs, substitute_actual_parameters_mutator(), and substitute_actual_parameters_context::usecounts.

Referenced by inline_function().

◆ substitute_actual_parameters_in_from()

static Query * substitute_actual_parameters_in_from ( Query expr,
int  nargs,
List args 
)
static

◆ substitute_actual_parameters_in_from_mutator()

static Node * substitute_actual_parameters_in_from_mutator ( Node node,
substitute_actual_parameters_in_from_context context 
)
static

Definition at line 6159 of file clauses.c.

6161{
6162 Node *result;
6163
6164 if (node == NULL)
6165 return NULL;
6166 if (IsA(node, Query))
6167 {
6168 context->sublevels_up++;
6169 result = (Node *) query_tree_mutator((Query *) node,
6171 context,
6172 0);
6173 context->sublevels_up--;
6174 return result;
6175 }
6176 if (IsA(node, Param))
6177 {
6178 Param *param = (Param *) node;
6179
6180 if (param->paramkind == PARAM_EXTERN)
6181 {
6182 if (param->paramid <= 0 || param->paramid > context->nargs)
6183 elog(ERROR, "invalid paramid: %d", param->paramid);
6184
6185 /*
6186 * Since the parameter is being inserted into a subquery, we must
6187 * adjust levels.
6188 */
6189 result = copyObject(list_nth(context->args, param->paramid - 1));
6190 IncrementVarSublevelsUp(result, context->sublevels_up, 0);
6191 return result;
6192 }
6193 }
6194 return expression_tree_mutator(node,
6196 context);
6197}

References substitute_actual_parameters_in_from_context::args, copyObject, elog, ERROR, expression_tree_mutator, fb(), IncrementVarSublevelsUp(), IsA, list_nth(), substitute_actual_parameters_in_from_context::nargs, PARAM_EXTERN, Param::paramid, Param::paramkind, query_tree_mutator, substitute_actual_parameters_in_from_context::sublevels_up, and substitute_actual_parameters_in_from_mutator().

Referenced by substitute_actual_parameters_in_from(), and substitute_actual_parameters_in_from_mutator().

◆ substitute_actual_parameters_mutator()

static Node * substitute_actual_parameters_mutator ( Node node,
substitute_actual_parameters_context context 
)
static

Definition at line 5636 of file clauses.c.

5638{
5639 if (node == NULL)
5640 return NULL;
5641 if (IsA(node, Param))
5642 {
5643 Param *param = (Param *) node;
5644
5645 if (param->paramkind != PARAM_EXTERN)
5646 elog(ERROR, "unexpected paramkind: %d", (int) param->paramkind);
5647 if (param->paramid <= 0 || param->paramid > context->nargs)
5648 elog(ERROR, "invalid paramid: %d", param->paramid);
5649
5650 /* Count usage of parameter */
5651 context->usecounts[param->paramid - 1]++;
5652
5653 /* Select the appropriate actual arg and replace the Param with it */
5654 /* We don't need to copy at this time (it'll get done later) */
5655 return list_nth(context->args, param->paramid - 1);
5656 }
5658}

References substitute_actual_parameters_context::args, elog, ERROR, expression_tree_mutator, fb(), IsA, list_nth(), substitute_actual_parameters_context::nargs, PARAM_EXTERN, Param::paramid, Param::paramkind, substitute_actual_parameters_mutator(), and substitute_actual_parameters_context::usecounts.

Referenced by substitute_actual_parameters(), and substitute_actual_parameters_mutator().

◆ var_is_nonnullable()

bool var_is_nonnullable ( PlannerInfo root,
Var var,
NotNullSource  source 
)

Definition at line 4626 of file clauses.c.

4627{
4628 Assert(IsA(var, Var));
4629
4630 /* skip upper-level Vars */
4631 if (var->varlevelsup != 0)
4632 return false;
4633
4634 /* could the Var be nulled by any outer joins or grouping sets? */
4635 if (!bms_is_empty(var->varnullingrels))
4636 return false;
4637
4638 /* system columns cannot be NULL */
4639 if (var->varattno < 0)
4640 return true;
4641
4642 /* we don't trust whole-row Vars */
4643 if (var->varattno == 0)
4644 return false;
4645
4646 /* Check if the Var is defined as NOT NULL. */
4647 switch (source)
4648 {
4650 {
4651 /*
4652 * We retrieve the column NOT NULL constraint information from
4653 * the corresponding RelOptInfo.
4654 */
4655 RelOptInfo *rel;
4656 Bitmapset *notnullattnums;
4657
4658 rel = find_base_rel(root, var->varno);
4659 notnullattnums = rel->notnullattnums;
4660
4661 return bms_is_member(var->varattno, notnullattnums);
4662 }
4664 {
4665 /*
4666 * We retrieve the column NOT NULL constraint information from
4667 * the hash table.
4668 */
4670 Bitmapset *notnullattnums;
4671
4672 rte = planner_rt_fetch(var->varno, root);
4673
4674 /* We can only reason about ordinary relations */
4675 if (rte->rtekind != RTE_RELATION)
4676 return false;
4677
4678 /*
4679 * We must skip inheritance parent tables, as some child
4680 * tables may have a NOT NULL constraint for a column while
4681 * others may not. This cannot happen with partitioned
4682 * tables, though.
4683 */
4684 if (rte->inh && rte->relkind != RELKIND_PARTITIONED_TABLE)
4685 return false;
4686
4687 notnullattnums = find_relation_notnullatts(root, rte->relid);
4688
4689 return bms_is_member(var->varattno, notnullattnums);
4690 }
4692 {
4693 /*
4694 * We look up the "attnotnull" field in the attribute
4695 * relation.
4696 */
4698
4699 rte = planner_rt_fetch(var->varno, root);
4700
4701 /* We can only reason about ordinary relations */
4702 if (rte->rtekind != RTE_RELATION)
4703 return false;
4704
4705 /*
4706 * We must skip inheritance parent tables, as some child
4707 * tables may have a NOT NULL constraint for a column while
4708 * others may not. This cannot happen with partitioned
4709 * tables, though.
4710 *
4711 * Note that we need to check if the relation actually has any
4712 * children, as we might not have done that yet.
4713 */
4714 if (rte->inh && has_subclass(rte->relid) &&
4715 rte->relkind != RELKIND_PARTITIONED_TABLE)
4716 return false;
4717
4718 return get_attnotnull(rte->relid, var->varattno);
4719 }
4720 default:
4721 elog(ERROR, "unrecognized NotNullSource: %d",
4722 (int) source);
4723 break;
4724 }
4725
4726 return false;
4727}

References Assert, bms_is_empty, bms_is_member(), elog, ERROR, fb(), find_base_rel(), find_relation_notnullatts(), get_attnotnull(), has_subclass(), IsA, NOTNULL_SOURCE_HASHTABLE, NOTNULL_SOURCE_RELOPT, NOTNULL_SOURCE_SYSCACHE, RelOptInfo::notnullattnums, planner_rt_fetch, root, RTE_RELATION, source, Var::varattno, Var::varlevelsup, and Var::varno.

Referenced by expr_is_nonnullable().